|
|
|
/*
|
|
|
|
|
|
|
|
Copyright (C) 2010 Timothy Pearson <kb9vqf@pearsoncomputing.net>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <tqt.h>
|
|
|
|
#include <tqtranslator.h>
|
|
|
|
|
|
|
|
#ifdef USE_QT4
|
|
|
|
|
|
|
|
static uint elfHash( const char * name )
|
|
|
|
{
|
|
|
|
const uchar *k;
|
|
|
|
uint h = 0;
|
|
|
|
uint g;
|
|
|
|
|
|
|
|
if ( name ) {
|
|
|
|
k = (const uchar *) name;
|
|
|
|
while ( *k ) {
|
|
|
|
h = ( h << 4 ) + *k++;
|
|
|
|
if ( (g = (h & 0xf0000000)) != 0 )
|
|
|
|
h ^= g >> 24;
|
|
|
|
h &= ~g;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( !h )
|
|
|
|
h = 1;
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\class QTranslatorMessage
|
|
|
|
|
|
|
|
\brief The QTranslatorMessage class contains a translator message and its
|
|
|
|
properties.
|
|
|
|
|
|
|
|
\ingroup i18n
|
|
|
|
\ingroup environment
|
|
|
|
|
|
|
|
This class is of no interest to most applications. It is useful
|
|
|
|
for translation tools such as \link linguist-manual.book Qt
|
|
|
|
Linguist\endlink. It is provided simply to make the API complete
|
|
|
|
and regular.
|
|
|
|
|
|
|
|
For a QTranslator object, a lookup key is a triple (\e context, \e
|
|
|
|
{source text}, \e comment) that uniquely identifies a message. An
|
|
|
|
extended key is a quadruple (\e hash, \e context, \e {source
|
|
|
|
text}, \e comment), where \e hash is computed from the source text
|
|
|
|
and the comment. Unless you plan to read and write messages
|
|
|
|
yourself, you need not worry about the hash value.
|
|
|
|
|
|
|
|
QTranslatorMessage stores this triple or quadruple and the relevant
|
|
|
|
translation if there is any.
|
|
|
|
|
|
|
|
\sa QTranslator
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a translator message with the extended key (0, 0, 0, 0)
|
|
|
|
and QString::null as translation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QTranslatorMessage::QTranslatorMessage()
|
|
|
|
: h( 0 ), cx( 0 ), st( 0 ), cm( 0 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs an translator message with the extended key (\e h, \a
|
|
|
|
context, \a sourceText, \a comment), where \e h is computed from
|
|
|
|
\a sourceText and \a comment, and possibly with a \a translation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QTranslatorMessage::QTranslatorMessage( const char * context,
|
|
|
|
const char * sourceText,
|
|
|
|
const char * comment,
|
|
|
|
const QString& translation )
|
|
|
|
: cx( context ), st( sourceText ), cm( comment ), tn( translation )
|
|
|
|
{
|
|
|
|
// 0 means we don't know, "" means empty
|
|
|
|
if ( cx == (const char*)0 )
|
|
|
|
cx = "";
|
|
|
|
if ( st == (const char*)0 )
|
|
|
|
st = "";
|
|
|
|
if ( cm == (const char*)0 )
|
|
|
|
cm = "";
|
|
|
|
h = elfHash( st + cm );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a translator message read from the \a stream. The
|
|
|
|
resulting message may have any combination of content.
|
|
|
|
|
|
|
|
\sa QTranslator::save()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QTranslatorMessage::QTranslatorMessage( QDataStream & stream )
|
|
|
|
: cx( 0 ), st( 0 ), cm( 0 )
|
|
|
|
{
|
|
|
|
QString str16;
|
|
|
|
char tag;
|
|
|
|
Q_UINT8 obs1;
|
|
|
|
|
|
|
|
for ( ;; ) {
|
|
|
|
tag = 0;
|
|
|
|
if ( !stream.atEnd() )
|
|
|
|
stream.readRawBytes( &tag, 1 );
|
|
|
|
switch( (Tag)tag ) {
|
|
|
|
case Tag_End:
|
|
|
|
if ( h == 0 )
|
|
|
|
h = elfHash( st + cm );
|
|
|
|
return;
|
|
|
|
case Tag_SourceText16: // obsolete
|
|
|
|
stream >> str16;
|
|
|
|
st = str16.latin1();
|
|
|
|
break;
|
|
|
|
case Tag_Translation:
|
|
|
|
stream >> tn;
|
|
|
|
break;
|
|
|
|
case Tag_Context16: // obsolete
|
|
|
|
stream >> str16;
|
|
|
|
cx = str16.latin1();
|
|
|
|
break;
|
|
|
|
case Tag_Hash:
|
|
|
|
stream >> h;
|
|
|
|
break;
|
|
|
|
case Tag_SourceText:
|
|
|
|
stream >> st;
|
|
|
|
break;
|
|
|
|
case Tag_Context:
|
|
|
|
stream >> cx;
|
|
|
|
if ( cx == "" ) // for compatibility
|
|
|
|
cx = 0;
|
|
|
|
break;
|
|
|
|
case Tag_Comment:
|
|
|
|
stream >> cm;
|
|
|
|
break;
|
|
|
|
case Tag_Obsolete1: // obsolete
|
|
|
|
stream >> obs1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
h = 0;
|
|
|
|
st = 0;
|
|
|
|
cx = 0;
|
|
|
|
cm = 0;
|
|
|
|
tn = QString::null;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a copy of translator message \a m.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QTranslatorMessage::QTranslatorMessage( const QTranslatorMessage & m )
|
|
|
|
: cx( m.cx ), st( m.st ), cm( m.cm ), tn( m.tn )
|
|
|
|
{
|
|
|
|
h = m.h;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Assigns message \a m to this translator message and returns a
|
|
|
|
reference to this translator message.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QTranslatorMessage & QTranslatorMessage::operator=(
|
|
|
|
const QTranslatorMessage & m )
|
|
|
|
{
|
|
|
|
h = m.h;
|
|
|
|
cx = m.cx;
|
|
|
|
st = m.st;
|
|
|
|
cm = m.cm;
|
|
|
|
tn = m.tn;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn uint QTranslatorMessage::hash() const
|
|
|
|
|
|
|
|
Returns the hash value used internally to represent the lookup
|
|
|
|
key. This value is zero only if this translator message was
|
|
|
|
constructed from a stream containing invalid data.
|
|
|
|
|
|
|
|
The hashing function is unspecified, but it will remain unchanged
|
|
|
|
in future versions of Qt.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn const char *QTranslatorMessage::context() const
|
|
|
|
|
|
|
|
Returns the context for this message (e.g. "MyDialog").
|
|
|
|
|
|
|
|
\warning This may return 0 if the QTranslator object is stripped
|
|
|
|
(compressed).
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn const char *QTranslatorMessage::sourceText() const
|
|
|
|
|
|
|
|
Returns the source text of this message (e.g. "&Save").
|
|
|
|
|
|
|
|
\warning This may return 0 if the QTranslator object is stripped
|
|
|
|
(compressed).
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn const char *QTranslatorMessage::comment() const
|
|
|
|
|
|
|
|
Returns the comment for this message (e.g. "File|Save").
|
|
|
|
|
|
|
|
\warning This may return 0 if the QTranslator object is stripped
|
|
|
|
(compressed).
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn void QTranslatorMessage::setTranslation( const QString & translation )
|
|
|
|
|
|
|
|
Sets the translation of the source text to \a translation.
|
|
|
|
|
|
|
|
\sa translation()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn QString QTranslatorMessage::translation() const
|
|
|
|
|
|
|
|
Returns the translation of the source text (e.g., "&Sauvegarder").
|
|
|
|
|
|
|
|
\sa setTranslation()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\enum QTranslatorMessage::Prefix
|
|
|
|
|
|
|
|
Let (\e h, \e c, \e s, \e m) be the extended key. The possible
|
|
|
|
prefixes are
|
|
|
|
|
|
|
|
\value NoPrefix no prefix
|
|
|
|
\value Hash only (\e h)
|
|
|
|
\value HashContext only (\e h, \e c)
|
|
|
|
\value HashContextSourceText only (\e h, \e c, \e s)
|
|
|
|
\value HashContextSourceTextComment the whole extended key, (\e
|
|
|
|
h, \e c, \e s, \e m)
|
|
|
|
|
|
|
|
\sa write() commonPrefix()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Writes this translator message to the \a stream. If \a strip is
|
|
|
|
FALSE (the default), all the information in the message is
|
|
|
|
written. If \a strip is TRUE, only the part of the extended key
|
|
|
|
specified by \a prefix is written with the translation (\c
|
|
|
|
HashContextSourceTextComment by default).
|
|
|
|
|
|
|
|
\sa commonPrefix()
|
|
|
|
*/
|
|
|
|
|
|
|
|
void QTranslatorMessage::write( QDataStream & stream, bool strip,
|
|
|
|
Prefix prefix ) const
|
|
|
|
{
|
|
|
|
char tag;
|
|
|
|
|
|
|
|
tag = (char)Tag_Translation;
|
|
|
|
stream.writeRawBytes( &tag, 1 );
|
|
|
|
stream << tn;
|
|
|
|
|
|
|
|
bool mustWriteHash = TRUE;
|
|
|
|
if ( !strip )
|
|
|
|
prefix = HashContextSourceTextComment;
|
|
|
|
|
|
|
|
switch ( prefix ) {
|
|
|
|
case HashContextSourceTextComment:
|
|
|
|
tag = (char)Tag_Comment;
|
|
|
|
stream.writeRawBytes( &tag, 1 );
|
|
|
|
stream << cm;
|
|
|
|
// fall through
|
|
|
|
case HashContextSourceText:
|
|
|
|
tag = (char)Tag_SourceText;
|
|
|
|
stream.writeRawBytes( &tag, 1 );
|
|
|
|
stream << st;
|
|
|
|
// fall through
|
|
|
|
case HashContext:
|
|
|
|
tag = (char)Tag_Context;
|
|
|
|
stream.writeRawBytes( &tag, 1 );
|
|
|
|
stream << cx;
|
|
|
|
// fall through
|
|
|
|
default:
|
|
|
|
if ( mustWriteHash ) {
|
|
|
|
tag = (char)Tag_Hash;
|
|
|
|
stream.writeRawBytes( &tag, 1 );
|
|
|
|
stream << h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tag = (char)Tag_End;
|
|
|
|
stream.writeRawBytes( &tag, 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the widest lookup prefix that is common to this translator
|
|
|
|
message and to message \a m.
|
|
|
|
|
|
|
|
For example, if the extended key is for this message is (71,
|
|
|
|
"PrintDialog", "Yes", "Print?") and that for \a m is (71,
|
|
|
|
"PrintDialog", "No", "Print?"), this function returns \c
|
|
|
|
HashContext.
|
|
|
|
|
|
|
|
\sa write()
|
|
|
|
*/
|
|
|
|
|
|
|
|
QTranslatorMessage::Prefix QTranslatorMessage::commonPrefix(
|
|
|
|
const QTranslatorMessage& m ) const
|
|
|
|
{
|
|
|
|
if ( h != m.h )
|
|
|
|
return NoPrefix;
|
|
|
|
if ( cx != m.cx )
|
|
|
|
return Hash;
|
|
|
|
if ( st != m.st )
|
|
|
|
return HashContext;
|
|
|
|
if ( cm != m.cm )
|
|
|
|
return HashContextSourceText;
|
|
|
|
return HashContextSourceTextComment;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns TRUE if the extended key of this object is equal to that of
|
|
|
|
\a m; otherwise returns FALSE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool QTranslatorMessage::operator==( const QTranslatorMessage& m ) const
|
|
|
|
{
|
|
|
|
return h == m.h && cx == m.cx && st == m.st && cm == m.cm;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool QTranslatorMessage::operator!=( const QTranslatorMessage& m ) const
|
|
|
|
|
|
|
|
Returns TRUE if the extended key of this object is different from
|
|
|
|
that of \a m; otherwise returns FALSE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns TRUE if the extended key of this object is
|
|
|
|
lexicographically before than that of \a m; otherwise returns
|
|
|
|
FALSE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool QTranslatorMessage::operator<( const QTranslatorMessage& m ) const
|
|
|
|
{
|
|
|
|
return h != m.h ? h < m.h
|
|
|
|
: ( cx != m.cx ? cx < m.cx
|
|
|
|
: (st != m.st ? st < m.st : cm < m.cm) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool QTranslatorMessage::operator<=( const QTranslatorMessage& m ) const
|
|
|
|
|
|
|
|
Returns TRUE if the extended key of this object is
|
|
|
|
lexicographically before that of \a m or if they are equal;
|
|
|
|
otherwise returns FALSE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool QTranslatorMessage::operator>( const QTranslatorMessage& m ) const
|
|
|
|
|
|
|
|
Returns TRUE if the extended key of this object is
|
|
|
|
lexicographically after that of \a m; otherwise returns FALSE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool QTranslatorMessage::operator>=( const QTranslatorMessage& m ) const
|
|
|
|
|
|
|
|
Returns TRUE if the extended key of this object is
|
|
|
|
lexicographically after that of \a m or if they are equal;
|
|
|
|
otherwise returns FALSE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#endif // USE_QT4
|