kdecore Library: kconfigdialogmanager.cpp Source File (kdecore Library)

| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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() : 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     // QT
    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     // We can only store one thing, so you can't have
    00077     // a ButtonGroup that is checkable.
    00078     changedMap.insert("QButtonGroup", SIGNAL(clicked(int)));
    00079     changedMap.insert("QGroupBox", SIGNAL(toggled(bool)));
    00080     changedMap.insert("QComboBox", SIGNAL(activated (int)));
    00081     //qsqlproperty map doesn't store the text, but the value!
    00082     //changedMap.insert("QComboBox", SIGNAL(textChanged(const QString &)));
    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     // KDE
    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   // Go through all of the children of the widgets and find all known widgets
    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; // Skip non-widgets
    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       // This is one of our widgets!
    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            // 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 KConfigXT 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, 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         // This is one of our widgets!
    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       // this widget is not known as something we can store.
    00252       // Maybe we can store one of its children.
    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 //        kdDebug(178) << "The setting '" << it.currentKey() << "' [" << widget->className() << "] has changed" << endl;
    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 //        kdDebug(178) << "Widget for '" << it.currentKey() << "' has changed." << endl;
    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

This file is part of the documentation for kdecore Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:18:03 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003