Browse Source

Merge pull request #25 from fiffty-50/develop-newflightdialog

Develop newflightdialog
Felix Turowsky 4 years ago
parent
commit
7d10bb6f48

+ 1 - 0
assets/database/templates/changelog.csv

@@ -11,3 +11,4 @@ revision,comment,date
 10,added viewDefault as a copy of Logbook (deprecated),2020-11-23
 11,added viewQCompleter as a copy of QCompleterView (deprecated),2020-11-23
 12,reworked views to display self or picname according CASE,2020-12-11
+13,Reworked viewEASA to incorporate NULL handling,2020-12-17

+ 33 - 2
mainwindow.cpp

@@ -63,6 +63,8 @@ MainWindow::MainWindow(QWidget *parent)
     aircraftWidget = new AircraftWidget(this);
     ui->stackedWidget->addWidget(aircraftWidget);
 
+    connectWidgets();
+
     // Startup Screen (Home Screen)
     // ui->stackedWidget->setCurrentWidget(homeWidget);
     // Debup Widget for now
@@ -70,6 +72,25 @@ MainWindow::MainWindow(QWidget *parent)
     ui->stackedWidget->addWidget(debugWidget);
     ui->stackedWidget->setCurrentWidget(debugWidget);
 
+    //// START DEBUG ////
+    /// [F] I understand how it is annoying to not have the database
+    /// working when something has changed. Hopefully this check
+    /// helps to avoid that in the future!
+    const int DATABASE_REVISION_NUMBER = 13;
+    QSqlQuery query;
+    query.prepare("SELECT COUNT (*) FROM changelog");
+    query.exec();
+    query.next();
+    if (query.value(0).toInt() < DATABASE_REVISION_NUMBER) {
+        DEB("##########################################");
+        DEB("Your database is out of date.");
+        DEB("Curren Revision: " << DATABASE_REVISION_NUMBER);
+        DEB("You have revision: " << query.value(0).toInt());
+        DEB("Use of DebugWidget to udpate recommended.");
+        DEB("##########################################");
+    }
+    //// END DEBUG ////
+
 }
 
 MainWindow::~MainWindow()
@@ -109,6 +130,16 @@ void MainWindow::on_actionDebug_triggered()
     ui->stackedWidget->setCurrentWidget(debugWidget);
 }
 
+void MainWindow::connectWidgets()
+{
+    QObject::connect(experimental::aDB(), &experimental::ADataBase::commitSuccessful,
+                     logbookWidget, &LogbookWidget::onDatabaseChanged);
+    QObject::connect(experimental::aDB(), &experimental::ADataBase::commitSuccessful,
+                     pilotsWidget, &PilotsWidget::onDatabaseChanged);
+    QObject::connect(experimental::aDB(), &experimental::ADataBase::commitSuccessful,
+                     aircraftWidget, &AircraftWidget::onDatabaseChanged);
+}
+
 void MainWindow::on_actionSettings_triggered()
 {
     ui->stackedWidget->setCurrentWidget(settingsWidget);
@@ -126,7 +157,7 @@ void MainWindow::on_actionAircraft_triggered()
 
 void MainWindow::on_actionNewFlight_triggered()
 {
-    NewFlightDialog nf = NewFlightDialog(this, Db::createNew);
+    NewFlightDialog nf = NewFlightDialog(this);
     nf.exec();
 
 }
@@ -139,6 +170,6 @@ void MainWindow::on_actionNewAircraft_triggered()
 
 void MainWindow::on_actionNewPilot_triggered()
 {
-    NewPilotDialog np =NewPilotDialog(Db::createNew, this);
+    NewPilotDialog np = NewPilotDialog(Db::createNew, this);
     np.exec();
 }

+ 2 - 0
mainwindow.h

@@ -92,6 +92,8 @@ private:
 
     DebugWidget* debugWidget;
 
+    void connectWidgets();
+
 
 
 

+ 15 - 12
src/database/adatabasesetup.cpp

@@ -19,7 +19,7 @@
 #include "src/testing/adebug.h"
 
 
-// Statements for creation of database tables, Revision 12
+// Statements for creation of database tables, Revision 13
 
 const QString createTablePilots = "CREATE TABLE \"pilots\" ( "
             "\"pilot_id\"       INTEGER NOT NULL, "
@@ -165,9 +165,9 @@ const QString createViewEASA = "CREATE VIEW viewEASA AS "
         "dest AS 'Dest', printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time ', "
         "make||' '||model||'-'||variant AS 'Type', "
         "registration AS 'Registration', "
-        "(SELECT printf('%02d',(tSPSE/60))||':'||printf('%02d',(tSPSE%60)) WHERE tSPSE IS NOT \"\") AS 'SP SE', "
-        "(SELECT printf('%02d',(tSPME/60))||':'||printf('%02d',(tSPME%60)) WHERE tSPME IS NOT \"\") AS 'SP ME', "
-        "(SELECT printf('%02d',(tMP/60))||':'||printf('%02d',(tMP%60)) WHERE tMP IS NOT \"\") AS 'MP', "
+        "(SELECT printf('%02d',(tSPSE/60))||':'||printf('%02d',(tSPSE%60)) WHERE tSPSE IS NOT NULL) AS 'SP SE', "
+        "(SELECT printf('%02d',(tSPME/60))||':'||printf('%02d',(tSPME%60)) WHERE tSPME IS NOT NULL) AS 'SP ME', "
+        "(SELECT printf('%02d',(tMP/60))||':'||printf('%02d',(tMP%60)) WHERE tMP IS NOT NULL) AS 'MP', "
         "printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total', "
         "CASE "
         "WHEN pilot_id = 1 THEN alias "
@@ -176,12 +176,12 @@ const QString createViewEASA = "CREATE VIEW viewEASA AS "
         "AS 'Name PIC', "
         "ldgDay AS 'L/D', "
         "ldgNight AS 'L/N', "
-        "(SELECT printf('%02d',(tNight/60))||':'||printf('%02d',(tNight%60)) WHERE tNight IS NOT \"\")  AS 'Night', "
-        "(SELECT printf('%02d',(tIFR/60))||':'||printf('%02d',(tIFR%60)) WHERE tIFR IS NOT \"\")  AS 'IFR', "
-        "(SELECT printf('%02d',(tPIC/60))||':'||printf('%02d',(tPIC%60)) WHERE tPIC IS NOT \"\")  AS 'PIC', "
-        "(SELECT printf('%02d',(tSIC/60))||':'||printf('%02d',(tSIC%60)) WHERE tSIC IS NOT \"\")  AS 'SIC', "
-        "(SELECT printf('%02d',(tDual/60))||':'||printf('%02d',(tDual%60)) WHERE tDual IS NOT \"\")  AS 'Dual', "
-        "(SELECT printf('%02d',(tFI/60))||':'||printf('%02d',(tFI%60)) WHERE tFI IS NOT \"\")  AS 'FI', "
+        "(SELECT printf('%02d',(tNight/60))||':'||printf('%02d',(tNight%60)) WHERE tNight IS NOT NULL)  AS 'Night', "
+        "(SELECT printf('%02d',(tIFR/60))||':'||printf('%02d',(tIFR%60)) WHERE tIFR IS NOT NULL)  AS 'IFR', "
+        "(SELECT printf('%02d',(tPIC/60))||':'||printf('%02d',(tPIC%60)) WHERE tPIC IS NOT NULL)  AS 'PIC', "
+        "(SELECT printf('%02d',(tSIC/60))||':'||printf('%02d',(tSIC%60)) WHERE tSIC IS NOT NULL)  AS 'SIC', "
+        "(SELECT printf('%02d',(tDual/60))||':'||printf('%02d',(tDual%60)) WHERE tDual IS NOT NULL)  AS 'Dual', "
+        "(SELECT printf('%02d',(tFI/60))||':'||printf('%02d',(tFI%60)) WHERE tFI IS NOT NULL)  AS 'FI', "
         "Remarks "
         "FROM flights "
         "INNER JOIN pilots on flights.pic = pilots.pilot_id "
@@ -428,8 +428,11 @@ bool ADataBaseSetup::commitData(QVector<QStringList> fromCSV, const QString &tab
     for (int i = 0; i < fromCSV.first().length(); i++){
         query.prepare(statement);
         for(int j = 0; j < fromCSV.length(); j++) {
-            query.addBindValue(fromCSV[j][i]);
-        }
+             fromCSV[j][i] == QString("") ? // make sure NULL is committed for empty values
+                         query.addBindValue(QVariant(QVariant::String))
+                       : query.addBindValue(fromCSV[j][i]);
+             //query.addBindValue(fromCSV[j][i]);
+         }
         query.exec();
     }
 

+ 52 - 10
src/experimental/adatabase.cpp

@@ -97,7 +97,7 @@ bool ADataBase::remove(AEntry entry)
     if (query.lastError().type() == QSqlError::NoError)
     {
         DEB("Entry " << entry.getPosition().tableName << entry.getPosition().rowId << " removed.");
-        emit sqlSuccessful();
+        emit deleteSuccessful();
         return true;
     } else {
         DEB("Unable to delete.");
@@ -134,7 +134,7 @@ bool ADataBase::removeMany(QList<DataPosition> data_position_list)
         query.prepare("COMMIT");
         query.exec();
         if(query.lastError().type() == QSqlError::NoError) {
-            emit sqlSuccessful();
+            emit deleteSuccessful();
             return true;
         } else {
             emit sqlError(query.lastError(), "Transaction unsuccessful. Error count: " + QString::number(errorCount));
@@ -225,7 +225,7 @@ bool ADataBase::update(AEntry updated_entry)
     if (query.lastError().type() == QSqlError::NoError)
     {
         DEB("Entry successfully committed.");
-        emit sqlSuccessful();
+        emit commitSuccessful();
         return true;
     } else {
         DEB("Unable to commit.");
@@ -263,7 +263,7 @@ bool ADataBase::insert(AEntry new_entry)
     if (query.lastError().type() == QSqlError::NoError)
     {
         DEB("Entry successfully committed.");
-        emit sqlSuccessful();
+        emit commitSuccessful();
         return true;
     } else {
         DEB("Unable to commit.");
@@ -363,20 +363,20 @@ AFlightEntry ADataBase::getFlightEntry(RowId row_id)
     return flight_entry;
 }
 
-const QStringList ADataBase::getCompletionList(ADataBase::CompleterTarget target)
+const QStringList ADataBase::getCompletionList(ADataBase::DatabaseTarget target)
 {
     QString statement;
 
     switch (target) {
     case pilots:
-        statement.append("SELECT piclastname||\",\"||picfirstname FROM pilots");
+        statement.append("SELECT piclastname||\", \"||picfirstname FROM pilots");
         break;
     case aircraft:
         statement.append("SELECT make||\" \"||model FROM aircraft WHERE model IS NOT NULL "
                          "UNION "
                          "SELECT make||\" \"||model||\"-\"||variant FROM aircraft WHERE variant IS NOT NULL");
         break;
-    case airports:
+    case airport_identifier_all:
         statement.append("SELECT icao FROM airports UNION SELECT iata FROM airports");
         break;
     case registrations:
@@ -385,6 +385,9 @@ const QStringList ADataBase::getCompletionList(ADataBase::CompleterTarget target
     case companies:
         statement.append("SELECT company FROM pilots");
         break;
+    default:
+        DEB("Not a valid completer target for this function.");
+        return QStringList();
     }
 
     QSqlQuery query;
@@ -406,19 +409,31 @@ const QStringList ADataBase::getCompletionList(ADataBase::CompleterTarget target
     return completer_list;
 }
 
-const QMap<QString, int> ADataBase::getIdMap(ADataBase::CompleterTarget target)
+const QMap<QString, int> ADataBase::getIdMap(ADataBase::DatabaseTarget target)
 {
     QString statement;
 
     switch (target) {
     case pilots:
-        statement.append("SELECT ROWID, piclastname||\",\"||picfirstname FROM pilots");
+        statement.append("SELECT ROWID, piclastname||\", \"||picfirstname FROM pilots");
         break;
     case aircraft:
         statement.append("SELECT ROWID, make||\" \"||model FROM aircraft WHERE model IS NOT NULL "
                          "UNION "
                          "SELECT ROWID, make||\" \"||model||\"-\"||variant FROM aircraft WHERE variant IS NOT NULL");
         break;
+    case airport_identifier_icao:
+        statement.append("SELECT ROWID, icao FROM airports");
+        break;
+    case airport_identifier_iata:
+        statement.append("SELECT ROWID, iata FROM airports WHERE iata NOT NULL");
+        break;
+    case airport_names:
+        statement.append("SELECT ROWID, name FROM airports");
+        break;
+    case tails:
+        statement.append("SELECT ROWID, registration FROM tails");
+        break;
     default:
         DEB("Not a valid completer target for this function.");
         return QMap<QString, int>();
@@ -441,6 +456,33 @@ const QMap<QString, int> ADataBase::getIdMap(ADataBase::CompleterTarget target)
     }
 }
 
+int ADataBase::getLastEntry(ADataBase::DatabaseTarget target)
+{
+    QString statement = "SELECT MAX(ROWID) FROM ";
+
+    switch (target) {
+    case pilots:
+        statement.append("pilots");
+        break;
+    case aircraft:
+        statement.append("aircraft");
+        break;
+    case tails:
+        statement.append("tails");
+        break;
+    default:
+        DEB("Not a valid completer target for this function.");
+        return 0;
+    }
+    auto query = QSqlQuery(statement);
+    if (query.first()) {
+        return query.value(0).toInt();
+    } else {
+        DEB("No entry found.");
+        return 0;
+    }
+}
+
 QVector<QString> ADataBase::customQuery(QString statement, int return_values)
 {
     QSqlQuery query(statement);
@@ -461,7 +503,7 @@ QVector<QString> ADataBase::customQuery(QString statement, int return_values)
                 result.append(query.value(i).toString());
             }
         }
-        emit sqlSuccessful();
+        emit commitSuccessful();
         return result;
     }
 }

+ 9 - 5
src/experimental/adatabase.h

@@ -56,7 +56,7 @@ public:
      * \brief The CompleterTarget enum provides the items for which QCompleter
      * completion lists are provided from the database.
      */
-    enum CompleterTarget {airports, pilots, registrations, aircraft, companies};
+    enum DatabaseTarget {airport_identifier_icao, airport_identifier_iata, airport_identifier_all, airport_names, pilots, registrations, aircraft, companies, tails};
 
     /*!
      * \brief Connect to the database and populate database information.
@@ -169,16 +169,20 @@ public:
      * QCompleter based on database values
      * \return
      */
-    const QStringList getCompletionList(CompleterTarget);
+    const QStringList getCompletionList(DatabaseTarget);
 
     /*!
-     * \brief getIdMap returns a map of a human-readable database value and
+     * \brief returns a QMap<QString, int> of a human-readable database value and
      * its row id. Used in the Dialogs to map user input to unique database entries.
      * \return
      */
-    const QMap<QString, int> getIdMap(CompleterTarget);
+    const QMap<QString, int> getIdMap(DatabaseTarget);
+
+    int getLastEntry(DatabaseTarget);
 signals:
-    void sqlSuccessful();
+    void commitSuccessful();
+
+    void deleteSuccessful();
 
     void sqlError(const QSqlError &sqlError, const QString &sqlStatement);
 

+ 4 - 0
src/experimental/decl.h

@@ -16,6 +16,7 @@ using RowId = int;
 using TableNames = QStringList;
 /// [G]: May lead to some confusion. TableData suggest data for the entire table.
 /// but in reallity it is data per column *of single row* (unless i misunderstand)
+/// [F]: That's correct. We could maybe call it EntryData or RowData?
 using TableData = QMap<ColName, ColData>;
 using ColumnData = QPair<ColName, ColData>;
 using ColumnNames = QStringList;
@@ -24,6 +25,9 @@ using TableColumns = QMap<TableName, ColumnNames>;
 /// [G]: Needs some work. Inheriting from QPair may be helpful but
 /// may also be overkill. Lets determine the specific uses of DataPosition
 /// and provide our own interface i would say.
+/// [F]: Good idea! Implementing something similar to first and second methods
+/// of QPair would be useful to carry over, or some other way of quickly and
+/// unambiguously accessing the elements.
 struct DataPosition : QPair<TableName, RowId> {
     TableName tableName;
     RowId rowId;

+ 32 - 189
src/functions/acalc.cpp

@@ -4,76 +4,40 @@
 using namespace ACalc;
 
 /*!
- * \brief ACalc::blocktime Calculates Block Time for a given departure and arrival time
- * \param tofb QTime Time Off Blocks
- * \param tonb QTime Time On Blocks
- * \return Block Time in minutes
+ * \brief ACalc::formatTimeInput verifies user input and formats to hh:mm
+ * if the output is not a valid time, an empty string is returned. Accepts
+ * input as hh:mm, h:mm, hhmm or hmm.
+ * \param userinput from a QLineEdit
+ * \return formatted QString "hh:mm" or Empty String
  */
-QTime ACalc::blocktime(QTime tofb, QTime tonb)
+QString ACalc::formatTimeInput(QString user_input)
 {
-    QTime blocktime_out(0, 0); // initialise return value at midnight
-
-    if (tonb > tofb) { // landing same day
-        int blockseconds = tofb.secsTo(tonb);
-        blocktime_out = blocktime_out.addSecs(blockseconds);
-    } else { // landing next day
-        QTime midnight(0, 0);
-        int blockseconds = tofb.secsTo(midnight);
-        blocktime_out = blocktime_out.addSecs(blockseconds);
-        blockseconds = midnight.secsTo(tonb);
-        blocktime_out = blocktime_out.addSecs(blockseconds);
-    }
-    return blocktime_out;
-}
-
+    QString output; //
+    QTime temp_time; //empty time object is invalid by default
 
-/*!
- * \brief ACalc::minutes_to_string Converts database time to String Time
- * \param blockminutes from database
- * \return String hh:mm
- */
-QString ACalc::minutesToString(QString blockminutes)
-{
-    int minutes = blockminutes.toInt();
-    QString hour = QString::number(minutes / 60);
-    if (hour.size() < 2) {
-        hour.prepend("0");
-    }
-    QString minute = QString::number(minutes % 60);
-    if (minute.size() < 2) {
-        minute.prepend("0");
+    bool contains_seperator = user_input.contains(":");
+    if (user_input.length() == 4 && !contains_seperator) {
+        temp_time = QTime::fromString(user_input, "hhmm");
+    } else if (user_input.length() == 3 && !contains_seperator) {
+        if (user_input.toInt() < 240) { //Qtime is invalid if time is between 000 and 240 for this case
+            QString tempstring = user_input.prepend("0");
+            temp_time = QTime::fromString(tempstring, "hhmm");
+        } else {
+            temp_time = QTime::fromString(user_input, "Hmm");
+        }
+    } else if (user_input.length() == 4 && contains_seperator) {
+        temp_time = QTime::fromString(user_input, "h:mm");
+    } else if (user_input.length() == 5 && contains_seperator) {
+        temp_time = QTime::fromString(user_input, "hh:mm");
     }
-    QString blocktime = hour + ":" + minute;
-    return blocktime;
-};
 
-/*!
- * \brief ACalc::time_to_minutes converts QTime to int minutes
- * \param time QTime
- * \return int time as number of minutes
- */
-int ACalc::QTimeToMinutes(QTime time)
-{
-    QString timestring = time.toString("hh:mm");
-    int minutes = (timestring.left(2).toInt()) * 60;
-    minutes += timestring.right(2).toInt();
-    return minutes;
-}
-
-/*!
- * \brief ACalc::string_to_minutes Converts String Time to String Number of Minutes
- * \param timestring "hh:mm"
- * \return String number of minutes
- */
-int ACalc::stringToMinutes(QString timestring)
-{
-    int minutes = (timestring.left(2).toInt()) * 60;
-    minutes += timestring.right(2).toInt();
-    timestring = QString::number(minutes);
-    return minutes;
+    output = temp_time.toString("hh:mm");
+    if (output.isEmpty()) {
+        qDebug() << "Time input is invalid.";
+    }
+    return output;
 }
 
-
 /*!
  * The purpose of the following functions is to provide functionality enabling the Calculation of
  * night flying time. EASA defines night as follows:
@@ -98,47 +62,7 @@ int ACalc::stringToMinutes(QString timestring)
  * Radians.
  */
 
-/*!
- * \brief radToDeg Converts radians to degrees
- * \param rad
- * \return degrees
- */
-double ACalc::radToDeg(double rad)
-{
-    double deg = rad * (180 / M_PI);
-    return deg;
-}
-
-/*!
- * \brief degToRad Converts degrees to radians
- * \param deg
- * \return radians
- */
-double ACalc::degToRad(double deg)
-{
-    double rad = deg * (M_PI / 180);
-    return rad;
-}
-
-/*!
- * \brief radToNauticalMiles Convert Radians to nautical miles
- * \param rad
- * \return nautical miles
- */
-double ACalc::radToNauticalMiles(double rad)
-{
-    double nm = rad * 3440.06479482;
-    return nm;
-}
 
-/*!
- * \brief greatCircleDistance Calculates Great Circle distance between two coordinates, return in Radians.
- * \param lat1 Location Latitude in degrees -90:90 ;S(-) N(+)
- * \param lon1 Location Longitude in degrees -180:180 W(-) E(+)
- * \param lat2 Location Latitude in degrees -90:90 ;S(-) N(+)
- * \param lon2 Location Longitude in degrees -180:180 W(-) E(+)
- * \return
- */
 double ACalc::greatCircleDistance(double lat1, double lon1, double lat2, double lon2)
 {
     // Converting Latitude and Longitude to Radians
@@ -157,13 +81,7 @@ double ACalc::greatCircleDistance(double lat1, double lon1, double lat2, double
     return result;
 }
 
-/*!
- * \brief ACalc::greatCircleDistanceBetweenAirports Calculates Great
- * Circle distance between two coordinates, return in nautical miles.
- * \param dept ICAO 4-letter Airport Identifier
- * \param dest ICAO 4-letter Airport Identifier
- * \return Nautical Miles From Departure to Destination
- */
+
 double ACalc::greatCircleDistanceBetweenAirports(QString dept, QString dest)
 {
     QVector<QString> dept_coordinates = Db::multiSelect({"lat", "long"}, "airports", "icao", dept,
@@ -192,16 +110,7 @@ double ACalc::greatCircleDistanceBetweenAirports(QString dept, QString dest)
     return radToNauticalMiles(result);
 }
 
-/*!
- * \brief  Calculates a list of points (lat,lon) along the Great Circle between two points.
- * The points are spaced equally, one minute of block time apart.
- * \param lat1 Location Latitude in degrees -90:90 ;S(-) N(+)
- * \param lon1 Location Longitude in degrees -180:180 W(-) E(+)
- * \param lat2 Location Latitude in degrees -90:90 ;S(-) N(+)
- * \param lon2 Location Longitude in degrees -180:180 W(-) E(+)
- * \param tblk Total Blocktime in minutes
- * \return coordinates {lat,lon} along the Great Circle Track
- */
+
 QVector<QVector<double>> ACalc::intermediatePointsOnGreatCircle(double lat1, double lon1,
                                                                double lat2, double lon2, int tblk)
 {
@@ -232,22 +141,7 @@ QVector<QVector<double>> ACalc::intermediatePointsOnGreatCircle(double lat1, dou
     return coordinates;
 }
 
-/*!
- * \brief Calculates solar elevation angle for a given point in time and latitude/longitude coordinates
- *
- * It is based on the formulas found here: http://stjarnhimlen.se/comp/tutorial.html#5
- *
- * Credit also goes to Darin C. Koblick for his matlab implementation of various of these
- * formulas and to Kevin Godden for porting it to C++.
- *
- * Darin C. Koblock: https://www.mathworks.com/matlabcentral/profile/authors/1284781
- * Kevin Godden: https://www.ridgesolutions.ie/index.php/about-us/
- *
- * \param utc_time_point - QDateTime (UTC) for which the elevation is Calculated
- * \param lat - Location Latitude in degrees -90:90 ;S(-) N(+)
- * \param lon - Location Longitude in degrees -180:180 W(-) E(+)
- * \return elevation - double of solar elevation in degrees.
- */
+
 double ACalc::solarElevation(QDateTime utc_time_point, double lat, double lon)
 {
     double Alt =
@@ -307,16 +201,7 @@ double ACalc::solarElevation(QDateTime utc_time_point, double lat, double lon)
     return elevation;
 }
 
-/*!
- * \brief Calculates which portion of a flight was conducted in night conditions.
- * \param dept - ICAO 4-letter code of Departure Airport
- * \param dest - ICAO 4-letter Code of Destination Airport
- * \param departureTime - QDateTime of Departure (UTC)
- * \param tblk - Total block time in minutes
- * \param nightAngle - the solar elevation angle where night conditons exist.
- * Default -6 (end of civil evening twilight)
- * \return Total number of minutes under night flying conditions
- */
+
 int ACalc::calculateNightTime(const QString &dept, const QString &dest, QDateTime departureTime, int tblk, int nightAngle)
 {
     QVector<QString> dept_coordinates = Db::multiSelect({"lat", "long"}, "airports", "icao", dept,
@@ -334,12 +219,7 @@ int ACalc::calculateNightTime(const QString &dept, const QString &dest, QDateTim
     double dept_lon = degToRad(dept_coordinates[1].toDouble());
     double dest_lat = degToRad(dest_coordinates[0].toDouble());
     double dest_lon = degToRad(dest_coordinates[1].toDouble());
-/*
-    qDebug() << "ACalc::CalculateNightTime deptLat = " << deptLat;
-    qDebug() << "ACalc::CalculateNightTime deptLon = " << deptLon;
-    qDebug() << "ACalc::CalculateNightTime destLat = " << destLat;
-    qDebug() << "ACalc::CalculateNightTime destLon = " << destLon;
-*/
+
     QVector<QVector<double>> route = intermediatePointsOnGreatCircle(dept_lat, dept_lon, dest_lat, dest_lon,
                                                                      tblk);
 
@@ -350,8 +230,6 @@ int ACalc::calculateNightTime(const QString &dept, const QString &dest, QDateTim
             night_time ++;
         }
     }
-    //qDebug() << "ACalc::CalculateNightTime result for angle: "<< nightAngle
-    //         << " :" << nightTime << " minutes night flying time.";
     return night_time;
 }
 
@@ -374,41 +252,6 @@ bool ACalc::isNight(QString icao, QDateTime event_time, int nightAngle)
     }
 }
 
-/*!
- * \brief ACalc::formatTimeInput verifies user input and formats to hh:mm
- * if the output is not a valid time, an empty string is returned. Accepts
- * input as hh:mm, h:mm, hhmm or hmm.
- * \param userinput from a QLineEdit
- * \return formatted QString "hh:mm" or Empty String
- */
-QString ACalc::formatTimeInput(QString user_input)
-{
-    QString output; //
-    QTime temp_time; //empty time object is invalid by default
-
-    bool contains_seperator = user_input.contains(":");
-    if (user_input.length() == 4 && !contains_seperator) {
-        temp_time = QTime::fromString(user_input, "hhmm");
-    } else if (user_input.length() == 3 && !contains_seperator) {
-        if (user_input.toInt() < 240) { //Qtime is invalid if time is between 000 and 240 for this case
-            QString tempstring = user_input.prepend("0");
-            temp_time = QTime::fromString(tempstring, "hhmm");
-        } else {
-            temp_time = QTime::fromString(user_input, "Hmm");
-        }
-    } else if (user_input.length() == 4 && contains_seperator) {
-        temp_time = QTime::fromString(user_input, "h:mm");
-    } else if (user_input.length() == 5 && contains_seperator) {
-        temp_time = QTime::fromString(user_input, "hh:mm");
-    }
-
-    output = temp_time.toString("hh:mm");
-    if (output.isEmpty()) {
-        qDebug() << "Time input is invalid.";
-    }
-    return output;
-}
-
 /*!
  * \brief ACalc::updateAutoTimes When the details of an aircraft are changed,
  * this function recalculates deductable times for this aircraft and updates

+ 146 - 9
src/functions/acalc.h

@@ -16,32 +16,169 @@
 
 namespace ACalc {
 
-QTime blocktime(QTime tofb, QTime tonb);
-
-QString minutesToString(QString blockminutes);
+/*!
+ * \brief ACalc::blocktime Calculates Block Time for a given departure and arrival time
+ * \param tofb QTime Time Off Blocks
+ * \param tonb QTime Time On Blocks
+ * \return Block Time in minutes
+ */
+inline QTime blocktime(QTime tofb, QTime tonb)
+{
+    QTime blocktime_out(0, 0); // initialise return value at midnight
+
+    if (tonb > tofb) { // landing same day
+        int blockseconds = tofb.secsTo(tonb);
+        blocktime_out = blocktime_out.addSecs(blockseconds);
+    } else { // landing next day
+        QTime midnight(0, 0);
+        int blockseconds = tofb.secsTo(midnight);
+        blocktime_out = blocktime_out.addSecs(blockseconds);
+        blockseconds = midnight.secsTo(tonb);
+        blocktime_out = blocktime_out.addSecs(blockseconds);
+    }
+    return blocktime_out;
+}
+/*!
+ * \brief ACalc::minutes_to_string Converts database time to String Time
+ * \param blockminutes from database
+ * \return String hh:mm
+ */
+inline QString minutesToString(QString blockminutes)
+{
+    int minutes = blockminutes.toInt();
+    QString hour = QString::number(minutes / 60);
+    if (hour.size() < 2) {
+        hour.prepend("0");
+    }
+    QString minute = QString::number(minutes % 60);
+    if (minute.size() < 2) {
+        minute.prepend("0");
+    }
+    QString blocktime = hour + ":" + minute;
+    return blocktime;
+};
 
-int stringToMinutes(QString time);
+/*!
+ * \brief ACalc::time_to_minutes converts QTime to int minutes
+ * \param time QTime
+ * \return int time as number of minutes
+ */
+inline int QTimeToMinutes(QTime time)
+{
+    QString timestring = time.toString("hh:mm");
+    int minutes = (timestring.left(2).toInt()) * 60;
+    minutes += timestring.right(2).toInt();
+    return minutes;
+}
 
-int QTimeToMinutes(QTime time);
+/*!
+ * \brief ACalc::string_to_minutes Converts String Time to String Number of Minutes
+ * \param timestring "hh:mm"
+ * \return String number of minutes
+ */
+inline int stringToMinutes(QString timestring)
+{
+    int minutes = (timestring.left(2).toInt()) * 60;
+    minutes += timestring.right(2).toInt();
+    timestring = QString::number(minutes);
+    return minutes;
+}
 
-double radToDeg(double rad);
+/*!
+ * \brief radToDeg Converts radians to degrees
+ * \param rad
+ * \return degrees
+ */
+inline double radToDeg(double rad)
+{
+    double deg = rad * (180 / M_PI);
+    return deg;
+}
 
-double degToRad(double deg);
+/*!
+ * \brief degToRad Converts degrees to radians
+ * \param deg
+ * \return radians
+ */
+inline double degToRad(double deg)
+{
+    double rad = deg * (M_PI / 180);
+    return rad;
+}
 
-double radToNauticalMiles(double rad);
+/*!
+ * \brief radToNauticalMiles Convert Radians to nautical miles
+ * \param rad
+ * \return nautical miles
+ */
+inline double radToNauticalMiles(double rad)
+{
+    double nm = rad * 3440.06479482;
+    return nm;
+}
 
+/*!
+ * \brief greatCircleDistance Calculates Great Circle distance between two coordinates, return in Radians.
+ * \param lat1 Location Latitude in degrees -90:90 ;S(-) N(+)
+ * \param lon1 Location Longitude in degrees -180:180 W(-) E(+)
+ * \param lat2 Location Latitude in degrees -90:90 ;S(-) N(+)
+ * \param lon2 Location Longitude in degrees -180:180 W(-) E(+)
+ * \return
+ */
 double greatCircleDistance(double lat1, double lon1, double lat2, double lon2);
 
+/*!
+ * \brief ACalc::greatCircleDistanceBetweenAirports Calculates Great
+ * Circle distance between two coordinates, return in nautical miles.
+ * \param dept ICAO 4-letter Airport Identifier
+ * \param dest ICAO 4-letter Airport Identifier
+ * \return Nautical Miles From Departure to Destination
+ */
 double greatCircleDistanceBetweenAirports(QString dept, QString dest);
 
+/*!
+ * \brief  Calculates a list of points (lat,lon) along the Great Circle between two points.
+ * The points are spaced equally, one minute of block time apart.
+ * \param lat1 Location Latitude in degrees -90:90 ;S(-) N(+)
+ * \param lon1 Location Longitude in degrees -180:180 W(-) E(+)
+ * \param lat2 Location Latitude in degrees -90:90 ;S(-) N(+)
+ * \param lon2 Location Longitude in degrees -180:180 W(-) E(+)
+ * \param tblk Total Blocktime in minutes
+ * \return coordinates {lat,lon} along the Great Circle Track
+ */
 QVector<QVector<double>> intermediatePointsOnGreatCircle(double lat1,
                                                          double lon1,
                                                          double lat2,
                                                          double lon2,
                                                          int tblk);
-
+/*!
+ * \brief Calculates solar elevation angle for a given point in time and latitude/longitude coordinates
+ *
+ * It is based on the formulas found here: http://stjarnhimlen.se/comp/tutorial.html#5
+ *
+ * Credit also goes to Darin C. Koblick for his matlab implementation of various of these
+ * formulas and to Kevin Godden for porting it to C++.
+ *
+ * Darin C. Koblock: https://www.mathworks.com/matlabcentral/profile/authors/1284781
+ * Kevin Godden: https://www.ridgesolutions.ie/index.php/about-us/
+ *
+ * \param utc_time_point - QDateTime (UTC) for which the elevation is Calculated
+ * \param lat - Location Latitude in degrees -90:90 ;S(-) N(+)
+ * \param lon - Location Longitude in degrees -180:180 W(-) E(+)
+ * \return elevation - double of solar elevation in degrees.
+ */
 double solarElevation(QDateTime utc_time_point, double lat, double lon);
 
+/*!
+ * \brief Calculates which portion of a flight was conducted in night conditions.
+ * \param dept - ICAO 4-letter code of Departure Airport
+ * \param dest - ICAO 4-letter Code of Destination Airport
+ * \param departureTime - QDateTime of Departure (UTC)
+ * \param tblk - Total block time in minutes
+ * \param nightAngle - the solar elevation angle where night conditons exist.
+ * Default -6 (end of civil evening twilight)
+ * \return Total number of minutes under night flying conditions
+ */
 int calculateNightTime(const QString &dept, const QString &dest, QDateTime departureTime, int tblk, int nightAngle);
 
 bool isNight(QString icao, QDateTime event_time, int nightAngle);

+ 25 - 17
src/gui/dialogues/newflight.ui

@@ -14,10 +14,10 @@
    <string>New Flight</string>
   </property>
   <layout class="QGridLayout" name="gridLayout_2">
-   <item row="0" column="0" colspan="3">
+   <item row="0" column="0" colspan="2">
     <widget class="QTabWidget" name="flightDataTabWidget">
      <property name="currentIndex">
-      <number>0</number>
+      <number>1</number>
      </property>
      <widget class="QWidget" name="flightDataTab">
       <attribute name="title">
@@ -819,6 +819,13 @@
          </property>
         </widget>
        </item>
+       <item row="0" column="3">
+        <widget class="QCheckBox" name="calendarCheckBox">
+         <property name="text">
+          <string>Calendar</string>
+         </property>
+        </widget>
+       </item>
       </layout>
       <zorder>placeLabel2</zorder>
       <zorder>deptLocLineEdit</zorder>
@@ -873,6 +880,7 @@
       <zorder>FlightNumberLabel</zorder>
       <zorder>doftDisplayLabel</zorder>
       <zorder>placeLabel1</zorder>
+      <zorder>calendarCheckBox</zorder>
      </widget>
      <widget class="QWidget" name="autoLoggingTab">
       <attribute name="title">
@@ -1413,26 +1421,28 @@
     </widget>
    </item>
    <item row="1" column="0">
-    <widget class="QPushButton" name="verifyButton">
+    <widget class="QPushButton" name="cancelButton">
+     <property name="styleSheet">
+      <string notr="true">color: rgb(164, 0, 0);</string>
+     </property>
      <property name="text">
-      <string>DebugButton</string>
+      <string>Cancel</string>
      </property>
     </widget>
    </item>
    <item row="1" column="1">
-    <widget class="QLineEdit" name="verifyEdit">
-     <property name="placeholderText">
-      <string>Debug Text</string>
+    <widget class="QPushButton" name="submitButton">
+     <property name="enabled">
+      <bool>false</bool>
      </property>
-    </widget>
-   </item>
-   <item row="1" column="2">
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
+     <property name="whatsThis">
+      <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Add your flight to the logbook.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can only perform this action if all of the mandatory fields are filled.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
      </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     <property name="styleSheet">
+      <string notr="true">color: rgb(78, 154, 6);</string>
+     </property>
+     <property name="text">
+      <string>Submit</string>
      </property>
     </widget>
    </item>
@@ -1466,8 +1476,6 @@
   <tabstop>restoreDefaultButton</tabstop>
   <tabstop>manualEditingCheckBox</tabstop>
   <tabstop>tblkTimeLineEdit</tabstop>
-  <tabstop>verifyButton</tabstop>
-  <tabstop>verifyEdit</tabstop>
   <tabstop>calendarWidget</tabstop>
   <tabstop>flightDataTabWidget</tabstop>
  </tabstops>

File diff suppressed because it is too large
+ 631 - 266
src/gui/dialogues/newflightdialog.cpp


+ 73 - 149
src/gui/dialogues/newflightdialog.h

@@ -32,47 +32,17 @@
 #include <QLineEdit>
 #include <QCalendarWidget>
 #include <QTabWidget>
-#include <QSqlRelationalTableModel>
+#include <QKeyEvent>
 
-
-#include "src/database/db.h"
-#include "src/classes/flight.h"
-#include "src/classes/aircraft.h"
-#include "src/classes/astrictrxvalidator.h"
-#include "src/classes/asettings.h"
-#include "src/functions/acalc.h"
-#include "src/experimental/adatabase.h"
-
-#include "src/gui/dialogues/newpilotdialog.h"
 #include "src/gui/dialogues/newtaildialog.h"
+#include "src/gui/dialogues/newpilotdialog.h"
 
-class SqlColumnNum{
-public:
-    SqlColumnNum() : _column(-1) {}
-    explicit
-    SqlColumnNum(int column) : _column(column) {}
-    int column() const { return _column; }
-private:
-    int _column;
-};
-
-class LineEditSettings {
-public:
-    LineEditSettings() = default;
-    explicit LineEditSettings(QRegularExpression input_valid_rgx, QRegularExpression input_invalid_rgx,
-                              SqlColumnNum sql_column)
-        : _input_valid_rgx(input_valid_rgx), _input_invalid_rgx(input_invalid_rgx),
-          _sql_column(sql_column) {}
-
-    const std::tuple<QRegularExpression, QRegularExpression, SqlColumnNum> getAll() const
-    {
-        return {_input_valid_rgx, _input_invalid_rgx, _sql_column};
-    }
-private:
-    QRegularExpression _input_valid_rgx = QRegularExpression("");
-    QRegularExpression _input_invalid_rgx = QRegularExpression("");
-    SqlColumnNum _sql_column = SqlColumnNum(-1);
-};
+#include "src/experimental/adatabase.h"
+#include "src/experimental/aflightentry.h"
+#include "src/experimental/apilotentry.h"
+#include "src/experimental/atailentry.h"
+#include "src/functions/acalc.h"
+#include "src/testing/atimer.h"
 
 namespace Ui {
 class NewFlight;
@@ -83,153 +53,107 @@ class NewFlightDialog : public QDialog
     Q_OBJECT
 
 public:
-    explicit NewFlightDialog(QWidget *parent, Db::editRole edRole);
-    explicit NewFlightDialog(QWidget *parent, Flight oldFlight, Db::editRole edRole);
+    explicit NewFlightDialog(QWidget *parent = nullptr);
+    explicit NewFlightDialog(int row_id, QWidget *parent = nullptr);
     ~NewFlightDialog();
 
-    //QStringList* getResult();
-
-private:
-
-    bool eventFilter(QObject* object, QEvent* event);
-
-    void setup();
-
-    void formFiller(Flight oldFlight);
-
-    void setupLineEdit(QLineEdit* line_edit, LineEditSettings settings);
-
-    void addNewPilotMessageBox(QLineEdit *parent);
-
-    void addNewAircraftMessageBox(QLineEdit *parent);
-
-    void readSettings();
-
-    void writeSettings();
-
-    void collectBasicData();
-
-    void collectAdditionalData();
-
-    void fillExtras();
-
-    bool verifyInput();
-
-    void onInputRejected(QLineEdit* line_edit, QRegularExpression rgx);
-
-    void onEditingFinishedCleanup(QLineEdit* line_edit);
-
-    void update();
-
-    bool isLessOrEqualToTotalTime(QString timeString);
+signals:
+    void goodInputReceived(QLineEdit*);
+    void badInputReceived(QLineEdit*);
+    void locationEditingFinished(QLineEdit*, QLabel*);
+    void timeEditingFinished(QLineEdit*);
+    void mandatoryLineEditsFilled();
 
 private slots:
 
-    void on_verifyButton_clicked(); //debug button
-
-    void on_deptTZ_currentTextChanged(const QString &arg1);
-    void on_destTZ_currentIndexChanged(const QString &arg1);
-
-    void on_tofbTimeLineEdit_editingFinished();
-    void on_tonbTimeLineEdit_editingFinished();
-    void on_tofbTimeLineEdit_inputRejected();
-    void on_tonbTimeLineEdit_inputRejected();
+    void onGoodInputReceived(QLineEdit*);
+    void onBadInputReceived(QLineEdit *);
+    void onTextChangedToUpper(const QString&);
+    void onPilotNameLineEdit_editingFinished();
+    void onLocLineEdit_editingFinished(QLineEdit*, QLabel*);
+    void onTimeLineEdit_editingFinished();
+    void onMandatoryLineEditsFilled();
+    void onCompleterHighlighted(const QString&);
+    void onCompleterActivated(const QString &);
+    void onDateClicked(const QDate &date);
+    void onDateSelected(const QDate &date);
+    void onDoftLineEditEntered();
 
     void on_deptLocLineEdit_editingFinished();
     void on_destLocLineEdit_editingFinished();
-    void on_destLocLineEdit_inputRejected();
-    void on_deptLocLineEdit_inputRejected();
-
-    void on_deptLocLineEdit_textEdited(const QString &arg1);
-    void on_destLocLineEdit_textEdited(const QString &arg1);
-
-    void on_doftTimeEdit_editingFinished();
-
-    void on_acftLineEdit_inputRejected();
     void on_acftLineEdit_editingFinished();
 
-    void on_picNameLineEdit_inputRejected();
-    void on_picNameLineEdit_editingFinished();
-    void on_secondPilotNameLineEdit_editingFinished();
-    void on_secondPilotNameLineEdit_inputRejected();
-    void on_thirdPilotNameLineEdit_editingFinished();
-    void on_thirdPilotNameLineEdit_inputRejected();
 
-    void on_setAsDefaultButton_clicked();
-    void on_restoreDefaultButton_clicked();
+/////// DEBUG
+    void onInputRejected();
+/////// DEBUG
 
-    void on_buttonBox_accepted();
-    void on_buttonBox_rejected();
+    void on_calendarCheckBox_stateChanged(int arg1);
 
-    void on_PilotFlyingCheckBox_stateChanged(int);
+    void on_doftLineEdit_editingFinished();
 
-    void on_ApproachComboBox_currentTextChanged(const QString &arg1);
+    void on_cancelButton_clicked();
 
-    void on_tSPSETimeLineEdit_editingFinished();
-    void on_tSPMETimeLineEdit_editingFinished();
+    void on_submitButton_clicked();
 
-    void on_tMPTimeLineEdit_editingFinished();
+    void on_setAsDefaultButton_clicked();
+
+    void on_restoreDefaultButton_clicked();
 
-    void on_tIFRTimeLineEdit_editingFinished();
-    void on_tNIGHTTimeLineEdit_editingFinished();
-    void on_tPICTimeLineEdit_editingFinished();
-    void on_tSICTimeLineEdit_editingFinished();
-    void on_tDUALTimeLineEdit_editingFinished();
-    void on_tFITimeLineEdit_editingFinished();
-    void on_FlightNumberLineEdit_textChanged(const QString &arg1);
+    void on_PilotFlyingCheckBox_stateChanged(int arg1);
 
+    void on_IfrCheckBox_stateChanged(int);
 
     void on_manualEditingCheckBox_stateChanged(int arg1);
 
-    void on_FunctionComboBox_currentTextChanged();
-
-    void on_tblkTimeLineEdit_editingFinished();
+    void on_ApproachComboBox_currentTextChanged(const QString &arg1);
 
-    void on_IfrCheckBox_stateChanged();
 
-    void on_TakeoffSpinBox_valueChanged(int arg1);
+    void on_FunctionComboBox_currentIndexChanged(int index);
 
-    void on_LandingSpinBox_valueChanged(int arg1);
+private:
+    Ui::NewFlight *ui;
 
-    void on_AutolandSpinBox_valueChanged(int arg1);
+    experimental::AFlightEntry flightEntry;
 
-    void on_TakeoffCheckBox_stateChanged(int arg1);
+    QList<QLineEdit*> mandatoryLineEdits;
+    QList<QLineEdit*> primaryTimeLineEdits;
+    QList<QLineEdit*> pilotsLineEdits;
 
-    void on_LandingCheckBox_stateChanged(int arg1);
+    QBitArray mandatoryLineEditsGood;
 
-    void on_AutolandCheckBox_stateChanged(int arg1);
+    QStringList pilotList;
+    QStringList tailsList;
+    QStringList airportList;
 
-    //void on_doftToolButton_clicked();
+    QMap<QString, int> pilotsIdMap;
+    QMap<QString, int> tailsIdMap;
+    QMap<QString, int> airportIcaoIdMap;
+    QMap<QString, int> airportIataIdMap;
+    QMap<QString, int> airportNameIdMap;
 
-    void date_clicked(const QDate &date);
+    bool eventFilter(QObject *object, QEvent *event);
 
-    void date_selected(const QDate &date);
+    bool updateEnabled;
 
-    void on_doftLineEdit_inputRejected();
+    bool isLessOrEqualThanBlockTime(const QString time_string);
 
-    void on_doftLineEdit_editingFinished();
+    void setup();
+    void readSettings();
+    void writeSettings();
+    void setupButtonGroups();
+    void setPopUpCalendarEnabled(bool state);
+    void setupRawInputValidation();
+    void setupLineEditSignalsAndSlots();
 
-    void on_doftLineEditEntered();
+    void formFiller();
 
-signals:
-    void mandatoryFieldsValid(NewFlightDialog* nf);
+    void fillDeductibleData();
+    experimental::TableData collectInput();
 
-private:
-    Db::editRole role;
-    Flight entry;
-    bool doUpdate;
-    Ui::NewFlight *ui;
-    QMap<QLineEdit*, int> lineEditBitMap;
-    QVector<QLineEdit*> mandatoryLineEdits;
-    QBitArray allOkBits;
-    QMessageBox messageBox;
-    QDate clickedDate;
-    // For Flight Object
-    QMap<QString, QString> airportMap;
-    QStringList airports;
-    QStringList pilots;
-    QStringList tails;
-    QMap<QString, QString> newData;
+    void addNewTail(QLineEdit*);
+    void addNewPilot(QLineEdit *);
 };
 
+
 #endif // NEWFLIGHT_H

+ 1 - 1
src/gui/dialogues/newpilotdialog.cpp

@@ -119,7 +119,7 @@ void NewPilotDialog::setup()
     ///   makes it easier to maintain.
     /// - these signals and slots are specific to this dialog, for communication with
     ///   other widgets we have the QDialog::accepted() and QDialog::rejected signals.
-    QObject::connect(aDB(), &ADataBase::sqlSuccessful,
+    QObject::connect(aDB(), &ADataBase::commitSuccessful,
                      this, &NewPilotDialog::onCommitSuccessful);
     QObject::connect(aDB(), &ADataBase::sqlError,
                      this, &NewPilotDialog::onCommitUnsuccessful);

+ 1 - 1
src/gui/dialogues/newtaildialog.cpp

@@ -111,7 +111,7 @@ void NewTailDialog::setupValidators()
 void NewTailDialog::connectSignals()
 {
     using namespace experimental;
-    QObject::connect(aDB(), &ADataBase::sqlSuccessful,
+    QObject::connect(aDB(), &ADataBase::commitSuccessful,
                      this,  &NewTailDialog::onCommitSuccessful);
     QObject::connect(aDB(), &ADataBase::sqlError,
                      this,  &NewTailDialog::onCommitUnsuccessful);

+ 7 - 1
src/gui/widgets/aircraftwidget.cpp

@@ -128,7 +128,7 @@ void AircraftWidget::on_deleteButton_clicked()
     }
 }
 
-void AircraftWidget::on_newButton_clicked()
+void AircraftWidget::on_newAircraftButton_clicked()
 {
     auto nt = NewTailDialog(QString(), this);
     connect(&nt, SIGNAL(accepted()), this, SLOT(acft_editing_finished()));
@@ -144,6 +144,12 @@ void AircraftWidget::on_aircraftSearchLineEdit_textChanged(const QString &arg1)
     model->setFilter(ui->aircraftSearchComboBox->currentText() + " LIKE \"%" + arg1 + "%\"");
 }
 
+void AircraftWidget::onDatabaseChanged()
+{
+    //refresh view to reflect changes the user has made via a dialog.
+    model->select();
+}
+
 void AircraftWidget::tableView_selectionChanged()
 {
     if (this->findChild<NewTailDialog*>() != nullptr) {

+ 4 - 1
src/gui/widgets/aircraftwidget.h

@@ -49,12 +49,15 @@ private slots:
 
     void on_deleteButton_clicked();
 
-    void on_newButton_clicked();
+    void on_newAircraftButton_clicked();
 
     void acft_editing_finished();
 
     void on_aircraftSearchLineEdit_textChanged(const QString &arg1);
 
+public slots:
+    void onDatabaseChanged();
+
 private:
     Ui::AircraftWidget *ui;
 

+ 1 - 1
src/gui/widgets/aircraftwidget.ui

@@ -153,7 +153,7 @@
     </layout>
    </item>
    <item row="1" column="0">
-    <widget class="QPushButton" name="newButton">
+    <widget class="QPushButton" name="newAircraftButton">
      <property name="text">
       <string>New Aircraft</string>
      </property>

+ 8 - 0
src/gui/widgets/debugwidget.cpp

@@ -164,6 +164,14 @@ void DebugWidget::on_importCsvPushButton_clicked()
 
 void DebugWidget::on_debugPushButton_clicked()
 {
+    using namespace experimental;
+
+    auto pilotsIdMap  = aDB()->getIdMap(ADataBase::pilots);
+    auto pilotList    = aDB()->getCompletionList(ADataBase::pilots);
+
+    DEB(pilotsIdMap.key(aDB()->getLastEntry(ADataBase::pilots)));
+    DEB(pilotList);
+
 
 }
 

+ 50 - 47
src/gui/widgets/debugwidget.ui

@@ -24,6 +24,13 @@
        <string>Database</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_2">
+       <item row="2" column="3">
+        <widget class="QLabel" name="label_3">
+         <property name="text">
+          <string>Fill a new database with sample entries</string>
+         </property>
+        </widget>
+       </item>
        <item row="3" column="3">
         <widget class="QLineEdit" name="importCsvLineEdit">
          <property name="minimumSize">
@@ -37,8 +44,18 @@
          </property>
         </widget>
        </item>
-       <item row="3" column="4">
-        <widget class="QPushButton" name="selectCsvPushButton">
+       <item row="4" column="3">
+        <widget class="QLineEdit" name="debugLineEdit"/>
+       </item>
+       <item row="2" column="0">
+        <widget class="QPushButton" name="fillUserDataPushButton">
+         <property name="text">
+          <string>Fill User Table with test data</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="0">
+        <widget class="QPushButton" name="importCsvPushButton">
          <property name="minimumSize">
           <size>
            <width>110</width>
@@ -46,27 +63,21 @@
           </size>
          </property>
          <property name="text">
-          <string>Select File</string>
+          <string>Import CSV</string>
          </property>
         </widget>
        </item>
-       <item row="0" column="0">
-        <widget class="QPushButton" name="resetDatabasePushButton">
-         <property name="minimumSize">
-          <size>
-           <width>220</width>
-           <height>0</height>
-          </size>
-         </property>
+       <item row="4" column="0">
+        <widget class="QPushButton" name="debugPushButton">
          <property name="text">
-          <string>Reset Database</string>
+          <string>Do Debug Stuff!</string>
          </property>
         </widget>
        </item>
-       <item row="2" column="0">
-        <widget class="QPushButton" name="fillUserDataPushButton">
+       <item row="1" column="3">
+        <widget class="QLabel" name="label_2">
          <property name="text">
-          <string>Fill User Table with test data</string>
+          <string>Keep current database but delete entries in pilots, aircraft and flights</string>
          </property>
         </widget>
        </item>
@@ -83,6 +94,19 @@
          </property>
         </widget>
        </item>
+       <item row="3" column="4">
+        <widget class="QPushButton" name="selectCsvPushButton">
+         <property name="minimumSize">
+          <size>
+           <width>110</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>Select File</string>
+         </property>
+        </widget>
+       </item>
        <item row="0" column="3">
         <widget class="QLabel" name="label">
          <property name="text">
@@ -90,10 +114,16 @@
          </property>
         </widget>
        </item>
-       <item row="1" column="3">
-        <widget class="QLabel" name="label_2">
+       <item row="0" column="0">
+        <widget class="QPushButton" name="resetDatabasePushButton">
+         <property name="minimumSize">
+          <size>
+           <width>220</width>
+           <height>0</height>
+          </size>
+         </property>
          <property name="text">
-          <string>Keep current database but delete entries in pilots, aircraft and flights</string>
+          <string>Reset Database</string>
          </property>
         </widget>
        </item>
@@ -112,35 +142,8 @@
          </item>
         </widget>
        </item>
-       <item row="3" column="0">
-        <widget class="QPushButton" name="importCsvPushButton">
-         <property name="minimumSize">
-          <size>
-           <width>110</width>
-           <height>0</height>
-          </size>
-         </property>
-         <property name="text">
-          <string>Import CSV</string>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="3">
-        <widget class="QLabel" name="label_3">
-         <property name="text">
-          <string>Fill a new database with sample entries</string>
-         </property>
-        </widget>
-       </item>
-       <item row="4" column="0">
-        <widget class="QPushButton" name="debugPushButton">
-         <property name="text">
-          <string>Do Debug Stuff!</string>
-         </property>
-        </widget>
-       </item>
-       <item row="4" column="3">
-        <widget class="QLineEdit" name="debugLineEdit"/>
+       <item row="5" column="3">
+        <widget class="QLineEdit" name="debug2LineEdit"/>
        </item>
       </layout>
      </widget>

+ 11 - 5
src/gui/widgets/logbookwidget.cpp

@@ -76,7 +76,7 @@ void LogbookWidget::connectSignalsAndSlots()
     QObject::connect(view->selectionModel(), &QItemSelectionModel::selectionChanged,
                      this, &LogbookWidget::flightsTableView_selectionChanged);
     using namespace experimental;
-    QObject::connect(aDB(), &ADataBase::sqlSuccessful,
+    QObject::connect(aDB(), &ADataBase::deleteSuccessful,
                      this, &LogbookWidget::onDeletedSuccessfully);
     QObject::connect(aDB(), &ADataBase::sqlError,
                      this, &LogbookWidget::onDeleteUnsuccessful);
@@ -174,7 +174,7 @@ void LogbookWidget::flightsTableView_selectionChanged()//
 
 void LogbookWidget::on_newFlightButton_clicked()
 {
-    auto nf = new NewFlightDialog(this, Db::createNew);
+    auto nf = new NewFlightDialog(this);
     nf->setAttribute(Qt::WA_DeleteOnClose);
     nf->exec();
     displayModel->select();
@@ -183,7 +183,7 @@ void LogbookWidget::on_newFlightButton_clicked()
 void LogbookWidget::on_editFlightButton_clicked()
 {
     if(selectedFlights.length() == 1){
-        auto ef = new NewFlightDialog(this,Flight(selectedFlights.first()), Db::editExisting);
+        auto ef = new NewFlightDialog(selectedFlights.first(), this);
         ef->setAttribute(Qt::WA_DeleteOnClose);
         ef->exec();
         displayModel->select();
@@ -268,7 +268,7 @@ void LogbookWidget::on_actionDelete_Flight_triggered()
 
 void LogbookWidget::onDeletedSuccessfully()
 {
-    messageBox->setText(QString::number(selectedFlights.length()) + " flights have been deleted.");
+    messageBox->setText(QString::number(selectedFlights.length()) + " entries have been deleted.");
     messageBox->exec();
 }
 
@@ -289,11 +289,17 @@ void LogbookWidget::on_tableView_doubleClicked()
     emit ui->editFlightButton->clicked();
 }
 
-void LogbookWidget::on_flightSearchComboBox_currentIndexChanged()
+void LogbookWidget::on_flightSearchComboBox_currentIndexChanged(int)
 {
     emit ui->showAllButton->clicked();
 }
 
+void LogbookWidget::onDatabaseChanged()
+{
+    //refresh view to reflect changes the user has made via a dialog.
+    displayModel->select();
+}
+
 void LogbookWidget::on_showAllButton_clicked()
 {
     ui->flightSearchLlineEdit->setText(QString());

+ 4 - 1
src/gui/widgets/logbookwidget.h

@@ -69,7 +69,10 @@ private slots:
 
     void on_flightSearchLlineEdit_textChanged(const QString &arg1);
 
-    void on_flightSearchComboBox_currentIndexChanged();
+    void on_flightSearchComboBox_currentIndexChanged(int);
+
+public slots:
+    void onDatabaseChanged();
 
 private:
     Ui::LogbookWidget *ui;

+ 8 - 2
src/gui/widgets/pilotswidget.cpp

@@ -71,6 +71,12 @@ void PilotsWidget::on_pilotSearchLineEdit_textChanged(const QString &arg1)
     model->setFilter("\"" + ui->pilotsSearchComboBox->currentText() + "\" LIKE \"%" + arg1 + "%\" AND ID > 1");
 }
 
+void PilotsWidget::onDatabaseChanged()
+{
+    //refresh view to reflect changes the user has made via a dialog.
+    model->select();
+}
+
 void PilotsWidget::tableView_selectionChanged()//const QItemSelection &index, const QItemSelection &
 {
     if (this->findChild<NewPilotDialog*>() != nullptr) {
@@ -111,7 +117,7 @@ void PilotsWidget::tableView_headerClicked(int column)
     ASettings::write("userdata/pilSortColumn", column);
 }
 
-void PilotsWidget::on_newButton_clicked()
+void PilotsWidget::on_newPilotButton_clicked()
 {
     NewPilotDialog* np = new NewPilotDialog(this);
     QObject::connect(np,   &QDialog::accepted,
@@ -122,7 +128,7 @@ void PilotsWidget::on_newButton_clicked()
     np->exec();
 }
 
-void PilotsWidget::on_deletePushButton_clicked()
+void PilotsWidget::on_deletePilotButton_clicked()
 {
     if (selectedPilots.length() == 0) {
         auto mb = QMessageBox(this);

+ 5 - 2
src/gui/widgets/pilotswidget.h

@@ -45,9 +45,9 @@ private slots:
 
     void tableView_headerClicked(int);
 
-    void on_newButton_clicked();
+    void on_newPilotButton_clicked();
 
-    void on_deletePushButton_clicked();
+    void on_deletePilotButton_clicked();
 
     void on_deleteUnsuccessful();
 
@@ -55,6 +55,9 @@ private slots:
 
     void on_pilotSearchLineEdit_textChanged(const QString &arg1);
 
+public slots:
+    void onDatabaseChanged();
+
 private:
     Ui::PilotsWidget *ui;
 

+ 2 - 2
src/gui/widgets/pilotswidget.ui

@@ -139,14 +139,14 @@
     </layout>
    </item>
    <item row="1" column="0">
-    <widget class="QPushButton" name="newPilotPushButton">
+    <widget class="QPushButton" name="newPilotButton">
      <property name="text">
       <string>New Pilot</string>
      </property>
     </widget>
    </item>
    <item row="2" column="0">
-    <widget class="QPushButton" name="deletPilotButton">
+    <widget class="QPushButton" name="deletePilotButton">
      <property name="text">
       <string>Delete Pilot</string>
      </property>

Some files were not shown because too many files changed in this diff