Browse Source

Implementation of Alog and Message Handling

Added a new System for handling Debugging, Logging and User Notification, using a qMessageHandler  to intercept and redirect calls to qDebug, qInfo, qWarning and qCritical

These messages are then formatted and written (depending on their message type) to console and/or logfile and/or the user in the GUI. Added a logs folder to AStandardPaths, the logfiles are rotated (last 10 logs are kept).

There are a number of convenince makros available - these are mostly unchanged. The available makros are:
- DEB - Messages go to Console out. Normally, they would not go into the log file, but for early testing, logging debug to the logfile is also enabled
- LOG - Logging of important application milestones. These are logged to console and log file, but not displayed to the user.
- INFO - Written to console, log file and displayed to the user in the GUI. Use INFO if the information is important enough that the user should be made aware of this. If this is not required, use LOG.
- WARN - Same as INFO, but displays a Warning instead of an information to the user
- CRIT - Same as WARN, but with a critical Warning message.

Code is documented but some more detailed docs are in the works
Felix Turo 3 years ago
parent
commit
864c122e5d

+ 1 - 4
CMakeLists.txt

@@ -50,9 +50,9 @@ set(PROJECT_SOURCES
     src/gui/widgets/logbookwidget.cpp
     src/gui/widgets/pilotswidget.cpp
     src/gui/widgets/settingswidget.cpp
-    src/testing/abenchmark.cpp
     src/testing/atimer.cpp
     
+    src/opl.h
     mainwindow.h
     src/classes/acurrencyentry.h
     src/classes/astyle.h
@@ -85,9 +85,6 @@ set(PROJECT_SOURCES
     src/gui/widgets/logbookwidget.h
     src/gui/widgets/pilotswidget.h
     src/gui/widgets/settingswidget.h
-    src/oplconstants.h
-    src/testing/abenchmark.h
-    src/testing/adebug.h
     src/testing/atimer.h
     
     mainwindow.ui

+ 4 - 1
main.cpp

@@ -16,6 +16,8 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "mainwindow.h"
+#include "src/opl.h"
+#include "src/functions/alog.h"
 #include "src/gui/dialogues/firstrundialog.h"
 #include "src/classes/arunguard.h"
 #include "src/database/adatabase.h"
@@ -23,7 +25,6 @@
 #include "src/classes/astandardpaths.h"
 #include "src/classes/asettings.h"
 #include "src/classes/astyle.h"
-#include "src/oplconstants.h"
 #include "src/functions/alog.h"
 #include <QApplication>
 #include <QProcess>
@@ -48,6 +49,8 @@ int main(int argc, char *argv[])
         return 1;
     }
 
+    ALog::init(true); // Initialise logging and message handling
+
     ASettings::setup();
 
     AStyle::setup();

+ 3 - 5
openPilotLog.pro

@@ -34,6 +34,7 @@ SOURCES += \
     src/database/adatabase.cpp \
     src/database/adatabasesetup.cpp \
     src/functions/acalc.cpp \
+    src/functions/alog.cpp \
     src/functions/areadcsv.cpp \
     src/functions/astat.cpp \
     src/gui/dialogues/firstrundialog.cpp \
@@ -47,11 +48,11 @@ SOURCES += \
     src/gui/widgets/logbookwidget.cpp \
     src/gui/widgets/pilotswidget.cpp \
     src/gui/widgets/settingswidget.cpp \
-    src/testing/abenchmark.cpp \
     src/testing/atimer.cpp
 
 HEADERS += \
     mainwindow.h \
+    src/opl.h \
     src/classes/acurrencyentry.h \
     src/classes/astyle.h \
     src/classes/astandardpaths.h \
@@ -83,10 +84,7 @@ HEADERS += \
     src/gui/widgets/logbookwidget.h \
     src/gui/widgets/pilotswidget.h \
     src/gui/widgets/settingswidget.h \
-    src/oplconstants.h \
-    src/testing/abenchmark.h \
-    src/testing/adebug.h \
-    src/testing/atimer.h
+    src/testing/atimer.h \
 
 FORMS += \
     mainwindow.ui \

+ 1 - 1
src/classes/aaircraftentry.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "aaircraftentry.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 
 AAircraftEntry::AAircraftEntry()
     : AEntry::AEntry(Opl::Db::DEFAULT_AIRCRAFT_POSITION)

+ 1 - 1
src/classes/acurrencyentry.cpp

@@ -1,5 +1,5 @@
 #include "acurrencyentry.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 
 //ACurrencyEntry::ACurrencyEntry()
 //{

+ 1 - 0
src/classes/adownload.cpp

@@ -16,6 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "adownload.h"
+#include "src/opl.h"
 #include "src/functions/alog.h"
 
 

+ 1 - 1
src/classes/aflightentry.cpp

@@ -17,7 +17,7 @@
  */
 #include "aflightentry.h"
 #include "src/database/adatabase.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 #include "src/functions/atime.h"
 #include "src/classes/asettings.h"
 

+ 1 - 1
src/classes/apilotentry.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "apilotentry.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 
 APilotEntry::APilotEntry()
     : AEntry::AEntry(Opl::Db::DEFAULT_PILOT_POSITION)

+ 5 - 2
src/classes/astandardpaths.cpp

@@ -16,6 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "src/classes/astandardpaths.h"
+#include "src/opl.h"
 
 QMap<AStandardPaths::Directories, QDir> AStandardPaths::directories;
 
@@ -27,7 +28,9 @@ bool AStandardPaths::setup()
         {Templates, QDir(QStandardPaths::writableLocation(data_location)
          + QLatin1String("/templates"))},
         {Backup, QDir(QStandardPaths::writableLocation(data_location)
-         + QLatin1String("/backup"))}
+         + QLatin1String("/backup"))},
+        {Log, QDir(QStandardPaths::writableLocation(data_location)
+         + QLatin1String("/log"))}
     };
     if (scan_directories())
         return true;
@@ -52,7 +55,7 @@ const QMap<AStandardPaths::Directories, QDir>& AStandardPaths::allDirectories()
 
 bool AStandardPaths::scan_directories()
 {
-    for(const auto& dir : directories){
+    for(const auto& dir : qAsConst(directories)){
         if(!dir.exists()) {
             DEB << dir << "Does not exist. Creating:" << dir.absolutePath();
             if (!dir.mkpath(dir.absolutePath()))

+ 2 - 2
src/classes/astandardpaths.h

@@ -18,7 +18,6 @@
 #ifndef ASTANDARDPATHS_H
 #define ASTANDARDPATHS_H
 
-#include "src/functions/alog.h"
 #include <QStandardPaths>
 #include <QString>
 #include <QMap>
@@ -33,7 +32,8 @@ public:
     enum Directories {
         Database,
         Templates,
-        Backup
+        Backup,
+        Log
     };
 private:
     static QMap<Directories, QDir> directories;

+ 1 - 1
src/classes/astyle.cpp

@@ -21,11 +21,11 @@
  * https://github.com/Alexhuszagh/BreezeStyleSheets
  */
 #include "astyle.h"
+#include "src/opl.h"
 #include <QStyle>
 #include <QStyleFactory>
 #include <QApplication>
 #include <QFont>
-#include "src/functions/alog.h"
 #include "src/classes/asettings.h"
 #include "src/functions/alog.h"
 

+ 1 - 1
src/classes/atailentry.cpp

@@ -16,7 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "atailentry.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 
 ATailEntry::ATailEntry()
     : AEntry::AEntry(Opl::Db::DEFAULT_TAIL_POSITION)

+ 9 - 9
src/database/adatabase.cpp

@@ -18,7 +18,7 @@
 #include "adatabase.h"
 #include "src/functions/alog.h"
 #include "src/classes/astandardpaths.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 #include "src/functions/alog.h"
 
 
@@ -661,7 +661,7 @@ QMap<ADatabaseSummaryKey, QString> ADatabase::databaseSummary(const QString &db_
     const QString connection_name = QStringLiteral("summary_connection");
     QMap<ADatabaseSummaryKey, QString> return_values;
     { // scope for a temporary database connection, ensures proper cleanup when removeDatabase() is called.
-        DEB << "Adding temporary connection to database:" << db_path;
+        //DEB << "Adding temporary connection to database:" << db_path;
         QSqlDatabase temp_database = QSqlDatabase::addDatabase(SQLITE_DRIVER, connection_name); // Don't use default connection
         temp_database.setDatabaseName(db_path);
         if (!temp_database.open())
@@ -723,7 +723,7 @@ QMap<ADatabaseSummaryKey, QString> ADatabase::databaseSummary(const QString &db_
  */
 bool ADatabase::createBackup(const QString& dest_file)
 {
-    INFO << "Backing up current database to: " << dest_file;
+    LOG << "Backing up current database to: " << dest_file;
     ADatabase::disconnect();
     QFile db_file(databaseFile.absoluteFilePath());
     DEB << "File to Overwrite:" << db_file;  // [G]: Check adebug.h got INFO WARN, ... additions and discuss convention of use.
@@ -734,11 +734,11 @@ bool ADatabase::createBackup(const QString& dest_file)
 //    }
 
     if (!db_file.copy(dest_file)) {
-        WARN << "Unable to backup old database:" << db_file.errorString();
+        LOG << "Unable to backup old database:" << db_file.errorString();
         return false;
     }
 
-    INFO << "Backed up old database as:" << dest_file;
+    LOG << "Backed up old database as:" << dest_file;
     ADatabase::connect();
     emit connectionReset();
     return true;
@@ -751,7 +751,7 @@ bool ADatabase::createBackup(const QString& dest_file)
  */
 bool ADatabase::restoreBackup(const QString& backup_file)
 {
-    INFO << "Restoring backup from file:" << backup_file;
+    LOG << "Restoring backup from file:" << backup_file;
 
     QString default_loc = databaseFile.absoluteFilePath();
 
@@ -760,13 +760,13 @@ bool ADatabase::restoreBackup(const QString& backup_file)
     QFile current_db(default_loc);
 
     if (!current_db.rename(default_loc + QLatin1String(".tmp"))) { // move previously used db out of the way
-        WARN << current_db.errorString() << "Unable to remove current db file";
+        LOG << current_db.errorString() << "Unable to remove current db file";
         return false;
     }
 
     if (!backup.copy(default_loc))
     {
-        WARN << backup.errorString() << "Could not copy" << backup << "to" << databaseFile;
+        LOG << backup.errorString() << "Could not copy" << backup << "to" << databaseFile;
         // try to restore previously used db
         current_db.rename(default_loc);
         return false;
@@ -774,7 +774,7 @@ bool ADatabase::restoreBackup(const QString& backup_file)
 
     // backup has been restored, clean up the previously moved file
     current_db.remove();
-    INFO << "Backup successfully restored!";
+    LOG << "Backup successfully restored!";
     ADatabase::connect();
     emit connectionReset();
     return true;

+ 1 - 1
src/database/adatabasesetup.cpp

@@ -21,7 +21,7 @@
 #include "src/functions/areadcsv.h"
 #include "src/classes/astandardpaths.h"
 #include "src/classes/adownload.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 #include "src/functions/adatetime.h"
 #include "src/functions/alog.h"
 

+ 1 - 1
src/functions/acalc.cpp

@@ -19,7 +19,7 @@
 #include "src/functions/alog.h"
 #include "src/database/adatabase.h"
 #include "src/classes/asettings.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 
 using namespace ACalc;
 

+ 1 - 1
src/functions/adatetime.h

@@ -18,7 +18,7 @@
 #ifndef ADATETIME_H
 #define ADATETIME_H
 #include <QtCore>
-#include "src/oplconstants.h"
+#include "src/opl.h"
 
 namespace ADateTime {
 

+ 20 - 23
src/functions/alog.cpp

@@ -1,13 +1,16 @@
 #include "alog.h"
+#include <QMessageBox>
 
 namespace ALog {
 
+static bool logDebug = false;
+
 /*!
  * \brief setLogFileName sets a log file name ("Log_<Date>_<Time>.txt")
  */
 void setLogFileName()
 {
-    logFileName = QString(logFolderName + QLatin1String("/Log_%1_%2.txt")
+    logFileName = QString(logFolder.absolutePath() + QLatin1String("/Log_%1_%2.txt")
                           ).arg(QDate::currentDate().toString(QStringLiteral("yyyy_MM_dd")),
                                 QTime::currentTime().toString(QStringLiteral("hh_mm_ss")));
 }
@@ -17,16 +20,10 @@ void setLogFileName()
  *
  */
 void deleteOldLogs()
-{
-    if(!QDir(logFolderName).exists()) {
-        QDir().mkdir(logFolderName);
-    }
+{  
+    logFolder.setSorting(QDir::Time | QDir::Reversed);
 
-    QDir dir;
-    dir.setSorting(QDir::Time | QDir::Reversed);
-    dir.setPath(logFolderName);
-
-    QFileInfoList logs_list = dir.entryInfoList();
+    QFileInfoList logs_list = logFolder.entryInfoList();
     if (logs_list.size() <= numberOfLogs) {
         return;
     } else {
@@ -39,15 +36,13 @@ void deleteOldLogs()
 }
 
 /*!
- * \brief initialise logging, clean up logfiles and install a QMessageHandler
+ * \brief initialise logging, clean up logfiles and install a QMessageHandler. To enable
+ * logging of debug messages, pass parameter as true.
  */
-bool init()
+bool init(bool log_debug)
 {
-    // Create folder for logfiles if it doesn't exist, move to AStandardPaths later
-    if(!QDir(logFolderName).exists()) {
-        QDir().mkdir(logFolderName);
-    }
-
+    logDebug = log_debug;
+    logFolder = AStandardPaths::directory(AStandardPaths::Log);
     deleteOldLogs();
     setLogFileName();
 
@@ -90,25 +85,27 @@ void aMessageHandler(QtMsgType type, const QMessageLogContext &context,
 
     switch (type) {
         case QtDebugMsg:
-            QTextStream(stdout) << "\t\033\[31m" << function << DEB_HEADER << msg << "\033[m" << endl;
+            QTextStream(stdout) << DEB_HEADER_CONSOLE << msg << "\n\t" << function << "\033[m" << endl;
+            if(logDebug)
+                log_stream << timeNow() << DEB_HEADER << msg << "\t\t" << function << endl;
             break;
         case QtInfoMsg:
-            log_stream << QTime::currentTime().toString(Qt::ISODate) << INFO_HEADER << msg << function << endl;
-            QTextStream(stdout) << INFO_HEADER_CONSOLE << msg  << endl;
+            log_stream << timeNow() << INFO_HEADER << msg.chopped(2) << "\t\t" << function << endl;
+            QTextStream(stdout) << INFO_HEADER_CONSOLE << msg;
             break;
         case QtWarningMsg:
-            log_stream << QTime::currentTime().toString(Qt::ISODate) << WARN_HEADER << msg << function << endl;
+            log_stream << timeNow() << WARN_HEADER << msg.chopped(2) << "\t\t" << endl;
             QTextStream(stdout) << WARN_HEADER_CONSOLE << msg << endl;
             break;
         case QtCriticalMsg:
-            log_stream << QTime::currentTime().toString(Qt::ISODate) << CRIT_HEADER << msg << function << endl;
+            log_stream << timeNow() << CRIT_HEADER << msg.chopped(2) << "\t\t" << endl;
             QTextStream(stdout) << CRIT_HEADER_CONSOLE << msg << endl;
             break;
     default:
             log_stream << QTime::currentTime().toString(Qt::ISODate) << INFO_HEADER << msg << function << endl;
             QTextStream(stdout) << INFO_HEADER_CONSOLE << msg << endl;
             break;
-        }
+    }
 }
 
 } // namespace ALog

+ 16 - 18
src/functions/alog.h

@@ -9,21 +9,7 @@
 #include <QFileInfoList>
 #include <iostream>
 #include <QDebug>
-
-#if defined(__GNUC__) || defined(__clang__)
-    #define FUNC_IDENT __PRETTY_FUNCTION__
-#elif defined(_MSC_VER)
-    #define FUNC_IDENT __FUNCSIG__
-#else
-    #define FUNC_IDENT __func__
-#endif
-
-#define DEB qDebug() << FUNC_IDENT << "\n\t"    // Use for debugging
-#define LOG qInfo()                             // Use for logging milestones (silently, will be written to log file and console out only)
-#define INFO qInfo()                            // Use for messages of interest to the user (will be displayed in GUI)
-#define WARN qWarning()                         // Use for warnings (will be displayed in GUI)
-#define CRIT qCritical()                        // Use for critical warnings (will be displayed in GUI)
-#define TODO qCritical() << "!\n\tTo Do:\t"
+#include "src/classes/astandardpaths.h"
 
 /*!
  * \brief The ALog namespace encapsulates constants and functions used to provide logging to files
@@ -46,23 +32,35 @@
  */
 namespace ALog
 {
-    static QString logFolderName = "logs"; // To Do: AStandardpaths
+    static QDir logFolder;
     static QString logFileName;
     const static int numberOfLogs = 10; // max number of log files to keep
     const static int sizeOfLogs = 1024 * 100; // max log size in bytes, = 100kB
 
-    const static auto DEB_HEADER  = QLatin1String("\n[OPL - Deb ]: ");
+    const static auto DEB_HEADER  = QLatin1String(" [OPL - Deb ]: ");
     const static auto INFO_HEADER = QLatin1String(" [OPL - INFO]: ");
     const static auto WARN_HEADER = QLatin1String(" [OPL - WARN]: ");
     const static auto CRIT_HEADER = QLatin1String(" [OPL - CRIT]: ");
+    const static auto DEB_HEADER_CONSOLE  = QLatin1String("\u001b[38;5;69m[OPL - Deb ]: ");
     const static auto INFO_HEADER_CONSOLE = QLatin1String("\033[32m[OPL - INFO]: \033[m");
     const static auto WARN_HEADER_CONSOLE = QLatin1String("\033[33m[OPL - WARN]: \033[m");
     const static auto CRIT_HEADER_CONSOLE = QLatin1String("\033[35m[OPL - CRIT]: \033[m");
 
-    bool init();
+    bool init(bool log_debug = false);
     void setLogFileName();
     void deleteOldLogs();
     void aMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString& msg);
+    inline static const QString timeNow(){return QTime::currentTime().toString(Qt::ISODate);}
+
+    /*!
+     * \brief info - Informs the user of an important program milestone
+     * \param msg - the message to be displayed. Shall be a translatable string (tr)
+     * \abstract This function is used to inform the user about an important step the
+     * program has (successfully) completed. This is achieved by displaying a QMessageBox.
+     *
+     * This function also creates a qInfo message, which will be written to the logfile and
+     * to stdout
+     */
 } // namespace ALog
 
 /*!

+ 1 - 1
src/functions/atime.h

@@ -20,7 +20,7 @@
 
 #include <QtCore>
 #include <QTime>
-#include "src/oplconstants.h"
+#include "src/opl.h"
 #include "src/functions/alog.h"
 
 namespace ATime {

+ 1 - 1
src/gui/dialogues/firstrundialog.cpp

@@ -23,7 +23,7 @@
 #include "src/classes/apilotentry.h"
 #include "src/classes/adownload.h"
 #include "src/classes/asettings.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 #include <QErrorMessage>
 #include "src/classes/astyle.h"
 

+ 1 - 1
src/gui/dialogues/newflightdialog.cpp

@@ -22,7 +22,7 @@
 #include "src/functions/acalc.h"
 #include "src/testing/atimer.h"
 #include "src/database/adatabase.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 
 #include "src/functions/alog.h"
 

+ 1 - 0
src/gui/dialogues/newpilotdialog.cpp

@@ -17,6 +17,7 @@
  */
 #include "newpilotdialog.h"
 #include "ui_newpilot.h"
+#include "src/opl.h"
 
 #include "src/database/adatabase.h"
 #include "src/classes/aentry.h"

+ 1 - 1
src/gui/dialogues/newtaildialog.cpp

@@ -18,7 +18,7 @@
 #include "newtaildialog.h"
 #include "ui_newtail.h"
 #include "src/functions/alog.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 
 static const auto REG_VALID = QPair<QString, QRegularExpression> {
     QStringLiteral("registrationLineEdit"), QRegularExpression("\\w+-\\w+")};

+ 1 - 0
src/gui/widgets/aircraftwidget.cpp

@@ -17,6 +17,7 @@
  */
 #include "aircraftwidget.h"
 #include "ui_aircraftwidget.h"
+#include "src/opl.h"
 #include "src/gui/dialogues/newtaildialog.h"
 #include "src/classes/asettings.h"
 #include "src/database/adatabase.h"

+ 8 - 7
src/gui/widgets/backupwidget.cpp

@@ -1,5 +1,6 @@
 #include "backupwidget.h"
 #include "ui_backupwidget.h"
+#include "src/opl.h"
 #include "src/classes/astandardpaths.h"
 #include "src/functions/alog.h"
 #include "src/database/adatabase.h"
@@ -96,7 +97,7 @@ void BackupWidget::on_createLocalPushButton_clicked()
     DEB << filename;
 
     if(!aDB->createBackup(filename)) {
-        WARN << "Could not create local file:" << filename;
+        WARN(tr("Could not create local file: %1").arg(filename));
         return;
     }
 
@@ -116,7 +117,7 @@ void BackupWidget::on_createLocalPushButton_clicked()
 void BackupWidget::on_restoreLocalPushButton_clicked()
 {
     if(selectedFileInfo == nullptr) {
-        INFO << "No backup selected";
+        INFO(tr("No backup selected"));
         return;
     }
 
@@ -126,7 +127,7 @@ void BackupWidget::on_restoreLocalPushButton_clicked()
                 );
 
     if(!aDB->restoreBackup(backup_name)) {
-        WARN << "Couldnt restore" << backup_name;
+        WARN(tr("Couldnt restore Backup: %1").arg(backup_name));
     }
 }
 
@@ -134,7 +135,7 @@ void BackupWidget::on_deleteSelectedPushButton_clicked()
 {
     TODO << "Test external deletion";
     if(selectedFileInfo == nullptr) {
-        INFO << "No backup was selected";
+        INFO(tr("No backup was selected"));
         return;
     }
 
@@ -142,13 +143,13 @@ void BackupWidget::on_deleteSelectedPushButton_clicked()
     QFile file(filename.absoluteFilePath());
 
     if(!file.exists()) {
-        WARN << "Selected backup file doesnt exist:" << file;
+        WARN(tr("Selected backup file doesnt exist: %1").arg(filename.absolutePath()));
         return;
     }
 
     DEB << "deleting:" << filename;
     if(!file.remove()) {
-        WARN << "Unable to remove file:" << file.errorString();
+        WARN(tr("Unable to remove file %1\nError: %2").arg(filename.fileName(),file.errorString()));
         return;
     }
 
@@ -161,7 +162,7 @@ void BackupWidget::on_createExternalPushButton_clicked()
 {
     QString filename = QFileDialog::getSaveFileName(
                 this,
-                "Choose destination file",
+                tr("Choose destination file"),
                 // [G]: Is this necessary?
                 //QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).absoluteFilePath("untitled.db"),
                 QDir::homePath() + QDir::separator() + backupName(),

+ 2 - 4
src/gui/widgets/debugwidget.cpp

@@ -186,10 +186,8 @@ void DebugWidget::on_importCsvPushButton_clicked()
 
 void DebugWidget::on_debugPushButton_clicked()
 {
-
-    DEB << ASettings::read(ASettings::UserData::CurrWarningThreshold).toInt();
-    // debug space
-    //ASettings::write(ASettings::Setup::SetupComplete, false);
+    WARN("Whoops, a warning!");
+    CRIT("Yikes, this doesn't look good... ");
 }
 
 /* //Comparing two functions template

+ 0 - 1
src/gui/widgets/debugwidget.h

@@ -33,7 +33,6 @@
 #include "src/classes/aentry.h"
 #include "src/classes/apilotentry.h"
 
-#include "src/testing/abenchmark.h"
 #include "src/testing/atimer.h"
 #include "src/functions/alog.h"
 

+ 0 - 1
src/gui/widgets/homewidget.cpp

@@ -108,7 +108,6 @@ void HomeWidget::fillCurrency(ACurrencyEntry::CurrencyName currency_name, QLabel
 void HomeWidget::fillAllCurrencies()
 {
     fillCurrencyTakeOffLanding();
-    DEB << "Show med currency?" << ASettings::read(ASettings::UserData::ShowMedCurrency).toBool();
 
     ASettings::read(ASettings::UserData::ShowLicCurrency).toBool() ?
                 fillCurrency(ACurrencyEntry::CurrencyName::Licence, ui->currLicDisplayLabel)

+ 1 - 0
src/gui/widgets/pilotswidget.cpp

@@ -17,6 +17,7 @@
  */
 #include "pilotswidget.h"
 #include "ui_pilotswidget.h"
+#include "src/opl.h"
 #include "src/functions/alog.h"
 #include "src/database/adatabase.h"
 #include "src/classes/apilotentry.h"

+ 1 - 1
src/gui/widgets/settingswidget.cpp

@@ -22,7 +22,7 @@
 #include "src/classes/asettings.h"
 #include "src/database/adatabase.h"
 #include "src/classes/apilotentry.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 
 static const auto FIRSTNAME_VALID = QPair<QString, QRegularExpression> {
     QStringLiteral("firstnameLineEdit"), QRegularExpression("[a-zA-Z]+")};

+ 256 - 0
src/opl.h

@@ -0,0 +1,256 @@
+/*
+ *openPilotLog - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020-2021 Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#ifndef OPLCONSTANTS_H
+#define OPLCONSTANTS_H
+
+#include <QtCore>
+#include <QMessageBox>
+#include "src/database/adatabasetypes.h"
+
+/*!
+ *  \brief A namespace to collect constants and enums used throughout the application.
+ *
+ *  \details The opl namespace collects enums and constants that are used throughout
+ *  the application and provide uniform access.
+ *
+ *  The date, time and datetime namespaces include enums used to differentiate
+ *  date and time formats for QDate, QTime and QDateTime that deviate from standard values
+ *  included in the Qt Framework like Qt::ISODate and are to be used in conjunction with the
+ *  .toString() members of these classes.
+ *
+ *  The db namespace contains constants for programatically accessing the database in a fast
+ *  and uniform manner.
+ */
+namespace Opl {
+
+#if defined(__GNUC__) || defined(__clang__)
+    #define FUNC_IDENT __PRETTY_FUNCTION__
+#elif defined(_MSC_VER)
+    #define FUNC_IDENT __FUNCSIG__
+#else
+    #define FUNC_IDENT __func__
+#endif
+
+#define DEB qDebug()                            // Use for debugging
+#define LOG qInfo()                             // Use for logging milestones (silently, will be written to log file and console out only)
+#define TODO qCritical() << "!\n\tTo Do:\t"
+
+#define INFO(msg) Opl::ANotificationHandler::info(msg, this)  // Use for messages of interest to the user (will be displayed in GUI)
+#define WARN(msg) Opl::ANotificationHandler::warn(msg, this)  // Use for warnings (will be displayed in GUI)
+#define CRIT(msg) Opl::ANotificationHandler::crit(msg, this)  // Use for critical warnings (will be displayed in GUI)
+
+/*!
+ * \brief The ANotificationHandler class handles displaying of user-directed messages. It displays
+ * information to the user and forwards the displayed message to ALog so it is written
+ * to the console and log files. The INFO, WARN and CRIT makros provide convenient access.
+ */
+class ANotificationHandler {
+public:
+    static inline void info(const QString msg, QWidget *parent = nullptr){
+        qInfo() << msg;
+        QMessageBox mb(parent);
+        mb.setText(msg);
+        mb.setIcon(QMessageBox::Information);
+        mb.exec();
+    };
+    static inline void warn(const QString msg, QWidget *parent = nullptr){
+        qWarning() << msg;
+        QMessageBox mb(parent);
+        mb.setText(msg);
+        mb.setIcon(QMessageBox::Warning);
+        mb.exec();
+    };
+    static inline void crit(const QString msg, QWidget *parent = nullptr){
+        qCritical() << msg;
+        QMessageBox mb(parent);
+        mb.setText(msg);
+        mb.setIcon(QMessageBox::Critical);
+        mb.exec();
+    };
+}; // class ANotificationHandler
+
+static const auto ApproachTypes = QStringList{
+        QLatin1String("VISUAL"),
+        QLatin1String("ILS CAT I"),
+        QLatin1String("ILS CAT II"),
+        QLatin1String("ILS CAT III"),
+        QLatin1String("GLS"),
+        QLatin1String("MLS"),
+        QLatin1String("LOC"),
+        QLatin1String("LOC/DME"),
+        QLatin1String("RNAV"),
+        QLatin1String("RNAV (LNAV)"),
+        QLatin1String("RNAV (LNAV/VNAV)"),
+        QLatin1String("RNAV (LPV)"),
+        QLatin1String("RNAV (RNP)"),
+        QLatin1String("RNAV (RNP-AR)"),
+        QLatin1String("VOR"),
+        QLatin1String("VOR/DME"),
+        QLatin1String("NDB"),
+        QLatin1String("NDB/DME"),
+        QLatin1String("TACAN"),
+        QLatin1String("SRA"),
+        QLatin1String("PAR"),
+        QLatin1String("OTHER")
+};
+
+namespace Date {
+
+enum DateFormat {Default, Text};
+
+} // namespace opl::date
+
+namespace Time {
+
+enum FlightTimeFormat {Default, Decimal};
+
+} // namespace opl::time
+
+namespace Datetime {
+
+enum DateTimeFormat {Default, Backup};
+
+} // namespace opl::datetime
+
+/*!
+ *  The opl::db namespace provides string literals to programatically access the database
+ *
+ *  Example usage, do:
+ *  newData.insert(opl::db::FLIGHTS_DEP, ui->deptLocLineEdit->text());
+ *  newData.value(opl::db::AIRCRAFT_MULTIPILOT);
+ *
+ *  instead of:
+ *  newData.insert("dept", ui->deptLocLineEdit->text());
+ *  newData.value("multipilot");
+ *
+ *  Declaring these literals here avoids memory allocation at runtime for construction of temporary
+ *  qstrings like ("dept"). See https://doc.qt.io/qt-5/qstring.html#QStringLiteral and ensures
+ *  uniform use throughout the application.
+ */
+namespace Db {
+
+
+// Table names
+static const auto TABLE_FLIGHTS          = QLatin1String("flights");
+static const auto TABLE_PILOTS           = QLatin1String("pilots");
+static const auto TABLE_TAILS            = QLatin1String("tails");
+static const auto TABLE_AIRCRAFT         = QLatin1String("aircraft");
+static const auto TABLE_AIRPORTS         = QLatin1String("airports");
+static const auto TABLE_CURRENCIES       = QLatin1String("currencies");
+
+// Flights table columns
+static const auto FLIGHTS_DOFT           = QLatin1String("doft");
+static const auto FLIGHTS_DEPT           = QLatin1String("dept");
+static const auto FLIGHTS_DEST           = QLatin1String("dest");
+static const auto FLIGHTS_TOFB           = QLatin1String("tofb");
+static const auto FLIGHTS_TONB           = QLatin1String("tonb");
+static const auto FLIGHTS_PIC            = QLatin1String("pic");
+static const auto FLIGHTS_ACFT           = QLatin1String("acft");
+static const auto FLIGHTS_TBLK           = QLatin1String("tblk");
+static const auto FLIGHTS_TSPSE          = QLatin1String("tSPSE");
+static const auto FLIGHTS_TSPME          = QLatin1String("tSPME");
+static const auto FLIGHTS_TMP            = QLatin1String("tMP");
+static const auto FLIGHTS_TNIGHT         = QLatin1String("tNIGHT");
+static const auto FLIGHTS_TIFR           = QLatin1String("tIFR");
+static const auto FLIGHTS_TPIC           = QLatin1String("tPIC");
+static const auto FLIGHTS_TPICUS         = QLatin1String("tPICUS");
+static const auto FLIGHTS_TSIC           = QLatin1String("tSIC");
+static const auto FLIGHTS_TDUAL          = QLatin1String("tDUAL");
+static const auto FLIGHTS_TFI            = QLatin1String("tFI");
+static const auto FLIGHTS_TSIM           = QLatin1String("tSIM");
+static const auto FLIGHTS_PILOTFLYING    = QLatin1String("pilotFlying");
+static const auto FLIGHTS_TODAY          = QLatin1String("toDay");
+static const auto FLIGHTS_TONIGHT        = QLatin1String("toNight");
+static const auto FLIGHTS_LDGDAY         = QLatin1String("ldgDay");
+static const auto FLIGHTS_LDGNIGHT       = QLatin1String("ldgNight");
+static const auto FLIGHTS_AUTOLAND       = QLatin1String("autoland");
+static const auto FLIGHTS_SECONDPILOT    = QLatin1String("secondPilot");
+static const auto FLIGHTS_THIRDPILOT     = QLatin1String("thirdPilot");
+static const auto FLIGHTS_APPROACHTYPE   = QLatin1String("approachType");
+static const auto FLIGHTS_FLIGHTNUMBER   = QLatin1String("flightNumber");
+static const auto FLIGHTS_REMARKS        = QLatin1String("remarks");
+
+// tails table
+
+static const auto TAILS_REGISTRATION     = QLatin1String("registration");
+static const auto TAILS_COMPANY          = QLatin1String("company");
+static const auto TAILS_MAKE             = QLatin1String("make");
+static const auto TAILS_MODEL            = QLatin1String("model");
+static const auto TAILS_VARIANT          = QLatin1String("variant");
+static const auto TAILS_MULTIPILOT       = QLatin1String("multipilot");
+static const auto TAILS_MULTIENGINE      = QLatin1String("multiengine");
+static const auto TAILS_ENGINETYPE       = QLatin1String("engineType");
+static const auto TAILS_WEIGHTCLASS      = QLatin1String("weightClass");
+
+// pilots table
+
+static const auto PILOTS_LASTNAME        = QLatin1String("lastname");
+static const auto PILOTS_FIRSTNAME       = QLatin1String("firstname");
+static const auto PILOTS_ALIAS           = QLatin1String("alias");
+static const auto PILOTS_COMPANY         = QLatin1String("company");
+static const auto PILOTS_EMPLOYEEID      = QLatin1String("employeeid");
+static const auto PILOTS_PHONE           = QLatin1String("phone");
+static const auto PILOTS_EMAIL           = QLatin1String("email");
+
+// Currencies table
+static const auto CURRENCIES_EXPIRYDATE  = QLatin1String("expiryDate");
+
+// all tables
+static const auto ROWID                  = QLatin1String("ROWID");
+static const auto NULL_TIME_hhmm         = QLatin1String("00:00");
+
+static const auto DEFAULT_FLIGHT_POSITION   = DataPosition(TABLE_FLIGHTS, 0);
+static const auto DEFAULT_PILOT_POSITION    = DataPosition(TABLE_PILOTS, 0);
+static const auto DEFAULT_TAIL_POSITION     = DataPosition(TABLE_TAILS, 0);
+static const auto DEFAULT_AIRCRAFT_POSITION = DataPosition(TABLE_AIRCRAFT, 0);
+
+} // namespace opl::db
+
+namespace Assets {
+
+static const auto LOGO                          = QLatin1String(":/icons/opl-icons/logos/logo_text.png");
+static const auto ICON_MAIN                     = QLatin1String(":/icons/opl-icons/app/icon_main.png");
+static const auto ICON_APPICON_LINUX            = QLatin1String(":/icons/opl-icons/app/icon_linux.svg");
+static const auto ICON_APPICON_IOS              = QLatin1String(":/icons/opl-icons/app/icon_ios.svg");
+static const auto ICON_APPICON_WIN              = QLatin1String(":/icons/opl-icons/app/icon_windows.ico");
+
+static const auto ICON_TOOLBAR_HOME             = QLatin1String(":/icons/opl-icons/toolbar/thick/light/icon_home.svg");
+static const auto ICON_TOOLBAR_NEW_FLIGHT       = QLatin1String(":/icons/opl-icons/toolbar/thick/light/icon_new_flight.svg");
+static const auto ICON_TOOLBAR_LOGBOOK          = QLatin1String(":/icons/opl-icons/toolbar/thick/light/icon_logbook.svg");
+static const auto ICON_TOOLBAR_AIRCRAFT         = QLatin1String(":/icons/opl-icons/toolbar/thick/light/icon_airplane.svg");
+static const auto ICON_TOOLBAR_PILOT            = QLatin1String(":/icons/opl-icons/toolbar/thick/light/icon_pilot.svg");
+static const auto ICON_TOOLBAR_SETTINGS         = QLatin1String(":/icons/opl-icons/toolbar/thick/light/icon_settings.svg");
+static const auto ICON_TOOLBAR_QUIT             = QLatin1String(":/icons/opl-icons/toolbar/thick/light/icon_exit.svg");
+
+static const auto ICON_TOOLBAR_BACKUP           = QLatin1String(":/icons/opl-icons/toolbar/thick/light/icon_backup.svg");
+
+static const auto ICON_TOOLBAR_HOME_DARK        = QLatin1String(":/icons/opl-icons/toolbar/thick/dark/icon_home_dm.svg");
+static const auto ICON_TOOLBAR_NEW_FLIGHT_DARK  = QLatin1String(":/icons/opl-icons/toolbar/thick/dark/icon_new_flight_dm.svg");
+static const auto ICON_TOOLBAR_LOGBOOK_DARK     = QLatin1String(":/icons/opl-icons/toolbar/thick/dark/icon_logbook_dm.svg");
+static const auto ICON_TOOLBAR_AIRCRAFT_DARK    = QLatin1String(":/icons/opl-icons/toolbar/thick/dark/icon_airplane_dm.svg");
+static const auto ICON_TOOLBAR_PILOT_DARK       = QLatin1String(":/icons/opl-icons/toolbar/thick/dark/icon_pilot_dm.svg");
+static const auto ICON_TOOLBAR_SETTINGS_DARK    = QLatin1String(":/icons/opl-icons/toolbar/thick/dark/icon_settings_dm.svg");
+static const auto ICON_TOOLBAR_QUIT_DARK        = QLatin1String(":/icons/opl-icons/toolbar/thick/dark/icon_exit_dm.svg");
+
+static const auto ICON_TOOLBAR_BACKUP_DARK      = QLatin1String(":/icons/opl-icons/toolbar/thick/dark/icon_backup_dm.svg");
+
+}
+
+} // namespace opl
+
+#endif // OPLCONSTANTS_H

+ 15 - 0
src/oplconstants.h

@@ -37,6 +37,21 @@
  */
 namespace Opl {
 
+#if defined(__GNUC__) || defined(__clang__)
+    #define FUNC_IDENT __PRETTY_FUNCTION__
+#elif defined(_MSC_VER)
+    #define FUNC_IDENT __FUNCSIG__
+#else
+    #define FUNC_IDENT __func__
+#endif
+
+#define DEB qDebug() << FUNC_IDENT << "\n\t"    // Use for debugging
+#define LOG qInfo()                             // Use for logging milestones (silently, will be written to log file and console out only)
+#define INFO qInfo()                            // Use for messages of interest to the user (will be displayed in GUI)
+#define WARN qWarning()                         // Use for warnings (will be displayed in GUI)
+#define CRIT qCritical()                        // Use for critical warnings (will be displayed in GUI)
+#define TODO qCritical() << "!\n\tTo Do:\t"
+
 static const auto ApproachTypes = QStringList{
         QLatin1String("VISUAL"),
         QLatin1String("ILS CAT I"),

+ 0 - 74
src/testing/abenchmark.cpp

@@ -1,74 +0,0 @@
-/*
- *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
- *
- *This program is free software: you can redistribute it and/or modify
- *it under the terms of the GNU General Public License as published by
- *the Free Software Foundation, either version 3 of the License, or
- *(at your option) any later version.
- *
- *This program is distributed in the hope that it will be useful,
- *but WITHOUT ANY WARRANTY; without even the implied warranty of
- *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *GNU General Public License for more details.
- *
- *You should have received a copy of the GNU General Public License
- *along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-#include "abenchmark.h"
-#include <chrono>
-
-ABenchmark::ABenchmark()
-{
-
-}
-
-ABenchmark::ABenchmark(void (*function_one)(), void (*function_two)(), int number_of_runs)
-{
-        auto start1 = std::chrono::high_resolution_clock::now();
-        for (int i = 0; i < number_of_runs; i++) {
-            function_one();
-        }
-        auto stop1 = std::chrono::high_resolution_clock::now();
-        DEB << "First Function execution finished (" << number_of_runs << " runs)";
-
-
-        auto start2 = std::chrono::high_resolution_clock::now();
-        for (int i = 0; i < number_of_runs; i++) {
-            function_two();
-        }
-        auto stop2 = std::chrono::high_resolution_clock::now();
-        DEB << "Second Function execution finished (" << number_of_runs << " runs)";
-
-        DEB << "Execution time for function 1: "
-            << std::chrono::duration_cast<std::chrono::milliseconds>(stop1 - start1).count()
-            << "milliseconds.";
-        DEB << "Execution time for function 2: "
-            << std::chrono::duration_cast<std::chrono::milliseconds>(stop2 - start2).count()
-            << "milliseconds.";
-}
-
-ABenchmark::ABenchmark(bool (*function_one)(), bool (*function_two)(), int number_of_runs)
-{
-    auto start1 = std::chrono::high_resolution_clock::now();
-    for (int i = 0; i < number_of_runs; i++) {
-        function_one();
-    }
-    auto stop1 = std::chrono::high_resolution_clock::now();
-    DEB << "First Function execution finished (" << number_of_runs << " runs)";
-
-
-    auto start2 = std::chrono::high_resolution_clock::now();
-    for (int i = 0; i < number_of_runs; i++) {
-        function_two();
-    }
-    auto stop2 = std::chrono::high_resolution_clock::now();
-    DEB << "Second Function execution finished (" << number_of_runs << " runs)";
-
-    DEB << "Execution time for function 1: "
-        << std::chrono::duration_cast<std::chrono::milliseconds>(stop1 - start1).count()
-        << "milliseconds.";
-    DEB << "Execution time for function 2: "
-        << std::chrono::duration_cast<std::chrono::milliseconds>(stop2 - start2).count()
-        << "milliseconds.";
-}

+ 0 - 40
src/testing/abenchmark.h

@@ -1,40 +0,0 @@
-/*
- *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
- *
- *This program is free software: you can redistribute it and/or modify
- *it under the terms of the GNU General Public License as published by
- *the Free Software Foundation, either version 3 of the License, or
- *(at your option) any later version.
- *
- *This program is distributed in the hope that it will be useful,
- *but WITHOUT ANY WARRANTY; without even the implied warranty of
- *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *GNU General Public License for more details.
- *
- *You should have received a copy of the GNU General Public License
- *along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-#ifndef ABENCHMARK_H
-#define ABENCHMARK_H
-
-#include <QObject>
-#include "src/functions/alog.h"
-
-/*!
- * \brief The ABenchmark class provides quick access to benchmarking two functions for
- * the purpose of performance testing.
- *
- */
-class ABenchmark
-{
-public:
-    ABenchmark();
-
-    ABenchmark(void (*function_one)(), void (*function_two)(), int number_of_runs);
-
-    ABenchmark(bool (*function_one)(), bool (*function_two)(), int number_of_runs);
-
-};
-
-#endif // ABENCHMARK_H

+ 1 - 0
src/testing/atimer.cpp

@@ -16,6 +16,7 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "atimer.h"
+#include "src/opl.h"
 
 
 ATimer::ATimer(QObject *parent) : QObject(parent)