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 <tdestandarddirs.h>
28#include <kstringhandler.h>
29#include <tdelocale.h>
30
31#include <tqfile.h>
32#include <tqstringlist.h>
33
34TDEConfigPropagator::Change::~Change()
35{
36}
37
38TDEConfigPropagator::ChangeConfig::ChangeConfig()
39 : TDEConfigPropagator::Change( i18n("Change Config Value") ),
40 hideValue( false )
41{
42}
43
44TQString TDEConfigPropagator::ChangeConfig::arg1() const
45{
46 return file + "/" + group + "/" + name;
47}
48
49TQString TDEConfigPropagator::ChangeConfig::arg2() const
50{
51 if ( hideValue ) return "*";
52 else return value;
53}
54
55void TDEConfigPropagator::ChangeConfig::apply()
56{
57 TDEConfig cfg( file );
58 cfg.setGroup( group );
59 cfg.writeEntry( name, value );
60
61 cfg.sync();
62}
63
64TDEConfigPropagator::TDEConfigPropagator()
65 : mSkeleton( 0 )
66{
67 init();
68}
69
70TDEConfigPropagator::TDEConfigPropagator( TDEConfigSkeleton *skeleton,
71 const TQString &kcfgFile )
72 : mSkeleton( skeleton ), mKcfgFile( kcfgFile )
73{
74 init();
75
76 readKcfgFile();
77}
78
79void TDEConfigPropagator::init()
80{
81 mChanges.setAutoDelete( true );
82}
83
84void 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
137TDEConfigPropagator::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
153void 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
175TDEConfigPropagator::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
190void TDEConfigPropagator::commit()
191{
192 updateChanges();
193
194 Change *c;
195 for( c = mChanges.first(); c; c = mChanges.next() ) {
196 c->apply();
197 }
198}
199
200TDEConfigSkeletonItem *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
220TQString 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
232void 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
281TDEConfigPropagator::Change::List TDEConfigPropagator::changes()
282{
283 return mChanges;
284}
285
286TDEConfigPropagator::Rule::List TDEConfigPropagator::rules()
287{
288 return mRules;
289}