summaryrefslogtreecommitdiffstats
path: root/src/UiGuiSettings.cpp
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2022-07-16 15:18:45 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2022-07-16 15:18:45 +0900
commitd017bd37253ae35b29d82e3277b9adcbb4517dd0 (patch)
treed884d5cf71c4dd350d1abcf752c438e117a872d5 /src/UiGuiSettings.cpp
parenta0148cf62fc298126980a7dc27603b123e1d764c (diff)
downloaduniversal-indent-gui-tqt-d017bd37253ae35b29d82e3277b9adcbb4517dd0.tar.gz
universal-indent-gui-tqt-d017bd37253ae35b29d82e3277b9adcbb4517dd0.zip
Convert files to unix format. Convert C++ header names to C header names.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'src/UiGuiSettings.cpp')
-rwxr-xr-xsrc/UiGuiSettings.cpp1376
1 files changed, 688 insertions, 688 deletions
diff --git a/src/UiGuiSettings.cpp b/src/UiGuiSettings.cpp
index f997ec3..5d8349b 100755
--- a/src/UiGuiSettings.cpp
+++ b/src/UiGuiSettings.cpp
@@ -1,688 +1,688 @@
-/***************************************************************************
-* Copyright (C) 2006-2012 by Thomas Schweitzer *
-* thomas-schweitzer(at)arcor.de *
-* *
-* This program is free software; you can redistribute it and/or modify *
-* it under the terms of the GNU General Public License version 2.0 as *
-* published by the Free Software Foundation. *
-* *
-* This program 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 General Public License for more details. *
-* *
-* You should have received a copy of the GNU General Public License *
-* along with this program in the file LICENSE.GPL; if not, write to the *
-* Free Software Foundation, Inc., *
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
-***************************************************************************/
-
-#include "UiGuiSettings.h"
-
-#include "SettingsPaths.h"
-
-#include <QSettings>
-#include <QPoint>
-#include <QSize>
-#include <QDir>
-#include <QDate>
-#include <QStringList>
-#include <QCoreApplication>
-#include <QMetaMethod>
-#include <QMetaProperty>
-#include <QWidget>
-
-//! \defgroup grp_Settings All concerning the settings.
-
-/*!
- \class UiGuiSettings
- \ingroup grp_Settings
- \brief Handles the settings of the program. Reads them on startup and saves them on exit.
- Is a singleton class and can only be accessed via getInstance().
-*/
-
-// Inits the single class instance pointer.
-QWeakPointer<UiGuiSettings> UiGuiSettings::_instance;
-
-
-/*!
- \brief The constructor for the settings.
-*/
-UiGuiSettings::UiGuiSettings() : QObject() {
- // Create the main application settings object from the UniversalIndentGUI.ini file.
- _qsettings = new QSettings(SettingsPaths::getSettingsPath() + "/UniversalIndentGUI.ini", QSettings::IniFormat, this);
-
- _indenterDirctoryStr = SettingsPaths::getGlobalFilesPath() + "/indenters";
- readAvailableTranslations();
- initSettings();
-}
-
-
-/*!
- \brief Returns the instance of the settings class. If no instance exists, ONE will be created.
- */
-QSharedPointer<UiGuiSettings> UiGuiSettings::getInstance() {
- QSharedPointer<UiGuiSettings> sharedInstance = _instance.toStrongRef();
- if ( sharedInstance.isNull() ) {
- // Create the settings object, which loads all UiGui settings from a file.
- sharedInstance = QSharedPointer<UiGuiSettings>(new UiGuiSettings());
- _instance = sharedInstance.toWeakRef();
- }
-
- return sharedInstance;
-}
-
-
-/*!
- \brief The destructor saves the settings to a file.
- */
-UiGuiSettings::~UiGuiSettings() {
- // Convert the language setting from an integer index to a string.
- int index = _qsettings->value("UniversalIndentGUI/language", 0).toInt();
- if ( index < 0 || index >= _availableTranslations.size() )
- index = 0;
-
- _qsettings->setValue( "UniversalIndentGUI/language", _availableTranslations.at(index) );
-}
-
-
-/*!
- \brief Scans the translations directory for available translation files and
- stores them in the QList \a _availableTranslations.
- */
-void UiGuiSettings::readAvailableTranslations() {
- QString languageShort;
- QStringList languageFileList;
-
- // English is the default language. A translation file does not exist but to have a menu entry, added here.
- languageFileList << "universalindent_en.qm";
-
- // Find all translation files in the "translations" directory.
- QDir translationDirectory = QDir( SettingsPaths::getGlobalFilesPath() + "/translations" );
- languageFileList << translationDirectory.entryList( QStringList("universalindent_*.qm") );
-
- // Loop for each found translation file
- foreach ( languageShort, languageFileList ) {
- // Remove the leading string "universalindent_" from the filename.
- languageShort.remove(0,16);
- // Remove trailing file extension ".qm".
- languageShort.chop(3);
-
- _availableTranslations.append(languageShort);
- }
-}
-
-
-/*!
- \brief Returns a list of the mnemonics of the available translations.
- */
-QStringList UiGuiSettings::getAvailableTranslations() {
- return _availableTranslations;
-}
-
-
-/*!
- \brief Returns the value of the by \a settingsName defined setting as QVariant.
-
- If the named setting does not exist, 0 is being returned.
-*/
-QVariant UiGuiSettings::getValueByName(QString settingName) {
- return _qsettings->value("UniversalIndentGUI/" + settingName);
-}
-
-
-/*!
- \brief Loads the settings for the main application.
-
- Settings are for example last selected indenter, last loaded source code file and so on.
-*/
-bool UiGuiSettings::initSettings()
-{
- // Read the version string saved in the settings file.
- _qsettings->setValue( "UniversalIndentGUI/version", _qsettings->value("UniversalIndentGUI/version", "") );
-
- // Read windows last size and position from the settings file.
- _qsettings->setValue( "UniversalIndentGUI/maximized", _qsettings->value("UniversalIndentGUI/maximized", false) );
- _qsettings->setValue( "UniversalIndentGUI/position", _qsettings->value("UniversalIndentGUI/position", QPoint(50, 50)) );
- _qsettings->setValue( "UniversalIndentGUI/size", _qsettings->value("UniversalIndentGUI/size", QSize(800, 600)) );
-
- // Read last selected encoding for the opened source code file.
- _qsettings->setValue( "UniversalIndentGUI/encoding", _qsettings->value("UniversalIndentGUI/encoding", "UTF-8") );
-
- // Read maximum length of list for recently opened files.
- _qsettings->setValue( "UniversalIndentGUI/recentlyOpenedListSize", _qsettings->value("UniversalIndentGUI/recentlyOpenedListSize", 5) );
-
- // Read if last opened source code file should be loaded on startup.
- _qsettings->setValue( "UniversalIndentGUI/loadLastSourceCodeFileOnStartup", _qsettings->value("UniversalIndentGUI/loadLastSourceCodeFileOnStartup", true) );
-
- // Read last opened source code file from the settings file.
- _qsettings->setValue( "UniversalIndentGUI/lastSourceCodeFile", _qsettings->value("UniversalIndentGUI/lastSourceCodeFile", _indenterDirctoryStr+"/example.cpp") );
-
- // Read last selected indenter from the settings file.
- int selectedIndenter = _qsettings->value("UniversalIndentGUI/selectedIndenter", 0).toInt();
- if ( selectedIndenter < 0 ) {
- selectedIndenter = 0;
- }
- _qsettings->setValue( "UniversalIndentGUI/selectedIndenter", selectedIndenter );
-
- // Read if syntax highlighting is enabled.
- _qsettings->setValue( "UniversalIndentGUI/SyntaxHighlightingEnabled", _qsettings->value("UniversalIndentGUI/SyntaxHighlightingEnabled", true) );
-
- // Read if white space characters should be displayed.
- _qsettings->setValue( "UniversalIndentGUI/whiteSpaceIsVisible", _qsettings->value("UniversalIndentGUI/whiteSpaceIsVisible", false) );
-
- // Read if indenter parameter tool tips are enabled.
- _qsettings->setValue( "UniversalIndentGUI/indenterParameterTooltipsEnabled", _qsettings->value("UniversalIndentGUI/indenterParameterTooltipsEnabled", true) );
-
- // Read the tab width from the settings file.
- _qsettings->setValue( "UniversalIndentGUI/tabWidth", _qsettings->value("UniversalIndentGUI/tabWidth", 4) );
-
- // Read the last selected language and stores the index it has in the list of available translations.
- _qsettings->setValue( "UniversalIndentGUI/language", _availableTranslations.indexOf( _qsettings->value("UniversalIndentGUI/language", "").toString() ) );
-
- // Read the update check settings from the settings file.
- _qsettings->setValue( "UniversalIndentGUI/CheckForUpdate", _qsettings->value("UniversalIndentGUI/CheckForUpdate", false) );
- _qsettings->setValue( "UniversalIndentGUI/LastUpdateCheck", _qsettings->value("UniversalIndentGUI/LastUpdateCheck", QDate(1900,1,1)) );
-
- // Read the main window state.
- _qsettings->setValue( "UniversalIndentGUI/MainWindowState", _qsettings->value("UniversalIndentGUI/MainWindowState", QByteArray()) );
-
- return true;
-}
-
-
-/*!
- \brief Register the by \a propertyName defined property of \a obj to be connected to the setting defined by \a settingName.
-
- The \a propertyName must be one of those that are listed in the Qt "Properties" documentation section of a Qt Object.
- All further needed info is retrieved via the \a obj's MetaObject, like the to the property bound signal.
- */
-bool UiGuiSettings::registerObjectProperty( QObject *obj, const QString &propertyName, const QString &settingName )
-{
- const QMetaObject *metaObject = obj->metaObject();
- bool connectSuccess = false;
-
- // Connect to the objects destroyed signal, so that it will be correctly unregistered.
- connectSuccess = connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectProperty(QObject*)));
-
- int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
- if ( connectSuccess && indexOfProp > -1 ) {
- QMetaProperty mProp = metaObject->property(indexOfProp);
-
- // Connect to the property's value changed signal.
- if ( mProp.hasNotifySignal() ) {
- QMetaMethod signal = mProp.notifySignal();
- //QString teststr = qPrintable(SIGNAL() + QString(signal.signature()));
- // The command "SIGNAL() + QString(signal.signature())" assembles the signal methods signature to a valid Qt SIGNAL.
- connectSuccess = connect(obj, qPrintable(SIGNAL() + QString(signal.signature())), this, SLOT(handleObjectPropertyChange()));
- }
-
- if ( connectSuccess ) {
- _registeredObjectProperties[obj] = QStringList() << propertyName << settingName;
- }
- else {
- //TODO: Write a debug warning to the log.
- disconnect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectProperty(QObject*)));
- return false;
- }
-
- // If setting already exists, set the objects property to the setting value.
- if ( _qsettings->contains("UniversalIndentGUI/" + settingName) ) {
- mProp.write(obj, _qsettings->value("UniversalIndentGUI/" + settingName));
- }
- // Otherwise add the setting and set it to the value of the objects property.
- else {
- _qsettings->setValue("UniversalIndentGUI/" + settingName, mProp.read(obj));
- }
- }
- else {
- //TODO: Write a debug warning to the log.
- disconnect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectProperty(QObject*)));
- return false;
- }
-
- return true;
-}
-
-
-/*!
- \brief Searches the child QObjects of \a obj for a property name and setting name definition within
- their custom properties and registers this property name to that setting name if both were found.
-
- The custom properties, for which are searched, are "connectedPropertyName" and "connectedSettingName",
- where "connectedPropertyName" is the name of a QObject property as it is documented in the QtDocs, and
- "connectedSettingName" is the name of a setting here within UiGuiSettings. If the mentioned setting
- name doesn't exist, it will be created.
-
- Returns true, if all found property and setting definitions could be successfully registered.
- Returns false, if any of those registrations fails.
- */
-bool UiGuiSettings::registerObjectPropertyRecursive(QObject *obj) {
- return checkCustomPropertiesAndCallFunction(obj, &UiGuiSettings::registerObjectProperty);
-}
-
-
-/*!
- \brief Assigns the by \a settingName defined setting value to the by \a propertyName defined property of \a obj.
-
- Returns true, if the value could be assigned, otherwise returns false, which is the case if settingName doesn't exist
- within the settings or if the mentioned propertyName wasn't found for the \a obj.
- */
-bool UiGuiSettings::setObjectPropertyToSettingValue( QObject *obj, const QString &propertyName, const QString &settingName )
-{
- const QMetaObject *metaObject = obj->metaObject();
-
- int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
- if ( indexOfProp > -1 ) {
- QMetaProperty mProp = metaObject->property(indexOfProp);
-
- // If setting already exists, set the objects property to the setting value.
- if ( _qsettings->contains("UniversalIndentGUI/" + settingName) ) {
- mProp.write(obj, _qsettings->value("UniversalIndentGUI/" + settingName));
- }
- // The setting didn't exist so return that setting the objects property failed.
- else {
- //TODO: Write a debug warning to the log.
- return false;
- }
- }
- else {
- //TODO: Write a debug warning to the log.
- return false;
- }
-
- return true;
-}
-
-
-/*!
- \brief Searches the child QObjects of \a obj for a property name and setting name definition within
- their custom properties and sets each property to settings value.
-
- The custom properties, for which are searched, are "connectedPropertyName" and "connectedSettingName",
- where "connectedPropertyName" is the name of a QObject property as it is documented in the QtDocs, and
- "connectedSettingName" is the name of a setting here within UiGuiSettings.
-
- Returns true, if all found property and setting definitions could be successfully registered.
- Returns false, if any of those registrations fails.
- */
-bool UiGuiSettings::setObjectPropertyToSettingValueRecursive(QObject *obj) {
- return checkCustomPropertiesAndCallFunction(obj, &UiGuiSettings::setObjectPropertyToSettingValue);
-}
-
-
-/*!
- \brief Assigns the by \a propertyName defined property's value of \a obj to the by \a settingName defined setting.
-
- If the \a settingName didn't exist yet, it will be created.
-
- Returns true, if the value could be assigned, otherwise returns false, which is the case if the mentioned
- propertyName wasn't found for the \a obj.
- */
-bool UiGuiSettings::setSettingToObjectPropertyValue( QObject *obj, const QString &propertyName, const QString &settingName )
-{
- const QMetaObject *metaObject = obj->metaObject();
-
- int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
- if ( indexOfProp > -1 ) {
- QMetaProperty mProp = metaObject->property(indexOfProp);
-
- setValueByName(settingName, mProp.read(obj));
- }
- else {
- //TODO: Write a debug warning to the log.
- return false;
- }
-
- return true;
-}
-
-
-/*!
- \brief Searches the child QObjects of \a obj for a property name and setting name definition within
- their custom properties and sets each setting to the property value.
-
- The custom properties, for which are searched, are "connectedPropertyName" and "connectedSettingName",
- where "connectedPropertyName" is the name of a QObject property as it is documented in the QtDocs, and
- "connectedSettingName" is the name of a setting here within UiGuiSettings. If the settingName
- didn't exist yet, it will be created.
-
- Returns true, if all found property and setting definitions could be successfully registered.
- Returns false, if any of those registrations fails.
- */
-bool UiGuiSettings::setSettingToObjectPropertyValueRecursive(QObject *obj) {
- return checkCustomPropertiesAndCallFunction(obj, &UiGuiSettings::setSettingToObjectPropertyValue);
-}
-
-
-/*!
- \brief Iterates over all \a objs child QObjects and checks whether they have the custom properties
- "connectedPropertyName" and "connectedSettingName" set. If both are set, it invokes the \a callBackFunc
- with both.
- */
-bool UiGuiSettings::checkCustomPropertiesAndCallFunction(QObject *obj, bool (UiGuiSettings::*callBackFunc)(QObject *obj, const QString &propertyName, const QString &settingName)) {
- bool success = true;
-
- // Find all widgets that have PropertyName and SettingName defined in their style sheet.
- QList<QObject *> allObjects = obj->findChildren<QObject *>();
- foreach (QObject *object, allObjects) {
- QString propertyName = object->property("connectedPropertyName").toString();
- QString settingName = object->property("connectedSettingName").toString();
-
- // If property and setting name were found, register that widget with the settings.
- if ( !propertyName.isEmpty() && !settingName.isEmpty() ) {
- success &= (this->*callBackFunc)( object, propertyName, settingName );
- }
- }
-
- return success;
-}
-
-
-/*!
- \brief The with a certain property registered \a obj gets unregistered.
- */
-void UiGuiSettings::unregisterObjectProperty(QObject *obj) {
- if ( _registeredObjectProperties.contains(obj) ) {
- const QMetaObject *metaObject = obj->metaObject();
- QString propertyName = _registeredObjectProperties[obj].first();
- QString settingName = _registeredObjectProperties[obj].last();
-
- bool connectSuccess = false;
- int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
- if ( indexOfProp > -1 ) {
- QMetaProperty mProp = metaObject->property(indexOfProp);
-
- // Disconnect to the property's value changed signal.
- if ( mProp.hasNotifySignal() ) {
- QMetaMethod signal = mProp.notifySignal();
- // The command "SIGNAL() + QString(signal.signature())" assembles the signal methods signature to a valid Qt SIGNAL.
- connectSuccess = disconnect(obj, qPrintable(SIGNAL() + QString(signal.signature())), this, SLOT(handleObjectPropertyChange()));
- }
- }
- _registeredObjectProperties.remove(obj);
- }
-}
-
-
-/*!
- \brief Registers a slot form the \a obj by its \a slotName to be invoked, if the by \a settingName defined
- setting changes.
-
- The registered slot may have no parameters or exactly one. If it accepts one parameter, whenever the setting
- \a settingName changes the slot gets tried to be invoked with the settings value as parameter. This only works,
- if the slot parameter is of the same type as the setting.
- */
-bool UiGuiSettings::registerObjectSlot(QObject *obj, const QString &slotName, const QString &settingName) {
-
- const QMetaObject *metaObject = obj->metaObject();
-
- bool connectSuccess = false;
- // Connect to the objects destroyed signal, so that it will be correctly unregistered.
- connectSuccess = connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectSlot(QObject*)));
-
- QString normalizedSlotName = QMetaObject::normalizedSignature( qPrintable(slotName) );
- int indexOfMethod = metaObject->indexOfMethod( qPrintable(normalizedSlotName) );
- if ( connectSuccess && indexOfMethod > -1 ) {
- QMetaMethod mMethod = metaObject->method(indexOfMethod);
- //QMetaMethod::Access access = mMethod.access();
- //QMetaMethod::MethodType methType = mMethod.methodType();
-
- // Since the method can at maximum be invoked with the setting value as argument,
- // only methods taking max one argument are allowed.
- if ( mMethod.parameterTypes().size() <= 1 ) {
- _registeredObjectSlots.insert(obj, QStringList() << normalizedSlotName << settingName);
- }
- else {
- //TODO: Write a debug warning to the log.
- disconnect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectSlot(QObject*)));
- return false;
- }
- }
- else {
- //TODO: Write a debug warning to the log.
- disconnect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectSlot(QObject*)));
- return false;
- }
-
- return true;
-}
-
-
-/*!
- \brief If \a obj, \a slotName and \a settingName are given, that certain connection is unregistered.
- If only \a obj is given, all to this object registered slot-setting connections are unregistered.
- */
-void UiGuiSettings::unregisterObjectSlot(QObject *obj, const QString &slotName, const QString &settingName) {
- //const QMetaObject *metaObject = obj->metaObject();
- QString normalizedSlotName = QMetaObject::normalizedSignature( qPrintable(slotName) );
- QMutableMapIterator<QObject*, QStringList> it(_registeredObjectSlots);
- while (it.hasNext()) {
- it.next();
- if (it.key() == obj && slotName.isEmpty() && settingName.isEmpty())
- it.remove();
- else if (it.key() == obj && it.value().first() == slotName && it.value().last() == settingName)
- it.remove();
- }
-}
-
-
-/*!
- \brief This private slot gets invoked whenever a registered objects property changes
- and distributes the new value to all other to the same settingName registered objects.
- */
-void UiGuiSettings::handleObjectPropertyChange() {
- QObject *obj = QObject::sender();
- QString className = obj->metaObject()->className();
- const QMetaObject *metaObject = obj->metaObject();
- QString propertyName = _registeredObjectProperties[obj].first();
- QString settingName = _registeredObjectProperties[obj].last();
-
- int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
- if ( indexOfProp > -1 ) {
- QMetaProperty mProp = metaObject->property(indexOfProp);
- setValueByName(settingName, mProp.read(obj));
- }
-}
-
-
-/*!
- \brief Sets the setting defined by \a settingName to \a value.
-
- When setting a changed value, all to this settingName registered objects get
- the changed value set too.
- If the \a settingName didn't exist yet, it will be created.
- */
-void UiGuiSettings::setValueByName(const QString &settingName, const QVariant &value) {
- // Do the updating only, if the setting was really changed.
- if ( _qsettings->value("UniversalIndentGUI/" + settingName) != value ) {
- _qsettings->setValue("UniversalIndentGUI/" + settingName, value);
-
- // Set the new value for all registered object properties for settingName.
- for ( QMap<QObject*, QStringList>::ConstIterator it = _registeredObjectProperties.begin(); it != _registeredObjectProperties.end(); ++it ) {
- if ( it.value().last() == settingName ) {
- QObject *obj = it.key();
- const QMetaObject *metaObject = obj->metaObject();
- QString propertyName = it.value().first();
-
- int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
- if ( indexOfProp > -1 ) {
- QMetaProperty mProp = metaObject->property(indexOfProp);
- mProp.write(obj, value);
- }
- }
- }
-
- // Invoke all registered object methods for settingName.
- for ( QMap<QObject*, QStringList>::ConstIterator it = _registeredObjectSlots.begin(); it != _registeredObjectSlots.end(); ++it ) {
- if ( it.value().last() == settingName ) {
- QObject *obj = it.key();
- const QMetaObject *metaObject = obj->metaObject();
- QString slotName = it.value().first();
-
- int indexOfMethod = metaObject->indexOfMethod( qPrintable(slotName) );
- if ( indexOfMethod > -1 ) {
- QMetaMethod mMethod = metaObject->method(indexOfMethod);
- //QMetaMethod::Access access = mMethod.access();
- //QMetaMethod::MethodType methType = mMethod.methodType();
-
- bool success = false;
-
- // Handle registered slots taking one parameter.
- if ( mMethod.parameterTypes().size() == 1 ) {
- if ( mMethod.parameterTypes().first() == value.typeName() ) {
- success = invokeMethodWithValue(obj, mMethod, value);
- }
- }
- // Handle registered slots taking zero parameters.
- else {
- success = mMethod.invoke( obj, Qt::DirectConnection );
- }
-
- if ( success == false ) {
- // TODO: Write a warning to the log if no success.
- }
- }
- }
- }
- }
-}
-
-
-#include <QBitArray>
-#include <QBitmap>
-#include <QBrush>
-#include <QCursor>
-#include <QDateTime>
-#include <QFont>
-#include <QIcon>
-#include <QKeySequence>
-#include <QLocale>
-#include <QPalette>
-#include <QPen>
-#include <QSizePolicy>
-#include <QTextFormat>
-#include <QTextLength>
-#include <QUrl>
-#if QT_VERSION >= 0x040600
-#include <QMatrix4x4>
-#include <QVector2D>
-#endif
-
-bool UiGuiSettings::invokeMethodWithValue( QObject *obj, QMetaMethod mMethod, QVariant value )
-{
- switch (value.type()) {
- case QVariant::BitArray :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QBitArray, value.toBitArray()) );
- case QVariant::Bitmap :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QBitmap, value.value<QBitmap>()) );
- case QVariant::Bool :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(bool, value.toBool()) );
- case QVariant::Brush :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QBrush, value.value<QBrush>()) );
- case QVariant::ByteArray :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QByteArray, value.toByteArray()) );
- case QVariant::Char :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QChar, value.toChar()) );
- case QVariant::Color :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QColor, value.value<QColor>()) );
- case QVariant::Cursor :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QCursor, value.value<QCursor>()) );
- case QVariant::Date :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QDate, value.toDate()) );
- case QVariant::DateTime :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QDateTime, value.toDateTime()) );
- case QVariant::Double :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(double, value.toDouble()) );
- case QVariant::Font :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QFont, value.value<QFont>()) );
- case QVariant::Hash :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVariantHash, value.toHash()) );
- case QVariant::Icon :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QIcon, value.value<QIcon>()) );
- case QVariant::Image :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QImage, value.value<QImage>()) );
- case QVariant::Int :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(int, value.toInt()) );
- case QVariant::KeySequence :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QKeySequence, value.value<QKeySequence>()) );
- case QVariant::Line :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QLine, value.toLine()) );
- case QVariant::LineF :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QLineF, value.toLineF()) );
- case QVariant::List :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVariantList, value.toList()) );
- case QVariant::Locale :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QLocale, value.toLocale()) );
- case QVariant::LongLong :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(qlonglong, value.toLongLong()) );
- case QVariant::Map :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVariantMap, value.toMap()) );
- case QVariant::Matrix :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QMatrix, value.value<QMatrix>()) );
- case QVariant::Transform :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QTransform, value.value<QTransform>()) );
-#if QT_VERSION >= 0x040600
- case QVariant::Matrix4x4 :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QMatrix4x4, value.value<QMatrix4x4>()) );
-#endif
- case QVariant::Palette :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPalette, value.value<QPalette>()) );
- case QVariant::Pen :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPen, value.value<QPen>()) );
- case QVariant::Pixmap :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPixmap, value.value<QPixmap>()) );
- case QVariant::Point :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPoint, value.toPoint()) );
- // case QVariant::PointArray :
- // return Q_ARG(QPointArray, value.value<QPointArray>()) );
- case QVariant::PointF :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPointF, value.toPointF()) );
- case QVariant::Polygon :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPolygon, value.value<QPolygon>()) );
-#if QT_VERSION >= 0x040600
- case QVariant::Quaternion :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QQuaternion, value.value<QQuaternion>()) );
-#endif
- case QVariant::Rect :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QRect, value.toRect()) );
- case QVariant::RectF :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QRectF, value.toRectF()) );
- case QVariant::RegExp :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QRegExp, value.toRegExp()) );
- case QVariant::Region :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QRegion, value.value<QRegion>()) );
- case QVariant::Size :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QSize, value.toSize()) );
- case QVariant::SizeF :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QSizeF, value.toSizeF()) );
- case QVariant::SizePolicy :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QSizePolicy, value.value<QSizePolicy>()) );
- case QVariant::String :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QString, value.toString()) );
- case QVariant::StringList :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QStringList, value.toStringList()) );
- case QVariant::TextFormat :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QTextFormat, value.value<QTextFormat>()) );
- case QVariant::TextLength :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QTextLength, value.value<QTextLength>()) );
- case QVariant::Time :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QTime, value.toTime()) );
- case QVariant::UInt :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(uint, value.toUInt()) );
- case QVariant::ULongLong :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(qulonglong, value.toULongLong()) );
- case QVariant::Url :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QUrl, value.toUrl()) );
-#if QT_VERSION >= 0x040600
- case QVariant::Vector2D :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVector2D, value.value<QVector2D>()) );
- case QVariant::Vector3D :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVector3D, value.value<QVector3D>()) );
- case QVariant::Vector4D :
- return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVector4D, value.value<QVector4D>()) );
-#endif
- default:
- return false;
- }
-}
+/***************************************************************************
+* Copyright (C) 2006-2012 by Thomas Schweitzer *
+* thomas-schweitzer(at)arcor.de *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License version 2.0 as *
+* published by the Free Software Foundation. *
+* *
+* This program 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 General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program in the file LICENSE.GPL; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+***************************************************************************/
+
+#include "UiGuiSettings.h"
+
+#include "SettingsPaths.h"
+
+#include <tqsettings.h>
+#include <tqpoint.h>
+#include <tqsize.h>
+#include <tqdir.h>
+#include <tqdate.h>
+#include <tqstringlist.h>
+#include <tqcoreapplication.h>
+#include <tqmetamethod.h>
+#include <tqmetaproperty.h>
+#include <tqwidget.h>
+
+//! \defgroup grp_Settings All concerning the settings.
+
+/*!
+ \class UiGuiSettings
+ \ingroup grp_Settings
+ \brief Handles the settings of the program. Reads them on startup and saves them on exit.
+ Is a singleton class and can only be accessed via getInstance().
+*/
+
+// Inits the single class instance pointer.
+QWeakPointer<UiGuiSettings> UiGuiSettings::_instance;
+
+
+/*!
+ \brief The constructor for the settings.
+*/
+UiGuiSettings::UiGuiSettings() : QObject() {
+ // Create the main application settings object from the UniversalIndentGUI.ini file.
+ _qsettings = new QSettings(SettingsPaths::getSettingsPath() + "/UniversalIndentGUI.ini", QSettings::IniFormat, this);
+
+ _indenterDirctoryStr = SettingsPaths::getGlobalFilesPath() + "/indenters";
+ readAvailableTranslations();
+ initSettings();
+}
+
+
+/*!
+ \brief Returns the instance of the settings class. If no instance exists, ONE will be created.
+ */
+QSharedPointer<UiGuiSettings> UiGuiSettings::getInstance() {
+ QSharedPointer<UiGuiSettings> sharedInstance = _instance.toStrongRef();
+ if ( sharedInstance.isNull() ) {
+ // Create the settings object, which loads all UiGui settings from a file.
+ sharedInstance = QSharedPointer<UiGuiSettings>(new UiGuiSettings());
+ _instance = sharedInstance.toWeakRef();
+ }
+
+ return sharedInstance;
+}
+
+
+/*!
+ \brief The destructor saves the settings to a file.
+ */
+UiGuiSettings::~UiGuiSettings() {
+ // Convert the language setting from an integer index to a string.
+ int index = _qsettings->value("UniversalIndentGUI/language", 0).toInt();
+ if ( index < 0 || index >= _availableTranslations.size() )
+ index = 0;
+
+ _qsettings->setValue( "UniversalIndentGUI/language", _availableTranslations.at(index) );
+}
+
+
+/*!
+ \brief Scans the translations directory for available translation files and
+ stores them in the QList \a _availableTranslations.
+ */
+void UiGuiSettings::readAvailableTranslations() {
+ QString languageShort;
+ QStringList languageFileList;
+
+ // English is the default language. A translation file does not exist but to have a menu entry, added here.
+ languageFileList << "universalindent_en.qm";
+
+ // Find all translation files in the "translations" directory.
+ QDir translationDirectory = QDir( SettingsPaths::getGlobalFilesPath() + "/translations" );
+ languageFileList << translationDirectory.entryList( QStringList("universalindent_*.qm") );
+
+ // Loop for each found translation file
+ foreach ( languageShort, languageFileList ) {
+ // Remove the leading string "universalindent_" from the filename.
+ languageShort.remove(0,16);
+ // Remove trailing file extension ".qm".
+ languageShort.chop(3);
+
+ _availableTranslations.append(languageShort);
+ }
+}
+
+
+/*!
+ \brief Returns a list of the mnemonics of the available translations.
+ */
+QStringList UiGuiSettings::getAvailableTranslations() {
+ return _availableTranslations;
+}
+
+
+/*!
+ \brief Returns the value of the by \a settingsName defined setting as QVariant.
+
+ If the named setting does not exist, 0 is being returned.
+*/
+QVariant UiGuiSettings::getValueByName(QString settingName) {
+ return _qsettings->value("UniversalIndentGUI/" + settingName);
+}
+
+
+/*!
+ \brief Loads the settings for the main application.
+
+ Settings are for example last selected indenter, last loaded source code file and so on.
+*/
+bool UiGuiSettings::initSettings()
+{
+ // Read the version string saved in the settings file.
+ _qsettings->setValue( "UniversalIndentGUI/version", _qsettings->value("UniversalIndentGUI/version", "") );
+
+ // Read windows last size and position from the settings file.
+ _qsettings->setValue( "UniversalIndentGUI/maximized", _qsettings->value("UniversalIndentGUI/maximized", false) );
+ _qsettings->setValue( "UniversalIndentGUI/position", _qsettings->value("UniversalIndentGUI/position", QPoint(50, 50)) );
+ _qsettings->setValue( "UniversalIndentGUI/size", _qsettings->value("UniversalIndentGUI/size", QSize(800, 600)) );
+
+ // Read last selected encoding for the opened source code file.
+ _qsettings->setValue( "UniversalIndentGUI/encoding", _qsettings->value("UniversalIndentGUI/encoding", "UTF-8") );
+
+ // Read maximum length of list for recently opened files.
+ _qsettings->setValue( "UniversalIndentGUI/recentlyOpenedListSize", _qsettings->value("UniversalIndentGUI/recentlyOpenedListSize", 5) );
+
+ // Read if last opened source code file should be loaded on startup.
+ _qsettings->setValue( "UniversalIndentGUI/loadLastSourceCodeFileOnStartup", _qsettings->value("UniversalIndentGUI/loadLastSourceCodeFileOnStartup", true) );
+
+ // Read last opened source code file from the settings file.
+ _qsettings->setValue( "UniversalIndentGUI/lastSourceCodeFile", _qsettings->value("UniversalIndentGUI/lastSourceCodeFile", _indenterDirctoryStr+"/example.cpp") );
+
+ // Read last selected indenter from the settings file.
+ int selectedIndenter = _qsettings->value("UniversalIndentGUI/selectedIndenter", 0).toInt();
+ if ( selectedIndenter < 0 ) {
+ selectedIndenter = 0;
+ }
+ _qsettings->setValue( "UniversalIndentGUI/selectedIndenter", selectedIndenter );
+
+ // Read if syntax highlighting is enabled.
+ _qsettings->setValue( "UniversalIndentGUI/SyntaxHighlightingEnabled", _qsettings->value("UniversalIndentGUI/SyntaxHighlightingEnabled", true) );
+
+ // Read if white space characters should be displayed.
+ _qsettings->setValue( "UniversalIndentGUI/whiteSpaceIsVisible", _qsettings->value("UniversalIndentGUI/whiteSpaceIsVisible", false) );
+
+ // Read if indenter parameter tool tips are enabled.
+ _qsettings->setValue( "UniversalIndentGUI/indenterParameterTooltipsEnabled", _qsettings->value("UniversalIndentGUI/indenterParameterTooltipsEnabled", true) );
+
+ // Read the tab width from the settings file.
+ _qsettings->setValue( "UniversalIndentGUI/tabWidth", _qsettings->value("UniversalIndentGUI/tabWidth", 4) );
+
+ // Read the last selected language and stores the index it has in the list of available translations.
+ _qsettings->setValue( "UniversalIndentGUI/language", _availableTranslations.indexOf( _qsettings->value("UniversalIndentGUI/language", "").toString() ) );
+
+ // Read the update check settings from the settings file.
+ _qsettings->setValue( "UniversalIndentGUI/CheckForUpdate", _qsettings->value("UniversalIndentGUI/CheckForUpdate", false) );
+ _qsettings->setValue( "UniversalIndentGUI/LastUpdateCheck", _qsettings->value("UniversalIndentGUI/LastUpdateCheck", QDate(1900,1,1)) );
+
+ // Read the main window state.
+ _qsettings->setValue( "UniversalIndentGUI/MainWindowState", _qsettings->value("UniversalIndentGUI/MainWindowState", QByteArray()) );
+
+ return true;
+}
+
+
+/*!
+ \brief Register the by \a propertyName defined property of \a obj to be connected to the setting defined by \a settingName.
+
+ The \a propertyName must be one of those that are listed in the Qt "Properties" documentation section of a Qt Object.
+ All further needed info is retrieved via the \a obj's MetaObject, like the to the property bound signal.
+ */
+bool UiGuiSettings::registerObjectProperty( QObject *obj, const QString &propertyName, const QString &settingName )
+{
+ const QMetaObject *metaObject = obj->metaObject();
+ bool connectSuccess = false;
+
+ // Connect to the objects destroyed signal, so that it will be correctly unregistered.
+ connectSuccess = connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectProperty(QObject*)));
+
+ int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
+ if ( connectSuccess && indexOfProp > -1 ) {
+ QMetaProperty mProp = metaObject->property(indexOfProp);
+
+ // Connect to the property's value changed signal.
+ if ( mProp.hasNotifySignal() ) {
+ QMetaMethod signal = mProp.notifySignal();
+ //QString teststr = qPrintable(SIGNAL() + QString(signal.signature()));
+ // The command "SIGNAL() + QString(signal.signature())" assembles the signal methods signature to a valid Qt SIGNAL.
+ connectSuccess = connect(obj, qPrintable(SIGNAL() + QString(signal.signature())), this, SLOT(handleObjectPropertyChange()));
+ }
+
+ if ( connectSuccess ) {
+ _registeredObjectProperties[obj] = QStringList() << propertyName << settingName;
+ }
+ else {
+ //TODO: Write a debug warning to the log.
+ disconnect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectProperty(QObject*)));
+ return false;
+ }
+
+ // If setting already exists, set the objects property to the setting value.
+ if ( _qsettings->contains("UniversalIndentGUI/" + settingName) ) {
+ mProp.write(obj, _qsettings->value("UniversalIndentGUI/" + settingName));
+ }
+ // Otherwise add the setting and set it to the value of the objects property.
+ else {
+ _qsettings->setValue("UniversalIndentGUI/" + settingName, mProp.read(obj));
+ }
+ }
+ else {
+ //TODO: Write a debug warning to the log.
+ disconnect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectProperty(QObject*)));
+ return false;
+ }
+
+ return true;
+}
+
+
+/*!
+ \brief Searches the child QObjects of \a obj for a property name and setting name definition within
+ their custom properties and registers this property name to that setting name if both were found.
+
+ The custom properties, for which are searched, are "connectedPropertyName" and "connectedSettingName",
+ where "connectedPropertyName" is the name of a QObject property as it is documented in the QtDocs, and
+ "connectedSettingName" is the name of a setting here within UiGuiSettings. If the mentioned setting
+ name doesn't exist, it will be created.
+
+ Returns true, if all found property and setting definitions could be successfully registered.
+ Returns false, if any of those registrations fails.
+ */
+bool UiGuiSettings::registerObjectPropertyRecursive(QObject *obj) {
+ return checkCustomPropertiesAndCallFunction(obj, &UiGuiSettings::registerObjectProperty);
+}
+
+
+/*!
+ \brief Assigns the by \a settingName defined setting value to the by \a propertyName defined property of \a obj.
+
+ Returns true, if the value could be assigned, otherwise returns false, which is the case if settingName doesn't exist
+ within the settings or if the mentioned propertyName wasn't found for the \a obj.
+ */
+bool UiGuiSettings::setObjectPropertyToSettingValue( QObject *obj, const QString &propertyName, const QString &settingName )
+{
+ const QMetaObject *metaObject = obj->metaObject();
+
+ int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
+ if ( indexOfProp > -1 ) {
+ QMetaProperty mProp = metaObject->property(indexOfProp);
+
+ // If setting already exists, set the objects property to the setting value.
+ if ( _qsettings->contains("UniversalIndentGUI/" + settingName) ) {
+ mProp.write(obj, _qsettings->value("UniversalIndentGUI/" + settingName));
+ }
+ // The setting didn't exist so return that setting the objects property failed.
+ else {
+ //TODO: Write a debug warning to the log.
+ return false;
+ }
+ }
+ else {
+ //TODO: Write a debug warning to the log.
+ return false;
+ }
+
+ return true;
+}
+
+
+/*!
+ \brief Searches the child QObjects of \a obj for a property name and setting name definition within
+ their custom properties and sets each property to settings value.
+
+ The custom properties, for which are searched, are "connectedPropertyName" and "connectedSettingName",
+ where "connectedPropertyName" is the name of a QObject property as it is documented in the QtDocs, and
+ "connectedSettingName" is the name of a setting here within UiGuiSettings.
+
+ Returns true, if all found property and setting definitions could be successfully registered.
+ Returns false, if any of those registrations fails.
+ */
+bool UiGuiSettings::setObjectPropertyToSettingValueRecursive(QObject *obj) {
+ return checkCustomPropertiesAndCallFunction(obj, &UiGuiSettings::setObjectPropertyToSettingValue);
+}
+
+
+/*!
+ \brief Assigns the by \a propertyName defined property's value of \a obj to the by \a settingName defined setting.
+
+ If the \a settingName didn't exist yet, it will be created.
+
+ Returns true, if the value could be assigned, otherwise returns false, which is the case if the mentioned
+ propertyName wasn't found for the \a obj.
+ */
+bool UiGuiSettings::setSettingToObjectPropertyValue( QObject *obj, const QString &propertyName, const QString &settingName )
+{
+ const QMetaObject *metaObject = obj->metaObject();
+
+ int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
+ if ( indexOfProp > -1 ) {
+ QMetaProperty mProp = metaObject->property(indexOfProp);
+
+ setValueByName(settingName, mProp.read(obj));
+ }
+ else {
+ //TODO: Write a debug warning to the log.
+ return false;
+ }
+
+ return true;
+}
+
+
+/*!
+ \brief Searches the child QObjects of \a obj for a property name and setting name definition within
+ their custom properties and sets each setting to the property value.
+
+ The custom properties, for which are searched, are "connectedPropertyName" and "connectedSettingName",
+ where "connectedPropertyName" is the name of a QObject property as it is documented in the QtDocs, and
+ "connectedSettingName" is the name of a setting here within UiGuiSettings. If the settingName
+ didn't exist yet, it will be created.
+
+ Returns true, if all found property and setting definitions could be successfully registered.
+ Returns false, if any of those registrations fails.
+ */
+bool UiGuiSettings::setSettingToObjectPropertyValueRecursive(QObject *obj) {
+ return checkCustomPropertiesAndCallFunction(obj, &UiGuiSettings::setSettingToObjectPropertyValue);
+}
+
+
+/*!
+ \brief Iterates over all \a objs child QObjects and checks whether they have the custom properties
+ "connectedPropertyName" and "connectedSettingName" set. If both are set, it invokes the \a callBackFunc
+ with both.
+ */
+bool UiGuiSettings::checkCustomPropertiesAndCallFunction(QObject *obj, bool (UiGuiSettings::*callBackFunc)(QObject *obj, const QString &propertyName, const QString &settingName)) {
+ bool success = true;
+
+ // Find all widgets that have PropertyName and SettingName defined in their style sheet.
+ QList<QObject *> allObjects = obj->findChildren<QObject *>();
+ foreach (QObject *object, allObjects) {
+ QString propertyName = object->property("connectedPropertyName").toString();
+ QString settingName = object->property("connectedSettingName").toString();
+
+ // If property and setting name were found, register that widget with the settings.
+ if ( !propertyName.isEmpty() && !settingName.isEmpty() ) {
+ success &= (this->*callBackFunc)( object, propertyName, settingName );
+ }
+ }
+
+ return success;
+}
+
+
+/*!
+ \brief The with a certain property registered \a obj gets unregistered.
+ */
+void UiGuiSettings::unregisterObjectProperty(QObject *obj) {
+ if ( _registeredObjectProperties.contains(obj) ) {
+ const QMetaObject *metaObject = obj->metaObject();
+ QString propertyName = _registeredObjectProperties[obj].first();
+ QString settingName = _registeredObjectProperties[obj].last();
+
+ bool connectSuccess = false;
+ int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
+ if ( indexOfProp > -1 ) {
+ QMetaProperty mProp = metaObject->property(indexOfProp);
+
+ // Disconnect to the property's value changed signal.
+ if ( mProp.hasNotifySignal() ) {
+ QMetaMethod signal = mProp.notifySignal();
+ // The command "SIGNAL() + QString(signal.signature())" assembles the signal methods signature to a valid Qt SIGNAL.
+ connectSuccess = disconnect(obj, qPrintable(SIGNAL() + QString(signal.signature())), this, SLOT(handleObjectPropertyChange()));
+ }
+ }
+ _registeredObjectProperties.remove(obj);
+ }
+}
+
+
+/*!
+ \brief Registers a slot form the \a obj by its \a slotName to be invoked, if the by \a settingName defined
+ setting changes.
+
+ The registered slot may have no parameters or exactly one. If it accepts one parameter, whenever the setting
+ \a settingName changes the slot gets tried to be invoked with the settings value as parameter. This only works,
+ if the slot parameter is of the same type as the setting.
+ */
+bool UiGuiSettings::registerObjectSlot(QObject *obj, const QString &slotName, const QString &settingName) {
+
+ const QMetaObject *metaObject = obj->metaObject();
+
+ bool connectSuccess = false;
+ // Connect to the objects destroyed signal, so that it will be correctly unregistered.
+ connectSuccess = connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectSlot(QObject*)));
+
+ QString normalizedSlotName = QMetaObject::normalizedSignature( qPrintable(slotName) );
+ int indexOfMethod = metaObject->indexOfMethod( qPrintable(normalizedSlotName) );
+ if ( connectSuccess && indexOfMethod > -1 ) {
+ QMetaMethod mMethod = metaObject->method(indexOfMethod);
+ //QMetaMethod::Access access = mMethod.access();
+ //QMetaMethod::MethodType methType = mMethod.methodType();
+
+ // Since the method can at maximum be invoked with the setting value as argument,
+ // only methods taking max one argument are allowed.
+ if ( mMethod.parameterTypes().size() <= 1 ) {
+ _registeredObjectSlots.insert(obj, QStringList() << normalizedSlotName << settingName);
+ }
+ else {
+ //TODO: Write a debug warning to the log.
+ disconnect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectSlot(QObject*)));
+ return false;
+ }
+ }
+ else {
+ //TODO: Write a debug warning to the log.
+ disconnect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterObjectSlot(QObject*)));
+ return false;
+ }
+
+ return true;
+}
+
+
+/*!
+ \brief If \a obj, \a slotName and \a settingName are given, that certain connection is unregistered.
+ If only \a obj is given, all to this object registered slot-setting connections are unregistered.
+ */
+void UiGuiSettings::unregisterObjectSlot(QObject *obj, const QString &slotName, const QString &settingName) {
+ //const QMetaObject *metaObject = obj->metaObject();
+ QString normalizedSlotName = QMetaObject::normalizedSignature( qPrintable(slotName) );
+ QMutableMapIterator<QObject*, QStringList> it(_registeredObjectSlots);
+ while (it.hasNext()) {
+ it.next();
+ if (it.key() == obj && slotName.isEmpty() && settingName.isEmpty())
+ it.remove();
+ else if (it.key() == obj && it.value().first() == slotName && it.value().last() == settingName)
+ it.remove();
+ }
+}
+
+
+/*!
+ \brief This private slot gets invoked whenever a registered objects property changes
+ and distributes the new value to all other to the same settingName registered objects.
+ */
+void UiGuiSettings::handleObjectPropertyChange() {
+ QObject *obj = QObject::sender();
+ QString className = obj->metaObject()->className();
+ const QMetaObject *metaObject = obj->metaObject();
+ QString propertyName = _registeredObjectProperties[obj].first();
+ QString settingName = _registeredObjectProperties[obj].last();
+
+ int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
+ if ( indexOfProp > -1 ) {
+ QMetaProperty mProp = metaObject->property(indexOfProp);
+ setValueByName(settingName, mProp.read(obj));
+ }
+}
+
+
+/*!
+ \brief Sets the setting defined by \a settingName to \a value.
+
+ When setting a changed value, all to this settingName registered objects get
+ the changed value set too.
+ If the \a settingName didn't exist yet, it will be created.
+ */
+void UiGuiSettings::setValueByName(const QString &settingName, const QVariant &value) {
+ // Do the updating only, if the setting was really changed.
+ if ( _qsettings->value("UniversalIndentGUI/" + settingName) != value ) {
+ _qsettings->setValue("UniversalIndentGUI/" + settingName, value);
+
+ // Set the new value for all registered object properties for settingName.
+ for ( QMap<QObject*, QStringList>::ConstIterator it = _registeredObjectProperties.begin(); it != _registeredObjectProperties.end(); ++it ) {
+ if ( it.value().last() == settingName ) {
+ QObject *obj = it.key();
+ const QMetaObject *metaObject = obj->metaObject();
+ QString propertyName = it.value().first();
+
+ int indexOfProp = metaObject->indexOfProperty( qPrintable(propertyName) );
+ if ( indexOfProp > -1 ) {
+ QMetaProperty mProp = metaObject->property(indexOfProp);
+ mProp.write(obj, value);
+ }
+ }
+ }
+
+ // Invoke all registered object methods for settingName.
+ for ( QMap<QObject*, QStringList>::ConstIterator it = _registeredObjectSlots.begin(); it != _registeredObjectSlots.end(); ++it ) {
+ if ( it.value().last() == settingName ) {
+ QObject *obj = it.key();
+ const QMetaObject *metaObject = obj->metaObject();
+ QString slotName = it.value().first();
+
+ int indexOfMethod = metaObject->indexOfMethod( qPrintable(slotName) );
+ if ( indexOfMethod > -1 ) {
+ QMetaMethod mMethod = metaObject->method(indexOfMethod);
+ //QMetaMethod::Access access = mMethod.access();
+ //QMetaMethod::MethodType methType = mMethod.methodType();
+
+ bool success = false;
+
+ // Handle registered slots taking one parameter.
+ if ( mMethod.parameterTypes().size() == 1 ) {
+ if ( mMethod.parameterTypes().first() == value.typeName() ) {
+ success = invokeMethodWithValue(obj, mMethod, value);
+ }
+ }
+ // Handle registered slots taking zero parameters.
+ else {
+ success = mMethod.invoke( obj, Qt::DirectConnection );
+ }
+
+ if ( success == false ) {
+ // TODO: Write a warning to the log if no success.
+ }
+ }
+ }
+ }
+ }
+}
+
+
+#include <tqbitarray.h>
+#include <tqbitmap.h>
+#include <tqbrush.h>
+#include <tqcursor.h>
+#include <tqdatetime.h>
+#include <tqfont.h>
+#include <tqicon.h>
+#include <tqkeysequence.h>
+#include <tqlocale.h>
+#include <tqpalette.h>
+#include <tqpen.h>
+#include <tqsizepolicy.h>
+#include <tqtextformat.h>
+#include <tqtextlength.h>
+#include <tqurl.h>
+#if QT_VERSION >= 0x040600
+#include <tqmatrix4x4.h>
+#include <tqvector2d.h>
+#endif
+
+bool UiGuiSettings::invokeMethodWithValue( QObject *obj, QMetaMethod mMethod, QVariant value )
+{
+ switch (value.type()) {
+ case QVariant::BitArray :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QBitArray, value.toBitArray()) );
+ case QVariant::Bitmap :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QBitmap, value.value<QBitmap>()) );
+ case QVariant::Bool :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(bool, value.toBool()) );
+ case QVariant::Brush :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QBrush, value.value<QBrush>()) );
+ case QVariant::ByteArray :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QByteArray, value.toByteArray()) );
+ case QVariant::Char :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QChar, value.toChar()) );
+ case QVariant::Color :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QColor, value.value<QColor>()) );
+ case QVariant::Cursor :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QCursor, value.value<QCursor>()) );
+ case QVariant::Date :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QDate, value.toDate()) );
+ case QVariant::DateTime :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QDateTime, value.toDateTime()) );
+ case QVariant::Double :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(double, value.toDouble()) );
+ case QVariant::Font :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QFont, value.value<QFont>()) );
+ case QVariant::Hash :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVariantHash, value.toHash()) );
+ case QVariant::Icon :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QIcon, value.value<QIcon>()) );
+ case QVariant::Image :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QImage, value.value<QImage>()) );
+ case QVariant::Int :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(int, value.toInt()) );
+ case QVariant::KeySequence :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QKeySequence, value.value<QKeySequence>()) );
+ case QVariant::Line :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QLine, value.toLine()) );
+ case QVariant::LineF :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QLineF, value.toLineF()) );
+ case QVariant::List :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVariantList, value.toList()) );
+ case QVariant::Locale :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QLocale, value.toLocale()) );
+ case QVariant::LongLong :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(qlonglong, value.toLongLong()) );
+ case QVariant::Map :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVariantMap, value.toMap()) );
+ case QVariant::Matrix :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QMatrix, value.value<QMatrix>()) );
+ case QVariant::Transform :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QTransform, value.value<QTransform>()) );
+#if QT_VERSION >= 0x040600
+ case QVariant::Matrix4x4 :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QMatrix4x4, value.value<QMatrix4x4>()) );
+#endif
+ case QVariant::Palette :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPalette, value.value<QPalette>()) );
+ case QVariant::Pen :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPen, value.value<QPen>()) );
+ case QVariant::Pixmap :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPixmap, value.value<QPixmap>()) );
+ case QVariant::Point :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPoint, value.toPoint()) );
+ // case QVariant::PointArray :
+ // return Q_ARG(QPointArray, value.value<QPointArray>()) );
+ case QVariant::PointF :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPointF, value.toPointF()) );
+ case QVariant::Polygon :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QPolygon, value.value<QPolygon>()) );
+#if QT_VERSION >= 0x040600
+ case QVariant::Quaternion :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QQuaternion, value.value<QQuaternion>()) );
+#endif
+ case QVariant::Rect :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QRect, value.toRect()) );
+ case QVariant::RectF :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QRectF, value.toRectF()) );
+ case QVariant::RegExp :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QRegExp, value.toRegExp()) );
+ case QVariant::Region :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QRegion, value.value<QRegion>()) );
+ case QVariant::Size :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QSize, value.toSize()) );
+ case QVariant::SizeF :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QSizeF, value.toSizeF()) );
+ case QVariant::SizePolicy :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QSizePolicy, value.value<QSizePolicy>()) );
+ case QVariant::String :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QString, value.toString()) );
+ case QVariant::StringList :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QStringList, value.toStringList()) );
+ case QVariant::TextFormat :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QTextFormat, value.value<QTextFormat>()) );
+ case QVariant::TextLength :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QTextLength, value.value<QTextLength>()) );
+ case QVariant::Time :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QTime, value.toTime()) );
+ case QVariant::UInt :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(uint, value.toUInt()) );
+ case QVariant::ULongLong :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(qulonglong, value.toULongLong()) );
+ case QVariant::Url :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QUrl, value.toUrl()) );
+#if QT_VERSION >= 0x040600
+ case QVariant::Vector2D :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVector2D, value.value<QVector2D>()) );
+ case QVariant::Vector3D :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVector3D, value.value<QVector3D>()) );
+ case QVariant::Vector4D :
+ return mMethod.invoke( obj, Qt::DirectConnection, Q_ARG(QVector4D, value.value<QVector4D>()) );
+#endif
+ default:
+ return false;
+ }
+}