Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

kateconfig.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #define QTOPIA_INTERNAL_LANGLIST
00022 #include "kateconfig.h"
00023 
00024 /* OPIE */
00025 #include <opie2/odebug.h>
00026 #include <qpe/global.h>
00027 using namespace Opie::Core;
00028 
00029 /* QT */
00030 #include <qdir.h>
00031 #include <qmessagebox.h>
00032 #if QT_VERSION <= 230 && defined(QT_NO_CODECS)
00033 #include <qtextcodec.h>
00034 #endif
00035 #include <qtextstream.h>
00036 
00037 /* STD */
00038 #include <sys/stat.h>
00039 #include <sys/types.h>
00040 #include <fcntl.h>
00041 #include <stdlib.h>
00042 #include <unistd.h>
00043 
00044 
00048 QString KateConfig::configFilename(const QString& name, Domain d)
00049 {
00050     switch (d) {
00051     case File:
00052         return name;
00053     case User: {
00054         QDir dir = (QString(getenv("HOME")) + "/Settings");
00055         if ( !dir.exists() )
00056         mkdir(dir.path().local8Bit(),0700);
00057         return dir.path() + "/" + name + ".conf";
00058     }
00059     }
00060     return name;
00061 }
00062 
00099 KateConfig::KateConfig( const QString &name, Domain domain )
00100     : filename( configFilename(name,domain) )
00101 {
00102     owarn << "KateConfig constructor\n" << oendl;
00103     git = groups.end();
00104     read();
00105     QStringList l = Global::languageList();
00106     lang = l[0];
00107     glang = l[1];
00108 }
00109 
00110 
00111 // Sharp ROM compatibility
00112 KateConfig::KateConfig ( const QString &name, bool what )
00113     : filename( configFilename(name,what ? User : File) )
00114 {
00115     git = groups.end();
00116     read();
00117     QStringList l = Global::languageList();
00118     lang = l[0];
00119     glang = l[1];
00120 }
00121 
00125 KateConfig::~KateConfig()
00126 {
00127     owarn << "KateConfig destructor\n" << oendl;
00128     if ( changed )
00129     write();
00130 }
00131 
00135 bool KateConfig::hasKey( const QString &key ) const
00136 {
00137     if ( groups.end() == git )
00138     return FALSE;
00139     KateConfigGroup::ConstIterator it = ( *git ).find( key );
00140     return it != ( *git ).end();
00141 }
00142 
00152 void KateConfig::setGroup( const QString &gname )
00153 {
00154     QMap< QString, KateConfigGroup>::Iterator it = groups.find( gname );
00155     if ( it == groups.end() ) {
00156     git = groups.insert( gname, KateConfigGroup() );
00157     changed = TRUE;
00158     return;
00159     }
00160     git = it;
00161 }
00162 
00168 void KateConfig::writeEntry( const QString &key, const char* value )
00169 {
00170     writeEntry(key,QString(value));
00171 }
00172 
00178 void KateConfig::writeEntry( const QString &key, const QString &value )
00179 {
00180     if ( git == groups.end() ) {
00181     owarn << "no group set" << oendl;
00182     return;
00183     }
00184     if ( (*git)[key] != value ) {
00185     ( *git ).insert( key, value );
00186     changed = TRUE;
00187     }
00188 }
00189 
00190 /*
00191   Note that the degree of protection offered by the encryption here is
00192   only sufficient to avoid the most casual observation of the configuration
00193   files. People with access to the files can write down the contents and
00194   decrypt it using this source code.
00195 
00196   Conceivably, and at some burden to the user, this encryption could
00197   be improved.
00198 */
00199 static QString encipher(const QString& plain)
00200 {
00201     // mainly, we make it long
00202     QString cipher;
00203     int mix=28730492;
00204     for (int i=0; i<(int)plain.length(); i++) {
00205     int u = plain[i].unicode();
00206     int c = u ^ mix;
00207     QString x = QString::number(c,36);
00208     cipher.append(QChar('a'+x.length()));
00209     cipher.append(x);
00210     mix *= u;
00211     }
00212     return cipher;
00213 }
00214 
00215 static QString decipher(const QString& cipher)
00216 {
00217     QString plain;
00218     int mix=28730492;
00219     for (int i=0; i<(int)cipher.length();) {
00220     int l = cipher[i].unicode()-'a';
00221     QString x = cipher.mid(i+1,l); i+=l+1;
00222     int u = x.toInt(0,36) ^ mix;
00223     plain.append(QChar(u));
00224     mix *= u;
00225     }
00226     return plain;
00227 }
00228 
00238 void KateConfig::writeEntryCrypt( const QString &key, const QString &value )
00239 {
00240     if ( git == groups.end() ) {
00241     owarn << "no group set" << oendl;
00242     return;
00243     }
00244     QString evalue = encipher(value);
00245     if ( (*git)[key] != evalue ) {
00246     ( *git ).insert( key, evalue );
00247     changed = TRUE;
00248     }
00249 }
00250 
00256 void KateConfig::writeEntry( const QString &key, int num )
00257 {
00258     QString s;
00259     s.setNum( num );
00260     writeEntry( key, s );
00261 }
00262 
00263 void KateConfig::writeEntry( const QString &key, unsigned int num )
00264 {
00265     QString s;
00266     s.setNum( num );
00267     writeEntry( key, s );
00268 }
00269 
00270 #ifdef Q_HAS_BOOL_TYPE
00271 
00277 void KateConfig::writeEntry( const QString &key, bool b )
00278 {
00279     QString s;
00280     s.setNum( ( int )b );
00281     writeEntry( key, s );
00282 }
00283 #endif
00284 
00291 void KateConfig::writeEntry( const QString &key, const QStringList &lst, const QChar &sep )
00292 {
00293     QString s;
00294     QStringList::ConstIterator it = lst.begin();
00295     for ( ; it != lst.end(); ++it )
00296     s += *it + sep;
00297     writeEntry( key, s );
00298 }
00299 
00300 void KateConfig::writeEntry( const QString &key, const QColor &val )
00301 {
00302     QStringList l;
00303     l.append( QString().setNum(val.red()) );
00304     l.append( QString().setNum(val.green()) );
00305     l.append( QString().setNum(val.blue()) );
00306 
00307     writeEntry( key, l, QChar(',') );
00308 }
00309 
00310 void KateConfig::writeEntry( const QString &key, const QFont &val )
00311 {
00312     QStringList l;
00313     l.append( val.family() );
00314     l.append( QString().setNum(val.pointSize()) );
00315     l.append( QString().setNum(val.weight()) );
00316     l.append( QString().setNum((int)val.italic()) );
00317     l.append( QString().setNum((int)val.charSet()) );
00318 
00319     writeEntry( key, l, QChar(',') );
00320 }
00321 
00327 void KateConfig::removeEntry( const QString &key )
00328 {
00329     if ( git == groups.end() ) {
00330     owarn << "no group set" << oendl;
00331     return;
00332     }
00333     ( *git ).remove( key );
00334     changed = TRUE;
00335 }
00336 
00359 QString KateConfig::readEntry( const QString &key, const QString &deflt )
00360 {
00361     QString res = readEntryDirect( key+"["+lang+"]" );
00362     if ( !res.isNull() )
00363     return res;
00364     if ( !glang.isEmpty() ) {
00365     res = readEntryDirect( key+"["+glang+"]" );
00366     if ( !res.isNull() )
00367         return res;
00368     }
00369     return readEntryDirect( key, deflt );
00370 }
00371 
00382 QString KateConfig::readEntryCrypt( const QString &key, const QString &deflt )
00383 {
00384     QString res = readEntryDirect( key+"["+lang+"]" );
00385     if ( res.isNull() && glang.isEmpty() )
00386     res = readEntryDirect( key+"["+glang+"]" );
00387     if ( res.isNull() )
00388     res = readEntryDirect( key, QString::null );
00389     if ( res.isNull() )
00390     return deflt;
00391     return decipher(res);
00392 }
00393 
00403 QString KateConfig::readEntryDirect( const QString &key, const QString &deflt )
00404 {
00405     if ( git == groups.end() ) {
00406     //owarn << "no group set" << oendl;
00407     return deflt;
00408     }
00409     KateConfigGroup::ConstIterator it = ( *git ).find( key );
00410     if ( it != ( *git ).end() )
00411     return *it;
00412     else
00413     return deflt;
00414 }
00415 
00425 int KateConfig::readNumEntry( const QString &key, int deflt )
00426 {
00427     QString s = readEntry( key );
00428     if ( s.isEmpty() )
00429     return deflt;
00430     else
00431     return s.toInt();
00432 }
00433 
00443 bool KateConfig::readBoolEntry( const QString &key, bool deflt )
00444 {
00445     QString s = readEntry( key );
00446     if ( s.isEmpty() )
00447     return deflt;
00448     else
00449     return (bool)s.toInt();
00450 }
00451 
00461 QStringList KateConfig::readListEntry( const QString &key, const QChar &sep )
00462 {
00463     QString s = readEntry( key );
00464     if ( s.isEmpty() )
00465     return QStringList();
00466     else
00467     return QStringList::split( sep, s );
00468 }
00469 
00470 QColor KateConfig::readColorEntry( const QString &key, const QColor &def ) const
00471 {
00472     QStringList list = readListEntry(key, QChar(','));
00473     if( list.count() != 3 )
00474         return def;
00475 
00476     return QColor(list[0].toInt(), list[1].toInt(), list[2].toInt());
00477 }
00478 
00479 QFont KateConfig::readFontEntry( const QString &key, const QFont &def ) const
00480 {
00481     QStringList list = readListEntry(key, QChar(','));
00482     if( list.count() != 5 )
00483         return def;
00484 
00485     return QFont(list[0], list[1].toInt(), list[2].toInt(), (bool)list[3].toInt(), (QFont::CharSet)list[4].toInt());
00486 }
00487 
00488 QValueList<int> KateConfig::readIntListEntry( const QString &key ) const
00489 {
00490     QString s = readEntry( key );
00491     QValueList<int> il;
00492     if ( s.isEmpty() )
00493     return il;
00494 
00495     QStringList l = QStringList::split( QChar(','), s );
00496 
00497     QStringList::Iterator l_it;
00498     for( l_it = l.begin(); l_it != l.end(); ++l_it )
00499         il.append( (*l_it).toInt() );
00500     return il;
00501 }
00502 
00506 void KateConfig::clearGroup()
00507 {
00508     if ( git == groups.end() ) {
00509     owarn << "no group set" << oendl;
00510     return;
00511     }
00512     if ( !(*git).isEmpty() ) {
00513     ( *git ).clear();
00514     changed = TRUE;
00515     }
00516 }
00517 
00521 void KateConfig::write( const QString &fn )
00522 {
00523     QString strNewFile;
00524     if ( !fn.isEmpty() )
00525     filename = fn;
00526     strNewFile = filename + ".new";
00527 
00528     QFile f( strNewFile );
00529     if ( !f.open( IO_WriteOnly|IO_Raw ) ) {
00530     owarn << "could not open for writing `" << strNewFile << "'" << oendl;
00531     git = groups.end();
00532     return;
00533     }
00534 
00535     QString str;
00536     QCString cstr;
00537     QMap< QString, KateConfigGroup >::Iterator g_it = groups.begin();
00538 
00539     for ( ; g_it != groups.end(); ++g_it ) {
00540     str += "[" + g_it.key() + "]\n";
00541     KateConfigGroup::Iterator e_it = ( *g_it ).begin();
00542     for ( ; e_it != ( *g_it ).end(); ++e_it )
00543         str += e_it.key() + " = " + *e_it + "\n";
00544     }
00545     cstr = str.utf8();
00546 
00547     int total_length;
00548     total_length = f.writeBlock( cstr.data(), cstr.length() );
00549     if ( total_length != int(cstr.length()) ) {
00550     QMessageBox::critical( 0, QObject::tr("Out of Space"),
00551                    QObject::tr("There was a problem creating\nKateConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") );
00552     f.close();
00553     QFile::remove( strNewFile );
00554     return;
00555     }
00556 
00557     f.close();
00558     // now rename the file...
00559     if ( rename( strNewFile, filename ) < 0 ) {
00560     owarn << "problem renaming the file " << strNewFile.latin1() << " to " << filename.latin1() << oendl;
00561     QFile::remove( strNewFile );
00562     }
00563 }
00564 
00568 bool KateConfig::isValid() const
00569 {
00570     return groups.end() != git;
00571 }
00572 
00576 void KateConfig::read()
00577 {
00578     changed = FALSE;
00579 
00580     if ( !QFileInfo( filename ).exists() ) {
00581     git = groups.end();
00582     return;
00583     }
00584 
00585     QFile f( filename );
00586     if ( !f.open( IO_ReadOnly ) ) {
00587     git = groups.end();
00588     return;
00589     }
00590 
00591     QTextStream s( &f );
00592 #if QT_VERSION <= 230 && defined(QT_NO_CODECS)
00593     // The below should work, but doesn't in Qt 2.3.0
00594     s.setCodec( QTextCodec::codecForMib( 106 ) );
00595 #else
00596     s.setEncoding( QTextStream::UnicodeUTF8 );
00597 #endif
00598 
00599     QStringList list = QStringList::split('\n', s.read() );
00600     f.close();
00601 
00602     for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
00603         if ( !parse( *it ) ) {
00604             git = groups.end();
00605             return;
00606         }
00607     }
00608 }
00609 
00613 bool KateConfig::parse( const QString &l )
00614 {
00615     QString line = l.stripWhiteSpace();
00616 
00617     if ( line [0] == QChar ( '#' ))
00618         return true; // ignore comments
00619 
00620     if ( line[ 0 ] == QChar( '[' ) ) {
00621     QString gname = line;
00622     gname = gname.remove( 0, 1 );
00623     if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) )
00624         gname = gname.remove( gname.length() - 1, 1 );
00625     git = groups.insert( gname, KateConfigGroup() );
00626     } else if ( !line.isEmpty() ) {
00627     if ( git == groups.end() )
00628         return FALSE;
00629     int eq = line.find( '=' );
00630     if ( eq == -1 )
00631         return FALSE;
00632     QString key = line.left(eq).stripWhiteSpace();
00633     QString value = line.mid(eq+1).stripWhiteSpace();
00634     ( *git ).insert( key, value );
00635     }
00636     return TRUE;
00637 }

Generated on Sat Nov 5 16:17:11 2005 for OPIE by  doxygen 1.4.2