Browse Source

Preliminary Settings rework

Adding new Airports is now supported in the NewFlightDialog.

Overhaul of the settings class. Instead of using enums and type conversions wherever settings are read or written, there are now typed functions available to set and get setting values.

Currencies are handled exclusively in the database now instead of in the settings. Some adjusments to HomeWidget and SettingsWidget pending.
Felix Turowsky 1 year ago
parent
commit
ff1e5d9482

+ 6 - 5
assets/database/database_schema.sql

@@ -89,11 +89,12 @@ CREATE TABLE IF NOT EXISTS 'airports' (
 	PRIMARY KEY('airport_id' AUTOINCREMENT)
 );
 DROP TABLE IF EXISTS 'currencies';
-CREATE TABLE IF NOT EXISTS 'currencies' (
-	'currency_id'	INTEGER NOT NULL,
-	'currencyName'	TEXT,
-	'expiryDate'	NUMERIC,
-	PRIMARY KEY('currency_id' AUTOINCREMENT)
+CREATE TABLE IF NOT EXISTS "currencies" (
+        "currency_id"	INTEGER NOT NULL,
+        "currencyName"	TEXT,
+        "expiryDate"	NUMERIC,
+        "displayName"	TEXT,
+        PRIMARY KEY('currency_id' AUTOINCREMENT)
 );
 DROP TABLE IF EXISTS 'changelog';
 CREATE TABLE IF NOT EXISTS 'changelog' (

+ 6 - 1
assets/database/templates/currencies.json

@@ -28,5 +28,10 @@
         "currency_id": 6,
         "currencyName": "Custom2",
         "expiryDate": null
+    },
+    {
+        "currency_id": 7,
+        "currencyName": "Take Off / Landing",
+        "expiryDate": null
     }
-]
+]

+ 6 - 4
main.cpp

@@ -52,7 +52,7 @@ void init()
         LOG << "Unable to initalise logging.";
     }
     LOG << "Reading Settings...";
-    Settings::setup();
+    Settings::init();
     LOG << "Setting up application style...";
     OPL::Style::setup();
     // Translations to be done at a later stage
@@ -71,7 +71,8 @@ int firstRun()
         return 1;
     }
 
-    Settings::write(Settings::Main::SetupComplete, true);
+    Settings::setSetupCompleted(true);
+//    Settings::write(Settings::Main::SetupComplete, true);
     LOG << "Initial Setup Completed successfully";
     QMessageBox mb;
     mb.setText("Initial set-up has been completed successfully.<br><br>Please re-start the application.");
@@ -98,9 +99,10 @@ int main(int argc, char *argv[])
     init();
 
     // Check for First Run and launch Setup Wizard
-    if (!Settings::read(Settings::Main::SetupComplete).toBool())
+//    if (!Settings::read(Settings::Main::SetupComplete).toBool())
+//        return firstRun();
+    if(!Settings::getSetupCompleted())
         return firstRun();
-
     // Create Main Window and set Window Icon acc. to Platform
     MainWindow w;
 #ifdef __linux__

+ 4 - 13
mainwindow.cpp

@@ -29,18 +29,8 @@
 // Quick and dirty Debug area
 void MainWindow::doDebugStuff()
 {
-    OPL::RowData_T xp = DB->getTotals(false);
-    LOG << "Totals without previous:";
-    LOG << xp;
-
-    xp = DB->getTotals(true);
-    LOG << "Totals with previous:";
-    LOG << xp;
-
-    OPL::FlightEntry fe = OPL::FlightEntry();
-    LOG << "FLIGHT table: " << fe.getTableName();
-    OPL::Row row = OPL::Row();
-    LOG << "ROW table: " << row.getTableName();
+    LOG << "Setup completed? ";
+    LOG << Settings::getSetupCompleted();
 }
 
 MainWindow::MainWindow(QWidget *parent)
@@ -235,7 +225,8 @@ void MainWindow::onDatabaseInvalid()
             LOG << "Initial setup incomplete or unsuccessfull.";
             on_actionQuit_triggered();
         }
-        Settings::write(Settings::Main::SetupComplete, true);
+        Settings::setSetupCompleted(true);
+//        Settings::write(Settings::Main::SetupComplete, true);
         LOG << "Initial Setup Completed successfully";
     }
 }

+ 22 - 106
src/classes/settings.cpp

@@ -19,50 +19,12 @@
 #include <QSettings>
 #include "src/classes/paths.h"
 
-
-QMap<Settings::Main, QString> Settings::mainMap = {
-    {Main::SetupComplete,               QStringLiteral("setupComplete")},
-    {Main::Style,                       QStringLiteral("style")},
-    {Main::Font,                        QStringLiteral("font")},
-    {Main::FontSize,                    QStringLiteral("fontSize")},
-    {Main::UseSystemFont,               QStringLiteral("useSystemFont")},
-    {Main::LogbookView,                 QStringLiteral("logbookView")},
-    {Main::DateFormat,                  QStringLiteral("dateFormat")},
-};
-
-QMap<Settings::UserData, QString> Settings::userDataMap = {
-    {UserData::DisplaySelfAs,           QStringLiteral("displayselfas")},
-    {UserData::TailSortColumn,          QStringLiteral("tailSortColumn")},
-    {UserData::PilotSortColumn,         QStringLiteral("pilotSortColumn")},
-    {UserData::FtlWarningThreshold,     QStringLiteral("ftlWarningThreshold")},
-    {UserData::CurrWarningThreshold,    QStringLiteral("currWarningThreshold")},
-    {UserData::ShowToLgdCurrency,       QStringLiteral("showToLdgCurrency")},
-    {UserData::ShowLicCurrency,         QStringLiteral("showLicCurrency")},
-    {UserData::ShowTrCurrency,          QStringLiteral("showTrCurrency")},
-    {UserData::ShowLckCurrency,         QStringLiteral("showLckCurrency")},
-    {UserData::ShowMedCurrency,         QStringLiteral("showMedCurrency")},
-    {UserData::ShowCustom1Currency,     QStringLiteral("showCustom1Currency")},
-    {UserData::ShowCustom2Currency,     QStringLiteral("showCustom2Currency")},
-    {UserData::Custom1CurrencyName,     QStringLiteral("custom1CurrencyName")},
-    {UserData::Custom2CurrencyName,     QStringLiteral("custom2CurrencyName")},
-};
-
-QMap<Settings::FlightLogging, QString> Settings::flightLoggingMap = {
-    {FlightLogging::Function,           QStringLiteral("function")},
-    {FlightLogging::Approach,           QStringLiteral("approach")},
-    {FlightLogging::NightLoggingEnabled,QStringLiteral("nightLoggingEnabled")},
-    {FlightLogging::LogIFR,             QStringLiteral("logIfr")},
-    {FlightLogging::FlightNumberPrefix, QStringLiteral("flightnumberPrefix")},
-    {FlightLogging::PilotFlying,        QStringLiteral("pilotFlying")},
-    {FlightLogging::NightAngle,         QStringLiteral("nightangle")},
-    //{FlightLogging::FlightTimeFormat,   QStringLiteral("flightTimeFormat")},
-};
-
-void Settings::setup()
+void Settings::init()
 {
+    LOG << "Initialising application settings...";
     QSettings::setDefaultFormat(QSettings::IniFormat);
     QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, OPL::Paths::path(OPL::Paths::Settings));
-    QSettings();
+    Settings::settingsInstance = new QSettings();
 }
 
 /*!
@@ -70,70 +32,24 @@ void Settings::setup()
  */
 void Settings::resetToDefaults()
 {
-    write(Main::Style, QStringLiteral("Fusion"));
-    write(Main::UseSystemFont, true);
-    write(Main::LogbookView, 0);
-    write(Main::DateFormat, 0);
-
-    write(UserData::DisplaySelfAs, 0);
-    write(UserData::FtlWarningThreshold, 0.8); // To Do: UI Option
-    write(UserData::CurrWarningThreshold, 30);
-    write(UserData::ShowToLgdCurrency, true);
-    write(UserData::ShowLicCurrency, false);
-    write(UserData::ShowTrCurrency, false);
-    write(UserData::ShowLckCurrency, false);
-    write(UserData::ShowMedCurrency, false);
-    write(UserData::ShowCustom1Currency, false);
-    write(UserData::ShowCustom2Currency, false);
-    write(UserData::PilotSortColumn, 0);
-    write(UserData::TailSortColumn, 0);
-
-    write(FlightLogging::PilotFlying, true);
-    write(FlightLogging::NightAngle, -6);
+    setApplicationStyle(QStringLiteral("Fusion"));
+    setUseSystemFont(true);
+    setLogbookView(OPL::LogbookView::Default);
+    setDateFormat(OPL::DateFormat::ISODate);
+    setLogAsPilotFlying(true);
+    setNightAngle(-6);
+    setShowSelfAs(0);
+    setFtlWarningThreshold(0.8);
+    setCurrencyWarningThreshold(90);
+    setPilotSortColumn(0);
+    setTailSortColumn(0);
+    setShowCurrency(OPL::CurrencyEntry::TakeOffLanding, true);
+    setShowCurrency(OPL::CurrencyEntry::Licence, false);
+    setShowCurrency(OPL::CurrencyEntry::TypeRating, false);
+    setShowCurrency(OPL::CurrencyEntry::LineCheck, false);
+    setShowCurrency(OPL::CurrencyEntry::Medical, false);
+    setShowCurrency(OPL::CurrencyEntry::Custom1, false);
+    setShowCurrency(OPL::CurrencyEntry::Custom2, false);
+    sync();
 }
 
-//
-// Read/Write
-//
-
-QVariant Settings::read(const FlightLogging key)
-{ return QSettings().value(groupOfKey(key)); }
-
-void Settings::write(const FlightLogging key, const QVariant &val)
-{ QSettings().setValue(groupOfKey(key), val); }
-
-QVariant Settings::read(const Main key)
-{ return QSettings().value(groupOfKey(key)); }
-
-void Settings::write(const Main key, const QVariant &val)
-{ QSettings().setValue(groupOfKey(key), val); }
-
-QVariant Settings::read(const UserData key)
-{ return QSettings().value(groupOfKey(key)); }
-
-void Settings::write(const UserData key, const QVariant &val)
-{ QSettings().setValue(groupOfKey(key), val); }
-
-//
-// QString conversion PATH
-//
-QString Settings::groupOfKey (const Settings::FlightLogging key)
-{ return QStringLiteral("flightlogging/") + flightLoggingMap[key]; }
-
-QString Settings::groupOfKey (const Settings::Main key)
-{ return QStringLiteral("main/") + mainMap[key]; }
-
-QString Settings::groupOfKey (const Settings::UserData key)
-{ return QStringLiteral("userdata/") + userDataMap[key]; }
-
-//
-// QString conversion ONLY KEY
-//
-QString Settings::stringOfKey (const Settings::FlightLogging key)
-{ return  flightLoggingMap[key]; }
-
-QString Settings::stringOfKey (const Settings::Main key)
-{ return  mainMap[key]; }
-
-QString Settings::stringOfKey (const Settings::UserData key)
-{ return  userDataMap[key]; }

+ 225 - 63
src/classes/settings.h

@@ -17,89 +17,251 @@
  */
 #ifndef SETTINGS_H
 #define SETTINGS_H
+#include "src/database/currencyentry.h"
+#include "src/opl.h"
 #include <QtCore>
 #include <QSettings>
 
 /*!
- * \brief Thin wrapper for the QSettings class,
- * simplifying reading and writing of settings.
+ * \brief A wrapper for the QSettings class, simplifying reading and writing of settings.
  */
 class Settings {
 public:
-    enum class Main {
-        SetupComplete,
-        Style,
-        Font,
-        FontSize,
-        UseSystemFont,
-        LogbookView,
-        DateFormat,
-    };
-
-    enum class UserData {
-        DisplaySelfAs,
-        TailSortColumn,
-        PilotSortColumn,
-        FtlWarningThreshold,
-        CurrWarningThreshold,
-        ShowToLgdCurrency,
-        ShowLicCurrency,
-        ShowTrCurrency,
-        ShowLckCurrency,
-        ShowMedCurrency,
-        ShowCustom1Currency,
-        ShowCustom2Currency,
-        Custom1CurrencyName,
-        Custom2CurrencyName,
-    };
-
-    enum class FlightLogging {
-        Function,
-        Approach,
-        NightLoggingEnabled,
-        LogIFR,
-        FlightNumberPrefix,
-        PilotFlying,
-        NightAngle,
-        //FlightTimeFormat,
-    };
-
-    /*!
-     * \brief Should be called after QCoreApplication::set...Name have been called.
-     */
-    static void setup();
+    /*!
+     * \brief Initialise the default setting object. Call after QCoreApplication has been set up in main
+     */
+    static void init();
+
+    /*!
+     * \brief Reset the application settings to its default values
+     */
     static void resetToDefaults();
 
-    static QVariant read(const Main key);
-    static void write(const Main key, const QVariant &val);
+    /*!
+     * \brief Writes any unsaved changes to permanent storage
+     * \note This function is called automatically from QSettings's destructor and by the event loop at regular intervals,
+     * so you normally don't need to call it yourself.
+     */
+    static void sync() { settingsInstance->sync(); }
+
+    /*!
+     * \brief Initial set-up of the application and database has been completed
+     */
+    static bool getSetupCompleted() { return settingsInstance->value(MAIN_SETUP_COMPLETE, false).toBool(); }
+
+    /*!
+     * \brief Initial set-up of the application and database has been completed
+     */
+    static void setSetupCompleted(bool completed) { settingsInstance->setValue(MAIN_SETUP_COMPLETE, completed); }
+
+    /*!
+     * \brief returns the name of the preferred application style (default: fusion)
+     */
+    static const QString getApplicationStyle() { return settingsInstance->value(MAIN_STYLE, "Fusion").toString(); }
+
+    /*!
+     * \brief set the name of the preferred application style
+     */
+    static const void setApplicationStyle(const QString &style) { settingsInstance->setValue(MAIN_STYLE, style); }
+
+    /*!
+     * \brief returns the name of the preferred application font (default: system font)
+     * \return
+     */
+    static const QString getApplicationFontName() { return settingsInstance->value(MAIN_FONT_NAME, QString()).toString(); }
+
+    /*!
+     * \brief set the name of the preferred application font
+     * \return
+     */
+    static const void setApplicationFontName(const QString &fontName) { settingsInstance->setValue(MAIN_FONT_NAME, fontName); }
+
+    /*!
+     * \brief returns the preferred font size (default: 10)
+     * \return
+     */
+    static int getApplicationFontSize() { return settingsInstance->value(MAIN_FONT_SIZE, 10).toInt(); }
+
+    /*!
+     * \brief sets the preferred font size
+     */
+    static void setApplicationFontSize(int size) { settingsInstance->setValue(MAIN_FONT_SIZE, size); }
+
+    /*!
+     * \brief returns if the default system font should be used (default: true)
+     */
+    static bool getUseSystemFont() { return settingsInstance->value(MAIN_USE_SYSTEM_FONT, true).toBool(); }
+
+    /*!
+     * \brief sets if the default system font should be used
+     */
+    static void setUseSystemFont(bool value) { settingsInstance->setValue(MAIN_USE_SYSTEM_FONT, value); }
+
+    /*!
+     * \brief returns the view to be used in the logbook widget
+     */
+    static OPL::LogbookView getLogbookView() { return OPL::LogbookView(settingsInstance->value(MAIN_LOGBOOK_VIEW).toInt()); }
+
+    /*!
+     * \brief sets the view to be used in the logbook widget
+     */
+    static void setLogbookView(OPL::LogbookView view) { (settingsInstance->setValue(MAIN_LOGBOOK_VIEW, static_cast<int>(view))); }
+
+    /*!
+     * \brief returns the date format to be used in the application
+     */
+    static OPL::DateFormat getDateFormat() { return OPL::DateFormat(settingsInstance->value(MAIN_DATE_FORMAT).toInt()); }
+
+    /*!
+     * \brief sets the date format to be used in the application
+     */
+    static void setDateFormat(OPL::DateFormat format) { (settingsInstance->setValue(MAIN_DATE_FORMAT, static_cast<int>(format))); }
+
+    /*!
+     * \brief returns the default pilot function for new flights
+     */
+    static OPL::PilotFunction getPilotFunction() { return OPL::PilotFunction(settingsInstance->value(LOG_FUNCTION).toInt()); }
+
+    /*!
+     * \brief sets the default pilot function for new flights
+     */
+    static void setPilotFunction(OPL::PilotFunction function) { settingsInstance->setValue(LOG_FUNCTION, static_cast<int>(function)); }
+
+    /*!
+     * \brief returns the default approach type for new flights
+     */
+    static const QString getApproachType() { return settingsInstance->value(LOG_APPROACH).toString(); }
+    /*!
+     * \brief sets the default approach type for new flights
+     */
+    static void setApproachType(const QString &value) { settingsInstance->setValue(LOG_APPROACH, value); }
+
+    /*!
+     * \brief returns if automatic night time calculation is enabled for new flights
+     */
+    static bool getNightLoggingEnabled() { return settingsInstance->value(LOG_NIGHT).toBool(); }
+
+    /*!
+     * \brief sets if automatic night time calculation is enabled for new flights
+     */
+    static void setNightLoggingEnabled(bool value) { settingsInstance->setValue(LOG_NIGHT, value); }
+
+    /*!
+     * \brief returns the angle of elevation for night time calculation (default: -6 degrees)
+     */
+    static int getNightAngle() { return settingsInstance->value(LOG_NIGHT_ANGLE, -6).toInt(); }
+
+    /*!
+     * \brief sets the angle of elevation for night time calculation
+     */
+    static void setNightAngle(int value) { settingsInstance->setValue(LOG_NIGHT_ANGLE, value); }
+
+    /*!
+     * \brief returns if flight time should be logged as IFR for new flights
+     */
+    static bool getLogIfr() { return settingsInstance->value(LOG_IFR).toBool(); }
+
+    /*!
+     * \brief sets if flight time should be logged as IFR for new flights
+     */
+    static void setLogIfr(bool value) { settingsInstance->setValue(LOG_IFR, value); }
+
+    /*!
+     * \brief returns if new flights should be logged as Pilot Flying
+     */
+    static bool getLogAsPilotFlying() { return settingsInstance->value(LOG_AS_PF).toBool(); }
 
-    static QVariant read(const FlightLogging key);
-    static void write(const UserData key, const QVariant &val);
+    /*!
+     * \brief sets if new flights should be logged as Pilot Flying
+     */
+    static void setLogAsPilotFlying(bool value) { settingsInstance->setValue(LOG_AS_PF, value); }
 
-    static QVariant read(const UserData key);
-    static void write(const FlightLogging key, const QVariant &val);
+    /*!
+     * \brief returns the default Flight Number Prefix for new flights
+     */
+    static const QString getFlightNumberPrefix() { return settingsInstance->value(LOG_PREFIX).toString(); }
+
+    /*!
+     * \brief sets the default Flight Number Prefix for new flights
+     */
+    static void setFlightNumberPrefix(const QString &value) { settingsInstance->setValue(LOG_PREFIX, value); }
+
+    // TODO test these
+
+    /*!
+     * \brief returns whether the Currency passed as a parameter is shown on the Home screen
+     */
+    static bool getShowCurrency(OPL::CurrencyEntry::Currency currency) { return settingsInstance->value(CURRENCY_STUB.arg(CURRENCIES.value(currency))).toBool(); }
 
     /*!
-     * \brief Return string representation of group of key: "ini_header/key"
+     * \brief sets whether the Currency passed as a parameter is shown on the home screen
      */
-    static QString groupOfKey(const Main key);
-    static QString groupOfKey(const FlightLogging key);
-    static QString groupOfKey(const UserData key);
+    static void setShowCurrency(OPL::CurrencyEntry::Currency currency, bool value) { settingsInstance->setValue(CURRENCY_STUB.arg(CURRENCIES.value(currency)), value); }
 
     /*!
-     * \brief Return string representation of key
+     * \brief sets how the logbook owner is shown in the view
+     * \details
+     * <ul>
+     * <li> 0 - self
+     *
      */
-    static QString stringOfKey(const Main key);
-    static QString stringOfKey(const FlightLogging key);
-    static QString stringOfKey(const UserData key);
+    static int getShowSelfAs() { return settingsInstance->value(SHOW_SELF_AS).toInt(); }
+
+    static void setShowSelfAs(int value) { settingsInstance->setValue(SHOW_SELF_AS, value); }
+
+    static int getTailSortColumn() { return settingsInstance->value(TAIL_SORT_COLUMN).toInt(); }
+    static void setTailSortColumn(int value) { settingsInstance->setValue(TAIL_SORT_COLUMN, value); }
+
+    static int getPilotSortColumn() { return settingsInstance->value(PILOT_SORT_COLUMN).toInt(); }
+    static void setPilotSortColumn(int value) { settingsInstance->setValue(PILOT_SORT_COLUMN, value); }
+
+    static double getFtlWarningThreshold() { return settingsInstance->value(FTL_WARNING_THR, 0.8).toDouble(); }
+    static void setFtlWarningThreshold(double value) { settingsInstance->setValue(FTL_WARNING_THR, value); }
+
+    static int getCurrencyWarningThreshold() { return settingsInstance->value(CURR_WARNING_THR, 90).toInt(); }
+    static void setCurrencyWarningThreshold(int days) { settingsInstance->setValue(CURR_WARNING_THR, days); }
+
 
-    static QSettings settings();
-    static void sync() { QSettings().sync(); }
 
 private:
-    static QMap<Main, QString> mainMap;
-    static QMap<UserData, QString> userDataMap;
-    static QMap<FlightLogging, QString> flightLoggingMap;
+
+    // keep an instance to avoid having to create a new QSettings object every time
+    static inline QSettings *settingsInstance;
+
+    // Setting keys
+    const static inline QString CURRENCY_STUB   	= QStringLiteral("userdata/%1Currency");
+    const static inline QString SHOW_SELF_AS    	= QStringLiteral("userdata/displaySelfAs");
+    const static inline QString TAIL_SORT_COLUMN    = QStringLiteral("userdata/tailSortColumn");
+    const static inline QString PILOT_SORT_COLUMN	= QStringLiteral("userdata/pilotSortColumn");
+    const static inline QString FTL_WARNING_THR		= QStringLiteral("ftlWarningThreshold");
+    const static inline QString CURR_WARNING_THR	= QStringLiteral("currWarningThreshold");
+
+    const static inline QString LOG_FUNCTION	= QStringLiteral("flightlogging/function");
+    const static inline QString LOG_APPROACH	= QStringLiteral("flightlogging/approach");
+    const static inline QString LOG_NIGHT	 	= QStringLiteral("flightlogging/nightLoggingEnabled");
+    const static inline QString LOG_NIGHT_ANGLE	= QStringLiteral("flightlogging/nightangle");
+    const static inline QString LOG_IFR	 	 	= QStringLiteral("flightlogging/logIfr");
+    const static inline QString LOG_AS_PF	 	= QStringLiteral("flightlogging/pilotFlying");
+    const static inline QString LOG_PREFIX	 	= QStringLiteral("flightlogging/flightnumberPrefix");
+
+    const static inline QString MAIN_SETUP_COMPLETE  = QStringLiteral("main/setupComplete");
+    const static inline QString MAIN_STYLE			 = QStringLiteral("main/style");
+    const static inline QString MAIN_FONT_NAME		 = QStringLiteral("main/font");
+    const static inline QString MAIN_FONT_SIZE 		 = QStringLiteral("main/fontSize");
+    const static inline QString MAIN_USE_SYSTEM_FONT = QStringLiteral("main/useSystemFont");
+    const static inline QString MAIN_LOGBOOK_VIEW 	 = QStringLiteral("main/logbookView");
+    const static inline QString MAIN_DATE_FORMAT 	 = QStringLiteral("main/dateFormat");
+
+    const static inline QHash<OPL::CurrencyEntry::Currency, QString> CURRENCIES = {
+        {OPL::CurrencyEntry::Licence, QStringLiteral("Licence")},
+        {OPL::CurrencyEntry::TypeRating, QStringLiteral("Type Rating")},
+        {OPL::CurrencyEntry::LineCheck, QStringLiteral("Line Check")},
+        {OPL::CurrencyEntry::Medical, QStringLiteral("Medical")},
+        {OPL::CurrencyEntry::Custom1, QStringLiteral("Custom1")},
+        {OPL::CurrencyEntry::Custom2, QStringLiteral("Custom2")},
+        {OPL::CurrencyEntry::TakeOffLanding, QStringLiteral("TakeOffLanding")},
+        };
+
 };
 
 #endif // SETTINGS_H

+ 7 - 6
src/classes/style.cpp

@@ -50,21 +50,22 @@ QLatin1String Style::DARK_PALETTE = QLatin1String("Dark-Palette");
  */
 void Style::setup()
 {
-    if (!Settings::read(Settings::Main::SetupComplete).toBool()) // Use system default for first run
+    if (!Settings::getSetupCompleted()) // Use system default for first run
         return;
+//    if (!Settings::read(Settings::Main::SetupComplete).toBool()) // Use system default for first run
+//        return;
     // Set Font
-    if (!Settings::read(Settings::Main::UseSystemFont).toBool()) {
-        QFont font(Settings::read(Settings::Main::Font).toString());
-        font.setPointSize(Settings::read(Settings::Main::FontSize).toUInt());
+    if (!Settings::getUseSystemFont()) {
+        const QFont font(Settings::getApplicationFontName(), Settings::getApplicationFontSize());
         qApp->setFont(font);
         LOG << "Application Font set: " << font.toString().split(',').first();
     }
     // Set style, stylesheet or palette
-    QString style_setting = Settings::read(Settings::Main::Style).toString();
+    const QString style_setting = Settings::getApplicationStyle();
 
     if (style_setting == DARK_PALETTE) {
         Style::setStyle(Style::darkPalette());
-        Settings::write(Settings::Main::Style, style_setting);
+        Settings::setApplicationStyle(style_setting);
         return;
     }
     for (const auto &style_name : styles) {

+ 34 - 6
src/database/currencyentry.cpp

@@ -16,16 +16,17 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "currencyentry.h"
+#include "src/database/database.h"
 
 namespace OPL {
 
-CurrencyEntry::CurrencyEntry()
-    : Row(DbTable::Currencies, 0)
-{}
+//CurrencyEntry::CurrencyEntry()
+//    : Row(DbTable::Currencies, 0)
+//{}
 
-CurrencyEntry::CurrencyEntry(const RowData_T &row_data)
-    : Row(DbTable::Currencies, 0, row_data)
-{}
+//CurrencyEntry::CurrencyEntry(const RowData_T &row_data)
+//    : Row(DbTable::Currencies, 0, row_data)
+//{}
 
 CurrencyEntry::CurrencyEntry(int row_id, const RowData_T &row_data)
     : Row(DbTable::Currencies, row_id, row_data)
@@ -36,4 +37,31 @@ const QString CurrencyEntry::getTableName() const
     return TABLE_NAME;
 }
 
+void CurrencyEntry::setDisplayName(const QString &displayName)
+{
+    auto data = getData();
+    data.insert(DISPLAY_NAME, displayName);
+    setData(data);
+    DB->commit(*this);
+}
+
+const QString CurrencyEntry::getDisplayName() const
+{
+    return getData().value(DISPLAY_NAME).toString();
+}
+
+void CurrencyEntry::setExpiryDate(const QDate &date)
+{
+    auto data = getData();
+    data.insert(EXPIRYDATE, date.toString(Qt::ISODate));
+    setData(data);
+    DB->commit(*this);
+}
+
+const QDate CurrencyEntry::getExpiryDate() const
+{
+    const QString &date = getData().value(EXPIRYDATE).toString();
+    return QDate::fromString(date, Qt::ISODate);
+}
+
 } // namespace OPL

+ 23 - 5
src/database/currencyentry.h

@@ -29,23 +29,41 @@ namespace OPL {
  */
 class CurrencyEntry : public Row
 {
-    const static inline QString TABLE_NAME = QStringLiteral("currencies");
 public:
-    CurrencyEntry();
-    CurrencyEntry(const RowData_T &row_data);
+
+    enum Currency {Licence = 1, TypeRating = 2, LineCheck = 3, Medical = 4, Custom1 = 5, Custom2 = 6, TakeOffLanding = 7};
+
+    CurrencyEntry() = delete;
+    CurrencyEntry(const RowData_T &row_data) = delete;
     CurrencyEntry(int row_id, const RowData_T &row_data);
 
     const QString getTableName() const override;
 
+    void setDisplayName(const QString& displayName);
+    const QString getDisplayName() const;
+
+    void setExpiryDate(const QDate &date);
+    const QDate getExpiryDate() const;
+
+
 
+private:
     /*!
     * \brief The sql column name for the expiry date
     */
     const static inline QString EXPIRYDATE  = QStringLiteral("expiryDate");
+
+    /*!
+     * \brief The sql column name for the row id
+     */
+    const static inline QString ROW_ID = QStringLiteral("currency_id");
+
     /*!
-     * \brief The sql column name for the currency name
+     * \brief The sql column name for the display name
      */
-    const static inline QString CURRENCYNAME = QStringLiteral("currencyName");
+    const static inline QString DISPLAY_NAME = QStringLiteral("displayName");
+
+    const static inline QString TABLE_NAME = QStringLiteral("currencies");
 };
 
 } // namespace OPL

+ 3 - 3
src/database/database.h

@@ -277,10 +277,10 @@ public:
     /*!
      * \brief Retreives a currency entry from the database. See row class for details.
      */
-    inline OPL::CurrencyEntry getCurrencyEntry(int row_id)
+    inline OPL::CurrencyEntry getCurrencyEntry(OPL::CurrencyEntry::Currency currency)
     {
-        const auto data = getRowData(OPL::DbTable::Currencies, row_id);
-        return OPL::CurrencyEntry(row_id, data);
+        const auto data = getRowData(OPL::DbTable::Currencies, currency);
+        return OPL::CurrencyEntry(currency, data);
     }
 
     /*!

+ 1 - 1
src/functions/calc.cpp

@@ -343,7 +343,7 @@ void OPL::Calc::updateAutoTimes(int acft_id)
  */
 void OPL::Calc::updateNightTimes()
 {
-    const int night_angle = Settings::read(Settings::FlightLogging::NightAngle).toInt();
+    int night_angle = Settings::getNightAngle();
 
     //find all flights for aircraft
     auto statement = QStringLiteral("SELECT ROWID FROM flights");

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

@@ -56,7 +56,7 @@ void ExportToCsvDialog::selectRows()
     // create a QSqlTableModel based on the selected views
     const auto model = new QSqlTableModel(this);
     if(ui->viewComboBox->currentIndex() < 4)
-        model->setTable(OPL::GLOBALS->getViewIdentifier(OPL::DbViewName(ui->viewComboBox->currentIndex())));
+        model->setTable(OPL::GLOBALS->getViewIdentifier(OPL::LogbookView(ui->viewComboBox->currentIndex())));
     else
         model->setTable(exportView);
     model->select();

+ 34 - 65
src/gui/dialogues/firstrundialog.cpp

@@ -150,7 +150,7 @@ bool FirstRunDialog::finishSetup()
     } // if database file exists
 
     if (!DB->connect()) {
-        QMessageBox message_box(QMessageBox::Critical, tr("Database setup failed"),
+        QMessageBox message_box(QMessageBox::Critical, tr("Database setup failed (connect)"),
                                 tr("Errors have ocurred creating the database."
                                    "Without a working database The application will not be usable.<br>"
                                    "The following error has ocurred:<br>"
@@ -160,7 +160,7 @@ bool FirstRunDialog::finishSetup()
     }
 
     if (!setupDatabase()) {
-        QMessageBox message_box(QMessageBox::Critical, tr("Database setup failed"),
+        QMessageBox message_box(QMessageBox::Critical, tr("Database setup failed (create schema)"),
                                 tr("Errors have ocurred creating the database."
                                    "Without a working database The application will not be usable.<br>"
                                    "The following error has ocurred:<br>%1"
@@ -170,7 +170,7 @@ bool FirstRunDialog::finishSetup()
     }
 
     if (!createUserEntry()) {
-        QMessageBox message_box(QMessageBox::Critical, tr("Database setup failed"),
+        QMessageBox message_box(QMessageBox::Critical, tr("Database setup failed (user entry)"),
                                 tr("Unable to execute database query<br>"
                                    "The following error has occured:<br>%1"
                                    ).arg(DB->lastError.text()));
@@ -179,7 +179,7 @@ bool FirstRunDialog::finishSetup()
     }
 
     if (!setupPreviousExperienceEntry()) {
-        QMessageBox message_box(QMessageBox::Critical, tr("Database setup failed"),
+        QMessageBox message_box(QMessageBox::Critical, tr("Database setup failed (previous Experience)"),
                                 tr("Unable to execute database query<br>"
                                    "The following error has occured:<br>%1"
                                    ).arg(DB->lastError.text()));
@@ -187,14 +187,7 @@ bool FirstRunDialog::finishSetup()
         return false;
     }
 
-    if (!writeCurrencies()) {
-        QMessageBox message_box(QMessageBox::Critical, tr("Database setup failed"),
-                                tr("Unable to execute database query<br>"
-                                   "The following error has occured:<br>%1"
-                                   ).arg(DB->lastError.text()));
-        message_box.exec();
-        return false;
-    }
+    writeCurrencies();
     DB->disconnect(); // Connection will be re-established by MainWindow
     return true;
 }
@@ -274,23 +267,24 @@ bool FirstRunDialog::verifyTemplates()
 void FirstRunDialog::writeSettings()
 {
     Settings::resetToDefaults();
+    Settings::setPilotFunction(OPL::PilotFunction(ui->functionComboBox->currentIndex()));
+    Settings::setApproachType(ui->approachComboBox->currentText());
+    Settings::setNightLoggingEnabled(ui->nightComboBox->currentIndex());
+    Settings::setLogIfr(ui->rulesComboBox->currentIndex());
+    Settings::setFlightNumberPrefix(ui->prefixLineEdit->text());
+    Settings::setLogbookView(OPL::LogbookView(ui->logbookViewComboBox->currentIndex()));
+    Settings::setApplicationStyle(ui->styleComboBox->currentText());
 
-    Settings::write(Settings::FlightLogging::Function, ui->functionComboBox->currentIndex());
-    Settings::write(Settings::FlightLogging::Approach, ui->approachComboBox->currentIndex());
-    Settings::write(Settings::FlightLogging::NightLoggingEnabled, ui->nightComboBox->currentIndex());
     switch (ui->nightRulesComboBox->currentIndex()) {
     case 0:
-        Settings::write(Settings::FlightLogging::NightAngle, -6);
+        Settings::setNightAngle(-6);
         break;
     case 1:
-        Settings::write(Settings::FlightLogging::NightAngle, 0);
+        Settings::setNightAngle(0);
         break;
     }
-    Settings::write(Settings::FlightLogging::LogIFR, ui->rulesComboBox->currentIndex());
-    Settings::write(Settings::FlightLogging::FlightNumberPrefix, ui->prefixLineEdit->text());
-    Settings::write(Settings::UserData::DisplaySelfAs, ui->aliasComboBox->currentIndex());
-    Settings::write(Settings::Main::LogbookView, ui->logbookViewComboBox->currentIndex());
-    Settings::write(Settings::Main::Style, ui->styleComboBox->currentText());
+
+    Settings::setShowSelfAs(ui->aliasComboBox->currentIndex());
     Settings::sync();
 }
 
@@ -350,43 +344,28 @@ bool FirstRunDialog::setupPreviousExperienceEntry()
     return DB->commit(pXpEntry);
 }
 
-bool FirstRunDialog::writeCurrencies()
+void FirstRunDialog::writeCurrencies()
 {
-    const QMap<OPL::CurrencyName, QDateEdit*> currencies_list = {
-        {OPL::CurrencyName::Licence,    ui->currLicDateEdit},
-        {OPL::CurrencyName::TypeRating, ui->currTrDateEdit},
-        {OPL::CurrencyName::LineCheck,  ui->currLckDateEdit},
-        {OPL::CurrencyName::Medical,    ui->currMedDateEdit},
-        {OPL::CurrencyName::Custom1,    ui->currCustom1DateEdit},
-        {OPL::CurrencyName::Custom2,    ui->currCustom2DateEdit},
-    };
-    const QMap<OPL::CurrencyName, Settings::UserData> settings_list = {
-        {OPL::CurrencyName::Licence,    Settings::UserData::ShowLicCurrency },
-        {OPL::CurrencyName::TypeRating, Settings::UserData::ShowTrCurrency },
-        {OPL::CurrencyName::LineCheck,  Settings::UserData::ShowLckCurrency },
-        {OPL::CurrencyName::Medical,    Settings::UserData::ShowMedCurrency },
-        {OPL::CurrencyName::Custom1,    Settings::UserData::ShowCustom1Currency },
-        {OPL::CurrencyName::Custom2,    Settings::UserData::ShowCustom2Currency },
+    const QList<std::tuple<OPL::CurrencyEntry::Currency, const QString&, QDateEdit*>> currencies = {
+        {OPL::CurrencyEntry::Licence,    ui->currLicLabel->text(), 		  ui->currLicDateEdit},
+        {OPL::CurrencyEntry::TypeRating, ui->currTrLabel->text(), 		  ui->currTrDateEdit},
+        {OPL::CurrencyEntry::LineCheck,  ui->currLckLabel->text(),		  ui->currLckDateEdit},
+        {OPL::CurrencyEntry::Medical,    ui->currMedLabel->text(), 		  ui->currMedDateEdit},
+        {OPL::CurrencyEntry::Custom1,    ui->currCustom1LineEdit->text(), ui->currCustom1DateEdit},
+        {OPL::CurrencyEntry::Custom2,    ui->currCustom2LineEdit->text(), ui->currCustom2DateEdit},
     };
 
-    QDate today = QDate::currentDate();
-    for (const auto &date_edit : currencies_list) {
-        const auto enum_value = currencies_list.key(date_edit);
-        // only write dates that have been edited
-        if (date_edit->date() != today) {
-            OPL::RowData_T row_data = {{OPL::CurrencyEntry::EXPIRYDATE, date_edit->date().toString(Qt::ISODate)}};
-            if (enum_value == OPL::CurrencyName::Custom1)
-                row_data.insert(OPL::CurrencyEntry::CURRENCYNAME, ui->currCustom1LineEdit->text());
-            else if(enum_value == OPL::CurrencyName::Custom2)
-                row_data.insert(OPL::CurrencyEntry::CURRENCYNAME, ui->currCustom2LineEdit->text());
-
-            Settings::write(settings_list.value(enum_value), true); // Show selected currency on Home Screen
-            OPL::CurrencyEntry entry(static_cast<int>(enum_value), row_data);
-            if (!DB->commit(entry))
-                return false;
-        }
+    const QDate today = QDate::currentDate();
+
+    for(const auto &tuple : currencies) {
+        OPL::CurrencyEntry currencyEntry = DB->getCurrencyEntry(std::get<0>(tuple));
+        currencyEntry.setDisplayName(std::get<1>(tuple));
+
+        // only set expiry date if user has modified it
+        const QDate date = std::get<2>(tuple)->date();
+        if(date != today)
+            currencyEntry.setExpiryDate(date);
     }
-    return true;
 }
 
 void FirstRunDialog::reject()
@@ -434,16 +413,6 @@ void FirstRunDialog::on_styleComboBox_currentTextChanged(const QString &new_styl
     }
 }
 
-void FirstRunDialog::on_currCustom1LineEdit_editingFinished()
-{
-    Settings::write(Settings::UserData::Custom1CurrencyName, ui->currCustom1LineEdit->text());
-}
-
-void FirstRunDialog::on_currCustom2LineEdit_editingFinished()
-{
-    Settings::write(Settings::UserData::Custom2CurrencyName, ui->currCustom2LineEdit->text());
-}
-
 void FirstRunDialog::on_importPushButton_clicked()
 {
     QString filename = QDir::toNativeSeparators(QFileDialog::getOpenFileName(

+ 2 - 3
src/gui/dialogues/firstrundialog.h

@@ -18,6 +18,7 @@
 #ifndef FIRSTRUNDIALOG_H
 #define FIRSTRUNDIALOG_H
 
+#include "src/database/currencyentry.h"
 #include <QDialog>
 #include <QButtonGroup>
 #include <QMessageBox>
@@ -85,8 +86,6 @@ private slots:
     void on_previousPushButton_clicked();
     void on_nextPushButton_clicked();
     void on_styleComboBox_currentTextChanged(const QString &new_style_setting);
-    void on_currCustom1LineEdit_editingFinished();
-    void on_currCustom2LineEdit_editingFinished();
 
     /*!
      * \brief Import an existing database instead of creating a new one
@@ -125,7 +124,7 @@ private:
     /*!
      * \brief writeCurrencies - submits the user input to the currencies table in the database
      */
-    bool writeCurrencies();
+    void writeCurrencies();
 
     /*!
      * \brief downloadTemplates - Downloads the airports and aircraft database as JSON files from github

+ 117 - 108
src/gui/dialogues/newflightdialog.cpp

@@ -19,6 +19,7 @@
 #include "src/classes/time.h"
 #include "src/database/database.h"
 #include "src/database/databasecache.h"
+#include "src/gui/dialogues/newairportdialog.h"
 #include "src/gui/verification/airportinput.h"
 #include "src/gui/verification/completerprovider.h"
 #include "src/gui/verification/pilotinput.h"
@@ -41,18 +42,8 @@ NewFlightDialog::NewFlightDialog(QWidget *parent)
       ui(new Ui::NewFlightDialog)
 {
     init();
-    // Set up UI (New Flight)
-    LOG << Settings::read(Settings::FlightLogging::Function);
-    if(Settings::read(Settings::FlightLogging::Function).toInt() == static_cast<int>(OPL::PilotFunction::PIC)){
-        ui->picNameLineEdit->setText(self);
-        ui->functionComboBox->setCurrentIndex(0);
-        emit ui->picNameLineEdit->editingFinished();
-    }
-    if (Settings::read(Settings::FlightLogging::Function).toInt() == static_cast<int>(OPL::PilotFunction::SIC)) {
-        ui->sicNameLineEdit->setText(self);
-        ui->functionComboBox->setCurrentIndex(2);
-        emit ui->sicNameLineEdit->editingFinished();
-    }
+    setPilotFunction();
+
     ui->doftLineEdit->setText(OPL::DateTime::currentDate());
     emit ui->doftLineEdit->editingFinished();
 }
@@ -71,6 +62,20 @@ NewFlightDialog::~NewFlightDialog()
     delete ui;
 }
 
+void NewFlightDialog::setPilotFunction()
+{
+    if(Settings::getPilotFunction() == OPL::PilotFunction::PIC){
+        ui->picNameLineEdit->setText(self);
+        ui->functionComboBox->setCurrentIndex(0);
+        emit ui->picNameLineEdit->editingFinished();
+    }
+    if (Settings::getPilotFunction() == OPL::PilotFunction::SIC) {
+        ui->sicNameLineEdit->setText(self);
+        ui->functionComboBox->setCurrentIndex(2);
+        emit ui->sicNameLineEdit->editingFinished();
+    }
+}
+
 void NewFlightDialog::init()
 {
     // Setup UI
@@ -167,10 +172,10 @@ bool NewFlightDialog::eventFilter(QObject *object, QEvent *event)
  */
 void NewFlightDialog::readSettings()
 {
-    ui->functionComboBox->setCurrentIndex(Settings::read(Settings::FlightLogging::Function).toInt());
-    ui->approachComboBox->setCurrentIndex(Settings::read(Settings::FlightLogging::Approach).toInt());
-    ui->flightRulesComboBox->setCurrentIndex(Settings::read(Settings::FlightLogging::LogIFR).toInt());
-    ui->flightNumberLineEdit->setText(Settings::read(Settings::FlightLogging::FlightNumberPrefix).toString());
+    ui->functionComboBox->setCurrentIndex(static_cast<int>(Settings::getPilotFunction()));
+    ui->approachComboBox->setCurrentText(Settings::getApproachType());
+    ui->flightRulesComboBox->setCurrentIndex(Settings::getLogIfr());
+    ui->flightNumberLineEdit->setText(Settings::getFlightNumberPrefix());
 }
 
 /*!
@@ -198,28 +203,20 @@ void NewFlightDialog::fillWithEntryData()
     ui->thirdPilotNameLineEdit->setText(DBCache->getPilotNamesMap().value(flight_data.value(OPL::FlightEntry::THIRDPILOT).toInt()));
 
     //Function
-    const QHash<int, QString> functions = {
-        {0, OPL::FlightEntry::TPIC},
-        {1, OPL::FlightEntry::TPICUS},
-        {2, OPL::FlightEntry::TSIC},
-        {3, OPL::FlightEntry::TDUAL},
-        {4, OPL::FlightEntry::TFI},
-    };
     for (int i = 0; i < 5; i++) { // QHash::iterator not guarenteed to be in ordetr
-        if(flight_data.value(functions.value(i)).toInt() != 0)
+        if(flight_data.value(pilotFuncionsMap.value(i)).toInt() != 0)
             ui->functionComboBox->setCurrentIndex(i);
     }
     // Approach ComboBox
-    const QString& app = flight_data.value(OPL::FlightEntry::APPROACHTYPE).toString();
-    if(app != QString()){
+    const QString app = flight_data.value(OPL::FlightEntry::APPROACHTYPE).toString();
+    if(app != QString()) {
         ui->approachComboBox->setCurrentText(app);
     }
-    // Flight Rules
+    // Flight Rules, check if tIFR > 0
     bool time_ifr = flight_data.value(OPL::FlightEntry::TIFR).toBool();
-    int rulesIndex = time_ifr ? 1 : 0;
-    ui->flightRulesComboBox->setCurrentIndex(rulesIndex);
+    ui->flightRulesComboBox->setCurrentIndex(time_ifr);
     // Take-Off and Landing
-    int takeOffCount =  flight_data.value(OPL::FlightEntry::TODAY).toInt()
+    int takeOffCount = flight_data.value(OPL::FlightEntry::TODAY).toInt()
             + flight_data.value(OPL::FlightEntry::TONIGHT).toInt();
     int landingCount = flight_data.value(OPL::FlightEntry::LDGDAY).toInt()
             + flight_data.value(OPL::FlightEntry::LDGNIGHT).toInt();
@@ -262,7 +259,10 @@ void NewFlightDialog::onGoodInputReceived(QLineEdit *line_edit)
         validationState.validate(mandatoryLineEdits->indexOf(line_edit));
 
     if (validationState.timesValid()) {
-        updateBlockTimeLabel();
+        const OPL::Time tofb = OPL::Time::fromString(ui->tofbTimeLineEdit->text());
+        const OPL::Time tonb = OPL::Time::fromString(ui->tonbTimeLineEdit->text());
+        const OPL::Time tblk = OPL::Time::blockTime(tofb, tonb);
+        ui->tblkDisplayLabel->setText(tblk.toString());
     }
 }
 
@@ -278,81 +278,90 @@ void NewFlightDialog::onBadInputReceived(QLineEdit *line_edit)
     validationState.printValidationStatus();
 }
 
-void NewFlightDialog::updateBlockTimeLabel()
+bool NewFlightDialog::addNewDatabaseElement(QLineEdit *parent, OPL::DbTable table)
 {
-    const OPL::Time tofb = OPL::Time::fromString(ui->tofbTimeLineEdit->text());
-    const OPL::Time tonb = OPL::Time::fromString(ui->tonbTimeLineEdit->text());
-    const OPL::Time tblk = OPL::Time::blockTime(tofb, tonb);
-
-    ui->tblkDisplayLabel->setText(tblk.toString());
-}
+    QDialog *dialog = nullptr;
+    if(userWantsToAddNewEntry(table)) {
+        switch (table) {
+        case OPL::DbTable::Pilots:
+            dialog = new NewPilotDialog(this);
+            break;
+        case OPL::DbTable::Tails:
+            dialog = new NewTailDialog(ui->acftLineEdit->text(), this);
+            break;
+        case OPL::DbTable::Airports:
+            dialog = new NewAirportDialog(this);
+            break;
+        default:
+            return false;
+            break;
+        }
+    } else
+        return false;
 
-/*!
- * \brief NewFlightDialog::addNewTail If the user input is not in the aircraftList, the user
- * is prompted if he wants to add a new entry to the database
- */
-bool NewFlightDialog::addNewTail(QLineEdit& parent_line_edit)
-{
-    QMessageBox::StandardButton reply;
-    reply = QMessageBox::question(this, tr("No Aircraft found"),
-                                  tr("No aircraft with this registration found.<br>"
-                                     "If this is the first time you log a flight with this aircraft, "
-                                     "you have to add the registration to the database first."
-                                     "<br><br>Would you like to add a new aircraft to the database?"),
-                                  QMessageBox::Yes|QMessageBox::No);
-    if (reply == QMessageBox::Yes) {
-        // create and open new aircraft dialog
-        NewTailDialog nt(ui->acftLineEdit->text(), this);
-        int ret = nt.exec();
-        // update map and list, set line edit
-        if (ret == QDialog::Accepted) {
-            DEB << "New Tail Entry added:";
-            DEB << DB->getTailEntry(DB->getLastEntry(OPL::DbTable::Tails));
-
-            // update Line Edit with newly added tail
-            parent_line_edit.setText(DBCache->getTailsMap().value(DB->getLastEntry(OPL::DbTable::Tails)));
-            emit parent_line_edit.editingFinished();
-            return true;
-        } else {
+    // execute the dialog and check for success. Set the line edit to the newly created entry.
+    if(dialog->exec() == QDialog::Accepted) {
+        delete dialog;
+        int latestEntry = DB->getLastEntry(table);
+        switch (table) {
+        case OPL::DbTable::Pilots:
+            parent->setText(DBCache->getPilotNamesMap().value(latestEntry));
+            break;
+        case OPL::DbTable::Tails:
+            parent->setText(DBCache->getTailsMap().value(latestEntry));
+            break;
+        case OPL::DbTable::Airports:
+            parent->setText(DBCache->getAirportsMapICAO().value(latestEntry));
+            break;
+        default:
             return false;
+            break;
         }
     } else {
+        delete dialog;
         return false;
     }
+
+    // re-emit editing finished to trigger input validation
+    emit parent->editingFinished();
+    return true;
 }
 
-/*!
- * \brief NewFlightDialog::addNewPilot If the user input is not in the pilotNameList, the user
- * is prompted if he wants to add a new entry to the database
- */
-bool NewFlightDialog::addNewPilot(QLineEdit& parent_line_edit)
+bool NewFlightDialog::userWantsToAddNewEntry(OPL::DbTable table)
 {
     QMessageBox::StandardButton reply;
-    reply = QMessageBox::question(this, tr("No Pilot found"),
-                                  tr("No pilot found.<br>Please enter the Name as"
-                                     "<br><br><center><b>Lastname, Firstname</b></center><br><br>"
-                                     "If this is the first time you log a flight with this pilot, "
-                                     "you have to add the pilot to the database first."
-                                     "<br><br>Would you like to add a new pilot to the database?"),
-                                  QMessageBox::Yes|QMessageBox::No);
-    if (reply == QMessageBox::Yes) {
-        // create and open new pilot dialog
-        NewPilotDialog np(this);
-        int ret = np.exec();
-        // update map and list, set line edit
-        if (ret == QDialog::Accepted) {
-            DEB << "New Pilot Entry added:";
-            DEB << DB->getPilotEntry(DB->getLastEntry(OPL::DbTable::Pilots));
-
-            // update Line Edit with newly added pilot
-            parent_line_edit.setText(DBCache->getPilotNamesMap().value(DB->getLastEntry(OPL::DbTable::Pilots)));
-            emit parent_line_edit.editingFinished();
-            return true;
-        } else {
-            return false;
-        }
-    } else
-        return false;
+    switch (table) {
+    case OPL::DbTable::Pilots:
+        reply = QMessageBox::question(this, tr("No Pilot found"),
+                                     tr("No pilot found.<br>Please enter the Name as"
+                                        "<br><br><center><b>Lastname, Firstname</b></center><br><br>"
+                                        "If this is the first time you log a flight with this pilot, "
+                                        "you have to add the pilot to the database first."
+                                        "<br><br>Would you like to add a new pilot to the database?"),
+                                     QMessageBox::Yes|QMessageBox::No);
+        break;
+    case OPL::DbTable::Tails:
+        reply = QMessageBox::question(this, tr("No Aircraft found"),
+                                      tr("No aircraft with this registration found.<br>"
+                                         "If this is the first time you log a flight with this aircraft, "
+                                         "you have to add the registration to the database first."
+                                         "<br><br>Would you like to add a new aircraft to the database?"),
+                                      QMessageBox::Yes|QMessageBox::No);
+        break;
+    case OPL::DbTable::Airports:
+        reply = QMessageBox::question(this, tr("No Aircraft found"),
+                                      tr("No aircraft with this registration found.<br>"
+                                         "If this is the first time you log a flight with this aircraft, "
+                                         "you have to add the registration to the database first."
+                                         "<br><br>Would you like to add a new aircraft to the database?"),
+                                      QMessageBox::Yes|QMessageBox::No);
+        break;
+    default:
+        reply = QMessageBox::No;
+        break;
+    }
+
+    return reply == QMessageBox::Yes;
 }
 
 /*!
@@ -375,7 +384,7 @@ OPL::RowData_T NewFlightDialog::prepareFlightEntryData()
 
     QDateTime departure_date_time = OPL::DateTime::fromString(ui->doftLineEdit->text() + ui->tofbTimeLineEdit->text());
     const auto night_time_data = OPL::Calc::NightTimeValues(ui->deptLocationLineEdit->text(), ui->destLocationLineEdit->text(),
-                           departure_date_time, block_minutes, Settings::read(Settings::FlightLogging::NightAngle).toInt());
+                           departure_date_time, block_minutes, Settings::getNightAngle());
     // Mandatory data
     new_data.insert(OPL::FlightEntry::DOFT, ui->doftLineEdit->text());
     new_data.insert(OPL::FlightEntry::DEPT, ui->deptLocationLineEdit->text());
@@ -461,7 +470,7 @@ OPL::RowData_T NewFlightDialog::prepareFlightEntryData()
         new_data.insert(OPL::FlightEntry::AUTOLAND, ui->landingSpinBox->value());
 
     // Pilot flying / Pilot monitoring
-    bool isPilotFlying = toDay + toNight + ldgDay + ldgNight > 0;
+    bool isPilotFlying = toDay + toNight + ldgDay + ldgNight;
     new_data.insert(OPL::FlightEntry::PILOTFLYING, isPilotFlying);
 
     // Additional Data
@@ -493,7 +502,7 @@ void NewFlightDialog::onPilotNameLineEdit_editingFinshed()
 {
     auto line_edit = this->findChild<QLineEdit*>(sender()->objectName());
     if(!verifyUserInput(line_edit, PilotInput(line_edit->text()))) {
-        if(!addNewPilot(*line_edit))
+        if(!addNewDatabaseElement(line_edit, OPL::DbTable::Pilots))
             onBadInputReceived(line_edit);
     }
 }
@@ -514,16 +523,21 @@ void NewFlightDialog::onLocationLineEdit_editingFinished()
         name_label->setText(DBCache->getAirportsMapNames().value(
                                 DBCache->getAirportsMapICAO().key(
                                     line_edit->text())));
-    } else
+    } else {
         name_label->setText("Unknown Airport");
+        addNewDatabaseElement(line_edit, OPL::DbTable::Airports);
+    }
 }
 
 void NewFlightDialog::on_acftLineEdit_editingFinished()
 {
     const auto line_edit = ui->acftLineEdit;
+    if(line_edit->text().isEmpty()){
+        return;
+    }
 
     if(!verifyUserInput(line_edit, TailInput(line_edit->text())))
-        if(!addNewTail(*line_edit))
+        if(!addNewDatabaseElement(line_edit, OPL::DbTable::Tails))
             onBadInputReceived(line_edit);
 
     const auto space = QLatin1Char(' ');
@@ -638,17 +652,12 @@ void NewFlightDialog::on_buttonBox_accepted()
         emit le->editingFinished();
     // If input verification is passed, continue, otherwise prompt user to correct
     if (!validationState.allValid()) {
-        const auto display_names = QHash<ValidationState::ValidationItem, QString> {
-            {ValidationState::ValidationItem::doft, QObject::tr("Date of Flight")},      {ValidationState::ValidationItem::dept, QObject::tr("Departure Airport")},
-            {ValidationState::ValidationItem::dest, QObject::tr("Destination Airport")}, {ValidationState::ValidationItem::tofb, QObject::tr("Time Off Blocks")},
-            {ValidationState::ValidationItem::tonb, QObject::tr("Time on Blocks")},      {ValidationState::ValidationItem::pic, QObject::tr("PIC Name")},
-            {ValidationState::ValidationItem::acft, QObject::tr("Aircraft Registration")}
-        };
+
         QString missing_items;
         for (int i=0; i < mandatoryLineEdits->size(); i++) {
             if (!validationState.validAt(i)){
-                missing_items.append(display_names.value(static_cast<ValidationState::ValidationItem>(i)) + "<br>");
-                mandatoryLineEdits->at(i)->setStyleSheet(QStringLiteral("border: 1px solid red"));
+                missing_items.append(validationItemsDisplayNames.value(static_cast<ValidationState::ValidationItem>(i)) + "<br>");
+                mandatoryLineEdits->at(i)->setStyleSheet(OPL::CssStyles::RED_BORDER);
             }
         }
 

+ 46 - 8
src/gui/dialogues/newflightdialog.h

@@ -88,23 +88,47 @@ private:
     /*!
      * \brief timeLineEdits - Line Edits for time Off Blocks and Time On Blocks
      */
-    static const inline QList<QLineEdit*>* timeLineEdits;
+    static const inline QList<QLineEdit*> *timeLineEdits;
     /*!
      * \brief locationLineEdits - Line Edits for Departure and Destination Airports
      */
-    static const inline QList<QLineEdit*>* locationLineEdits;
+    static const inline QList<QLineEdit*> *locationLineEdits;
     /*!
      * \brief pilotNameLineEdits - Line Edits for Pilot in Command, Second in Command (Co-Pilot) and Third Pilot
      */
-    static const inline QList<QLineEdit*>* pilotNameLineEdits;
+    static const inline QList<QLineEdit*> *pilotNameLineEdits;
     /*!
      * \brief mandatoryLineEdits - Contains the Line Edits that are needed for logging a complete flight from A to B.
      * The list is ordered like the ValidationItem enum so that indexed access is possible using the enum.
      */
-    static const inline QList<QLineEdit*>* mandatoryLineEdits;
+    static const inline QList<QLineEdit*> *mandatoryLineEdits;
     static const inline QLatin1String self = QLatin1String("self");
+    static const inline QHash<int, QString> pilotFuncionsMap = {
+                                           {0, OPL::FlightEntry::TPIC},
+                                           {1, OPL::FlightEntry::TPICUS},
+                                           {2, OPL::FlightEntry::TSIC},
+                                           {3, OPL::FlightEntry::TDUAL},
+                                           {4, OPL::FlightEntry::TFI},
+                                           };
+    static const inline QHash<ValidationState::ValidationItem, QString> validationItemsDisplayNames = {
+        {ValidationState::ValidationItem::doft, QObject::tr("Date of Flight")},
+        {ValidationState::ValidationItem::dept, QObject::tr("Departure Airport")},
+        {ValidationState::ValidationItem::dest, QObject::tr("Destination Airport")},
+        {ValidationState::ValidationItem::tofb, QObject::tr("Time Off Blocks")},
+        {ValidationState::ValidationItem::tonb, QObject::tr("Time on Blocks")},
+        {ValidationState::ValidationItem::pic, QObject::tr("PIC Name")},
+        {ValidationState::ValidationItem::acft, QObject::tr("Aircraft Registration")},
+    };
 
+    /*!
+     * \brief init - set up the UI
+     */
     void init();
+    /*!
+     * \brief setPilotFunction - Reads the application setting and pre-fills the logbook owners
+     * desired function
+     */
+    void setPilotFunction();
     void setupRawInputValidation();
     void setupSignalsAndSlots();
     void readSettings();
@@ -124,11 +148,25 @@ private:
      */
     void onBadInputReceived(QLineEdit *line_edit);
 
-    void updateBlockTimeLabel();
-    void setNightCheckboxes();
+    /*!
+     * \brief addNewDatabaseElement Adds a new element to the database
+     * \param parent - The line edit that triggered the event
+     * \param table - The table to which the new element is added
+     * \return true on success
+     * \details The flights database has a couple of NOT NULL constraints which
+     * must be met before a new flight can be submitted. If the user enters a
+     * constrained field which does not exist in a related table (pilots, tails
+     * or airports), the user is prompted to add a new entry to one of those
+     * tables before proceeding to log a flight with the missing element.
+     */
+    bool addNewDatabaseElement(QLineEdit* parent, OPL::DbTable table);
 
-    bool addNewTail(QLineEdit& parent_line_edit);
-    bool addNewPilot(QLineEdit& parent_line_edit);
+    /*!
+     * \brief userWantsToAddNewEntry - Asks the user if he wants to add a new entry to the database
+     * \param table - The table to which the entry will be committed.
+     * \return true if the reply is QMessageBox::Yes
+     */
+    bool userWantsToAddNewEntry(OPL::DbTable table);
 
 
     bool checkPilotFunctionsValid();

+ 198 - 184
src/gui/dialogues/newflightdialog.ui

@@ -7,15 +7,22 @@
     <x>0</x>
     <y>0</y>
     <width>767</width>
-    <height>362</height>
+    <height>391</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Add New Flight</string>
   </property>
   <layout class="QGridLayout" name="gridLayout">
-   <item row="5" column="5">
-    <widget class="QLineEdit" name="flightNumberLineEdit">
+   <item row="0" column="0">
+    <widget class="QLabel" name="doftLabel">
+     <property name="text">
+      <string>Date of flight</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="doftLineEdit">
      <property name="minimumSize">
       <size>
        <width>160</width>
@@ -28,26 +35,42 @@
        <height>16777215</height>
       </size>
      </property>
+     <property name="placeholderText">
+      <string>YYYY-MM-DD</string>
+     </property>
     </widget>
    </item>
-   <item row="2" column="2">
-    <widget class="QLineEdit" name="deptLocationLineEdit">
+   <item row="0" column="2">
+    <widget class="QLabel" name="doftDisplayLabel">
      <property name="minimumSize">
       <size>
-       <width>160</width>
+       <width>200</width>
        <height>0</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
-       <width>120</width>
+       <width>200</width>
        <height>16777215</height>
       </size>
      </property>
+     <property name="text">
+      <string/>
+     </property>
     </widget>
    </item>
-   <item row="3" column="5">
-    <widget class="QLineEdit" name="sicNameLineEdit">
+   <item row="0" column="3">
+    <widget class="QLabel" name="acftLabel">
+     <property name="text">
+      <string>Aircraft</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="4">
+    <widget class="QLineEdit" name="acftLineEdit">
      <property name="minimumSize">
       <size>
        <width>160</width>
@@ -62,14 +85,30 @@
      </property>
     </widget>
    </item>
-   <item row="7" column="4">
-    <widget class="QLabel" name="takeOffLabel">
+   <item row="1" column="0">
+    <widget class="QLabel" name="deptLabel">
      <property name="text">
-      <string>Take Off</string>
+      <string>Departure</string>
      </property>
     </widget>
    </item>
-   <item row="2" column="3">
+   <item row="1" column="1">
+    <widget class="QLineEdit" name="deptLocationLineEdit">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>120</width>
+       <height>16777215</height>
+      </size>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="2">
     <widget class="QLabel" name="deptNameLabel">
      <property name="enabled">
       <bool>false</bool>
@@ -96,8 +135,18 @@
      </property>
     </widget>
    </item>
-   <item row="1" column="5">
-    <widget class="QLineEdit" name="acftLineEdit">
+   <item row="1" column="3">
+    <widget class="QLabel" name="picLabel">
+     <property name="text">
+      <string>PIC</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="4">
+    <widget class="QLineEdit" name="picNameLineEdit">
      <property name="minimumSize">
       <size>
        <width>160</width>
@@ -112,18 +161,15 @@
      </property>
     </widget>
    </item>
-   <item row="7" column="5">
-    <widget class="QSpinBox" name="takeOffSpinBox"/>
-   </item>
    <item row="2" column="0">
-    <widget class="QLabel" name="deptLabel">
+    <widget class="QLabel" name="destLabel">
      <property name="text">
-      <string>Departure</string>
+      <string>Destination</string>
      </property>
     </widget>
    </item>
-   <item row="4" column="5">
-    <widget class="QLineEdit" name="thirdPilotNameLineEdit">
+   <item row="2" column="1">
+    <widget class="QLineEdit" name="destLocationLineEdit">
      <property name="minimumSize">
       <size>
        <width>160</width>
@@ -138,64 +184,45 @@
      </property>
     </widget>
    </item>
-   <item row="5" column="0">
-    <widget class="QLabel" name="tonbLabel">
-     <property name="text">
-      <string>On Blocks</string>
+   <item row="2" column="2">
+    <widget class="QLabel" name="destNameLabel">
+     <property name="enabled">
+      <bool>false</bool>
      </property>
-    </widget>
-   </item>
-   <item row="3" column="2">
-    <widget class="QLineEdit" name="destLocationLineEdit">
      <property name="minimumSize">
       <size>
-       <width>160</width>
+       <width>200</width>
        <height>0</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
-       <width>120</width>
+       <width>200</width>
        <height>16777215</height>
       </size>
      </property>
-    </widget>
-   </item>
-   <item row="11" column="0">
-    <widget class="QLabel" name="tblkLabel">
-     <property name="text">
-      <string>Total Time</string>
-     </property>
-    </widget>
-   </item>
-   <item row="11" column="2">
-    <widget class="QLabel" name="tblkDisplayLabel">
-     <property name="minimumSize">
-      <size>
-       <width>160</width>
-       <height>0</height>
-      </size>
+     <property name="font">
+      <font>
+       <italic>true</italic>
+      </font>
      </property>
      <property name="text">
-      <string>00:00</string>
+      <string/>
      </property>
     </widget>
    </item>
-   <item row="11" column="4" colspan="2">
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="enabled">
-      <bool>true</bool>
-     </property>
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
+   <item row="2" column="3">
+    <widget class="QLabel" name="sicLabel">
+     <property name="text">
+      <string>SIC</string>
      </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     <property name="alignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
      </property>
     </widget>
    </item>
-   <item row="5" column="2">
-    <widget class="QLineEdit" name="tonbTimeLineEdit">
+   <item row="2" column="4">
+    <widget class="QLineEdit" name="sicNameLineEdit">
      <property name="minimumSize">
       <size>
        <width>160</width>
@@ -211,31 +238,14 @@
     </widget>
    </item>
    <item row="3" column="0">
-    <widget class="QLabel" name="destLabel">
-     <property name="text">
-      <string>Destination</string>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="4">
-    <widget class="QLabel" name="acftLabel">
-     <property name="text">
-      <string>Aircraft</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="0">
     <widget class="QLabel" name="tofbLabel">
      <property name="text">
       <string>Off Blocks</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="2">
-    <widget class="QLineEdit" name="doftLineEdit">
+   <item row="3" column="1">
+    <widget class="QLineEdit" name="tofbTimeLineEdit">
      <property name="minimumSize">
       <size>
        <width>160</width>
@@ -248,12 +258,9 @@
        <height>16777215</height>
       </size>
      </property>
-     <property name="placeholderText">
-      <string>YYYY-MM-DD</string>
-     </property>
     </widget>
    </item>
-   <item row="4" column="3">
+   <item row="3" column="2">
     <widget class="QLabel" name="tofbSpacerLabel">
      <property name="enabled">
       <bool>false</bool>
@@ -275,8 +282,18 @@
      </property>
     </widget>
    </item>
-   <item row="2" column="5">
-    <widget class="QLineEdit" name="picNameLineEdit">
+   <item row="3" column="3">
+    <widget class="QLabel" name="thirdPilotLabel">
+     <property name="text">
+      <string>Third Pilot</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="4">
+    <widget class="QLineEdit" name="thirdPilotNameLineEdit">
      <property name="minimumSize">
       <size>
        <width>160</width>
@@ -291,34 +308,30 @@
      </property>
     </widget>
    </item>
-   <item row="3" column="3">
-    <widget class="QLabel" name="destNameLabel">
-     <property name="enabled">
-      <bool>false</bool>
+   <item row="4" column="0">
+    <widget class="QLabel" name="tonbLabel">
+     <property name="text">
+      <string>On Blocks</string>
      </property>
+    </widget>
+   </item>
+   <item row="4" column="1">
+    <widget class="QLineEdit" name="tonbTimeLineEdit">
      <property name="minimumSize">
       <size>
-       <width>200</width>
+       <width>160</width>
        <height>0</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
-       <width>200</width>
+       <width>120</width>
        <height>16777215</height>
       </size>
      </property>
-     <property name="font">
-      <font>
-       <italic>true</italic>
-      </font>
-     </property>
-     <property name="text">
-      <string/>
-     </property>
     </widget>
    </item>
-   <item row="5" column="3">
+   <item row="4" column="2">
     <widget class="QLabel" name="tonbSpacerLabel">
      <property name="enabled">
       <bool>false</bool>
@@ -340,8 +353,18 @@
      </property>
     </widget>
    </item>
-   <item row="6" column="5">
-    <widget class="QLineEdit" name="remarksLineEdit">
+   <item row="4" column="3">
+    <widget class="QLabel" name="flightNumberLabel">
+     <property name="text">
+      <string>Flight Number</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="4">
+    <widget class="QLineEdit" name="flightNumberLineEdit">
      <property name="minimumSize">
       <size>
        <width>160</width>
@@ -356,79 +379,28 @@
      </property>
     </widget>
    </item>
-   <item row="6" column="4">
-    <widget class="QLabel" name="remarksLabel">
-     <property name="text">
-      <string>Remarks</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-     </property>
-    </widget>
-   </item>
-   <item row="5" column="4">
-    <widget class="QLabel" name="flightNumberLabel">
-     <property name="text">
-      <string>Flight Number</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-     </property>
-    </widget>
-   </item>
-   <item row="2" column="4">
-    <widget class="QLabel" name="picLabel">
-     <property name="text">
-      <string>PIC</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-     </property>
-    </widget>
-   </item>
-   <item row="3" column="4">
-    <widget class="QLabel" name="sicLabel">
+   <item row="5" column="0">
+    <widget class="QLabel" name="functionLabel">
      <property name="text">
-      <string>SIC</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+      <string>Function</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="0">
-    <widget class="QLabel" name="doftLabel">
-     <property name="text">
-      <string>Date of flight</string>
-     </property>
-    </widget>
+   <item row="5" column="1">
+    <widget class="QComboBox" name="functionComboBox"/>
    </item>
-   <item row="4" column="4">
-    <widget class="QLabel" name="thirdPilotLabel">
+   <item row="5" column="3">
+    <widget class="QLabel" name="remarksLabel">
      <property name="text">
-      <string>Third Pilot</string>
+      <string>Remarks</string>
      </property>
      <property name="alignment">
       <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
      </property>
     </widget>
    </item>
-   <item row="6" column="0">
-    <widget class="QLabel" name="functionLabel">
-     <property name="text">
-      <string>Function</string>
-     </property>
-    </widget>
-   </item>
-   <item row="7" column="0">
-    <widget class="QLabel" name="approachLabel">
-     <property name="text">
-      <string>Approach</string>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="2">
-    <widget class="QLineEdit" name="tofbTimeLineEdit">
+   <item row="5" column="4">
+    <widget class="QLineEdit" name="remarksLineEdit">
      <property name="minimumSize">
       <size>
        <width>160</width>
@@ -443,20 +415,34 @@
      </property>
     </widget>
    </item>
-   <item row="8" column="0">
-    <widget class="QLabel" name="flightRulesLabel">
+   <item row="6" column="0">
+    <widget class="QLabel" name="approachLabel">
      <property name="text">
-      <string>Flight Rules</string>
+      <string>Approach</string>
      </property>
     </widget>
    </item>
-   <item row="6" column="2">
-    <widget class="QComboBox" name="functionComboBox"/>
-   </item>
-   <item row="7" column="2">
+   <item row="6" column="1">
     <widget class="QComboBox" name="approachComboBox"/>
    </item>
-   <item row="8" column="2">
+   <item row="6" column="3">
+    <widget class="QLabel" name="takeOffLabel">
+     <property name="text">
+      <string>Take Off</string>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="4">
+    <widget class="QSpinBox" name="takeOffSpinBox"/>
+   </item>
+   <item row="7" column="0">
+    <widget class="QLabel" name="flightRulesLabel">
+     <property name="text">
+      <string>Flight Rules</string>
+     </property>
+    </widget>
+   </item>
+   <item row="7" column="1">
     <widget class="QComboBox" name="flightRulesComboBox">
      <item>
       <property name="text">
@@ -470,36 +456,51 @@
      </item>
     </widget>
    </item>
-   <item row="8" column="4">
+   <item row="7" column="3">
     <widget class="QLabel" name="landingLabel">
      <property name="text">
       <string>Landing</string>
      </property>
     </widget>
    </item>
-   <item row="8" column="5">
+   <item row="7" column="4">
     <widget class="QSpinBox" name="landingSpinBox"/>
    </item>
-   <item row="1" column="3">
-    <widget class="QLabel" name="doftDisplayLabel">
+   <item row="8" column="0">
+    <widget class="QLabel" name="pilotFlyingLabel">
+     <property name="text">
+      <string>Pilot Flying</string>
+     </property>
+    </widget>
+   </item>
+   <item row="8" column="1">
+    <widget class="QCheckBox" name="pilotFlyingCheckBox">
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+   </item>
+   <item row="9" column="0">
+    <widget class="QLabel" name="tblkLabel">
+     <property name="text">
+      <string>Total Time</string>
+     </property>
+    </widget>
+   </item>
+   <item row="9" column="1">
+    <widget class="QLabel" name="tblkDisplayLabel">
      <property name="minimumSize">
       <size>
-       <width>200</width>
+       <width>160</width>
        <height>0</height>
       </size>
      </property>
-     <property name="maximumSize">
-      <size>
-       <width>200</width>
-       <height>16777215</height>
-      </size>
-     </property>
      <property name="text">
-      <string/>
+      <string>00:00</string>
      </property>
     </widget>
    </item>
-   <item row="11" column="3">
+   <item row="9" column="2">
     <widget class="QLabel" name="submissionReadyLabel">
      <property name="minimumSize">
       <size>
@@ -518,6 +519,19 @@
      </property>
     </widget>
    </item>
+   <item row="9" column="3" colspan="2">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="enabled">
+      <bool>true</bool>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <tabstops>

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

@@ -300,6 +300,6 @@ void DebugWidget::on_debug2LineEdit_editingFinished()
 void DebugWidget::on_pushButton_clicked()
 {
     Settings::resetToDefaults();
-    Settings::write(Settings::Main::SetupComplete, false);
+    Settings::setSetupCompleted(false);
 }
 

+ 30 - 36
src/gui/widgets/homewidget.cpp

@@ -39,8 +39,8 @@ HomeWidget::HomeWidget(QWidget *parent) :
 {
     ui->setupUi(this);
     today = QDate::currentDate();
-    ftlWarningThreshold = Settings::read(Settings::UserData::FtlWarningThreshold).toDouble();
-    currWarningThreshold = Settings::read(Settings::UserData::CurrWarningThreshold).toInt();
+    ftlWarningThreshold = Settings::getFtlWarningThreshold();
+    currWarningThreshold = Settings::getCurrencyWarningThreshold();
     auto logo = QPixmap(OPL::Assets::LOGO);
     ui->logoLabel->setPixmap(logo);
     ui->welcomeLabel->setText(tr("Welcome to openPilotLog, %1!").arg(getLogbookOwnerName()));
@@ -52,7 +52,6 @@ HomeWidget::HomeWidget(QWidget *parent) :
         ui->FlightTime12mDisplayLabel
     };
 
-    LOG << "Filling Home Widget...";
     fillTotals();
     fillSelectedCurrencies();
     fillLimitations();
@@ -68,7 +67,6 @@ HomeWidget::~HomeWidget()
 
 void HomeWidget::refresh()
 {
-    LOG << "Updating HomeWidget...";
     const auto label_list = this->findChildren<QLabel *>();
     for (const auto label : label_list)
         label->setVisible(true);
@@ -105,28 +103,28 @@ void HomeWidget::fillTotals()
     ui->totalsStackedWidget->setCurrentWidget(tw);
 }
 
-void HomeWidget::fillCurrency(OPL::CurrencyName currency_name, QLabel* display_label)
+void HomeWidget::fillCurrency(OPL::CurrencyEntry::Currency currency, QLabel* display_label)
 {
-    const auto currency_entry = DB->getCurrencyEntry(static_cast<int>(currency_name));
-
-    if (currency_name == OPL::CurrencyName::Custom1) {
-        ui->currCustom1Label->setText(currency_entry.getData().value(OPL::CurrencyEntry::CURRENCYNAME).toString());
-    } else if (currency_name == OPL::CurrencyName::Custom2) {
-        ui->currCustom2Label->setText(currency_entry.getData().value(OPL::CurrencyEntry::CURRENCYNAME).toString());
-    }
+    const auto currency_entry = DB->getCurrencyEntry(currency);
 
     if (currency_entry.isValid()) {
-        const auto currency_date = QDate::fromString(currency_entry.getData().value(
-                                               OPL::CurrencyEntry::EXPIRYDATE).toString(),
-                                               Qt::ISODate);
-        display_label->setText(currency_date.toString(Qt::TextDate));
+        // set label for custom currencies
+        if (currency == OPL::CurrencyEntry::Custom1) {
+            ui->currCustom1Label->setText(currency_entry.getDisplayName());
+        } else if (currency == OPL::CurrencyEntry::Custom2) {
+            ui->currCustom2Label->setText(currency_entry.getDisplayName());
+        }
+        // get date and set visible
+        const QDate date = currency_entry.getExpiryDate();
+        display_label->setText(date.toString(Qt::ISODate));
         setLabelColour(display_label, Colour::None);
 
-        if (today >= currency_date) { // is expired
+        if (today >= date) {
+            // currency is expired
             setLabelColour(display_label, Colour::Red);
             return;
-        } else if (today.addDays(currWarningThreshold) >=currency_date) { // expires less than <currWarningThreshold> days from current Date
-
+        } else if (today.addDays(currWarningThreshold) >= date) {
+            // currency expires less than <currWarningThreshold> days from current Date
             setLabelColour(display_label, Colour::Orange);
         }
     } else {
@@ -142,26 +140,23 @@ void HomeWidget::fillSelectedCurrencies()
 {
     fillCurrencyTakeOffLanding();
 
-    Settings::read(Settings::UserData::ShowLicCurrency).toBool() ?
-                fillCurrency(OPL::CurrencyName::Licence, ui->currLicDisplayLabel)
+    Settings::getShowCurrency(OPL::CurrencyEntry::Licence) ?
+                fillCurrency(OPL::CurrencyEntry::Licence, ui->currLicDisplayLabel)
               : hideLabels(ui->currLicLabel, ui->currLicDisplayLabel);
-    Settings::read(Settings::UserData::ShowTrCurrency).toBool() ?
-                fillCurrency(OPL::CurrencyName::TypeRating, ui->currTrDisplayLabel)
+    Settings::getShowCurrency(OPL::CurrencyEntry::TypeRating) ?
+                fillCurrency(OPL::CurrencyEntry::TypeRating, ui->currTrDisplayLabel)
               : hideLabels(ui->currTrLabel, ui->currTrDisplayLabel);
-    Settings::read(Settings::UserData::ShowLckCurrency).toBool() ?
-                fillCurrency(OPL::CurrencyName::LineCheck, ui->currLckDisplayLabel)
+    Settings::getShowCurrency(OPL::CurrencyEntry::LineCheck) ?
+                fillCurrency(OPL::CurrencyEntry::LineCheck, ui->currLckDisplayLabel)
               : hideLabels(ui->currLckLabel, ui->currLckDisplayLabel);
-    Settings::read(Settings::UserData::ShowMedCurrency).toBool() ?
-                fillCurrency(OPL::CurrencyName::Medical, ui->currMedDisplayLabel)
+    Settings::getShowCurrency(OPL::CurrencyEntry::Medical) ?
+                fillCurrency(OPL::CurrencyEntry::Medical, ui->currMedDisplayLabel)
               : hideLabels(ui->currMedLabel, ui->currMedDisplayLabel);
-    Settings::read(Settings::UserData::ShowCustom1Currency).toBool() ?
-                fillCurrency(OPL::CurrencyName::Custom1, ui->currCustom1DisplayLabel)
-              : hideLabels(ui->currCustom1Label, ui->currCustom1DisplayLabel);
-    Settings::read(Settings::UserData::ShowCustom1Currency).toBool() ?
-                fillCurrency(OPL::CurrencyName::Custom1, ui->currCustom1DisplayLabel)
+    Settings::getShowCurrency(OPL::CurrencyEntry::Custom1) ?
+                fillCurrency(OPL::CurrencyEntry::Custom1, ui->currCustom1DisplayLabel)
               : hideLabels(ui->currCustom1Label, ui->currCustom1DisplayLabel);
-    Settings::read(Settings::UserData::ShowCustom2Currency).toBool() ?
-                fillCurrency(OPL::CurrencyName::Custom2, ui->currCustom2DisplayLabel)
+    Settings::getShowCurrency(OPL::CurrencyEntry::Custom2) ?
+                fillCurrency(OPL::CurrencyEntry::Custom2, ui->currCustom2DisplayLabel)
               : hideLabels(ui->currCustom2Label, ui->currCustom2DisplayLabel);
 }
 
@@ -183,7 +178,7 @@ void HomeWidget::fillCurrencyTakeOffLanding()
     if (takeoff_landings[1].toUInt() < 3)
         setLabelColour(ui->LandingsDisplayLabel, Colour::Red);
 
-    if (Settings::read(Settings::UserData::ShowToLgdCurrency).toBool()) {
+    if (Settings::getShowCurrency(OPL::CurrencyEntry::TakeOffLanding)) {
         QDate expiration_date = OPL::Statistics::currencyTakeOffLandingExpiry();
         if (expiration_date <= QDate::currentDate())
             setLabelColour(ui->currToLdgDisplayLabel, Colour::Red);
@@ -232,6 +227,5 @@ const QString HomeWidget::getLogbookOwnerName()
     if(name.isEmpty()) {
         name = owner.getLastName();
     }
-    DEB << "owner name: " << name;
     return name;
 }

+ 1 - 1
src/gui/widgets/homewidget.h

@@ -64,7 +64,7 @@ private:
     void fillTotals();
     void fillSelectedCurrencies();
     void fillCurrencyTakeOffLanding();
-    void fillCurrency(OPL::CurrencyName currency_name, QLabel *display_label);
+    void fillCurrency(OPL::CurrencyEntry::Currency currency, QLabel *display_label);
     void fillLimitations();
 
     enum class Colour {Red, Orange, None};

+ 8 - 6
src/gui/widgets/logbookwidget.cpp

@@ -42,7 +42,8 @@ LogbookWidget::LogbookWidget(QWidget *parent) :
     displayModel = new QSqlTableModel(this);
     view = ui->tableView;
 
-    setupModelAndView(Settings::read(Settings::Main::LogbookView).toInt());
+    setupModelAndView(Settings::getLogbookView());
+//    setupModelAndView(Settings::read(Settings::Main::LogbookView).toInt());
     connectSignalsAndSlots();
 
 }
@@ -61,9 +62,10 @@ LogbookWidget::~LogbookWidget()
  * according to the current view.
  * \param view_id - retreived from Settings::Main::LogbookView
  */
-void LogbookWidget::setupModelAndView(int view_id)
+void LogbookWidget::setupModelAndView(OPL::LogbookView logbookView)
 {
-    displayModel->setTable(OPL::GLOBALS->getViewIdentifier(OPL::DbViewName(view_id)));
+    int view_id = static_cast<int>(logbookView);
+    displayModel->setTable(OPL::GLOBALS->getViewIdentifier(OPL::LogbookView(view_id)));
     displayModel->select();
 
     view->setModel(displayModel);
@@ -228,7 +230,7 @@ void LogbookWidget::refresh()
 void LogbookWidget::onLogbookWidget_viewSelectionChanged(SettingsWidget::SettingSignal signal)
 {
     if (signal == SettingsWidget::SettingSignal::LogbookWidget)
-        setupModelAndView(Settings::read(Settings::Main::LogbookView).toInt());
+        setupModelAndView(Settings::getLogbookView());
 }
 
 //void LogbookWidget::on_showAllButton_clicked()
@@ -277,13 +279,13 @@ void LogbookWidget::repopulateModel()
     delete displayModel;
     // create a new model and populate it
     displayModel = new QSqlTableModel(this);
-    setupModelAndView(Settings::read(Settings::Main::LogbookView).toInt());
+    setupModelAndView(Settings::getLogbookView());
     connectSignalsAndSlots();
 }
 
 void LogbookWidget::on_viewsComboBox_currentIndexChanged(int index)
 {
-    setupModelAndView(index);
+    setupModelAndView(OPL::LogbookView(index));
 }
 
 void LogbookWidget::on_actionEdit_Flight_triggered()

+ 1 - 1
src/gui/widgets/logbookwidget.h

@@ -83,7 +83,7 @@ private:
 
     QList<int> selectedEntries;
 
-    void setupModelAndView(int view_id);
+    void setupModelAndView(OPL::LogbookView logbookView);
     void connectSignalsAndSlots();
 
     const QString getFlightSummary(const OPL::FlightEntry &flight) const;

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

@@ -59,7 +59,7 @@ void PilotsWidget::setupModelAndView()
     view->verticalHeader()->hide();
     view->setAlternatingRowColors(true);
     view->setSortingEnabled(true);
-    sortColumn = Settings::read(Settings::UserData::PilotSortColumn).toInt();
+    sortColumn = Settings::getPilotSortColumn();
     view->sortByColumn(sortColumn, Qt::AscendingOrder);
 
     view->show();
@@ -138,8 +138,7 @@ void PilotsWidget::tableView_selectionChanged()
 
 void PilotsWidget::tableView_headerClicked(int column)
 {
-    sortColumn = column;
-    Settings::write(Settings::UserData::PilotSortColumn, column);
+    Settings::setPilotSortColumn(column);
 }
 
 void PilotsWidget::on_newPilotButton_clicked()

+ 93 - 107
src/gui/widgets/settingswidget.cpp

@@ -69,29 +69,25 @@ void SettingsWidget::setupComboBoxes(){
 void SettingsWidget::setupDateEdits()
 {
     // Read Display Format Setting
-    int date_format_index = Settings::read(Settings::Main::DateFormat).toInt();
-    const QString date_format_string = OPL::DateTime::getFormatString(
-                static_cast<OPL::DateFormat>(date_format_index));
+    const QString dateFormatString = OPL::DateTime::getFormatString(Settings::getDateFormat());
     const auto date_edits = this->findChildren<QDateEdit*>();
     for (const auto &date_edit : date_edits) {
-        date_edit->setDisplayFormat(date_format_string);
+        date_edit->setDisplayFormat(dateFormatString);
     }
     // Fill currencies
-    const QList<QPair<OPL::CurrencyName, QDateEdit*>> currencies_list = {
-        {OPL::CurrencyName::Licence,    ui->currLicDateEdit},
-        {OPL::CurrencyName::TypeRating, ui->currTrDateEdit},
-        {OPL::CurrencyName::LineCheck,  ui->currLckDateEdit},
-        {OPL::CurrencyName::Medical,    ui->currMedDateEdit},
-        {OPL::CurrencyName::Custom1,    ui->currCustom1DateEdit},
-        {OPL::CurrencyName::Custom2,    ui->currCustom2DateEdit},
+    const QList<QPair<OPL::CurrencyEntry::Currency, QDateEdit*>> currencies_list = {
+        {OPL::CurrencyEntry::Licence,    ui->currLicDateEdit},
+        {OPL::CurrencyEntry::TypeRating, ui->currTrDateEdit},
+        {OPL::CurrencyEntry::LineCheck,  ui->currLckDateEdit},
+        {OPL::CurrencyEntry::Medical,    ui->currMedDateEdit},
+        {OPL::CurrencyEntry::Custom1,    ui->currCustom1DateEdit},
+        {OPL::CurrencyEntry::Custom2,    ui->currCustom2DateEdit},
     };
     for (const auto &pair : currencies_list) {
         const QSignalBlocker signal_blocker(pair.second);
-        const auto entry = DB->getCurrencyEntry(static_cast<int>(pair.first));
+        const auto entry = DB->getCurrencyEntry(pair.first);
         if (entry.isValid()) { // set date
-            const auto date = QDate::fromString(
-                entry.getData().value(OPL::CurrencyEntry::EXPIRYDATE).toString(),
-                        Qt::ISODate);
+            const auto date = entry.getExpiryDate();
             if(date.isValid())
                 pair.second->setDate(date);
         } else { // set current date
@@ -135,29 +131,29 @@ void SettingsWidget::readSettings()
     ui->emailLineEdit->setText(user_data.value(OPL::PilotEntry::EMAIL).toString());
 
     // FLight Logging Tab
-    ui->functionComboBox->setCurrentIndex(Settings::read(Settings::FlightLogging::Function).toInt());
-    ui->rulesComboBox->setCurrentIndex(Settings::read(Settings::FlightLogging::LogIFR).toInt());
-    ui->approachComboBox->setCurrentIndex(Settings::read(Settings::FlightLogging::Approach).toInt());
-    ui->nightComboBox->setCurrentIndex(Settings::read(Settings::FlightLogging::NightLoggingEnabled).toInt());
-    ui->prefixLineEdit->setText(Settings::read(Settings::FlightLogging::FlightNumberPrefix).toString());
+    ui->functionComboBox->setCurrentIndex(static_cast<int>(Settings::getPilotFunction()));
+    ui->rulesComboBox->setCurrentIndex(Settings::getLogIfr());
+    ui->approachComboBox->setCurrentText(Settings::getApproachType());
+    ui->nightComboBox->setCurrentIndex(Settings::getNightLoggingEnabled());
+    ui->prefixLineEdit->setText(Settings::getFlightNumberPrefix());
 
-    ui->logbookViewComboBox->setCurrentIndex(Settings::read(Settings::Main::LogbookView).toInt());
-    ui->aliasComboBox->setCurrentIndex(Settings::read(Settings::UserData::DisplaySelfAs).toInt());
+    ui->logbookViewComboBox->setCurrentIndex(static_cast<int>(Settings::getLogbookView()));
+    ui->aliasComboBox->setCurrentIndex(Settings::getShowSelfAs());
 
     // Currencies Tab
-    ui->currToLdgCheckBox->setChecked(Settings::read(Settings::UserData::ShowToLgdCurrency).toBool());
-    ui->currLicCheckBox->setChecked(Settings::read(Settings::UserData::ShowLicCurrency).toBool());
-    ui->currTrCheckBox->setChecked(Settings::read(Settings::UserData::ShowTrCurrency).toBool());
-    ui->currLckCheckBox->setChecked(Settings::read(Settings::UserData::ShowLckCurrency).toBool());
-    ui->currMedCheckBox->setChecked(Settings::read(Settings::UserData::ShowMedCurrency).toBool());
-    ui->currCustom1CheckBox->setChecked(Settings::read(Settings::UserData::ShowCustom1Currency).toBool());
-    ui->currCustom2CheckBox->setChecked(Settings::read(Settings::UserData::ShowCustom2Currency).toBool());
-    ui->currCustom1LineEdit->setText(Settings::read(Settings::UserData::Custom1CurrencyName).toString());
-    ui->currCustom2LineEdit->setText(Settings::read(Settings::UserData::Custom2CurrencyName).toString());
-
+    ui->currToLdgCheckBox->setChecked(Settings::getShowCurrency(OPL::CurrencyEntry::TakeOffLanding));
+    ui->currLicCheckBox->setChecked(Settings::getShowCurrency(OPL::CurrencyEntry::LineCheck));
+    ui->currTrCheckBox->setChecked(Settings::getShowCurrency(OPL::CurrencyEntry::TypeRating));
+    ui->currLckCheckBox->setChecked(Settings::getShowCurrency(OPL::CurrencyEntry::TypeRating));
+    ui->currMedCheckBox->setChecked(Settings::getShowCurrency(OPL::CurrencyEntry::Medical));
+    ui->currCustom1CheckBox->setChecked(Settings::getShowCurrency(OPL::CurrencyEntry::Custom1));
+    ui->currCustom2CheckBox->setChecked(Settings::getShowCurrency(OPL::CurrencyEntry::Custom2));
+
+    ui->currCustom1LineEdit->setText(DB->getCurrencyEntry(OPL::CurrencyEntry::Custom1).getDisplayName());
+    ui->currCustom2LineEdit->setText(DB->getCurrencyEntry(OPL::CurrencyEntry::Custom2).getDisplayName());
     // Misc Tab
-    ui->acftSortComboBox->setCurrentIndex(Settings::read(Settings::UserData::TailSortColumn).toInt());
-    ui->pilotSortComboBox->setCurrentIndex(Settings::read(Settings::UserData::PilotSortColumn).toInt());
+    ui->acftSortComboBox->setCurrentIndex(Settings::getTailSortColumn());
+    ui->pilotSortComboBox->setCurrentIndex(Settings::getPilotSortColumn());
 
     // Don't emit signals for OPL::Style changes during setup
     const QSignalBlocker style_blocker(ui->styleComboBox);
@@ -165,10 +161,10 @@ void SettingsWidget::readSettings()
     const QSignalBlocker font_blocker_2(ui->fontComboBox);
     const QSignalBlocker font_blocker_3(ui->fontCheckBox);
 
-    ui->styleComboBox->setCurrentText(Settings::read(Settings::Main::Style).toString());
-    ui->fontSpinBox->setValue(Settings::read(Settings::Main::FontSize).toUInt());
-    ui->fontComboBox->setCurrentFont(QFont(Settings::read(Settings::Main::Font).toString()));
-    bool use_system_font = Settings::read(Settings::Main::UseSystemFont).toBool();
+    ui->styleComboBox->setCurrentText(Settings::getApplicationStyle());
+    ui->fontSpinBox->setValue(Settings::getApplicationFontSize());
+    ui->fontComboBox->setCurrentFont(QFont(Settings::getApplicationFontName()));
+    bool use_system_font = Settings::getUseSystemFont();
     ui->fontCheckBox->setChecked(use_system_font);
     if (!use_system_font) {
         ui->fontComboBox->setEnabled(true);
@@ -262,44 +258,43 @@ void SettingsWidget::on_phoneLineEdit_editingFinished()
 
 void SettingsWidget::on_aliasComboBox_currentIndexChanged(int index)
 {
-    Settings::write(Settings::UserData::DisplaySelfAs, index);
+    Settings::setShowSelfAs(index);
     updatePersonalDetails();
 }
 
 void SettingsWidget::on_functionComboBox_currentIndexChanged(int arg1)
 {
-    Settings::write(Settings::FlightLogging::Function, arg1);
+    Settings::setPilotFunction(OPL::PilotFunction(arg1));
 }
 
 void SettingsWidget::on_rulesComboBox_currentIndexChanged(int arg1)
 {
-    Settings::write(Settings::FlightLogging::LogIFR, arg1);
+    Settings::setLogIfr(arg1);
 }
 
 void SettingsWidget::on_approachComboBox_currentIndexChanged(int arg1)
 {
-    Settings::write(Settings::FlightLogging::Approach, arg1);
+    Settings::setApproachType(ui->approachComboBox->currentText());
 }
 
 void SettingsWidget::on_nightComboBox_currentIndexChanged(int index)
 {
-    Settings::write(Settings::FlightLogging::NightLoggingEnabled, index);
+    Settings::setNightLoggingEnabled(index);
     switch (index) {
     case 1:
-        Settings::write(Settings::FlightLogging::NightAngle, -6);
+        Settings::setNightAngle(-6);
         break;
     case 2:
-        Settings::write(Settings::FlightLogging::NightAngle, 0);
+        Settings::setNightAngle(0);
         break;
     default:
-        Settings::write(Settings::FlightLogging::NightAngle, -6);
+        Settings::setNightAngle(-6);
     }
 }
 
 void SettingsWidget::on_prefixLineEdit_textChanged(const QString &arg1)
 {
-    Settings::write(Settings::FlightLogging::FlightNumberPrefix, arg1);
-
+    Settings::setFlightNumberPrefix(arg1);
 }
 
 /*
@@ -308,18 +303,19 @@ void SettingsWidget::on_prefixLineEdit_textChanged(const QString &arg1)
 
 void SettingsWidget::on_logbookViewComboBox_currentIndexChanged(int index)
 {
-    Settings::write(Settings::Main::LogbookView, index);
+//    Settings::write(Settings::Main::LogbookView, index);
+    Settings::setLogbookView(OPL::LogbookView(index));
     emit settingChanged(SettingSignal::LogbookWidget);
 }
 void SettingsWidget::on_pilotSortComboBox_currentIndexChanged(int index)
 {
-    Settings::write(Settings::UserData::PilotSortColumn, index);
+    Settings::setPilotSortColumn(index);
     emit settingChanged(PilotsWidget);
 }
 
 void SettingsWidget::on_acftSortComboBox_currentIndexChanged(int index)
 {
-    Settings::write(Settings::UserData::TailSortColumn, index);
+    Settings::setTailSortColumn(index);
     emit settingChanged(AircraftWidget);
 }
 
@@ -404,14 +400,16 @@ void SettingsWidget::on_styleComboBox_currentTextChanged(const QString& new_styl
 {
     if (new_style_setting == QLatin1String("Dark-Palette")) {
         OPL::Style::setStyle(OPL::Style::darkPalette());
-        Settings::write(Settings::Main::Style, new_style_setting);
+//        Settings::write(Settings::Main::Style, new_style_setting);
+        Settings::setApplicationStyle(new_style_setting);
         emit settingChanged(MainWindow);
         return;
     }
     for (const auto &style_name : OPL::Style::styles) {
         if (new_style_setting == style_name) {
             OPL::Style::setStyle(style_name);
-            Settings::write(Settings::Main::Style, new_style_setting);
+//            Settings::write(Settings::Main::Style, new_style_setting);
+            Settings::setApplicationStyle(style_name);
             emit settingChanged(MainWindow);
             return;
         }
@@ -420,7 +418,8 @@ void SettingsWidget::on_styleComboBox_currentTextChanged(const QString& new_styl
     for (const auto &style_sheet : OPL::Style::styleSheets) {
         if (new_style_setting == style_sheet.styleSheetName) {
             OPL::Style::setStyle(style_sheet);
-            Settings::write(Settings::Main::Style, new_style_setting);
+//            Settings::write(Settings::Main::Style, new_style_setting);
+            Settings::setApplicationStyle(new_style_setting);
             emit settingChanged(MainWindow);
             return;
         }
@@ -430,7 +429,8 @@ void SettingsWidget::on_styleComboBox_currentTextChanged(const QString& new_styl
 void SettingsWidget::on_fontComboBox_currentFontChanged(const QFont &f)
 {
     qApp->setFont(f);
-    Settings::write(Settings::Main::Font, f.toString());
+//    Settings::write(Settings::Main::Font, f.toString());
+    Settings::setApplicationFontName(f.toString());
     DEB << "Setting Font:" << f.toString();
 }
 
@@ -439,7 +439,8 @@ void SettingsWidget::on_fontSpinBox_valueChanged(int arg1)
     QFont f = qApp->font();
     f.setPointSize(arg1);
     qApp->setFont(f);
-    Settings::write(Settings::Main::FontSize, arg1);
+//    Settings::write(Settings::Main::FontSize, arg1);
+    Settings::setApplicationFontSize(arg1);
     DEB << "Setting Font:" << f.toString();
 }
 
@@ -455,7 +456,8 @@ void SettingsWidget::on_fontCheckBox_stateChanged(int arg1)
     {
         ui->fontComboBox->setEnabled(true);
         ui->fontSpinBox->setEnabled(true);
-        Settings::write(Settings::Main::UseSystemFont, false);
+//        Settings::write(Settings::Main::UseSystemFont, false);
+        Settings::setUseSystemFont(false);
         QFont font(ui->fontComboBox->currentFont());
         font.setPointSize(ui->fontSpinBox->value());
         qApp->setFont(font);
@@ -466,7 +468,8 @@ void SettingsWidget::on_fontCheckBox_stateChanged(int arg1)
     {
         ui->fontComboBox->setEnabled(false);
         ui->fontSpinBox->setEnabled(false);
-        Settings::write(Settings::Main::UseSystemFont, true);
+//        Settings::write(Settings::Main::UseSystemFont, true);
+        Settings::setUseSystemFont(true);
         INFO(tr("The application will be restarted for this change to take effect."));
         qApp->quit();
         QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
@@ -498,64 +501,43 @@ void SettingsWidget::on_resetStylePushButton_clicked()
 
 void SettingsWidget::on_currLicDateEdit_userDateChanged(const QDate &date)
 {
-    const OPL::RowData_T row_data = {{OPL::CurrencyEntry::EXPIRYDATE, date.toString(Qt::ISODate)}};
-    const OPL::CurrencyEntry entry(static_cast<int>(OPL::CurrencyName::Licence), row_data);
-    if (!DB->commit(entry))
-        WARN(tr("Unable to update currency. The following error has ocurred:<br>%1").arg(DB->lastError.text()));
-
+    auto entry = DB->getCurrencyEntry(OPL::CurrencyEntry::Licence);
+    entry.setExpiryDate(date);
     emit settingChanged(HomeWidget);
 }
 
 void SettingsWidget::on_currTrDateEdit_userDateChanged(const QDate &date)
 {
-    const OPL::RowData_T row_data = {{OPL::CurrencyEntry::EXPIRYDATE, date.toString(Qt::ISODate)}};
-    const OPL::CurrencyEntry entry(static_cast<int>(OPL::CurrencyName::TypeRating), row_data);
-    if (!DB->commit(entry))
-        WARN(tr("Unable to update currency. The following error has ocurred:<br>%1").arg(DB->lastError.text()));
-
+    auto entry = DB->getCurrencyEntry(OPL::CurrencyEntry::TypeRating);
+    entry.setExpiryDate(date);
     emit settingChanged(HomeWidget);
 }
 
 void SettingsWidget::on_currLckDateEdit_userDateChanged(const QDate &date)
 {
-    const OPL::RowData_T row_data = {{OPL::CurrencyEntry::EXPIRYDATE, date.toString(Qt::ISODate)}};
-    const OPL::CurrencyEntry entry(static_cast<int>(OPL::CurrencyName::LineCheck), row_data);
-    if (!DB->commit(entry))
-        WARN(tr("Unable to update currency. The following error has ocurred:<br>%1").arg(DB->lastError.text()));
-
+    auto entry = DB->getCurrencyEntry(OPL::CurrencyEntry::LineCheck);
+    entry.setExpiryDate(date);
     emit settingChanged(HomeWidget);
 }
 
 void SettingsWidget::on_currMedDateEdit_userDateChanged(const QDate &date)
 {
-    const OPL::RowData_T row_data = {{OPL::CurrencyEntry::EXPIRYDATE, date.toString(Qt::ISODate)}};
-    const OPL::CurrencyEntry entry(static_cast<int>(OPL::CurrencyName::Medical), row_data);
-    if (!DB->commit(entry))
-        WARN(tr("Unable to update currency. The following error has ocurred:<br>%1").arg(DB->lastError.text()));
-
+    auto entry = DB->getCurrencyEntry(OPL::CurrencyEntry::Medical);
+    entry.setExpiryDate(date);
     emit settingChanged(HomeWidget);
 }
 
 void SettingsWidget::on_currCustom1DateEdit_userDateChanged(const QDate &date)
 {
-    const OPL::RowData_T row_data = {{OPL::CurrencyEntry::EXPIRYDATE, date.toString(Qt::ISODate)},
-                                {OPL::CurrencyEntry::CURRENCYNAME, ui->currCustom1LineEdit->text()}};
-    const OPL::CurrencyEntry entry(static_cast<int>(OPL::CurrencyName::Custom1), row_data);
-    DEB << entry;
-    if (!DB->commit(entry))
-        WARN(tr("Unable to update currency. The following error has ocurred:<br><br>%1").arg(DB->lastError.text()));
-
+    auto entry = DB->getCurrencyEntry(OPL::CurrencyEntry::Custom1);
+    entry.setExpiryDate(date);
     emit settingChanged(HomeWidget);
 }
 
 void SettingsWidget::on_currCustom2DateEdit_userDateChanged(const QDate &date)
 {
-    const OPL::RowData_T row_data = {{OPL::CurrencyEntry::EXPIRYDATE, date.toString(Qt::ISODate)},
-                                {OPL::CurrencyEntry::CURRENCYNAME, ui->currCustom2LineEdit->text()}};
-    const OPL::CurrencyEntry entry(static_cast<int>(OPL::CurrencyName::Custom2), row_data);
-    if (!DB->commit(entry))
-        WARN(tr("Unable to update currency. The following error has ocurred:<br><br>%1").arg(DB->lastError.text()));
-
+    auto entry = DB->getCurrencyEntry(OPL::CurrencyEntry::Custom2);
+    entry.setExpiryDate(date);
     emit settingChanged(HomeWidget);
 }
 
@@ -563,10 +545,10 @@ void SettingsWidget::on_currToLdgCheckBox_stateChanged(int arg1)
 {
     switch (arg1) {
     case Qt::CheckState::Checked:
-        Settings::write(Settings::UserData::ShowToLgdCurrency, true);
+        Settings::setShowCurrency(OPL::CurrencyEntry::TakeOffLanding, true);
         break;
     case Qt::CheckState::Unchecked:
-        Settings::write(Settings::UserData::ShowToLgdCurrency, false);
+        Settings::setShowCurrency(OPL::CurrencyEntry::TakeOffLanding, false);
         break;
     default:
         break;
@@ -578,10 +560,10 @@ void SettingsWidget::on_currLicCheckBox_stateChanged(int arg1)
 {
     switch (arg1) {
     case Qt::CheckState::Checked:
-        Settings::write(Settings::UserData::ShowLicCurrency, true);
+        Settings::setShowCurrency(OPL::CurrencyEntry::Licence, true);
         break;
     case Qt::CheckState::Unchecked:
-        Settings::write(Settings::UserData::ShowLicCurrency, false);
+        Settings::setShowCurrency(OPL::CurrencyEntry::Licence, false);
         break;
     default:
         break;
@@ -593,10 +575,10 @@ void SettingsWidget::on_currTrCheckBox_stateChanged(int arg1)
 {
     switch (arg1) {
     case Qt::CheckState::Checked:
-        Settings::write(Settings::UserData::ShowTrCurrency, true);
+        Settings::setShowCurrency(OPL::CurrencyEntry::TypeRating, true);
         break;
     case Qt::CheckState::Unchecked:
-        Settings::write(Settings::UserData::ShowTrCurrency, false);
+        Settings::setShowCurrency(OPL::CurrencyEntry::TypeRating, false);
         break;
     default:
         break;
@@ -608,10 +590,10 @@ void SettingsWidget::on_currLckCheckBox_stateChanged(int arg1)
 {
     switch (arg1) {
     case Qt::CheckState::Checked:
-        Settings::write(Settings::UserData::ShowLckCurrency, true);
+        Settings::setShowCurrency(OPL::CurrencyEntry::LineCheck, true);
         break;
     case Qt::CheckState::Unchecked:
-        Settings::write(Settings::UserData::ShowLckCurrency, false);
+        Settings::setShowCurrency(OPL::CurrencyEntry::LineCheck, false);
         break;
     default:
         break;
@@ -623,10 +605,10 @@ void SettingsWidget::on_currMedCheckBox_stateChanged(int arg1)
 {
     switch (arg1) {
     case Qt::CheckState::Checked:
-        Settings::write(Settings::UserData::ShowMedCurrency, true);
+        Settings::setShowCurrency(OPL::CurrencyEntry::Medical, true);
         break;
     case Qt::CheckState::Unchecked:
-        Settings::write(Settings::UserData::ShowMedCurrency, false);
+        Settings::setShowCurrency(OPL::CurrencyEntry::Medical, false);
         break;
     default:
         break;
@@ -638,10 +620,10 @@ void SettingsWidget::on_currCustom1CheckBox_stateChanged(int arg1)
 {
     switch (arg1) {
     case Qt::CheckState::Checked:
-        Settings::write(Settings::UserData::ShowCustom1Currency, true);
+        Settings::setShowCurrency(OPL::CurrencyEntry::Custom1, true);
         break;
     case Qt::CheckState::Unchecked:
-        Settings::write(Settings::UserData::ShowCustom1Currency, false);
+        Settings::setShowCurrency(OPL::CurrencyEntry::Custom1, false);
         break;
     default:
         break;
@@ -653,10 +635,10 @@ void SettingsWidget::on_currCustom2CheckBox_stateChanged(int arg1)
 {
     switch (arg1) {
     case Qt::CheckState::Checked:
-        Settings::write(Settings::UserData::ShowCustom2Currency, true);
+        Settings::setShowCurrency(OPL::CurrencyEntry::Custom2, true);
         break;
     case Qt::CheckState::Unchecked:
-        Settings::write(Settings::UserData::ShowCustom2Currency, false);
+        Settings::setShowCurrency(OPL::CurrencyEntry::Custom2, false);
         break;
     default:
         break;
@@ -666,12 +648,16 @@ void SettingsWidget::on_currCustom2CheckBox_stateChanged(int arg1)
 
 void SettingsWidget::on_currCustom1LineEdit_editingFinished()
 {
-    Settings::write(Settings::UserData::Custom1CurrencyName, ui->currCustom1LineEdit->text());
+    auto entry = DB->getCurrencyEntry(OPL::CurrencyEntry::Custom1);
+    entry.setDisplayName(ui->currCustom1LineEdit->text());
+    emit settingChanged(HomeWidget);
 }
 
 void SettingsWidget::on_currCustom2LineEdit_editingFinished()
 {
-    Settings::write(Settings::UserData::Custom2CurrencyName, ui->currCustom2LineEdit->text());
+    auto entry = DB->getCurrencyEntry(OPL::CurrencyEntry::Custom2);
+    entry.setDisplayName(ui->currCustom2LineEdit->text());
+    emit settingChanged(HomeWidget);
 }
 
 void SettingsWidget::on_languageComboBox_activated(int arg1)

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

@@ -17,7 +17,7 @@
    <item row="0" column="0">
     <widget class="QTabWidget" name="tabWidget">
      <property name="currentIndex">
-      <number>2</number>
+      <number>4</number>
      </property>
      <widget class="QWidget" name="personalTab">
       <attribute name="title">
@@ -930,7 +930,7 @@
           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Determines how your logbook is displayed in the logbook tab. This has no influence on what details are logged, just on what is displayed by default.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
          </property>
          <property name="text">
-          <string>Logbook Dispay</string>
+          <string>Logbook Display</string>
          </property>
         </widget>
        </item>

+ 2 - 3
src/gui/widgets/tailswidget.cpp

@@ -59,7 +59,7 @@ void TailsWidget::setupModelAndView()
     view->verticalHeader()->hide();
     view->setAlternatingRowColors(true);
 
-    sortColumn = Settings::read(Settings::UserData::TailSortColumn).toInt();
+    sortColumn = Settings::getTailSortColumn();
     view->setSortingEnabled(true);
     view->sortByColumn(sortColumn, Qt::DescendingOrder);
 
@@ -153,8 +153,7 @@ void TailsWidget::on_aircraftSearchLineEdit_textChanged(const QString &arg1)
 
 void TailsWidget::tableView_headerClicked(int column)
 {
-    sortColumn = column;
-    Settings::write(Settings::UserData::TailSortColumn, column);
+    Settings::setTailSortColumn(column);
 }
 
 void TailsWidget::on_deleteAircraftButton_clicked()

+ 14 - 14
src/opl.h

@@ -142,7 +142,7 @@ enum class Translation {English, German, Spanish};
 /*!
  * \brief Enumerates the available SQL views in the database
  */
-enum class DbViewName {Default, DefaultWithSim, Easa, EasaWithSim, SimulatorOnly};
+enum class LogbookView {Default, DefaultWithSim, Easa, EasaWithSim, SimulatorOnly};
 
 /*!
  * \brief Enumerates the Simulator Types: Flight and Navigation Procedures Trainer 1/2, Flight Simulation Training Device
@@ -176,7 +176,7 @@ public:
 
     inline const QStringList &getApproachTypes() const {return APPROACH_TYPES;}
     inline const QString getLanguageFilePath(Translation language) const {return L10N_FilePaths.value(language);}
-    inline const QString getViewIdentifier(DbViewName view_name) const {return DATABASE_VIEWS.value(view_name);}
+    inline const QString getViewIdentifier(LogbookView view_name) const {return DATABASE_VIEWS.value(view_name);}
     inline const QString getDbTableName(DbTable table_name) const {return DB_TABLES.value(table_name);}
 
 private:
@@ -191,19 +191,19 @@ private:
         {Translation::German,  QStringLiteral("Deutsch")},
         {Translation::Spanish, QStringLiteral("Español")},
     };
-    const static inline QMap<DbViewName, QString> DATABASE_VIEWS = {
-        {DbViewName::Default,        QStringLiteral("viewDefault")},
-        {DbViewName::DefaultWithSim, QStringLiteral("viewDefaultSim")},
-        {DbViewName::Easa,           QStringLiteral("viewEasa")},
-        {DbViewName::EasaWithSim,    QStringLiteral("viewEasaSim")},
-        {DbViewName::SimulatorOnly,  QStringLiteral("viewSimulators")},
+    const static inline QMap<LogbookView, QString> DATABASE_VIEWS = {
+        {LogbookView::Default,        QStringLiteral("viewDefault")},
+        {LogbookView::DefaultWithSim, QStringLiteral("viewDefaultSim")},
+        {LogbookView::Easa,           QStringLiteral("viewEasa")},
+        {LogbookView::EasaWithSim,    QStringLiteral("viewEasaSim")},
+        {LogbookView::SimulatorOnly,  QStringLiteral("viewSimulators")},
     };
-    const QMap<DbViewName, QString> DATABASE_VIEW_DISPLAY_NAMES = {
-        {DbViewName::Default,        tr("Default")},
-        {DbViewName::DefaultWithSim, tr("Default with Simulator")},
-        {DbViewName::Easa,           tr("EASA-FCL")},
-        {DbViewName::EasaWithSim,    tr("EASA-FCL with Simulator")},
-        {DbViewName::SimulatorOnly,  tr("Simulator Sessions Only")},
+    const QMap<LogbookView, QString> DATABASE_VIEW_DISPLAY_NAMES = {
+        {LogbookView::Default,        tr("Default")},
+        {LogbookView::DefaultWithSim, tr("Default with Simulator")},
+        {LogbookView::Easa,           tr("EASA-FCL")},
+        {LogbookView::EasaWithSim,    tr("EASA-FCL with Simulator")},
+        {LogbookView::SimulatorOnly,  tr("Simulator Sessions Only")},
     };
     const static inline QMap<PilotFunction, QString> PILOT_FUNCTIONS = {
         {PilotFunction::PIC,   QStringLiteral("PIC")},