瀏覽代碼

Merge pull request #75 from fiffty-50/develop-logging-debugging

Develop logging debugging
Felix Turowsky 3 年之前
父節點
當前提交
31cbe20b36
共有 43 個文件被更改,包括 739 次插入371 次删除
  1. 2 4
      CMakeLists.txt
  2. 42 32
      main.cpp
  3. 11 1
      mainwindow.cpp
  4. 3 5
      openPilotLog.pro
  5. 1 1
      src/classes/aaircraftentry.cpp
  6. 1 1
      src/classes/acurrencyentry.cpp
  7. 2 1
      src/classes/adownload.cpp
  8. 1 1
      src/classes/aflightentry.cpp
  9. 1 1
      src/classes/apilotentry.cpp
  10. 5 2
      src/classes/astandardpaths.cpp
  11. 2 2
      src/classes/astandardpaths.h
  12. 5 5
      src/classes/astyle.cpp
  13. 1 1
      src/classes/atailentry.cpp
  14. 12 12
      src/database/adatabase.cpp
  15. 4 4
      src/database/adatabasesetup.cpp
  16. 1 1
      src/database/adatabasetypes.h
  17. 2 2
      src/functions/acalc.cpp
  18. 1 1
      src/functions/acalc.h
  19. 1 1
      src/functions/adatetime.h
  20. 126 0
      src/functions/alog.cpp
  21. 87 7
      src/functions/alog.h
  22. 1 1
      src/functions/astat.cpp
  23. 2 2
      src/functions/atime.h
  24. 2 2
      src/gui/dialogues/firstrundialog.cpp
  25. 2 2
      src/gui/dialogues/newflightdialog.cpp
  26. 2 1
      src/gui/dialogues/newpilotdialog.cpp
  27. 2 2
      src/gui/dialogues/newtaildialog.cpp
  28. 2 1
      src/gui/widgets/aircraftwidget.cpp
  29. 62 36
      src/gui/widgets/backupwidget.cpp
  30. 65 107
      src/gui/widgets/backupwidget.ui
  31. 2 4
      src/gui/widgets/debugwidget.cpp
  32. 1 2
      src/gui/widgets/debugwidget.h
  33. 1 2
      src/gui/widgets/homewidget.cpp
  34. 5 5
      src/gui/widgets/logbookwidget.cpp
  35. 2 1
      src/gui/widgets/pilotswidget.cpp
  36. 2 2
      src/gui/widgets/settingswidget.cpp
  37. 256 0
      src/opl.h
  38. 15 0
      src/oplconstants.h
  39. 0 74
      src/testing/abenchmark.cpp
  40. 0 40
      src/testing/abenchmark.h
  41. 2 1
      src/testing/adebug.h
  42. 1 0
      src/testing/atimer.cpp
  43. 1 1
      src/testing/atimer.h

+ 2 - 4
CMakeLists.txt

@@ -36,6 +36,7 @@ set(PROJECT_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
@@ -49,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
@@ -84,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

+ 42 - 32
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>
@@ -36,51 +37,60 @@
 #define ORGNAME QStringLiteral("opl")
 #define ORGDOMAIN QStringLiteral("https://github.com/fiffty-50/openpilotlog")
 
-int main(int argc, char *argv[])
-{
-    QApplication openPilotLog(argc, argv);
-    QCoreApplication::setOrganizationName(ORGNAME);
-    QCoreApplication::setOrganizationDomain(ORGDOMAIN);
-    QCoreApplication::setApplicationName(APPNAME);
 
-    if(!AStandardPaths::setup()){
-        LOG << "Unable to create directories.\n";
-        return 1;
+void init()
+{
+    LOG << "Setting up / verifying Application Directories...";
+    if(AStandardPaths::setup()) {
+        LOG << "Application Directories... verified";
+    } else {
+        LOG << "Unable to create directories.";
     }
-
+    LOG << "Setting up logging facilities...";
+    if(ALog::init(true)) {
+        LOG << "Logging enabled.";
+    } else {
+        LOG << "Unable to initalise logging.";
+    }
+    LOG << "Reading Settings...";
     ASettings::setup();
-
+    LOG << "Setting up application style...";
     AStyle::setup();
+}
 
-    if (ASettings::read(ASettings::Main::SetupComplete).toBool()) {
-        QFileInfo database_file(AStandardPaths::directory(AStandardPaths::Database).
-                                     absoluteFilePath(QStringLiteral("logbook.db")));
-        if (!database_file.exists()) {
-            LOG << "Error: Database file not found\n";
-            return 2;
-        }
-    } else {
-        if(FirstRunDialog().exec() == QDialog::Rejected){
-            LOG << "Initial setup incomplete or unsuccessfull. Exiting.\n";
-            return 3;
-        }
-        ASettings::write(ASettings::Main::SetupComplete, true);
-        DEB << "Wrote setup_commplete";
+void firstRun()
+{
+    if(FirstRunDialog().exec() == QDialog::Rejected){
+        LOG << "Initial setup incomplete or unsuccessfull.";
+        return;
     }
+    ASettings::write(ASettings::Main::SetupComplete, true);
+    LOG << "Initial Setup Completed successfully";
+}
 
-    if (!aDB->connect()) {
-        LOG << "Error establishing database connection\n";
-        return 4;
-    }
+int main(int argc, char *argv[])
+{
+    QApplication openPilotLog(argc, argv);
+    QCoreApplication::setOrganizationName(ORGNAME);
+    QCoreApplication::setOrganizationDomain(ORGDOMAIN);
+    QCoreApplication::setApplicationName(APPNAME);
 
+    // Check for another instance already running
     ARunGuard guard(QStringLiteral("opl_single_key"));
     if ( !guard.tryToRun() ){
-        LOG << "Another Instance of openPilotLog is already running. Exiting.\n";
+        LOG << "Another Instance of openPilotLog is already running. Exiting.";
         return 0;
     }
 
-    MainWindow w;
+    // Set Up the Application
+    init();
+
+    // Check for First Run and launch Setup Wizard
+    if (!ASettings::read(ASettings::Main::SetupComplete).toBool())
+        firstRun();
 
+    // Create Main Window and set Window Icon acc. to Platform
+    MainWindow w;
 #ifdef __linux__
     w.setWindowIcon(QIcon(Opl::Assets::ICON_APPICON_LINUX));
 #elif defined(_WIN32) || defined(_WIN64)

+ 11 - 1
mainwindow.cpp

@@ -17,7 +17,7 @@
  */
 #include "mainwindow.h"
 #include "ui_mainwindow.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 #include "src/database/adatabase.h"
 #include "src/classes/astyle.h"
 
@@ -26,6 +26,16 @@ MainWindow::MainWindow(QWidget *parent)
     , ui(new Ui::MainWindow)
 {
     ui->setupUi(this);
+    // connect to the Database
+    TODO << "Create more verbose warning about DB and offer instructions how to fix it.";
+    QFileInfo database_file(AStandardPaths::directory(AStandardPaths::Database).
+                                         absoluteFilePath(QStringLiteral("logbook.db")));
+            if (!database_file.exists()) {
+                WARN(tr("Error: Database file not found."));
+            }
+    if(!aDB->connect()){
+        WARN(tr("Error establishing database connection."));
+    }
 
     // Create a spacer for the toolbar to separate left and right parts
     auto *spacer = new QWidget();

+ 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()
 //{

+ 2 - 1
src/classes/adownload.cpp

@@ -16,7 +16,8 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "adownload.h"
-#include "src/testing/adebug.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/testing/adebug.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;

+ 5 - 5
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/testing/adebug.h"
 #include "src/classes/asettings.h"
 #include "src/functions/alog.h"
 
@@ -51,7 +51,7 @@ void AStyle::setup()
         QFont font(ASettings::read(ASettings::Main::Font).toString());
         font.setPointSize(ASettings::read(ASettings::Main::FontSize).toUInt());
         qApp->setFont(font);
-        LOG << "Application Font set:\t" << font.toString().splitRef(',').first() << "\n";
+        LOG << "Application Font set: " << font.toString().splitRef(',').first();
     }
     // Set style, stylesheet or palette
     QString style_setting = ASettings::read(ASettings::Main::Style).toString();
@@ -88,7 +88,7 @@ void AStyle::resetStyle()
 void AStyle::setStyle(const QString &style_key)
 {
     resetStyle();
-    LOG << "Setting style:\t" << style_key << "\n";
+    LOG << "Setting style: " << style_key;
     QApplication::setStyle(QStyleFactory::create(style_key));
     currentStyle = style_key;
 }
@@ -96,7 +96,7 @@ void AStyle::setStyle(const QString &style_key)
 void AStyle::setStyle(const StyleSheet &style_sheet)
 {
     resetStyle();
-    LOG << "Setting stylesheet:\t" << style_sheet.styleSheetName << "\n";
+    LOG << "Setting stylesheet: " << style_sheet.styleSheetName;
     qApp->setStyleSheet(read_stylesheet(style_sheet.fileName));
     currentStyle = style_sheet.styleSheetName;
 }
@@ -104,7 +104,7 @@ void AStyle::setStyle(const StyleSheet &style_sheet)
 void AStyle::setStyle(const QPalette &palette)
 {
     resetStyle();
-    LOG << "Setting Colour Palette...\n";
+    LOG << "Setting Colour Palette...";
     qApp->setPalette(palette);
 }
 

+ 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)

+ 12 - 12
src/database/adatabase.cpp

@@ -16,9 +16,9 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "adatabase.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 #include "src/classes/astandardpaths.h"
-#include "src/oplconstants.h"
+#include "src/opl.h"
 #include "src/functions/alog.h"
 
 
@@ -111,7 +111,7 @@ bool ADatabase::connect()
     if (!db.open())
         return false;
 
-    LOG << "Database connection established.\n";
+    LOG << "Database connection established.";
     // Enable foreign key restrictions
     QSqlQuery query(QStringLiteral("PRAGMA foreign_keys = ON;"));
     updateLayout();
@@ -123,7 +123,7 @@ void ADatabase::disconnect()
 {
     auto db = ADatabase::database();
     db.close();
-    LOG << "Database connection closed.\n";
+    LOG << "Database connection closed.";
 }
 
 QSqlDatabase ADatabase::database()
@@ -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;

+ 4 - 4
src/database/adatabasesetup.cpp

@@ -17,11 +17,11 @@
  */
 #include "adatabasesetup.h"
 #include "src/database/adatabase.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 #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"
 
@@ -432,9 +432,9 @@ bool ADataBaseSetup::createSchemata(const QStringList &statements)
     }
 
     if (!errors.isEmpty()) {
-        DEB_SRC << "The following errors have ocurred: ";
+        DEB << "The following errors have ocurred: ";
         for (const auto& error : qAsConst(errors)) {
-            DEB_RAW << error;
+            DEB << error;
         }
         return false;
     }

+ 1 - 1
src/database/adatabasetypes.h

@@ -19,7 +19,7 @@
 #define DECLARATIONS_H
 
 #include <QtCore>
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 
 /// \todo Short descriptions
 using RowId_T = int;

+ 2 - 2
src/functions/acalc.cpp

@@ -16,10 +16,10 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "acalc.h"
-#include "src/testing/adebug.h"
+#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/acalc.h

@@ -24,7 +24,7 @@
 #include <cmath>
 #include <QDateTime>
 #include <QDebug>
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 /*!
  * \brief The ACalc namespace provides various functions for calculations that are performed
  * outside of the database. This includes tasks like converting different units and formats,

+ 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 {
 

+ 126 - 0
src/functions/alog.cpp

@@ -0,0 +1,126 @@
+/*
+ *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 "alog.h"
+#include <QMessageBox>
+
+namespace ALog {
+
+static bool logDebug = false; // Debug doesn't log to file by default
+
+/*!
+ * \brief setLogFileName sets a log file name ("Log_<Date>_<Time>.txt")
+ */
+void setLogFileName()
+{
+    logFileName = QString(logFolder.absolutePath() + QLatin1String("/Log_%1_%2.txt")
+                          ).arg(QDate::currentDate().toString(QStringLiteral("yyyy_MM_dd")),
+                                QTime::currentTime().toString(QStringLiteral("hh_mm_ss")));
+}
+
+/*!
+ * \brief Cleans up old logs and initializes logging by preparing and installing a QMessageHandler
+ *
+ */
+void deleteOldLogs()
+{  
+    logFolder.setSorting(QDir::Time | QDir::Reversed);
+
+    QFileInfoList logs_list = logFolder.entryInfoList();
+    if (logs_list.size() <= numberOfLogs) {
+        return;
+    } else {
+        for (int i = 0; i < (logs_list.size() - numberOfLogs); i++) {
+            const QString path = logs_list.at(i).absoluteFilePath();
+            QFile file(path);
+            file.remove();
+        }
+    }
+}
+
+/*!
+ * \brief initialise logging, clean up logfiles and install a QMessageHandler. To enable
+ * logging of debug messages, pass parameter as true.
+ */
+bool init(bool log_debug)
+{
+    logDebug = log_debug;
+    logFolder = AStandardPaths::directory(AStandardPaths::Log);
+    deleteOldLogs();
+    setLogFileName();
+
+    QFile log_file((logFileName));
+    if(log_file.open(QIODevice::WriteOnly | QIODevice::Append)) {
+        qInstallMessageHandler(ALog::aMessageHandler);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/*!
+ * \brief aMessageHandler Intercepts Messages and prints to console and log file
+ *
+ * \abstract The message handler is responsible for intercepting the output from
+ * qDebug(), qInfo(), qWarning() and qCritical(), formatting them and printing them
+ * to the standard console out and to a logfile using QTextStream. Debug messages are
+ * not written to the log file.
+ *
+ */
+void aMessageHandler(QtMsgType type, const QMessageLogContext &context,
+                      const QString& msg)
+{
+    const char *function = context.function ? context.function : "";
+    //check file size and if needed create new log!
+    {
+        QFile outFileCheck(logFileName);
+        if (outFileCheck.size() > sizeOfLogs) {
+            deleteOldLogs();
+            setLogFileName();
+        }
+    }
+    // open the log file and prepare a textstream to write to it
+    QFile log_file(logFileName);
+    log_file.open(QIODevice::WriteOnly | QIODevice::Append);
+    QTextStream log_stream(&log_file);
+
+    switch (type) {
+        case QtDebugMsg:
+            QTextStream(stdout) << DEB_HEADER_CONSOLE << msg << endl << D_SPACER << function << "\033[m" << endl;
+            if(logDebug)
+                log_stream << timeNow() << DEB_HEADER << msg << D_SPACER << function << endl;
+            break;
+        case QtInfoMsg:
+            log_stream << timeNow() << INFO_HEADER << msg << SPACER << function << endl;
+            QTextStream(stdout) << INFO_HEADER_CONSOLE << msg << endl;
+            break;
+        case QtWarningMsg:
+            log_stream << timeNow() << WARN_HEADER << msg << SPACER << endl;
+            QTextStream(stdout) << WARN_HEADER_CONSOLE << msg << endl;
+            break;
+        case QtCriticalMsg:
+            log_stream << timeNow() << CRIT_HEADER << msg << SPACER << endl;
+            QTextStream(stdout) << CRIT_HEADER_CONSOLE << msg << endl;
+            break;
+    default:
+            log_stream << timeNow() << INFO_HEADER << msg << function << endl;
+            QTextStream(stdout) << INFO_HEADER_CONSOLE << msg << endl;
+            break;
+    }
+}
+
+} // namespace ALog

+ 87 - 7
src/functions/alog.h

@@ -18,15 +18,95 @@
 #ifndef ALOG_H
 #define ALOG_H
 
+#include <QTime>
+#include <QFile>
+#include <QFileInfo>
 #include <QDebug>
+#include <QDir>
+#include <QFileInfoList>
+#include <iostream>
+#include <QDebug>
+#include "src/classes/astandardpaths.h"
 
-/* Use QTextStream to print status messages. These messages
- * are oriented towards end-users and will persist even when
- * compiling a release without enabling qDebug. As such, LOG
- * should be used to document "important" enough steps that
- * the user would care about or that are "milestones" that
- * the program runs through.
+/*!
+ * \brief The ALog namespace encapsulates constants and functions used to provide logging to files
+ * and logging to console (stdout)
+ *
+ * \abstract
+ *
+ * The console output is color coded - green, amber, magenta for info, warn and crit messages, whereas
+ * the log files are just plain text.
+ *
+ * There is a maximum of <numberOfLogs> log files with a maximum size of <sizeOfLogs>,
+ * at the moment, up to 10 logs of up to 100kB in size are kept, older logs are
+ * automatically deleted.
+ *
+ * Debug output is not written to the logfile.
+ *
+ * In order to start logging, the ALog::init() function has to be called
+ *
+ * Credits to [Andy Dunkel](https://andydunkel.net/) for his excellent blog post on Qt Log File Rotation!
+ */
+namespace ALog
+{
+    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(" [DEBG]:\t");
+    const static auto INFO_HEADER = QLatin1String(" [INFO]:\t");
+    const static auto WARN_HEADER = QLatin1String(" [WARN]:\t");
+    const static auto CRIT_HEADER = QLatin1String(" [CRIT]:\t");
+    const static auto DEB_HEADER_CONSOLE  = QLatin1String("\u001b[38;5;75m[DEBG]:\t");
+    const static auto INFO_HEADER_CONSOLE = QLatin1String("\033[32m[INFO]:\t\033[m");
+    const static auto WARN_HEADER_CONSOLE = QLatin1String("\033[33m[WARN]:\t\033[m");
+    const static auto CRIT_HEADER_CONSOLE = QLatin1String("\033[35m[CRIT]:\t\033[m");
+    const static auto SPACER = QLatin1String("\t\t");
+    const static auto D_SPACER = QLatin1String("\t\t\t\t");
+
+    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
+
+/*!
+ * Representation macro for custom classes.
+ *
+ * Usage
+ * -----
+ * class Myclass {
+ *  ...
+ * 	REPR(MyClass,
+ *       "member1=" + object.member1 + ", "
+ *       "something2" + object.calculate()
+ *      )
+ * };
+ *
+ * MyClass mc;
+ * DEB << mc;
+ *
+ * output:
+ * MyClass(member1=3000, something2="A320")
  */
-#define LOG QTextStream(stdout) << "openPilotLog - "
+#define REPR(cls, str) \
+friend \
+QDebug operator<<(QDebug qdb, const cls& object) \
+{ \
+    qdb << QString(#cls) + '(' + str + ')'; \
+    return qdb; \
+}
 
 #endif // ALOG_H

+ 1 - 1
src/functions/astat.cpp

@@ -17,7 +17,7 @@
  */
 #include "astat.h"
 #include "src/database/adatabase.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 
 /*!
  * \brief AStat::totalTime Looks up Total Blocktime in the flights database

+ 2 - 2
src/functions/atime.h

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

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

@@ -17,13 +17,13 @@
  */
 #include "firstrundialog.h"
 #include "ui_firstrundialog.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 #include "src/database/adatabase.h"
 #include "src/database/adatabasesetup.h"
 #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"
 

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

@@ -22,9 +22,9 @@
 #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/testing/adebug.h"
+#include "src/functions/alog.h"
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///                                         constants                                           ///

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

@@ -17,10 +17,11 @@
  */
 #include "newpilotdialog.h"
 #include "ui_newpilot.h"
+#include "src/opl.h"
 
 #include "src/database/adatabase.h"
 #include "src/classes/aentry.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 
 /* Examples for names around the world:
  * José Eduardo Santos Tavares Melo Silva

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

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

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

@@ -17,12 +17,13 @@
  */
 #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"
 #include "src/classes/atailentry.h"
 #include "src/classes/aflightentry.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 
 AircraftWidget::AircraftWidget(QWidget *parent) :
     QWidget(parent),

+ 62 - 36
src/gui/widgets/backupwidget.cpp

@@ -1,7 +1,8 @@
 #include "backupwidget.h"
 #include "ui_backupwidget.h"
+#include "src/opl.h"
 #include "src/classes/astandardpaths.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 #include "src/database/adatabase.h"
 #include "src/functions/adatetime.h"
 
@@ -17,27 +18,9 @@ BackupWidget::BackupWidget(QWidget *parent) :
 {
     ui->setupUi(this);
 
-    /* This is just a quick and dirty overview to get something into the view so you have an idea.
-     * The goal is that the view does not just display file names, but a String, for example
-     *
-     * Available Backups
-     * =================
-     * 2020-01-01 - 476 Flights, 23 Aircraft, 12 Pilots, 1580:33 Total Time, Last Flight 2019-12-28
-     * 2020-02-02 - 512 Flights, 25 Aircraft, 13 Pilots, 1640:47 Total Time, Last Flight 2020-01-23
-     * ...
-     *
-     * So instead of QFileSystemModel with QListView, which would be the easiest way, using QAbstractItemModel
-     * and QTableView might be preferable since it allows us to customize the data we display.
-     *
-     * Below is just some sample code to fill the table with data to give you an impression of what
-     * the end result is supposed to be like. If you have another idea of how to get there, that's fine as well!
-     *
-     */
-
-
     model = new QStandardItemModel(this);
-    model->setHorizontalHeaderLabels(QStringList{"Backup File","Total Flights", "Total Tails",
-                                                 "Total Pilots", "Max Doft", "Total Time"});  // [G]: TODO make const but where?
+    model->setHorizontalHeaderLabels(QStringList{tr("Backup File"),tr("Flights"), tr("Aircraft"),
+                                                 tr("Pilots"), tr("Last Flight"), tr("Total Time")});  // [G]: TODO make const but where?
     view = ui->tableView;
     refresh();
 }
@@ -96,27 +79,25 @@ 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;
     }
 
-    // [G] TODO: propably make a function out of this for future tweaks
     QFileIconProvider provider;
     QMap<ADatabaseSummaryKey, QString> summary = aDB->databaseSummary(filename);
-    model->appendRow({new AFileStandardItem(provider.icon(QFileIconProvider::File), QFileInfo(filename)),
+    model->insertRow(0, {new AFileStandardItem(provider.icon(QFileIconProvider::File), QFileInfo(filename)),
                       new QStandardItem(summary[ADatabaseSummaryKey::total_flights]),
                       new QStandardItem(summary[ADatabaseSummaryKey::total_tails]),
                       new QStandardItem(summary[ADatabaseSummaryKey::total_pilots]),
                       new QStandardItem(summary[ADatabaseSummaryKey::max_doft]),
                       new QStandardItem(summary[ADatabaseSummaryKey::total_time])
                      });
-    model->sort(0);
 }
 
 void BackupWidget::on_restoreLocalPushButton_clicked()
 {
     if(selectedFileInfo == nullptr) {
-        INFO << "No backup selected";
+        INFO(tr("No backup selected"));
         return;
     }
 
@@ -125,16 +106,31 @@ void BackupWidget::on_restoreLocalPushButton_clicked()
                 selectedFileInfo->data(Qt::DisplayRole).toString()
                 );
 
+    QMessageBox confirm(this);
+    confirm.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+    confirm.setDefaultButton(QMessageBox::No);
+    confirm.setIcon(QMessageBox::Warning);
+    confirm.setWindowTitle(tr("Restoring Backup"));
+    confirm.setText(tr("The following backup will be restored:<br><br><b><tt>"
+                       "%1</b></tt><br><br>"
+                       "This will replace your currently active database with the backup.<br>This action is irreversible.<br><br>Are you sure?"
+                       ).arg(selectedFileInfo->info().fileName()));
+    if (confirm.exec() == QMessageBox::No)
+        return;
+
     if(!aDB->restoreBackup(backup_name)) {
-        WARN << "Couldnt restore" << backup_name;
+        WARN(tr("Couldnt restore Backup: %1").arg(backup_name));
     }
+
+    view->clearSelection();
+    selectedFileInfo = nullptr;
 }
 
 void BackupWidget::on_deleteSelectedPushButton_clicked()
 {
-    NOT_IMPLEMENTED("Test external deletion");
+    TODO << "Test external deletion";
     if(selectedFileInfo == nullptr) {
-        INFO << "No backup was selected";
+        INFO(tr("No backup was selected"));
         return;
     }
 
@@ -142,13 +138,25 @@ 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;
+    QMessageBox confirm(this);
+    confirm.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+    confirm.setDefaultButton(QMessageBox::No);
+    confirm.setIcon(QMessageBox::Question);
+    confirm.setWindowTitle(tr("Delete Backup"));
+    confirm.setText(tr("The following backup will be deleted:<br><br><b><tt>"
+                       "%1</b></tt><br><br>"
+                       "Are you sure?"
+                       ).arg(filename.fileName()));
+    if (confirm.exec() == QMessageBox::No)
+        return;
+
+    LOG << "Deleting backup:" << 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 +169,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(),
@@ -203,9 +211,27 @@ void BackupWidget::on_restoreExternalPushButton_clicked()
     }
 }
 
-void BackupWidget::on_aboutPushButton_clicked() {
-    // [G]: Add message text. Could this be predefined in Opl::Assets?
-    QMessageBox msg_box(QMessageBox::Information, "About backups", "...", QMessageBox::Ok);
+void BackupWidget::on_aboutPushButton_clicked()
+{
+    TODO << "Implement settings and automatic backups";
+    QString text = tr(
+
+                      "<h3><center>About Backups</center></h3>"
+                      "<br>"
+                      "<p>By creating a backup, you create a copy of your logbook for safekeeping. This copy includes all your "
+                      "flights, pilots, aircraft and expiries. By creating a backup, you are creating a snapshot of your logbook to date. This backup can "
+                      "later be restored or kept for safekeeping. OpenPilotLog offers two kinds of backups: Local and External Backups.<br><br>Local backups "
+                      "are automatically stored in a folder on this computer and will show up in the list below. They can easily be created by selecting <b>Create Local backup</b> and restored with "
+                      "<b>Restore Local Backup</b>.<br>"
+                      "When using <b>Create External Backup</b>, you will be asked where to save your backup file. This can be a pen drive, a cloud location or any other location of your choice. "
+                      "This functionality can also be used to sync your database across devices or to take it with you when you buy a new PC. You can then import your backup file by selecting "
+                      "it with <b>Restore external backup</b>.</p>"
+                      "<p>Frequent backups are recommended to guard against data loss or corruption. It is also recommended to keep a backup copy in a seperate location from your main "
+                      "computer to prevent data loss due to system failures.</p>"
+                      //todo "<p>By default, OpenPilotLog creates a weekly automatic backup. If you would like to change this behaviour, you can adjust it in the settings.</p>"
+                      "<br>"
+                      );
+    QMessageBox msg_box(QMessageBox::Information, "About backups", text, QMessageBox::Ok, this);
     msg_box.exec();
 }
 

+ 65 - 107
src/gui/widgets/backupwidget.ui

@@ -14,44 +14,6 @@
    <string>Form</string>
   </property>
   <layout class="QGridLayout" name="gridLayout">
-   <item row="4" column="0">
-    <widget class="QTableView" name="tableView">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="sizeAdjustPolicy">
-      <enum>QAbstractScrollArea::AdjustToContents</enum>
-     </property>
-     <property name="editTriggers">
-      <set>QAbstractItemView::NoEditTriggers</set>
-     </property>
-     <property name="alternatingRowColors">
-      <bool>true</bool>
-     </property>
-     <property name="selectionMode">
-      <enum>QAbstractItemView::SingleSelection</enum>
-     </property>
-     <property name="selectionBehavior">
-      <enum>QAbstractItemView::SelectRows</enum>
-     </property>
-     <attribute name="horizontalHeaderStretchLastSection">
-      <bool>true</bool>
-     </attribute>
-     <attribute name="verticalHeaderVisible">
-      <bool>false</bool>
-     </attribute>
-    </widget>
-   </item>
-   <item row="2" column="0">
-    <widget class="Line" name="line">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-    </widget>
-   </item>
    <item row="6" column="0">
     <widget class="Line" name="line_2">
      <property name="orientation">
@@ -59,78 +21,43 @@
      </property>
     </widget>
    </item>
-   <item row="0" column="0">
-    <layout class="QHBoxLayout" name="horizontalLayout_2">
-     <item>
-      <widget class="QLabel" name="aboutSpacerLabel1">
-       <property name="text">
-        <string/>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QLabel" name="aboutSpacerLabel2">
-       <property name="text">
-        <string/>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QLabel" name="aboutSpacerLabel3">
-       <property name="text">
-        <string/>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="aboutPushButton">
-       <property name="text">
-        <string>About Backups</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
+   <item row="2" column="0">
+    <widget class="QLabel" name="availableBackupsLabel">
+     <property name="font">
+      <font>
+       <pointsize>10</pointsize>
+       <weight>75</weight>
+       <bold>true</bold>
+      </font>
+     </property>
+     <property name="text">
+      <string>Available Backups</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
    </item>
    <item row="1" column="0">
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="titleSpacerLabel1">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="text">
-        <string/>
-       </property>
-      </widget>
-     </item>
+    <layout class="QHBoxLayout" name="horizontalLayout_11">
      <item>
-      <widget class="QLabel" name="availableBackupsLabel">
+      <widget class="QPushButton" name="createLocalPushButton">
        <property name="text">
-        <string>Available Backups</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignCenter</set>
+        <string>Create Local Backup</string>
        </property>
       </widget>
      </item>
      <item>
-      <widget class="QLabel" name="titleSpacerLabel2">
+      <widget class="QPushButton" name="restoreLocalPushButton">
        <property name="text">
-        <string/>
+        <string>Restore Local Backup</string>
        </property>
       </widget>
      </item>
-    </layout>
-   </item>
-   <item row="3" column="0">
-    <layout class="QHBoxLayout" name="horizontalLayout_11">
      <item>
-      <widget class="QPushButton" name="restoreExternalPushButton">
+      <widget class="QPushButton" name="deleteSelectedPushButton">
        <property name="text">
-        <string>Restore External Backup</string>
+        <string>Delete Selected Backup</string>
        </property>
       </widget>
      </item>
@@ -142,28 +69,59 @@
       </widget>
      </item>
      <item>
-      <widget class="QPushButton" name="deleteSelectedPushButton">
-       <property name="text">
-        <string>Delete Selected Backup</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="restoreLocalPushButton">
+      <widget class="QPushButton" name="restoreExternalPushButton">
        <property name="text">
-        <string>Restore Local Backup</string>
+        <string>Restore External Backup</string>
        </property>
       </widget>
      </item>
      <item>
-      <widget class="QPushButton" name="createLocalPushButton">
+      <widget class="QPushButton" name="aboutPushButton">
        <property name="text">
-        <string>Create Local Backup</string>
+        <string>About Backups</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
+   <item row="4" column="0">
+    <widget class="QTableView" name="tableView">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="sizeAdjustPolicy">
+      <enum>QAbstractScrollArea::AdjustToContents</enum>
+     </property>
+     <property name="editTriggers">
+      <set>QAbstractItemView::NoEditTriggers</set>
+     </property>
+     <property name="alternatingRowColors">
+      <bool>true</bool>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::SingleSelection</enum>
+     </property>
+     <property name="selectionBehavior">
+      <enum>QAbstractItemView::SelectRows</enum>
+     </property>
+     <attribute name="horizontalHeaderStretchLastSection">
+      <bool>true</bool>
+     </attribute>
+     <attribute name="verticalHeaderVisible">
+      <bool>false</bool>
+     </attribute>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="Line" name="line">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <resources/>

+ 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

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

@@ -33,9 +33,8 @@
 #include "src/classes/aentry.h"
 #include "src/classes/apilotentry.h"
 
-#include "src/testing/abenchmark.h"
 #include "src/testing/atimer.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 
 namespace Ui {
 class DebugWidget;

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

@@ -17,7 +17,7 @@
  */
 #include "homewidget.h"
 #include "ui_homewidget.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 #include "src/database/adatabase.h"
 #include "src/functions/atime.h"
 #include "src/classes/asettings.h"
@@ -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)

+ 5 - 5
src/gui/widgets/logbookwidget.cpp

@@ -22,7 +22,7 @@
 #include "src/database/adatabase.h"
 #include "src/classes/asettings.h"
 #include "src/gui/dialogues/newflightdialog.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 #include "src/functions/alog.h"
 
 const QMap<int, QString> FILTER_MAP = {
@@ -70,17 +70,17 @@ void LogbookWidget::setupModelAndView(int view_id)
 {
     switch (view_id) {
     case 0:
-        LOG << "Loading Default View...\n";
+        LOG << "Loading Default View...";
         displayModel->setTable(QStringLiteral("viewDefault"));
         displayModel->select();
         break;
     case 1:
-        LOG << "Loading EASA View...\n";
+        LOG << "Loading EASA View...";
         displayModel->setTable(QStringLiteral("viewEASA"));
         displayModel->select();
         break;
     default:
-        LOG << "Loading Default View...\n";
+        LOG << "Loading Default View...";
         displayModel->setTable(QStringLiteral("viewDefault"));
         displayModel->select();
     }
@@ -164,7 +164,7 @@ void LogbookWidget::on_deleteFlightPushButton_clicked()
             flights_list_string.append(QStringLiteral("&nbsp;&nbsp;&nbsp;&nbsp;<br>"));
         }
 
-        QMessageBox confirm;
+        QMessageBox confirm(this);
         confirm.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
         confirm.setDefaultButton(QMessageBox::No);
         confirm.setIcon(QMessageBox::Question);

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

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

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

@@ -17,12 +17,12 @@
  */
 #include "settingswidget.h"
 #include "ui_settingswidget.h"
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 #include "src/classes/astyle.h"
 #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() << "TO 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/testing/adebug.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

+ 2 - 1
src/testing/adebug.h

@@ -1,6 +1,7 @@
 #ifndef ADEBUG_H
 #define ADEBUG_H
 
+/*
 #include <QDebug>
 
 #if defined(__GNUC__) || defined(__clang__)
@@ -31,7 +32,7 @@
 #define CRIT qCritical() << "critical:"
 //#define NOT_IMPLEMENTED qCritical() << FUNC_IDENT << "\n\t" << "~~ NOT IMPLEMENTED ~~";
 #define NOT_IMPLEMENTED(msg) qCritical() << FUNC_IDENT << "\n\tNOT IMPLEMENTED:" << msg
-
+*/
 /*!
  * Representation macro for custom classes.
  *

+ 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)

+ 1 - 1
src/testing/atimer.h

@@ -21,7 +21,7 @@
 #include <QObject>
 #include <chrono>
 #include <QDebug>
-#include "src/testing/adebug.h"
+#include "src/functions/alog.h"
 
 /*!
  * \brief The ATimer class provides an easy to use performance timer.