123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
- #include "newnewflightdialog.h"
- #include "ui_newnewflightdialog.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"
- #include <QDateTime>
- #include <QCompleter>
- #include <QKeyEvent>
- NewNewFlightDialog::NewNewFlightDialog(ACompletionData &completion_data,
- QWidget *parent)
- : QDialog(parent),
- ui(new Ui::NewNewFlightDialog),
- completionData(completion_data)
- {
- ui->setupUi(this);
- init();
- }
- NewNewFlightDialog::~NewNewFlightDialog()
- {
- delete ui;
- }
- void NewNewFlightDialog::init()
- {
- // Initialise line edit lists
- timeLineEdits = {ui->tofbTimeLineEdit, ui->tonbTimeLineEdit};
- locationLineEdits = {ui->deptLocationLineEdit, ui->destLocationLineEdit};
- pilotNameLineEdits = {ui->picNameLineEdit, ui->sicNameLineEdit, ui->thirdPilotNameLineEdit};
- // {doft = 0, dept = 1, dest = 2, tofb = 3, tonb = 4, pic = 5, acft = 6}
- mandatoryLineEdits = {ui->doftLineEdit, ui->deptLocationLineEdit, ui->destLocationLineEdit,
- ui->tofbTimeLineEdit, ui->tonbTimeLineEdit,
- ui->picNameLineEdit, ui->acftLineEdit};
- setupRawInputValidation();
- setupSignalsAndSlots();
- //readSettings();
- ui->doftLineEdit->setText(QDate::currentDate().toString(Qt::ISODate));
- emit ui->doftLineEdit->editingFinished();
- }
- /*!
- * \brief NewNewFlightDialog::setupRawInputValidation outfits the line edits with QRegularExpresionValidators and QCompleters
- */
- void NewNewFlightDialog::setupRawInputValidation()
- {
- // Time Line Edits
- for (const auto& line_edit : qAsConst(timeLineEdits)) {
- auto validator = new QRegularExpressionValidator(QRegularExpression("([01]?[0-9]|2[0-3]):?[0-5][0-9]?"), line_edit);
- line_edit->setValidator(validator);
- }
- // Location Line Edits
- for (const auto& line_edit : qAsConst(locationLineEdits)) {
- auto validator = new QRegularExpressionValidator(QRegularExpression("[a-zA-Z0-9]{1,4}"), line_edit);
- line_edit->setValidator(validator);
- auto completer = new QCompleter(completionData.airportList, line_edit);
- completer->setCaseSensitivity(Qt::CaseInsensitive);
- completer->setCompletionMode(QCompleter::PopupCompletion);
- completer->setFilterMode(Qt::MatchContains);
- line_edit->setCompleter(completer);
- }
- // Name Line Edits
- for (const auto& line_edit : qAsConst(pilotNameLineEdits)) {
- auto completer = new QCompleter(completionData.pilotList, line_edit);
- completer->setCaseSensitivity(Qt::CaseInsensitive);
- completer->setCompletionMode(QCompleter::PopupCompletion);
- completer->setFilterMode(Qt::MatchContains);
- line_edit->setCompleter(completer);
- }
- // Acft Line Edit
- auto completer = new QCompleter(completionData.tailsList, ui->acftLineEdit);
- completer->setCaseSensitivity(Qt::CaseInsensitive);
- completer->setCompletionMode(QCompleter::PopupCompletion);
- completer->setFilterMode(Qt::MatchContains);
- ui->acftLineEdit->setCompleter(completer);
- }
- void NewNewFlightDialog::setupSignalsAndSlots()
- {
- for (const auto& line_edit : qAsConst(timeLineEdits))
- QObject::connect(line_edit, &QLineEdit::editingFinished,
- this, &NewNewFlightDialog::onTimeLineEdit_editingFinished);
- // Change text to upper case for location and acft line edits
- QObject::connect(ui->acftLineEdit, &QLineEdit::textChanged,
- this, &NewNewFlightDialog::toUpper);
- for (const auto& line_edit : qAsConst(locationLineEdits)) {
- QObject::connect(line_edit, &QLineEdit::textChanged,
- this, &NewNewFlightDialog::toUpper);
- QObject::connect(line_edit, &QLineEdit::editingFinished,
- this, &NewNewFlightDialog::onLocationLineEdit_editingFinished);
- }
- for (const auto& line_edit : qAsConst(pilotNameLineEdits))
- QObject::connect(line_edit, &QLineEdit::editingFinished,
- this, &NewNewFlightDialog::onPilotNameLineEdit_editingFinshed);
- }
- void NewNewFlightDialog::onGoodInputReceived(QLineEdit *line_edit)
- {
- DEB << line_edit->objectName() << " - Good input received - " << line_edit->text();
- line_edit->setStyleSheet(QString());
- if (mandatoryLineEdits.contains(line_edit))
- validationState.validate(mandatoryLineEdits.indexOf(line_edit));
- if (validationState.timesValid()) {
- DEB << "All mandatory Line Edits valid!";
- // Update Block Time Label
- QTime tblk = calculateBlockTime();
- ui->tblkDisplayLabel->setText(ATime::toString(tblk));
- if (validationState.allValid())
- updateNightCheckBoxes();
- }
- validationState.printValidationStatus();
- }
- void NewNewFlightDialog::onBadInputReceived(QLineEdit *line_edit)
- {
- DEB << line_edit->objectName() << " - Bad input received - " << line_edit->text();
- line_edit->setStyleSheet(QStringLiteral("border: 1px solid red"));
- line_edit->setText(QString());
- if (mandatoryLineEdits.contains(line_edit))
- validationState.invalidate(mandatoryLineEdits.indexOf(line_edit));
- validationState.printValidationStatus();
- }
- QTime NewNewFlightDialog::calculateBlockTime()
- {
- if (!validationState.timesValid())
- return {};
- const auto tofb = ATime::fromString(ui->tofbTimeLineEdit->text());
- const auto tonb = ATime::fromString(ui->tonbTimeLineEdit->text());
- return ATime::blocktime(tofb, tonb);
- }
- /*!
- * \brief NewNewFlightDialog::updateNightCheckBoxes updates the check boxes for take-off and landing
- * at night. Returns the number of minutes of night time.
- * \return
- */
- int NewNewFlightDialog::updateNightCheckBoxes()
- {
- if (!validationState.allValid())
- return 0;
- // Calculate Block Time
- const auto tofb = ATime::fromString(ui->tofbTimeLineEdit->text());
- const auto tonb = ATime::fromString(ui->tonbTimeLineEdit->text());
- const auto tblk = ATime::blocktime(tofb, tonb);
- const auto block_minutes = ATime::toMinutes(tblk);
- // Calculate Night Time
- const QString dept_date = ui->doftLineEdit->text() + 'T'
- + ATime::toString(tofb);
- const auto dept_date_time = QDateTime::fromString(dept_date, QStringLiteral("yyyy-MM-ddThh:mm"));
- const int night_angle = ASettings::read(ASettings::FlightLogging::NightAngle).toInt();
- const auto night_time = ATime::fromMinutes(ACalc::calculateNightTime(
- ui->deptLocationLineEdit->text(),
- ui->destLocationLineEdit->text(),
- dept_date_time,
- block_minutes,
- night_angle));
- const auto night_minutes = ATime::toMinutes(night_time);
- // set check boxes
- if (night_minutes == 0) {
- ui->toNightCheckBox->setCheckState(Qt::Unchecked);
- ui->ldgNightCheckBox->setCheckState(Qt::Unchecked);
- }
- else if (night_minutes == ATime::toMinutes(calculateBlockTime())) {
- ui->toNightCheckBox->setCheckState(Qt::Checked);
- ui->ldgNightCheckBox->setCheckState(Qt::Checked);
- } else {
- if(ACalc::isNight(ui->deptLocationLineEdit->text(), dept_date_time, night_angle)) {
- ui->toNightCheckBox->setCheckState(Qt::Checked);
- ui->ldgNightCheckBox->setCheckState(Qt::Unchecked);
- } else {
- ui->toNightCheckBox->setCheckState(Qt::Unchecked);
- ui->ldgNightCheckBox->setCheckState(Qt::Checked);
- }
- }
- return ATime::toMinutes(night_time);
- }
- // # Slots
- void NewNewFlightDialog::toUpper(const QString &text)
- {
- const auto line_edit = this->findChild<QLineEdit*>(sender()->objectName());
- {
- const QSignalBlocker blocker(line_edit);
- line_edit->setText(text.toUpper());
- }
- }
- void NewNewFlightDialog::onTimeLineEdit_editingFinished()
- {
- auto line_edit = this->findChild<QLineEdit*>(sender()->objectName());
- DEB << line_edit->objectName() << "Editing finished -" << line_edit->text();
- const QString time_string = ATime::formatTimeInput(line_edit->text());
- const QTime time = ATime::fromString(time_string);
- if (time.isValid()) {
- line_edit->setText(time_string);
- onGoodInputReceived(line_edit);
- } else {
- onBadInputReceived(line_edit);
- line_edit->setText(QString());
- }
- }
- void NewNewFlightDialog::onPilotNameLineEdit_editingFinshed()
- {
- auto line_edit = this->findChild<QLineEdit*>(sender()->objectName());
- DEB << line_edit->objectName() << "Editing Finished -" << line_edit->text();
- if(line_edit->text().contains(self, Qt::CaseInsensitive)) {
- DEB << "self recognized.";
- line_edit->setText(completionData.pilotsIdMap.value(1));
- onGoodInputReceived(line_edit);
- return;
- }
- if(completionData.pilotsIdMap.key(line_edit->text()) != 0) {
- DEB << "Mapped: " << line_edit->text() << completionData.pilotsIdMap.key(line_edit->text());
- onGoodInputReceived(line_edit);
- return;
- }
- if (line_edit->text().isEmpty()) {
- return;
- }
- if (!line_edit->completer()->currentCompletion().isEmpty()) {
- DEB << "Trying to fix input...";
- line_edit->setText(line_edit->completer()->currentCompletion());
- emit line_edit->editingFinished();
- return;
- }
- onBadInputReceived(line_edit);
- TODO << "Add new Pilot...";
- //addNewPilot(line_edit);
- }
- void NewNewFlightDialog::onLocationLineEdit_editingFinished()
- {
- const QString line_edit_name = sender()->objectName();
- const auto line_edit = this->findChild<QLineEdit*>(line_edit_name);
- DEB << line_edit->objectName() << "Editing Finished -" << line_edit->text();
- QLabel* name_label;
- if (line_edit_name.contains(QLatin1String("dept"))) {
- name_label = ui->deptNameLabel;
- } else {
- name_label = ui->destNameLabel;
- }
- const auto &text = line_edit->text();
- int airport_id = 0;
- // try to map iata or icao code to airport id;
- if (text.length() == 3) {
- airport_id = completionData.airportIataIdMap.key(text);
- } else {
- airport_id = completionData.airportIcaoIdMap.key(text);
- }
- // check result
- if (airport_id == 0) {
- // to do: prompt user how to handle unknown airport
- name_label->setText(tr("Unknown airport identifier"));
- onBadInputReceived(line_edit);
- return;
- }
- line_edit->setText(completionData.airportIcaoIdMap.value(airport_id));
- name_label->setText(completionData.airportNameIdMap.value(airport_id));
- onGoodInputReceived(line_edit);
- }
- void NewNewFlightDialog::on_acftLineEdit_editingFinished()
- {
- const auto line_edit = ui->acftLineEdit;
- int acft_id = completionData.tailsIdMap.key(line_edit->text());
- DEB << "acft_id: " << acft_id;
- if (acft_id != 0) { // Success
- auto acft = aDB->getTailEntry(acft_id);
- ui->acftDisplayLabel->setText(acft.type());
- onGoodInputReceived(line_edit);
- return;
- }
- // try to use a completion
- if (!line_edit->completer()->currentCompletion().isEmpty() && !line_edit->text().isEmpty()) {
- line_edit->setText(line_edit->completer()->currentCompletion().split(QLatin1Char(' ')).first());
- emit line_edit->editingFinished();
- return;
- }
- // Mark as bad input and prompt for adding new tail
- onBadInputReceived(line_edit);
- ui->acftDisplayLabel->setText(tr("Unknown Registration."));
- WARN("Add new tail..");
- }
- void NewNewFlightDialog::on_doftLineEdit_editingFinished()
- {
- const auto line_edit = ui->doftLineEdit;
- auto text = ui->doftLineEdit->text();
- auto label = ui->doftDisplayLabel;
- //DEB << line_edit->objectName() << "Editing finished - " << text;
- TODO << "Non-default Date formats not implemented yet.";
- Opl::Date::ADateFormat date_format = Opl::Date::ADateFormat::ISODate;
- auto date = ADate::parseInput(text, date_format);
- if (date.isValid()) {
- label->setText(date.toString(Qt::TextDate));
- line_edit->setText(ADate::toString(date, date_format));
- onGoodInputReceived(line_edit);
- return;
- }
- label->setText(tr("Invalid Date."));
- onBadInputReceived(line_edit);
- }
- void NewNewFlightDialog::on_pilotFlyingCheckBox_stateChanged(int arg1)
- {
- if (arg1 == Qt::CheckState::Checked) {
- ui->takeOffSpinBox->setValue(1);
- ui->landingSpinBox->setValue(1);
- } else {
- ui->takeOffSpinBox->setValue(0);
- ui->landingSpinBox->setValue(0);
- }
- }
- void NewNewFlightDialog::on_buttonBox_accepted()
- {
- // emit editing finished for all mandatory line edits to trigger input verification
- for (const auto &line_edit : qAsConst(mandatoryLineEdits)) {
- emit line_edit->editingFinished();
- }
- // If input verification is passed, continue, otherwise prompt user to correct
- // enum ValidationItem {doft = 0, dept = 1, dest = 2, tofb = 3, tonb = 4, pic = 5, acft = 6};
- if (!validationState.allValid()) {
- const auto display_names = QMap<ValidationItem, QString> {
- {ValidationItem::doft, QObject::tr("Date of Flight")}, {ValidationItem::dept, QObject::tr("Departure Airport")},
- {ValidationItem::dest, QObject::tr("Destination Airport")}, {ValidationItem::tofb, QObject::tr("Time Off Blocks")},
- {ValidationItem::tonb, QObject::tr("Time on Blocks")}, {ValidationItem::pic, QObject::tr("PIC Name")},
- {ValidationItem::acft, QObject::tr("Aircraft Registration")}
- };
- QString missing_items;
- for (int i=0; i < mandatoryLineEdits.size(); i++) {
- if (!validationState.validAt(i)){
- missing_items.append(display_names.value(static_cast<ValidationItem>(i)) + "<br>");
- mandatoryLineEdits[i]->setStyleSheet(QStringLiteral("border: 1px solid red"));
- }
- }
- INFO(tr("Not all mandatory entries are valid.<br>"
- "The following item(s) are empty or missing:"
- "<br><br><center><b>%1</b></center><br>"
- "Please go back and fill in the required data."
- ).arg(missing_items));
- return;
- }
- // If input verification passed, collect input and submit to database
- //auto newData = collectInput();
- //DEB << "Setting Data for flightEntry...";
- //flightEntry.setData(newData);
- //DEB << "Committing...";
- //if (!aDB->commit(flightEntry)) {
- // WARN(tr("The following error has ocurred:"
- // "<br><br>%1<br><br>"
- // "The entry has not been saved."
- // ).arg(aDB->lastError.text()));
- // return;
- //} else {
- // QDialog::accept();
- //}
- }
|