tdeconfigpropagator.cpp
00001 /* 00002 This file is part of libtdepim. 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 "tdeconfigpropagator.h" 00023 00024 #include <kdebug.h> 00025 #include <tdeconfig.h> 00026 #include <tdeconfigskeleton.h> 00027 #include <kstandarddirs.h> 00028 #include <kstringhandler.h> 00029 #include <tdelocale.h> 00030 00031 #include <tqfile.h> 00032 #include <tqstringlist.h> 00033 00034 TDEConfigPropagator::Change::~Change() 00035 { 00036 } 00037 00038 TDEConfigPropagator::ChangeConfig::ChangeConfig() 00039 : TDEConfigPropagator::Change( i18n("Change Config Value") ), 00040 hideValue( false ) 00041 { 00042 } 00043 00044 TQString TDEConfigPropagator::ChangeConfig::arg1() const 00045 { 00046 return file + "/" + group + "/" + name; 00047 } 00048 00049 TQString TDEConfigPropagator::ChangeConfig::arg2() const 00050 { 00051 if ( hideValue ) return "*"; 00052 else return value; 00053 } 00054 00055 void TDEConfigPropagator::ChangeConfig::apply() 00056 { 00057 TDEConfig cfg( file ); 00058 cfg.setGroup( group ); 00059 cfg.writeEntry( name, value ); 00060 00061 cfg.sync(); 00062 } 00063 00064 TDEConfigPropagator::TDEConfigPropagator() 00065 : mSkeleton( 0 ) 00066 { 00067 init(); 00068 } 00069 00070 TDEConfigPropagator::TDEConfigPropagator( TDEConfigSkeleton *skeleton, 00071 const TQString &kcfgFile ) 00072 : mSkeleton( skeleton ), mKcfgFile( kcfgFile ) 00073 { 00074 init(); 00075 00076 readKcfgFile(); 00077 } 00078 00079 void TDEConfigPropagator::init() 00080 { 00081 mChanges.setAutoDelete( true ); 00082 } 00083 00084 void TDEConfigPropagator::readKcfgFile() 00085 { 00086 TQString filename = locate( "kcfg", mKcfgFile ); 00087 if ( filename.isEmpty() ) { 00088 kdError() << "Unable to find kcfg file '" << mKcfgFile << "'" << endl; 00089 return; 00090 } 00091 00092 TQFile input( filename ); 00093 TQDomDocument doc; 00094 TQString 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 TQDomElement 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 TQDomNode n; 00112 for ( n = cfgElement.firstChild(); !n.isNull(); n = n.nextSibling() ) { 00113 TQDomElement e = n.toElement(); 00114 00115 TQString 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 TQDomNode n2; 00123 for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) { 00124 TQDomElement 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 TDEConfigPropagator::Rule TDEConfigPropagator::parsePropagation( const TQDomElement &e ) 00138 { 00139 Rule r; 00140 00141 TQString source = e.attribute( "source" ); 00142 parseConfigEntryPath( source, r.sourceFile, r.sourceGroup, r.sourceEntry ); 00143 00144 TQString 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 TDEConfigPropagator::parseConfigEntryPath( const TQString &path, 00154 TQString &file, 00155 TQString &group, 00156 TQString &entry ) 00157 { 00158 TQStringList p = TQStringList::split( "/", path ); 00159 00160 if ( p.count() != 3 ) { 00161 kdError() << "Path has to be of form file/group/entry" << endl; 00162 file = TQString(); 00163 group = TQString(); 00164 entry = TQString(); 00165 return; 00166 } 00167 00168 file = p[ 0 ]; 00169 group = p[ 1 ]; 00170 entry = p[ 2 ]; 00171 00172 return; 00173 } 00174 00175 TDEConfigPropagator::Condition TDEConfigPropagator::parseCondition( const TQDomElement &e ) 00176 { 00177 Condition c; 00178 00179 TQString 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 TDEConfigPropagator::commit() 00191 { 00192 updateChanges(); 00193 00194 Change *c; 00195 for( c = mChanges.first(); c; c = mChanges.next() ) { 00196 c->apply(); 00197 } 00198 } 00199 00200 TDEConfigSkeletonItem *TDEConfigPropagator::findItem( const TQString &group, 00201 const TQString &name ) 00202 { 00203 // kdDebug() << "TDEConfigPropagator::findItem()" << endl; 00204 00205 if ( !mSkeleton ) return 0; 00206 00207 TDEConfigSkeletonItem::List items = mSkeleton->items(); 00208 TDEConfigSkeletonItem::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 TQString TDEConfigPropagator::itemValueAsString( TDEConfigSkeletonItem *item ) 00221 { 00222 TQVariant p = item->property(); 00223 00224 if ( p.type() == TQVariant::Bool ) { 00225 if ( p.toBool() ) return "true"; 00226 else return "false"; 00227 } 00228 00229 return p.toString(); 00230 } 00231 00232 void TDEConfigPropagator::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 TDEConfigSkeletonItem *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 TQString value = itemValueAsString( item ); 00247 kdDebug() << " Value: " << value << endl; 00248 if ( value != c.value ) { 00249 continue; 00250 } 00251 } 00252 } 00253 00254 TDEConfigSkeletonItem *item = findItem( r.sourceGroup, r.sourceEntry ); 00255 if ( !item ) { 00256 kdError() << "Item " << r.sourceGroup << "/" << r.sourceEntry 00257 << " not found." << endl; 00258 continue; 00259 } 00260 TQString value = itemValueAsString( item ); 00261 00262 TDEConfig target( r.targetFile ); 00263 target.setGroup( r.targetGroup ); 00264 TQString 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 TDEConfigPropagator::Change::List TDEConfigPropagator::changes() 00282 { 00283 return mChanges; 00284 } 00285 00286 TDEConfigPropagator::Rule::List TDEConfigPropagator::rules() 00287 { 00288 return mRules; 00289 }