]> vaikene.ee Git - evaf/commitdiff
Added the eVaf::Common::iProp interface for global properties and variables.
authorEnar Väikene <enar@vaikene.net>
Wed, 23 Nov 2011 10:10:10 +0000 (12:10 +0200)
committerEnar Väikene <enar@vaikene.net>
Wed, 23 Nov 2011 10:10:10 +0000 (12:10 +0200)
src/libs/Common/CMakeLists.txt
src/libs/Common/globals.cpp
src/libs/Common/iProp [new file with mode: 0644]
src/libs/Common/iprop.h [new file with mode: 0644]
src/libs/Common/prop.cpp [new file with mode: 0644]
src/libs/Common/prop.h [new file with mode: 0644]

index f308c06927e54e900219f8eba7797c8066cebcbd..a9916b4b4dcd9d957632c78045be30d8070ca7ed 100644 (file)
@@ -25,6 +25,7 @@ set(SRCS
     util.cpp
     inifile.cpp
     config.cpp
+    prop.cpp
 )
 
 # Header files for the meta-object compiler
@@ -34,11 +35,13 @@ set(MOC_HDRS
     ilogger.h
     iregistry.h
     iconfig.h
+    iprop.h
     app.h
     eventqueue.h
     logger.h
     registry.h
     config.h
+    prop.h
 )
 
 # Version info resource file for Windows builds
index b981fff43ceee7f65537fe162d19c58e11475aa4..02aedd84d37a26a93ee8683b85213c1e8da2fe3a 100644 (file)
@@ -20,6 +20,7 @@
 #include "globals.h"
 #include "app.h"
 #include "config.h"
+#include "prop.h"
 #include "logger.h"
 #include "version.h"
 #include "ilogger.h"
@@ -41,23 +42,29 @@ bool eVaf::Common::init()
     // Initialize all the common interface implementations in the proper sequence
 
     eVaf::Common::Internal::App * app =
-        qobject_cast<eVaf::Common::Internal::App *>(eVaf::Common::iApp::instance());
+            qobject_cast<eVaf::Common::Internal::App *>(eVaf::Common::iApp::instance());
     if (app) {
         if (!app->init())
             return false;
     }
     eVaf::Common::Internal::Logger * logger =
-        qobject_cast<eVaf::Common::Internal::Logger *>(eVaf::Common::iLogger::instance());
+            qobject_cast<eVaf::Common::Internal::Logger *>(eVaf::Common::iLogger::instance());
     if (logger) {
         if (!logger->init())
             return false;
     }
     eVaf::Common::Internal::Config * config =
-        qobject_cast<eVaf::Common::Internal::Config *>(eVaf::Common::iConfig::instance());
+            qobject_cast<eVaf::Common::Internal::Config *>(eVaf::Common::iConfig::instance());
     if (config) {
         if (!config->init())
             return false;
     }
+    eVaf::Common::Internal::Prop * prop =
+            qobject_cast<eVaf::Common::Internal::Prop *>(eVaf::Common::iProp::instance());
+    if (prop) {
+        if (!prop->init())
+            return false;
+    }
 
     EVAF_INFO("%s-Globals initialized", VER_MODULE_NAME_STR);
 
diff --git a/src/libs/Common/iProp b/src/libs/Common/iProp
new file mode 100644 (file)
index 0000000..5a0b9d2
--- /dev/null
@@ -0,0 +1 @@
+#include "iprop.h"
diff --git a/src/libs/Common/iprop.h b/src/libs/Common/iprop.h
new file mode 100644 (file)
index 0000000..864c8f5
--- /dev/null
@@ -0,0 +1,122 @@
+/**
+ * @file Common/iprop.h
+ * @brief eVaf properties interface
+ * @author Enar Vaikene
+ *
+ * Copyright (c) 2011 Enar Vaikene
+ *
+ * This file is part of the eVaf C++ cross-platform application development framework.
+ *
+ * This file can be used under the terms of the GNU General Public License
+ * version 3.0 as published by the Free Software Foundation and appearing in
+ * the file LICENSE included in the packaging of this file. Please review the
+ * the following information to ensure the GNU General Public License version
+ * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+ *
+ * Alternatively, this file may be used in accordance with the Commercial License
+ * Agreement provided with the Software.
+ */
+
+#ifndef __COMMON_IPROP_H
+#  define __COMMON_IPROP_H
+
+#include "libcommon.h"
+
+#include <QObject>
+#include <QString>
+#include <QVariant>
+
+namespace eVaf {
+namespace Common {
+
+/**
+ * Global properties and variables for eVaf applications.
+ * @code#include <Common/iProp>@endcode
+ *
+ * Global properties and variables are shared by all the eVaf modules. Their function is similar to
+ * configuration parameters with the main difference that properties are not meant to be modified by
+ * users. For example, the 'applicationName' property contains the name of the current application.
+ *
+ * Properties are implemented as name/value pairs where the name uniquely identifies the property.
+ * The default implementation of the iProp interface does not enforce any rules for property names and any
+ * string is a valid name.
+ *
+ * Properties can be temporary or persistent. Temporary properties exist only as long as the application
+ * is running and will be lost when the application is restarted. Persistent properties are stored
+ * and reloaded when the application is restarted.
+ *
+ * Application's XML file section \<properties\> can be used to define default properties for the application.
+ * These are initialized when the application is started up.
+ *
+ * Individual properties are defined in \<property\> nodes with the following attributes:
+ * @li name="\<name\>" - specifies the name of the global property;
+ * @li value="\<value\>" - specifies the value of the global property;
+ * @li config="\<file/section/key\>" - value of the property is read from the configuration file (used only if
+ * the 'value' attribute is missing);
+ * @li windowsonly="yes" - the property is initialized only on Windows;
+ * @li linuxonly="yes" - the property is initialized only on Linux.
+ */
+class COMMON_EXPORT iProp : public QObject
+{
+    Q_OBJECT
+
+public:
+
+    /// Interface constructor
+    iProp() : QObject() {}
+
+    /// Empty virtual dtor
+    virtual ~iProp() {}
+
+    /**
+     * Returns the iProp interface instance
+     * @return The iProp interface instance
+     *
+     * This function returns the global iProp interface instance. If the eVaf module is linked against
+     * the common eVaf library, then this is the preferred method of obtaining the iProp interface.
+     * Another option would be using the eVaf::Common::iRegistry interface.
+     */
+    static iProp * instance();
+
+    /**
+     * Returns the value of the global property or variable
+     * @param name Name of the property
+     * @param defaultValue Default value
+     * @return The value of the global property or the default value if the property cannot be found
+     *
+     * The getValue() function returns a global property or variable identified by the name. If the property
+     * is not found, returns the default value.
+     */
+    virtual QVariant getValue(QString const & name, QVariant const & defaultValue = QVariant()) const = 0;
+
+    /**
+     * Sets the global property or variable
+     * @param name Name of the property
+     * @param value Value of the property
+     * @param persistent If True, then the property is stored permanently
+     *
+     * The setValue() function sets the value of a global property or variable identified by the name. The property
+     * is added if it does not exist. Set the persistent argument to True to make the change permanent.
+     *
+     * The valueChanged() signal is emitted indicating that a property changed.
+     */
+    virtual void setValue(QString const & name, QVariant const & value, bool persistent = false) = 0;
+
+
+signals:
+
+    /**
+     * Global property or variable changed
+     * @param name Name of the property
+     * @param value New value of the property
+     *
+     * The valueChanged() signal is emitted when a global property or variable is changed.
+     */
+    void valueChanged(QString const & name, QVariant const & value);
+
+};
+
+} // namespace eVaf::Common
+} // namespace eVaf
+
+#endif // iprop.h
diff --git a/src/libs/Common/prop.cpp b/src/libs/Common/prop.cpp
new file mode 100644 (file)
index 0000000..b3ccb6f
--- /dev/null
@@ -0,0 +1,170 @@
+/**
+ * @file Common/prop.h
+ * @brief Implementation of the iProp interface
+ * @author Enar Vaikene
+ *
+ * Copyright (c) 2011 Enar Vaikene
+ *
+ * This file is part of the eVaf C++ cross-platform application development framework.
+ *
+ * This file can be used under the terms of the GNU General Public License
+ * version 3.0 as published by the Free Software Foundation and appearing in
+ * the file LICENSE included in the packaging of this file. Please review the
+ * the following information to ensure the GNU General Public License version
+ * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+ *
+ * Alternatively, this file may be used in accordance with the Commercial License
+ * Agreement provided with the Software.
+ */
+
+#include "prop.h"
+#include "iregistry.h"
+#include "ilogger.h"
+#include "iapp.h"
+#include "iconfig.h"
+#include "util.h"
+#include "version.h"
+
+#include <QtCore>
+
+//-------------------------------------------------------------------
+
+using namespace eVaf::Common;
+
+iProp * iProp::instance()
+{
+    static Internal::Prop singleton;
+    return singleton.interface();
+}
+
+
+//-------------------------------------------------------------------
+
+using namespace eVaf::Common::Internal;
+
+Prop::Prop()
+    : iProp()
+    , mPersistentProps(0)
+{
+    setObjectName(QString("%1.iProp").arg(VER_MODULE_NAME_STR));
+}
+
+Prop::~Prop()
+{
+    done();
+}
+
+iProp * Prop::interface() const
+{
+    return evafQueryInterface<iProp>("iProp");
+}
+
+bool Prop::init()
+{
+    // Register the iProp interface
+    iRegistry::instance()->registerInterface("iProp", this);
+
+    // Set application name and language properties
+    setValue("applicationName", iApp::instance()->name());
+    setValue("applicationLanguage", iApp::instance()->language());
+
+    // Initialize properties defined in the application's XML file
+    QFile xmlFile(iApp::instance()->etcDir() + iApp::instance()->xmlFileName());
+    if (xmlFile.open(QFile::ReadOnly)) {
+        bool isProp = false;
+        QXmlStreamReader xml(&xmlFile);
+        while (!xml.atEnd()) {
+            xml.readNext();
+            if (xml.isStartElement()) {
+                if (xml.name() == "properties") {
+                    isProp = true;
+                }
+                else if (isProp && xml.name() == "property") {
+#ifdef Q_OS_LINUX
+                    if (isTrue(xml.attributes().value("windowsonly").toString()))
+                        continue;
+#endif
+#ifdef Q_OS_WIN32
+                    if (isTrue(xml.attributes().value("linuxonly").toString()))
+                        continue;
+#endif
+                    // Get the name/value pair
+                    QString name = xml.attributes().value("name").toString();
+                    if (name.isEmpty())
+                        continue;
+                    QString value = xml.attributes().value("value").toString();
+
+                    // If value is empty, try the configuration
+                    if (value.isEmpty()) {
+                        QString paramName = xml.attributes().value("config").toString();
+                        if (!paramName.isEmpty())
+                            value = iConfig::instance()->getValue(paramName, "").toString();
+                    }
+
+                    setValue(name, value);
+                }
+            }
+            else if (xml.isEndElement()) {
+                if (xml.name() == "properties")
+                    isProp = false;
+            }
+        }
+        if (xml.hasError()) {
+            EVAF_FATAL_ERROR("Error in the application's XML file %s : %s", qPrintable(xmlFile.fileName()), qPrintable(xml.errorString()));
+            return false;
+        }
+    }
+
+    // Initialize persistent properties
+    if (mPersistentProps)
+        delete mPersistentProps;
+    mPersistentProps = new QSettings(QString("%1/.%2.dat").arg(iApp::instance()->dataRootDir()).arg(iApp::instance()->name()), QSettings::IniFormat);
+    QStringList keys = mPersistentProps->allKeys();
+    for (int i = 0; i < keys.size(); ++i) {
+        QString key = keys.at(i);
+        setValue(key, mPersistentProps->value(key));
+    }
+
+    return true;
+}
+
+void Prop::done()
+{
+    if (mPersistentProps) {
+        delete mPersistentProps;
+        mPersistentProps = 0;
+    }
+}
+
+QVariant Prop::getValue(QString const & name, QVariant const & defaultValue) const
+{
+    QHash<QString, QVariant>::const_iterator it = mProps.constFind(name);
+    if (it != mProps.constEnd()) {
+        QVariant value = *it;
+        if (value.type() == defaultValue.type())
+            return value;
+        else
+            return toVariant(value.toString(), defaultValue);
+    }
+    else
+        return defaultValue;
+}
+
+void Prop::setValue(QString const & name, QVariant const & value, bool persistent)
+{
+    bool isChanged = true;
+
+    QHash<QString, QVariant>::iterator it = mProps.find(name);
+    if (it != mProps.end()) {
+        isChanged = *it != value;
+        *it = value;
+    }
+    else
+        mProps.insert(name, value);
+
+    if (persistent && mPersistentProps && mPersistentProps->isWritable())
+        mPersistentProps->setValue(name, value);
+
+    if (isChanged)
+        emit valueChanged(name, value);
+}
diff --git a/src/libs/Common/prop.h b/src/libs/Common/prop.h
new file mode 100644 (file)
index 0000000..4e44e27
--- /dev/null
@@ -0,0 +1,90 @@
+/**
+ * @file Common/prop.h
+ * @brief Implementation of the iProp interface
+ * @author Enar Vaikene
+ *
+ * Copyright (c) 2011 Enar Vaikene
+ *
+ * This file is part of the eVaf C++ cross-platform application development framework.
+ *
+ * This file can be used under the terms of the GNU General Public License
+ * version 3.0 as published by the Free Software Foundation and appearing in
+ * the file LICENSE included in the packaging of this file. Please review the
+ * the following information to ensure the GNU General Public License version
+ * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+ *
+ * Alternatively, this file may be used in accordance with the Commercial License
+ * Agreement provided with the Software.
+ */
+
+#ifndef __COMMON_PROP_H
+#  define __COMMON_PROP_H
+
+#include "iprop.h"
+
+#include <QHash>
+
+class QSettings;
+
+namespace eVaf {
+namespace Common {
+namespace Internal {
+
+/**
+ * Implementation of the iProp interface.
+ *
+ * This class implements the iProp interface for global properties and variables.
+ * Persistent properties are stored in the file '.\<appname\>.dat' in the directory
+ * returned with the eVaf::Common::iApp::dataRootDir() function. The file is in the
+ * QSettings::IniFormat format.
+ */
+class Prop : public iProp
+{
+    Q_OBJECT
+
+public:
+
+    Prop();
+
+    virtual ~Prop();
+
+    /**
+     * Returns the current implementation of the iProp interface
+     */
+    iProp * interface() const;
+
+    /**
+     * Initializes the iProp interface implementation
+     * @return True if succeeded; false if not
+     */
+    bool init();
+
+    /**
+     * Finalizes the iProp interface implementation
+     */
+    void done();
+
+    /*
+        iProp interface
+    */
+
+    virtual QVariant getValue(QString const & name, QVariant const & defaultValue) const;
+
+    virtual void setValue(QString const & name, QVariant const & value, bool persistent = false);
+
+
+private: // Members
+
+    /// List of properties
+    QHash<QString, QVariant> mProps;
+
+    /// Persistent property values
+    QSettings * mPersistentProps;
+
+};
+
+} // namespace eVaf::Common::Internal
+} // namespace eVaf::Common
+} // namespace eVaf
+
+#endif // prop.h