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 <qbuttongroup.h>
00025 #include <qcombobox.h>
00026 #include <qlabel.h>
00027 #include <qmetaobject.h>
00028 #include <qobjectlist.h>
00029 #include <qsqlpropertymap.h>
00030 #include <qtimer.h>
00031 #include <qwhatsthis.h>
00032
00033 #include <kapplication.h>
00034 #include <kconfigskeleton.h>
00035 #include <kdebug.h>
00036 #include <kglobal.h>
00037
00038 #include <assert.h>
00039
00040 class KConfigDialogManager::Private {
00041
00042 public:
00043 Private() : insideGroupBox(false) { }
00044
00045 public:
00046 QDict<QWidget> knownWidget;
00047 QDict<QWidget> buddyWidget;
00048 bool insideGroupBox;
00049 };
00050
00051 KConfigDialogManager::KConfigDialogManager(QWidget *parent, KConfigSkeleton *conf, const char *name)
00052 : QObject(parent, name), m_conf(conf), m_dialog(parent)
00053 {
00054 d = new Private();
00055
00056 kapp->installKDEPropertyMap();
00057 propertyMap = QSqlPropertyMap::defaultMap();
00058
00059 init(true);
00060 }
00061
00062 KConfigDialogManager::~KConfigDialogManager()
00063 {
00064 delete d;
00065 }
00066
00067 void KConfigDialogManager::init(bool trackChanges)
00068 {
00069 if(trackChanges)
00070 {
00071
00072 changedMap.insert("QButton", SIGNAL(stateChanged(int)));
00073 changedMap.insert("QCheckBox", SIGNAL(stateChanged(int)));
00074 changedMap.insert("QPushButton", SIGNAL(stateChanged(int)));
00075 changedMap.insert("QRadioButton", SIGNAL(stateChanged(int)));
00076
00077
00078 changedMap.insert("QButtonGroup", SIGNAL(clicked(int)));
00079 changedMap.insert("QGroupBox", SIGNAL(toggled(bool)));
00080 changedMap.insert("QComboBox", SIGNAL(activated (int)));
00081
00082
00083 changedMap.insert("QDateEdit", SIGNAL(valueChanged(const QDate &)));
00084 changedMap.insert("QDateTimeEdit", SIGNAL(valueChanged(const QDateTime &)));
00085 changedMap.insert("QDial", SIGNAL(valueChanged (int)));
00086 changedMap.insert("QLineEdit", SIGNAL(textChanged(const QString &)));
00087 changedMap.insert("QSlider", SIGNAL(valueChanged(int)));
00088 changedMap.insert("QSpinBox", SIGNAL(valueChanged(int)));
00089 changedMap.insert("QTimeEdit", SIGNAL(valueChanged(const QTime &)));
00090 changedMap.insert("QTextEdit", SIGNAL(textChanged()));
00091 changedMap.insert("QTextBrowser", SIGNAL(sourceChanged(const QString &)));
00092 changedMap.insert("QMultiLineEdit", SIGNAL(textChanged()));
00093 changedMap.insert("QListBox", SIGNAL(selectionChanged()));
00094 changedMap.insert("QTabWidget", SIGNAL(currentChanged(QWidget *)));
00095
00096
00097 changedMap.insert( "KComboBox", SIGNAL(activated (int)));
00098 changedMap.insert( "KFontCombo", SIGNAL(activated (int)));
00099 changedMap.insert( "KFontRequester", SIGNAL(fontSelected(const QFont &)));
00100 changedMap.insert( "KFontChooser", SIGNAL(fontSelected(const QFont &)));
00101 changedMap.insert( "KHistoryCombo", SIGNAL(activated (int)));
00102
00103 changedMap.insert( "KColorButton", SIGNAL(changed(const QColor &)));
00104 changedMap.insert( "KDatePicker", SIGNAL(dateSelected (QDate)));
00105 changedMap.insert( "KDateWidget", SIGNAL(changed (QDate)));
00106 changedMap.insert( "KDateTimeWidget", SIGNAL(valueChanged (const QDateTime &)));
00107 changedMap.insert( "KEditListBox", SIGNAL(changed()));
00108 changedMap.insert( "KListBox", SIGNAL(selectionChanged()));
00109 changedMap.insert( "KLineEdit", SIGNAL(textChanged(const QString &)));
00110 changedMap.insert( "KPasswordEdit", SIGNAL(textChanged(const QString &)));
00111 changedMap.insert( "KRestrictedLine", SIGNAL(textChanged(const QString &)));
00112 changedMap.insert( "KTextBrowser", SIGNAL(sourceChanged(const QString &)));
00113 changedMap.insert( "KTextEdit", SIGNAL(textChanged()));
00114 changedMap.insert( "KURLRequester", SIGNAL(textChanged (const QString& )));
00115 changedMap.insert( "KIntNumInput", SIGNAL(valueChanged (int)));
00116 changedMap.insert( "KIntSpinBox", SIGNAL(valueChanged (int)));
00117 changedMap.insert( "KDoubleNumInput", SIGNAL(valueChanged (double)));
00118 }
00119
00120
00121 (void) parseChildren(m_dialog, trackChanges);
00122 }
00123
00124 void KConfigDialogManager::addWidget(QWidget *widget)
00125 {
00126 (void) parseChildren(widget, true);
00127 }
00128
00129 void KConfigDialogManager::setupWidget(QWidget *widget, KConfigSkeletonItem *item)
00130 {
00131 QVariant minValue = item->minValue();
00132 if (minValue.isValid())
00133 {
00134 if (widget->metaObject()->findProperty("minValue", true) != -1)
00135 widget->setProperty("minValue", minValue);
00136 }
00137 QVariant maxValue = item->maxValue();
00138 if (maxValue.isValid())
00139 {
00140 if (widget->metaObject()->findProperty("maxValue", true) != -1)
00141 widget->setProperty("maxValue", maxValue);
00142 }
00143 if (QWhatsThis::textFor( widget ).isEmpty())
00144 {
00145 QString whatsThis = item->whatsThis();
00146 if ( !whatsThis.isEmpty() )
00147 {
00148 QWhatsThis::add( widget, whatsThis );
00149 }
00150 }
00151 }
00152
00153 bool KConfigDialogManager::parseChildren(const QWidget *widget, bool trackChanges)
00154 {
00155 bool valueChanged = false;
00156 const QObjectList *listOfChildren = widget->children();
00157 if(!listOfChildren)
00158 return valueChanged;
00159
00160 QObject *object;
00161 for( QPtrListIterator<QObject> it( *listOfChildren );
00162 (object = it.current()); ++it )
00163 {
00164 if(!object->isWidgetType())
00165 continue;
00166
00167 QWidget *childWidget = (QWidget *)object;
00168
00169 const char *widgetName = childWidget->name(0);
00170 bool bParseChildren = true;
00171 bool bSaveInsideGroupBox = d->insideGroupBox;
00172
00173 if (widgetName && (strncmp(widgetName, "kcfg_", 5) == 0))
00174 {
00175
00176 QString configId = widgetName+5;
00177 KConfigSkeletonItem *item = m_conf->findItem(configId);
00178 if (item)
00179 {
00180 d->knownWidget.insert(configId, childWidget);
00181
00182 setupWidget(childWidget, item);
00183
00184 QMap<QString, QCString>::const_iterator changedIt = changedMap.find(childWidget->className());
00185
00186 if (changedIt == changedMap.end())
00187 {
00188
00189
00190
00191
00192 changedIt = changedMap.find(childWidget->metaObject()->superClassName());
00193 }
00194
00195 if (changedIt == changedMap.end())
00196 {
00197 kdWarning(178) << "Don't know how to monitor widget '" << childWidget->className() << "' for changes!" << endl;
00198 }
00199 else
00200 {
00201 connect(childWidget, *changedIt,
00202 this, SIGNAL(widgetModified()));
00203
00204 QGroupBox *gb = dynamic_cast<QGroupBox *>(childWidget);
00205 if (!gb)
00206 bParseChildren = false;
00207 else
00208 d->insideGroupBox = true;
00209
00210 QComboBox *cb = dynamic_cast<QComboBox *>(childWidget);
00211 if (cb && cb->editable())
00212 connect(cb, SIGNAL(textChanged(const QString &)),
00213 this, SIGNAL(widgetModified()));
00214 }
00215 }
00216 else
00217 {
00218 kdWarning(178) << "A widget named '" << widgetName << "' was found but there is no setting named '" << configId << "'" << endl;
00219 assert(false);
00220 }
00221 }
00222 else if (childWidget->inherits("QLabel"))
00223 {
00224 QLabel *label = static_cast<QLabel *>(childWidget);
00225 QWidget *buddy = label->buddy();
00226 if (!buddy)
00227 continue;
00228 const char *buddyName = buddy->name(0);
00229 if (buddyName && (strncmp(buddyName, "kcfg_", 5) == 0))
00230 {
00231
00232 QString configId = buddyName+5;
00233 d->buddyWidget.insert(configId, childWidget);
00234 }
00235 }
00236 #ifndef NDEBUG
00237 else if (widgetName)
00238 {
00239 QMap<QString, QCString>::const_iterator changedIt = changedMap.find(childWidget->className());
00240 if (changedIt != changedMap.end())
00241 {
00242 if ((!d->insideGroupBox || !childWidget->inherits("QRadioButton")) &&
00243 !childWidget->inherits("QGroupBox"))
00244 kdDebug(178) << "Widget '" << widgetName << "' (" << childWidget->className() << ") remains unmanaged." << endl;
00245 }
00246 }
00247 #endif
00248
00249 if(bParseChildren)
00250 {
00251
00252
00253 valueChanged |= parseChildren(childWidget, trackChanges);
00254 }
00255 d->insideGroupBox = bSaveInsideGroupBox;
00256 }
00257 return valueChanged;
00258 }
00259
00260 void KConfigDialogManager::updateWidgets()
00261 {
00262 bool changed = false;
00263 bool bSignalsBlocked = signalsBlocked();
00264 blockSignals(true);
00265
00266 QWidget *widget;
00267 for( QDictIterator<QWidget> it( d->knownWidget );
00268 (widget = it.current()); ++it )
00269 {
00270 KConfigSkeletonItem *item = m_conf->findItem(it.currentKey());
00271 if (!item)
00272 {
00273 kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl;
00274 continue;
00275 }
00276
00277 QVariant p = item->property();
00278 if (p != property(widget))
00279 {
00280 setProperty(widget, p);
00281
00282 changed = true;
00283 }
00284 if (item->isImmutable())
00285 {
00286 widget->setEnabled(false);
00287 QWidget *buddy = d->buddyWidget.find(it.currentKey());
00288 if (buddy)
00289 buddy->setEnabled(false);
00290 }
00291 }
00292 blockSignals(bSignalsBlocked);
00293
00294 if (changed)
00295 QTimer::singleShot(0, this, SIGNAL(widgetModified()));
00296 }
00297
00298 void KConfigDialogManager::updateWidgetsDefault()
00299 {
00300 bool bUseDefaults = m_conf->useDefaults(true);
00301 updateWidgets();
00302 m_conf->useDefaults(bUseDefaults);
00303 }
00304
00305 void KConfigDialogManager::updateSettings()
00306 {
00307 bool changed = false;
00308
00309 QWidget *widget;
00310 for( QDictIterator<QWidget> it( d->knownWidget );
00311 (widget = it.current()); ++it )
00312 {
00313 KConfigSkeletonItem *item = m_conf->findItem(it.currentKey());
00314 if (!item)
00315 {
00316 kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl;
00317 continue;
00318 }
00319
00320 QVariant p = property(widget);
00321 if (p != item->property())
00322 {
00323 item->setProperty(p);
00324 changed = true;
00325 }
00326 }
00327 if (changed)
00328 {
00329 m_conf->writeConfig();
00330 emit settingsChanged();
00331 }
00332 }
00333
00334 void KConfigDialogManager::setProperty(QWidget *w, const QVariant &v)
00335 {
00336 QButtonGroup *bg = dynamic_cast<QButtonGroup *>(w);
00337 if (bg)
00338 {
00339 bg->setButton(v.toInt());
00340 return;
00341 }
00342
00343 QComboBox *cb = dynamic_cast<QComboBox *>(w);
00344 if (cb && cb->editable())
00345 {
00346 cb->setCurrentText(v.toString());
00347 return;
00348 }
00349
00350 propertyMap->setProperty(w, v);
00351 }
00352
00353 QVariant KConfigDialogManager::property(QWidget *w)
00354 {
00355 QButtonGroup *bg = dynamic_cast<QButtonGroup *>(w);
00356 if (bg)
00357 return QVariant(bg->selectedId());
00358
00359 QComboBox *cb = dynamic_cast<QComboBox *>(w);
00360 if (cb && cb->editable())
00361 return QVariant(cb->currentText());
00362
00363 return propertyMap->property(w);
00364 }
00365
00366 bool KConfigDialogManager::hasChanged()
00367 {
00368
00369 QWidget *widget;
00370 for( QDictIterator<QWidget> it( d->knownWidget );
00371 (widget = it.current()); ++it )
00372 {
00373 KConfigSkeletonItem *item = m_conf->findItem(it.currentKey());
00374 if (!item)
00375 {
00376 kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl;
00377 continue;
00378 }
00379
00380 QVariant p = property(widget);
00381 if (p != item->property())
00382 {
00383
00384 return true;
00385 }
00386 }
00387 return false;
00388 }
00389
00390 bool KConfigDialogManager::isDefault()
00391 {
00392 bool bUseDefaults = m_conf->useDefaults(true);
00393 bool result = !hasChanged();
00394 m_conf->useDefaults(bUseDefaults);
00395 return result;
00396 }
00397
00398 #include "kconfigdialogmanager.moc"
00399