libkdepim

kconfigpropagator.cpp

00001 /*
00002     This file is part of libkdepim.
00003 
00004     Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "kconfigpropagator.h"
00023 
00024 #include <kdebug.h>
00025 #include <kconfig.h>
00026 #include <kconfigskeleton.h>
00027 #include <kstandarddirs.h>
00028 #include <kstringhandler.h>
00029 #include <klocale.h>
00030 
00031 #include <qfile.h>
00032 #include <qstringlist.h>
00033 
00034 KConfigPropagator::Change::~Change()
00035 {
00036 }
00037 
00038 KConfigPropagator::ChangeConfig::ChangeConfig()
00039   : KConfigPropagator::Change( i18n("Change Config Value") ),
00040     hideValue( false )
00041 {
00042 }
00043 
00044 QString KConfigPropagator::ChangeConfig::arg1() const
00045 {
00046   return file + "/" + group + "/" + name;
00047 }
00048 
00049 QString KConfigPropagator::ChangeConfig::arg2() const
00050 {
00051   if ( hideValue ) return "*";
00052   else return value;
00053 }
00054 
00055 void KConfigPropagator::ChangeConfig::apply()
00056 {
00057   KConfig cfg( file );
00058   cfg.setGroup( group );
00059   cfg.writeEntry( name, value );
00060 
00061   cfg.sync();
00062 }
00063 
00064 KConfigPropagator::KConfigPropagator()
00065   : mSkeleton( 0 )
00066 {
00067   init();
00068 }
00069 
00070 KConfigPropagator::KConfigPropagator( KConfigSkeleton *skeleton,
00071                                       const QString &kcfgFile )
00072   : mSkeleton( skeleton ), mKcfgFile( kcfgFile )
00073 {
00074   init();
00075 
00076   readKcfgFile();
00077 }
00078 
00079 void KConfigPropagator::init()
00080 {
00081   mChanges.setAutoDelete( true );
00082 }
00083 
00084 void KConfigPropagator::readKcfgFile()
00085 {
00086   QString filename = locate( "kcfg", mKcfgFile );
00087   if ( filename.isEmpty() ) {
00088     kdError() << "Unable to find kcfg file '" << mKcfgFile << "'" << endl;
00089     return;
00090   }
00091 
00092   QFile input( filename );
00093   QDomDocument doc;
00094   QString errorMsg;
00095   int errorRow;
00096   int errorCol;
00097   if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
00098     kdError() << "Parse error in " << mKcfgFile << ", line " << errorRow << ", col " << errorCol << ": " << errorMsg << endl;
00099     return;
00100   }
00101 
00102   QDomElement cfgElement = doc.documentElement();
00103 
00104   if ( cfgElement.isNull() ) {
00105     kdError() << "No document in kcfg file" << endl;
00106     return;
00107   }
00108 
00109   mRules.clear();
00110 
00111   QDomNode n;
00112   for ( n = cfgElement.firstChild(); !n.isNull(); n = n.nextSibling() ) {
00113     QDomElement e = n.toElement();
00114 
00115     QString tag = e.tagName();
00116 
00117     if ( tag == "propagation" ) {
00118       Rule rule = parsePropagation( e );
00119       mRules.append( rule );
00120     } else if ( tag == "condition" ) {
00121       Condition condition = parseCondition( e );
00122       QDomNode n2;
00123       for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
00124         QDomElement e2 = n2.toElement();
00125         if ( e2.tagName() == "propagation" ) {
00126           Rule rule = parsePropagation( e2 );
00127           rule.condition = condition;
00128           mRules.append( rule );
00129         } else {
00130           kdError() << "Unknow tag: " << e2.tagName() << endl;
00131         }
00132       }
00133     }
00134   }
00135 }
00136 
00137 KConfigPropagator::Rule KConfigPropagator::parsePropagation( const QDomElement &e )
00138 {
00139   Rule r;
00140 
00141   QString source = e.attribute( "source" );
00142   parseConfigEntryPath( source, r.sourceFile, r.sourceGroup, r.sourceEntry );
00143 
00144   QString target = e.attribute( "target" );
00145   parseConfigEntryPath( target, r.targetFile, r.targetGroup, r.targetEntry );
00146 
00147   r.hideValue = e.hasAttribute( "hidevalue" ) &&
00148                 e.attribute( "hidevalue" ) == "true";
00149 
00150   return r;
00151 }
00152 
00153 void KConfigPropagator::parseConfigEntryPath( const QString &path,
00154                                               QString &file,
00155                                               QString &group,
00156                                               QString &entry )
00157 {
00158   QStringList p = QStringList::split( "/", path );
00159 
00160   if ( p.count() != 3 ) {
00161     kdError() << "Path has to be of form file/group/entry" << endl;
00162     file = QString::null;
00163     group = QString::null;
00164     entry = QString::null;
00165     return;
00166   }
00167   
00168   file = p[ 0 ];
00169   group = p[ 1 ];  
00170   entry = p[ 2 ];
00171   
00172   return;
00173 }
00174 
00175 KConfigPropagator::Condition KConfigPropagator::parseCondition( const QDomElement &e )
00176 {
00177   Condition c;
00178   
00179   QString key = e.attribute( "key" );
00180   
00181   parseConfigEntryPath( key, c.file, c.group, c.key );
00182   
00183   c.value = e.attribute( "value" );
00184 
00185   c.isValid = true;
00186 
00187   return c;
00188 }
00189 
00190 void KConfigPropagator::commit()
00191 {
00192   updateChanges();
00193 
00194   Change *c;
00195   for( c = mChanges.first(); c; c = mChanges.next() ) {
00196     c->apply();
00197   }
00198 }
00199 
00200 KConfigSkeletonItem *KConfigPropagator::findItem( const QString &group,
00201                                                   const QString &name )
00202 {
00203 //  kdDebug() << "KConfigPropagator::findItem()" << endl;
00204 
00205   if ( !mSkeleton ) return 0;
00206 
00207   KConfigSkeletonItem::List items = mSkeleton->items();
00208   KConfigSkeletonItem::List::ConstIterator it;
00209   for( it = items.begin(); it != items.end(); ++it ) {
00210 //    kdDebug() << "  Item: " << (*it)->name() << "  Type: "
00211 //              << (*it)->property().typeName() << endl;
00212     if ( (*it)->group() == group && (*it)->name() == name ) {
00213       break;
00214     }
00215   }
00216   if ( it == items.end() ) return 0;
00217   else return *it;
00218 }
00219 
00220 QString KConfigPropagator::itemValueAsString( KConfigSkeletonItem *item )
00221 {
00222   QVariant p = item->property();
00223 
00224   if ( p.type() == QVariant::Bool ) {
00225     if ( p.toBool() ) return "true";
00226     else return "false";
00227   }
00228   
00229   return p.toString();
00230 }
00231 
00232 void KConfigPropagator::updateChanges()
00233 {
00234   mChanges.clear();
00235 
00236   Rule::List::ConstIterator it;
00237   for( it = mRules.begin(); it != mRules.end(); ++it ) {
00238     Rule r = *it;
00239     Condition c = r.condition;
00240     if ( c.isValid ) {
00241       KConfigSkeletonItem *item = findItem( c.group, c.key );
00242       kdDebug() << "Item " << c.group << "/" << c.key << ":" << endl;
00243       if ( !item ) {
00244         kdError() << "  Item not found." << endl;
00245       } else {
00246         QString value = itemValueAsString( item );
00247         kdDebug() << "  Value: " << value << endl;
00248         if ( value != c.value ) {
00249           continue;
00250         }
00251       }
00252     }
00253 
00254     KConfigSkeletonItem *item = findItem( r.sourceGroup, r.sourceEntry );
00255     if ( !item ) {
00256       kdError() << "Item " << r.sourceGroup << "/" << r.sourceEntry 
00257                 << " not found." << endl;
00258       continue;
00259     }
00260     QString value = itemValueAsString( item );
00261 
00262     KConfig target( r.targetFile );
00263     target.setGroup( r.targetGroup );
00264     QString targetValue = target.readEntry( r.targetEntry );
00265     if ( r.hideValue ) targetValue = KStringHandler::obscure( targetValue );
00266     if ( targetValue != value ) {
00267       ChangeConfig *change = new ChangeConfig();
00268       change->file = r.targetFile;
00269       change->group = r.targetGroup;
00270       change->name = r.targetEntry;
00271       if ( r.hideValue ) value = KStringHandler::obscure( value );
00272       change->value = value;
00273       change->hideValue = r.hideValue;
00274       mChanges.append( change );
00275     }
00276   }
00277 
00278   addCustomChanges( mChanges );
00279 }
00280 
00281 KConfigPropagator::Change::List KConfigPropagator::changes()
00282 {
00283   return mChanges;
00284 }
00285 
00286 KConfigPropagator::Rule::List KConfigPropagator::rules()
00287 {
00288   return mRules;
00289 }
KDE Home | KDE Accessibility Home | Description of Access Keys