]> vaikene.ee Git - evaf/blob - src/libs/Common/prop.cpp
b76c3c5417d54ae4942d16912d491602c76ea689
[evaf] / src / libs / Common / prop.cpp
1 /**
2 * @file Common/prop.h
3 * @brief Implementation of the iProp interface
4 * @author Enar Vaikene
5 *
6 * Copyright (c) 2011-2019 Enar Vaikene
7 *
8 * This file is part of the eVaf C++ cross-platform application development framework.
9 *
10 * This file can be used under the terms of the GNU General Public License
11 * version 3.0 as published by the Free Software Foundation and appearing in
12 * the file LICENSE included in the packaging of this file. Please review the
13 * the following information to ensure the GNU General Public License version
14 * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
15 *
16 * Alternatively, this file may be used in accordance with the Commercial License
17 * Agreement provided with the Software.
18 */
19
20 #include "prop.h"
21 #include "iregistry.h"
22 #include "ilogger.h"
23 #include "iapp.h"
24 #include "iconfig.h"
25 #include "util.h"
26 #include "version.h"
27
28 #include <QtCore>
29
30 //-------------------------------------------------------------------
31
32 using namespace eVaf::Common;
33
34 namespace
35 {
36 static Internal::Prop * singleton = nullptr;
37 }
38
39 iProp * iProp::instance()
40 {
41 if (nullptr == singleton)
42 {
43 singleton = new Internal::Prop;
44 }
45 return singleton->_interface();
46 }
47
48
49 //-------------------------------------------------------------------
50
51 using namespace eVaf::Common::Internal;
52
53 void Prop::destroyInstance()
54 {
55 if (nullptr != singleton)
56 {
57 delete singleton;
58 singleton = nullptr;
59 }
60 }
61
62 Prop::Prop()
63 : iProp()
64 {
65 setObjectName(QString("%1.iProp").arg(VER_MODULE_NAME_STR));
66
67 // Register the iProp interface
68 iRegistry::instance()->registerInterface("iProp", this);
69
70 EVAF_INFO("%s-Prop created", VER_MODULE_NAME_STR);
71 }
72
73 Prop::~Prop()
74 {
75 done();
76 EVAF_INFO("%s-Prop destroyed", VER_MODULE_NAME_STR);
77 }
78
79 iProp * Prop::_interface() const
80 {
81 return evafQueryInterface<iProp>("iProp");
82 }
83
84 bool Prop::init()
85 {
86 // Set application name and language properties
87 setValue("applicationName", iApp::instance()->name());
88 setValue("applicationLanguage", iApp::instance()->language());
89
90 // Initialize properties defined in the application's XML file
91 QFile xmlFile(iApp::instance()->etcDir() + iApp::instance()->xmlFileName());
92 if (xmlFile.open(QFile::ReadOnly)) {
93 bool isProp = false;
94 QXmlStreamReader xml(&xmlFile);
95 while (!xml.atEnd()) {
96 xml.readNext();
97 if (xml.isStartElement()) {
98 if (xml.name() == "properties") {
99 isProp = true;
100 }
101 else if (isProp && xml.name() == "property") {
102 #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
103 if (isTrue(xml.attributes().value("windowsonly").toString()))
104 continue;
105 #endif
106 #ifdef Q_OS_WIN32
107 if (isTrue(xml.attributes().value("linuxonly").toString()))
108 continue;
109 #endif
110 // Get the name/value pair
111 QString name = xml.attributes().value("name").toString();
112 if (name.isEmpty())
113 continue;
114 QString value = xml.attributes().value("value").toString();
115
116 // If value is empty, try the configuration
117 if (value.isEmpty()) {
118 QString paramName = xml.attributes().value("config").toString();
119 if (!paramName.isEmpty())
120 value = iConfig::instance()->getValue(paramName, "").toString();
121 }
122
123 setValue(name, value);
124 }
125 }
126 else if (xml.isEndElement()) {
127 if (xml.name() == "properties")
128 isProp = false;
129 }
130 }
131 if (xml.hasError()) {
132 EVAF_FATAL_ERROR("Error in the application's XML file %s : %s", qPrintable(xmlFile.fileName()), qPrintable(xml.errorString()));
133 return false;
134 }
135 }
136
137 // Initialize persistent properties
138 mPersistentProps.reset(new QSettings(QString("%1/.%2.dat")
139 .arg(iApp::instance()->dataRootDir())
140 .arg(iApp::instance()->name()),
141 QSettings::IniFormat));
142 QStringList keys = mPersistentProps->allKeys();
143 for (int i = 0; i < keys.size(); ++i) {
144 QString key = keys.at(i);
145 setValue(key, mPersistentProps->value(key));
146 }
147
148 return true;
149 }
150
151 void Prop::done()
152 {
153 mPersistentProps.reset();
154 }
155
156 QVariant Prop::getValue(QString const & name, QVariant const & defaultValue) const
157 {
158 QHash<QString, QVariant>::const_iterator it = mProps.constFind(name);
159 if (it != mProps.constEnd()) {
160 QVariant value = *it;
161 if (value.type() == defaultValue.type())
162 return value;
163 else
164 return toVariant(value.toString(), defaultValue);
165 }
166 else
167 return defaultValue;
168 }
169
170 void Prop::setValue(QString const & name, QVariant const & value, bool persistent)
171 {
172 bool isChanged = true;
173
174 QHash<QString, QVariant>::iterator it = mProps.find(name);
175 if (it != mProps.end()) {
176 isChanged = *it != value;
177 *it = value;
178 }
179 else
180 mProps.insert(name, value);
181
182 if (persistent && mPersistentProps && mPersistentProps->isWritable())
183 mPersistentProps->setValue(name, value);
184
185 if (isChanged)
186 emit valueChanged(name, value);
187 }