Browse Source

Cleanup and fixes

Small adjustments to input verification
Correct handling of custom delegates in LogbookTableEditWidget when view selection is changed
Updated RegEx for time input (allowing decimal time inputs)
Felix Turowsky 1 year ago
parent
commit
20b1d6d192

+ 1 - 0
src/database/database.cpp

@@ -517,6 +517,7 @@ const RowData_T Database::getTotals(bool includePreviousExperience)
         return entry_data;
     }
 
+    // name the return types for easy mapping to QLineEdit names
     statement = "SELECT"
                 " SUM(tblk) AS tblk,"
                 " SUM(tSPSE) AS tSPSE,"

+ 44 - 10
src/gui/dialogues/newflightdialog.cpp

@@ -47,7 +47,7 @@ NewFlightDialog::NewFlightDialog(QWidget *parent)
     setPilotFunction();
 
     ui->doftLineEdit->setText(OPL::Date::today(m_format).toString());
-    emit ui->doftLineEdit->editingFinished();
+//    emit ui->doftLineEdit->editingFinished();
 }
 
 NewFlightDialog::NewFlightDialog(int row_id, QWidget *parent)
@@ -69,12 +69,10 @@ void NewFlightDialog::setPilotFunction()
     if(Settings::getPilotFunction() == OPL::PilotFunction::PIC){
         ui->picNameLineEdit->setText(self);
         ui->functionComboBox->setCurrentIndex(0);
-        emit ui->picNameLineEdit->editingFinished();
     }
     if (Settings::getPilotFunction() == OPL::PilotFunction::SIC) {
         ui->sicNameLineEdit->setText(self);
         ui->functionComboBox->setCurrentIndex(2);
-        emit ui->sicNameLineEdit->editingFinished();
     }
     ui->pilotFlyingCheckBox->setCheckState(Qt::Checked);
 }
@@ -367,11 +365,11 @@ bool NewFlightDialog::userWantsToAddNewEntry(OPL::DbTable table)
                                       QMessageBox::Yes|QMessageBox::No);
         break;
     case OPL::DbTable::Airports:
-        reply = QMessageBox::question(this, tr("No Aircraft found"),
-                                      tr("No aircraft with this registration found.<br>"
-                                         "If this is the first time you log a flight with this aircraft, "
-                                         "you have to add the registration to the database first."
-                                         "<br><br>Would you like to add a new aircraft to the database?"),
+        reply = QMessageBox::question(this, tr("No Airport found"),
+                                      tr("No Airport with this identifier found.<br>"
+                                         "If this is the first time you log a flight to this airport, "
+                                         "you have to add the airport to the database first."
+                                         "<br><br>Would you like to add a new airport to the database?"),
                                       QMessageBox::Yes|QMessageBox::No);
         break;
     default:
@@ -400,7 +398,7 @@ OPL::RowData_T NewFlightDialog::prepareFlightEntryData()
     const OPL::Time tonb = OPL::Time::fromString(ui->tonbTimeLineEdit->text(), m_format);
     const int block_minutes = OPL::Time::blockMinutes(tofb, tonb);
 
-    QDateTime departure_date_time = OPL::DateTime::fromString(ui->doftLineEdit->text() + ui->tofbTimeLineEdit->text());
+    const QDateTime departure_date_time = OPL::DateTime::fromString(ui->doftLineEdit->text() + ui->tofbTimeLineEdit->text());
     const auto night_time_data = OPL::Calc::NightTimeValues(ui->deptLocationLineEdit->text(), ui->destLocationLineEdit->text(),
                            departure_date_time, block_minutes, Settings::getNightAngle());
     // Mandatory data
@@ -513,7 +511,43 @@ void NewFlightDialog::toUpper(const QString &text)
 void NewFlightDialog::onTimeLineEdit_editingFinished()
 {
     auto line_edit = this->findChild<QLineEdit*>(sender()->objectName());
-    verifyUserInput(line_edit, TimeInput(line_edit->text()));
+
+    if(OPL::Time::fromString(line_edit->text(), m_format).isValidTimeOfDay()) {
+        onGoodInputReceived(line_edit);
+        return;
+    }
+
+    // try to fix up the input
+    QString text = line_edit->text();
+    // don't mess with decimal time formats
+    if(text.contains('.')) {
+        DEB << "Bad input received: " << text;
+        onBadInputReceived(line_edit);
+    }
+
+    DEB << "Trying to fix input: " << text;
+    // try inserting a ':' for hhmm inputs
+    QString fixed = text;
+    if (text.contains(':')) { // contains seperator
+        if(text.length() == 4)
+            fixed.prepend(QLatin1Char('0'));
+    } else { // does not contain seperator
+        if(text.length() == 4) {
+            fixed.insert(2, ':');
+        }
+        if(text.length() == 3) {
+            fixed.prepend(QLatin1Char('0'));
+            fixed.insert(2, ':');
+        }
+    }
+
+    if(OPL::Time::fromString(fixed, m_format).isValidTimeOfDay()) {
+        line_edit->setText(fixed);
+        onGoodInputReceived(line_edit);
+    } else {
+        DEB << "Bad input received: " << text;
+        onBadInputReceived(line_edit);
+    }
 }
 
 void NewFlightDialog::onPilotNameLineEdit_editingFinshed()

+ 20 - 15
src/gui/verification/timeinput.cpp

@@ -12,23 +12,28 @@ bool TimeInput::isValid() const
  * \details If the user input is not a valid time, this function tries to fix it. Accepted Inputs are
  * hh:mm, h:mm, hhmm or hmm. Returns "hh:mm" or an empty string if the resulting time is invalid.
  */
+QT_DEPRECATED // time input verification depends on display format...fix this TODO
 QString TimeInput::fixup() const
 {
-    QString fixed = input;
+     // don't mess with decimal time formats
+     if(input.contains('.'))
+         return input;
 
-    if (input.contains(':')) { // contains seperator
-        if(input.length() == 4)
-            fixed.prepend(QLatin1Char('0'));
-    } else { // does not contain seperator
-        if(input.length() == 4) {
-            fixed.insert(2, ':');
-        }
-        if(input.length() == 3) {
-            fixed.prepend(QLatin1Char('0'));
-            fixed.insert(2, ':');
-        }
-    }
+     // try inserting a ':' for hhmm inputs
+     QString fixed = input;
+     if (input.contains(':')) { // contains seperator
+         if(input.length() == 4)
+             fixed.prepend(QLatin1Char('0'));
+     } else { // does not contain seperator
+         if(input.length() == 4) {
+             fixed.insert(2, ':');
+         }
+         if(input.length() == 3) {
+             fixed.prepend(QLatin1Char('0'));
+             fixed.insert(2, ':');
+         }
+     }
 
-    QTime time = QTime::fromString(fixed, OPL::Format::TIME_FORMAT);
-    return time.toString(OPL::Format::TIME_FORMAT);
+     QTime time = QTime::fromString(fixed, OPL::Format::TIME_FORMAT);
+     return time.toString(OPL::Format::TIME_FORMAT);
 }

+ 23 - 11
src/gui/widgets/logbooktableeditwidget.cpp

@@ -76,12 +76,6 @@ EntryEditDialog *LogbookTableEditWidget::getEntryEditDialog(QWidget *parent)
     return new NewFlightDialog(parent);
 }
 
-void LogbookTableEditWidget::viewSelectionChanged(SettingsWidget::SettingSignal widget)
-{
-    if(widget == SettingsWidget::SettingSignal::LogbookWidget)
-        setupModelAndView();
-}
-
 void LogbookTableEditWidget::filterTextChanged(const QString &filterString)
 {}
 
@@ -145,25 +139,43 @@ void LogbookTableEditWidget::deleteEntryRequested()
 
 // private implementations
 
+void LogbookTableEditWidget::viewSelectionChanged(SettingsWidget::SettingSignal widget)
+{
+    for(auto i = m_defaultDelegates.constBegin(); i != m_defaultDelegates.constEnd(); i++) {
+        m_view->setItemDelegateForColumn(i.key(), i.value());
+        // should probably delete the old custom delegate, Qt docs say the
+        // view does not take ownership of the delegates so they might be leaking
+        // https://doc.qt.io/qt-6/qabstractitemdelegate.html
+    }
+
+    if(widget == SettingsWidget::SettingSignal::LogbookWidget)
+        setupModelAndView();
+}
+
 void LogbookTableEditWidget::setupDelegates()
 {
     // minutes to hh:mm
     const auto timeDelegate = new StyledTimeDelegate(m_format, m_model);
-    m_view->setItemDelegateForColumn(-1, timeDelegate); // shut up ctidy
     for(const auto col : OPL::LogbookViewInfo::getTimeColumns(m_logbookView)) {
+        m_defaultDelegates.insert(col, m_view->itemDelegateForColumn(col));
         m_view->setItemDelegateForColumn(col, timeDelegate);
     }
 
     // julian day to Date Format
+    const int dateCol = OPL::LogbookViewInfo::getDateColumn(m_logbookView);
     const auto dateDelegate = new StyledDateDelegate(Settings::getDisplayFormat(), m_model);
-    m_view->setItemDelegateForColumn(OPL::LogbookViewInfo::getDateColumn(m_logbookView), dateDelegate);
+    m_defaultDelegates.insert(dateCol, m_view->itemDelegateForColumn(dateCol));
+    m_view->setItemDelegateForColumn(dateCol, dateDelegate);
 
     // pilot_id to names
+    const int pilCol = OPL::LogbookViewInfo::getPicColumn(m_logbookView);
     const auto pilotDelegate = new StyledPilotDelegate(m_model);
-    m_view->setItemDelegateForColumn(OPL::LogbookViewInfo::getPicColumn(m_logbookView), pilotDelegate);
+    m_defaultDelegates.insert(pilCol, m_view->itemDelegateForColumn(pilCol));
+    m_view->setItemDelegateForColumn(pilCol, pilotDelegate);
 
     // tail_id to aircraft type and registration
+    const int typeCol = OPL::LogbookViewInfo::getTypeColumn(m_logbookView);
     const auto typeDelegate = new StyledTypeDelegate(m_model);
-    m_view->setItemDelegateForColumn(OPL::LogbookViewInfo::getTypeColumn(m_logbookView), typeDelegate);
-
+    m_defaultDelegates.insert(typeCol, m_view->itemDelegateForColumn(typeCol));
+    m_view->setItemDelegateForColumn(typeCol, typeDelegate);
 }

+ 3 - 0
src/gui/widgets/logbooktableeditwidget.h

@@ -36,6 +36,9 @@ private:
 
     static constexpr int COL_ROWID = 0;
 
+    // keep track of default and custom delegates set on certain columns
+    QHash<int, QAbstractItemDelegate*> m_defaultDelegates;
+
     // TableEditWidget interface
 public:
     virtual void setupModelAndView() override;

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

@@ -108,7 +108,7 @@ void TotalsWidget::fillTotals(const WidgetType widgetType)
                 line_edit->setText(field.toString());
             } else {
                 // line edits for total time
-                OPL::Time time = OPL::Time(field.toInt(), m_format);// = Time(field.toInt());
+                OPL::Time time = OPL::Time(field.toInt(), m_format);
                 line_edit->setText(time.toString());
             }
         }

+ 2 - 1
src/opl.h

@@ -366,7 +366,8 @@ namespace RegEx {
 
 const inline auto RX_PHONE_NUMBER  = QRegularExpression(QStringLiteral("^[+]{0,1}[0-9\\-\\s]+"));
 const inline auto RX_EMAIL_ADDRESS = QRegularExpression(QStringLiteral("\\A[a-z0-9!#$%&'*+/=?^_‘{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_‘{|}~-]+)*@"));
-const inline auto RX_TIME_ENTRY    = QRegularExpression(QStringLiteral("([01]?[0-9]|2[0-3]):?[0-5][0-9]?"));
+//const inline auto RX_TIME_ENTRY    = QRegularExpression(QStringLiteral("([01]?[0-9]|2[0-3]):?[0-5][0-9]?"));
+const inline auto RX_TIME_ENTRY    = QRegularExpression(QStringLiteral("^(?:(?:([01]?\\d|2[0-3])(?::?)([0-5]\\d))|(?:([01]?\\d|2[0-3])([0-5]\\d))|(?:([1-9]|[1-9]\\d)\\:([0-5]\\d)?)|(?:([01]?\\d|2[0-3])\\.([0-5]?\\d)))$"));
 const inline auto RX_AIRPORT_CODE  = QRegularExpression(QStringLiteral("[a-zA-Z0-9]{1,4}"));
 
 } // namespace RegEx