Procházet zdrojové kódy

Finishing up AirportWidget and NewAirportDialog

- NewAirportDialog can now be used to also edit existing entries.
- Added input verification
Felix Turo před 2 roky
rodič
revize
2752532a82

+ 5 - 2
mainwindow.cpp

@@ -26,10 +26,13 @@
 #include "src/gui/dialogues/newsimdialog.h"
 // Quick and dirty Debug area
 #include <QTimeZone>
+#include "src/gui/dialogues/newairportdialog.h"
 void MainWindow::doDebugStuff()
 {
-    const auto list = QTimeZone::availableTimeZoneIds();
-    DEB << list;
+    //const auto list = QTimeZone::availableTimeZoneIds();
+    //DEB << list;
+    auto nad = new NewAirportDialog(5, this);
+    nad->exec();
 }
 
 MainWindow::MainWindow(QWidget *parent)

+ 1 - 1
mainwindow.ui

@@ -146,7 +146,7 @@
     <string>Airports</string>
    </property>
    <property name="toolTip">
-    <string>Create or restore a backup of the database</string>
+    <string>Add a new or edit an existing airport</string>
    </property>
    <property name="shortcut">
     <string>Ctrl+A</string>

+ 9 - 0
src/database/database.h

@@ -255,6 +255,15 @@ public:
         return OPL::CurrencyEntry(row_id, data);
     }
 
+    /*!
+     * \brief Retreives an airport entry from the database. See row class for details.
+     */
+    inline OPL::AirportEntry getAirportEntry(int row_id)
+    {
+        const auto data = getRowData(OPL::DbTable::Airports, row_id);
+        return OPL::AirportEntry(row_id, data);
+    }
+
     /*!
      * \brief returns the ROWID for the newest entry in the respective table.
      */

+ 53 - 66
src/gui/dialogues/newairportdialog.cpp

@@ -8,14 +8,23 @@
 #include "src/database/row.h"
 
 NewAirportDialog::NewAirportDialog(QWidget *parent) :
-    QDialog(parent),
-    ui(new Ui::NewAirportDialog)
+    QDialog(parent), ui(new Ui::NewAirportDialog)
 {
+    rowId = 0; // new entry
     ui->setupUi(this);
     setValidators();
     loadTimeZones();
 }
 
+NewAirportDialog::NewAirportDialog(int row_id, QWidget *parent)
+    : QDialog(parent), ui(new Ui::NewAirportDialog), rowId(row_id)
+{
+    ui->setupUi(this);
+    setValidators();
+    loadTimeZones();
+    loadAirportData(row_id);
+}
+
 NewAirportDialog::~NewAirportDialog()
 {
     delete ui;
@@ -23,10 +32,8 @@ NewAirportDialog::~NewAirportDialog()
 
 void NewAirportDialog::setValidators()
 {
-    ui->latitudeLineEdit ->setValidator(new QDoubleValidator(-90,90,10,this));   // -90  <= Latitude  <= 90
-    ui->longitudeLineEdit->setValidator(new QDoubleValidator(-180,180,10,this)); // -180 <= Longitude <= 180
-    ui->icaoLineEdit     ->setValidator(new QRegularExpressionValidator(QRegularExpression("\\w{4}"), this)); // 4 letter code
-    ui->iataLineEdit     ->setValidator(new QRegularExpressionValidator(QRegularExpression("\\w{3}"), this)); // 3 letter code
+    ui->icaoLineEdit->setValidator(new QRegularExpressionValidator(QRegularExpression("\\w{4}"), this)); // 4 letter code
+    ui->iataLineEdit->setValidator(new QRegularExpressionValidator(QRegularExpression("\\w{3}"), this)); // 3 letter code
 }
 
 void NewAirportDialog::loadTimeZones()
@@ -37,8 +44,42 @@ void NewAirportDialog::loadTimeZones()
     ui->timeZoneComboBox->addItems(tz_list);
 }
 
-bool NewAirportDialog::confirmTimezone()
+void NewAirportDialog::loadAirportData(int row_id)
 {
+    const auto airport_data = DB->getAirportEntry(row_id).getData();
+    //const auto airport_data = airport.getData();
+    DEB << "Filling Airport Data: " << airport_data;
+
+    ui->nameLineEdit->setText(airport_data.value(OPL::Db::AIRPORTS_NAME).toString());
+    ui->icaoLineEdit->setText(airport_data.value(OPL::Db::AIRPORTS_ICAO).toString());
+    ui->iataLineEdit->setText(airport_data.value(OPL::Db::AIRPORTS_IATA).toString());
+    ui->latDoubleSpinBox->setValue(airport_data.value(OPL::Db::AIRPORTS_LAT).toDouble());
+    ui->lonDoubleSpinBox->setValue(airport_data.value(OPL::Db::AIRPORTS_LON).toDouble());
+    ui->countryLineEdit->setText(airport_data.value(OPL::Db::AIRPORTS_COUNTRY).toString());
+
+    const QString timezone = airport_data.value(OPL::Db::AIRPORTS_TZ_OLSON).toString();
+    DEB << "Timezone: " << timezone;
+    if (timezone.isNull())
+        WARN(tr("Unable to read timezone data for this airport. Please verify."));
+    ui->timeZoneComboBox->setCurrentText(timezone);
+}
+
+bool NewAirportDialog::verifyInput()
+{
+    if (ui->nameLineEdit->text().isEmpty()) {
+        WARN(tr("Please enter the airport name."));
+        return false;
+    }
+    if (ui->icaoLineEdit->text().length() != 4) {
+        WARN(tr("Invalid ICAO Code."));
+        return false;
+    }
+    if (ui->latDoubleSpinBox->value() == 0 || ui->lonDoubleSpinBox->value() == 0) {
+        WARN(tr("Please enter the latitude and longitude in decimal degrees.<br><br>"
+                "This data is required for calculation of sunrise and sunset times."));
+        return false;
+    }
+
     if (ui->timeZoneComboBox->currentIndex() == 0) {
 
         QString airport_name = ui->nameLineEdit->text();
@@ -63,29 +104,20 @@ bool NewAirportDialog::confirmTimezone()
 
 void NewAirportDialog::on_buttonBox_accepted()
 {
-    // validate input
-    if (!ui->latitudeLineEdit->hasAcceptableInput()) {
-        WARN(tr("The entered latitude is invalid. Please enter the latitude as a decimal number between -90.0 and 90.0 degrees."));
-        return;
-    }
-    if (!ui->longitudeLineEdit->hasAcceptableInput()) {
-        WARN(tr("The entered longitude is invalid. Please enter the longitude as a decimal number between -180.0 and 180.0 degrees."));
-        return;
-    }
-    if (!confirmTimezone())
+    if (!verifyInput())
         return;
-
     // create Entry object
     OPL::RowData_T airport_data = {
+        {OPL::Db::AIRPORTS_NAME,     ui->nameLineEdit->text()},
         {OPL::Db::AIRPORTS_ICAO,     ui->icaoLineEdit->text()},
         {OPL::Db::AIRPORTS_IATA,     ui->iataLineEdit->text()},
-        {OPL::Db::AIRPORTS_LAT,      ui->latitudeLineEdit->text()},
-        {OPL::Db::AIRPORTS_LON,      ui->longitudeLineEdit->text()},
+        {OPL::Db::AIRPORTS_LAT,      ui->latDoubleSpinBox->value()},
+        {OPL::Db::AIRPORTS_LON,      ui->lonDoubleSpinBox->value()},
         {OPL::Db::AIRPORTS_TZ_OLSON, ui->timeZoneComboBox->currentText()},
         {OPL::Db::AIRPORTS_COUNTRY,  ui->countryLineEdit->text()},
     };
 
-    OPL::AirportEntry entry(airport_data);
+    OPL::AirportEntry entry(rowId, airport_data);
     if(DB->commit(entry))
         QDialog::accept();
     else {
@@ -104,51 +136,6 @@ void NewAirportDialog::on_icaoLineEdit_textChanged(const QString &arg1)
     ui->icaoLineEdit->setText(arg1.toUpper());
 }
 
-void NewAirportDialog::on_nameLineEdit_editingFinished()
-{
-    DEB << "Editing finished: ";
-}
-
-void NewAirportDialog::on_iataLineEdit_editingFinished()
-{
-    DEB << "Editing finished: ";
-}
-
-void NewAirportDialog::on_icaoLineEdit_editingFinished()
-{
-    DEB << "Editing finished: ";
-}
-
-void NewAirportDialog::on_latitudeLineEdit_editingFinished()
-{
-    DEB << "Editing finished: ";
-}
-
-void NewAirportDialog::on_longitudeLineEdit_editingFinished()
-{
-    DEB << "Editing finished: ";
-}
-
-void NewAirportDialog::on_latitudeLineEdit_inputRejected()
-{
-    DEB << "Input Rejected";
-}
-
-void NewAirportDialog::on_longitudeLineEdit_inputRejected()
-{
-    DEB << "Input Rejected";
-}
-
-void NewAirportDialog::on_icaoLineEdit_inputRejected()
-{
-    DEB << "Input Rejected";
-}
-
-void NewAirportDialog::on_iataLineEdit_inputRejected()
-{
-    DEB << "Input Rejected";
-}
-
 void NewAirportDialog::on_buttonBox_rejected()
 {
     QDialog::reject();

+ 5 - 18
src/gui/dialogues/newairportdialog.h

@@ -13,8 +13,10 @@ class NewAirportDialog : public QDialog
 
 public:
     explicit NewAirportDialog(QWidget *parent = nullptr);
+    explicit NewAirportDialog(int row_id, QWidget* parent = nullptr);
     ~NewAirportDialog();
 
+
 private slots:
     void on_buttonBox_accepted();
 
@@ -22,24 +24,6 @@ private slots:
 
     void on_icaoLineEdit_textChanged(const QString &arg1);
 
-    void on_nameLineEdit_editingFinished();
-
-    void on_iataLineEdit_editingFinished();
-
-    void on_icaoLineEdit_editingFinished();
-
-    void on_latitudeLineEdit_editingFinished();
-
-    void on_longitudeLineEdit_editingFinished();
-
-    void on_latitudeLineEdit_inputRejected();
-
-    void on_longitudeLineEdit_inputRejected();
-
-    void on_icaoLineEdit_inputRejected();
-
-    void on_iataLineEdit_inputRejected();
-
     void on_buttonBox_rejected();
 
 private:
@@ -47,6 +31,9 @@ private:
     void setValidators();
     void loadTimeZones();
     bool confirmTimezone();
+    void loadAirportData(int row_id);
+    bool verifyInput();
+    int rowId;
 };
 
 #endif // NEWAIRPORTDIALOG_H

+ 109 - 182
src/gui/dialogues/newairportdialog.ui

@@ -6,193 +6,120 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>435</width>
-    <height>574</height>
+    <width>260</width>
+    <height>246</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Add New Airport</string>
   </property>
-  <widget class="QLabel" name="nameLabel">
-   <property name="geometry">
-    <rect>
-     <x>9</x>
-     <y>31</y>
-     <width>87</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Airport Name</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="nameLineEdit">
-   <property name="geometry">
-    <rect>
-     <x>102</x>
-     <y>31</y>
-     <width>142</width>
-     <height>23</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="iataLabel">
-   <property name="geometry">
-    <rect>
-     <x>9</x>
-     <y>82</y>
-     <width>65</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>IATA Code</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="iataLineEdit">
-   <property name="geometry">
-    <rect>
-     <x>102</x>
-     <y>82</y>
-     <width>142</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="maxLength">
-    <number>3</number>
-   </property>
-  </widget>
-  <widget class="QLabel" name="icaoLabel">
-   <property name="geometry">
-    <rect>
-     <x>9</x>
-     <y>133</y>
-     <width>70</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>ICAO Code</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="icaoLineEdit">
-   <property name="geometry">
-    <rect>
-     <x>102</x>
-     <y>133</y>
-     <width>142</width>
-     <height>23</height>
-    </rect>
-   </property>
-   <property name="maxLength">
-    <number>4</number>
-   </property>
-  </widget>
-  <widget class="QLabel" name="latitudeLabel">
-   <property name="geometry">
-    <rect>
-     <x>7</x>
-     <y>228</y>
-     <width>54</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Latitude</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="latitudeLineEdit">
-   <property name="geometry">
-    <rect>
-     <x>100</x>
-     <y>228</y>
-     <width>142</width>
-     <height>23</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="longitudeLabel">
-   <property name="geometry">
-    <rect>
-     <x>7</x>
-     <y>279</y>
-     <width>65</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Longitude</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="longitudeLineEdit">
-   <property name="geometry">
-    <rect>
-     <x>100</x>
-     <y>279</y>
-     <width>142</width>
-     <height>23</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QDialogButtonBox" name="buttonBox">
-   <property name="geometry">
-    <rect>
-     <x>80</x>
-     <y>400</y>
-     <width>166</width>
-     <height>24</height>
-    </rect>
-   </property>
-   <property name="standardButtons">
-    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-   </property>
-  </widget>
-  <widget class="QLabel" name="timezoneLabel">
-   <property name="geometry">
-    <rect>
-     <x>7</x>
-     <y>330</y>
-     <width>63</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Timezone</string>
-   </property>
-  </widget>
-  <widget class="QComboBox" name="timeZoneComboBox">
-   <property name="geometry">
-    <rect>
-     <x>100</x>
-     <y>330</y>
-     <width>141</width>
-     <height>24</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="countryLabel">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>180</y>
-     <width>62</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Country</string>
-   </property>
-  </widget>
-  <widget class="QLineEdit" name="countryLineEdit">
-   <property name="geometry">
-    <rect>
-     <x>100</x>
-     <y>180</y>
-     <width>141</width>
-     <height>23</height>
-    </rect>
-   </property>
-  </widget>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="9" column="1" colspan="2">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QLabel" name="countryLabel">
+     <property name="text">
+      <string>Country</string>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="0">
+    <widget class="QLabel" name="longitudeLabel">
+     <property name="text">
+      <string>Longitude</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0">
+    <widget class="QLabel" name="latitudeLabel">
+     <property name="text">
+      <string>Latitude</string>
+     </property>
+    </widget>
+   </item>
+   <item row="8" column="0">
+    <widget class="QLabel" name="timezoneLabel">
+     <property name="text">
+      <string>Timezone</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="2">
+    <widget class="QLineEdit" name="countryLineEdit"/>
+   </item>
+   <item row="1" column="2">
+    <widget class="QLineEdit" name="iataLineEdit">
+     <property name="maxLength">
+      <number>3</number>
+     </property>
+    </widget>
+   </item>
+   <item row="8" column="2">
+    <widget class="QComboBox" name="timeZoneComboBox"/>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="icaoLabel">
+     <property name="text">
+      <string>ICAO Code</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="iataLabel">
+     <property name="text">
+      <string>IATA Code</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="2">
+    <widget class="QLineEdit" name="nameLineEdit"/>
+   </item>
+   <item row="0" column="0" colspan="2">
+    <widget class="QLabel" name="nameLabel">
+     <property name="text">
+      <string>Airport Name</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="2">
+    <widget class="QLineEdit" name="icaoLineEdit">
+     <property name="maxLength">
+      <number>4</number>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="2">
+    <widget class="QDoubleSpinBox" name="lonDoubleSpinBox">
+     <property name="decimals">
+      <number>10</number>
+     </property>
+     <property name="minimum">
+      <double>-180.000000000000000</double>
+     </property>
+     <property name="maximum">
+      <double>180.000000000000000</double>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="2">
+    <widget class="QDoubleSpinBox" name="latDoubleSpinBox">
+     <property name="decimals">
+      <number>10</number>
+     </property>
+     <property name="minimum">
+      <double>-90.000000000000000</double>
+     </property>
+     <property name="maximum">
+      <double>90.000000000000000</double>
+     </property>
+    </widget>
+   </item>
+  </layout>
  </widget>
  <resources/>
  <connections/>

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

@@ -18,7 +18,6 @@
 #include "newflightdialog.h"
 #include "ui_newflightdialog.h"
 #include "src/opl.h"
-#include "src/functions/alog.h"
 #include "src/functions/adate.h"
 #include "src/classes/asettings.h"
 #include "src/functions/acalc.h"

+ 21 - 7
src/gui/widgets/airportwidget.cpp

@@ -11,10 +11,12 @@ AirportWidget::AirportWidget(QWidget *parent) :
     setupModelAndeView();
     setupSearch();
 
-    QObject::connect(model,                  &QSqlTableModel::beforeUpdate,
-                     this,                   &AirportWidget::onUpdate);
+    QObject::connect(DB,                     &OPL::Database::dataBaseUpdated,
+                     this,                   &AirportWidget::refresh);
     QObject::connect(view->selectionModel(), &QItemSelectionModel::selectionChanged,
                      this,                   &AirportWidget::onSelectionChanged);
+    QObject::connect(view,                   &QTableView::doubleClicked,
+                     this,                   &AirportWidget::on_editAirportPushButton_clicked);
 }
 
 AirportWidget::~AirportWidget()
@@ -33,9 +35,10 @@ void AirportWidget::setupModelAndeView()
     view = ui->tableView;
     view->setModel(model);
 
-    view->horizontalHeader()->setStretchLastSection(QHeaderView::Stretch);
+    view->horizontalHeader()->setStretchLastSection(QHeaderView::Stretch); 
     view->setSelectionBehavior(QAbstractItemView::SelectRows);
     view->setSelectionMode(QAbstractItemView::ExtendedSelection);
+    view->setEditTriggers(QAbstractItemView::NoEditTriggers);
     view->hideColumn(0);
     view->resizeColumnsToContents();
     view->verticalHeader()->hide();
@@ -59,6 +62,8 @@ void AirportWidget::on_searchLineEdit_textChanged(const QString &arg1)
 
     model->setFilter(FILTER_MAP.value(ui->searchComboBox->currentIndex())
                      + arg1 + QLatin1String("%\""));
+    DEB << "Filter set: " << FILTER_MAP.value(ui->searchComboBox->currentIndex())
+           + arg1 + QLatin1String("%\"");
 }
 
 
@@ -139,9 +144,20 @@ void AirportWidget::on_deletePushButton_clicked()
     }
 }
 
-void AirportWidget::onUpdate()
+void AirportWidget::on_editAirportPushButton_clicked()
 {
-    emit DB->dataBaseUpdated(OPL::DbTable::Airports);
+    if (selectedEntries.isEmpty()) {
+        WARN(tr("No airport selected."));
+        return;
+    }
+
+    auto apd = NewAirportDialog(selectedEntries.first(), this);
+    apd.exec();
+}
+
+void AirportWidget::refresh()
+{
+    model->select();
 }
 
 void AirportWidget::onSelectionChanged()
@@ -153,5 +169,3 @@ void AirportWidget::onSelectionChanged()
     }
 }
 
-
-

+ 6 - 7
src/gui/widgets/airportwidget.h

@@ -27,15 +27,14 @@ private slots:
 
     void on_newAirportPushButton_clicked();
 
-    /*!
-     * \brief onUpdate is called whenever the user modifies an entry in the airports table
-     */
-    void onUpdate();
-
     void onSelectionChanged();
 
     void on_deletePushButton_clicked();
 
+    void on_editAirportPushButton_clicked();
+
+    void refresh();
+
 private:
     Ui::AirportWidget *ui;
     QSqlTableModel *model;
@@ -46,13 +45,13 @@ private:
     void setupSearch();
 
     inline const static QString TABLE_NAME = QStringLiteral("airports");
-    inline const static QHash<int, QString> FILTER_MAP = {
+    inline const static QMap<int, QString> FILTER_MAP = {
         {0, QStringLiteral("icao LIKE \"%")},
         {1, QStringLiteral("iata LIKE \"%")},
         {2, QStringLiteral("name LIKE \"%")},
         {3, QStringLiteral("country LIKE \"%")},
     };
-    inline const static QHash<int, QString> HEADER_MAP = {
+    inline const static QMap<int, QString> HEADER_MAP = {
         {0, QStringLiteral("ICAO")},
         {1, QStringLiteral("IATA")},
         {2, QStringLiteral("Name")},

+ 18 - 11
src/gui/widgets/airportwidget.ui

@@ -14,16 +14,16 @@
    <string>Form</string>
   </property>
   <layout class="QGridLayout" name="gridLayout">
-   <item row="0" column="0" colspan="4">
-    <widget class="QTableView" name="tableView"/>
-   </item>
    <item row="1" column="1">
     <widget class="QLineEdit" name="searchLineEdit"/>
    </item>
-   <item row="2" column="0" colspan="4">
-    <widget class="QPushButton" name="newAirportPushButton">
+   <item row="0" column="0" colspan="4">
+    <widget class="QTableView" name="tableView"/>
+   </item>
+   <item row="4" column="0" colspan="4">
+    <widget class="QPushButton" name="deletePushButton">
      <property name="text">
-      <string>Add New Airport</string>
+      <string>Delete Selected Airport</string>
      </property>
     </widget>
    </item>
@@ -34,20 +34,27 @@
      </property>
     </widget>
    </item>
-   <item row="1" column="0">
-    <widget class="QLabel" name="searchLabel">
+   <item row="2" column="0" colspan="4">
+    <widget class="QPushButton" name="newAirportPushButton">
      <property name="text">
-      <string>Search</string>
+      <string>Add New Airport</string>
      </property>
     </widget>
    </item>
    <item row="1" column="3">
     <widget class="QComboBox" name="searchComboBox"/>
    </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="searchLabel">
+     <property name="text">
+      <string>Search</string>
+     </property>
+    </widget>
+   </item>
    <item row="3" column="0" colspan="4">
-    <widget class="QPushButton" name="deletePushButton">
+    <widget class="QPushButton" name="editAirportPushButton">
      <property name="text">
-      <string>Delete Selected Airport</string>
+      <string>Edit Selected Airport</string>
      </property>
     </widget>
    </item>