libtdepim

tdeconfigpropagator.cpp
1 /*
2  This file is part of libtdepim.
3 
4  Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "tdeconfigpropagator.h"
23 
24 #include <kdebug.h>
25 #include <tdeconfig.h>
26 #include <tdeconfigskeleton.h>
27 #include <kstandarddirs.h>
28 #include <kstringhandler.h>
29 #include <tdelocale.h>
30 
31 #include <tqfile.h>
32 #include <tqstringlist.h>
33 
34 TDEConfigPropagator::Change::~Change()
35 {
36 }
37 
38 TDEConfigPropagator::ChangeConfig::ChangeConfig()
39  : TDEConfigPropagator::Change( i18n("Change Config Value") ),
40  hideValue( false )
41 {
42 }
43 
44 TQString TDEConfigPropagator::ChangeConfig::arg1() const
45 {
46  return file + "/" + group + "/" + name;
47 }
48 
49 TQString TDEConfigPropagator::ChangeConfig::arg2() const
50 {
51  if ( hideValue ) return "*";
52  else return value;
53 }
54 
55 void TDEConfigPropagator::ChangeConfig::apply()
56 {
57  TDEConfig cfg( file );
58  cfg.setGroup( group );
59  cfg.writeEntry( name, value );
60 
61  cfg.sync();
62 }
63 
64 TDEConfigPropagator::TDEConfigPropagator()
65  : mSkeleton( 0 )
66 {
67  init();
68 }
69 
70 TDEConfigPropagator::TDEConfigPropagator( TDEConfigSkeleton *skeleton,
71  const TQString &kcfgFile )
72  : mSkeleton( skeleton ), mKcfgFile( kcfgFile )
73 {
74  init();
75 
76  readKcfgFile();
77 }
78 
79 void TDEConfigPropagator::init()
80 {
81  mChanges.setAutoDelete( true );
82 }
83 
84 void TDEConfigPropagator::readKcfgFile()
85 {
86  TQString filename = locate( "kcfg", mKcfgFile );
87  if ( filename.isEmpty() ) {
88  kdError() << "Unable to find kcfg file '" << mKcfgFile << "'" << endl;
89  return;
90  }
91 
92  TQFile input( filename );
93  TQDomDocument doc;
94  TQString errorMsg;
95  int errorRow;
96  int errorCol;
97  if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
98  kdError() << "Parse error in " << mKcfgFile << ", line " << errorRow << ", col " << errorCol << ": " << errorMsg << endl;
99  return;
100  }
101 
102  TQDomElement cfgElement = doc.documentElement();
103 
104  if ( cfgElement.isNull() ) {
105  kdError() << "No document in kcfg file" << endl;
106  return;
107  }
108 
109  mRules.clear();
110 
111  TQDomNode n;
112  for ( n = cfgElement.firstChild(); !n.isNull(); n = n.nextSibling() ) {
113  TQDomElement e = n.toElement();
114 
115  TQString tag = e.tagName();
116 
117  if ( tag == "propagation" ) {
118  Rule rule = parsePropagation( e );
119  mRules.append( rule );
120  } else if ( tag == "condition" ) {
121  Condition condition = parseCondition( e );
122  TQDomNode n2;
123  for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
124  TQDomElement e2 = n2.toElement();
125  if ( e2.tagName() == "propagation" ) {
126  Rule rule = parsePropagation( e2 );
127  rule.condition = condition;
128  mRules.append( rule );
129  } else {
130  kdError() << "Unknow tag: " << e2.tagName() << endl;
131  }
132  }
133  }
134  }
135 }
136 
137 TDEConfigPropagator::Rule TDEConfigPropagator::parsePropagation( const TQDomElement &e )
138 {
139  Rule r;
140 
141  TQString source = e.attribute( "source" );
142  parseConfigEntryPath( source, r.sourceFile, r.sourceGroup, r.sourceEntry );
143 
144  TQString target = e.attribute( "target" );
145  parseConfigEntryPath( target, r.targetFile, r.targetGroup, r.targetEntry );
146 
147  r.hideValue = e.hasAttribute( "hidevalue" ) &&
148  e.attribute( "hidevalue" ) == "true";
149 
150  return r;
151 }
152 
153 void TDEConfigPropagator::parseConfigEntryPath( const TQString &path,
154  TQString &file,
155  TQString &group,
156  TQString &entry )
157 {
158  TQStringList p = TQStringList::split( "/", path );
159 
160  if ( p.count() != 3 ) {
161  kdError() << "Path has to be of form file/group/entry" << endl;
162  file = TQString();
163  group = TQString();
164  entry = TQString();
165  return;
166  }
167 
168  file = p[ 0 ];
169  group = p[ 1 ];
170  entry = p[ 2 ];
171 
172  return;
173 }
174 
175 TDEConfigPropagator::Condition TDEConfigPropagator::parseCondition( const TQDomElement &e )
176 {
177  Condition c;
178 
179  TQString key = e.attribute( "key" );
180 
181  parseConfigEntryPath( key, c.file, c.group, c.key );
182 
183  c.value = e.attribute( "value" );
184 
185  c.isValid = true;
186 
187  return c;
188 }
189 
190 void TDEConfigPropagator::commit()
191 {
192  updateChanges();
193 
194  Change *c;
195  for( c = mChanges.first(); c; c = mChanges.next() ) {
196  c->apply();
197  }
198 }
199 
200 TDEConfigSkeletonItem *TDEConfigPropagator::findItem( const TQString &group,
201  const TQString &name )
202 {
203 // kdDebug() << "TDEConfigPropagator::findItem()" << endl;
204 
205  if ( !mSkeleton ) return 0;
206 
207  TDEConfigSkeletonItem::List items = mSkeleton->items();
208  TDEConfigSkeletonItem::List::ConstIterator it;
209  for( it = items.begin(); it != items.end(); ++it ) {
210 // kdDebug() << " Item: " << (*it)->name() << " Type: "
211 // << (*it)->property().typeName() << endl;
212  if ( (*it)->group() == group && (*it)->name() == name ) {
213  break;
214  }
215  }
216  if ( it == items.end() ) return 0;
217  else return *it;
218 }
219 
220 TQString TDEConfigPropagator::itemValueAsString( TDEConfigSkeletonItem *item )
221 {
222  TQVariant p = item->property();
223 
224  if ( p.type() == TQVariant::Bool ) {
225  if ( p.toBool() ) return "true";
226  else return "false";
227  }
228 
229  return p.toString();
230 }
231 
232 void TDEConfigPropagator::updateChanges()
233 {
234  mChanges.clear();
235 
236  Rule::List::ConstIterator it;
237  for( it = mRules.begin(); it != mRules.end(); ++it ) {
238  Rule r = *it;
239  Condition c = r.condition;
240  if ( c.isValid ) {
241  TDEConfigSkeletonItem *item = findItem( c.group, c.key );
242  kdDebug() << "Item " << c.group << "/" << c.key << ":" << endl;
243  if ( !item ) {
244  kdError() << " Item not found." << endl;
245  } else {
246  TQString value = itemValueAsString( item );
247  kdDebug() << " Value: " << value << endl;
248  if ( value != c.value ) {
249  continue;
250  }
251  }
252  }
253 
254  TDEConfigSkeletonItem *item = findItem( r.sourceGroup, r.sourceEntry );
255  if ( !item ) {
256  kdError() << "Item " << r.sourceGroup << "/" << r.sourceEntry
257  << " not found." << endl;
258  continue;
259  }
260  TQString value = itemValueAsString( item );
261 
262  TDEConfig target( r.targetFile );
263  target.setGroup( r.targetGroup );
264  TQString targetValue = target.readEntry( r.targetEntry );
265  if ( r.hideValue ) targetValue = KStringHandler::obscure( targetValue );
266  if ( targetValue != value ) {
267  ChangeConfig *change = new ChangeConfig();
268  change->file = r.targetFile;
269  change->group = r.targetGroup;
270  change->name = r.targetEntry;
271  if ( r.hideValue ) value = KStringHandler::obscure( value );
272  change->value = value;
273  change->hideValue = r.hideValue;
274  mChanges.append( change );
275  }
276  }
277 
278  addCustomChanges( mChanges );
279 }
280 
281 TDEConfigPropagator::Change::List TDEConfigPropagator::changes()
282 {
283  return mChanges;
284 }
285 
286 TDEConfigPropagator::Rule::List TDEConfigPropagator::rules()
287 {
288  return mRules;
289 }