]>
vaikene.ee Git - evaf/blob - src/libs/Common/app.cpp
3 * @brief Application interface implementation
6 * Copyright (c) 2011-2019 Enar Vaikene
8 * This file is part of the eVaf C++ cross-platform application development framework.
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.
16 * Alternatively, this file may be used in accordance with the Commercial License
17 * Agreement provided with the Software.
22 #include "iregistry.h"
23 #include "ieventqueue.h"
30 //-------------------------------------------------------------------
32 using namespace eVaf::Common
;
36 static Internal::App
* singleton
= nullptr;
39 iApp
* iApp::instance()
41 if (nullptr == singleton
)
43 singleton
= new Internal::App
;
48 char const * const iApp::EV_QUIT
= "iApp::quit";
49 char const * const iApp::EV_RESTART
= "iApp::restart";
50 char const * const iApp::EV_READY
= "iApp::ready";
51 char const * const iApp::EV_TERMINATING
= "iApp::terminating";
54 //-------------------------------------------------------------------
56 using namespace eVaf::Common::Internal
;
58 void App::destroyInstance()
60 if (nullptr != singleton
)
70 , mName(VER_PRODUCT_NAME_STR
)
76 setObjectName(QString("%1.iApp").arg(VER_MODULE_NAME_STR
));
77 EVAF_INFO("%s-App created", VER_MODULE_NAME_STR
);
82 EVAF_INFO("%s-App destroyed", VER_MODULE_NAME_STR
);
87 // Register our interface
88 iRegistry::instance()->registerInterface("iApp", this);
91 mEvQuit
= iEventQueue::instance()->subscribeEvent(iEventQueue::instance()->registerEvent(EV_QUIT
), this);
92 mEvRestart
= iEventQueue::instance()->subscribeEvent(iEventQueue::instance()->registerEvent(EV_RESTART
), this);
93 mEvReady
= iEventQueue::instance()->registerEvent(EV_READY
);
94 mEvTerminating
= iEventQueue::instance()->registerEvent(EV_TERMINATING
);
96 // Set the default application name and language
97 mName
= VER_PRODUCT_NAME_STR
;
98 mLanguage
= QLocale::system().name();
100 // Clear the XML file name
103 // Set initial bin and root directories
104 mRootDir
= mBinDir
= qApp
->applicationDirPath();
105 int t
= mBinDir
.lastIndexOf(QChar('/'), -1);
107 mRootDir
= mBinDir
.left(t
);
109 if (!mBinDir
.endsWith('/'))
111 if (!mRootDir
.endsWith('/'))
112 mRootDir
.append('/');
114 // Clear other directories
115 mDataRootDir
.clear();
116 mQtPluginsDir
.clear();
121 // Process environment variables
122 QStringList env
= QProcess::systemEnvironment();
123 for (int i
= 0; i
< env
.size(); ++i
) {
124 // Get the name/value pair
125 QString name
= env
.at(i
).section('=', 0, 0).trimmed();
126 QString value
= env
.at(i
).section('=', 1).trimmed();
128 if (name
== "EVAF_APP_NAME")
130 else if (name
== "EVAF_LANGUAGE")
132 else if (name
== "EVAF_ROOT_DIR") {
134 if (!mRootDir
.endsWith('/'))
135 mRootDir
.append('/');
137 else if (name
== "EVAF_DATA_ROOT_DIR") {
138 mDataRootDir
= value
;
139 if (!mDataRootDir
.endsWith('/'))
140 mDataRootDir
.append('/');
142 else if (name
== "EVAF_ETC_DIR") {
144 if (!mEtcDir
.endsWith('/'))
147 else if (name
== "EVAF_LOG_DIR") {
149 if (!mLogDir
.endsWith('/'))
152 else if (name
== "EVAF_DOC_DIR") {
154 if (!mDocDir
.endsWith('/'))
157 else if (name
== "EVAF_QT_PLUGINS_DIR") {
158 mQtPluginsDir
= value
;
159 if (!mQtPluginsDir
.endsWith('/'))
160 mQtPluginsDir
.append('/');
164 // Then process command-line arguments
165 env
= QCoreApplication::arguments();
166 for (int i
= 0; i
< env
.size(); ++i
) {
167 // Get the name and optional value
168 QStringList arg
= env
.at(i
).simplified().split('=');
170 if (QRegExp("-[-]?app(lication)?").exactMatch(arg
.at(0)) && arg
.size() > 1)
172 else if (QRegExp("-[-]?lang(uage)?").exactMatch(arg
.at(0)) && arg
.size() > 1)
173 mLanguage
= arg
.at(1);
174 else if (QRegExp("-[-]?root(dir)?").exactMatch(arg
.at(0)) && arg
.size() > 1) {
175 mRootDir
= arg
.at(1);
176 if (!mRootDir
.endsWith('/'))
177 mRootDir
.append('/');
179 else if (QRegExp("-[-]?dataroot(dir)?").exactMatch(arg
.at(0)) && arg
.size() > 1) {
180 mDataRootDir
= arg
.at(1);
181 if (!mDataRootDir
.endsWith('/'))
182 mDataRootDir
.append('/');
184 else if (QRegExp("-[-]?etc(dir)?").exactMatch(arg
.at(0)) && arg
.size() > 1) {
186 if (!mEtcDir
.endsWith('/'))
189 else if (QRegExp("-[-]?log(dir)?").exactMatch(arg
.at(0)) && arg
.size() > 1) {
191 if (!mLogDir
.endsWith('/'))
194 else if (QRegExp("-[-]?doc(dir)?").exactMatch(arg
.at(0)) && arg
.size() > 1) {
196 if (!mDocDir
.endsWith('/'))
199 else if (QRegExp("-[-]?qtplugins(dir)?").exactMatch(arg
.at(0)) && arg
.size() > 1) {
200 mQtPluginsDir
= arg
.at(1);
201 if (!mQtPluginsDir
.endsWith('/'))
202 mQtPluginsDir
.append('/');
209 bool App::event(QEvent
* e
)
211 if (e
->type() == Event::eVafEvent
) {
212 Event
* event
= static_cast<Event
*>(e
);
213 if (event
->id() == mEvQuit
)
215 else if (event
->id() == mEvRestart
)
221 return iApp::event(e
);
224 QString
const App::dataRootDir() const
226 if (mDataRootDir
.isEmpty()) {
227 #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
228 QString dataLoc
= QDir::homePath();
229 if (!dataLoc
.endsWith('/'))
231 dataLoc
.append(".local/share/data/");
232 mDataRootDir
= dataLoc
+ name();
233 if (!mDataRootDir
.endsWith('/'))
234 mDataRootDir
.append('/');
236 /// @TODO: Needs local data directory on Windows
237 mDataRootDir
= rootDir();
243 QString
const App::etcDir() const
245 if (mEtcDir
.isEmpty())
246 mEtcDir
= dataRootDir() + "etc/";
250 QString
const App::logDir() const
252 if (mLogDir
.isEmpty())
253 mLogDir
= dataRootDir() + "log/";
257 QString
const App::docDir() const
259 if (mDocDir
.isEmpty())
260 mDocDir
= rootDir() + "doc/";
264 QString
const App::qtPluginsDir() const
266 if (mQtPluginsDir
.isEmpty())
267 mQtPluginsDir
= binDir();
268 return mQtPluginsDir
;
271 QString
const App::xmlFileName() const
273 if (mXmlFile
.isEmpty()) {
276 // Try the full application name + country + language combination
277 QString name
= mName
+ "_" + mLanguage
+ ".xml";
278 fi
.setFile(etcDir() + name
);
282 // Try application name + country
283 name
= mName
+ "_" + mLanguage
.left(2) + ".xml";
284 fi
.setFile(etcDir() + name
);
288 // Fall-back to the generic name
289 mXmlFile
= mName
+ ".xml";
298 int const rval
= QCoreApplication::exec();
305 QCoreApplication::exit(RC_Restart
);
308 void App::quit(bool err
)
310 QCoreApplication::exit(err
? RC_Error
: RC_Quit
);
313 void App::setReady(bool value
)
315 if (mReady
!= value
) {
317 iEventQueue::instance()->broadcastEvent(new Event(mReady
? mEvReady
: mEvTerminating
));