/*
*openPilotLog - A FOSS Pilot Logbook Application
*Copyright (C) 2020-2023 Felix Turowsky
*
*This program is free software: you can redistribute it and/or modify
*it under the terms of the GNU General Public License as published by
*the Free Software Foundation, either version 3 of the License, or
*(at your option) any later version.
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License
*along with this program. If not, see .
*/
#ifndef NewFlightDialog_H
#define NewFlightDialog_H
#include
#include
#include
#include
#include
#include "src/database/flightentry.h"
#include "src/gui/verification/userinput.h"
#include "src/opl.h"
#include "src/gui/verification/validationstate.h"
namespace Ui {
class NewFlightDialog;
}
/*!
* \brief The NewFlightDialog is used to add or edit entries from the flights table in the database
* \details NewFlightDialog offers two constructors, one is used to create a new flight entry from scratch, where the other one is used
* to edit an existing entry. This entry is identified by its ROW ID, which is used to retreive the entry data and pre-populate the
* user interface with the data from the database.
*
* The flights table is the core of the application's database and care needs to be taken when interfacing with it.
*
* To ensure only good data is written to the database, the ValidationState class is used. It contains a QBitArray with each bit representing
* a mandatory data point. The array is initialized to all false and progressively changed to true as entry data is validated. An entry can
* only be submitted if all the verification bits are set.
*
* Inputs from the user are verified with a two-step process. The first level of verification is accomplished by QRegularExpressionValidator, which limits the
* user to only inputting generally acceptable data (like numbers for date or time, or characters for airport identifiers). If the input
* passes this sanity check, the line edits emit the editingFinished() signal, which triggers a more granular and sophisticated set of input
* verification, broadly based on cross-checking the entered data against known good values. The ACompletionData class is used to provide
* QHashs of known good values from the database and their respective ROW_IDs. If user-entered data has been matched to a known good database
* value, the data is considered acceptable. This means that in order to, for example, log a flight with a certain Pilot, that this pilot
* already has to exist in the pilots table. If this is not the case, the user is prompted to add a new pilot (or aircraft) to the database
* before proceeding. In order to make this matching process seamless for the user, the completionData also contains a set of QStringLists
* for each of the database tables which are used to create QCompleters that provide pop-up completion on the respective QLineEdits.
*
* Once the user is satisfied with his entries, a final set of input verification is triggered and the entry is submitted to the database,
* see on_buttonBox_accepted() and Database::commit()
*/
class NewFlightDialog : public QDialog
{
Q_OBJECT
public:
/*!
* \brief NewFlightDialog - Creates a NewFlightDialog that can be used to add a new flight entry to the logbook
*/
explicit NewFlightDialog(QWidget *parent = nullptr);
/*!
* \brief NewFlightDialog - Creates a NewFlightDialog that can be used to edit an existing entry in the logbook
* \param row_id - The database ROW ID of the entry to be edited
*/
explicit NewFlightDialog(int row_id, QWidget* parent = nullptr);
~NewFlightDialog();
private:
Ui::NewFlightDialog *ui;
ValidationState validationState;
/*!
* \brief a AFlightEntry object that is used to store either position data
* from an old entry, is used to fill the form for editing an entry, or is
* filled with new data for adding a new entry to the logbook.
*/
OPL::FlightEntry flightEntry;
/*!
* \brief timeLineEdits - Line Edits for time Off Blocks and Time On Blocks
*/
static const inline QList* timeLineEdits;
/*!
* \brief locationLineEdits - Line Edits for Departure and Destination Airports
*/
static const inline QList* locationLineEdits;
/*!
* \brief pilotNameLineEdits - Line Edits for Pilot in Command, Second in Command (Co-Pilot) and Third Pilot
*/
static const inline QList* pilotNameLineEdits;
/*!
* \brief mandatoryLineEdits - Contains the Line Edits that are needed for logging a complete flight from A to B.
* The list is ordered like the ValidationItem enum so that indexed access is possible using the enum.
*/
static const inline QList* mandatoryLineEdits;
static const inline QLatin1String self = QLatin1String("self");
void init();
void setupRawInputValidation();
void setupSignalsAndSlots();
void readSettings();
void fillWithEntryData();
bool verifyUserInput(QLineEdit *line_edit, const UserInput &input);
/*!
* \brief onGoodInputReceived - Sets a verification bit for the line edit that has been edited.
* \details When a Line Edit of the mandatoryLineEdits list is edited, on editingFinished(), the received input is
* evaluated and if considered a good input, the validation bit in validationState is set.
*/
void onGoodInputReceived(QLineEdit *line_edit);
/*!
* \brief onBadInputReceived Unsets a verification bit for the line edit that has been edited.
* \details When a Line Edit of the mandatoryLineEdits list is edited, on editingFinished(), the received input is
* evaluated and if considered a bad input, the validation bit in validationState is unset.
*/
void onBadInputReceived(QLineEdit *line_edit);
void updateBlockTimeLabel();
void setNightCheckboxes();
bool addNewTail(QLineEdit& parent_line_edit);
bool addNewPilot(QLineEdit& parent_line_edit);
bool checkPilotFunctionsValid();
OPL::RowData_T prepareFlightEntryData();
const static inline auto CAT_3 = QLatin1String(OPL::GLOBALS->getApproachTypes()[3].toLatin1());
private slots:
void toUpper(const QString& text);
void onTimeLineEdit_editingFinished();
void onPilotNameLineEdit_editingFinshed();
void onLocationLineEdit_editingFinished();
void on_acftLineEdit_editingFinished();
void on_doftLineEdit_editingFinished();
void on_buttonBox_accepted();
void on_pilotFlyingCheckBox_stateChanged(int arg1);
void on_approachComboBox_currentTextChanged(const QString &arg1);
void on_functionComboBox_currentIndexChanged(int index);
protected:
bool eventFilter(QObject* object, QEvent* event) override;
};
#endif // NewFlightDialog_H