tdeconfigdialogmanager.cpp
00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (C) 2003 Benjamin C Meyer (ben+tdelibs at meyerhome dot net) 00004 * Copyright (C) 2003 Waldo Bastian <bastian@kde.org> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Library General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Library General Public License 00017 * along with this library; see the file COPYING.LIB. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "tdeconfigdialogmanager.h" 00023 00024 #include <tqbuttongroup.h> 00025 #include <tqcombobox.h> 00026 #include <tqlabel.h> 00027 #include <tqmetaobject.h> 00028 #include <tqobjectlist.h> 00029 #include <tqsqlpropertymap.h> 00030 #include <tqtimer.h> 00031 #include <tqwhatsthis.h> 00032 00033 #include <tdeapplication.h> 00034 #include <tdeconfigskeleton.h> 00035 #include <kdebug.h> 00036 #include <tdeglobal.h> 00037 00038 #include <assert.h> 00039 00040 class TDEConfigDialogManager::Private { 00041 00042 public: 00043 Private() : insideGroupBox(false) { } 00044 00045 public: 00046 TQDict<TQWidget> knownWidget; 00047 TQDict<TQWidget> buddyWidget; 00048 bool insideGroupBox; 00049 }; 00050 00051 TDEConfigDialogManager::TDEConfigDialogManager(TQWidget *parent, TDEConfigSkeleton *conf, const char *name) 00052 : TQObject(parent, name), m_conf(conf), m_dialog(parent) 00053 { 00054 d = new Private(); 00055 00056 kapp->installKDEPropertyMap(); 00057 propertyMap = TQSqlPropertyMap::defaultMap(); 00058 00059 init(true); 00060 } 00061 00062 TDEConfigDialogManager::~TDEConfigDialogManager() 00063 { 00064 delete d; 00065 } 00066 00067 void TDEConfigDialogManager::init(bool trackChanges) 00068 { 00069 if(trackChanges) 00070 { 00071 // QT 00072 changedMap.insert(TQBUTTON_OBJECT_NAME_STRING, TQT_SIGNAL(stateChanged(int))); 00073 changedMap.insert(TQCHECKBOX_OBJECT_NAME_STRING, TQT_SIGNAL(stateChanged(int))); 00074 changedMap.insert(TQPUSHBUTTON_OBJECT_NAME_STRING, TQT_SIGNAL(stateChanged(int))); 00075 changedMap.insert(TQRADIOBUTTON_OBJECT_NAME_STRING, TQT_SIGNAL(stateChanged(int))); 00076 // We can only store one thing, so you can't have 00077 // a ButtonGroup that is checkable. 00078 changedMap.insert(TQBUTTONGROUP_OBJECT_NAME_STRING, TQT_SIGNAL(clicked(int))); 00079 changedMap.insert(TQGROUPBOX_OBJECT_NAME_STRING, TQT_SIGNAL(toggled(bool))); 00080 changedMap.insert(TQCOMBOBOX_OBJECT_NAME_STRING, TQT_SIGNAL(activated (int))); 00081 //qsqlproperty map doesn't store the text, but the value! 00082 //changedMap.insert(TQCOMBOBOX_OBJECT_NAME_STRING, TQT_SIGNAL(textChanged(const TQString &))); 00083 changedMap.insert(TQDATEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(const TQDate &))); 00084 changedMap.insert(TQDATETIMEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(const TQDateTime &))); 00085 changedMap.insert(TQDIAL_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged (int))); 00086 changedMap.insert(TQLINEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(textChanged(const TQString &))); 00087 changedMap.insert(TQSLIDER_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(int))); 00088 changedMap.insert(TQSPINBOX_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(int))); 00089 changedMap.insert(TQTIMEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(const TQTime &))); 00090 changedMap.insert(TQTEXTEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(textChanged())); 00091 changedMap.insert(TQTEXTBROWSER_OBJECT_NAME_STRING, TQT_SIGNAL(sourceChanged(const TQString &))); 00092 changedMap.insert(TQMULTILINEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(textChanged())); 00093 changedMap.insert(TQLISTBOX_OBJECT_NAME_STRING, TQT_SIGNAL(selectionChanged())); 00094 changedMap.insert(TQTABWIDGET_OBJECT_NAME_STRING, TQT_SIGNAL(currentChanged(TQWidget *))); 00095 00096 // KDE 00097 changedMap.insert( "KComboBox", TQT_SIGNAL(activated (int))); 00098 changedMap.insert( "TDEFontCombo", TQT_SIGNAL(activated (int))); 00099 changedMap.insert( "TDEFontRequester", TQT_SIGNAL(fontSelected(const TQFont &))); 00100 changedMap.insert( "TDEFontChooser", TQT_SIGNAL(fontSelected(const TQFont &))); 00101 changedMap.insert( "KHistoryCombo", TQT_SIGNAL(activated (int))); 00102 00103 changedMap.insert( "KColorButton", TQT_SIGNAL(changed(const TQColor &))); 00104 changedMap.insert( "KDatePicker", TQT_SIGNAL(dateSelected (TQDate))); 00105 changedMap.insert( "KDateWidget", TQT_SIGNAL(changed (TQDate))); 00106 changedMap.insert( "KDateTimeWidget", TQT_SIGNAL(valueChanged (const TQDateTime &))); 00107 changedMap.insert( "KEditListBox", TQT_SIGNAL(changed())); 00108 changedMap.insert( "TDEListBox", TQT_SIGNAL(selectionChanged())); 00109 changedMap.insert( "KLineEdit", TQT_SIGNAL(textChanged(const TQString &))); 00110 changedMap.insert( "KPasswordEdit", TQT_SIGNAL(textChanged(const TQString &))); 00111 changedMap.insert( "KRestrictedLine", TQT_SIGNAL(textChanged(const TQString &))); 00112 changedMap.insert( "KTextBrowser", TQT_SIGNAL(sourceChanged(const TQString &))); 00113 changedMap.insert( "KTextEdit", TQT_SIGNAL(textChanged())); 00114 changedMap.insert( "KURLRequester", TQT_SIGNAL(textChanged (const TQString& ))); 00115 changedMap.insert( "KIntNumInput", TQT_SIGNAL(valueChanged (int))); 00116 changedMap.insert( "KIntSpinBox", TQT_SIGNAL(valueChanged (int))); 00117 changedMap.insert( "KDoubleNumInput", TQT_SIGNAL(valueChanged (double))); 00118 } 00119 00120 // Go through all of the children of the widgets and find all known widgets 00121 (void) parseChildren(m_dialog, trackChanges); 00122 } 00123 00124 void TDEConfigDialogManager::addWidget(TQWidget *widget) 00125 { 00126 (void) parseChildren(widget, true); 00127 } 00128 00129 void TDEConfigDialogManager::setupWidget(TQWidget *widget, TDEConfigSkeletonItem *item) 00130 { 00131 TQVariant minValue = item->minValue(); 00132 if (minValue.isValid()) 00133 { 00134 if (widget->metaObject()->findProperty("minValue", true) != -1) 00135 widget->setProperty("minValue", minValue); 00136 } 00137 TQVariant maxValue = item->maxValue(); 00138 if (maxValue.isValid()) 00139 { 00140 if (widget->metaObject()->findProperty("maxValue", true) != -1) 00141 widget->setProperty("maxValue", maxValue); 00142 } 00143 if (TQWhatsThis::textFor( widget ).isEmpty()) 00144 { 00145 TQString whatsThis = item->whatsThis(); 00146 if ( !whatsThis.isEmpty() ) 00147 { 00148 TQWhatsThis::add( widget, whatsThis ); 00149 } 00150 } 00151 } 00152 00153 bool TDEConfigDialogManager::parseChildren(const TQWidget *widget, bool trackChanges) 00154 { 00155 bool valueChanged = false; 00156 const TQObjectList listOfChildren = widget->childrenListObject(); 00157 if(listOfChildren.isEmpty()) 00158 return valueChanged; 00159 00160 TQObject *object; 00161 for( TQObjectListIterator it( listOfChildren ); 00162 (object = it.current()); ++it ) 00163 { 00164 if(!object->isWidgetType()) 00165 continue; // Skip non-widgets 00166 00167 TQWidget *childWidget = (TQWidget *)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 // This is one of our widgets! 00176 TQString configId = widgetName+5; 00177 TDEConfigSkeletonItem *item = m_conf->findItem(configId); 00178 if (item) 00179 { 00180 d->knownWidget.insert(configId, childWidget); 00181 00182 setupWidget(childWidget, item); 00183 00184 TQMap<TQString, TQCString>::const_iterator changedIt = changedMap.find(childWidget->className()); 00185 00186 if (changedIt == changedMap.end()) 00187 { 00188 // If the class name of the widget wasn't in the monitored widgets map, then look for 00189 // it again using the super class name. This fixes a problem with using QtRuby/Korundum 00190 // widgets with TDEConfigXT where 'Qt::Widget' wasn't being seen a the real deal, even 00191 // though it was a 'QWidget'. 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, TQT_SIGNAL(widgetModified())); 00203 00204 TQGroupBox *gb = dynamic_cast<TQGroupBox *>(childWidget); 00205 if (!gb) 00206 bParseChildren = false; 00207 else 00208 d->insideGroupBox = true; 00209 00210 TQComboBox *cb = dynamic_cast<TQComboBox *>(childWidget); 00211 if (cb && cb->editable()) 00212 connect(cb, TQT_SIGNAL(textChanged(const TQString &)), 00213 this, TQT_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 } 00220 } 00221 else if (childWidget->inherits(TQLABEL_OBJECT_NAME_STRING)) 00222 { 00223 TQLabel *label = static_cast<TQLabel *>(childWidget); 00224 TQWidget *buddy = label->buddy(); 00225 if (!buddy) 00226 continue; 00227 const char *buddyName = buddy->name(0); 00228 if (buddyName && (strncmp(buddyName, "kcfg_", 5) == 0)) 00229 { 00230 // This is one of our widgets! 00231 TQString configId = buddyName+5; 00232 d->buddyWidget.insert(configId, childWidget); 00233 } 00234 } 00235 #ifndef NDEBUG 00236 else if (widgetName) 00237 { 00238 TQMap<TQString, TQCString>::const_iterator changedIt = changedMap.find(childWidget->className()); 00239 if (changedIt != changedMap.end()) 00240 { 00241 if ((!d->insideGroupBox || !childWidget->inherits(TQRADIOBUTTON_OBJECT_NAME_STRING)) && 00242 !childWidget->inherits(TQGROUPBOX_OBJECT_NAME_STRING)) 00243 kdDebug(178) << "Widget '" << widgetName << "' (" << childWidget->className() << ") remains unmanaged." << endl; 00244 } 00245 } 00246 #endif 00247 00248 if(bParseChildren) 00249 { 00250 // this widget is not known as something we can store. 00251 // Maybe we can store one of its children. 00252 valueChanged |= parseChildren(childWidget, trackChanges); 00253 } 00254 d->insideGroupBox = bSaveInsideGroupBox; 00255 } 00256 return valueChanged; 00257 } 00258 00259 void TDEConfigDialogManager::updateWidgets() 00260 { 00261 bool changed = false; 00262 bool bSignalsBlocked = signalsBlocked(); 00263 blockSignals(true); 00264 00265 TQWidget *widget; 00266 for( TQDictIterator<TQWidget> it( d->knownWidget ); 00267 (widget = it.current()); ++it ) 00268 { 00269 TDEConfigSkeletonItem *item = m_conf->findItem(it.currentKey()); 00270 if (!item) 00271 { 00272 kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl; 00273 continue; 00274 } 00275 00276 TQVariant p = item->property(); 00277 if (p != property(widget)) 00278 { 00279 setProperty(widget, p); 00280 // kdDebug(178) << "The setting '" << it.currentKey() << "' [" << widget->className() << "] has changed" << endl; 00281 changed = true; 00282 } 00283 if (item->isImmutable()) 00284 { 00285 widget->setEnabled(false); 00286 TQWidget *buddy = d->buddyWidget.find(it.currentKey()); 00287 if (buddy) 00288 buddy->setEnabled(false); 00289 } 00290 } 00291 blockSignals(bSignalsBlocked); 00292 00293 if (changed) 00294 TQTimer::singleShot(0, this, TQT_SIGNAL(widgetModified())); 00295 } 00296 00297 void TDEConfigDialogManager::updateWidgetsDefault() 00298 { 00299 bool bUseDefaults = m_conf->useDefaults(true); 00300 updateWidgets(); 00301 m_conf->useDefaults(bUseDefaults); 00302 } 00303 00304 void TDEConfigDialogManager::updateSettings() 00305 { 00306 bool changed = false; 00307 00308 TQWidget *widget; 00309 for( TQDictIterator<TQWidget> it( d->knownWidget ); 00310 (widget = it.current()); ++it ) 00311 { 00312 TDEConfigSkeletonItem *item = m_conf->findItem(it.currentKey()); 00313 if (!item) 00314 { 00315 kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl; 00316 continue; 00317 } 00318 00319 TQVariant p = property(widget); 00320 if (p != item->property()) 00321 { 00322 item->setProperty(p); 00323 changed = true; 00324 } 00325 } 00326 if (changed) 00327 { 00328 m_conf->writeConfig(); 00329 emit settingsChanged(); 00330 } 00331 } 00332 00333 void TDEConfigDialogManager::setProperty(TQWidget *w, const TQVariant &v) 00334 { 00335 TQButtonGroup *bg = dynamic_cast<TQButtonGroup *>(w); 00336 if (bg) 00337 { 00338 bg->setButton(v.toInt()); 00339 return; 00340 } 00341 00342 TQComboBox *cb = dynamic_cast<TQComboBox *>(w); 00343 if (cb && cb->editable()) 00344 { 00345 cb->setCurrentText(v.toString()); 00346 return; 00347 } 00348 00349 propertyMap->setProperty(w, v); 00350 } 00351 00352 TQVariant TDEConfigDialogManager::property(TQWidget *w) 00353 { 00354 TQButtonGroup *bg = dynamic_cast<TQButtonGroup *>(w); 00355 if (bg) 00356 return TQVariant(bg->selectedId()); 00357 00358 TQComboBox *cb = dynamic_cast<TQComboBox *>(w); 00359 if (cb && cb->editable()) 00360 return TQVariant(cb->currentText()); 00361 00362 return propertyMap->property(w); 00363 } 00364 00365 bool TDEConfigDialogManager::hasChanged() 00366 { 00367 00368 TQWidget *widget; 00369 for( TQDictIterator<TQWidget> it( d->knownWidget ); 00370 (widget = it.current()); ++it ) 00371 { 00372 TDEConfigSkeletonItem *item = m_conf->findItem(it.currentKey()); 00373 if (!item) 00374 { 00375 kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl; 00376 continue; 00377 } 00378 00379 TQVariant p = property(widget); 00380 if (p != item->property()) 00381 { 00382 // kdDebug(178) << "Widget for '" << it.currentKey() << "' has changed." << endl; 00383 return true; 00384 } 00385 } 00386 return false; 00387 } 00388 00389 bool TDEConfigDialogManager::isDefault() 00390 { 00391 bool bUseDefaults = m_conf->useDefaults(true); 00392 bool result = !hasChanged(); 00393 m_conf->useDefaults(bUseDefaults); 00394 return result; 00395 } 00396 00397 #include "tdeconfigdialogmanager.moc" 00398