kdecore Library API Documentation

kconfigdialogmanager.cpp

00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (C) 2003 Benjamin C Meyer (ben+kdelibs 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., 59 Temple Place - Suite 330,
00019  *  Boston, MA 02111-1307, USA.
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() { }
00044 
00045 public:
00046   QDict<QWidget> knownWidget;
00047   QDict<QWidget> buddyWidget;
00048 };
00049 
00050 KConfigDialogManager::KConfigDialogManager(QWidget *parent, KConfigSkeleton *conf, const char *name)
00051  : QObject(parent, name), m_conf(conf), m_dialog(parent)
00052 {
00053   d = new Private();
00054 
00055   kapp->installKDEPropertyMap();
00056   propertyMap = QSqlPropertyMap::defaultMap();
00057 
00058   init(true);
00059 }
00060 
00061 KConfigDialogManager::~KConfigDialogManager()
00062 {
00063   delete d;
00064 }
00065 
00066 void KConfigDialogManager::init(bool trackChanges)
00067 {
00068   if(trackChanges)
00069   {
00070     // QT
00071     changedMap.insert("QButton", SIGNAL(stateChanged(int)));
00072     changedMap.insert("QCheckBox", SIGNAL(stateChanged(int)));
00073     changedMap.insert("QPushButton", SIGNAL(stateChanged(int)));
00074     changedMap.insert("QRadioButton", SIGNAL(stateChanged(int)));
00075     // We can only store one thing, so you can't have
00076     // a ButtonGroup that is checkable.
00077     changedMap.insert("QButtonGroup", SIGNAL(clicked(int)));
00078     changedMap.insert("QGroupBox", SIGNAL(toggled(bool)));
00079     changedMap.insert("QComboBox", SIGNAL(activated (int)));
00080     //qsqlproperty map doesn't store the text, but the value!
00081     //changedMap.insert("QComboBox", SIGNAL(textChanged(const QString &)));
00082     changedMap.insert("QDateEdit", SIGNAL(valueChanged(const QDate &)));
00083     changedMap.insert("QDateTimeEdit", SIGNAL(valueChanged(const QDateTime &)));
00084     changedMap.insert("QDial", SIGNAL(valueChanged (int)));
00085     changedMap.insert("QLineEdit", SIGNAL(textChanged(const QString &)));
00086     changedMap.insert("QSlider", SIGNAL(valueChanged(int)));
00087     changedMap.insert("QSpinBox", SIGNAL(valueChanged(int)));
00088     changedMap.insert("QTimeEdit", SIGNAL(valueChanged(const QTime &)));
00089     changedMap.insert("QTextEdit", SIGNAL(textChanged()));
00090     changedMap.insert("QTextBrowser", SIGNAL(sourceChanged(const QString &)));
00091     changedMap.insert("QMultiLineEdit", SIGNAL(textChanged()));
00092     changedMap.insert("QListBox", SIGNAL(selectionChanged()));
00093     changedMap.insert("QTabWidget", SIGNAL(currentChanged(QWidget *)));
00094 
00095     // KDE
00096     changedMap.insert( "KComboBox", SIGNAL(activated (int)));
00097     changedMap.insert( "KFontCombo", SIGNAL(activated (int)));
00098     changedMap.insert( "KFontRequester", SIGNAL(fontSelected(const QFont &)));
00099     changedMap.insert( "KFontChooser",  SIGNAL(fontSelected(const QFont &)));
00100     changedMap.insert( "KHistoryCombo", SIGNAL(activated (int)));
00101 
00102     changedMap.insert( "KColorButton", SIGNAL(changed(const QColor &)));
00103     changedMap.insert( "KDatePicker", SIGNAL(dateSelected (QDate)));
00104     changedMap.insert( "KDateWidget", SIGNAL(changed (QDate)));
00105     changedMap.insert( "KDateTimeWidget", SIGNAL(valueChanged (const QDateTime &)));
00106     changedMap.insert( "KEditListBox", SIGNAL(changed()));
00107     changedMap.insert( "KListBox", SIGNAL(selectionChanged()));
00108     changedMap.insert( "KLineEdit", SIGNAL(textChanged(const QString &)));
00109     changedMap.insert( "KPasswordEdit", SIGNAL(textChanged(const QString &)));
00110     changedMap.insert( "KRestrictedLine", SIGNAL(textChanged(const QString &)));
00111     changedMap.insert( "KTextBrowser", SIGNAL(sourceChanged(const QString &)));
00112     changedMap.insert( "KTextEdit", SIGNAL(textChanged()));
00113     changedMap.insert( "KURLRequester",  SIGNAL(textChanged (const QString& )));
00114     changedMap.insert( "KIntNumInput", SIGNAL(valueChanged (int)));
00115     changedMap.insert( "KIntSpinBox", SIGNAL(valueChanged (int)));
00116     changedMap.insert( "KDoubleNumInput", SIGNAL(valueChanged (double)));
00117   }
00118 
00119   // Go through all of the children of the widgets and find all known widgets
00120   (void) parseChildren(m_dialog, trackChanges);
00121 }
00122 
00123 void KConfigDialogManager::addWidget(QWidget *widget)
00124 {
00125   (void) parseChildren(widget, true);
00126 }
00127 
00128 void KConfigDialogManager::setupWidget(QWidget *widget, KConfigSkeletonItem *item)
00129 {
00130   QVariant minValue = item->minValue();
00131   if (minValue.isValid())
00132   {
00133     if (widget->metaObject()->findProperty("minValue", true) != -1)
00134        widget->setProperty("minValue", minValue);
00135   }
00136   QVariant maxValue = item->maxValue();
00137   if (maxValue.isValid())
00138   {
00139     if (widget->metaObject()->findProperty("maxValue", true) != -1)
00140        widget->setProperty("maxValue", maxValue);
00141   }
00142   QString whatsThis = item->whatsThis();
00143   if ( !whatsThis.isEmpty() )
00144   {
00145     QWhatsThis::add( widget, whatsThis );
00146   }
00147 }
00148 
00149 bool KConfigDialogManager::parseChildren(const QWidget *widget, bool trackChanges)
00150 {
00151   bool valueChanged = false;
00152   const QObjectList *listOfChildren = widget->children();
00153   if(!listOfChildren)
00154     return valueChanged;
00155 
00156   QObject *object;
00157   for( QPtrListIterator<QObject> it( *listOfChildren );
00158        (object = it.current()); ++it )
00159   {
00160     if(!object->isWidgetType())
00161       continue; // Skip non-widgets
00162 
00163     QWidget *childWidget = (QWidget *)object;
00164 
00165     const char *widgetName = childWidget->name(0);
00166     bool bParseChildren = true;
00167 
00168     if (widgetName && (strncmp(widgetName, "kcfg_", 5) == 0))
00169     {
00170       // This is one of our widgets!
00171       QString configId = widgetName+5;
00172       KConfigSkeletonItem *item = m_conf->findItem(configId);
00173       if (item)
00174       {
00175         d->knownWidget.insert(configId, childWidget);
00176 
00177         setupWidget(childWidget, item);
00178 
00179         QMap<QString, QCString>::const_iterator changedIt = changedMap.find(childWidget->className());
00180         if (changedIt == changedMap.end())
00181         {
00182           kdWarning(178) << "Don't know how to monitor widget '" << childWidget->className() << "' for changes!" << endl;
00183         }
00184         else
00185         {
00186           connect(childWidget, *changedIt,
00187                   this, SIGNAL(widgetModified()));
00188 
00189           QGroupBox *gb = dynamic_cast<QGroupBox *>(childWidget);
00190           if (!gb)
00191             bParseChildren = false;
00192 
00193           QComboBox *cb = dynamic_cast<QComboBox *>(childWidget);
00194           if (cb && cb->editable())
00195             connect(cb, SIGNAL(textChanged(const QString &)),
00196                     this, SIGNAL(widgetModified()));
00197         }
00198       }
00199       else
00200       {
00201         kdWarning(178) << "A widget named '" << widgetName << "' was found but there is no setting named '" << configId << "'" << endl;
00202         assert(false);
00203       }
00204     }
00205     else if (childWidget->inherits("QLabel"))
00206     {
00207       QLabel *label = static_cast<QLabel *>(childWidget);
00208       QWidget *buddy = label->buddy();
00209       if (!buddy)
00210         continue;
00211       const char *buddyName = buddy->name(0);
00212       if (buddyName && (strncmp(buddyName, "kcfg_", 5) == 0))
00213       {
00214         // This is one of our widgets!
00215         QString configId = buddyName+5;
00216         d->buddyWidget.insert(configId, childWidget);
00217       }
00218     }
00219     else if (widgetName)
00220     {
00221       QMap<QString, QCString>::const_iterator changedIt = changedMap.find(childWidget->className());
00222       if (changedIt != changedMap.end())
00223         kdDebug(178) << "Widget '" << widgetName << "' (" << childWidget->className() << ") remains unmanaged." << endl;
00224     }
00225 
00226     if(bParseChildren)
00227     {
00228       // this widget is not known as something we can store.
00229       // Maybe we can store one of its children.
00230       valueChanged |= parseChildren(childWidget, trackChanges);
00231     }
00232   }
00233   return valueChanged;
00234 }
00235 
00236 void KConfigDialogManager::updateWidgets()
00237 {
00238   bool changed = false;
00239   bool bSignalsBlocked = signalsBlocked();
00240   blockSignals(true);
00241 
00242   QWidget *widget;
00243   for( QDictIterator<QWidget> it( d->knownWidget );
00244        (widget = it.current()); ++it )
00245   {
00246      KConfigSkeletonItem *item = m_conf->findItem(it.currentKey());
00247      if (!item)
00248      {
00249         kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl;
00250         continue;
00251      }
00252 
00253      QVariant p = item->property();
00254      if (p != property(widget))
00255      {
00256         setProperty(widget, p);
00257         changed = true;
00258      }
00259      if (item->isImmutable())
00260      {
00261         widget->setEnabled(false);
00262         QWidget *buddy = d->buddyWidget.find(it.currentKey());
00263         if (buddy)
00264            buddy->setEnabled(false);
00265      }
00266   }
00267   blockSignals(bSignalsBlocked);
00268 
00269   if (changed)
00270     QTimer::singleShot(0, this, SIGNAL(widgetModified()));
00271 }
00272 
00273 void KConfigDialogManager::updateWidgetsDefault()
00274 {
00275   bool bUseDefaults = m_conf->useDefaults(true);
00276   updateWidgets();
00277   m_conf->useDefaults(bUseDefaults);
00278 }
00279 
00280 void KConfigDialogManager::updateSettings()
00281 {
00282   bool changed = false;
00283 
00284   QWidget *widget;
00285   for( QDictIterator<QWidget> it( d->knownWidget );
00286        (widget = it.current()); ++it )
00287   {
00288      KConfigSkeletonItem *item = m_conf->findItem(it.currentKey());
00289      if (!item)
00290      {
00291         kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl;
00292         continue;
00293      }
00294 
00295      QVariant p = property(widget);
00296      if (p != item->property())
00297      {
00298         item->setProperty(p);
00299         changed = true;
00300      }
00301   }
00302   if (changed)
00303   {
00304      m_conf->writeConfig();
00305      emit settingsChanged();
00306   }
00307 }
00308 
00309 void KConfigDialogManager::setProperty(QWidget *w, const QVariant &v)
00310 {
00311   QButtonGroup *bg = dynamic_cast<QButtonGroup *>(w);
00312   if (bg)
00313   {
00314     bg->setButton(v.toInt());
00315     return;
00316   }
00317 
00318   QComboBox *cb = dynamic_cast<QComboBox *>(w);
00319   if (cb && cb->editable())
00320   {
00321     cb->setCurrentText(v.toString());
00322     return;
00323   }
00324 
00325   propertyMap->setProperty(w, v);
00326 }
00327 
00328 QVariant KConfigDialogManager::property(QWidget *w)
00329 {
00330   QButtonGroup *bg = dynamic_cast<QButtonGroup *>(w);
00331   if (bg)
00332     return QVariant(bg->selectedId());
00333 
00334   QComboBox *cb = dynamic_cast<QComboBox *>(w);
00335   if (cb && cb->editable())
00336       return QVariant(cb->currentText());
00337 
00338   return propertyMap->property(w);
00339 }
00340 
00341 bool KConfigDialogManager::hasChanged()
00342 {
00343 
00344   QWidget *widget;
00345   for( QDictIterator<QWidget> it( d->knownWidget );
00346        (widget = it.current()); ++it )
00347   {
00348      KConfigSkeletonItem *item = m_conf->findItem(it.currentKey());
00349      if (!item)
00350      {
00351         kdWarning(178) << "The setting '" << it.currentKey() << "' has disappeared!" << endl;
00352         continue;
00353      }
00354 
00355      QVariant p = property(widget);
00356      if (p != item->property())
00357      {
00358 //      kdDebug(178) << "Widget for '" << it.currentKey() << "' has changed." << endl;
00359         return true;
00360      }
00361   }
00362   return false;
00363 }
00364 
00365 bool KConfigDialogManager::isDefault()
00366 {
00367   bool bUseDefaults = m_conf->useDefaults(true);
00368   bool result = !hasChanged();
00369   m_conf->useDefaults(bUseDefaults);
00370   return result;
00371 }
00372 
00373 #include "kconfigdialogmanager.moc"
00374 
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 30 10:09:38 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003