X-Git-Url: https://vaikene.ee/gitweb/pswgen11.html?a=blobdiff_plain;f=src%2Flibs%2FCommon%2Fapp.cpp;h=b907a4b4ebe05c7749d026a4e52fd9d9a598cb14;hb=HEAD;hp=6f289427a864d3c53b7703208499daae3991fa75;hpb=688e916955a6b848dbbae1f65ae85a73593ed680;p=evaf
diff --git a/src/libs/Common/app.cpp b/src/libs/Common/app.cpp
index 6f28942..b907a4b 100644
--- a/src/libs/Common/app.cpp
+++ b/src/libs/Common/app.cpp
@@ -3,7 +3,7 @@
* @brief Application interface implementation
* @author Enar Vaikene
*
- * Copyright (c) 2011 Enar Vaikene
+ * Copyright (c) 2011-2019 Enar Vaikene
*
* This file is part of the eVaf C++ cross-platform application development framework.
*
@@ -19,8 +19,9 @@
#include "app.h"
#include "globals.h"
-#include "registry.h"
-#include "ienv.h"
+#include "iregistry.h"
+#include "ieventqueue.h"
+#include "event.h"
#include "version.h"
#include
@@ -30,10 +31,18 @@
using namespace eVaf::Common;
+namespace
+{
+ static Internal::App * singleton = nullptr;
+}
+
iApp * iApp::instance()
{
- Internal::App singleton;
- return &singleton;
+ if (nullptr == singleton)
+ {
+ singleton = new Internal::App;
+ }
+ return singleton;
}
char const * const iApp::EV_QUIT = "iApp::quit";
@@ -46,17 +55,31 @@ char const * const iApp::EV_TERMINATING = "iApp::terminating";
using namespace eVaf::Common::Internal;
+void App::destroyInstance()
+{
+ if (nullptr != singleton)
+ {
+ delete singleton;
+ singleton = nullptr;
+ }
+}
+
App::App()
: iApp()
, mReady(false)
, mName(VER_PRODUCT_NAME_STR)
+ , mEvQuit(0)
+ , mEvRestart(0)
+ , mEvReady(0)
+ , mEvTerminating(0)
{
setObjectName(QString("%1.iApp").arg(VER_MODULE_NAME_STR));
-
+ EVAF_INFO("%s-App created", VER_MODULE_NAME_STR);
}
App::~App()
{
+ EVAF_INFO("%s-App destroyed", VER_MODULE_NAME_STR);
}
bool App::init()
@@ -64,6 +87,12 @@ bool App::init()
// Register our interface
iRegistry::instance()->registerInterface("iApp", this);
+ // Register events
+ mEvQuit = iEventQueue::instance()->subscribeEvent(iEventQueue::instance()->registerEvent(EV_QUIT), this);
+ mEvRestart = iEventQueue::instance()->subscribeEvent(iEventQueue::instance()->registerEvent(EV_RESTART), this);
+ mEvReady = iEventQueue::instance()->registerEvent(EV_READY);
+ mEvTerminating = iEventQueue::instance()->registerEvent(EV_TERMINATING);
+
// Set the default application name and language
mName = VER_PRODUCT_NAME_STR;
mLanguage = QLocale::system().name();
@@ -71,6 +100,24 @@ bool App::init()
// Clear the XML file name
mXmlFile.clear();
+ // Set initial bin and root directories
+ mRootDir = mBinDir = qApp->applicationDirPath();
+ int t = mBinDir.lastIndexOf(QChar('/'), -1);
+ if (t >= 0)
+ mRootDir = mBinDir.left(t);
+
+ if (!mBinDir.endsWith('/'))
+ mBinDir.append('/');
+ if (!mRootDir.endsWith('/'))
+ mRootDir.append('/');
+
+ // Clear other directories
+ mDataRootDir.clear();
+ mQtPluginsDir.clear();
+ mEtcDir.clear();
+ mLogDir.clear();
+ mDocDir.clear();
+
// Process environment variables
QStringList env = QProcess::systemEnvironment();
for (int i = 0; i < env.size(); ++i) {
@@ -82,6 +129,36 @@ bool App::init()
mName = value;
else if (name == "EVAF_LANGUAGE")
mLanguage = value;
+ else if (name == "EVAF_ROOT_DIR") {
+ mRootDir = value;
+ if (!mRootDir.endsWith('/'))
+ mRootDir.append('/');
+ }
+ else if (name == "EVAF_DATA_ROOT_DIR") {
+ mDataRootDir = value;
+ if (!mDataRootDir.endsWith('/'))
+ mDataRootDir.append('/');
+ }
+ else if (name == "EVAF_ETC_DIR") {
+ mEtcDir = value;
+ if (!mEtcDir.endsWith('/'))
+ mEtcDir.append('/');
+ }
+ else if (name == "EVAF_LOG_DIR") {
+ mLogDir = value;
+ if (!mLogDir.endsWith('/'))
+ mLogDir.append('/');
+ }
+ else if (name == "EVAF_DOC_DIR") {
+ mDocDir = value;
+ if (!mDocDir.endsWith('/'))
+ mDocDir.append('/');
+ }
+ else if (name == "EVAF_QT_PLUGINS_DIR") {
+ mQtPluginsDir = value;
+ if (!mQtPluginsDir.endsWith('/'))
+ mQtPluginsDir.append('/');
+ }
}
// Then process command-line arguments
@@ -94,7 +171,101 @@ bool App::init()
mName = arg.at(1);
else if (QRegExp("-[-]?lang(uage)?").exactMatch(arg.at(0)) && arg.size() > 1)
mLanguage = arg.at(1);
+ else if (QRegExp("-[-]?root(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) {
+ mRootDir = arg.at(1);
+ if (!mRootDir.endsWith('/'))
+ mRootDir.append('/');
+ }
+ else if (QRegExp("-[-]?dataroot(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) {
+ mDataRootDir = arg.at(1);
+ if (!mDataRootDir.endsWith('/'))
+ mDataRootDir.append('/');
+ }
+ else if (QRegExp("-[-]?etc(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) {
+ mEtcDir = arg.at(1);
+ if (!mEtcDir.endsWith('/'))
+ mEtcDir.append('/');
+ }
+ else if (QRegExp("-[-]?log(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) {
+ mLogDir = arg.at(1);
+ if (!mLogDir.endsWith('/'))
+ mLogDir.append('/');
+ }
+ else if (QRegExp("-[-]?doc(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) {
+ mDocDir = arg.at(1);
+ if (!mDocDir.endsWith('/'))
+ mDocDir.append('/');
+ }
+ else if (QRegExp("-[-]?qtplugins(dir)?").exactMatch(arg.at(0)) && arg.size() > 1) {
+ mQtPluginsDir = arg.at(1);
+ if (!mQtPluginsDir.endsWith('/'))
+ mQtPluginsDir.append('/');
+ }
}
+
+ return true;
+}
+
+bool App::event(QEvent * e)
+{
+ if (e->type() == Event::eVafEvent) {
+ Event * event = static_cast(e);
+ if (event->id() == mEvQuit)
+ quit();
+ else if (event->id() == mEvRestart)
+ restart();
+
+ return false;
+ }
+ else
+ return iApp::event(e);
+}
+
+QString const App::dataRootDir() const
+{
+ if (mDataRootDir.isEmpty()) {
+#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
+ QString dataLoc = QDir::homePath();
+ if (!dataLoc.endsWith('/'))
+ dataLoc.append('/');
+ dataLoc.append(".local/share/data/");
+ mDataRootDir = dataLoc + name();
+ if (!mDataRootDir.endsWith('/'))
+ mDataRootDir.append('/');
+#endif
+ /// @TODO: Needs local data directory on Windows
+ mDataRootDir = rootDir();
+ }
+
+ return mDataRootDir;
+}
+
+QString const App::etcDir() const
+{
+ if (mEtcDir.isEmpty())
+ mEtcDir = dataRootDir() + "etc/";
+ return mEtcDir;
+}
+
+QString const App::logDir() const
+{
+ if (mLogDir.isEmpty())
+ mLogDir = dataRootDir() + "log/";
+ return mLogDir;
+}
+
+QString const App::docDir() const
+{
+ if (mDocDir.isEmpty())
+ mDocDir = rootDir() + "doc/";
+ return mDocDir;
+}
+
+QString const App::qtPluginsDir() const
+{
+ if (mQtPluginsDir.isEmpty())
+ mQtPluginsDir = binDir();
+ return mQtPluginsDir;
}
QString const App::xmlFileName() const
@@ -104,15 +275,15 @@ QString const App::xmlFileName() const
// Try the full application name + country + language combination
QString name = mName + "_" + mLanguage + ".xml";
- fi.setFile(iEnv::instance()->etcDir() + name);
+ fi.setFile(etcDir() + name);
if (fi.isReadable())
mXmlFile = name;
else {
// Try application name + country
name = mName + "_" + mLanguage.left(2) + ".xml";
- fi.setFile(iEnv::instance()->etcDir() + name);
+ fi.setFile(etcDir() + name);
if (fi.isReadable())
- mName = name;
+ mXmlFile = name;
else
// Fall-back to the generic name
mXmlFile = mName + ".xml";
@@ -121,6 +292,14 @@ QString const App::xmlFileName() const
return mXmlFile;
}
+int App::exec()
+{
+ setReady(true);
+ int const rval = QCoreApplication::exec();
+ setReady(false);
+ return rval;
+}
+
void App::restart()
{
QCoreApplication::exit(RC_Restart);
@@ -130,3 +309,15 @@ void App::quit(bool err)
{
QCoreApplication::exit(err ? RC_Error : RC_Quit);
}
+
+void App::setReady(bool value)
+{
+ if (mReady != value) {
+ mReady = value;
+ iEventQueue::instance()->broadcastEvent(new Event(mReady ? mEvReady : mEvTerminating));
+ if (mReady)
+ emit ready();
+ else
+ emit terminating();
+ }
+}