Browse Source

WIP on database views

Started work on moving the display of database data from the SQL side (with views) into the application side (using Delegates to dynamically paint the db values in human readable formatting).
Felix Turowsky 1 year ago
parent
commit
74efb02655

+ 13 - 1
CMakeLists.txt

@@ -120,6 +120,8 @@ set(PROJECT_SOURCES
     src/classes/time.cpp
     src/classes/easaftl.h
     src/classes/easaftl.cpp
+    src/classes/defaultlogbookview.h
+    src/classes/defaultlogbookview.cpp
 
     # Database Entries
     src/database/flightentry.h
@@ -136,6 +138,16 @@ set(PROJECT_SOURCES
     src/database/simulatorentry.cpp
     src/database/currencyentry.h
     src/database/currencyentry.cpp
+    src/classes/date.h
+    src/classes/date.cpp
+    src/classes/styleddatedelegate.h
+    src/classes/styleddatedelegate.cpp
+    src/classes/styledtimedelegate.h
+    src/classes/styledtimedelegate.cpp
+    src/classes/styledpilotdelegate.h
+    src/classes/styledpilotdelegate.cpp
+    src/classes/styledregistrationdelegate.h
+    src/classes/styledregistrationdelegate.cpp
 
     src/database/previousexperienceentry.h
     src/database/previousexperienceentry.cpp
@@ -228,7 +240,7 @@ if(WIN32)
         )
     endif()
 else()
-    if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
+if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
         qt_add_executable(openPilotLog
             ${PROJECT_SOURCES}
             ${QM_FILES}

+ 7 - 2
mainwindow.cpp

@@ -17,6 +17,7 @@
  */
 #include <QToolBar>
 #include "mainwindow.h"
+#include "src/classes/defaultlogbookview.h"
 #include "ui_mainwindow.h"
 #include "src/database/database.h"
 #include "src/classes/style.h"
@@ -29,8 +30,12 @@
 // Quick and dirty Debug area
 void MainWindow::doDebugStuff()
 {
-    LOG << "Setup completed? ";
-    LOG << Settings::getSetupCompleted();
+    auto widget = new QWidget(this);
+    widget->setWindowFlags(Qt::Dialog);
+    auto layout = new QGridLayout();
+    layout->addWidget(new DefaultLogbookView(this));
+    widget->setLayout(layout);
+    widget->show();
 }
 
 MainWindow::MainWindow(QWidget *parent)

+ 25 - 0
src/classes/date.cpp

@@ -0,0 +1,25 @@
+#include "date.h"
+
+namespace OPL {
+
+Date::Date(int julianDay)
+{
+    date = QDate::fromJulianDay(julianDay);
+}
+
+const QString Date::toString(Format format) const
+{
+    switch (format) {
+    case Default:
+        return date.toString(Qt::ISODate);
+    case SystemLocaleLong:
+        return date.toString(QLocale::system().dateFormat(QLocale::LongFormat));
+    case SystemLocaleShort:
+        return date.toString(QLocale::system().dateFormat(QLocale::ShortFormat));
+    default:
+        return QString();
+    }
+}
+
+
+} // namespace OPL

+ 43 - 0
src/classes/date.h

@@ -0,0 +1,43 @@
+#ifndef DATE_H
+#define DATE_H
+#include <QDate>
+#include <QLocale>
+namespace OPL {
+
+/*!
+ * \brief The Date class wraps the QDate class.
+ * \details The QDate class stores dates internally as a Julian Day number,
+ * an integer count of every day in a contiguous range, with 24 November 4714 BCE
+ * in the Gregorian calendar being Julian Day 0 (1 January 4713 BCE in the Julian calendar).
+ *
+ * Storing a given date as an integer value allows for easy conversion to localised strings
+ * as well as calculations like date ranges.
+ */
+class Date
+{
+public:
+
+    /*!
+     * \brief Enumerates how dates can be formatted to a localised format.
+     * \value Default - The Application standard, Equivalent to Qt::ISODate
+     * \value SystemLocaleLong - The current system locale, elaborate
+     * \value SystemLocaleShort - The current system locale, short
+     */
+    enum Format {Default, SystemLocaleLong, SystemLocaleShort};
+
+    Date() = delete;
+
+    Date(int julianDay);
+
+    const static inline Date fromJulianDay(int julianDay) { return Date(julianDay); }
+
+    const QString toString(Format format = Format::Default) const;
+
+private:
+    QDate date;
+
+};
+
+} // namespace OPL
+
+#endif // DATE_H

+ 65 - 0
src/classes/defaultlogbookview.cpp

@@ -0,0 +1,65 @@
+#include "defaultlogbookview.h"
+#include "QtWidgets/qheaderview.h"
+#include "src/classes/styleddatedelegate.h"
+#include "src/classes/styledpilotdelegate.h"
+#include "src/classes/styledregistrationdelegate.h"
+#include "src/classes/styledtimedelegate.h"
+#include "src/database/database.h"
+#include "src/classes/settings.h"
+
+DefaultLogbookView::DefaultLogbookView(QWidget *parent)
+    : QTableView(parent)
+{
+    auto model = new QSqlTableModel(this, DB->database());
+    model->setTable(OPL::GLOBALS->getDbTableName(OPL::DbTable::Flights));
+    model->select();
+
+    model->setHeaderData(COL_DATE, Qt::Horizontal, tr("Date of Flight"));
+    model->setHeaderData(COL_DEPT, Qt::Horizontal, tr("Dept"));
+    model->setHeaderData(COL_DEST, Qt::Horizontal, tr("Dest"));
+    model->setHeaderData(COL_TOFB, Qt::Horizontal, tr("Time"));
+    model->setHeaderData(COL_TONB, Qt::Horizontal, tr("Time"));
+    model->setHeaderData(COL_PIC, Qt::Horizontal, tr("Name PIC"));
+    model->setHeaderData(COL_ACFT, Qt::Horizontal, tr("Registration"));
+    model->setHeaderData(COL_FLIGHT_NR, Qt::Horizontal, tr("Flight #"));
+    model->setHeaderData(COL_REMARKS, Qt::Horizontal, tr("Remarks"));
+
+    // set the item delegates for converting db values to human readable formatting
+    const auto dateDelegate = new StyledDateDelegate(Settings::getDateFormat(), this);
+    setItemDelegateForColumn(COL_DATE, dateDelegate);
+
+    const auto timeDelegate = new StyledTimeDelegate(this);
+    setItemDelegateForColumn(COL_TOFB, timeDelegate);
+    setItemDelegateForColumn(COL_TONB, timeDelegate);
+    setItemDelegateForColumn(COL_TBLK, timeDelegate);
+
+    const auto pilotDelegate = new StyledPilotDelegate(this);
+    setItemDelegateForColumn(COL_PIC, pilotDelegate);
+
+    const auto registrationDelegate = new StyledRegistrationDelegate(this);
+    setItemDelegateForColumn(COL_ACFT, registrationDelegate);
+
+
+    setModel(model);
+    setSelectionBehavior(QAbstractItemView::SelectRows);
+    setSelectionMode(QAbstractItemView::ExtendedSelection);
+    setEditTriggers(QAbstractItemView::NoEditTriggers);
+    setContextMenuPolicy(Qt::CustomContextMenu);
+    resizeColumnsToContents();
+    horizontalHeader()->setStretchLastSection(QHeaderView::Stretch);
+    verticalHeader()->hide();
+    setAlternatingRowColors(true);
+
+    for(int i = 0; i < COLUMN_COUNT; i++) {
+        hideColumn(i);
+    }
+    showColumn(COL_DATE);
+    showColumn(COL_ACFT);
+    showColumn(COL_PIC);
+    showColumn(COL_TONB);
+    showColumn(COL_DEPT);
+    showColumn(COL_DEST);
+    showColumn(COL_TOFB);
+    showColumn(COL_FLIGHT_NR);
+    showColumn(COL_REMARKS);
+}

+ 49 - 0
src/classes/defaultlogbookview.h

@@ -0,0 +1,49 @@
+#ifndef DEFAULTLOGBOOKVIEW_H
+#define DEFAULTLOGBOOKVIEW_H
+
+#include <QTableView>
+
+class DefaultLogbookView : public QTableView
+{
+public:
+    DefaultLogbookView(QWidget *parent = nullptr);
+private:
+    const static int COL_ID   = 0;
+    const static int COL_DATE = 1;
+    const static int COL_DEPT = 2;
+    const static int COL_DEST = 3;
+    const static int COL_TOFB = 4;
+    const static int COL_TONB = 5;
+    const static int COL_PIC  = 6;
+    const static int COL_ACFT = 7;
+    const static int COL_TBLK = 8;
+    const static int COL_TSPSE = 9;
+    const static int COL_TSPME = 10;
+    const static int COL_TMP = 11;
+    const static int COL_TNIGHT = 12;
+    const static int COL_TIFR = 13;
+    const static int COL_TPIC = 14;
+    const static int COL_TPICUS = 15;
+    const static int COL_TSIC = 16;
+    const static int COL_TDUAL = 17;
+    const static int COL_TFI = 18;
+    const static int COL_TSIM = 19;// do not use, use sim table TODO: remove from DB
+    const static int COL_PF = 20;
+    const static int COL_TO_DAY = 21;
+    const static int COL_TO_NIGHT = 22;
+    const static int COL_LDG_DAY = 23;
+    const static int COL_LDG_NIGHT = 24;
+    const static int COL_AUTOLAND = 25;
+    const static int COL_SECOND_PILOT = 26;
+    const static int COL_THIRD_PILOT = 27;
+    const static int COL_APP_TYPE = 28;
+    const static int COL_FLIGHT_NR = 29;
+    const static int COL_REMARKS = 30;
+
+    const static int COLUMN_COUNT = 31;
+
+
+
+};
+
+#endif // DEFAULTLOGBOOKVIEW_H

+ 1 - 1
src/classes/settings.cpp

@@ -35,7 +35,7 @@ void Settings::resetToDefaults()
     setApplicationStyle(QStringLiteral("Fusion"));
     setUseSystemFont(true);
     setLogbookView(OPL::LogbookView::Default);
-    setDateFormat(OPL::DateFormat::ISODate);
+    setDateFormat(OPL::Date::Format::Default);
     setLogAsPilotFlying(true);
     setNightAngle(-6);
     setShowSelfAs(0);

+ 10 - 20
src/classes/settings.h

@@ -17,8 +17,8 @@
  */
 #ifndef SETTINGS_H
 #define SETTINGS_H
-#include "src/database/currencyentry.h"
 #include "src/opl.h"
+#include "src/classes/date.h"
 #include <QtCore>
 #include <QSettings>
 
@@ -110,12 +110,12 @@ public:
     /*!
      * \brief returns the date format to be used in the application
      */
-    static OPL::DateFormat getDateFormat() { return OPL::DateFormat(settingsInstance->value(MAIN_DATE_FORMAT).toInt()); }
+    static OPL::Date::Format getDateFormat() { return OPL::Date::Format(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))); }
+    static void setDateFormat(OPL::Date::Format format) { (settingsInstance->setValue(MAIN_DATE_FORMAT, static_cast<int>(format))); }
 
     /*!
      * \brief returns the default pilot function for new flights
@@ -232,23 +232,13 @@ private:
     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")},
-        };
+    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");
 
 };
 

+ 13 - 0
src/classes/styleddatedelegate.cpp

@@ -0,0 +1,13 @@
+#include "styleddatedelegate.h"
+
+StyledDateDelegate::StyledDateDelegate(OPL::Date::Format dateFormat, QObject *parent)
+    :
+    QStyledItemDelegate(parent),
+    m_dateFormat(dateFormat)
+{}
+
+QString StyledDateDelegate::displayText(const QVariant &value, const QLocale &locale) const
+{
+    const OPL::Date date(value.toInt());
+    return date.toString(m_dateFormat);
+}

+ 23 - 0
src/classes/styleddatedelegate.h

@@ -0,0 +1,23 @@
+#ifndef STYLEDDATEDELEGATE_H
+#define STYLEDDATEDELEGATE_H
+
+#include <QStyledItemDelegate>
+#include "src/classes/date.h"
+
+/*!
+ * \brief The StyledDateDelegate class is used to display a database date value human-readable.
+ * \details The database stores dates as an integer representing the days elapsed since the
+ * beginning of the julian calendar. This integer has to be converted to a human-readable date
+ * according to the users selected date format.
+ */
+class StyledDateDelegate : public QStyledItemDelegate
+{
+public:
+    StyledDateDelegate(OPL::Date::Format dateFormat, QObject * parent = nullptr);
+
+    QString displayText(const QVariant &value, const QLocale &locale) const override;
+private:
+    OPL::Date::Format m_dateFormat;
+};
+
+#endif // STYLEDDATEDELEGATE_H

+ 13 - 0
src/classes/styledpilotdelegate.cpp

@@ -0,0 +1,13 @@
+#include "styledpilotdelegate.h"
+#include "src/database/databasecache.h"
+
+StyledPilotDelegate::StyledPilotDelegate(QObject *parent)
+    : QStyledItemDelegate{parent}
+{
+
+}
+
+QString StyledPilotDelegate::displayText(const QVariant &value, const QLocale &locale) const
+{
+    return DBCache->getPilotNamesMap().value(value.toInt());
+}

+ 20 - 0
src/classes/styledpilotdelegate.h

@@ -0,0 +1,20 @@
+#ifndef STYLEDPILOTDELEGATE_H
+#define STYLEDPILOTDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+/*!
+ * \brief The StyledPilotDelegate class is used to display a database date value human-readable.
+ * \details The database stores pilots as an integer representing a foreign key into a database
+ * of pilots. This delegate uses the Database cache to map this ID to a name and displays the name
+ * in the view.
+ */
+class StyledPilotDelegate : public QStyledItemDelegate
+{
+public:
+    explicit StyledPilotDelegate(QObject *parent = nullptr);
+
+    QString displayText(const QVariant &value, const QLocale &locale) const override;
+};
+
+#endif // STYLEDPILOTDELEGATE_H

+ 14 - 0
src/classes/styledregistrationdelegate.cpp

@@ -0,0 +1,14 @@
+#include "styledregistrationdelegate.h"
+#include "src/database/databasecache.h"
+
+StyledRegistrationDelegate::StyledRegistrationDelegate(QObject *parent)
+    : QStyledItemDelegate{parent}
+{
+
+}
+
+QString StyledRegistrationDelegate::displayText(const QVariant &value, const QLocale &locale) const
+{
+    return DBCache->getTailsMap().value(value.toInt());
+
+}

+ 20 - 0
src/classes/styledregistrationdelegate.h

@@ -0,0 +1,20 @@
+#ifndef STYLEDREGISTRATIONDELEGATE_H
+#define STYLEDREGISTRATIONDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+/*!
+ * \brief The StyledRegistrationDelegate class is used to display a database date value human-readable.
+ * \details The database stores tails as an integer representing a foreign key into a database
+ * of tails. This delegate uses the Database cache to map this ID to a registration to display
+ * in the view.
+ */
+class StyledRegistrationDelegate : public QStyledItemDelegate
+{
+public:
+    explicit StyledRegistrationDelegate(QObject *parent = nullptr);
+
+    QString displayText(const QVariant &value, const QLocale &locale) const override;
+};
+
+#endif // STYLEDREGISTRATIONDELEGATE_H

+ 12 - 0
src/classes/styledtimedelegate.cpp

@@ -0,0 +1,12 @@
+#include "styledtimedelegate.h"
+#include "src/classes/time.h"
+
+StyledTimeDelegate::StyledTimeDelegate(QObject *parent)
+    : QStyledItemDelegate{parent}
+{}
+
+QString StyledTimeDelegate::displayText(const QVariant &value, const QLocale &locale) const
+{
+    const OPL::Time time(value.toInt());
+    return time.toString();
+}

+ 19 - 0
src/classes/styledtimedelegate.h

@@ -0,0 +1,19 @@
+#ifndef STYLEDTIMEDELEGATE_H
+#define STYLEDTIMEDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+/*!
+ * \brief The StyledTimeDelegate class is used to convert the database time format to a human-readable format.
+ * \details The database stores time values as an integer representing minutes elapsed since midnight. This
+ * delegate can be used in a QTableView to format the database value as "hh:mm"
+ */
+class StyledTimeDelegate : public QStyledItemDelegate
+{
+public:
+    explicit StyledTimeDelegate(QObject *parent = nullptr);
+
+    QString displayText(const QVariant &value, const QLocale &locale) const override;
+};
+
+#endif // STYLEDTIMEDELEGATE_H

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

@@ -15,6 +15,7 @@
  *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 "src/classes/defaultlogbookview.h"
 #include "src/classes/time.h"
 #include "src/database/database.h"
 #include "logbookwidget.h"
@@ -43,7 +44,6 @@ LogbookWidget::LogbookWidget(QWidget *parent) :
     view = ui->tableView;
 
     setupModelAndView(Settings::getLogbookView());
-//    setupModelAndView(Settings::read(Settings::Main::LogbookView).toInt());
     connectSignalsAndSlots();
 
 }