/* * This file is part of the KDE libraries * Copyright (C) 2003 Benjamin C Meyer (ben+tdelibs at meyerhome dot net) * Copyright (C) 2003 Waldo Bastian <bastian@kde.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kconfigdialogmanager.h" #include <tqbuttongroup.h> #include <tqcombobox.h> #include <tqlabel.h> #include <tqmetaobject.h> #include <tqobjectlist.h> #include <tqsqlpropertymap.h> #include <tqtimer.h> #include <tqwhatsthis.h> #include <kapplication.h> #include <kconfigskeleton.h> #include <kdebug.h> #include <kglobal.h> #include <assert.h> class TDEConfigDialogManager::Private { public: Private() : insideGroupBox(false) { } public: TQDict<TQWidget> knownWidget; TQDict<TQWidget> buddyWidget; bool insideGroupBox; }; TDEConfigDialogManager::TDEConfigDialogManager(TQWidget *parent, TDEConfigSkeleton *conf, const char *name) : TQObject(parent, name), m_conf(conf), m_dialog(parent) { d = new Private(); kapp->installKDEPropertyMap(); propertyMap = TQSqlPropertyMap::defaultMap(); init(true); } TDEConfigDialogManager::~TDEConfigDialogManager() { delete d; } void TDEConfigDialogManager::init(bool trackChanges) { if(trackChanges) { // QT changedMap.insert(TQBUTTON_OBJECT_NAME_STRING, TQT_SIGNAL(stateChanged(int))); changedMap.insert(TQCHECKBOX_OBJECT_NAME_STRING, TQT_SIGNAL(stateChanged(int))); changedMap.insert(TQPUSHBUTTON_OBJECT_NAME_STRING, TQT_SIGNAL(stateChanged(int))); changedMap.insert(TQRADIOBUTTON_OBJECT_NAME_STRING, TQT_SIGNAL(stateChanged(int))); // We can only store one thing, so you can't have // a ButtonGroup that is checkable. changedMap.insert(TQBUTTONGROUP_OBJECT_NAME_STRING, TQT_SIGNAL(clicked(int))); changedMap.insert(TQGROUPBOX_OBJECT_NAME_STRING, TQT_SIGNAL(toggled(bool))); changedMap.insert(TQCOMBOBOX_OBJECT_NAME_STRING, TQT_SIGNAL(activated (int))); //qsqlproperty map doesn't store the text, but the value! //changedMap.insert(TQCOMBOBOX_OBJECT_NAME_STRING, TQT_SIGNAL(textChanged(const TQString &))); changedMap.insert(TQDATEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(const TQDate &))); changedMap.insert(TQDATETIMEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(const TQDateTime &))); changedMap.insert(TQDIAL_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged (int))); changedMap.insert(TQLINEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(textChanged(const TQString &))); changedMap.insert(TQSLIDER_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(int))); changedMap.insert(TQSPINBOX_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(int))); changedMap.insert(TQTIMEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(valueChanged(const TQTime &))); changedMap.insert(TQTEXTEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(textChanged())); changedMap.insert(TQTEXTBROWSER_OBJECT_NAME_STRING, TQT_SIGNAL(sourceChanged(const TQString &))); changedMap.insert(TQMULTILINEEDIT_OBJECT_NAME_STRING, TQT_SIGNAL(textChanged())); changedMap.insert(TQLISTBOX_OBJECT_NAME_STRING, TQT_SIGNAL(selectionChanged())); changedMap.insert(TQTABWIDGET_OBJECT_NAME_STRING, TQT_SIGNAL(currentChanged(TQWidget *))); // KDE changedMap.insert( "KComboBox", TQT_SIGNAL(activated (int))); changedMap.insert( "KFontCombo", TQT_SIGNAL(activated (int))); changedMap.insert( "KFontRequester", TQT_SIGNAL(fontSelected(const TQFont &))); changedMap.insert( "KFontChooser", TQT_SIGNAL(fontSelected(const TQFont &))); changedMap.insert( "KHistoryCombo", TQT_SIGNAL(activated (int))); changedMap.insert( "KColorButton", TQT_SIGNAL(changed(const TQColor &))); changedMap.insert( "KDatePicker", TQT_SIGNAL(dateSelected (TQDate))); changedMap.insert( "KDateWidget", TQT_SIGNAL(changed (TQDate))); changedMap.insert( "KDateTimeWidget", TQT_SIGNAL(valueChanged (const TQDateTime &))); changedMap.insert( "KEditListBox", TQT_SIGNAL(changed())); changedMap.insert( "KListBox", TQT_SIGNAL(selectionChanged())); changedMap.insert( "KLineEdit", TQT_SIGNAL(textChanged(const TQString &))); changedMap.insert( "KPasswordEdit", TQT_SIGNAL(textChanged(const TQString &))); changedMap.insert( "KRestrictedLine", TQT_SIGNAL(textChanged(const TQString &))); changedMap.insert( "KTextBrowser", TQT_SIGNAL(sourceChanged(const TQString &))); changedMap.insert( "KTextEdit", TQT_SIGNAL(textChanged())); changedMap.insert( "KURLRequester", TQT_SIGNAL(textChanged (const TQString& ))); changedMap.insert( "KIntNumInput", TQT_SIGNAL(valueChanged (int))); changedMap.insert( "KIntSpinBox", TQT_SIGNAL(valueChanged (int))); changedMap.insert( "KDoubleNumInput", TQT_SIGNAL(valueChanged (double))); } // Go through all of the children of the widgets and find all known widgets (void) parseChildren(m_dialog, trackChanges); } void TDEConfigDialogManager::addWidget(TQWidget *widget) { (void) parseChildren(widget, true); } void TDEConfigDialogManager::setupWidget(TQWidget *widget, TDEConfigSkeletonItem *item) { TQVariant minValue = item->minValue(); if (minValue.isValid()) { if (widget->metaObject()->findProperty("minValue", true) != -1) widget->setProperty("minValue", minValue); } TQVariant maxValue = item->maxValue(); if (maxValue.isValid()) { if (widget->metaObject()->findProperty("maxValue", true) != -1) widget->setProperty("maxValue", maxValue); } if (TQWhatsThis::textFor( widget ).isEmpty()) { TQString whatsThis = item->whatsThis(); if ( !whatsThis.isEmpty() ) { TQWhatsThis::add( widget, whatsThis ); } } } bool TDEConfigDialogManager::parseChildren(const TQWidget *widget, bool trackChanges) { bool valueChanged = false; const TQObjectList listOfChildren = widget->childrenListObject(); if(listOfChildren.isEmpty()) return valueChanged; TQObject *object; for( TQObjectListIterator it( listOfChildren ); (object = it.current()); ++it ) { if(!object->isWidgetType()) continue; // Skip non-widgets TQWidget *childWidget = (TQWidget *)object; const char *widgetName = childWidget->name(0); bool bParseChildren = true; bool bSaveInsideGroupBox = d->insideGroupBox; if (widgetName && (strncmp(widgetName, "kcfg_", 5) == 0)) { // This is one of our widgets! TQString configId = widgetName+5; TDEConfigSkeletonItem *item = m_conf->findItem(configId); if (item) { d->knownWidget.insert(configId, childWidget); setupWidget(childWidget, item); TQMap<TQString, TQCString>::const_iterator changedIt = changedMap.find(childWidget->className()); if (changedIt == changedMap.end()) { // If the class name of the widget wasn't in the monitored widgets map, then look for // it again using the super class name. This fixes a problem with using QtRuby/Korundum // widgets with TDEConfigXT where 'Qt::Widget' wasn't being seen a the real deal, even // though it was a 'QWidget'. changedIt = changedMap.find(childWidget->metaObject()->superClassName()); } if (changedIt == changedMap.end()) { kdWarning(178) << "Don't know how to monitor widget '" << childWidget->className() << "' for changes!" << endl; } else { connect(childWidget, *changedIt, this, TQT_SIGNAL(widgetModified())); TQGroupBox *gb = dynamic_cast<TQGroupBox *>(childWidget); if (!gb) bParseChildren = false; else d->insideGroupBox = true; TQComboBox *cb = dynamic_cast<TQComboBox *>(childWidget); if (cb && cb->editable()) connect(cb, TQT_SIGNAL(textChanged(const TQString &)), this, TQT_SIGNAL(widgetModified())); } } else { kdWarning(178) << "A widget named '" << widgetName << "' was found but there is no setting named '" << configId << "'" << endl; } } else if (childWidget->inherits(TQLABEL_OBJECT_NAME_STRING)) { TQLabel *label = static_cast<TQLabel *>(childWidget); TQWidget *buddy = label->buddy(); if (!buddy) continue; const char *buddyName = buddy->name(0); if (buddyName && (strncmp(buddyName, "kcfg_", 5) == 0)) { // This is one of our widgets! TQString configId = buddyName+5; d->buddyWidget.insert(configId, childWidget); } } #ifndef NDEBUG else if (widgetName) { TQMap<TQString, TQCString>::const_iterator changedIt = changedMap.find(childWidget->className()); if (changedIt != changedMap.end()) { if ((!d->insideGroupBox || !childWidget->inherits(TQRADIOBUTTON_OBJECT_NAME_STRING)) && !childWidget->inherits(TQGROUPBOX_OBJECT_NAME_STRING)) kdDebug(178) << "Widget '" << widgetName << "' (" << childWidget->className() << ") remains unmanaged." << endl; } } #endif if(bParseChildren) { // this widget is not known as something we can store. // Maybe we can store one of its children. valueChanged |= parseChildren(childWidget, trackChanges); } d->insideGroupBox = bSaveInsideGroupBox; } return valueChanged; } void TDEConfigDialogManager::updateWidgets() { bool changed = false; bool bSignalsBlocked = signalsBlocked(); blockSignals(true); TQWidget *widget; for( TQDictIterator<TQWidget> it( d->knownWidget ); (widget = it.current()); ++it ) { TDEConfigSkeletonItem *item = m_conf->findItem(it.currentKey()); if (!item) { kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl; continue; } TQVariant p = item->property(); if (p != property(widget)) { setProperty(widget, p); // kdDebug(178) << "The setting '" << it.currentKey() << "' [" << widget->className() << "] has changed" << endl; changed = true; } if (item->isImmutable()) { widget->setEnabled(false); TQWidget *buddy = d->buddyWidget.find(it.currentKey()); if (buddy) buddy->setEnabled(false); } } blockSignals(bSignalsBlocked); if (changed) TQTimer::singleShot(0, this, TQT_SIGNAL(widgetModified())); } void TDEConfigDialogManager::updateWidgetsDefault() { bool bUseDefaults = m_conf->useDefaults(true); updateWidgets(); m_conf->useDefaults(bUseDefaults); } void TDEConfigDialogManager::updateSettings() { bool changed = false; TQWidget *widget; for( TQDictIterator<TQWidget> it( d->knownWidget ); (widget = it.current()); ++it ) { TDEConfigSkeletonItem *item = m_conf->findItem(it.currentKey()); if (!item) { kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl; continue; } TQVariant p = property(widget); if (p != item->property()) { item->setProperty(p); changed = true; } } if (changed) { m_conf->writeConfig(); emit settingsChanged(); } } void TDEConfigDialogManager::setProperty(TQWidget *w, const TQVariant &v) { TQButtonGroup *bg = dynamic_cast<TQButtonGroup *>(w); if (bg) { bg->setButton(v.toInt()); return; } TQComboBox *cb = dynamic_cast<TQComboBox *>(w); if (cb && cb->editable()) { cb->setCurrentText(v.toString()); return; } propertyMap->setProperty(w, v); } TQVariant TDEConfigDialogManager::property(TQWidget *w) { TQButtonGroup *bg = dynamic_cast<TQButtonGroup *>(w); if (bg) return TQVariant(bg->selectedId()); TQComboBox *cb = dynamic_cast<TQComboBox *>(w); if (cb && cb->editable()) return TQVariant(cb->currentText()); return propertyMap->property(w); } bool TDEConfigDialogManager::hasChanged() { TQWidget *widget; for( TQDictIterator<TQWidget> it( d->knownWidget ); (widget = it.current()); ++it ) { TDEConfigSkeletonItem *item = m_conf->findItem(it.currentKey()); if (!item) { kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl; continue; } TQVariant p = property(widget); if (p != item->property()) { // kdDebug(178) << "Widget for '" << it.currentKey() << "' has changed." << endl; return true; } } return false; } bool TDEConfigDialogManager::isDefault() { bool bUseDefaults = m_conf->useDefaults(true); bool result = !hasChanged(); m_conf->useDefaults(bUseDefaults); return result; } #include "kconfigdialogmanager.moc"