Util.cpp

Go to the documentation of this file.
00001 #include "Util.h"
00002 
00003 const QString Util::languageCodeList[] = { 
00004     QObject::tr( "en" ), QObject::tr( "fr" ), QObject::tr( "es" ), QObject::tr( "ja" ), QObject::tr( "de" ), 
00005     QObject::tr( "ar" ), QObject::tr( "bg" ), QObject::tr( "el" ), QObject::tr( "it" ), QObject::tr( "ko" ), QObject::tr( "nl" ), 
00006     QObject::tr( "pt" ), QObject::tr( "ru" ), QObject::tr( "sw" ), QObject::tr( "th" ), QObject::tr( "vi" ), QObject::tr( "zh" )
00007 };
00008 
00009 QMap<QString,QString>* Util::digraphMap = 0;
00010 
00011 const QString& Util::getLanguageCode( const QString& language ) {
00012     int languageCodeListLength = sizeof( languageCodeList ) / sizeof( QString );
00013     for( int i = 0; i < languageCodeListLength; i++ ) {
00014         if( QObject::tr( languageCodeList[ i ] ) == language ) 
00015             return( languageCodeList[ i ] );
00016     }
00017     return( QString::null ); // Should never happen.
00018 }
00019 
00020 QString Util::getDefaultLabelsFontFamily() {
00021     return( getDefaultFontFamily() );
00022 }
00023 
00024 int Util::getDefaultLabelsFontSizeModifier() {
00025     return( 0 );
00026 }
00027 
00028 QString Util::getDefaultFontFamily() {
00029     QFontDatabase fontDatabase;
00030     QStringList families = fontDatabase.families( false );
00031     int unifontCount = families.contains( QString( "unifont" ) );
00032     int lcfontCount = families.contains( QString( "lcfont" ) );
00033     if( unifontCount > 0 )
00034         return( QString( "unifont" ) );
00035     else if( lcfontCount > 0 )
00036         return( QString( "lcfontCount" ) );
00037     else
00038         return( QFont::defaultFont().family() );
00039 }
00040 
00041 int Util::getDefaultFontSizeModifier() {
00042     return( 0 );
00043 }
00044 
00045 int Util::getDefaultQuizLength() {
00046     return( 1 );
00047 }
00048 
00049 QString Util::escapeXml( QString xml ) {
00050     QString escapedStr;
00051     for( uint i = 0; i < xml.length(); i++ ) {
00052         if( xml[ i ] == QChar( '&' ) )
00053             escapedStr.append( "&amp;" );
00054         else if( xml[ i ] == QChar( '<' ) )
00055             escapedStr.append( "&lt;" );
00056         else if( xml[ i ] == QChar( '>' ) )
00057             escapedStr.append( "&gt;" );
00058         else
00059             escapedStr.append( xml[ i ] );
00060     }
00061     return( escapedStr );
00062 }
00063 
00064 QString Util::term2Xml( const Term& term, QStringList* languages, uint indentLevel = 0 ) {
00065     QString indent;
00066     for( uint i = 0; i < indentLevel; i++ )
00067         indent += QString( "\t" );
00068 
00069     QString xml;
00070     QTextStream ts( &xml, IO_WriteOnly );
00071     ts << indent << QString( "<term id=\"" ) << QString::number( term.getId() ) << QString( "\"" );
00072     if( term.getImagePath() != QString::null ) {
00073         QString fileExtension = term.getImagePath().right( 4 );
00074         QString imageFilename = QString::number( term.getId() ) + fileExtension;
00075         ts << QString( " imagePath=\"" ) << imageFilename << QString( "\"" );
00076     }
00077     ts << QString( ">" ) << endl;
00078     for( Term::TranslationMap::ConstIterator it = term.translationsBegin(); it != term.translationsEnd(); it++ ) {
00079         const Translation& translation = it.data();
00080         if( !languages || languages->contains( translation.getLanguage() ) ) {
00081             ts << indent << QString( "\t<trans lang=\"" ) << translation.getLanguage() << QString( "\">" ) << endl;
00082             if( !translation.getWord().isEmpty() )
00083                 ts << indent << QString( "\t\t<word>" ) << Util::escapeXml( translation.getWord() ) << QString( "</word>" ) << endl;
00084             if( !translation.getAlt().isEmpty() )
00085                 ts << indent << QString( "\t\t<alt>" ) << Util::escapeXml( translation.getAlt() ) << QString( "</alt>" ) << endl;
00086             ts << indent << QString( "\t</trans>" ) << endl;
00087         }
00088     }
00089     for( Term::CommentMap::ConstIterator it = term.commentsBegin(); it != term.commentsEnd(); it++ ) {
00090         const BilingualKey& key = it.key();
00091         const QString& comment = it.data();
00092         if( !comment.isEmpty() ) {
00093             if( !languages || ( languages->contains( key.getFirstLanguage() ) && languages->contains( key.getSecondLanguage() ) ) )
00094                 ts << indent << "\t<comment languages=\"" << key.toString() << "\">" << Util::escapeXml( comment ) << "</comment>" << endl;
00095         }
00096     }
00097     ts << indent << QString( "</term>" ) << endl;
00098     return( xml );
00099 }
00100 
00101 bool Util::makeDirectory( const QString& dir ) {
00102     QDir d( dir );
00103     QDir absDir( d.absPath() );
00104     if( absDir.exists() )
00105         return( true );
00106 
00107     QStringList subDirs = QStringList::split( QString( "/" ), d.absPath() );
00108     for( uint i = 0; i < subDirs.count(); i++ ) {
00109         QString tempDirStr( "" );
00110         for( uint j = 0; j <= i; j++ ) 
00111             tempDirStr = tempDirStr + QString( "/" ) + subDirs[ j ];
00112         QDir tempDir( tempDirStr );
00113         if( !tempDir.exists() ) {
00114             if( !tempDir.mkdir( tempDir.path() ) )
00115                 return( false );
00116         }
00117     }
00118     return( true );
00119 }
00120 
00121 bool Util::copy( const QString& fromFile, const QString& toFile ) {
00122     //cerr << "copy " << fromFile << " to " << toFile << endl;
00123     QFileInfo srcInfo( fromFile );
00124     QFileInfo destInfo( toFile );
00125 
00126     // If the source and destination are the same, we don't need to perform the copy.
00127     if( srcInfo.absFilePath() == destInfo.absFilePath() ) 
00128         return( true );
00129 
00130     QFile src( fromFile );
00131     if( !src.open( IO_ReadOnly ) ) {
00132         cerr << "Cannot open src file " << fromFile << " when performing copy." << endl;
00133         return( false );
00134     }
00135     QFile dest( toFile );
00136     if( !dest.open( IO_WriteOnly ) ) {
00137         src.close();
00138         cerr << "Cannot open dest file " << fromFile << " when performing copy." << endl;
00139         return( false );
00140     }
00141     bool isOk = false;
00142     
00143     uInt bufferSize = 8192; // Arbitrary size for now.
00144     char* buffer = (char*)malloc( bufferSize ); 
00145     int bytesRead;
00146     while( ( bytesRead = src.readBlock( buffer, bufferSize ) ) > 0 ) {
00147         int bytesWritten = dest.writeBlock( buffer, bytesRead );
00148         if( bytesRead != bytesWritten ) {
00149             cerr << "Read and written bytes count differs (" << bytesRead << " vs " << bytesWritten << ") when performing copy." << endl;
00150             break;
00151         }
00152     }
00153     if( bytesRead == 0 )
00154         isOk = true;
00155     delete( buffer );
00156     src.close();
00157     dest.close();
00158     return( isOk );
00159 }
00160 
00161 bool Util::deleteDirectory( const QString& dir ) {
00162     QDir d( dir );
00163     QDir absDir( d.absPath() );
00164     if( !absDir.exists() )
00165         return( false );
00166 
00167     QStringList entries = absDir.entryList();
00168     for( QStringList::Iterator it = entries.begin(); it != entries.end(); it++ ) {
00169         QString entry = *it;
00170         QString entryPath = absDir.path() + "/" + entry;
00171         QFileInfo info( entryPath );
00172         if( info.isDir() ) {
00173             if( entry != "." && entry != ".." ) {
00174                 if( !deleteDirectory( entryPath ) )
00175                     return( false );
00176             }
00177         }
00178         else if( info.isFile() ) {
00179             QFile f( entryPath );
00180             if( !f.remove() )
00181                 return( false );
00182         }
00183     }
00184 
00185     return( absDir.rmdir( d.absPath() ) );
00186 }
00187 
00188 QString Util::getDigraph( const QString& buffer ) {
00189     if( !digraphMap ) 
00190         initDigraphs();
00191     return( digraphMap->contains( buffer ) ? (*digraphMap)[ buffer ] : QString::null );
00192 }
00193 
00194 void Util::initDigraphs() {
00195     digraphMap = new QMap<QString, QString>();
00196 
00197     QString digraphFilename( "/opt/Qtopia/lib/toMOTko/digraphs.conf" );
00198     QFile digraphFile( digraphFilename );
00199 
00200     if( !digraphFile.open( IO_ReadOnly ) ) {
00201         cerr << "Could not open /opt/Qtopia/lib/toMOTko/digraphs.conf" << endl;
00202         return;
00203     }
00204 
00205     QTextStream ts( &digraphFile );
00206     while ( !ts.eof() ) {
00207         QString line = ts.readLine();
00208         if( line.startsWith( "#" ) || line.length() == 0 )
00209             continue;
00210         QString digraph = line.left( 2 );
00211         QString strValue = line.mid( 5, 2 );
00212         if( !digraph.isNull() && !strValue.isNull() ) {
00213             bool isOk;
00214             uint value = strValue.toUInt( &isOk, 16 );
00215             if( isOk )
00216                 (*digraphMap)[ digraph ] = QString( QChar( value ) );
00217         }
00218     }
00219 
00220     digraphFile.close();
00221 }
00222 
00223 QAction* Util::createAction( const QString& name, const char** icon, QObject* receiver, const char* slot, int defaultKey = -1, bool toggle = false ) {
00224     QAction *a;
00225     if( icon == NULL )
00226         a = new QAction( name, name, 0, receiver, 0, toggle );
00227     else
00228         a = new QAction( name, QIconSet( ZPIXMAP( icon ) ), name, 0, receiver, 0, toggle );
00229     if( toggle )
00230         QObject::connect( a, SIGNAL( toggled( bool ) ), receiver, slot );
00231     else
00232         QObject::connect( a, SIGNAL( activated() ), receiver, slot );
00233     if( defaultKey != -1 )
00234         a->setAccel( defaultKey );
00235     return a;
00236 }
00237 
00238 QString Util::describeKey( int key ) {
00239     QString ks;
00240     if( (key & Qt::CTRL) != 0 )
00241         ks += "Ctrl+";
00242     if( (key & Qt::ALT) != 0 )
00243         ks += "Alt+";
00244     if( (key & Qt::SHIFT) != 0)
00245         ks += "Shift+";
00246 
00247     key = key & ~Qt::MODIFIER_MASK;
00248 
00249     if (key == 0x20)
00250         ks += "Space";
00251     else if (0x21 <= key && key <= 0xff) {
00252         char st[2];
00253         st[0] = key;
00254         st[1] = 0;
00255         ks += st;
00256     }
00257     else if (0x1030 <= key && key <= 0x1052)
00258         ks += QString("f") + QChar(key - 0x1030 + 1);
00259     else {
00260         switch (key) {
00261             case Qt::Key_Escape:
00262                 ks += "Esc";
00263                 break;
00264             case Qt::Key_Tab:
00265                 ks += "Tab";
00266                 break;
00267             case Qt::Key_Backtab:
00268                 ks += "Backtab";
00269                 break;
00270             case Qt::Key_Backspace:
00271                 ks += "Backspace";
00272                 break;
00273             case Qt::Key_Return:
00274                 ks += "Return";
00275                 break;
00276             case Qt::Key_Enter:
00277                 ks += "Enter";
00278                 break;
00279             case Qt::Key_Insert:
00280                 ks += "Insert";
00281                 break;
00282             case Qt::Key_Delete:
00283                 ks += "Delete";
00284                 break;
00285             case Qt::Key_Pause:
00286                 ks += "Pause";
00287                 break;
00288             case Qt::Key_Print:
00289                 ks += "Print";
00290                 break;
00291             case Qt::Key_SysReq:
00292                 ks += "SysReq";
00293                 break;
00294             case Qt::Key_Home:
00295                 ks += "Home";
00296                 break;
00297             case Qt::Key_End:
00298                 ks += "End";
00299                 break;
00300             case Qt::Key_Left:
00301                 ks += "Left";
00302                 break;
00303             case Qt::Key_Up:
00304                 ks += "Up";
00305                 break;
00306             case Qt::Key_Right:
00307                 ks += "Right";
00308                 break;
00309             case Qt::Key_Down:
00310                 ks += "Down";
00311                 break;
00312             case Qt::Key_PageUp:
00313                 ks += "PageUp";
00314                 break;
00315             case Qt::Key_PageDown:
00316                 ks += "PageDown";
00317                 break;
00318             case Qt::Key_Super_L:
00319                 ks += "Super_L";
00320                 break;
00321             case Qt::Key_Super_R:
00322                 ks += "Super_R";
00323                 break;
00324             case Qt::Key_Menu:
00325                 ks += "Menu";
00326                 break;
00327             case Qt::Key_Hyper_L:
00328                 ks += "Hyper_L";
00329                 break;
00330             case Qt::Key_Hyper_R:
00331                 ks += "Hyper_R";
00332                 break;
00333             case Qt::Key_Help:
00334                 ks += "Help";
00335                 break;
00336             default:
00337                 ks += "<" + QString::number( key, 16 ) + ">";
00338                 break;
00339         }
00340     }
00341     return ks;
00342 }
00343 
00344 QByteArray Util::qCompress( const QByteArray& byteArray, int compressionLevel ) {
00345     const uchar* data = (const uchar*)(byteArray.data());
00346     int nbytes = byteArray.size();
00347 
00348     if (nbytes == 0) {
00349         QByteArray a( 4 );
00350         a.fill( '\0' );
00351         return( a );
00352     }
00353     if (!data) {
00354         qWarning("qCompress: Data is null");
00355         return QByteArray();
00356     }
00357     if (compressionLevel < -1 || compressionLevel > 9)
00358         compressionLevel = -1;
00359 
00360     ulong len = nbytes + nbytes / 100 + 13;
00361     QByteArray bazip;
00362     int res;
00363     do {
00364         bazip.resize(len + 4);
00365         res = ::compress2((uchar*)bazip.data()+4, &len, (uchar*)data, nbytes, compressionLevel);
00366 
00367         switch (res) {
00368         case Z_OK:
00369             bazip.resize(len + 4);
00370             bazip[0] = (nbytes & 0xff000000) >> 24;
00371             bazip[1] = (nbytes & 0x00ff0000) >> 16;
00372             bazip[2] = (nbytes & 0x0000ff00) >> 8;
00373             bazip[3] = (nbytes & 0x000000ff);
00374             break;
00375         case Z_MEM_ERROR:
00376             qWarning("qCompress: Z_MEM_ERROR: Not enough memory");
00377             bazip.resize(0);
00378             break;
00379         case Z_BUF_ERROR:
00380             len *= 2;
00381             break;
00382         }
00383     } while (res == Z_BUF_ERROR);
00384 
00385     return bazip;
00386 }
00387 
00388 QByteArray Util::qUncompress( const QByteArray& byteArray ) {
00389     const uchar* data = (const uchar*)(byteArray.data());
00390     int nbytes = byteArray.size();
00391 
00392     if (!data) {
00393         qWarning("qUncompress: Data is null");
00394         return QByteArray();
00395     }
00396     if (nbytes <= 4) {
00397         if (nbytes < 4 || (data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0))
00398             qWarning("qUncompress: Input data is corrupted");
00399         return QByteArray();
00400     }
00401     ulong expectedSize = (data[0] << 24) | (data[1] << 16) | (data[2] <<  8) | (data[3] );
00402     //qMax(expectedSize, 1ul);
00403     ulong len = ( expectedSize > 1ul ? expectedSize : 1ul );
00404     QByteArray baunzip;
00405     int res;
00406     do {
00407         baunzip.resize(len);
00408         res = ::uncompress((uchar*)baunzip.data(), &len, (uchar*)data+4, nbytes-4);
00409 
00410         switch (res) {
00411         case Z_OK:
00412             if ((uint)len != baunzip.size())
00413                 baunzip.resize(len);
00414             break;
00415         case Z_MEM_ERROR:
00416             qWarning("qUncompress: Z_MEM_ERROR: Not enough memory");
00417             break;
00418         case Z_BUF_ERROR:
00419             len *= 2;
00420             break;
00421         case Z_DATA_ERROR:
00422             qWarning("qUncompress: Z_DATA_ERROR: Input data is corrupted");
00423             break;
00424         }
00425     } while (res == Z_BUF_ERROR);
00426 
00427     if (res != Z_OK)
00428         baunzip = QByteArray();
00429 
00430     return baunzip;
00431 }

Generated on Sun Mar 1 17:30:47 2009 for toMOTko by  doxygen 1.5.6