Build with non-standard boost locations.
[kdepim.git] / wizards / kconfigpropagator.cpp
blob33b1f533e441c6d246bf3e1052025f75cc98575f
1 /*
2 This file is part of libkdepim.
4 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
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.
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.
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.
22 #include "kconfigpropagator.h"
24 #include <KConfig>
25 #include <KConfigSkeleton>
26 #include <KDebug>
27 #include <KLocale>
28 #include <KStandardDirs>
29 #include <KStringHandler>
31 #include <QFile>
32 #include <QStringList>
34 #include <boost/bind.hpp>
35 #include <algorithm>
37 KConfigPropagator::Change::~Change()
41 KConfigPropagator::ChangeConfig::ChangeConfig()
42 : KConfigPropagator::Change( i18n( "Change Config Value" ) ),
43 hideValue( false )
47 QString KConfigPropagator::ChangeConfig::arg1() const
49 return file + '/' + group + '/' + name;
52 QString KConfigPropagator::ChangeConfig::arg2() const
54 if ( hideValue ) {
55 return "*";
56 } else {
57 return value;
61 void KConfigPropagator::ChangeConfig::apply()
63 KConfig _cfg( file );
64 KConfigGroup cfg( &_cfg, group );
65 cfg.writeEntry( name, value );
67 cfg.sync();
70 KConfigPropagator::KConfigPropagator()
71 : mSkeleton( 0 )
73 init();
76 KConfigPropagator::KConfigPropagator( KConfigSkeleton *skeleton,
77 const QString &kcfgFile )
78 : mSkeleton( skeleton ), mKcfgFile( kcfgFile )
80 init();
82 readKcfgFile();
85 void KConfigPropagator::init()
89 void KConfigPropagator::readKcfgFile()
91 QString filename = KStandardDirs::locate( "kcfg", mKcfgFile );
92 if ( filename.isEmpty() ) {
93 kError() << "Unable to find kcfg file '" << mKcfgFile << "'";
94 return;
97 QFile input( filename );
98 QDomDocument doc;
99 QString errorMsg;
100 int errorRow;
101 int errorCol;
102 if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
103 kError() << "Parse error in" << mKcfgFile
104 << ", line" << errorRow
105 << ", col" << errorCol
106 << ":" << errorMsg;
107 return;
110 QDomElement cfgElement = doc.documentElement();
112 if ( cfgElement.isNull() ) {
113 kError() <<"No document in kcfg file";
114 return;
117 mRules.clear();
119 QDomNode n;
120 for ( n = cfgElement.firstChild(); !n.isNull(); n = n.nextSibling() ) {
121 QDomElement e = n.toElement();
123 QString tag = e.tagName();
125 if ( tag == "propagation" ) {
126 Rule rule = parsePropagation( e );
127 mRules.append( rule );
128 } else if ( tag == "condition" ) {
129 Condition condition = parseCondition( e );
130 QDomNode n2;
131 for ( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
132 QDomElement e2 = n2.toElement();
133 if ( e2.tagName() == "propagation" ) {
134 Rule rule = parsePropagation( e2 );
135 rule.condition = condition;
136 mRules.append( rule );
137 } else {
138 kError() <<"Unknow tag:" << e2.tagName();
145 KConfigPropagator::Rule KConfigPropagator::parsePropagation( const QDomElement &e )
147 Rule r;
149 QString source = e.attribute( "source" );
150 parseConfigEntryPath( source, r.sourceFile, r.sourceGroup, r.sourceEntry );
152 QString target = e.attribute( "target" );
153 parseConfigEntryPath( target, r.targetFile, r.targetGroup, r.targetEntry );
155 r.hideValue = e.hasAttribute( "hidevalue" ) &&
156 e.attribute( "hidevalue" ) == "true";
158 return r;
161 void KConfigPropagator::parseConfigEntryPath( const QString &path,
162 QString &file,
163 QString &group,
164 QString &entry )
166 QStringList p = path.split( '/' );
168 if ( p.count() != 3 ) {
169 kError() <<"Path has to be of form file/group/entry";
170 file.clear();
171 group.clear();
172 entry.clear();
173 return;
176 file = p[ 0 ];
177 group = p[ 1 ];
178 entry = p[ 2 ];
180 return;
183 KConfigPropagator::Condition KConfigPropagator::parseCondition( const QDomElement &e )
185 Condition c;
187 QString key = e.attribute( "key" );
189 parseConfigEntryPath( key, c.file, c.group, c.key );
191 c.value = e.attribute( "value" );
193 c.isValid = true;
195 return c;
198 void KConfigPropagator::commit()
200 updateChanges();
202 std::for_each( mChanges.begin(), mChanges.end(), boost::bind( &Change::apply, _1 ) );
205 KConfigSkeletonItem *KConfigPropagator::findItem( const QString &group,
206 const QString &name )
208 if ( !mSkeleton ) {
209 return 0;
212 KConfigSkeletonItem::List items = mSkeleton->items();
213 KConfigSkeletonItem::List::ConstIterator it;
214 for ( it = items.constBegin(); it != items.constEnd(); ++it ) {
215 if ( (*it)->group() == group && (*it)->name() == name ) {
216 break;
219 if ( it == items.constEnd() ) {
220 return 0;
221 } else {
222 return *it;
226 QString KConfigPropagator::itemValueAsString( KConfigSkeletonItem *item )
228 QVariant p = item->property();
230 if ( p.type() == QVariant::Bool ) {
231 if ( p.toBool() ) {
232 return "true";
233 } else {
234 return "false";
238 return p.toString();
241 void KConfigPropagator::updateChanges()
243 qDeleteAll( mChanges );
244 mChanges.clear();
246 Rule::List::ConstIterator it;
247 for ( it = mRules.constBegin(); it != mRules.constEnd(); ++it ) {
248 Rule r = *it;
249 Condition c = r.condition;
250 if ( c.isValid ) {
251 KConfigSkeletonItem *item = findItem( c.group, c.key );
252 kDebug() <<"Item" << c.group <<"/" << c.key <<":";
253 if ( !item ) {
254 kError() <<" Item not found.";
255 } else {
256 QString value = itemValueAsString( item );
257 kDebug() <<" Value:" << value;
258 if ( value != c.value ) {
259 continue;
264 KConfigSkeletonItem *item = findItem( r.sourceGroup, r.sourceEntry );
265 if ( !item ) {
266 kError() <<"Item" << r.sourceGroup <<"/" << r.sourceEntry
267 << "not found.";
268 continue;
270 QString value = itemValueAsString( item );
272 KConfig _target( r.targetFile );
273 KConfigGroup target( &_target, r.targetGroup );
274 QString targetValue = target.readEntry( r.targetEntry, QString() );
275 if ( r.hideValue ) {
276 targetValue = KStringHandler::obscure( targetValue );
278 if ( targetValue != value ) {
279 ChangeConfig *change = new ChangeConfig();
280 change->file = r.targetFile;
281 change->group = r.targetGroup;
282 change->name = r.targetEntry;
283 if ( r.hideValue ) {
284 value = KStringHandler::obscure( value );
286 change->value = value;
287 change->hideValue = r.hideValue;
288 mChanges.append( change );
292 addCustomChanges( mChanges );
295 KConfigPropagator::Change::List KConfigPropagator::changes() const
297 return mChanges;
300 KConfigPropagator::Rule::List KConfigPropagator::rules() const
302 return mRules;