You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
451 lines
16 KiB
451 lines
16 KiB
/*
|
|
* This file is part of the KDE libraries
|
|
* Copyright (C) 2003 Benjamin C Meyer (ben+kdelibs at meyerhome dot net)
|
|
*
|
|
* 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 "kautoconfig.h"
|
|
|
|
#include <kglobal.h>
|
|
#include <qsqlpropertymap.h>
|
|
#include <qobjectlist.h>
|
|
#include <kconfig.h>
|
|
#include <kapplication.h>
|
|
#include <kdeversion.h>
|
|
|
|
/**
|
|
* Macro function to warn developers when they are making calls
|
|
* that can never return anything of value
|
|
*/
|
|
#ifndef NDEBUG
|
|
#include "kdebug.h"
|
|
#define functionCallPreOrderCheck(functionName, returnValue) \
|
|
if(!d->retrievedSettings){ \
|
|
kdDebug(180) << "KAutoConfig::"functionName"() was called before " \
|
|
"KAutoConfig::retrieveSettings(). This should NEVER happen because " \
|
|
"it will do nothing. Please Fix." << endl; \
|
|
return returnValue; \
|
|
}
|
|
|
|
#define functionCallPostOrderCheck(functionName, returnValue) \
|
|
if(d->retrievedSettings){ \
|
|
kdDebug(180) << "KAutoConfig::"functionName"() was called after " \
|
|
"KAutoConfig::retrieveSettings(). This should NEVER happen because " \
|
|
"it will do nothing. Please Fix." << endl; \
|
|
return returnValue; \
|
|
}
|
|
#else
|
|
#define functionCallPostOrderCheck(functionName, returnValue)
|
|
#define functionCallPreOrderCheck(functionName, returnValue)
|
|
#endif
|
|
|
|
class KAutoConfig::KAutoConfigPrivate {
|
|
|
|
public:
|
|
KAutoConfigPrivate() : changed(false)
|
|
#ifndef NDEBUG
|
|
, retrievedSettings(false)
|
|
#endif
|
|
{ init(); }
|
|
|
|
// Widgets to parse
|
|
QPtrList<QWidget> widgets;
|
|
// Name of the group that KConfig should be set to for each widget.
|
|
QMap<QWidget*, QString> groups;
|
|
|
|
// Child widgets of widgets to ignore
|
|
QPtrList<QWidget> ignore;
|
|
|
|
// Reset to false after saveSettings returns true.
|
|
bool changed;
|
|
|
|
#ifndef NDEBUG
|
|
// Many functions require this to be true to be of any value.
|
|
bool retrievedSettings;
|
|
#endif
|
|
|
|
// Known widgets that can be configured
|
|
QMap<QWidget*, QPtrList<QWidget> > autoWidgets;
|
|
// Default values for the widgets.
|
|
QMap<QWidget*, QVariant> defaultValues;
|
|
// Widgets to not get properties on (QLabel etc)
|
|
QAsciiDict<int> ignoreTheseWidgets;
|
|
|
|
void init(){
|
|
ignoreTheseWidgets.insert("QLabel", new int(1));
|
|
ignoreTheseWidgets.insert("QFrame", new int(2));
|
|
ignoreTheseWidgets.insert("QGroupBox", new int(3));
|
|
ignoreTheseWidgets.insert("QButtonGroup", new int(4));
|
|
ignoreTheseWidgets.insert("QWidget", new int(5));
|
|
ignoreTheseWidgets.setAutoDelete(true);
|
|
|
|
static bool defaultKDEPropertyMapInstalled = false;
|
|
if ( !defaultKDEPropertyMapInstalled && kapp ) {
|
|
kapp->installKDEPropertyMap();
|
|
defaultKDEPropertyMapInstalled = true;
|
|
}
|
|
}
|
|
};
|
|
|
|
KAutoConfig::KAutoConfig(KConfig *kconfig, QObject *parent,
|
|
const char *name) : QObject(parent, name), config(kconfig) {
|
|
d = new KAutoConfigPrivate();
|
|
}
|
|
|
|
KAutoConfig::KAutoConfig(QObject *parent, const char *name) :
|
|
QObject(parent, name), config(KGlobal::config()) {
|
|
d = new KAutoConfigPrivate();
|
|
}
|
|
|
|
KAutoConfig::~KAutoConfig(){
|
|
delete d;
|
|
}
|
|
|
|
void KAutoConfig::addWidget(QWidget *widget, const QString &group){
|
|
functionCallPostOrderCheck("addWidget",);
|
|
d->groups.insert(widget, group);
|
|
d->widgets.append(widget);
|
|
QPtrList<QWidget> newAutoConfigWidget;
|
|
d->autoWidgets.insert(widget, newAutoConfigWidget );
|
|
}
|
|
|
|
void KAutoConfig::ignoreSubWidget(QWidget *widget){
|
|
functionCallPostOrderCheck("ignoreSubWidget",);
|
|
d->ignore.append(widget);
|
|
}
|
|
|
|
bool KAutoConfig::retrieveSettings(bool trackChanges){
|
|
#ifndef NDEBUG
|
|
if(d->retrievedSettings){
|
|
kdDebug(180) << "This should not happen. Function "
|
|
"KAutoConfig::retrieveSettings() was called more then once, returning "
|
|
"false. Please fix." << endl;
|
|
return false;
|
|
}
|
|
d->retrievedSettings = true;
|
|
#endif
|
|
|
|
if(trackChanges){
|
|
// QT
|
|
changedMap.insert(QString::fromLatin1("QButton"), SIGNAL(stateChanged(int)));
|
|
changedMap.insert(QString::fromLatin1("QCheckBox"), SIGNAL(stateChanged(int)));
|
|
changedMap.insert(QString::fromLatin1("QPushButton"), SIGNAL(stateChanged(int)));
|
|
changedMap.insert(QString::fromLatin1("QRadioButton"), SIGNAL(stateChanged(int)));
|
|
changedMap.insert(QString::fromLatin1("QComboBox"), SIGNAL(activated (int)));
|
|
//qsqlproperty map doesn't store the text, but the value!
|
|
//changedMap.insert(QString::fromLatin1("QComboBox"), SIGNAL(textChanged(const QString &)));
|
|
changedMap.insert(QString::fromLatin1("QDateEdit"), SIGNAL(valueChanged(const QDate &)));
|
|
changedMap.insert(QString::fromLatin1("QDateTimeEdit"), SIGNAL(valueChanged(const QDateTime &)));
|
|
changedMap.insert(QString::fromLatin1("QDial"), SIGNAL(valueChanged (int)));
|
|
changedMap.insert(QString::fromLatin1("QLineEdit"), SIGNAL(textChanged(const QString &)));
|
|
changedMap.insert(QString::fromLatin1("QSlider"), SIGNAL(valueChanged(int)));
|
|
changedMap.insert(QString::fromLatin1("QSpinBox"), SIGNAL(valueChanged(int)));
|
|
changedMap.insert(QString::fromLatin1("QTimeEdit"), SIGNAL(valueChanged(const QTime &)));
|
|
changedMap.insert(QString::fromLatin1("QTextEdit"), SIGNAL(textChanged()));
|
|
changedMap.insert(QString::fromLatin1("QTextBrowser"), SIGNAL(sourceChanged(const QString &)));
|
|
changedMap.insert(QString::fromLatin1("QMultiLineEdit"), SIGNAL(textChanged()));
|
|
changedMap.insert(QString::fromLatin1("QListBox"), SIGNAL(selectionChanged()));
|
|
changedMap.insert(QString::fromLatin1("QTabWidget"), SIGNAL(currentChanged(QWidget *)));
|
|
|
|
// KDE
|
|
changedMap.insert( QString::fromLatin1("KComboBox"), SIGNAL(activated (int)));
|
|
changedMap.insert( QString::fromLatin1("KFontCombo"), SIGNAL(activated (int)));
|
|
changedMap.insert( QString::fromLatin1("KFontRequester"), SIGNAL(fontSelected(const QFont &)));
|
|
changedMap.insert( QString::fromLatin1("KFontChooser"), SIGNAL(fontSelected(const QFont &)));
|
|
changedMap.insert( QString::fromLatin1("KHistoryCombo"), SIGNAL(activated (int)));
|
|
|
|
changedMap.insert( QString::fromLatin1("KColorButton"), SIGNAL(changed(const QColor &)));
|
|
changedMap.insert( QString::fromLatin1("KDatePicker"), SIGNAL(dateSelected (QDate)));
|
|
changedMap.insert( QString::fromLatin1("KEditListBox"), SIGNAL(changed()));
|
|
changedMap.insert( QString::fromLatin1("KListBox"), SIGNAL(selectionChanged()));
|
|
changedMap.insert( QString::fromLatin1("KLineEdit"), SIGNAL(textChanged(const QString &)));
|
|
changedMap.insert( QString::fromLatin1("KPasswordEdit"), SIGNAL(textChanged(const QString &)));
|
|
changedMap.insert( QString::fromLatin1("KRestrictedLine"), SIGNAL(textChanged(const QString &)));
|
|
changedMap.insert( QString::fromLatin1("KTextBrowser"), SIGNAL(sourceChanged(const QString &)));
|
|
changedMap.insert( QString::fromLatin1("KTextEdit"), SIGNAL(textChanged()));
|
|
changedMap.insert( QString::fromLatin1("KURLRequester"), SIGNAL(textChanged (const QString& )));
|
|
changedMap.insert( QString::fromLatin1("KIntNumInput"), SIGNAL(valueChanged (int)));
|
|
changedMap.insert( QString::fromLatin1("KIntSpinBox"), SIGNAL(valueChanged (int)));
|
|
changedMap.insert( QString::fromLatin1("KDoubleNumInput"), SIGNAL(valueChanged (double)));
|
|
}
|
|
|
|
// Go through all of the children of the widgets and find all known widgets
|
|
QPtrListIterator<QWidget> it( d->widgets );
|
|
QWidget *widget;
|
|
bool usingDefaultValues = false;
|
|
while ( (widget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[widget]);
|
|
usingDefaultValues |= parseChildren(widget, d->autoWidgets[widget], trackChanges);
|
|
}
|
|
return usingDefaultValues;
|
|
}
|
|
|
|
bool KAutoConfig::saveSettings() {
|
|
functionCallPreOrderCheck("saveSettings", false);
|
|
|
|
QSqlPropertyMap *propertyMap = QSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
QPtrListIterator<QWidget> it( d->widgets );
|
|
QWidget *widget;
|
|
while ( (widget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[widget]);
|
|
|
|
// Go through the known autowidgets of this widget and save
|
|
QPtrListIterator<QWidget> it( d->autoWidgets[widget] );
|
|
QWidget *groupWidget;
|
|
bool widgetChanged = false;
|
|
while ( (groupWidget = it.current()) != 0 ){
|
|
++it;
|
|
QVariant defaultValue = d->defaultValues[groupWidget];
|
|
QVariant currentValue = propertyMap->property(groupWidget);
|
|
#if KDE_IS_VERSION( 3, 1, 90 )
|
|
if(!config->hasDefault(QString::fromLatin1(groupWidget->name())) && currentValue == defaultValue){
|
|
config->revertToDefault(QString::fromLatin1(groupWidget->name()));
|
|
widgetChanged = true;
|
|
}
|
|
else{
|
|
#endif
|
|
QVariant savedValue = config->readPropertyEntry(groupWidget->name(),
|
|
defaultValue);
|
|
if(savedValue != currentValue){
|
|
config->writeEntry(groupWidget->name(), currentValue);
|
|
widgetChanged = true;
|
|
}
|
|
#if KDE_IS_VERSION( 3, 1, 90 )
|
|
}
|
|
#endif
|
|
}
|
|
d->changed |= widgetChanged;
|
|
if(widgetChanged)
|
|
emit( settingsChanged(widget) );
|
|
}
|
|
|
|
if(d->changed){
|
|
emit( settingsChanged() );
|
|
d->changed = false;
|
|
config->sync();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool KAutoConfig::hasChanged() const {
|
|
functionCallPreOrderCheck("hasChanged", false);
|
|
|
|
QSqlPropertyMap *propertyMap = QSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
QPtrListIterator<QWidget> it( d->widgets );
|
|
QWidget *widget;
|
|
while ( (widget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[widget]);
|
|
// Go through the known autowidgets of this widget and save
|
|
QPtrListIterator<QWidget> it( d->autoWidgets[widget] );
|
|
QWidget *groupWidget;
|
|
while ( (groupWidget = it.current()) != 0 ){
|
|
++it;
|
|
QVariant defaultValue = d->defaultValues[groupWidget];
|
|
QVariant currentValue = propertyMap->property(groupWidget);
|
|
QVariant savedValue = config->readPropertyEntry(groupWidget->name(),
|
|
defaultValue);
|
|
|
|
// Return once just one item is found to have changed.
|
|
if((currentValue == defaultValue && savedValue != currentValue) ||
|
|
(savedValue != currentValue))
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool KAutoConfig::isDefault() const {
|
|
functionCallPreOrderCheck("isDefault", false);
|
|
|
|
QSqlPropertyMap *propertyMap = QSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
QPtrListIterator<QWidget> it( d->widgets );
|
|
QWidget *widget;
|
|
while ( (widget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[widget]);
|
|
// Go through the known autowidgets of this widget and save
|
|
QPtrListIterator<QWidget> it( d->autoWidgets[widget] );
|
|
QWidget *groupWidget;
|
|
while ( (groupWidget = it.current()) != 0 ){
|
|
++it;
|
|
QVariant defaultValue = d->defaultValues[groupWidget];
|
|
QVariant currentValue = propertyMap->property(groupWidget);
|
|
if(currentValue != defaultValue){
|
|
//qDebug("groupWidget %s, has changed: default: %s new: %s", groupWidget->name(), defaultValue.toString().latin1(), currentValue.toString().latin1());
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void KAutoConfig::resetSettings() const {
|
|
functionCallPreOrderCheck("resetSettings",);
|
|
|
|
QSqlPropertyMap *propertyMap = QSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
QPtrListIterator<QWidget> it( d->widgets );
|
|
QWidget *widget;
|
|
while ( (widget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[widget]);
|
|
|
|
// Go through the known autowidgets of this widget and save
|
|
QPtrListIterator<QWidget> it( d->autoWidgets[widget] );
|
|
QWidget *groupWidget;
|
|
while ( (groupWidget = it.current()) != 0 ){
|
|
++it;
|
|
QVariant defaultValue = d->defaultValues[groupWidget];
|
|
if(defaultValue != propertyMap->property(groupWidget)){
|
|
propertyMap->setProperty(groupWidget, defaultValue);
|
|
d->changed = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KAutoConfig::reloadSettings() const {
|
|
functionCallPreOrderCheck("reloadSettings", );
|
|
|
|
QSqlPropertyMap *propertyMap = QSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
QPtrListIterator<QWidget> it( d->widgets );
|
|
QWidget *pageWidget;
|
|
while ( (pageWidget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[pageWidget]);
|
|
|
|
// Go through the known widgets of this page and reload
|
|
QPtrListIterator<QWidget> it( d->autoWidgets[pageWidget] );
|
|
QWidget *widget;
|
|
while ( (widget = it.current()) != 0 ){
|
|
++it;
|
|
QVariant defaultSetting = d->defaultValues[widget];
|
|
QVariant setting =
|
|
config->readPropertyEntry(widget->name(), defaultSetting);
|
|
propertyMap->setProperty(widget, setting);
|
|
}
|
|
}
|
|
d->changed = false;
|
|
}
|
|
|
|
bool KAutoConfig::parseChildren(const QWidget *widget,
|
|
QPtrList<QWidget>& currentGroup, bool trackChanges){
|
|
bool valueChanged = false;
|
|
const QPtrList<QObject> *listOfChildren = widget->children();
|
|
if(!listOfChildren)
|
|
return valueChanged;
|
|
|
|
QSqlPropertyMap *propertyMap = QSqlPropertyMap::defaultMap();
|
|
QPtrListIterator<QObject> it( *listOfChildren );
|
|
QObject *object;
|
|
while ( (object = it.current()) != 0 )
|
|
{
|
|
++it;
|
|
if(!object->isWidgetType()){
|
|
continue;
|
|
}
|
|
QWidget *childWidget = (QWidget *)object;
|
|
if(d->ignore.containsRef(childWidget)){
|
|
continue;
|
|
}
|
|
|
|
bool parseTheChildren = true;
|
|
#ifndef NDEBUG
|
|
if(d->ignoreTheseWidgets[childWidget->className()] == 0 &&
|
|
childWidget->name(0) == NULL){
|
|
// Without a name the widget is just skipped over.
|
|
kdDebug(180) << "KAutoConfig::retrieveSettings, widget with "
|
|
"NULL name. className: " << childWidget->className() << endl;
|
|
}
|
|
#endif
|
|
|
|
|
|
if( d->ignoreTheseWidgets[childWidget->className()] == 0 &&
|
|
childWidget->name(0) != NULL )
|
|
{
|
|
QVariant defaultSetting = propertyMap->property(childWidget);
|
|
if(defaultSetting.isValid())
|
|
{
|
|
parseTheChildren = false;
|
|
// Disable the widget if it is immutable?
|
|
if(config->entryIsImmutable( QString::fromLatin1(childWidget->name())))
|
|
childWidget->setEnabled(false);
|
|
else
|
|
{
|
|
// FOR THOSE WHO ARE LOOKING
|
|
// Here is the code were the widget is actually marked to watch.
|
|
//qDebug("KAutoConfig: Adding widget(%s)",childWidget->name());
|
|
currentGroup.append(childWidget);
|
|
d->defaultValues.insert(childWidget, defaultSetting);
|
|
}
|
|
// Get/Set settings and connect up the changed signal
|
|
QVariant setting =
|
|
config->readPropertyEntry(childWidget->name(), defaultSetting);
|
|
if(setting != defaultSetting)
|
|
{
|
|
propertyMap->setProperty(childWidget, setting);
|
|
valueChanged = true;
|
|
}
|
|
if(trackChanges && changedMap.find(QString::fromLatin1(childWidget->className())) !=
|
|
changedMap.end())
|
|
{
|
|
connect(childWidget, changedMap[QString::fromLatin1(childWidget->className())],
|
|
this, SIGNAL(widgetModified()));
|
|
}
|
|
#ifndef NDEBUG
|
|
else if(trackChanges &&
|
|
changedMap.find(QString::fromLatin1(childWidget->className())) == changedMap.end())
|
|
{
|
|
// Without a signal kautoconfigdialog could incorectly
|
|
// enable/disable the buttons
|
|
kdDebug(180) << "KAutoConfig::retrieveSettings, Unknown changed "
|
|
"signal for widget:" << childWidget->className() << endl;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
#ifndef NDEBUG
|
|
else
|
|
{
|
|
// If kautoconfig doesn't know how to get/set the widget's value
|
|
// nothing can be done to it and it is skipped.
|
|
kdDebug(180) << "KAutoConfig::retrieveSettings, Unknown widget:"
|
|
<< childWidget->className() << endl;
|
|
}
|
|
#endif
|
|
}
|
|
if(parseTheChildren)
|
|
{
|
|
// this widget is not known as something we can store.
|
|
// Maybe we can store one of its children.
|
|
valueChanged |= parseChildren(childWidget, currentGroup, trackChanges);
|
|
}
|
|
}
|
|
return valueChanged;
|
|
}
|
|
|
|
#include "kautoconfig.moc"
|
|
|