Browse Source

Adjustments to CurrencyTable and FirstRunDialog

Fixed some quirks in FirstRunDialog and CurrencyWidget to make them compatible with new database format.
Felix 1 year ago
parent
commit
f3684e5d72

+ 0 - 1
assets/database/database_schema.sql

@@ -93,7 +93,6 @@ 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';

+ 0 - 1
assets/database/templates.qrc

@@ -3,7 +3,6 @@
         <file>templates/aircraft.json</file>
         <file>templates/airports.json</file>
         <file>templates/changelog.json</file>
-        <file>templates/currencies.json</file>
         <file>database_schema.sql</file>
     </qresource>
 </RCC>

+ 0 - 37
assets/database/templates/currencies.json

@@ -1,37 +0,0 @@
-[
-    {
-        "currency_id": 1,
-        "currencyName": "Licence",
-        "expiryDate": null
-    },
-    {
-        "currency_id": 2,
-        "currencyName": "Type Rating",
-        "expiryDate": null
-    },
-    {
-        "currency_id": 3,
-        "currencyName": "Line Check",
-        "expiryDate": null
-    },
-    {
-        "currency_id": 4,
-        "currencyName": "Medical",
-        "expiryDate": null
-    },
-    {
-        "currency_id": 5,
-        "currencyName": "Custom1",
-        "expiryDate": null
-    },
-    {
-        "currency_id": 6,
-        "currencyName": "Custom2",
-        "expiryDate": null
-    },
-    {
-        "currency_id": 7,
-        "currencyName": "Take Off / Landing",
-        "expiryDate": null
-    }
-]

+ 40 - 33
main.cpp

@@ -33,24 +33,57 @@
 #include <QDebug>
 #include <QTranslator>
 
+
+
+/*!
+ * \brief firstRun - is run if the application is run for the first time and launches
+ * the FirstRunDialog which guides the user through the initial set-up process.
+ */
+bool firstRun()
+{
+    if(FirstRunDialog().exec() == QDialog::Rejected){
+        LOG << "Initial setup incomplete or unsuccessfull.";
+        return false;
+    }
+
+    Settings::setSetupCompleted(true);
+    LOG << "Initial Setup Completed successfully";
+    QMessageBox mb;
+    mb.setText("Initial set-up has been completed successfully.<br><br>Please re-start the application.");
+    mb.exec();
+    return true;
+}
+
+
 /*!
  * \brief init - Sets up the logging facilities, loads the user settings and sets
  * up the application style before the MainWindow is instantiated
  */
-void init()
+bool init()
 {
+    // Check if another instance of the application is already running, we don't want
+    // different processes writing to the same database
+    RunGuard guard(QStringLiteral("opl_single_key"));
+    if ( !guard.tryToRun() ){
+        LOG << "Another Instance of openPilotLog is already running. Exiting.";
+        return false;
+    }
+
     LOG << "Setting up / verifying Application Directories...";
     if(OPL::Paths::setup()) {
         LOG << "Application Directories... verified";
     } else {
+        return false;
         LOG << "Unable to create directories.";
     }
+
     LOG << "Setting up logging facilities...";
     if(OPL::Log::init(true)) {
         LOG << "Logging enabled.";
     } else {
         LOG << "Unable to initalise logging.";
     }
+
     LOG << "Reading Settings...";
     Settings::init();
     LOG << "Setting up application style...";
@@ -58,26 +91,12 @@ void init()
     // Translations to be done at a later stage
     //LOG << "Installing translator...";
     //ATranslator::installTranslator(OPL::Translations::English);
-}
 
-/*!
- * \brief firstRun - is run if the application is run for the first time and launches
- * the FirstRunDialog which guides the user through the initial set-up process.
- */
-int firstRun()
-{
-    if(FirstRunDialog().exec() == QDialog::Rejected){
-        LOG << "Initial setup incomplete or unsuccessfull.";
-        return 1;
-    }
+    // Check for First Run and launch Setup Wizard
+    if(!Settings::getSetupCompleted())
+        return firstRun();
 
-    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.");
-    mb.exec();
-    return 0;
+    return true;
 }
 
 int main(int argc, char *argv[])
@@ -87,22 +106,10 @@ int main(int argc, char *argv[])
     QCoreApplication::setOrganizationDomain(ORGDOMAIN);
     QCoreApplication::setApplicationName(APPNAME);
 
-    // Check of another instance of the application is already running, we don't want
-    // different processes writing to the same database
-    RunGuard guard(QStringLiteral("opl_single_key"));
-    if ( !guard.tryToRun() ){
-        LOG << "Another Instance of openPilotLog is already running. Exiting.";
-        return 0;
-    }
-
     // Set Up the Application
-    init();
+    if(!init())
+        return 1;
 
-    // Check for First Run and launch Setup Wizard
-//    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__

+ 2 - 0
src/classes/date.h

@@ -47,6 +47,8 @@ public:
         }
     }
 
+    const inline int toJulianDay() const { return date.toJulianDay(); }
+
     const static inline Date fromJulianDay(int julianDay) { return Date(julianDay); }
 
     const static inline Date today() { return Date(QDate::currentDate().toJulianDay()); }

+ 8 - 20
src/database/currencyentry.cpp

@@ -16,18 +16,9 @@
  *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(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)
 {}
@@ -37,31 +28,28 @@ const QString CurrencyEntry::getTableName() const
     return TABLE_NAME;
 }
 
-void CurrencyEntry::setDisplayName(const QString &displayName)
+void CurrencyEntry::setName(const QString &displayName)
 {
     auto data = getData();
-    data.insert(DISPLAY_NAME, displayName);
+    data.insert(NAME, displayName);
     setData(data);
-    DB->commit(*this);
 }
 
-const QString CurrencyEntry::getDisplayName() const
+const QString CurrencyEntry::getName() const
 {
-    return getData().value(DISPLAY_NAME).toString();
+    return getData().value(NAME).toString();
 }
 
-void CurrencyEntry::setExpiryDate(const QDate &date)
+void CurrencyEntry::setExpiryDate(const Date &date)
 {
     auto data = getData();
-    data.insert(EXPIRYDATE, date.toString(Qt::ISODate));
+    data.insert(EXPIRYDATE, date.toJulianDay());
     setData(data);
-    DB->commit(*this);
 }
 
-const QDate CurrencyEntry::getExpiryDate() const
+const Date CurrencyEntry::getExpiryDate() const
 {
-    const QString &date = getData().value(EXPIRYDATE).toString();
-    return QDate::fromString(date, Qt::ISODate);
+    return OPL::Date(getData().value(EXPIRYDATE).toInt());
 }
 
 } // namespace OPL

+ 10 - 9
src/database/currencyentry.h

@@ -18,6 +18,7 @@
 #ifndef CURRENCYENTRY_H
 #define CURRENCYENTRY_H
 #include "src/database/row.h"
+#include "src/classes/date.h"
 
 namespace OPL {
 
@@ -39,19 +40,15 @@ public:
 
     const QString getTableName() const override;
 
-    void setDisplayName(const QString& displayName);
-    const QString getDisplayName() const;
+    void setName(const QString& displayName);
+    const QString getName() const;
 
-    void setExpiryDate(const QDate &date);
-    const QDate getExpiryDate() const;
+    void setExpiryDate(const OPL::Date &date);
+    const OPL::Date 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
@@ -61,7 +58,11 @@ private:
     /*!
      * \brief The sql column name for the display name
      */
-    const static inline QString DISPLAY_NAME = QStringLiteral("displayName");
+    const static inline QString NAME = QStringLiteral("currencyName");
+    /*!
+    * \brief The sql column name for the expiry date
+    */
+    const static inline QString EXPIRYDATE  = QStringLiteral("expiryDate");
 
     const static inline QString TABLE_NAME = QStringLiteral("currencies");
 };

+ 26 - 15
src/gui/dialogues/firstrundialog.cpp

@@ -187,7 +187,10 @@ bool FirstRunDialog::finishSetup()
         return false;
     }
 
-    writeCurrencies();
+    // non-critical error
+    if(!writeCurrencies())
+        LOG << "Error writing currencies during initial setup.";
+
     DB->disconnect(); // Connection will be re-established by MainWindow
     return true;
 }
@@ -344,28 +347,36 @@ bool FirstRunDialog::setupPreviousExperienceEntry()
     return DB->commit(pXpEntry);
 }
 
-void FirstRunDialog::writeCurrencies()
+bool FirstRunDialog::writeCurrencies()
 {
-    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},
+    const QList<QPair<QString, QDateEdit*>> currencies = {
+        { ui->currLicLabel->text(), 		ui->currLicDateEdit },
+        { ui->currTrLabel->text(), 			ui->currTrDateEdit },
+        { ui->currLckLabel->text(), 		ui->currLckDateEdit },
+        { ui->currMedLabel->text(), 		ui->currMedDateEdit },
+        { ui->currCustom1LineEdit->text(), 	ui->currCustom1DateEdit },
+        { ui->currCustom2LineEdit->text(), 	ui->currCustom2DateEdit },
     };
 
     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));
+    for(const auto &pair : currencies) {
+        // list 0-indexed, db row indexes start at 1
+        OPL::CurrencyEntry currencyEntry = OPL::CurrencyEntry(currencies.indexOf(pair) + 1, OPL::RowData_T());
+
+        currencyEntry.setName(pair.first);
 
         // only set expiry date if user has modified it
-        const QDate date = std::get<2>(tuple)->date();
-        if(date != today)
-            currencyEntry.setExpiryDate(date);
+        const QDate date = pair.second->date();
+        if(date != today) {
+            int julianDay = date.toJulianDay();
+            currencyEntry.setExpiryDate(OPL::Date(julianDay));
+        }
+
+        if(!DB->commit(currencyEntry))
+            return false;
     }
+    return true;
 }
 
 void FirstRunDialog::reject()

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

@@ -124,7 +124,7 @@ private:
     /*!
      * \brief writeCurrencies - submits the user input to the currencies table in the database
      */
-    void writeCurrencies();
+    bool writeCurrencies();
 
     /*!
      * \brief downloadTemplates - Downloads the airports and aircraft database as JSON files from github

+ 55 - 34
src/gui/widgets/currencywidget.cpp

@@ -1,8 +1,9 @@
 #include "currencywidget.h"
 #include "QtSql/qsqltablemodel.h"
-#include "QtWidgets/qgridlayout.h"
 #include "QtWidgets/qheaderview.h"
+#include "qgridlayout.h"
 #include "src/classes/easaftl.h"
+#include "src/classes/styleddatedelegate.h"
 #include "src/classes/time.h"
 #include "src/database/database.h"
 #include "src/functions/statistics.h"
@@ -37,17 +38,19 @@ void CurrencyWidget::setupModelAndView()
     model->setHeaderData(EXPIRY_DATE_COLUMN, Qt::Horizontal, tr("Expiry Date"));
     model->setHeaderData(CURRENCY_NAME_COLUMN, Qt::Horizontal, tr("Name"));
 
-    tableView = new QTableView(this);
-    tableView->setModel(model);
-    tableView->setSelectionMode(QAbstractItemView::SingleSelection);
-    tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
-    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
-    tableView->resizeColumnsToContents();
-    tableView->horizontalHeader()->setStretchLastSection(QHeaderView::Stretch);
-    tableView->verticalHeader()->hide();
-    tableView->setAlternatingRowColors(true);
-    tableView->hideColumn(0);
-    tableView->hideColumn(1); // TODO remove once sql table is adjusted
+    view = new QTableView(this);
+    view->setModel(model);
+    view->setSelectionMode(QAbstractItemView::SingleSelection);
+    view->setSelectionBehavior(QAbstractItemView::SelectItems);
+    view->setEditTriggers(QAbstractItemView::NoEditTriggers);
+    view->resizeColumnsToContents();
+    view->horizontalHeader()->setStretchLastSection(QHeaderView::Stretch);
+    view->verticalHeader()->hide();
+    view->setAlternatingRowColors(true);
+    view->hideColumn(ROWID_COLUMN);
+
+    const auto dateDelegate = new StyledDateDelegate(Settings::getDateFormat(), this);
+    view->setItemDelegateForColumn(EXPIRY_DATE_COLUMN, dateDelegate);
 }
 
 void CurrencyWidget::setupUI()
@@ -102,7 +105,7 @@ void CurrencyWidget::setupUI()
     row++;
     gridLayout->addWidget(getHorizontalLine(), row, colL, singleRowSpan, allColSpan);
     row++;
-    gridLayout->addWidget(tableView, row, colL, singleRowSpan, allColSpan);
+    gridLayout->addWidget(view, row, colL, singleRowSpan, allColSpan);
 
     // set the layout active
     layout = gridLayout;
@@ -114,7 +117,7 @@ void CurrencyWidget::setupUI()
 
 
     // connect signals
-    QObject::connect(tableView,	&QTableView::activated,
+    QObject::connect(view,	&QTableView::activated,
                      this, &CurrencyWidget::editRequested);
     QObject::connect(calendar, &QCalendarWidget::selectionChanged,
                      this, &CurrencyWidget::newExpiryDateSelected);
@@ -168,27 +171,16 @@ void CurrencyWidget::fillFlightTimeLimitations()
 
 void CurrencyWidget::editRequested(const QModelIndex &index)
 {
-    lastSelection = index;
-    const QString selection = index.data().toString();
-    const QDate selectedDate = QDate::fromString(selection, dateFormat);
-    if(selectedDate.isValid()) {
-        // the date column has been selected for editing
-        const QSignalBlocker blocker(calendar);
-        calendar->setSelectedDate(selectedDate);
-        calendar->show();
-    } else {
-        // the displayName column has been selected for editing
+    if(index.column() == EXPIRY_DATE_COLUMN) {
+        expiryDateEditRequested(index);
+    }
+
+    if(index.column() == CURRENCY_NAME_COLUMN) {
         displayNameEditRequested(index);
     }
 }
 
-void CurrencyWidget::newExpiryDateSelected()
-{
-    calendar->hide();
-    const QString selectedDate = calendar->selectedDate().toString(dateFormat);
-    model->setData(lastSelection, selectedDate);
-    model->submitAll();
-}
+
 
 void CurrencyWidget::refresh()
 {
@@ -197,17 +189,46 @@ void CurrencyWidget::refresh()
     fillFlightTimeLimitations();
 }
 
-void CurrencyWidget::displayNameEditRequested(QModelIndex index)
+void CurrencyWidget::displayNameEditRequested(const QModelIndex &index)
 {
+    QString oldData = index.data().toString();
+    bool textEdited;
     const QString text = QInputDialog::getText(
         this,
         tr("Edit Currency Name"),
         tr("Please enter a name for this currency"),
         QLineEdit::Normal,
-        index.data().toString());
+        oldData,
+        &textEdited);
+
+    if(textEdited) {
+        model->setData(index, text);
+        model->submitAll();
+    }
+    view->resizeColumnsToContents();
 
-    model->setData(index, text);
+}
+
+void CurrencyWidget::expiryDateEditRequested(const QModelIndex &index)
+{
+    const QString selection = index.data().toString();
+    const QDate selectedDate = QDate::fromString(selection, dateFormat);
+    if(selectedDate.isValid()) {
+        const QSignalBlocker blocker(calendar);
+        calendar->setSelectedDate(selectedDate);
+        calendar->show();
+    } else {
+        calendar->show();
+    }
+    // calendars date selected signal is connected to newExpiryDateSelected()
+}
+
+void CurrencyWidget::newExpiryDateSelected()
+{
+    calendar->hide();
+    model->setData(view->selectionModel()->currentIndex(), calendar->selectedDate().toJulianDay());
     model->submitAll();
+    model->select();
 }
 
 void CurrencyWidget::warnAboutExpiries(int warningThreshold)

+ 13 - 10
src/gui/widgets/currencywidget.h

@@ -10,37 +10,40 @@ class CurrencyWidget : public QWidget
 {
     Q_OBJECT
     QLayout* layout;
-    QTableView *tableView;
+    QTableView *view;
     QSqlTableModel *model;
     QCalendarWidget *calendar;
     QString dateFormat;
     QModelIndex lastSelection;
 
+    int ROWID_COLUMN = 0;
+    int CURRENCY_NAME_COLUMN = 1;
     int EXPIRY_DATE_COLUMN = 2;
-    int CURRENCY_NAME_COLUMN = 3;
 
     void setupModelAndView();
     void setupUI();
     void fillTakeOffAndLandingCurrencies();
     void fillFlightTimeLimitations();
-    void displayNameEditRequested(QModelIndex index);
     void warnAboutExpiries(int warningThreshold);
 
+    void displayNameEditRequested(const QModelIndex &index);
+    void expiryDateEditRequested(const QModelIndex &index);
+
     QFrame *getHorizontalLine();
     QLabel *takeOffLandingHeaderLabel   		= new QLabel(tr("<b>Take-off and Landing Currency<\b>"), this);
     QLabel *takeOffCountLabel					= new QLabel(tr("Take offs (last 90 days)"), this);
-    QLabel *takeOffCountDisplayLabel 			= new QLabel(QStringLiteral("<b>%1<\b>"), this);
+    QLabel *takeOffCountDisplayLabel 			= new QLabel(QStringLiteral("<b>%1</b>"), this);
     QLabel *landingCountLabel 					= new QLabel(tr("Landings (last 90 days)"), this);
-    QLabel *landingCountDisplayLabel			= new QLabel(QStringLiteral("<b>%1<\b>"), this);
+    QLabel *landingCountDisplayLabel			= new QLabel(QStringLiteral("<b>%1</b>"), this);
     QLabel *takeOffLandingExpiryLabel   		= new QLabel(tr("3 Take-offs and Landings expiry date"), this);
-    QLabel *takeOffLandingExpiryDisplayLabel    = new QLabel(QStringLiteral("<b>%1<\b>"), this);
-    QLabel *flightTimeHeaderLabel		   		= new QLabel(tr("<b>Flight Time Limitations<\b>"), this);
+    QLabel *takeOffLandingExpiryDisplayLabel    = new QLabel(QStringLiteral("<b>%1</b>"), this);
+    QLabel *flightTimeHeaderLabel		   		= new QLabel(tr("<b>Flight Time Limitations</b>"), this);
     QLabel *flightTime28DaysLabel 	    		= new QLabel(tr("Flight time (last 28 days)"), this);
-    QLabel *flightTime28DaysDisplayLabel 	    = new QLabel(QStringLiteral("<b>%1<\b>"), this);
+    QLabel *flightTime28DaysDisplayLabel 	    = new QLabel(QStringLiteral("<b>%1</b>"), this);
     QLabel *flightTime365DaysLabel 	    		= new QLabel(tr("FLight time (last 365 days)"), this);
-    QLabel *flightTime365DaysDisplayLabel 	    = new QLabel(QStringLiteral("<b>%1<\b>"), this);
+    QLabel *flightTime365DaysDisplayLabel 	    = new QLabel(QStringLiteral("<b>%1</b>"), this);
     QLabel *flightTimeCalendarYearLabel 		= new QLabel(tr("Flight time (this calendar year"),this);
-    QLabel *flightTimeCalendarYearDisplayLabel  = new QLabel(QStringLiteral("<b>%1<\b>"), this);
+    QLabel *flightTimeCalendarYearDisplayLabel  = new QLabel(QStringLiteral("<b>%1</b>"), this);
     QLabel *expiriesHeaderLabel			   		= new QLabel(tr("<b>Expiries<\b>"), this);
 
     enum class Colour {Red, Orange, None};

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

@@ -196,7 +196,7 @@ void PilotsWidget::onDeleteUnsuccessful()
     } else {
         QString constrained_flights_string;
         for (int i=0; i<constrained_flights.length(); i++) {
-            constrained_flights_string.append(getFlightSummary(constrained_flights[i]) + QStringLiteral("&nbsp;&nbsp;&nbsp;&nbsp;<br>"));
+            constrained_flights_string.append(OPL::FlightEntry(constrained_flights[i]).getFlightSummary() + QStringLiteral("&nbsp;&nbsp;&nbsp;&nbsp;<br>"));
             if (i>10) {
                 constrained_flights_string.append("<br>[...]<br>");
                 break;
@@ -232,10 +232,3 @@ const QString PilotsWidget::getPilotName(const OPL::PilotEntry &pilot) const
 
     return pilot.getLastName() + QLatin1String(", ") + pilot.getFirstName();
 }
-
-const QString PilotsWidget::getFlightSummary(const OPL::FlightEntry &flight) const
-{
-
-
-
-}

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

@@ -118,8 +118,6 @@ private:
 
     const QString getPilotName(const OPL::PilotEntry &pilot) const;
 
-    const QString getFlightSummary(const OPL::FlightEntry &flight) const;
-
     void setupModelAndView();
 
     void connectSignalsAndSlots();

+ 0 - 1
src/opl.h

@@ -265,7 +265,6 @@ const inline auto  DATABASE_SCHEMA               = QStringLiteral(":/database/da
 const inline auto  DATABASE_TEMPLATE_AIRCRAFT    = QStringLiteral(":/database/templates/aircraft.json");
 const inline auto  DATABASE_TEMPLATE_AIRPORT     = QStringLiteral(":/database/templates/airports.json");
 const inline auto  DATABASE_TEMPLATE_CHANGELOG   = QStringLiteral(":/database/templates/changelog.json");
-const inline auto  DATABASE_TEMPLATE_CURRENCIES  = QStringLiteral(":/database/templates/currencies.json");
 
 const inline auto  LOGO                          = QStringLiteral(":/icons/opl-icons/logos/logo_text.png");
 const inline auto  ICON_MAIN                     = QStringLiteral(":/icons/opl-icons/app/icon_main.png");