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.
tdenetwork/kopete/libkopete/kautoconfig.cpp

451 lines
17 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 <tqsqlpropertymap.h>
#include <tqobjectlist.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
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"