00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kconfigdialogmanager.h"
00023
00024 #include <QComboBox>
00025 #include <QGroupBox>
00026 #include <QLabel>
00027 #include <QMetaObject>
00028 #include <QMetaProperty>
00029 #include <QTimer>
00030 #include <QRadioButton>
00031
00032
00033 #include <kconfigskeleton.h>
00034 #include <kdebug.h>
00035 #include <kglobal.h>
00036
00037 #include <assert.h>
00038
00039 typedef QHash<QString, QByteArray> MyHash;
00040 K_GLOBAL_STATIC(MyHash, s_propertyMap)
00041 K_GLOBAL_STATIC(MyHash, s_changedMap)
00042
00043 class KConfigDialogManager::Private {
00044
00045 public:
00046 Private(KConfigDialogManager *q) : q(q), insideGroupBox(false) { }
00047
00048 public:
00049 KConfigDialogManager *q;
00050
00054 KConfigSkeleton *m_conf;
00055
00059 QWidget *m_dialog;
00060
00061 QHash<QString, QWidget *> knownWidget;
00062 QHash<QString, QWidget *> buddyWidget;
00063 bool insideGroupBox : 1;
00064 bool trackChanges : 1;
00065 };
00066
00067 KConfigDialogManager::KConfigDialogManager(QWidget *parent, KConfigSkeleton *conf)
00068 : QObject(parent), d(new Private(this))
00069 {
00070 d->m_conf = conf;
00071 d->m_dialog = parent;
00072 init(true);
00073 }
00074
00075 KConfigDialogManager::~KConfigDialogManager()
00076 {
00077 delete d;
00078 }
00079
00080 void KConfigDialogManager::initMaps()
00081 {
00082 if ( s_propertyMap->isEmpty() ) {
00083 s_propertyMap->insert( "KButtonGroup", "current" );
00084 s_propertyMap->insert( "KColorButton", "color" );
00085 s_propertyMap->insert( "KColorCombo", "color" );
00086
00087
00088 }
00089
00090 if( s_changedMap->isEmpty() )
00091 {
00092
00093 s_changedMap->insert("QCheckBox", SIGNAL(stateChanged(int)));
00094 s_changedMap->insert("QPushButton", SIGNAL(clicked(bool)));
00095 s_changedMap->insert("QRadioButton", SIGNAL(toggled(bool)));
00096
00097
00098
00099 s_changedMap->insert("QGroupBox", SIGNAL(toggled(bool)));
00100 s_changedMap->insert("QComboBox", SIGNAL(activated (int)));
00101
00102
00103 s_changedMap->insert("QDateEdit", SIGNAL(dateChanged(const QDate &)));
00104 s_changedMap->insert("QTimeEdit", SIGNAL(timeChanged(const QTime &)));
00105 s_changedMap->insert("QDateTimeEdit", SIGNAL(dateTimeChanged(const QDateTime &)));
00106 s_changedMap->insert("QDial", SIGNAL(valueChanged (int)));
00107 s_changedMap->insert("QDoubleSpinBox", SIGNAL(valueChanged(double)));
00108 s_changedMap->insert("QLineEdit", SIGNAL(textChanged(const QString &)));
00109 s_changedMap->insert("QSlider", SIGNAL(valueChanged(int)));
00110 s_changedMap->insert("QSpinBox", SIGNAL(valueChanged(int)));
00111 s_changedMap->insert("QTextEdit", SIGNAL(textChanged()));
00112 s_changedMap->insert("QTextBrowser", SIGNAL(sourceChanged(const QString &)));
00113 s_changedMap->insert("QTabWidget", SIGNAL(currentChanged(int)));
00114
00115
00116 s_changedMap->insert( "KComboBox", SIGNAL(activated (int)));
00117 s_changedMap->insert( "KFontCombo", SIGNAL(activated (int)));
00118 s_changedMap->insert( "KFontRequester", SIGNAL(fontSelected(const QFont &)));
00119 s_changedMap->insert( "KFontChooser", SIGNAL(fontSelected(const QFont &)));
00120 s_changedMap->insert( "KHistoryCombo", SIGNAL(activated (int)));
00121 s_changedMap->insert( "KColorCombo", SIGNAL(activated (const QColor &)));
00122
00123 s_changedMap->insert( "KColorButton", SIGNAL(changed(const QColor &)));
00124 s_changedMap->insert( "KDatePicker", SIGNAL(dateSelected (QDate)));
00125 s_changedMap->insert( "KDateWidget", SIGNAL(changed (QDate)));
00126 s_changedMap->insert( "KDateTimeWidget", SIGNAL(valueChanged (const QDateTime &)));
00127 s_changedMap->insert( "KEditListBox", SIGNAL(changed()));
00128 s_changedMap->insert( "KListWidget", SIGNAL(itemSelectionChanged()));
00129 s_changedMap->insert( "KLineEdit", SIGNAL(textChanged(const QString &)));
00130 s_changedMap->insert( "KPasswordEdit", SIGNAL(textChanged(const QString &)));
00131 s_changedMap->insert( "KRestrictedLine", SIGNAL(textChanged(const QString &)));
00132 s_changedMap->insert( "KTextBrowser", SIGNAL(sourceChanged(const QString &)));
00133 s_changedMap->insert( "KTextEdit", SIGNAL(textChanged()));
00134 s_changedMap->insert( "KUrlRequester", SIGNAL(textChanged (const QString& )));
00135 s_changedMap->insert( "KUrlComboRequester", SIGNAL(textChanged (const QString& )));
00136 s_changedMap->insert( "KUrlComboBox", SIGNAL(urlActivated (const KUrl& )));
00137 s_changedMap->insert( "KIntNumInput", SIGNAL(valueChanged (int)));
00138 s_changedMap->insert( "KIntSpinBox", SIGNAL(valueChanged (int)));
00139 s_changedMap->insert( "KDoubleNumInput", SIGNAL(valueChanged (double)));
00140 s_changedMap->insert( "KButtonGroup", SIGNAL(changed(int)));
00141 }
00142 }
00143
00144 QHash<QString, QByteArray> *KConfigDialogManager::propertyMap()
00145 {
00146 initMaps();
00147 return s_propertyMap;
00148 }
00149
00150 QHash<QString, QByteArray> *KConfigDialogManager::changedMap()
00151 {
00152 initMaps();
00153 return s_changedMap;
00154 }
00155
00156 void KConfigDialogManager::init(bool trackChanges)
00157 {
00158 initMaps();
00159 d->trackChanges = trackChanges;
00160
00161
00162 (void) parseChildren(d->m_dialog, trackChanges);
00163 }
00164
00165 void KConfigDialogManager::addWidget(QWidget *widget)
00166 {
00167 (void) parseChildren(widget, true);
00168 }
00169
00170 void KConfigDialogManager::setupWidget(QWidget *widget, KConfigSkeletonItem *item)
00171 {
00172 QVariant minValue = item->minValue();
00173 if (minValue.isValid())
00174 {
00175
00176 if (widget->metaObject()->indexOfProperty("minValue") != -1)
00177 widget->setProperty("minValue", minValue);
00178 if (widget->metaObject()->indexOfProperty("minimum") != -1)
00179 widget->setProperty("minimum", minValue);
00180 }
00181 QVariant maxValue = item->maxValue();
00182 if (maxValue.isValid())
00183 {
00184
00185 if (widget->metaObject()->indexOfProperty("maxValue") != -1)
00186 widget->setProperty("maxValue", maxValue);
00187 if (widget->metaObject()->indexOfProperty("maximum") != -1)
00188 widget->setProperty("maximum", maxValue);
00189 }
00190
00191 if (widget->whatsThis().isEmpty())
00192 {
00193 QString whatsThis = item->whatsThis();
00194 if ( !whatsThis.isEmpty() )
00195 {
00196 widget->setWhatsThis(whatsThis );
00197 }
00198 }
00199
00200 if (widget->toolTip().isEmpty())
00201 {
00202 QString toolTip = item->toolTip();
00203 if ( !toolTip.isEmpty() )
00204 {
00205 widget->setToolTip(toolTip);
00206 }
00207 }
00208
00209 if(!item->isEqual( property(widget) ))
00210 setProperty( widget, item->property() );
00211 }
00212
00213 bool KConfigDialogManager::parseChildren(const QWidget *widget, bool trackChanges)
00214 {
00215 bool valueChanged = false;
00216 const QList<QObject*> listOfChildren = widget->children();
00217 if(listOfChildren.count()==0)
00218 return valueChanged;
00219
00220 foreach ( QObject *object, listOfChildren )
00221 {
00222 if(!object->isWidgetType())
00223 continue;
00224
00225 QWidget *childWidget = static_cast<QWidget *>(object);
00226
00227 QString widgetName = childWidget->objectName();
00228 bool bParseChildren = true;
00229 bool bSaveInsideGroupBox = d->insideGroupBox;
00230
00231 if (widgetName.startsWith("kcfg_"))
00232 {
00233
00234 QString configId = widgetName.mid(5);
00235 KConfigSkeletonItem *item = d->m_conf->findItem(configId);
00236 if (item)
00237 {
00238 d->knownWidget.insert(configId, childWidget);
00239
00240 setupWidget(childWidget, item);
00241
00242 if ( d->trackChanges ) {
00243 QHash<QString, QByteArray>::const_iterator changedIt = s_changedMap->constFind(childWidget->metaObject()->className());
00244
00245 if (changedIt == s_changedMap->constEnd())
00246 {
00247
00248
00249
00250
00251 if ( childWidget->metaObject()->superClass() )
00252 changedIt = s_changedMap->constFind(childWidget->metaObject()->superClass()->className());
00253 else
00254 changedIt = s_changedMap->constFind(0);
00255 }
00256
00257 if (changedIt == s_changedMap->constEnd())
00258 {
00259 kWarning(178) << "Don't know how to monitor widget '" << childWidget->metaObject()->className() << "' for changes!";
00260 }
00261 else
00262 {
00263 connect(childWidget, *changedIt,
00264 this, SIGNAL(widgetModified()));
00265
00266 QComboBox *cb = qobject_cast<QComboBox *>(childWidget);
00267 if (cb && cb->isEditable())
00268 connect(cb, SIGNAL(editTextChanged(const QString &)),
00269 this, SIGNAL(widgetModified()));
00270 }
00271 }
00272 QGroupBox *gb = qobject_cast<QGroupBox *>(childWidget);
00273 if (!gb)
00274 bParseChildren = false;
00275 else
00276 d->insideGroupBox = true;
00277 }
00278 else
00279 {
00280 kWarning(178) << "A widget named '" << widgetName << "' was found but there is no setting named '" << configId << "'";
00281 assert(false);
00282 }
00283 }
00284 else if (QLabel *label = qobject_cast<QLabel*>(childWidget))
00285 {
00286 QWidget *buddy = label->buddy();
00287 if (!buddy)
00288 continue;
00289 QString buddyName = buddy->objectName();
00290 if (buddyName.startsWith("kcfg_"))
00291 {
00292
00293 QString configId = buddyName.mid(5);
00294 d->buddyWidget.insert(configId, childWidget);
00295 }
00296 }
00297 #ifndef NDEBUG
00298 else if (!widgetName.isEmpty() && d->trackChanges)
00299 {
00300 QHash<QString, QByteArray>::const_iterator changedIt = s_changedMap->constFind(childWidget->metaObject()->className());
00301 if (changedIt != s_changedMap->constEnd())
00302 {
00303 if ((!d->insideGroupBox || !qobject_cast<QRadioButton*>(childWidget)) &&
00304 !qobject_cast<QGroupBox*>(childWidget) &&!qobject_cast<QTabWidget*>(childWidget) )
00305 kDebug(178) << "Widget '" << widgetName << "' (" << childWidget->metaObject()->className() << ") remains unmanaged.";
00306 }
00307 }
00308 #endif
00309
00310 if(bParseChildren)
00311 {
00312
00313
00314 valueChanged |= parseChildren(childWidget, trackChanges);
00315 }
00316 d->insideGroupBox = bSaveInsideGroupBox;
00317 }
00318 return valueChanged;
00319 }
00320
00321 void KConfigDialogManager::updateWidgets()
00322 {
00323 bool changed = false;
00324 bool bSignalsBlocked = signalsBlocked();
00325 blockSignals(true);
00326
00327 QWidget *widget;
00328 QHashIterator<QString, QWidget *> it( d->knownWidget );
00329 while(it.hasNext()) {
00330 it.next();
00331 widget = it.value();
00332
00333 KConfigSkeletonItem *item = d->m_conf->findItem(it.key());
00334 if (!item)
00335 {
00336 kWarning(178) << "The setting '" << it.key() << "' has disappeared!";
00337 continue;
00338 }
00339
00340 if(!item->isEqual( property(widget) ))
00341 {
00342 setProperty( widget, item->property() );
00343
00344 changed = true;
00345 }
00346 if (item->isImmutable())
00347 {
00348 widget->setEnabled(false);
00349 QWidget *buddy = d->buddyWidget.value(it.key(), 0);
00350 if (buddy)
00351 buddy->setEnabled(false);
00352 }
00353 }
00354 blockSignals(bSignalsBlocked);
00355
00356 if (changed)
00357 QTimer::singleShot(0, this, SIGNAL(widgetModified()));
00358 }
00359
00360 void KConfigDialogManager::updateWidgetsDefault()
00361 {
00362 bool bUseDefaults = d->m_conf->useDefaults(true);
00363 updateWidgets();
00364 d->m_conf->useDefaults(bUseDefaults);
00365 }
00366
00367 void KConfigDialogManager::updateSettings()
00368 {
00369 bool changed = false;
00370
00371 QWidget *widget;
00372 QHashIterator<QString, QWidget *> it( d->knownWidget );
00373 while(it.hasNext()) {
00374 it.next();
00375 widget = it.value();
00376
00377 KConfigSkeletonItem *item = d->m_conf->findItem(it.key());
00378 if (!item) {
00379 kWarning(178) << "The setting '" << it.key() << "' has disappeared!";
00380 continue;
00381 }
00382
00383 QVariant fromWidget = property(widget);
00384 if(!item->isEqual( fromWidget )) {
00385 item->setProperty( fromWidget );
00386 changed = true;
00387 }
00388 }
00389 if (changed)
00390 {
00391 d->m_conf->writeConfig();
00392 emit settingsChanged();
00393 }
00394 }
00395
00396 QByteArray KConfigDialogManager::getUserProperty(const QWidget *widget) const
00397 {
00398 if (!s_propertyMap->contains(widget->metaObject()->className())) {
00399 const QMetaObject *metaObject = widget->metaObject();
00400 const QMetaProperty user = metaObject->userProperty();
00401 if ( user.isValid() ) {
00402 s_propertyMap->insert( widget->metaObject()->className(), user.name() );
00403
00404
00405 }
00406 else {
00407 return QByteArray();
00408 }
00409 }
00410 return s_propertyMap->value( widget->metaObject()->className() );
00411 }
00412
00413 void KConfigDialogManager::setProperty(QWidget *w, const QVariant &v)
00414 {
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 QByteArray userproperty = getUserProperty( w );
00425 if ( userproperty.isEmpty() ) {
00426 QComboBox *cb = qobject_cast<QComboBox *>(w);
00427 if (cb) {
00428 if ( cb->isEditable() )
00429 {
00430 int i = cb->findText(v.toString());
00431 if (i != -1)
00432 cb->setCurrentIndex(i);
00433 else
00434 cb->setEditText(v.toString());
00435 } else {
00436 cb->setCurrentIndex( v.toInt() );
00437 }
00438 return;
00439 }
00440 kWarning(178) << w->metaObject()->className() << " widget not handled!";
00441 return;
00442 }
00443 w->setProperty( userproperty, v );
00444 }
00445
00446 QVariant KConfigDialogManager::property(QWidget *w) const
00447 {
00448
00449
00450
00451
00452 QByteArray userproperty = getUserProperty( w );
00453 if ( userproperty.isEmpty() ) {
00454 QComboBox *cb = qobject_cast<QComboBox *>(w);
00455 if (cb) {
00456 if ( cb->isEditable() )
00457 return QVariant(cb->currentText());
00458 else
00459 return QVariant(cb->currentIndex());
00460 }
00461 kWarning(178) << w->metaObject()->className() << " widget not handled!";
00462 return QVariant();
00463 }
00464
00465 return w->property( userproperty );
00466 }
00467
00468 bool KConfigDialogManager::hasChanged() const
00469 {
00470 QWidget *widget;
00471 QHashIterator<QString, QWidget *> it( d->knownWidget) ;
00472 while(it.hasNext()) {
00473 it.next();
00474 widget = it.value();
00475
00476 KConfigSkeletonItem *item = d->m_conf->findItem(it.key());
00477 if (!item) {
00478 kWarning(178) << "The setting '" << it.key() << "' has disappeared!";
00479 continue;
00480 }
00481
00482 if(!item->isEqual( property(widget) )) {
00483
00484 return true;
00485 }
00486 }
00487 return false;
00488 }
00489
00490 bool KConfigDialogManager::isDefault() const
00491 {
00492 bool bUseDefaults = d->m_conf->useDefaults(true);
00493 bool result = !hasChanged();
00494 d->m_conf->useDefaults(bUseDefaults);
00495 return result;
00496 }
00497
00498 #include "kconfigdialogmanager.moc"
00499