00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define QTOPIA_INTERNAL_LANGLIST
00022 #include "kateconfig.h"
00023
00024
00025 #include <opie2/odebug.h>
00026 #include <qpe/global.h>
00027 using namespace Opie::Core;
00028
00029
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
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
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
00192
00193
00194
00195
00196
00197
00198
00199 static QString encipher(const QString& plain)
00200 {
00201
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
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
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
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;
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 }