浏览代码

started work on FlightEntryEditDialog

This is a rework of the NewFlightDialog
Felix Turowsky 8 月之前
父节点
当前提交
8c8394894b
共有 7 个文件被更改,包括 466 次插入10 次删除
  1. 3 0
      CMakeLists.txt
  2. 12 9
      mainwindow.cpp
  3. 13 1
      src/gui/dialogues/entryeditdialog.h
  4. 310 0
      src/gui/dialogues/flightentryeditdialog.cpp
  5. 120 0
      src/gui/dialogues/flightentryeditdialog.h
  6. 7 0
      src/opl.cpp
  7. 1 0
      src/opl.h

+ 3 - 0
CMakeLists.txt

@@ -53,8 +53,11 @@ set(PROJECT_SOURCES
     src/gui/dialogues/exporttocsvdialog.h
     src/gui/dialogues/exporttocsvdialog.cpp
     src/gui/dialogues/exporttocsvdialog.ui
+
     src/gui/dialogues/entryeditdialog.h
     src/gui/dialogues/entryeditdialog.cpp
+    src/gui/dialogues/flightentryeditdialog.h
+    src/gui/dialogues/flightentryeditdialog.cpp
 
     # Widgets
     src/gui/widgets/homewidget.h

+ 12 - 9
mainwindow.cpp

@@ -17,6 +17,7 @@
  */
 #include <QToolBar>
 #include "mainwindow.h"
+#include "src/gui/dialogues/flightentryeditdialog.h"
 #include "src/gui/widgets/airporttableeditwidget.h"
 #include "src/gui/widgets/logbooktableeditwidget.h"
 #include "src/gui/widgets/pilottableeditwidget.h"
@@ -32,15 +33,17 @@
 #include "src/network/flightawarequery.h"
 void MainWindow::doDebugStuff()
 {
-    FlightAwareQuery query;
-    auto result = query.getFlightData("DY606", QDate::currentDate());
-    LOG << "Querying API...";
-    if(result.isEmpty()) {
-        LOG << "No flights found.";
-    }
-    for(const auto &flight : result) {
-        flight.print();
-    }
+    // FlightAwareQuery query;
+    // auto result = query.getFlightData("DY606", QDate::currentDate());
+    // LOG << "Querying API...";
+    // if(result.isEmpty()) {
+    //     LOG << "No flights found.";
+    // }
+    // for(const auto &flight : result) {
+    //     flight.print();
+    // }
+    FlightEntryEditDialog feed = new FlightEntryEditDialog(this);
+    feed.exec();
 }
 
 MainWindow::MainWindow(QWidget *parent)

+ 13 - 1
src/gui/dialogues/entryeditdialog.h

@@ -1,13 +1,14 @@
 #ifndef ENTRYEDITDIALOG_H
 #define ENTRYEDITDIALOG_H
 
+#include "src/database/row.h"
 #include <QDialog>
 #include <QObject>
 
 /*!
  * \brief The EntryEditDialog class is a base class for Dialogs that enable editing of individual database entries
  */
-class EntryEditDialog : public QDialog
+class  EntryEditDialog : public QDialog
 {
     Q_OBJECT
 public:
@@ -21,6 +22,17 @@ public:
      */
     virtual void loadEntry(int rowID) = 0;
 
+    /*!
+     * \brief load an entry for editing
+     * \param entry - The (stub) entry.
+     * \details This function can be used to edit an incomplete entry which may or may not exist in the
+     * database yet.
+     */
+    virtual void loadEntry(OPL::Row entry) {
+        TODO << "Implement in all subclasses";
+        qApp->quit();
+    }
+
     /*!
      * \brief delete an entry from the database
      * \param rowID - the row ID to be deleted

+ 310 - 0
src/gui/dialogues/flightentryeditdialog.cpp

@@ -0,0 +1,310 @@
+#include "flightentryeditdialog.h"
+#include "src/classes/date.h"
+#include "src/gui/verification/airportinput.h"
+#include "src/gui/verification/timeinput.h"
+#include <src/classes/settings.h>
+#include <QGridLayout>
+#include <QDialogButtonBox>
+
+FlightEntryEditDialog::FlightEntryEditDialog(QWidget *parent)
+    : EntryEditDialog(parent)
+{
+    init();
+}
+
+FlightEntryEditDialog::FlightEntryEditDialog(int rowId, QWidget *parent)
+    : EntryEditDialog(parent)
+{
+    init();
+}
+
+void FlightEntryEditDialog::loadEntry(int rowID)
+{
+
+}
+
+void FlightEntryEditDialog::loadEntry(OPL::Row entry)
+{
+
+}
+
+bool FlightEntryEditDialog::deleteEntry(int rowID)
+{
+
+}
+
+void FlightEntryEditDialog::init()
+{
+    setupUI();
+    // initialise QCompleters
+    // load ComboBoxes
+
+    // set up the pop-up date selection
+    calendarWidget = new QCalendarWidget(this);
+    calendarWidget->setVisible(false);
+    calendarWidget->setWindowFlag(Qt::Dialog);
+
+    setupSignalsAndSlots();
+}
+
+void FlightEntryEditDialog::setupUI()
+{
+    // setup layout
+    // const int column0 = 0;
+    // const int column1 = 1;
+    // const int column2 = 2;
+    // const int column3 = 3;
+    // const int allColSpan = 4;
+    QGridLayout *layout = new QGridLayout(this);
+    const int lastCol = 4;
+    int column = 0;
+    int row = 0;
+
+    registrationLineEdit.setObjectName(QStringLiteral("registrationLineEdit"));
+    layout->addWidget(&dateButton, row, column++);
+    layout->addWidget(&dateLineEdit, row, column++);
+    layout->addWidget(&dateDisplayLabel, row, column++);
+    layout->addWidget(&registrationLabel, row, column++);
+    layout->addWidget(&registrationLineEdit, row, column);
+
+    column = 0;
+    firstPilotLineEdit.setObjectName(QStringLiteral("firstPilotLineEdit"));
+    layout->addWidget(&departureLabel, ++row, column++);
+    layout->addWidget(&departureLineEdit, row, column++);
+    layout->addWidget(&departureDisplayLabel, row, column++);
+    layout->addWidget(&firstPilotLabel, row, column++);
+    layout->addWidget(&firstPilotLineEdit, row, column++);
+
+    column = 0;
+    secondPilotLineEdit.setObjectName(QStringLiteral("secondPilotLineEdit"));
+    layout->addWidget(&destinationLabel, ++row, column++);
+    layout->addWidget(&destinationLineEdit, row, column++);
+    layout->addWidget(&destinationDisplayLabel, row, column++);
+    layout->addWidget(&secondPilotLabel, row, column++);
+    layout->addWidget(&secondPilotLineEdit, row, column++);
+
+    column = 0;
+    thirdPilotLineEdit.setObjectName(QStringLiteral("thirdPilotLineEdit"));
+    timeOffLineEdit.setObjectName(QStringLiteral("timeOffLineEdit"));
+    layout->addWidget(&timeOutLabel, ++row, column++);
+    layout->addWidget(&timeOffLineEdit, row, column++);
+    column++;
+    layout->addWidget(&thirdPilotLabel, row, column++);
+    layout->addWidget(&thirdPilotLineEdit, row, column++);
+
+    column = 0;
+    timeInLineEdit.setObjectName(QStringLiteral("timeInLineEdit"));
+    layout->addWidget(&timeInLabel, ++row, column++);
+    layout->addWidget(&timeInLineEdit, row, column++);
+    column++;
+    layout->addWidget(&flightNumberLabel, row, column++);
+    layout->addWidget(&flightNumberLineEdit, row, column++);
+
+    column = 0;
+    layout->addWidget(&totalTimeLabel, ++row, column++);
+    layout->addWidget(&totalTimeDisplayLabel, row, column++);
+    column++;
+    layout->addWidget(&remarksLabel, row, column++);
+    layout->addWidget(&remarksLineEdit, row, column++);
+
+
+    column = 0;
+    layout->addWidget(&pilotFunctionLabel, ++row, column++);
+    layout->addWidget(&pilotFunctionComboBox, row, column++);
+    column++;
+    layout->addWidget(&pilotFlyingLabel, row, column++);
+    layout->addWidget(&pilotFlyingCheckBox, row, column++);
+
+
+    column = 0;
+    // TODO
+    // troubleshoot why this label is floating in the top right corner
+    takeOffCountLabel = new QLabel(tr("Take Off"), this);
+    landingCountLabel = new QLabel(tr("Landing"), this);
+    layout->addWidget(&approachTypeLabel, ++row, column++);
+    layout->addWidget(&approachTypeComboBox, row, column++);
+    column++;
+    layout->addWidget(takeOffCountLabel, row, column++);
+    layout->addWidget(&takeOffCountSpinBox, row, column++);
+
+    column = 0;
+    layout->addWidget(&flightRulesLabel, ++row, column++);
+    layout->addWidget(&flightRulesComboBox, row, column++);
+    column++;
+    layout->addWidget(landingCountLabel, row, column++);
+    layout->addWidget(&landingCountSpinBox, row, column++);
+
+    layout->addWidget(&acceptButtonBox, ++row, lastCol);
+
+    // initialise auto-completion
+    // finish up
+    OPL::GLOBALS->loadApproachTypes(&approachTypeComboBox);
+    OPL::GLOBALS->loadPilotFunctios(&pilotFunctionComboBox);
+    OPL::GLOBALS->loadFlightRules(&flightRulesComboBox);
+    takeOffCountSpinBox.setRange(0, 99);
+    landingCountSpinBox.setRange(0, 99);
+    totalTimeDisplayLabel.setEnabled(false);
+
+    readSettings();
+
+    // use the dateDisplayLabel as a spacer
+    OPL::Date today = OPL::Date::today(displayFormat);
+    dateLineEdit.setText(today.toString());
+    dateDisplayLabel.setMinimumWidth(200); // TODO make dynamic
+    dateDisplayLabel.setText(today.toString());
+
+}
+
+void FlightEntryEditDialog::setupSignalsAndSlots()
+{
+    // acceptButtonBox
+    QObject::connect(&acceptButtonBox, &QDialogButtonBox::accepted,
+                     this, &FlightEntryEditDialog::onDialogAccepted);
+    QObject::connect(&acceptButtonBox, &QDialogButtonBox::rejected,
+                     this, &FlightEntryEditDialog::reject);
+    // calendarWidget
+    QObject::connect(&dateButton, &QPushButton::clicked,
+                     this, &FlightEntryEditDialog::onCalendarRequested);
+    QObject::connect(calendarWidget, &QCalendarWidget::selectionChanged,
+                     this, &FlightEntryEditDialog::onCalendarDateSelected);
+    QObject::connect(calendarWidget, &QCalendarWidget::clicked,
+                     this, &FlightEntryEditDialog::onCalendarDateSelected);
+    // QLineEdits
+    QObject::connect(&dateLineEdit, &QLineEdit::editingFinished,
+                     this, &FlightEntryEditDialog::onDateEditingFinished);
+    QObject::connect(&timeOutLineEdit, &QLineEdit::editingFinished,
+
+                     this, &FlightEntryEditDialog::onTimeEditingFinished);
+    QObject::connect(&timeOffLineEdit, &QLineEdit::editingFinished,
+                     this, &FlightEntryEditDialog::onTimeEditingFinished);
+    QObject::connect(&timeOnLineEdit, &QLineEdit::editingFinished,
+                     this, &FlightEntryEditDialog::onTimeEditingFinished);
+    QObject::connect(&timeInLineEdit, &QLineEdit::editingFinished,
+                     this, &FlightEntryEditDialog::onTimeEditingFinished);
+
+    QObject::connect(&firstPilotLineEdit, &QLineEdit::editingFinished,
+                     this, &FlightEntryEditDialog::onNameEditingFinished);
+    QObject::connect(&secondPilotLineEdit, &QLineEdit::editingFinished,
+                     this, &FlightEntryEditDialog::onNameEditingFinished);
+    QObject::connect(&thirdPilotLineEdit, &QLineEdit::editingFinished,
+                     this, &FlightEntryEditDialog::onNameEditingFinished);
+
+    QObject::connect(&registrationLineEdit, &QLineEdit::editingFinished,
+                     this, &FlightEntryEditDialog::onRegistrationEditingFinished);
+
+}
+
+void FlightEntryEditDialog::readSettings()
+{
+    displayFormat = Settings::getDisplayFormat();
+
+    pilotFunctionComboBox.setCurrentIndex(static_cast<int>(Settings::getPilotFunction()));
+    approachTypeComboBox.setCurrentText(Settings::getApproachType());
+    flightRulesComboBox.setCurrentIndex(Settings::getLogIfr());
+    flightNumberLineEdit.setText(Settings::getFlightNumberPrefix());
+}
+
+bool FlightEntryEditDialog::verifyUserInput(QLineEdit *lineEdit, const UserInput &input)
+{
+    DEB << "Verifying user input: " << lineEdit->text();
+
+    if(!input.isValid()) {
+        QString fixed = input.fixup();
+        if(fixed == QString()) {
+            return false;
+        } else {
+            lineEdit->setText(fixed);
+            return true;
+        }
+    }
+    return true;
+}
+
+/*
+ * Slots
+ */
+
+void FlightEntryEditDialog::onDialogAccepted()
+{
+    LOG << "Dialog accepted";
+    accept();
+}
+
+void FlightEntryEditDialog::onCalendarRequested()
+{
+    calendarWidget->setVisible(true);
+}
+
+void FlightEntryEditDialog::onCalendarDateSelected()
+{
+    calendarWidget->setVisible(false);
+    dateLineEdit.setText(OPL::Date(calendarWidget->selectedDate(), dateTimeFormat).toString());
+}
+
+void FlightEntryEditDialog::onDateEditingFinished()
+{
+    OPL::Date date(dateLineEdit.text(), dateTimeFormat);
+
+    if(date.isValid()) {
+        clearBorder(dateLineEdit);
+        return;
+    }
+
+    setRedBorder(dateLineEdit);
+}
+
+void FlightEntryEditDialog::onTimeEditingFinished()
+{
+    auto lineEdit = this->findChild<QLineEdit*>(sender()->objectName());
+
+    if(verifyUserInput(lineEdit, TimeInput(lineEdit->text(), dateTimeFormat))) {
+        clearBorder(*lineEdit);
+        return;
+    }
+
+    setRedBorder(*lineEdit);
+}
+
+void FlightEntryEditDialog::onNameEditingFinished()
+{
+    // TODO
+    // - match with map
+    // - on negative match, offer to add new pilot entry
+    auto lineEdit = this->findChild<QLineEdit*>(sender()->objectName());
+
+    setRedBorder(*lineEdit);
+}
+
+void FlightEntryEditDialog::onRegistrationEditingFinished()
+{
+    // TODO
+    // - match with map
+    // - on negative match, offer to add new aircraft entry
+    auto lineEdit = this->findChild<QLineEdit*>(sender()->objectName());
+
+    setRedBorder(*lineEdit);
+}
+
+void FlightEntryEditDialog::onLocationEditingFinished()
+{
+    // determine which location line edit has been edited
+    const QString& lineEditName = sender()->objectName();
+    const auto lineEdit = this->findChild<QLineEdit*>(lineEditName);
+    QLabel *name_label;
+    if (lineEditName.contains(QLatin1String("departure")))
+        name_label = &departureDisplayLabel;
+    else
+        name_label = &destinationDisplayLabel;
+
+    // if(verifyUserInput(lineEdit, AirportInput(lineEdit->text())) ) {
+    //     // Match ICAO code with Airport Name and display on label
+    //     name_label->setText(DBCache->getAirportsMapNames().value(
+    //         DBCache->getAirportsMapICAO().key(
+    //             line_edit->text())));
+    // } else {
+    //     name_label->setText("Unknown Airport");
+    //     addNewDatabaseElement(line_edit, OPL::DbTable::Airports);
+    // }
+
+}
+

+ 120 - 0
src/gui/dialogues/flightentryeditdialog.h

@@ -0,0 +1,120 @@
+#ifndef FLIGHTENTRYEDITDIALOG_H
+#define FLIGHTENTRYEDITDIALOG_H
+
+#include <QLineEdit>
+#include <QSpinBox>
+#include <QComboBox>
+#include <QCheckBox>
+#include <QLabel>
+#include <QPushButton>
+#include <QDialogButtonBox>
+#include <QCalendarWidget>
+#include "entryeditdialog.h"
+#include "src/gui/verification/userinput.h"
+
+class FlightEntryEditDialog : public EntryEditDialog
+{
+public:
+    FlightEntryEditDialog(QWidget *parent = nullptr);
+    FlightEntryEditDialog(int rowId, QWidget *parent = nullptr);
+    virtual void loadEntry(int rowID) override;
+    virtual void loadEntry(OPL::Row entry) override;
+    virtual bool deleteEntry(int rowID) override;
+
+private:
+    OPL::DateTimeFormat dateTimeFormat = OPL::DateTimeFormat();
+
+    QLineEdit dateLineEdit = QLineEdit(this);
+    QLineEdit timeOutLineEdit = QLineEdit(this);
+    QLineEdit timeOffLineEdit = QLineEdit(this);
+    QLineEdit timeOnLineEdit =  QLineEdit(this);
+    QLineEdit timeInLineEdit = QLineEdit(this);
+
+    QLineEdit departureLineEdit = QLineEdit(this);
+    QLineEdit destinationLineEdit = QLineEdit(this);
+
+    QLineEdit firstPilotLineEdit =  QLineEdit(this);
+    QLineEdit secondPilotLineEdit = QLineEdit(this);
+    QLineEdit thirdPilotLineEdit = QLineEdit(this);
+
+    QLineEdit registrationLineEdit = QLineEdit(this);
+
+    QLineEdit remarksLineEdit = QLineEdit(this);
+    QLineEdit flightNumberLineEdit = QLineEdit(this);
+
+    QComboBox pilotFunctionComboBox = QComboBox(this);
+    QComboBox flightRulesComboBox = QComboBox(this);
+    QComboBox approachTypeComboBox = QComboBox(this);
+
+    QSpinBox takeOffCountSpinBox = QSpinBox(this);
+    QSpinBox landingCountSpinBox = QSpinBox(this);
+
+    QCheckBox pilotFlyingCheckBox = QCheckBox(this);
+
+    const QList<QLineEdit *> timeLineEdits = { &timeOutLineEdit, &timeOffLineEdit, &timeOnLineEdit, &timeInLineEdit };
+    const QList<QLineEdit *> pilotNameLineEdits = { &firstPilotLineEdit, &secondPilotLineEdit, &thirdPilotLineEdit };
+    const QList<QLineEdit *> mandatoryLineEdits = { &dateLineEdit, &timeOutLineEdit, &timeInLineEdit, &departureLineEdit,
+                                                    &destinationLineEdit, &firstPilotLineEdit, &registrationLineEdit };
+
+    QPushButton dateButton = QPushButton(tr("Date"), this);
+    QLabel dateDisplayLabel = QLabel(this);
+    QLabel timeOutLabel = QLabel(tr("Off Blocks"), this);
+    QLabel timeOffLabel = QLabel(tr("Take Off"), this);
+    QLabel timeOnLabel = QLabel(tr("Landing"), this);
+    QLabel timeInLabel = QLabel(tr("On Blocks"), this);
+    QLabel departureLabel = QLabel(tr("Departure"), this);
+    QLabel departureDisplayLabel = QLabel(this);
+    QLabel destinationLabel = QLabel(tr("Destination"), this);
+    QLabel destinationDisplayLabel = QLabel(this);
+    QLabel firstPilotLabel = QLabel(tr("PIC"), this);
+    QLabel secondPilotLabel = QLabel(tr("SIC"), this);
+    QLabel thirdPilotLabel = QLabel(tr("Third Pilot"), this);
+    QLabel registrationLabel = QLabel(tr("Registration"), this);
+    QLabel remarksLabel = QLabel(tr("Remarks"), this);
+    QLabel flightNumberLabel = QLabel(tr("Flight Number"), this);
+    QLabel pilotFlyingLabel = QLabel(tr("Pilot Flying"), this);
+    QLabel *takeOffCountLabel;
+    // QLabel takeOffCountLabel = QLabel(tr("Take Off"), this);
+    // QLabel landingCountLabel = QLabel(tr("Landing"), this);
+    QLabel *landingCountLabel;
+    QLabel totalTimeLabel = QLabel(tr("Total Time"), this);
+    QLabel totalTimeDisplayLabel = QLabel("00:00", this);
+    QLabel pilotFunctionLabel = QLabel(tr("Function"), this);
+    QLabel approachTypeLabel = QLabel(tr("Approach"), this);
+    QLabel flightRulesLabel = QLabel(tr("Flight Rules"), this);
+
+    QCalendarWidget *calendarWidget;
+
+    QDialogButtonBox acceptButtonBox = QDialogButtonBox(QDialogButtonBox::Ok |
+                                                        QDialogButtonBox::Cancel);
+
+    OPL::DateTimeFormat displayFormat;
+
+    void init();
+    void setupUI();
+    void setupSignalsAndSlots();
+    void readSettings();
+    bool verifyUserInput(QLineEdit *lineEdit, const UserInput &input);
+    inline void setRedBorder(QLineEdit &lineEdit) {
+        lineEdit.setStyleSheet(OPL::CssStyles::RED_BORDER);
+    }
+    inline void clearBorder(QLineEdit &lineEdit) {
+        lineEdit.setStyleSheet(QString());
+    }
+
+
+private slots:
+    void onDialogAccepted();
+    void onCalendarRequested();
+    void onCalendarDateSelected();
+
+
+    // line edits
+    void onDateEditingFinished();
+    void onTimeEditingFinished();
+    void onNameEditingFinished();
+    void onRegistrationEditingFinished();
+    void onLocationEditingFinished();
+};
+
+#endif // FLIGHTENTRYEDITDIALOG_H

+ 7 - 0
src/opl.cpp

@@ -37,4 +37,11 @@ void OplGlobals::loadApproachTypes(QComboBox *combo_box) const
         combo_box->addItem(approach);
 }
 
+void OplGlobals::loadFlightRules(QComboBox *combo_box) const
+{
+    const QSignalBlocker blocker(combo_box);
+    combo_box->addItem(QStringLiteral("VFR"));
+    combo_box->addItem(QStringLiteral("IFR"));
+}
+
 } // namespace Opl

+ 1 - 0
src/opl.h

@@ -236,6 +236,7 @@ public:
     void loadPilotFunctios(QComboBox *combo_box) const;
     void loadSimulatorTypes(QComboBox *combo_box) const;
     void loadApproachTypes(QComboBox *combo_box) const;
+    void loadFlightRules(QComboBox *combo_box) const;
 
     inline const QStringList &getApproachTypes() const {return APPROACH_TYPES;}
     inline const QString getLanguageFilePath(Translation language) const {return L10N_FilePaths.value(language);}