Changed directory names from GUI and CLI applications to follow namespace names.
add_subdirectory(libs)
-#add_subdirectory(main)
+add_subdirectory(main)
#add_subdirectory(plugins)
virtual void restart();
- virtual void quit(bool err);
+ virtual void quit(bool err = false);
virtual bool isReady() const { return mReady; }
# define __COMMON_GLOBALS_H
#include "libcommon.h"
+#include "ilogger.h"
/**
- * Common namespace for eVaf.
+ * eVaf is a C++ cross-platform modular application development framework using Qt.
+ *
+ * The eVaf main executable is an empty container that needs to be filled with external modules to
+ * provide the required functionality. The eVaf main GUI executable, if run without external modules,
+ * shows just an empty window that can be closed to terminate the application. The eVaf main CLI
+ * executable runs until terminated with CTRL+C.
+ *
+ * eVaf modules are loadable libraries (.so or .dll files) that implement the features and
+ * functions of the application. By combining together different modules, an unique application can
+ * be made in very little time. Every module implements a specific function or feature and only when
+ * put together, the actual application is created.
+ *
+ * eVaf interfaces are the way how the functionality of eVaf modules is used. Every feature implemented
+ * by a module has an interface used to feed the module with data or request information from the module.
+ *
+ * eVaf events are used by modules to send out information that they have collected or processed.
+ * While interfaces are the way how to feed modules with data or requests, then events are mostly for
+ * spontaneous data.
+ *
+ * Events broadcast by modules can have data objects attached to them. To avoid unnecessary copying of
+ * data, these data objects are shared and reference-counted. When the data object is attached to the
+ * event, its internal reference counter is increased by one. When the eVaf event queue has delivered
+ * the event to all the subscribers, it destroys the event and decreases the reference-counter of the
+ * data object by one. If no other module kept the data object, then the data object's reference counter
+ * becomes zero and it is destroyed too.
*/
namespace eVaf {
/**
* eVaf common library initialized
- * @param args List of arguments
* @return True if ok; false if the initialization failed
*
* Call this function to initialize the common eVaf library after creating the Qt application
* object and before loading any of the modules.
*/
-extern bool COMMON_EXPORT init(QStringList const & args);
+extern bool COMMON_EXPORT init();
+/**
+ * Internal implementation of the common eVaf library.
+ */
+namespace Internal {
+} // namespace eVaf::Common::Internal
} // namespace eVaf::Common
} // namespace eVaf
+/**
+ * Tests that the condition is true.
+ *
+ * This macro tests for the condition and if not true, exits with a fatal error.
+ * Use this macro to test for conditions that must be met in order for the application
+ * to continue.
+ */
+#define EVAF_TEST(cond) \
+ if (!cond) \
+ EVAF_FATAL(#cond);
+
+/**
+ * Tests that the condition is true with a custom error message.
+ *
+ * This macro tests for the condition and if not true, exist with a custom fatal error message.
+ */
+#define EVAF_TEST_X(const, msg) \
+ if (!cond) \
+ EVAF_FATAL(msg);
+
#endif // globals.h
*
* This function requests the eVaf application to quit.
*/
- virtual void quit(bool err) = 0;
+ virtual void quit(bool err = false) = 0;
/**
* Returns true if the eVaf application is ready.
* are output. With this function the severity level can be changed so that also less important
* messages are output.
*/
- virtual void setSeverity(Severity severity, QString const & source) = 0;
+ virtual void setSeverity(Severity severity, QString const & source = 0) = 0;
/**
* Returns the current maximum size of log files in KiB.
#endif
;
+/**
+ * Macro for fatal error messages.
+ *
+ * This macro expands to a fatal error message output with the location in the source code where the error
+ * occurred.
+ */
+#define EVAF_FATAL_ERROR(...) \
+ do { \
+ eVaf::Common::iLogger::instance()->write( \
+ eVaf::Common::iLogger::Fatal, \
+ eVaf::Common::iLogger::instance()->printf(__VA_ARGS__), \
+ 0, \
+ eVaf::Common::iLogger::instance()->printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__) \
+ ); \
+ } while (0)
+
+/**
+ * Macro for error messages.
+ *
+ * This macro expands to an error message output with the location in the source code where the error
+ * occurred.
+ */
+#define EVAF_ERROR(...) \
+ do { \
+ eVaf::Common::iLogger::instance()->write( \
+ eVaf::Common::iLogger::Error, \
+ eVaf::Common::iLogger::instance()->printf(__VA_ARGS__), \
+ 0, \
+ eVaf::Common::iLogger::instance()->printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__) \
+ ); \
+ } while (0)
+
+/**
+ * Macro for warning messages.
+ *
+ * This macro expands to a warning message output with the location in the source code where the warning
+ * occurred.
+ */
+#define EVAF_WARNING(...) \
+ do { \
+ eVaf::Common::iLogger::instance()->write( \
+ eVaf::Common::iLogger::Warning, \
+ eVaf::Common::iLogger::instance()->printf(__VA_ARGS__), \
+ 0, \
+ eVaf::Common::iLogger::instance()->printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__) \
+ ); \
+ } while (0)
+
+/**
+ * Macro for info messages.
+ *
+ * This macro expands to an info message output with the location in the source code where the message
+ * is output.
+ */
+#define EVAF_INFO(...) \
+ do { \
+ eVaf::Common::iLogger::instance()->write( \
+ eVaf::Common::iLogger::Info, \
+ eVaf::Common::iLogger::instance()->printf(__VA_ARGS__), \
+ 0, \
+ eVaf::Common::iLogger::instance()->printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__) \
+ ); \
+ } while (0)
+
+/**
+ * Macro for debug messages.
+ *
+ * This macro expands to a debug message output with the location in the source code where the message
+ * is output. All the debug messages are supressed when the NDEBUG directive is defined.
+ */
+#ifndef NDEBUG
+# define EVAF_DEBUG(...) \
+ do { \
+ eVaf::Common::iLogger::instance()->write( \
+ eVaf::Common::iLogger::Debug, \
+ eVaf::Common::iLogger::instance()->printf(__VA_ARGS__), \
+ 0, \
+ eVaf::Common::iLogger::instance()->printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__) \
+ ); \
+ } while (0)
+#else
+# define EVAF_DEBUG(...) \
+ do { } while (0)
+#endif
+
#endif // ilogger.h
--- /dev/null
+/**
+ * @file Common/logger.cpp
+ * @brief iLogger interface implementation
+ * @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 "logger.h"
+#include "iregistry.h"
+#include "ienv.h"
+
+#include <QtCore>
+
+#ifdef Q_OS_WIN32
+# include <windows.h>
+#endif
+
+#ifdef Q_OS_LINUX
+# include <stdio.h>
+# include <stdarg.h>
+# include <stdlib.h>
+#endif
+
+
+//-------------------------------------------------------------------
+
+using namespace eVaf::Common;
+
+iLogger * iLogger::instance()
+{
+ static Internal::Logger singleton;
+ return &singleton;
+}
+
+
+//-------------------------------------------------------------------
+
+using namespace eVaf::Common::Internal;
+
+void defFatalMsgHandler(QString const & msg, QString const & source, QString const & where)
+{
+ Q_UNUSED(source);
+
+ fprintf(stderr, "FATAL ERROR: %s (occurred in %s)\n", qPrintable(msg), qPrintable(where));
+
+#ifdef Q_OS_LINUX
+ abort();
+#else
+ exit(1);
+#endif
+}
+
+
+//-------------------------------------------------------------------
+
+LoggerSource::LoggerSource()
+ : QSharedData()
+ , severity(iLogger::Fatal)
+ , maxSize(100 * 1024)
+ , maxCount(3)
+{}
+
+LoggerSource::LoggerSource(LoggerSource const & o)
+ : QSharedData()
+ , severity(o.severity)
+ , maxSize(o.maxSize)
+ , maxCount(o.maxCount)
+{}
+
+void LoggerSource::init(QString const & source, QString const & logDir, QString const & etcDir)
+{
+ Q_UNUSED(etcDir);
+
+ fileName = logDir + source + ".log";
+}
+
+
+//-------------------------------------------------------------------
--- /dev/null
+/**
+ * @file Common/logger.h
+ * @brief iLogger interface implementation
+ * @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_LOGGER_H
+#define __COMMON_LOGGER_H
+
+#include "ilogger.h"
+
+#include <QObject>
+
+
+namespace eVaf {
+namespace Common {
+namespace Internal {
+
+/// Default fatal error message handler
+void defFatalMsgHandler(QString const & msg, QString const & source, QString const & where);
+
+/**
+ * Logger source.
+ *
+ * This class stores information about known sources.
+ */
+class LoggerSource : public QSharedData
+{
+public:
+
+ LoggerSource();
+
+ LoggerSource(LoggerSource const & o);
+
+ /**
+ * Initializes the source
+ * @param source Name of the source
+ * @param logDir Full path to the log directory
+ * @param etcDir Full path to the configuration files directory
+ *
+ * This function initializes the newly created logger source and sets initial
+ * parameters for the source.
+ *
+ * Default parameters:
+ * @li severity is set to Fatal
+ * @li maximum size of the log file is set to 100 KiB
+ * @li maximum number of log files is set to 3
+ *
+ * Default parameters can be overwritten with values read from the logger.ini file.
+ * This file should have the [.default] section with new default values for all the
+ * sources. Individual sources can have their parameters changed in sections with the
+ * name of the source.
+ *
+ * Example logger.ini file:
+ * @code
+ * [.default]
+ * severity = Fatal
+ * maxSize = 100
+ * maxCount = 3
+ *
+ * [my-source]
+ * severity = Warning
+ * maxSize = 1000
+ * maxCount = 10
+ * @endcode
+ */
+ void init(QString const & source, QString const & logDir, QString const & etcDir);
+
+
+public: // Members (we don't bother adding getter/setter functions)
+
+ /// Current severity level
+ iLogger::Severity severity;
+
+ /// Current log file name
+ QString fileName;
+
+ /// Current maximum size of log files
+ uint maxSize;
+
+ /// Current maximum number of log files
+ uint maxCount;
+
+};
+
+/**
+ * iLogger interface implementation.
+ *
+ * This class implements the iLogger interface.
+ */
+class Logger : public iLogger
+{
+ Q_OBJECT
+
+public:
+
+ Logger();
+
+ virtual ~Logger();
+
+ /**
+ * Initializes the interface implementation
+ * @return True if ok; false if initialization failed
+ */
+ bool init();
+
+ /*
+ iLogger interface
+ */
+
+ virtual QString defaultSource() const { return mDefaultSource; }
+
+ virtual void setDefaultSource(QString const & source);
+
+ virtual Severity severity(QString const & source = 0) const;
+
+ virtual void setSeverity(Severity severity, QString const & source = 0);
+
+ virtual uint maxSize(QString const & source = 0) const;
+
+ virtual void setMaxSize(uint maxSize, QString const & source = 0);
+
+ virtual uint maxCount(QString const & source = 0) const;
+
+ virtual void setMaxCount(uint maxCount, QString const & source = 0);
+
+ virtual Severity consoleSeverity() const { return mConsoleSeverity; }
+
+ virtual void setConsoleSeverity(Severity severity);
+
+ virtual void write(Severity severity, QString const & msg, QString const & source = 0, QString const & where = 0);
+
+ virtual QString printf(char const * const fmt, ...) const;
+
+ virtual FatalMsgHandler installFatalMsgHandler(FatalMsgHandler newHandler);
+
+
+private: // Members
+
+ /// Current fatal error message handler
+ FatalMsgHandler mFatalMsgHandler;
+
+ /// Current default source (defaults to "evaf")
+ QString mDefaultSource;
+
+ /// Logger sources
+ QHash<QString, QExplicitlySharedDataPointer<LoggerSource> > mSources;
+
+
+private: // Methods
+
+ /// Returns the source by the name
+ LoggerSource * getSource(QString const & name) const;
+
+ /// Creates a new source
+ LoggerSource * addSource(QString const & name);
+
+#ifdef Q_OS_WIN32
+ /// Changes text colors on the Windows console
+ void setColor(short int c);
+#endif
+
+};
+
+} // namespace eVaf::Common::Internal
+} // namespace eVaf::Common
+} // namespace eVaf
+
+#endif // logger.h
VALUE "OriginalFilename", VER_ORIGINAL_FILENAME_STR
VALUE "ProductName", VER_PRODUC_TNAME_STR
VALUE "ProductVersion", VER_PRODUCT_VERSION_STR
+ VALUE "Build Date", VER_PRODUCT_DATE_STR
VALUE "Module Name", VER_MODULE_NAME_STR
VALUE "Module Type", VER_MODULE_TYPE_STR
END
-add_subdirectory(gui)
-add_subdirectory(cli)
+add_subdirectory(GUI)
+#add_subdirectory(CLI)
include_directories(${eVaf_INCLUDE})
# Required eVaf libraries
-set(eVaf_LIBRARIES)
+set(eVaf_LIBRARIES CommonLib)
# Source files
set(SRCS
main.cpp
exithandler.cpp
fatalerr.cpp
- version.cpp
+ #version.cpp
)
if(WIN32)
set(SRCS
${SRCS}
winconsole.cpp
)
-)
+endif(WIN32)
# Header files for the meta-object compiler
set(MOC_HDRS
main.h
fatalerr.h
- version_p.h
+ #version_p.h
)
# Resources
--- /dev/null
+/**
+ * @file main/GUI/exithandler.cpp
+ * @brief Exit handlers for the eVaf main executable
+ * @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 "exithandler.h"
+
+#include <Common/iLogger>
+#include <Common/iApp>
+
+#include <QtCore>
+
+#ifdef Q_OS_LINUX
+# include <signal.h>
+#endif
+
+#ifdef Q_OS_WIN32
+# include <windows.h>
+#endif
+
+namespace eVaf {
+namespace GUI {
+namespace Internal {
+
+#ifdef Q_OS_LINUX
+
+/**
+ * Signal handler on Linux
+ *
+ * Handles TERM and HUP signals and either quits or restarts the application.
+ *
+ * @TODO According to the signal(7) documentation, only "safe" functions can be called from the
+ * signal handler. We don't know how safe it is to call iApp::quit() and iApp::restart() and
+ * probably have to implement "safe" versions of these functions.
+ */
+static void signalHandler(int sig)
+{
+ eVaf::Common::iApp * app = eVaf::Common::iApp::instance();
+
+ switch (sig) {
+ case SIGTERM:
+ if (app)
+ app->quit();
+ else
+ exit(0);
+ break;
+ case SIGHUP:
+ if (app)
+ app->restart();
+ break;
+ }
+}
+
+#endif
+
+#ifdef Q_OS_WIN32
+
+/**
+ * Signal handler on Windows
+ *
+ * Either quits or restarts the application.
+ *
+ * @TODO Is there a similar concept of "safe" functions for Windows signal handlers?
+ */
+static BOOL WINAPI signalHandler(DWORD sig)
+{
+ eVaf::Common::iApp * app = eVaf::Common::iApp::instance();
+
+ switch (sig) {
+ case CTRL_C_EVENT:
+ case CTRL_CLOSE_EVENT:
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ if (app)
+ app->quit();
+ else
+ exit(0);
+ return true;
+ break;
+ case CTRL_BREAK_EVENT:
+ if (app)
+ app->restart();
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+#endif
+
+} // namespace eVaf::GUI::Internal
+} // namespace eVaf::GUI
+} // namespace eVaf
+
+using namespace eVaf::GUI::Internal;
+
+bool installExitHandler()
+{
+
+#ifdef Q_OS_LINUX
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = signalHandler;
+ if (sigaction(SIGTERM, &sa, NULL) != 0) {
+ EVAF_FATAL_ERROR("sigaction() failed: %m");
+ return false;
+ }
+ if (sigaction(SIGHUP, &sa, NULL) != 0) {
+ EVAF_FATAL_ERROR("sigaction() failed: %m");
+ return false;
+ }
+#endif
+
+#ifdef Q_OS_WIN32
+ if (SetConsoleCtrlHandler(signalHandler, true) == 0) {
+ EVAF_FATAL_ERROR("SetConsoleCtrlHandler() failed");
+ return false;
+ }
+#endif
+
+ return true;
+}
/**
- * @file main/gui/main.h
- * @brief The main eVaf GUI application class
+ * @file main/GUI/exithandler.h
+ * @brief Exit handlers for the eVaf main executable
+ * @author Enar Vaikene
*
* Copyright (c) 2011 Enar Vaikene
*
* Agreement provided with the Software.
*/
-#ifndef __GUI_MAIN_H
-#define __GUI_MAIN_H
-
-#include <QApplication>
+#ifndef __GUI_EXITHANDLER_H
+# define __GUI_EXITHANDLER_H
+namespace eVaf {
+namespace GUI {
+namespace Internal {
/**
- * The main eVaf GUI application.
+ * Installs an exit handler for the selected platform.
*
- * eVafGUI is the main GUI executable. It provides an empty GUI application
- * that is used to load other eVaf modules.
- */
-namespace eVafGUI {
-
-/**
- * The main eVaf GUI application class.
+ * Exit handler quits or restarts the application when a corresponding signal
+ * is received.
*/
-class Application : public QApplication
-{
- Q_OBJECT
-
-public:
-
- Application(int & argc, char ** argv);
-
- virtual ~Application();
-
-};
+bool installExitHandler();
-} // namespace eVafGUI
+} // namespace eVaf::GUI::Internal
+} // namespace eVaf::GUI
+} // namespace eVaf
-#endif // main.h
+#endif // exithandler.h
--- /dev/null
+/**
+ * @file main/GUI/fatalerr.cpp
+ * @brief Fatal error message dialog box
+ * @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 "fatalerr.h"
+
+#include <QtGui>
+
+using namespace eVaf::GUI::Internal;
+
+
+//-------------------------------------------------------------------
+
+FatalErr::FatalErr(QString const & title, QString const & text, QWidget * parent)
+ : QDialog(parent, Qt::WindowTitleHint)
+ , mTimer(Timer)
+{
+ setWindowTitle(title);
+
+ QVBoxLayout * layout = new QVBoxLayout;
+ layout->setSpacing(10);
+ setLayout(layout);
+
+ QHBoxLayout * messageBox = new QHBoxLayout;
+ messageBox->setSpacing(20);
+ layout->addLayout(messageBox);
+
+ // Icon
+ QLabel * l = new QLabel;
+ l->setPixmap(QMessageBox::standardIcon(QMessageBox::Critical));
+ l->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ messageBox->addWidget(l);
+
+ // Error message text
+ l = new QLabel(text);
+ l->setWordWrap(true);
+ l->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ messageBox->addWidget(l);
+
+ // Warning about the Ignore button
+ l = new QLabel;
+ l->setTextFormat(Qt::RichText);
+ l->setText(tr(
+ "<p><small><i>Clicking on the 'Abort' button aborts the application.<br>"
+ "Clicking on the 'Ignore' button keeps the application running for diagnostics.</i></small></p>"
+ "<p><small><font color=\"red\">The application might be unstable if fatal errors are ignored!</font></small></p>"
+ ));
+ layout->addWidget(l);
+
+ // Buttons
+ QHBoxLayout * buttonBox = new QHBoxLayout;
+ layout->addLayout(buttonBox);
+
+ buttonBox->addStretch();
+
+ wAbort = new QPushButton(tr("%Abort (%1 sec)").arg(mTimer));
+ connect(wAbort, SIGNAL(clicked()), this, SLOT(abortClicked()));
+ buttonBox->addWidget(wAbort);
+ setFocusProxy(wAbort);
+
+ QPushButton * b = new QPushButton(tr("&Ignore"));
+ connect(b, SIGNAL(clicked()), this, SLOT(ignoreClicked()));
+ buttonBox->addWidget(b);
+
+ setResult(Abort);
+
+ // Start the count-down timer
+ startTimer(1000);
+}
+
+void FatalErr::timerEvent(QTimerEvent *)
+{
+ --mTimer;
+ wAbort->setText(tr("&Abort (%1 sec)").arg(mTimer));
+
+ if (mTimer <= 0)
+ done(Abort);
+}
+
+void FatalErr::abortClicked()
+{
+ done(Abort);
+}
+
+void FatalErr::ignoreClicked()
+{
+ done(Ignore);
+}
+
+int FatalErr::message(QString const & title, QString const & text, QWidget * parent)
+{
+ FatalErr msg(title, text, parent);
+ return msg.exec();
+}
--- /dev/null
+/**
+ * @file main/GUI/fatalerr.h
+ * @brief Fatal error message dialog box
+ * @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 __GUI_FATALERR_H
+# define __GUI_FATALERR_H
+
+#include <QDialog>
+
+class QTimerEvent;
+
+namespace eVaf {
+namespace GUI {
+namespace Internal {
+
+/**
+ * Fatal error message dialog box
+ *
+ * The fatal error message dialog box shows a fatal error message and starts a count-down
+ * to close the dialog box and abort the application. Users can click on the Ignore button
+ * to keep the application running for diagnostics.
+ */
+class FatalErr : public QDialog
+{
+ Q_OBJECT
+
+public:
+
+ /// Returns values
+ enum Result {
+ Abort = 0, ///< User clicked on the Abort button or the dialog box timed out
+ Ignore = 1 ///< User clicked on the Ignore button
+ };
+
+ /**
+ * Creates the fatal error message dialog box
+ * @param title Title of the dialog box
+ * @param text Text shown on the dialog box
+ * @param parent Optional parent widget
+ */
+ FatalErr(QString const & title, QString const & text, QWidget * parent = 0);
+
+ /**
+ * Shows a fatal error message dialog box
+ * @param title Title of the dialog box
+ * @param text Text shown on the dialog box
+ * @param parent Optional parent widget
+ * @return The result code
+ */
+ static int message(QString const & title, QString const & text, QWidget * parent = 0);
+
+
+protected:
+
+ /// Timer event handler
+ virtual void timerEvent(QTimerEvent *);
+
+
+private slots:
+
+ /// Ignore button clicked
+ void ignoreClicked();
+
+ /// Abort button clicked
+ void abortClicked();
+
+
+private:
+
+ /// Count-down time in secons
+ static int const Timer = 60;
+
+ /// Count-down timer
+ int mTimer;
+
+ /// The Abort button
+ QPushButton * wAbort;
+
+};
+
+} // namespace eVaf::GUI::Internal
+} // namespace eVaf::GUI
+} // namespace eVaf
+
+#endif // fatalerr.h
--- /dev/null
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/eVaf">
+</qresource>
+</RCC>
--- /dev/null
+/**
+ * @file main/GUI/main.cpp
+ * @brief The main eVaf GUI application class
+ * @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 "main.h"
+#include "exithandler.h"
+#include "fatalerr.h"
+//#include "version_p.h"
+#include "version.h"
+
+#ifdef Q_OS_WIN32
+#include "winconsole.h"
+#endif
+
+#include <Common/Globals>
+#include <Common/iLogger>
+#include <Common/iEnv>
+#include <Common/iApp>
+
+#include <QtGui>
+
+#ifdef Q_OS_LINUX
+# include <sys/types.h>
+# include <unistd.h>
+#endif
+
+
+//-------------------------------------------------------------------
+
+namespace eVaf {
+namespace GUI {
+namespace Internal {
+
+/**
+ * Flag indicating that the application should be more verbose when dealing with fatal errors.
+ *
+ * If this flag is set, then shows fatal errors on the screen as dialog boxes and
+ * the user has to close them before terminating the application.
+ *
+ * If this flag is not set, then no messages are shown and the application terminates
+ * silently. Error messages are written only into the log file.
+ */
+static bool BeVerbose = true;
+
+#ifdef Q_OS_WIN32
+/**
+ * Flag indicating that the application needs a console window.
+ *
+ * If this flag is set, opens an extra console window for message output.
+ */
+static bool NeedsConsole = false;
+#endif
+
+/**
+ * Console severity level.
+ *
+ * This variable is used to set the console severity level. The severity level is changed
+ * with command-line arguments.
+ */
+static eVaf::Common::iLogger::Severity ConsoleSeverityLevel = eVaf::Common::iLogger::Fatal;
+
+/**
+ * Qt message handler replacement.
+ * @param type Type of the message
+ * @param msg The message
+ *
+ * This function outputs messages to the console and to the log file.
+ */
+static void messageOutput(QtMsgType type, char const * const msg)
+{
+ static bool inHandler = false;
+
+ // Avoid recursions in case outputting a message causes another message to be output
+ if (inHandler)
+ return;
+ inHandler = true;
+
+ // Qt message type conversion to eVaf logger severity levels
+ eVaf::Common::iLogger::Severity v;
+ switch (type) {
+ case QtWarningMsg:
+ v = eVaf::Common::iLogger::Warning;
+ break;
+ case QtCriticalMsg:
+ v = eVaf::Common::iLogger::Error;
+ break;
+ case QtFatalMsg:
+ v = eVaf::Common::iLogger::Fatal;
+ break;
+ default:
+ v = eVaf::Common::iLogger::Debug;
+ }
+
+ // Output to the log file and console
+ eVaf::Common::iLogger::instance()->write(v, msg);
+
+ inHandler = false;
+}
+
+/**
+ * Fatal error message handler
+ * @param msg The error message
+ * @param source Source of the message
+ * @param where Where the error occurred
+ *
+ * This function shows a critical error message box on the screen if needed and then terminates
+ * the application.
+ *
+ * If the critical error message is shown, then the user has an option to ignore the error. In this
+ * case the application is not terminated.
+ */
+static void fatalMsgHandler(QString const & msg, QString const & source, QString const & where)
+{
+ // Show the message on the screen
+ if (BeVerbose) {
+ if (FatalErr::message(QObject::tr("Fatal Error"),
+ QObject::tr("%1\n\nOccurred in '%2'")
+ .arg(msg)
+ .arg(where),
+ 0) == FatalErr::Ignore)
+ return;
+ }
+#ifdef Q_OS_LINUX
+ abort();
+#else
+ exit(1);
+#endif
+}
+
+} // namespace eVaf::GUI::Internal
+} // namespace eVaf::GUI
+} // namespace eVaf
+
+
+//-------------------------------------------------------------------
+
+using namespace eVaf;
+using namespace eVaf::GUI;
+
+Application::Application(int & argc, char ** argv)
+ : QApplication(argc, argv)
+{
+ setObjectName(QString("%1-%2").arg(VER_MODULE_NAME_STR).arg(__FUNCTION__));
+
+ EVAF_INFO("%s version %s created", qPrintable(objectName()), VER_FILE_VERSION_STR);
+}
+
+Application::~Application()
+{
+ EVAF_INFO("%s destroyed", qPrintable(objectName()));
+}
+
+bool Application::processCommandLine(int argc, char ** argv)
+{
+ QStringList args;
+ for (int i = 1; i < argc; ++i)
+ args += argv[i];
+
+ for (int i = 0; i < args.size(); ++i) {
+ // Get the argument and optional value
+ QStringList arg = args.at(i).simplified().split(QChar('='));
+
+ if (QRegExp("(-[-]?version)|([-//]V)").exactMatch(arg.at(0))) {
+ printVersion();
+ return false;
+ }
+ else if (QRegExp("(-[-]?help)|([-//][h/?])").exactMatch(arg.at(0))) {
+ printHelp();
+ return false;
+ }
+ else if (QRegExp("-[-]?help-qt").exactMatch(arg.at(0))) {
+ printQtHelp();
+ return false;
+ }
+ else if (QRegExp("-[-]?verbose").exactMatch(arg.at(0)) && arg.size() > 1) {
+#ifdef Q_OS_WIN32
+ Internal::NeedsConsole = true;
+#endif
+ QString v = arg.at(1).toLower();
+ if (v == "debug")
+ Internal::ConsoleSeverityLevel = Common::iLogger::Debug;
+ else if (v == "info")
+ Internal::ConsoleSeverityLevel = Common::iLogger::Info;
+ else if (v == "warning")
+ Internal::ConsoleSeverityLevel = Common::iLogger::Warning;
+ else if (v == "error")
+ Internal::ConsoleSeverityLevel = Common::iLogger::Error;
+ else if (v == "fatal")
+ Internal::ConsoleSeverityLevel = Common::iLogger::Fatal;
+ else if (v == "none") {
+ Internal::ConsoleSeverityLevel = Common::iLogger::None;
+ Internal::BeVerbose = false;
+#ifdef Q_OS_WIN32
+ Internal::NeedsConsole = false;
+#endif
+ }
+ else {
+ printHelp();
+ return false;
+ }
+ }
+ else if (QRegExp("-[v]+").exactMatch(arg.at(0)) && arg.size() == 1) {
+ // The number of 'v's increases the verbosity
+ for (int j = 1; j < arg.at(0).size(); ++j) {
+ switch (Internal::ConsoleSeverityLevel) {
+ case Common::iLogger::None:
+ Internal::ConsoleSeverityLevel = Common::iLogger::Fatal;
+ break;
+ case Common::iLogger::Fatal:
+ Internal::ConsoleSeverityLevel = Common::iLogger::Error;
+ break;
+ case Common::iLogger::Error:
+ Internal::ConsoleSeverityLevel = Common::iLogger::Warning;
+ break;
+ case Common::iLogger::Warning:
+ Internal::ConsoleSeverityLevel = Common::iLogger::Info;
+ break;
+ case Common::iLogger::Info:
+ Internal::ConsoleSeverityLevel = Common::iLogger::Debug;
+ break;
+ case Common::iLogger::Debug:
+ break;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void Application::printHelp()
+{
+ char const * const txt = QT_TR_NOOP(
+ "Usage: eVafGUI [options]\n"
+ "\n"
+ // General options
+ " -help Shows this help and quits.\n"
+ " -help-qt Shows Qt command line options and quits.\n"
+ " -version Shows version information and quits.\n"
+ " -verbose=LEVEL Specifies the verbose level. LEVEL can be one of the\n"
+ " following: NONE, FATAL, ERROR, WARNING, INFO, DEBUG.\n"
+ " -v Makes the application more verbose. Can be repeated for\n"
+ " more verbosity.\n"
+ // Handled by the iApp interface implementation
+ " -appl[ication]=NAME Specifies the name of the application.\n"
+ " -lang[uage]=xx[_CC] Specifies the language, where xx is the ISO 639\n"
+ " language code followed by an optional ISO 3166 country\n"
+ " code.\n"
+ // Handled by the iEnv interface implementation
+ " -root[dir]=DIR Specifies the application's root directory.\n"
+ " -dataroot[dir]=DIR Specifies the data root directory.\n"
+ " -etc[dir]=DIR Specifies the configuration files directory.\n"
+ " -log[dir]=DIR Specifies the log files directory.\n"
+ " -doc[dir]=DIR Specifies the documentation directory.\n"
+ " -qtplugins[dir]=DIR Specifies the Qt plugins directory.\n"
+ );
+ ::fputs(tr(txt).toLocal8Bit().constData(), stdout);
+}
+
+void Application::printQtHelp()
+{
+ // Cannot translate this text as QT_TR_NOOP() is not able to process #ifdef parts.
+ char const * const txt =
+#ifdef QT_DEBUG
+ "Qt debugging options:\n"
+ " -nograb tells Qt that it must never grab the mouse or the keyboard.\n"
+#ifdef Q_OS_UNIX
+ " -dograb running under a debugger can cause an implicit -nograb,\n"
+ " use -dograb to override.\n"
+ " -sync switches to synchronous mode for debugging.\n\n"
+#endif
+#endif
+ "Qt common options:\n"
+ " -style=STYLE sets the application GUI style. Possible values are motif,\n"
+ " windows, and platinum.\n"
+ " -style STYLE is the same as listed above.\n"
+ " -stylesheet=STYLESHEET sets the application style sheet.\n"
+ " -stylesheet STYLESHEET is the same as listed above.\n"
+ " -session=SESSION restores the application from an earlier session.\n"
+ " -session SESSION is the same as listed above.\n"
+ " -widgetcount prints debug message at the end about number of widgets\n"
+ " left undestroyed and maximum number of widgets existed at\n"
+ " the same time.\n"
+ " -reverse sets the application's layout direction to Qt::RightToLeft\n\n"
+#ifdef Q_OS_WIN32
+ "Qt options on Windows:\n"
+ " -direct3d will make the Direct3D paint engine the default widget\n"
+ " paint engine in Qt.\n\n"
+#endif
+#ifdef Q_WS_X11
+ "Qt options on X11:\n"
+ " -display DISPLAY sets the X display.\n"
+ " -geometry GEOMETRY sets the client geometry of the first window that is\n"
+ " shown.\n"
+ " -fn or -font FONT defines the application font.\n"
+ " -bg or -background COLOR sets the default background color and an\n"
+ " application palette.\n"
+ " -fg or -foreground COLOR sets the default foreground color.\n"
+ " -btn or -button COLOR sets the default button color.\n"
+ " -name NAME sets the application name.\n"
+ " -title TITLE sets the application title.\n"
+ " -visual TrueColor forces the application to use a TrueColor visual on an\n"
+ " 8-bit display.\n"
+ " -ncols COUNT limits the number of colors allocated in the color cube on\n"
+ " an 8-bit display, if the application is using the\n"
+ " QApplication::ManyColor color specification. If COUNT is\n"
+ " 216 then a 6x6x6 color cube is used (i.e. 6 levels of red,\n"
+ " 6 of green, and 6 of blue); for other values, a cube\n"
+ " approximately proportional to a 2x3x1 cube is used.\n"
+ " -cmap causes the application to install a private color map on an\n"
+ " 8-bit display.\n"
+ " -im sets the input method server (equivalent to setting the\n"
+ " XMODIFIERS environment variable).\n"
+ " -noxim disables the input method framework (\"no X input method\").\n"
+ " -inputstyle defines how the input is inserted into the given widget.\n"
+ " E.g., onTheSpot makes the input appear directly in the\n"
+ " widget, while overTheSpot makes the input appear in a box\n"
+ " floating over the widget and is not inserted until the\n"
+ " editing is done.\n"
+#endif
+ ;
+ ::fputs(txt, stdout);
+}
+
+void Application::printVersion()
+{
+ ::printf("%s version %s release date %s, %s version %s\n",
+ VER_PRODUCT_NAME_STR,
+ VER_PRODUCT_VERSION_STR,
+ VER_PRODUCT_DATE_STR,
+ VER_MODULE_NAME_STR,
+ VER_FILE_VERSION_STR
+ );
+}
+
+
+//-------------------------------------------------------------------
+
+int main(int argc, char ** argv)
+{
+ Common::iLogger::instance()->setSeverity(Common::iLogger::Warning);
+
+ // Install our own message handlers
+ Common::iLogger::instance()->installFatalMsgHandler(Internal::fatalMsgHandler);
+ qInstallMsgHandler(Internal::messageOutput);
+
+ // Process command-line arguments
+ if (!Application::processCommandLine(argc, argv))
+ return 1;
+
+ // Set the console severity
+ Common::iLogger::instance()->setConsoleSeverity(Internal::ConsoleSeverityLevel);
+
+#ifdef Q_OS_WIN32
+ // Enable the extra message console on Windows
+ if (Internal::NeedsConsole)
+ Internal::enableWinConsole();
+#endif
+
+ EVAF_INFO("%s version %s release date %s, %s version %s",
+ VER_PRODUCT_NAME_STR,
+ VER_PRODUCT_VERSION_STR,
+ VER_PRODUCT_DATE_STR,
+ VER_MODULE_NAME_STR,
+ VER_FILE_VERSION_STR);
+
+#ifdef Q_OS_LINUX
+ EVAF_INFO("%s application pid = %d", VER_MODULE_NAME_STR, getpid());
+#endif
+
+ Application app(argc, argv);
+
+ // Install the exit handler
+ if (!Internal::installExitHandler())
+ return 1;
+
+ // Plugin manager
+ // Plugins::PluginManager pluginManager;
+
+ // The main run loop
+ bool quit = false;
+ int rval;
+ while (!quit) {
+
+ EVAF_INFO("%s is starting up", VER_MODULE_NAME_STR);
+
+ // Initialize the common library
+ if (!Common::init())
+ return 1;
+
+ // Initialize the plugin manager and load plugins
+ //if (!pluginManager.init())
+ // return 1;
+
+ // Run the application
+ rval = app.exec();
+
+ quit = rval != Common::iApp::RC_Restart;
+
+ EVAF_INFO("%s is %s", VER_MODULE_NAME_STR, quit ? "exiting" : "restarting");
+
+ // Unload plugins and finalize the plugin manager
+ // pluginManager.done();
+ }
+
+ EVAF_INFO("%s exit with code %d", VER_MODULE_NAME_STR, rval);
+
+ return rval;
+}
--- /dev/null
+/**
+ * @file main/GUI/main.h
+ * @brief The main eVaf GUI application class
+ * @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 __GUI_MAIN_H
+# define __GUI_MAIN_H
+
+#include <QApplication>
+
+
+namespace eVaf {
+
+/**
+ * The main eVaf GUI application.
+ *
+ * eVafGUI is the main GUI executable. It provides an empty GUI application
+ * that is used to load other eVaf modules.
+ */
+namespace GUI {
+
+/**
+ * Internal implementation of the main eVaf GUI application.
+ */
+namespace Internal {
+} // namespace eVaf::GUI::Internal
+
+/**
+ * The main eVaf GUI application class.
+ */
+class Application : public QApplication
+{
+ Q_OBJECT
+
+public:
+
+ Application(int & argc, char ** argv);
+
+ virtual ~Application();
+
+
+public: // Static methods
+
+ /**
+ * Processes command-line arguments
+ * @param argc Number of command-line arguments
+ * @param argv List of command-line arguments
+ * @return True if ok; false if the application should terminate
+ *
+ * This function processes command-line arguments and should be called before running
+ * the application.
+ */
+ static bool processCommandLine(int argc, char ** argv);
+
+ /**
+ * Prints out help for command-line arguments.
+ */
+ static void printHelp();
+
+ /**
+ * Prints out help for Qt command-line arguments.
+ */
+ static void printQtHelp();
+
+ /**
+ * Prints out version information.
+ */
+ static void printVersion();
+
+};
+
+} // namespace eVaf::GUI
+} // namespace eVaf
+
+#endif // main.h
--- /dev/null
+/**
+ * @file main/GUI/version.h
+ * @brief Version information for eVaf modules
+ * @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 __GUI_VERSION_H
+# define __GUI_VERSION_H
+
+#include <version_rc.h>
+
+/**
+ * Module/library version number in the form major,minor,release,build
+ */
+#define VER_FILE_VERSION 0,1,1,1
+
+/**
+ * Module/library version number in the string format (shall end with \0)
+ */
+#define VER_FILE_VERSION_STR "0.1.1.1\0"
+
+/**
+ * Module/library name (shall end with \0)
+ */
+#define VER_MODULE_NAME_STR "eVafGUI\0"
+
+/**
+ * Original file name for windows (shall end with \0)
+ */
+#define VER_ORIGINAL_FILE_NAME_STR "eVafGUI.exe\0"
+
+/**
+ * Description of the module/library (shall end with \0)
+ */
+#define VER_FILE_DESCRIPTION_STR "Main eVaf GUI executable.\0"
+
+#endif // version.h
--- /dev/null
+/**
+ * @file main/GUI/version.rc
+ * @brief Windows resource file with module/library version information.
+ * @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 "version.h"
+#include <version_rc.h>
+#include <winver.h>
+
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VER_FILE_VERSION
+ PRODUCTVERSION VER_PRODUCT_VERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+ BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0"
+ BEGIN
+ VALUE "CompanyName", VER_COMPANY_NAME_STR
+ VALUE "FileDescription", VER_FILE_DESCRIPTION_STR
+ VALUE "FileVersion", VER_FILE_VERSION_STR
+ VALUE "LegalCopyright", VER_LEGAL_COPYRIGHT_STR
+ VALUE "OriginalFilename", VER_ORIGINAL_FILENAME_STR
+ VALUE "ProductName", VER_PRODUC_TNAME_STR
+ VALUE "ProductVersion", VER_PRODUCT_VERSION_STR
+ VALUE "Build Date", VER_PRODUCT_DATE_STR
+ VALUE "Module Name", VER_MODULE_NAME_STR
+ END
+ END
+ END
--- /dev/null
+/**
+ * @file main/GUI/winconsole.cpp
+ * @brief Functions to redirect stdin, stdout and stderr to a separate console on Windows
+ * @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.
+ */
+
+#ifdef Q_OS_WIN32
+
+#include "winconsole.h"
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <windows.h>
+#include <stdio.h>
+
+using namespace eVaf::GUI::Internal;
+
+void enableWinConsole()
+{
+ AllocConsole();
+ freopen("conin$", "r", stdin);
+ freopen("conout$", "w", stdout);
+ freopen("conout$", "w", stderr);
+}
+
+#undef _CRT_SECURE_NO_WARNINGS
+
+#endif
--- /dev/null
+/**
+ * @file main/GUI/winconsole.h
+ * @brief Functions to redirect stdin, stdout and stderr to a separate console on Windows
+ * @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 __GUI_WINCONSOLE_H
+# define __GUI_WINCONSOLE_H
+
+namespace eVaf {
+namespace GUI {
+namespace Internal {
+
+#ifdef Q_OS_WIN32
+
+/**
+ * Enables the console window on Windows
+ */
+void enableWinConsole();
+
+#endif
+
+} // namespace eVaf::GUI::Internal
+} // namespace eVaf::GUI
+} // namespace eVaf
+
+#endif