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
17 KiB
451 lines
17 KiB
/*
|
|
* This file is part of the KDE libraries
|
|
* Copyright (C) 2003 Benjamin C Meyer (ben+tdelibs 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 <tqsqlpropertymap.h>
|
|
#include <tqobjectlist.h>
|
|
#include <kconfig.h>
|
|
#include <kapplication.h>
|
|
#include <tdeversion.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
|
|
TQPtrList<TQWidget> widgets;
|
|
// Name of the group that KConfig should be set to for each widget.
|
|
TQMap<TQWidget*, TQString> groups;
|
|
|
|
// Child widgets of widgets to ignore
|
|
TQPtrList<TQWidget> 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
|
|
TQMap<TQWidget*, TQPtrList<TQWidget> > autoWidgets;
|
|
// Default values for the widgets.
|
|
TQMap<TQWidget*, TQVariant> defaultValues;
|
|
// Widgets to not get properties on (TQLabel etc)
|
|
TQAsciiDict<int> ignoreTheseWidgets;
|
|
|
|
void init(){
|
|
ignoreTheseWidgets.insert(TQLABEL_OBJECT_NAME_STRING, new int(1));
|
|
ignoreTheseWidgets.insert(TQFRAME_OBJECT_NAME_STRING, new int(2));
|
|
ignoreTheseWidgets.insert(TQGROUPBOX_OBJECT_NAME_STRING, new int(3));
|
|
ignoreTheseWidgets.insert(TQBUTTONGROUP_OBJECT_NAME_STRING, new int(4));
|
|
ignoreTheseWidgets.insert(TQWIDGET_OBJECT_NAME_STRING, new int(5));
|
|
ignoreTheseWidgets.setAutoDelete(true);
|
|
|
|
static bool defaultKDEPropertyMapInstalled = false;
|
|
if ( !defaultKDEPropertyMapInstalled && kapp ) {
|
|
kapp->installKDEPropertyMap();
|
|
defaultKDEPropertyMapInstalled = true;
|
|
}
|
|
}
|
|
};
|
|
|
|
KAutoConfig::KAutoConfig(KConfig *kconfig, TQObject *parent,
|
|
const char *name) : TQObject(parent, name), config(kconfig) {
|
|
d = new KAutoConfigPrivate();
|
|
}
|
|
|
|
KAutoConfig::KAutoConfig(TQObject *parent, const char *name) :
|
|
TQObject(parent, name), config(KGlobal::config()) {
|
|
d = new KAutoConfigPrivate();
|
|
}
|
|
|
|
KAutoConfig::~KAutoConfig(){
|
|
delete d;
|
|
}
|
|
|
|
void KAutoConfig::addWidget(TQWidget *widget, const TQString &group){
|
|
functionCallPostOrderCheck("addWidget",);
|
|
d->groups.insert(widget, group);
|
|
d->widgets.append(widget);
|
|
TQPtrList<TQWidget> newAutoConfigWidget;
|
|
d->autoWidgets.insert(widget, newAutoConfigWidget );
|
|
}
|
|
|
|
void KAutoConfig::ignoreSubWidget(TQWidget *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(TQString::fromLatin1(TQBUTTON_OBJECT_NAME_STRING), TQT_SIGNAL(stateChanged(int)));
|
|
changedMap.insert(TQString::fromLatin1(TQCHECKBOX_OBJECT_NAME_STRING), TQT_SIGNAL(stateChanged(int)));
|
|
changedMap.insert(TQString::fromLatin1(TQPUSHBUTTON_OBJECT_NAME_STRING), TQT_SIGNAL(stateChanged(int)));
|
|
changedMap.insert(TQString::fromLatin1(TQRADIOBUTTON_OBJECT_NAME_STRING), TQT_SIGNAL(stateChanged(int)));
|
|
changedMap.insert(TQString::fromLatin1(TQCOMBOBOX_OBJECT_NAME_STRING), TQT_SIGNAL(activated (int)));
|
|
//qsqlproperty map doesn't store the text, but the value!
|
|
//changedMap.insert(TQString::fromLatin1(TQCOMBOBOX_OBJECT_NAME_STRING), TQT_SIGNAL(textChanged(const TQString &)));
|
|
changedMap.insert(TQString::fromLatin1(TQDATEEDIT_OBJECT_NAME_STRING), TQT_SIGNAL(valueChanged(const TQDate &)));
|
|
changedMap.insert(TQString::fromLatin1(TQDATETIMEEDIT_OBJECT_NAME_STRING), TQT_SIGNAL(valueChanged(const TQDateTime &)));
|
|
changedMap.insert(TQString::fromLatin1(TQDIAL_OBJECT_NAME_STRING), TQT_SIGNAL(valueChanged (int)));
|
|
changedMap.insert(TQString::fromLatin1(TQLINEEDIT_OBJECT_NAME_STRING), TQT_SIGNAL(textChanged(const TQString &)));
|
|
changedMap.insert(TQString::fromLatin1(TQSLIDER_OBJECT_NAME_STRING), TQT_SIGNAL(valueChanged(int)));
|
|
changedMap.insert(TQString::fromLatin1(TQSPINBOX_OBJECT_NAME_STRING), TQT_SIGNAL(valueChanged(int)));
|
|
changedMap.insert(TQString::fromLatin1(TQTIMEEDIT_OBJECT_NAME_STRING), TQT_SIGNAL(valueChanged(const TQTime &)));
|
|
changedMap.insert(TQString::fromLatin1(TQTEXTEDIT_OBJECT_NAME_STRING), TQT_SIGNAL(textChanged()));
|
|
changedMap.insert(TQString::fromLatin1(TQTEXTBROWSER_OBJECT_NAME_STRING), TQT_SIGNAL(sourceChanged(const TQString &)));
|
|
changedMap.insert(TQString::fromLatin1(TQMULTILINEEDIT_OBJECT_NAME_STRING), TQT_SIGNAL(textChanged()));
|
|
changedMap.insert(TQString::fromLatin1(TQLISTBOX_OBJECT_NAME_STRING), TQT_SIGNAL(selectionChanged()));
|
|
changedMap.insert(TQString::fromLatin1(TQTABWIDGET_OBJECT_NAME_STRING), TQT_SIGNAL(currentChanged(TQWidget *)));
|
|
|
|
// KDE
|
|
changedMap.insert( TQString::fromLatin1("KComboBox"), TQT_SIGNAL(activated (int)));
|
|
changedMap.insert( TQString::fromLatin1("KFontCombo"), TQT_SIGNAL(activated (int)));
|
|
changedMap.insert( TQString::fromLatin1("KFontRequester"), TQT_SIGNAL(fontSelected(const TQFont &)));
|
|
changedMap.insert( TQString::fromLatin1("KFontChooser"), TQT_SIGNAL(fontSelected(const TQFont &)));
|
|
changedMap.insert( TQString::fromLatin1("KHistoryCombo"), TQT_SIGNAL(activated (int)));
|
|
|
|
changedMap.insert( TQString::fromLatin1("KColorButton"), TQT_SIGNAL(changed(const TQColor &)));
|
|
changedMap.insert( TQString::fromLatin1("KDatePicker"), TQT_SIGNAL(dateSelected (TQDate)));
|
|
changedMap.insert( TQString::fromLatin1("KEditListBox"), TQT_SIGNAL(changed()));
|
|
changedMap.insert( TQString::fromLatin1("KListBox"), TQT_SIGNAL(selectionChanged()));
|
|
changedMap.insert( TQString::fromLatin1("KLineEdit"), TQT_SIGNAL(textChanged(const TQString &)));
|
|
changedMap.insert( TQString::fromLatin1("KPasswordEdit"), TQT_SIGNAL(textChanged(const TQString &)));
|
|
changedMap.insert( TQString::fromLatin1("KRestrictedLine"), TQT_SIGNAL(textChanged(const TQString &)));
|
|
changedMap.insert( TQString::fromLatin1("KTextBrowser"), TQT_SIGNAL(sourceChanged(const TQString &)));
|
|
changedMap.insert( TQString::fromLatin1("KTextEdit"), TQT_SIGNAL(textChanged()));
|
|
changedMap.insert( TQString::fromLatin1("KURLRequester"), TQT_SIGNAL(textChanged (const TQString& )));
|
|
changedMap.insert( TQString::fromLatin1("KIntNumInput"), TQT_SIGNAL(valueChanged (int)));
|
|
changedMap.insert( TQString::fromLatin1("KIntSpinBox"), TQT_SIGNAL(valueChanged (int)));
|
|
changedMap.insert( TQString::fromLatin1("KDoubleNumInput"), TQT_SIGNAL(valueChanged (double)));
|
|
}
|
|
|
|
// Go through all of the children of the widgets and find all known widgets
|
|
TQPtrListIterator<TQWidget> it( d->widgets );
|
|
TQWidget *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);
|
|
|
|
TQSqlPropertyMap *propertyMap = TQSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
TQPtrListIterator<TQWidget> it( d->widgets );
|
|
TQWidget *widget;
|
|
while ( (widget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[widget]);
|
|
|
|
// Go through the known autowidgets of this widget and save
|
|
TQPtrListIterator<TQWidget> it( d->autoWidgets[widget] );
|
|
TQWidget *groupWidget;
|
|
bool widgetChanged = false;
|
|
while ( (groupWidget = it.current()) != 0 ){
|
|
++it;
|
|
TQVariant defaultValue = d->defaultValues[groupWidget];
|
|
TQVariant currentValue = propertyMap->property(groupWidget);
|
|
#if KDE_IS_VERSION( 3, 1, 90 )
|
|
if(!config->hasDefault(TQString::fromLatin1(groupWidget->name())) && currentValue == defaultValue){
|
|
config->revertToDefault(TQString::fromLatin1(groupWidget->name()));
|
|
widgetChanged = true;
|
|
}
|
|
else{
|
|
#endif
|
|
TQVariant 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);
|
|
|
|
TQSqlPropertyMap *propertyMap = TQSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
TQPtrListIterator<TQWidget> it( d->widgets );
|
|
TQWidget *widget;
|
|
while ( (widget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[widget]);
|
|
// Go through the known autowidgets of this widget and save
|
|
TQPtrListIterator<TQWidget> it( d->autoWidgets[widget] );
|
|
TQWidget *groupWidget;
|
|
while ( (groupWidget = it.current()) != 0 ){
|
|
++it;
|
|
TQVariant defaultValue = d->defaultValues[groupWidget];
|
|
TQVariant currentValue = propertyMap->property(groupWidget);
|
|
TQVariant 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);
|
|
|
|
TQSqlPropertyMap *propertyMap = TQSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
TQPtrListIterator<TQWidget> it( d->widgets );
|
|
TQWidget *widget;
|
|
while ( (widget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[widget]);
|
|
// Go through the known autowidgets of this widget and save
|
|
TQPtrListIterator<TQWidget> it( d->autoWidgets[widget] );
|
|
TQWidget *groupWidget;
|
|
while ( (groupWidget = it.current()) != 0 ){
|
|
++it;
|
|
TQVariant defaultValue = d->defaultValues[groupWidget];
|
|
TQVariant 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",);
|
|
|
|
TQSqlPropertyMap *propertyMap = TQSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
TQPtrListIterator<TQWidget> it( d->widgets );
|
|
TQWidget *widget;
|
|
while ( (widget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[widget]);
|
|
|
|
// Go through the known autowidgets of this widget and save
|
|
TQPtrListIterator<TQWidget> it( d->autoWidgets[widget] );
|
|
TQWidget *groupWidget;
|
|
while ( (groupWidget = it.current()) != 0 ){
|
|
++it;
|
|
TQVariant defaultValue = d->defaultValues[groupWidget];
|
|
if(defaultValue != propertyMap->property(groupWidget)){
|
|
propertyMap->setProperty(groupWidget, defaultValue);
|
|
d->changed = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KAutoConfig::reloadSettings() const {
|
|
functionCallPreOrderCheck("reloadSettings", );
|
|
|
|
TQSqlPropertyMap *propertyMap = TQSqlPropertyMap::defaultMap();
|
|
// Go through all of the widgets
|
|
TQPtrListIterator<TQWidget> it( d->widgets );
|
|
TQWidget *pageWidget;
|
|
while ( (pageWidget = it.current()) != 0 ) {
|
|
++it;
|
|
config->setGroup(d->groups[pageWidget]);
|
|
|
|
// Go through the known widgets of this page and reload
|
|
TQPtrListIterator<TQWidget> it( d->autoWidgets[pageWidget] );
|
|
TQWidget *widget;
|
|
while ( (widget = it.current()) != 0 ){
|
|
++it;
|
|
TQVariant defaultSetting = d->defaultValues[widget];
|
|
TQVariant setting =
|
|
config->readPropertyEntry(widget->name(), defaultSetting);
|
|
propertyMap->setProperty(widget, setting);
|
|
}
|
|
}
|
|
d->changed = false;
|
|
}
|
|
|
|
bool KAutoConfig::parseChildren(const TQWidget *widget,
|
|
TQPtrList<TQWidget>& currentGroup, bool trackChanges){
|
|
bool valueChanged = false;
|
|
const TQObjectList listOfChildren = widget->childrenListObject();
|
|
if(listOfChildren.isEmpty())
|
|
return valueChanged;
|
|
|
|
TQSqlPropertyMap *propertyMap = TQSqlPropertyMap::defaultMap();
|
|
TQPtrListIterator<TQObject> it( listOfChildren );
|
|
TQObject *object;
|
|
while ( (object = it.current()) != 0 )
|
|
{
|
|
++it;
|
|
if(!object->isWidgetType()){
|
|
continue;
|
|
}
|
|
TQWidget *childWidget = (TQWidget *)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 )
|
|
{
|
|
TQVariant defaultSetting = propertyMap->property(childWidget);
|
|
if(defaultSetting.isValid())
|
|
{
|
|
parseTheChildren = false;
|
|
// Disable the widget if it is immutable?
|
|
if(config->entryIsImmutable( TQString::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
|
|
TQVariant setting =
|
|
config->readPropertyEntry(childWidget->name(), defaultSetting);
|
|
if(setting != defaultSetting)
|
|
{
|
|
propertyMap->setProperty(childWidget, setting);
|
|
valueChanged = true;
|
|
}
|
|
if(trackChanges && changedMap.find(TQString::fromLatin1(childWidget->className())) !=
|
|
changedMap.end())
|
|
{
|
|
connect(childWidget, changedMap[TQString::fromLatin1(childWidget->className())],
|
|
this, TQT_SIGNAL(widgetModified()));
|
|
}
|
|
#ifndef NDEBUG
|
|
else if(trackChanges &&
|
|
changedMap.find(TQString::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"
|
|
|