Browse Source

Integrated AirportWidget

Integrated the airportWidget into the UI where the backupWidget used to be (moved to settings). Preliminary icon only, actual tbd.

Implemented a mechanism to better detect changes to the database and update the UI where needed. In essence, the Database::databaseUpdated signal now also contains the table(s) that were edited, allowing for a more fine grained control of what to update.

MainWindow takes advantage of this to lazily update DbCompletionData on the fly.
Felix Turo 2 years ago
parent
commit
4f760159b0

+ 35 - 44
mainwindow.cpp

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -29,40 +29,7 @@
 // Quick and dirty Debug area
 void MainWindow::doDebugStuff()
 {
-    //auto widget = new AirportWidget(this);
-    //ui->stackedWidget->addWidget(widget);
-    //ui->stackedWidget->setCurrentWidget(widget);
-    //DEB << "Testing retreiving...";
-    //DEB << "Old";
-    //{
-    //ATimer timer;
-    //
-    //for (int i = 1; i < 1000; i++) {
-    //    DataPosition dp("airports", i);
-    //    auto entry = DB->getEntry(dp);
-    //    //auto entry = DB->(i);
-    //}
-    //DEB << "getEntry completed";
-    //}
-    //
-    //{
-    //ATimer timer;
-    //
-    //for (int i = 1; i < 1000; i++) {
-    //    auto row = DB->getRow(OPL::DbTable::Airports, i);
-    //}
-    //DEB << "getRow completed";
-    //}
-    //OPL::Row new_row(OPL::DbTable::Aircraft, 4, entry.getData());
-    //DEB << new_row;
-    //DEB << DB->commit(new_row);
-    //DEB << DB->getAircraftEntry(4);
-
-    auto row = DB->getRow(OPL::DbTable::Flights, 2);
-    DEB << row;
-    auto row_2 = DB->getRow(OPL::DbTable::Flights, 500);
-    DEB << row_2;
-
+    completionData.update();
 }
 
 MainWindow::MainWindow(QWidget *parent)
@@ -81,7 +48,8 @@ MainWindow::MainWindow(QWidget *parent)
         onDatabaseInvalid();
 
     if(!DB->connect()){
-        WARN(tr("Error establishing database connection."));
+        WARN(tr("Error establishing database connection. The following error has ocurred:<br><br>%1")
+             .arg(DB->lastError.text()));
     }
 
     // retreive completion lists and maps
@@ -97,8 +65,8 @@ MainWindow::MainWindow(QWidget *parent)
     pilotsWidget = new PilotsWidget(this);
     ui->stackedWidget->addWidget(pilotsWidget);
 
-    backupWidget = new BackupWidget(this);
-    ui->stackedWidget->addWidget(backupWidget);
+    airportWidget = new AirportWidget(this);
+    ui->stackedWidget->addWidget(airportWidget);
     settingsWidget = new SettingsWidget(this);
     ui->stackedWidget->addWidget(settingsWidget);
     debugWidget = new DebugWidget(this);
@@ -135,7 +103,7 @@ void MainWindow::setupToolbar()
     toolBar->addAction(ui->actionLogbook);
     toolBar->addAction(ui->actionAircraft);
     toolBar->addAction(ui->actionPilots);
-    toolBar->addAction(ui->actionBackup);
+    toolBar->addAction(ui->actionAirports);
     toolBar->addAction(ui->actionSettings);
     toolBar->addAction(ui->actionQuit);
     toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
@@ -154,7 +122,7 @@ void MainWindow::setActionIcons(StyleType style)
         ui->actionLogbook->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_LOGBOOK));
         ui->actionAircraft->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_AIRCRAFT));
         ui->actionPilots->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_PILOT));
-        ui->actionBackup->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_BACKUP));
+        ui->actionAirports->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_BACKUP));
         ui->actionSettings->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_SETTINGS));
         ui->actionQuit->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_QUIT));
         break;
@@ -166,7 +134,7 @@ void MainWindow::setActionIcons(StyleType style)
         ui->actionLogbook->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_LOGBOOK_DARK));
         ui->actionAircraft->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_AIRCRAFT_DARK));
         ui->actionPilots->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_PILOT_DARK));
-        ui->actionBackup->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_BACKUP_DARK));
+        ui->actionAirports->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_BACKUP_DARK));
         ui->actionSettings->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_SETTINGS_DARK));
         ui->actionQuit->setIcon(QIcon(OPL::Assets::ICON_TOOLBAR_QUIT_DARK));
         break;
@@ -215,6 +183,30 @@ void MainWindow::connectWidgets()
                      pilotsWidget,    &PilotsWidget::repopulateModel);
     QObject::connect(DB,              &OPL::Database::connectionReset,
                      aircraftWidget,  &AircraftWidget::repopulateModel);
+
+    // Catch database updates to lazily update CompletionData
+    QObject::connect(DB,              &OPL::Database::dataBaseUpdated,
+                     this,            &MainWindow::onDatabaseUpdated);
+}
+
+void MainWindow::onDatabaseUpdated(const OPL::DbTable table)
+{
+    switch (table) {
+    case OPL::DbTable::Pilots:
+        DEB << "Pilots table updated...";
+        completionData.updatePilots();
+        break;
+    case OPL::DbTable::Tails:
+        DEB << "Tails table updated...";
+        completionData.updateTails();
+        break;
+    case OPL::DbTable::Airports:
+        DEB << "Airports table updated...";
+        completionData.updateAirports();
+        break;
+    default:
+        break;
+    }
 }
 
 void MainWindow::onDatabaseInvalid()
@@ -289,9 +281,9 @@ void MainWindow::on_actionPilots_triggered()
     ui->stackedWidget->setCurrentWidget(pilotsWidget);
 }
 
-void MainWindow::on_actionBackup_triggered()
+void MainWindow::on_actionAirports_triggered()
 {
-    ui->stackedWidget->setCurrentWidget(backupWidget);
+    ui->stackedWidget->setCurrentWidget(airportWidget);
 }
 
 void MainWindow::on_actionSettings_triggered()
@@ -314,4 +306,3 @@ void MainWindow::on_actionNewSim_triggered()
     auto nsd = NewSimDialog(this);
     nsd.exec();
 }
-

+ 12 - 6
mainwindow.h

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@
 #include "src/gui/widgets/logbookwidget.h"
 #include "src/gui/widgets/aircraftwidget.h"
 #include "src/gui/widgets/airportwidget.h"
-#include "src/gui/widgets/backupwidget.h"
+#include "src/gui/widgets/airportwidget.h"
 #include "src/gui/widgets/pilotswidget.h"
 #include "src/gui/widgets/debugwidget.h"
 #include "src/gui/dialogues/newtaildialog.h"
@@ -78,9 +78,9 @@ QT_END_NAMESPACE
  *
  * Shows a view of the pilots table in a QTableView and enables editing the entries by spawning a child NewPilotDialog with the details for a selected pilot.
  *
- * ## Backup
+ * ## Airports
  *
- * Enables backing up and restoring the database.
+ * Enables viewing and editing the airports database
  *
  * ## Settings
  *
@@ -112,7 +112,7 @@ private slots:
 
     void on_actionPilots_triggered();
 
-    void on_actionBackup_triggered();
+    void on_actionAirports_triggered();
 
     void on_actionSettings_triggered();
 
@@ -122,6 +122,8 @@ private slots:
 
     void on_actionNewSim_triggered();
 
+    void onDatabaseUpdated(const OPL::DbTable table);
+
 private:
     Ui::MainWindow *ui;
 
@@ -133,7 +135,7 @@ private:
 
     PilotsWidget* pilotsWidget;
 
-    BackupWidget* backupWidget;
+    AirportWidget* airportWidget;
 
     SettingsWidget* settingsWidget;
 
@@ -141,6 +143,7 @@ private:
 
     // Completion Data for QCompleters and Mapping
     OPL::DbCompletionData completionData;
+    bool airportDbIsDirty = false;
 
     void setupToolbar();
     void setActionIcons(StyleType style = StyleType::Light);
@@ -185,6 +188,9 @@ protected:
 
         auto tool_bar = this->findChild<QToolBar*>();
         tool_bar->setIconSize(QSize(icon_size, icon_size));
+        event->accept();
     }
+
+    //void closeEvent(QCloseEvent *event) override; //TODO check and prompt for creation of backup?
 };
 #endif // MAINWINDOW_H

+ 3 - 3
mainwindow.ui

@@ -141,15 +141,15 @@
     <string>Ctrl+D</string>
    </property>
   </action>
-  <action name="actionBackup">
+  <action name="actionAirports">
    <property name="text">
-    <string>Backup</string>
+    <string>Airports</string>
    </property>
    <property name="toolTip">
     <string>Create or restore a backup of the database</string>
    </property>
    <property name="shortcut">
-    <string>Ctrl+B</string>
+    <string>Ctrl+A</string>
    </property>
   </action>
   <action name="actionNewSim">

+ 1 - 1
src/classes/adownload.h

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

+ 1 - 1
src/classes/ajson.cpp

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

+ 12 - 26
src/database/database.cpp

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -78,22 +78,6 @@ const QList<OPL::DbTable> &Database::getUserTables() const
     return USER_TABLES;
 }
 
-const UserDataState Database::getUserDataState() const
-{
-    QSqlQuery q;
-    q.prepare(QStringLiteral("SELECT COUNT (*) FROM tails"));
-    q.exec();
-    q.first();
-    int tails = q.value(0).toInt();
-
-    q.prepare(QStringLiteral("SELECT COUNT (*) FROM pilots"));
-    q.exec();
-    q.first();
-    int pilots = q.value(0).toInt();
-
-    return UserDataState(tails, pilots);
-}
-
 const QStringList Database::getTableColumns(OPL::DbTable table_name) const
 {
     return tableColumns.value(OPL::GLOBALS->getDbTableName(table_name));
@@ -118,7 +102,7 @@ void Database::updateLayout()
         }
         tableColumns.insert(table_name, table_columns);
     }
-    emit dataBaseUpdated();
+    emit dataBaseUpdated(DbTable::Any);
 }
 
 Database* Database::instance()
@@ -208,7 +192,9 @@ bool Database::remove(const OPL::Row &row)
         return false;
     }
 
-    QString statement = QLatin1String("DELETE FROM ") + OPL::GLOBALS->getDbTableName(row.getTableName())
+    const QString table_name = OPL::GLOBALS->getDbTableName(row.getTable());
+
+    QString statement = QLatin1String("DELETE FROM ") + table_name
             + QLatin1String(" WHERE ROWID=?");
 
     QSqlQuery query;
@@ -219,7 +205,7 @@ bool Database::remove(const OPL::Row &row)
     {
         LOG << "Entry removed:";
         LOG << row;
-        emit dataBaseUpdated();
+        emit dataBaseUpdated(row.getTable());
         return true;
     } else {
         DEB << "Unable to delete.";
@@ -253,7 +239,7 @@ bool Database::removeMany(OPL::DbTable table, const QList<int> &row_id_list)
     if (errorCount == 0) {
         query.prepare(QStringLiteral("COMMIT"));
         if(query.exec()) {
-            emit dataBaseUpdated();
+            emit dataBaseUpdated(table);
             LOG << "Transaction successfull.";
             return true;
         } else {
@@ -278,7 +264,7 @@ bool Database::exists(const OPL::Row &row)
         return false;
 
     //Check database for row id
-    QString statement = QLatin1String("SELECT COUNT(*) FROM ") + OPL::GLOBALS->getDbTableName(row.getTableName())
+    QString statement = QLatin1String("SELECT COUNT(*) FROM ") + OPL::GLOBALS->getDbTableName(row.getTable())
             + QLatin1String(" WHERE ROWID=?");
     QSqlQuery query;
     query.prepare(statement);
@@ -318,7 +304,7 @@ bool Database::clear()
 
 bool Database::update(const OPL::Row &updated_row)
 {
-    QString statement = QLatin1String("UPDATE ") + OPL::GLOBALS->getDbTableName(updated_row.getTableName()) + QLatin1String(" SET ");
+    QString statement = QLatin1String("UPDATE ") + OPL::GLOBALS->getDbTableName(updated_row.getTable()) + QLatin1String(" SET ");
     const auto& data = updated_row.getData();
     for (auto i = data.constBegin(); i != data.constEnd(); ++i) {
         statement.append(i.key() + "=?,");
@@ -341,7 +327,7 @@ bool Database::update(const OPL::Row &updated_row)
     if (query.exec())
     {
         DEB << "Entry successfully committed.";
-        emit dataBaseUpdated();
+        emit dataBaseUpdated(updated_row.getTable());
         return true;
     } else {
         DEB << "Unable to commit.";
@@ -354,7 +340,7 @@ bool Database::update(const OPL::Row &updated_row)
 
 bool Database::insert(const OPL::Row &new_row)
 {
-    QString statement = QLatin1String("INSERT INTO ") + OPL::GLOBALS->getDbTableName(new_row.getTableName()) + QLatin1String(" (");
+    QString statement = QLatin1String("INSERT INTO ") + OPL::GLOBALS->getDbTableName(new_row.getTable()) + QLatin1String(" (");
     const auto& data = new_row.getData();
     QHash<QString, QVariant>::const_iterator i;
     for (i = data.constBegin(); i != data.constEnd(); ++i) {
@@ -384,7 +370,7 @@ bool Database::insert(const OPL::Row &new_row)
     if (query.exec())
     {
         DEB << "Entry successfully committed.";
-        emit dataBaseUpdated();
+        emit dataBaseUpdated(new_row.getTable());
         return true;
     } else {
         DEB << "Unable to commit.";

+ 2 - 36
src/database/database.h

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -48,33 +48,6 @@ namespace OPL {
  */
 #define DB OPL::Database::instance()
 
-/*!
- * \brief The UserDateState struct caches the current number of entries in relevant database tables
- * for fast access
- * \param numTails - Number of tails in the database
- * \param numPilots - Number of pilots in the database
- */
-struct UserDataState {
-
-    UserDataState(){numTails = 0; numPilots = 0;}
-    UserDataState(int numTails_, int numPilots_)
-        : numTails(numTails_), numPilots(numPilots_){}
-
-    bool operator==(const UserDataState& other)
-    {
-        return numTails == other.numTails && numPilots == other.numPilots;
-    }
-    bool operator!=(const UserDataState& other)
-    {
-        return numTails != other.numTails || numPilots != other.numPilots;
-    }
-
-    int numTails;
-    int numPilots;
-};
-
-
-
 /*!
  * \brief The DB class encapsulates the SQL database by providing fast access
  * to hot database data.
@@ -309,13 +282,6 @@ public:
      */
     const QList<OPL::DbTable> &getTemplateTables() const;
 
-    /*!
-     * \brief getUserDataState returns a struct containing the current amount of entries in the tails and
-     * pilots tables.
-     * \return
-     */
-    const UserDataState getUserDataState() const;
-
     // Maintenance and setup
 
     /*!
@@ -360,7 +326,7 @@ signals:
      * trigger an update to the models of the views displaying database contents in
      * the user interface so that a user is always presented with up-to-date information.
      */
-    void dataBaseUpdated();
+    void dataBaseUpdated(const DbTable table);
     /*!
      * \brief connectionReset is emitted whenever the database connection is reset, for
      * example when creating or restoring a backup.

+ 33 - 12
src/database/dbcompletiondata.cpp

@@ -1,3 +1,20 @@
+/*
+ *openPilotLog - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020-2022 Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
 #include "dbcompletiondata.h"
 
 namespace OPL {
@@ -26,35 +43,39 @@ void DbCompletionData::init()
     airportIataIdMap = getIdMap(CompleterTarget::AirportIdentifierIATA);
     airportNameIdMap = getIdMap(CompleterTarget::AirportNames);
     airportList      = getCompletionList(CompleterTarget::AirportIdentifier);
-
-    current_state = DB->getUserDataState();
 }
 
 void DbCompletionData::update()
 {
-    if (current_state != DB->getUserDataState()) {
-        // retreive user modifiable data
-        pilotList   = getCompletionList(CompleterTarget::PilotNames);
-        tailsList   = getCompletionList(CompleterTarget::Registrations);
-        pilotsIdMap = getIdMap(CompleterTarget::PilotNames);
-        tailsIdMap  = getIdMap(CompleterTarget::Registrations);
-
-        current_state = DB->getUserDataState();
-    }
-}
+        updatePilots();
+        updateTails();
+        updateAirports();
+};
+
 
 void DbCompletionData::updateTails()
 {
+    DEB << "Updating Tails...";
     tailsIdMap  = getIdMap(CompleterTarget::Registrations);
     tailsList   = getCompletionList(CompleterTarget::Registrations);
 }
 
 void DbCompletionData::updatePilots()
 {
+    DEB << "Updating Pilots...";
     pilotsIdMap  = getIdMap(CompleterTarget::PilotNames);
     pilotList    = getCompletionList(CompleterTarget::PilotNames);
 }
 
+void DbCompletionData::updateAirports()
+{
+    DEB << "Updating Airports...";
+    airportIcaoIdMap = getIdMap(CompleterTarget::AirportIdentifierICAO);
+    airportIataIdMap = getIdMap(CompleterTarget::AirportIdentifierIATA);
+    airportNameIdMap = getIdMap(CompleterTarget::AirportNames);
+    airportList      = getCompletionList(CompleterTarget::AirportIdentifier);
+}
+
 const QStringList DbCompletionData::getCompletionList(CompleterTarget target)
 {
     QString statement;

+ 18 - 3
src/database/dbcompletiondata.h

@@ -1,3 +1,20 @@
+/*
+ *openPilotLog - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020-2022 Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
 #ifndef DBCOMPLETIONDATA_H
 #define DBCOMPLETIONDATA_H
 
@@ -43,7 +60,7 @@ public:
     void update();
     void updateTails();
     void updatePilots();
-
+    void updateAirports();
 
     // Maps for input mapping DB key - user input
     QHash<int, QString> pilotsIdMap;
@@ -55,8 +72,6 @@ public:
     QStringList pilotList;
     QStringList tailsList;
     QStringList airportList;
-    // User Data State to trigger update if needed
-    UserDataState current_state;
 
     /*!
      * \brief getCompletionList returns a QStringList of values for a

+ 17 - 0
src/database/dbsummary.cpp

@@ -1,3 +1,20 @@
+/*
+ *openPilotLog - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020-2022 Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
 #include "dbsummary.h"
 
 namespace OPL {

+ 17 - 0
src/database/dbsummary.h

@@ -1,3 +1,20 @@
+/*
+ *openPilotLog - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020-2022 Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
 #ifndef DBSUMMARY_H
 #define DBSUMMARY_H
 

+ 23 - 1
src/database/row.cpp

@@ -1,3 +1,20 @@
+/*
+ *openPilotLog - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020-2022 Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
 #include "row.h"
 
 namespace OPL {
@@ -42,11 +59,16 @@ void Row::setRowId(int value)
     rowId = value;
 }
 
-OPL::DbTable Row::getTableName() const
+OPL::DbTable Row::getTable() const
 {
     return table;
 }
 
+const QString Row::getTableName() const
+{
+    return OPL::GLOBALS->getDbTableName(table);
+}
+
 OPL::Row::operator QString() const
 {
     if (!isValid()) {

+ 58 - 3
src/database/row.h

@@ -1,3 +1,21 @@
+/*
+ *openPilotLog - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020-2022 Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
 #ifndef ROW_H
 #define ROW_H
 #include "src/opl.h"
@@ -7,7 +25,23 @@ namespace OPL {
 
 /*!
  * \brief The Row class provides an interface for retreiving and submitting entries from the database.
- * It is a bass class and when instantiated, the appropriate subclass should be used.
+ *
+ * \details The Row class is a base class and when instantiated, the appropriate subclass should be used.
+ *
+ * The database holds all the data related to the logbook in different tables. Each of these tables is composed of
+ * rows. Each row has different columns and each column contains the data. As such, an entry can be thought of
+ * as a row in the database. The row class encapsulates the data contained in each row.
+ *
+ * A row is uniquely identified by its position in the database, consisting of the table name (QString) and the row id (int).
+ * A new entry, which is not yet in the database has the row id 0. If a new row object is created, the hasData
+ * bool is set to false. Before submitting the entry to the database, setData() has to be called to fill the row
+ * with data and toggle the verification bit.
+ *
+ * The Row Object holds all the necessary information the Database class needs to commit (create or update) it.
+ * The Identifying information can be accessed with getRowId and getTable() / getTableName().
+ *
+ * For convenience and readabilty, subclasses exist that have the table property pre-set. These rows are then
+ * referred to as entries. See AircraftEntry, FlightEntry etc.
  */
 class Row
 {
@@ -24,11 +58,14 @@ public:
     void setData(const RowData_T &value);
     int getRowId() const;
     void setRowId(int value);
-    OPL::DbTable getTableName() const;
+    OPL::DbTable getTable() const;
+    const QString getTableName() const;
 
     bool isValid() const {return hasData && valid;}
 
-    // For Debugging
+    /*!
+     * \brief operator QString can be used for printing debug information to stdout
+     */
     operator QString() const;
 
 
@@ -41,6 +78,9 @@ protected:
     bool valid = true;
 };
 
+/*!
+ * \brief A Row representing an Aircraft entry. See Row class for details.
+ */
 class AircraftEntry : public Row
 {
 public:
@@ -49,6 +89,9 @@ public:
     AircraftEntry(int row_id, const RowData_T &row_data);
 };
 
+/*!
+ * \brief A Row representing a Tail (Registration) entry. See Row class for details.
+ */
 class TailEntry : public Row
 {
 public:
@@ -60,6 +103,9 @@ public:
     const QString type() const;
 };
 
+/*!
+ * \brief A Row representing a Pilot entry. See Row class for details.
+ */
 class PilotEntry : public Row
 {
 public:
@@ -69,6 +115,9 @@ public:
 
 };
 
+/*!
+ * \brief A Row representing a Simulator entry. See Row class for details.
+ */
 class SimulatorEntry : public Row
 {
 public:
@@ -77,6 +126,9 @@ public:
     SimulatorEntry(int row_id, const RowData_T &row_data);
 };
 
+/*!
+ * \brief A Row representing a Flight entry. See Row class for details.
+ */
 class FlightEntry : public Row
 {
 public:
@@ -85,6 +137,9 @@ public:
     FlightEntry(int row_id, const RowData_T &row_data);
 };
 
+/*!
+ * \brief A Row representing a Currency entry. See Row class for details.
+ */
 class CurrencyEntry : public Row
 {
 public:

+ 1 - 3
src/functions/acalc.cpp

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -22,8 +22,6 @@
 #include "src/opl.h"
 #include "src/functions/atime.h"
 
-//using namespace ACalc;
-
 /*!
  * \brief ACalc::formatTimeInput verifies user input and formats to hh:mm
  * if the output is not a valid time, an empty string is returned. Accepts

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

+ 1 - 1
src/gui/dialogues/newairportdialog.ui

@@ -11,7 +11,7 @@
    </rect>
   </property>
   <property name="windowTitle">
-   <string>Dialog</string>
+   <string>Add New Airport</string>
   </property>
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -214,6 +214,7 @@ void NewTailDialog::submitForm()
         message_box.exec();
         return;
     } else {
+        emit tailDataChanged();
         QDialog::accept();
     }
 }

+ 4 - 1
src/gui/dialogues/newtaildialog.h

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -74,6 +74,9 @@ public:
     explicit NewTailDialog(int row_id, QWidget *parent = nullptr);
 
     ~NewTailDialog();
+
+signals:
+    void tailDataChanged();
 private:
 
     Ui::NewTail *ui;

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

+ 10 - 0
src/gui/widgets/airportwidget.cpp

@@ -1,6 +1,7 @@
 #include "airportwidget.h"
 #include "ui_airportwidget.h"
 #include "src/gui/dialogues/newairportdialog.h"
+#include "src/database/database.h"
 
 AirportWidget::AirportWidget(QWidget *parent) :
     QWidget(parent),
@@ -9,6 +10,9 @@ AirportWidget::AirportWidget(QWidget *parent) :
     ui->setupUi(this);
     setupModelAndeView();
     setupSearch();
+
+    QObject::connect(model,     &QSqlTableModel::beforeUpdate,
+                     this,      &AirportWidget::onUpdate);
 }
 
 AirportWidget::~AirportWidget()
@@ -19,6 +23,7 @@ AirportWidget::~AirportWidget()
 void AirportWidget::setupModelAndeView()
 {
     model = new QSqlTableModel(this);
+    model->setEditStrategy(QSqlTableModel::OnFieldChange);
     model->setTable(TABLE_NAME);
     model->select();
 
@@ -67,3 +72,8 @@ void AirportWidget::on_newAirportPushButton_clicked()
     if (ap_dialog.exec() == QDialog::Accepted)
         model->select();
 }
+
+void AirportWidget::onUpdate()
+{
+    emit DB->dataBaseUpdated(OPL::DbTable::Airports);
+}

+ 8 - 0
src/gui/widgets/airportwidget.h

@@ -17,6 +17,9 @@ public:
     explicit AirportWidget(QWidget *parent = nullptr);
     ~AirportWidget();
 
+signals:
+    void airportDatabaseUpdated();
+
 private slots:
     void on_searchLineEdit_textChanged(const QString &arg1);
 
@@ -24,6 +27,11 @@ private slots:
 
     void on_newAirportPushButton_clicked();
 
+    /*!
+     * \brief onUpdate is called whenever the user modifies an entry in the airports table
+     */
+    void onUpdate();
+
 private:
     Ui::AirportWidget *ui;
     QSqlTableModel *model;

+ 15 - 15
src/gui/widgets/backupwidget.cpp

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -37,8 +37,8 @@ BackupWidget::BackupWidget(QWidget *parent) :
     ui->setupUi(this);
 
     model = new QStandardItemModel(this);
-    model->setHorizontalHeaderLabels(QStringList{tr("Backup File"),tr("Flights"), tr("Aircraft"),
-                                                 tr("Pilots"), tr("Last Flight"), tr("Total Time")});
+    model->setHorizontalHeaderLabels(QStringList{tr("Total Time"),tr("Flights"), tr("Aircraft"),
+                                                 tr("Pilots"), tr("Last Flight"), tr("Backup File")});
     view = ui->tableView;
     refresh();
 }
@@ -65,12 +65,12 @@ void BackupWidget::refresh()
     // Get summary of each db file and populate lists (columns) of data
     for (const auto &entry : entries) {
         QMap<OPL::DbSummaryKey, QString> summary = OPL::DbSummary::databaseSummary(backup_dir.absoluteFilePath(entry));
-        model->appendRow({new AFileStandardItem(provider.icon(QFileIconProvider::File), entry, AStandardPaths::Backup),
+        model->appendRow({new QStandardItem(summary[OPL::DbSummaryKey::total_time]),
                           new QStandardItem(summary[OPL::DbSummaryKey::total_flights]),
                           new QStandardItem(summary[OPL::DbSummaryKey::total_tails]),
                           new QStandardItem(summary[OPL::DbSummaryKey::total_pilots]),
                           new QStandardItem(summary[OPL::DbSummaryKey::last_flight]),
-                          new QStandardItem(summary[OPL::DbSummaryKey::total_time])
+                          new AFileStandardItem(provider.icon(QFileIconProvider::File), entry, AStandardPaths::Backup)
                          });
     }
 
@@ -113,12 +113,12 @@ void BackupWidget::on_createLocalPushButton_clicked()
 
     QFileIconProvider provider;
     QMap<OPL::DbSummaryKey, QString> summary = OPL::DbSummary::databaseSummary(filename);
-    model->insertRow(0, {new AFileStandardItem(provider.icon(QFileIconProvider::File), QFileInfo(filename)),
-                      new QStandardItem(summary[OPL::DbSummaryKey::total_flights]),
-                      new QStandardItem(summary[OPL::DbSummaryKey::total_tails]),
-                      new QStandardItem(summary[OPL::DbSummaryKey::total_pilots]),
-                      new QStandardItem(summary[OPL::DbSummaryKey::last_flight]),
-                      new QStandardItem(summary[OPL::DbSummaryKey::total_time])
+    model->insertRow(0, {new QStandardItem(summary[OPL::DbSummaryKey::total_time]),
+                         new QStandardItem(summary[OPL::DbSummaryKey::total_flights]),
+                         new QStandardItem(summary[OPL::DbSummaryKey::total_tails]),
+                         new QStandardItem(summary[OPL::DbSummaryKey::total_pilots]),
+                         new QStandardItem(summary[OPL::DbSummaryKey::last_flight]),
+                         new AFileStandardItem(provider.icon(QFileIconProvider::File), QFileInfo(filename)),
                      });
 }
 
@@ -262,14 +262,14 @@ void BackupWidget::on_aboutPushButton_clicked()
                       "<h3><center>About Backups</center></h3>"
                       "<br>"
                       "<p>By creating a backup, you create a copy of your logbook for safekeeping. This copy includes all your "
-                      "flights, pilots, aircraft and expiries. By creating a backup, you are creating a snapshot of your logbook to date. This backup can "
+                      "flights, pilots, aircraft and currencies. By creating a backup, you are creating a snapshot of your logbook to date. This backup can "
                       "later be restored. OpenPilotLog offers two kinds of backups: Local and External Backups.<br><br>Local backups "
                       "are automatically stored in a folder on this computer and will show up in the list below. They can easily be created by selecting <b>Create Local backup</b> and restored with "
-                      "<b>Restore Local Backup</b>.<br>"
-                      "When using <b>Create External Backup</b>, you will be asked where to save your backup file. This can be a pen drive, a cloud location or any other location of your choice. "
+                      "<b>Restore Local Backup</b>.<br><br>"
+                      "When using <b>Create External Backup</b>, you will be asked where to save your backup file. This can be an external hard drive, USB stick, a cloud location or any other location of your choice. "
                       "This functionality can also be used to sync your database across devices or to take it with you when you buy a new PC. You can then import your backup file by selecting "
                       "it with <b>Restore external backup</b>.</p>"
-                      "<p>Frequent backups are recommended to guard against data loss or corruption. It is also recommended to keep a backup copy in a seperate location from your main "
+                      "<p>Frequent backups are recommended to prevent data loss or corruption. It is also recommended to keep a backup copy in a location physically seperated from your main "
                       "computer to prevent data loss due to system failures.</p>"
                       //todo "<p>By default, OpenPilotLog creates a weekly automatic backup. If you would like to change this behaviour, you can adjust it in the settings.</p>"
                       "<br>"

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

+ 45 - 69
src/gui/widgets/backupwidget.ui

@@ -14,7 +14,42 @@
    <string>Form</string>
   </property>
   <layout class="QGridLayout" name="gridLayout">
-   <item row="2" column="0" colspan="5">
+   <item row="3" column="4">
+    <widget class="QPushButton" name="restoreExternalPushButton">
+     <property name="text">
+      <string>Restore External Backup</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="2">
+    <widget class="QPushButton" name="aboutPushButton">
+     <property name="text">
+      <string>About Backups</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QPushButton" name="createLocalPushButton">
+     <property name="text">
+      <string>Create Local Backup</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="2">
+    <widget class="QPushButton" name="deleteSelectedPushButton">
+     <property name="text">
+      <string>Delete Selected Backup</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1" rowspan="2">
+    <widget class="Line" name="line_3">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="0" colspan="5">
     <widget class="QTableView" name="tableView">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@@ -45,90 +80,31 @@
      </attribute>
     </widget>
    </item>
-   <item row="1" column="0" colspan="5">
-    <widget class="Line" name="line">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="1" rowspan="2">
-    <widget class="Line" name="line_3">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-    </widget>
-   </item>
-   <item row="5" column="4">
-    <widget class="QPushButton" name="restoreExternalPushButton">
-     <property name="text">
-      <string>Restore External Backup</string>
-     </property>
-    </widget>
-   </item>
-   <item row="5" column="2">
-    <widget class="QPushButton" name="aboutPushButton">
-     <property name="text">
-      <string>About Backups</string>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="0">
-    <widget class="QPushButton" name="createLocalPushButton">
-     <property name="text">
-      <string>Create Local Backup</string>
-     </property>
-    </widget>
-   </item>
-   <item row="3" column="0" colspan="5">
-    <widget class="Line" name="line_2">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="4">
+   <item row="2" column="4">
     <widget class="QPushButton" name="createExternalPushButton">
      <property name="text">
       <string>Create External Backup</string>
      </property>
     </widget>
    </item>
-   <item row="4" column="3" rowspan="2">
+   <item row="2" column="3" rowspan="2">
     <widget class="Line" name="line_4">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
     </widget>
    </item>
-   <item row="4" column="2">
-    <widget class="QPushButton" name="deleteSelectedPushButton">
-     <property name="text">
-      <string>Delete Selected Backup</string>
-     </property>
-    </widget>
-   </item>
-   <item row="0" column="2">
-    <widget class="QLabel" name="availableBackupsLabel">
-     <property name="font">
-      <font>
-       <pointsize>12</pointsize>
-       <weight>75</weight>
-       <bold>true</bold>
-      </font>
-     </property>
+   <item row="3" column="0">
+    <widget class="QPushButton" name="restoreLocalPushButton">
      <property name="text">
-      <string>Available Backups</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignCenter</set>
+      <string>Restore Local Backup</string>
      </property>
     </widget>
    </item>
-   <item row="5" column="0">
-    <widget class="QPushButton" name="restoreLocalPushButton">
-     <property name="text">
-      <string>Restore Local Backup</string>
+   <item row="1" column="0" colspan="5">
+    <widget class="Line" name="line_2">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
      </property>
     </widget>
    </item>

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -76,7 +76,7 @@ void DebugWidget::on_resetUserTablesPushButton_clicked()
     ATimer timer(this);
     if (DB->resetUserData()){
         LOG << "Database successfully reset";
-        emit DB->dataBaseUpdated();
+        emit DB->dataBaseUpdated(OPL::DbTable::Any);
     } else
         LOG <<"Errors have occurred. Check console for Debug output. ";
 }

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

@@ -55,6 +55,9 @@ HomeWidget::HomeWidget(QWidget *parent) :
     fillTotals();
     fillSelectedCurrencies();
     fillLimitations();
+
+    QObject::connect(DB,    &OPL::Database::dataBaseUpdated,
+                     this,  &HomeWidget::onPilotsDatabaseChanged);
 }
 
 HomeWidget::~HomeWidget()
@@ -76,6 +79,13 @@ void HomeWidget::refresh()
     fillLimitations();
 }
 
+void HomeWidget::onPilotsDatabaseChanged(const OPL::DbTable table)
+{
+    // maybe logbook owner name has changed, redraw
+    if (table == OPL::DbTable::Pilots)
+        ui->welcomeLabel->setText(tr("Welcome to openPilotLog, %1!").arg(userName()));
+}
+
 void HomeWidget::changeEvent(QEvent *event)
 {
     if (event != nullptr)

+ 2 - 0
src/gui/widgets/homewidget.h

@@ -101,6 +101,8 @@ private:
 public slots:
     void refresh();
 
+    void onPilotsDatabaseChanged(const OPL::DbTable table);
+
 protected:
     /*!
      * \brief Handles change events, like updating the UI to new localisation

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

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

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

+ 9 - 0
src/gui/widgets/settingswidget.cpp

@@ -24,6 +24,7 @@
 #include "src/database/row.h"
 #include "src/opl.h"
 #include "src/functions/adate.h"
+#include "src/gui/widgets/backupwidget.h"
 
 SettingsWidget::SettingsWidget(QWidget *parent) :
     QWidget(parent),
@@ -32,6 +33,7 @@ SettingsWidget::SettingsWidget(QWidget *parent) :
     ui->setupUi(this);
     ui->tabWidget->setCurrentIndex(0);
 
+    loadBackupWidget();
     setupComboBoxes();
     setupDateEdits();
     setupValidators();
@@ -97,6 +99,13 @@ void SettingsWidget::setupDateEdits()
     }
 }
 
+void SettingsWidget::loadBackupWidget()
+{
+    auto bw = new BackupWidget(this);
+    ui->backupStackedWidget->addWidget(bw);
+    ui->backupStackedWidget->setCurrentWidget(bw);
+}
+
 /*!
  * \brief SettingsWidget::readSettings Reads settings from ASettings and sets up the UI accordingly
  */

+ 2 - 0
src/gui/widgets/settingswidget.h

@@ -101,6 +101,8 @@ private:
 
     void setupDateEdits();
 
+    void loadBackupWidget();
+
     void updatePersonalDetails();
 
     bool usingStylesheet();

+ 15 - 5
src/gui/widgets/settingswidget.ui

@@ -17,7 +17,7 @@
    <item row="0" column="0">
     <widget class="QTabWidget" name="tabWidget">
      <property name="currentIndex">
-      <number>3</number>
+      <number>5</number>
      </property>
      <widget class="QWidget" name="personalTab">
       <attribute name="title">
@@ -969,11 +969,21 @@
        </item>
       </layout>
      </widget>
-     <widget class="QWidget" name="aboutTab">
+     <widget class="QWidget" name="backupTab">
+      <attribute name="title">
+       <string>Backups</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_7">
+       <item row="0" column="0">
+        <widget class="QStackedWidget" name="backupStackedWidget"/>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab">
       <attribute name="title">
        <string>About</string>
       </attribute>
-      <layout class="QGridLayout" name="gridLayout_3">
+      <layout class="QGridLayout" name="gridLayout_8">
        <item row="0" column="0">
         <spacer name="horizontalSpacer_7">
          <property name="orientation">
@@ -981,7 +991,7 @@
          </property>
          <property name="sizeHint" stdset="0">
           <size>
-           <width>259</width>
+           <width>461</width>
            <height>20</height>
           </size>
          </property>
@@ -1001,7 +1011,7 @@
          </property>
          <property name="sizeHint" stdset="0">
           <size>
-           <width>259</width>
+           <width>461</width>
            <height>20</height>
           </size>
          </property>

+ 2 - 2
src/opl.h

@@ -1,6 +1,6 @@
 /*
  *openPilotLog - A FOSS Pilot Logbook Application
- *Copyright (C) 2020-2021 Felix Turowsky
+ *Copyright (C) 2020-2022 Felix Turowsky
  *
  *This program is free software: you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -119,7 +119,7 @@ enum class SimulatorType {FNPTI = 0, FNPTII = 1, FSTD = 2};
 /*!
  * \brief Enumerates the tables in the database
  */
-enum class DbTable {Flights, Simulators, Pilots, Tails, Aircraft, Airports, Currencies, Changelog};
+enum class DbTable {Any, Flights, Simulators, Pilots, Tails, Aircraft, Airports, Currencies, Changelog};
 
 /*!
  * \brief Enumerates the currency names

+ 1 - 1
src/testing/importCrewlounge/importcrewlounge.cpp

@@ -63,6 +63,6 @@ void exec(const QString &csv_file_path)
 
     // destroy blocker
     blocker.unblock();
-    emit DB->dataBaseUpdated();
+    emit DB->dataBaseUpdated(OPL::DbTable::Any);
 }
 }// namespace ImportCrewLongue