Browse Source

Initial Rework of NewTailDialog

Refactored to make use of new experimental classes, simplified constructors, cleared up data flow, adjusted database to handle empty strings as NULL iso "", added structs and functions for aircraft and tails
Felix Turo 4 years ago
parent
commit
feb05cd3db

+ 1 - 1
mainwindow.cpp

@@ -132,7 +132,7 @@ void MainWindow::on_actionNewFlight_triggered()
 
 void MainWindow::on_actionNewAircraft_triggered()
 {
-    NewTailDialog nt = NewTailDialog(QString(), Db::createNew, this);
+    NewTailDialog nt = NewTailDialog(QString(), this);
     nt.exec();
 }
 

+ 5 - 0
openPilotLog.pro

@@ -29,9 +29,11 @@ SOURCES += \
     src/database/db.cpp \
     src/database/dbinfo.cpp \
     src/database/entry_deprecated.cpp \
+    src/experimental/aaircraftentry.cpp \
     src/experimental/adatabase.cpp \
     src/experimental/aentry.cpp \
     src/experimental/apilotentry.cpp \
+    src/experimental/atailentry.cpp \
     src/functions/acalc.cpp \
     src/functions/areadcsv.cpp \
     src/functions/astat.cpp \
@@ -61,11 +63,14 @@ HEADERS += \
     src/database/dbinfo.h \
     src/database/entry_deprecated.h \
     src/experimental/UserInput.h \
+    src/experimental/aaircraftentry.h \
     src/experimental/adatabase.h \
     src/experimental/aentry.h \
     src/experimental/apilotentry.h \
+    src/experimental/atailentry.h \
     src/experimental/decl.h \
     src/functions/acalc.h \
+    src/functions/adebug.h \
     src/functions/src/functions/adebug.h \
     src/functions/areadcsv.h \
     src/functions/astat.h \

+ 7 - 5
src/classes/adownload.cpp

@@ -46,13 +46,15 @@ void ADownload::download()
     QNetworkRequest request(target);
     DEB("Downloading from: " << target.toString());
 
-    //QObject::connect(manager.get(request), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
+    QObject::connect(manager.get(request), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
+}
+
+
+void ADownload::downloadProgress(qint64 received, qint64 total)
+{
+    DEB("Received " << received << " bytes of " << total);
 }
 
-/* not needed for now
- * void ADownload::downloadProgress(qint64 received, qint64 total)
- * {}
- */
 
 
 void ADownload::downloadFinished(QNetworkReply *data)

+ 1 - 1
src/classes/adownload.h

@@ -51,7 +51,7 @@ signals:
 
 public slots:
     void downloadFinished(QNetworkReply* data);
-    //void downloadProgress(qint64 received, qint64 total); //not needed for now
+    void downloadProgress(qint64 received, qint64 total);
 };
 
 #endif // ADOWNLOAD_H

+ 30 - 24
src/database/adatabasesetup.cpp

@@ -157,8 +157,6 @@ const QString createViewDefault = "CREATE VIEW viewDefault AS "
         "INNER JOIN tails on flights.acft = tails.tail_id "
         "ORDER BY date DESC ";
 
-
-
 const QString createViewEASA = "CREATE VIEW viewEASA AS "
         "SELECT "
         "flight_id, doft as 'Date', "
@@ -192,41 +190,49 @@ const QString createViewEASA = "CREATE VIEW viewEASA AS "
 
 const QString createViewTails = "CREATE VIEW viewTails AS "
         "SELECT "
-        "tail_id AS 'ID', registration AS 'Registration', "
-        "make||' '||model||'-'||variant AS 'Type', "
-        "company AS 'Company' "
-        "FROM tails";
+        "tail_id AS \"ID\", "
+        "registration AS \"Registration\", "
+        "make||\" \"||model AS \"Type\", "
+        "company AS \"Company\" "
+        "FROM tails WHERE model IS NOT NULL AND variant IS NULL "
+        "UNION "
+        "SELECT "
+        "tail_id AS \"ID\", "
+        "registration AS \"Registration\", "
+        "make||\" \"||model||\"-\"||variant AS \"Type\", "
+        "company AS \"Company\" "
+        "FROM tails WHERE variant IS NOT NULL";
 
 const QString createViewPilots = "CREATE VIEW viewPilots AS "
         "SELECT "
-        "pilot_id AS 'ID', "
-        "piclastname AS 'Last Name', "
-        "picfirstname AS 'First Name', company AS 'Company' "
+        "pilot_id AS \"ID\", "
+        "piclastname AS \"Last Name\", "
+        "picfirstname AS \"First Name\", company AS \"Company\" "
         "FROM pilots";
 
 const QString createViewQCompleter = "CREATE VIEW viewQCompleter AS "
         "SELECT airport_id, icao, iata, tail_id, registration, pilot_id, "
-        "piclastname||', '||picfirstname AS 'pilot_name', alias "
+        "piclastname||\", \"||picfirstname AS \"pilot_name\", alias "
         "FROM airports "
         "LEFT JOIN tails ON airports.airport_id = tails.tail_id "
         "LEFT JOIN pilots ON airports.airport_id = pilots.pilot_id";
 
 const QString createViewTotals = "CREATE VIEW viewTotals AS "
         "SELECT "
-        "printf('%02d',CAST(SUM(tblk) AS INT)/60)||':'||printf('%02d',CAST(SUM(tblk) AS INT)%60) AS 'TOTAL', "
-        "printf('%02d',CAST(SUM(tSPSE) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSPSE) AS INT)%60) AS 'SP SE', "
-        "printf('%02d',CAST(SUM(tSPME) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSPME) AS INT)%60) AS 'SP ME', "
-        "printf('%02d',CAST(SUM(tNIGHT) AS INT)/60)||':'||printf('%02d',CAST(SUM(tNIGHT) AS INT)%60) AS 'NIGHT', "
-        "printf('%02d',CAST(SUM(tIFR) AS INT)/60)||':'||printf('%02d',CAST(SUM(tIFR) AS INT)%60) AS 'IFR', "
-        "printf('%02d',CAST(SUM(tPIC) AS INT)/60)||':'||printf('%02d',CAST(SUM(tPIC) AS INT)%60) AS 'PIC', "
-        "printf('%02d',CAST(SUM(tPICUS) AS INT)/60)||':'||printf('%02d',CAST(SUM(tPICUS) AS INT)%60) AS 'PICUS', "
-        "printf('%02d',CAST(SUM(tSIC) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSIC) AS INT)%60) AS 'SIC', "
-        "printf('%02d',CAST(SUM(tDual) AS INT)/60)||':'||printf('%02d',CAST(SUM(tDual) AS INT)%60) AS 'DUAL', "
-        "printf('%02d',CAST(SUM(tFI) AS INT)/60)||':'||printf('%02d',CAST(SUM(tFI) AS INT)%60) AS 'INSTRUCTOR', "
-        "printf('%02d',CAST(SUM(tSIM) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSIM) AS INT)%60) AS 'SIMULATOR', "
-        "printf('%02d',CAST(SUM(tMP) AS INT)/60)||':'||printf('%02d',CAST(SUM(tMP) AS INT)%60) AS 'MultPilot', "
-        "CAST(SUM(toDay) AS INT) AS 'TO Day', CAST(SUM(toNight) AS INT) AS 'TO Night', "
-        "CAST(SUM(ldgDay) AS INT) AS 'LDG Day', CAST(SUM(ldgNight) AS INT) AS 'LDG Night' "
+        "printf(\"%02d\",CAST(SUM(tblk) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tblk) AS INT)%60) AS \"TOTAL\", "
+        "printf(\"%02d\",CAST(SUM(tSPSE) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tSPSE) AS INT)%60) AS \"SP SE\", "
+        "printf(\"%02d\",CAST(SUM(tSPME) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tSPME) AS INT)%60) AS \"SP ME\", "
+        "printf(\"%02d\",CAST(SUM(tNIGHT) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tNIGHT) AS INT)%60) AS \"NIGHT\", "
+        "printf(\"%02d\",CAST(SUM(tIFR) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tIFR) AS INT)%60) AS \"IFR\", "
+        "printf(\"%02d\",CAST(SUM(tPIC) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tPIC) AS INT)%60) AS \"PIC\", "
+        "printf(\"%02d\",CAST(SUM(tPICUS) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tPICUS) AS INT)%60) AS \"PICUS\", "
+        "printf(\"%02d\",CAST(SUM(tSIC) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tSIC) AS INT)%60) AS \"SIC\", "
+        "printf(\"%02d\",CAST(SUM(tDual) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tDual) AS INT)%60) AS \"DUAL\", "
+        "printf(\"%02d\",CAST(SUM(tFI) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tFI) AS INT)%60) AS \"INSTRUCTOR\", "
+        "printf(\"%02d\",CAST(SUM(tSIM) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tSIM) AS INT)%60) AS \"SIMULATOR\", "
+        "printf(\"%02d\",CAST(SUM(tMP) AS INT)/60)||\":\"||printf(\"%02d\",CAST(SUM(tMP) AS INT)%60) AS \"MultPilot\", "
+        "CAST(SUM(toDay) AS INT) AS \"TO Day\", CAST(SUM(toNight) AS INT) AS \"TO Night\", "
+        "CAST(SUM(ldgDay) AS INT) AS \"LDG Day\", CAST(SUM(ldgNight) AS INT) AS \"LDG Night\" "
         "FROM flights";
 const QStringList tables = {
     createTablePilots,

+ 34 - 0
src/experimental/aaircraftentry.cpp

@@ -0,0 +1,34 @@
+/*
+ *openTail Log - A FOSS Tail Logbook Application
+ *Copyright (C) 2020  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 <https://www.gnu.org/licenses/>.
+ */
+#include "aaircraftentry.h"
+
+namespace experimental {
+
+AAircraftEntry::AAircraftEntry()
+    : AEntry::AEntry(DEFAULT_AIRCRAFT_POSITION)
+{}
+
+AAircraftEntry::AAircraftEntry(int row_id)
+    : AEntry::AEntry(DataPosition("aircraft", row_id))
+{}
+
+AAircraftEntry::AAircraftEntry(TableData table_data)
+    : AEntry::AEntry(DEFAULT_AIRCRAFT_POSITION, table_data)
+{}
+
+} // namespace experimental

+ 20 - 0
src/experimental/aaircraftentry.h

@@ -0,0 +1,20 @@
+#ifndef AAIRCRAFTENTRY_H
+#define AAIRCRAFTENTRY_H
+
+#include "src/experimental/aentry.h"
+#include "src/experimental/decl.h"
+
+namespace experimental {
+
+struct AAircraftEntry : public AEntry {
+public:
+    AAircraftEntry();
+    AAircraftEntry(const AAircraftEntry& te) = default;
+    AAircraftEntry& operator=(const AAircraftEntry& te) = default;
+    AAircraftEntry(int row_id);
+    AAircraftEntry(TableData table_data);
+};
+
+} // namespace experimental
+
+#endif // AAIRCRAFTENTRY_H

+ 81 - 8
src/experimental/adatabase.cpp

@@ -1,3 +1,20 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  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 <https://www.gnu.org/licenses/>.
+ */
 #include "adatabase.h"
 
 namespace experimental {
@@ -118,10 +135,10 @@ bool ADataBase::update(AEntry updated_entry)
     auto data = updated_entry.getData();
     QString statement = "UPDATE " + updated_entry.getPosition().tableName + " SET ";
     for (auto i = data.constBegin(); i != data.constEnd(); ++i) {
-        if (i.key() != QString()) {
-            statement += i.key() + QLatin1String("=\"") + i.value() + QLatin1String("\", ");
+        if (i.value() == QString()) {
+            statement += i.key() + QLatin1String("=NULL") + QLatin1String(", ");
         } else {
-            DEB(i.key() << "is empty key. skipping.");
+            statement += i.key() + QLatin1String("=\"") + i.value() + QLatin1String("\", ");
         }
     }
     statement.chop(2); // Remove last comma
@@ -156,10 +173,15 @@ bool ADataBase::insert(AEntry new_entry)
     statement.chop(2);
     statement += QLatin1String(") VALUES (");
     for (i = data.begin(); i != data.end(); ++i) {
-        statement += QLatin1String("\"") + i.value() + QLatin1String("\", ");
+        if (i.value() == "") {
+            statement += QLatin1String("NULL, ");
+        } else {
+            statement += QLatin1String("\"") + i.value() + QLatin1String("\", ");
+        }
     }
     statement.chop(2);
     statement += QLatin1String(")");
+    DEB(statement);
 
     QSqlQuery query(statement);
     //check result.
@@ -233,12 +255,26 @@ AEntry ADataBase::getEntry(DataPosition data_position)
 
 APilotEntry ADataBase::getPilotEntry(RowId row_id)
 {
-    APilotEntry pilotEntry(row_id);
-    pilotEntry.setData(getEntryData(pilotEntry.getPosition()));
-    return pilotEntry;
+    APilotEntry pilot_entry(row_id);
+    pilot_entry.setData(getEntryData(pilot_entry.getPosition()));
+    return pilot_entry;
 }
 
-QStringList ADataBase::getCompletionList(ADataBase::CompleterTarget target)
+ATailEntry ADataBase::getTailEntry(RowId row_id)
+{
+    ATailEntry tail_entry(row_id);
+    tail_entry.setData(getEntryData(tail_entry.getPosition()));
+    return tail_entry;
+}
+
+AAircraftEntry ADataBase::getAircraftEntry(RowId row_id)
+{
+    AAircraftEntry aircraft_entry(row_id);
+    aircraft_entry.setData(getEntryData(aircraft_entry.getPosition()));
+    return aircraft_entry;
+}
+
+const QStringList ADataBase::getCompletionList(ADataBase::CompleterTarget target)
 {
     QString statement;
 
@@ -278,6 +314,43 @@ QStringList ADataBase::getCompletionList(ADataBase::CompleterTarget target)
     return completer_list;
 }
 
+const QMap<QString, int> ADataBase::getIdMap(ADataBase::CompleterTarget target)
+{
+    QString statement;
+
+    switch (target) {
+    case 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;
+    default:
+        DEB("Not a valid completer target for this function.");
+        return QMap<QString, int>();
+    }
+
+    auto id_map = QMap<QString, int>();
+    auto query = QSqlQuery(statement);
+    if (!query.first()) {
+        DEB("No result found. Check Query and Error.");
+        DEB("Query: " << statement);
+        DEB("Error: " << query.lastError().text());
+        emit sqlError(query.lastError(), statement);
+        return QMap<QString, int>();
+    } else {
+        query.first();
+        query.previous();
+        QVector<QString> query_result;
+        while (query.next()) {
+            id_map.insert(query.value(1).toString(), query.value(0).toInt());
+        }
+        return id_map;
+    }
+}
+
 QVector<QString> ADataBase::customQuery(QString statement, int return_values)
 {
     QSqlQuery query(statement);

+ 47 - 3
src/experimental/adatabase.h

@@ -1,3 +1,20 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  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 <https://www.gnu.org/licenses/>.
+ */
 #ifndef __DB_H__
 #define __DB_H__
 
@@ -12,6 +29,8 @@
 
 #include "aentry.h"
 #include "apilotentry.h"
+#include "atailentry.h"
+#include "aaircraftentry.h"
 
 namespace experimental {
 
@@ -106,15 +125,40 @@ public:
      * with only the RowId required as input.
      */
     APilotEntry getPilotEntry(RowId row_id);
-    // [G] TODO: Ensure PilotDialog works great and slowly move to
-    // other dialogs
+
+    /*!
+     * \brief retreives a TailEntry from the database.
+     *
+     * This function is a wrapper for DataBase::getEntry(DataPosition),
+     * where the table is already set and which returns a TailEntry
+     * instead of an Entry. It allows for easy access to a tail entry
+     * with only the RowId required as input.
+     */
+    ATailEntry getTailEntry(RowId row_id);
+
+    /*!
+     * \brief retreives a TailEntry from the database.
+     *
+     * This function is a wrapper for DataBase::getEntry(DataPosition),
+     * where the table is already set and which returns an AAircraftEntry
+     * instead of an AEntry. It allows for easy access to an aircraft entry
+     * with only the RowId required as input.
+     */
+    AAircraftEntry getAircraftEntry(RowId row_id);
 
     /*!
      * \brief getCompletionList returns a QStringList of values for a
      * QCompleter based on database values
      * \return
      */
-    QStringList getCompletionList(CompleterTarget);
+    const QStringList getCompletionList(CompleterTarget);
+
+    /*!
+     * \brief getIdMap returns a map 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);
 signals:
     void sqlSuccessful();
 

+ 17 - 0
src/experimental/aentry.cpp

@@ -1,3 +1,20 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  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 <https://www.gnu.org/licenses/>.
+ */
 #include "aentry.h"
 
 namespace experimental {

+ 17 - 0
src/experimental/aentry.h

@@ -1,3 +1,20 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  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 <https://www.gnu.org/licenses/>.
+ */
 #ifndef ENTRY_H
 #define ENTRY_H
 

+ 17 - 0
src/experimental/apilotentry.cpp

@@ -1,3 +1,20 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  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 <https://www.gnu.org/licenses/>.
+ */
 #include "apilotentry.h"
 
 namespace experimental {

+ 17 - 0
src/experimental/apilotentry.h

@@ -1,3 +1,20 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  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 <https://www.gnu.org/licenses/>.
+ */
 #ifndef APILOTENTRY_H
 #define APILOTENTRY_H
 

+ 34 - 0
src/experimental/atailentry.cpp

@@ -0,0 +1,34 @@
+/*
+ *openTail Log - A FOSS Tail Logbook Application
+ *Copyright (C) 2020  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 <https://www.gnu.org/licenses/>.
+ */
+#include "atailentry.h"
+
+namespace experimental {
+
+ATailEntry::ATailEntry()
+    : AEntry::AEntry(DEFAULT_TAIL_POSITION)
+{}
+
+ATailEntry::ATailEntry(int row_id)
+    : AEntry::AEntry(DataPosition("tails", row_id))
+{}
+
+ATailEntry::ATailEntry(TableData table_data)
+    : AEntry::AEntry(DEFAULT_TAIL_POSITION, table_data)
+{}
+
+} // namespace experimental

+ 37 - 0
src/experimental/atailentry.h

@@ -0,0 +1,37 @@
+/*
+ *openTail Log - A FOSS Tail Logbook Application
+ *Copyright (C) 2020  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 <https://www.gnu.org/licenses/>.
+ */
+#ifndef ATAILENTRY_H
+#define ATAILENTRY_H
+
+#include "src/experimental/aentry.h"
+#include "src/experimental/decl.h"
+
+namespace experimental {
+
+struct ATailEntry : public AEntry {
+public:
+    ATailEntry();
+    ATailEntry(const ATailEntry& te) = default;
+    ATailEntry& operator=(const ATailEntry& te) = default;
+    ATailEntry(int row_id);
+    ATailEntry(TableData table_data);
+};
+
+} // namespace experimental
+
+#endif // ATAILENTRY_H

+ 2 - 0
src/experimental/decl.h

@@ -38,6 +38,8 @@ struct DataPosition : QPair<TableName, RowId> {
     DataPosition& operator=(const DataPosition& other) = default;
 };
 auto const DEFAULT_PILOT_POSITION = DataPosition("pilots", 0);
+auto const DEFAULT_TAIL_POSITION = DataPosition("tails", 0);
+auto const DEFAULT_AIRCRAFT_POSITION = DataPosition("aircraft", 0);
 
 }
 

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

@@ -483,7 +483,7 @@ void NewFlightDialog::addNewAircraftMessageBox(QLineEdit *parent)
     {
         DEB("Add new aircraft selected");
         // create and open new aircraft dialog
-        auto na = NewTailDialog(ui->acftLineEdit->text(), Db::createNew, this);
+        auto na = NewTailDialog(ui->acftLineEdit->text(), this);
         na.exec();
         QString statement = "SELECT MAX(tail_id)  FROM tails";
         QString id = Db::customQuery(statement,1).first();

+ 0 - 2
src/gui/dialogues/newpilotdialog.h

@@ -45,8 +45,6 @@ public:
 private slots:
     void on_buttonBox_accepted();
 
-//public slots:
-
     void onCommitSuccessful();
 
     void onCommitUnsuccessful(const QSqlError &sqlError, const QString &);

+ 55 - 1
src/gui/dialogues/newtail.ui

@@ -16,6 +16,12 @@
   <layout class="QGridLayout" name="gridLayout">
    <item row="7" column="0">
     <widget class="QLabel" name="operationLabel">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="text">
       <string>Operation</string>
      </property>
@@ -43,6 +49,12 @@
    </item>
    <item row="6" column="0">
     <widget class="QLabel" name="variantLabel">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="text">
       <string>Variant</string>
      </property>
@@ -82,6 +94,12 @@
    </item>
    <item row="10" column="0">
     <widget class="QLabel" name="weightLabel">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="text">
       <string>Weight Class</string>
      </property>
@@ -118,6 +136,12 @@
    </item>
    <item row="2" column="0">
     <widget class="QLabel" name="registrationLabel">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="text">
       <string>Registration</string>
      </property>
@@ -125,6 +149,12 @@
    </item>
    <item row="5" column="0">
     <widget class="QLabel" name="modelLabel">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="text">
       <string>Model</string>
      </property>
@@ -132,6 +162,12 @@
    </item>
    <item row="3" column="0">
     <widget class="QLabel" name="companyLabel">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="text">
       <string>Company</string>
      </property>
@@ -157,7 +193,7 @@
    <item row="0" column="1">
     <widget class="QLineEdit" name="searchLineEdit">
      <property name="maxLength">
-      <number>20</number>
+      <number>40</number>
      </property>
      <property name="placeholderText">
       <string>start typing to search for aircraft types</string>
@@ -176,6 +212,12 @@
    </item>
    <item row="0" column="0">
     <widget class="QLabel" name="searchLabel">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="font">
       <font>
        <weight>75</weight>
@@ -224,6 +266,12 @@
    </item>
    <item row="8" column="0">
     <widget class="QLabel" name="powerPlantLabel">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="text">
       <string>Power Plant</string>
      </property>
@@ -231,6 +279,12 @@
    </item>
    <item row="4" column="0">
     <widget class="QLabel" name="makeLabel">
+     <property name="minimumSize">
+      <size>
+       <width>160</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="text">
       <string>Make</string>
      </property>

+ 138 - 119
src/gui/dialogues/newtaildialog.cpp

@@ -30,39 +30,40 @@ static const auto VARIANT_VALID = QPair<QString, QRegularExpression> {
 static const auto LINE_EDIT_VALIDATORS = QVector({REG_VALID, MAKE_VALID, MODEL_VALID, VARIANT_VALID});
 
 
-//Dialog to be used to create a new tail
-NewTailDialog::NewTailDialog(QString newreg, Db::editRole edRole, QWidget *parent) :
+NewTailDialog::NewTailDialog(QString new_registration, QWidget *parent) :
     QDialog(parent),
     ui(new Ui::NewTail)
 {
-    DEB("new NewTailDialog\n");
+    DEB("new NewTailDialog (experimental)");
     ui->setupUi(this);
 
-    role = edRole;
+    connectSignals();
     setupCompleter();
     setupValidators();
 
-    ui->registrationLineEdit->setText(newreg);
+    ui->registrationLineEdit->setText(new_registration);
     ui->searchLineEdit->setStyleSheet("border: 1px solid blue");
     ui->searchLineEdit->setFocus();
+
+    entry = experimental::ATailEntry();
 }
 
-//Dialog to be used to edit an existing tail
-NewTailDialog::NewTailDialog(Aircraft dbentry, Db::editRole edRole, QWidget *parent) :
+NewTailDialog::NewTailDialog(int row_id, QWidget *parent) :
     QDialog(parent),
     ui(new Ui::NewTail)
 {
-    DEB("new NewTailDialog\n");
-    oldEntry = dbentry;
-    role = edRole;
+    using namespace experimental;
+    DEB("New experimental New Pilot Dialog (edit existing)");
     ui->setupUi(this);
 
     ui->searchLabel->hide();
     ui->searchLineEdit->hide();
     ui->line->hide();
 
+    connectSignals();
     setupValidators();
-    formFiller(oldEntry);
+    entry = aDB()->getTailEntry(row_id);
+    fillForm(entry);
 }
 
 NewTailDialog::~NewTailDialog()
@@ -73,89 +74,97 @@ NewTailDialog::~NewTailDialog()
 /// Functions
 
 /*!
- * \brief NewTail::setupCompleter creates a QMap<aircaft_id,searchstring> for auto completion,
- * obtains a QStringList for QCompleter and sets up search line edit accordingly
+ * \brief NewTail::setupCompleter obtains a QMap<QString searchstring, int aircaft_id> for auto completion
+ * and obtains a QStringList for QCompleter. This function then sets up the search line edit where
+ * the user can select a template from the aircraft database to pre-fill the form with the details
+ * for the selected type.
  */
 void NewTailDialog::setupCompleter()
 {
-    auto query = QLatin1String("SELECT make||' '||model||'-'||variant, aircraft_id FROM aircraft");
-    auto vector = Db::customQuery(query, 2);
-    QMap<QString, int> map;
-    for (int i = 0; i < vector.length() - 2 ; i += 2) {
-        if (vector[i] != QLatin1String("")) {
-            map.insert(vector[i], vector[i + 1].toInt());
-        }
-    }
-    //creating QStringlist for QCompleter. This list is identical to a list of map<key>,
-    //but creating it like this is faster.
+    using namespace experimental;
+    idMap = aDB()->getIdMap(ADataBase::aircraft);
+    aircraftList = aDB()->getCompletionList(experimental::ADataBase::aircraft);
 
-
-    auto aircraftlist = experimental::aDB()->getCompletionList(experimental::ADataBase::aircraft);
-    idMap = map;
-    QCompleter *completer = new QCompleter(aircraftlist, ui->searchLineEdit);
+    QCompleter *completer = new QCompleter(aircraftList, ui->searchLineEdit);
     completer->setCaseSensitivity(Qt::CaseInsensitive);
     completer->setCompletionMode(QCompleter::PopupCompletion);
     completer->setFilterMode(Qt::MatchContains);
     ui->searchLineEdit->setCompleter(completer);
+
+    QObject::connect(completer, static_cast<void(QCompleter::*)(const QString &)>(&QCompleter::activated),
+                     this, &NewTailDialog::onSearchCompleterActivated);
+    QObject::connect(completer, static_cast<void(QCompleter::*)(const QString &)>(&QCompleter::highlighted),
+                     this, &NewTailDialog::onSearchCompleterActivated);
+
+
 }
 
 void NewTailDialog::setupValidators()
 {
     for(const auto& pair : LINE_EDIT_VALIDATORS){
-        auto line_edit = parent()->findChild<QLineEdit*>(pair.first);
-        auto validator = new QRegularExpressionValidator(pair.second,line_edit);
+        auto line_edit = this->findChild<QLineEdit*>(pair.first);
+        auto validator = new QRegularExpressionValidator(pair.second, line_edit);
         line_edit->setValidator(validator);
     }
 }
+
+void NewTailDialog::connectSignals()
+{
+    using namespace experimental;
+    QObject::connect(aDB(), &ADataBase::sqlSuccessful,
+                     this,  &NewTailDialog::onCommitSuccessful);
+    QObject::connect(aDB(), &ADataBase::sqlError,
+                     this,  &NewTailDialog::onCommitUnsuccessful);
+}
+
 /*!
- * \brief NewTail::formFiller populates the Dialog with the
- * information contained in an aircraft object.
- * \param db - entry retreived from database
+ * \brief NewTailDialog::fillForm populates the Dialog with the
+ * information contained in an entry object. This can be either
+ * a template (AAircraft, used when creating a new entry) or
+ * a tail (ATail, used when editing an existing entry)
+ * \param entry
  */
-void NewTailDialog::formFiller(Entry_deprecated entry)
+void NewTailDialog::fillForm(experimental::AEntry entry)
 {
-    DEB("Filling Form for a/c" << entry);
+    DEB("Filling Form for (experimental) a/c" << entry.getPosition());
     //fill Line Edits
-    auto line_edits = parent()->findChildren<QLineEdit *>();
+    auto line_edits = this->findChildren<QLineEdit *>();
     for (const auto &le : line_edits) {
-        QString name = le->objectName();
-        name.chop(8);//remove "LineEdit"
-        QString value = entry.data.value(name);
-        if (!value.isEmpty()) {
-            le->setText(value);
-        };
+        QString name = le->objectName().remove("LineEdit");
+        QString value = entry.getData().value(name);
+        le->setText(value);
     }
     //select comboboxes
-    QVector<QString> operation = {entry.data.value("singleengine"), entry.data.value("multiengine")};
-    QVector<QString> ppNumber =  {entry.data.value("singlepilot"), entry.data.value("multipilot")};
-    QVector<QString> ppType =    {entry.data.value("unpowered"), entry.data.value("piston"),
-                                  entry.data.value("turboprop"), entry.data.value("jet")
+    QVector<QString> operation = {entry.getData().value("singleengine"), entry.getData().value("multiengine")};
+    QVector<QString> ppNumber =  {entry.getData().value("singlepilot"), entry.getData().value("multipilot")};
+    QVector<QString> ppType =    {entry.getData().value("unpowered"), entry.getData().value("piston"),
+                                  entry.getData().value("turboprop"), entry.getData().value("jet")
                                  };
-    QVector<QString> weight =    {entry.data.value("light"), entry.data.value("medium"),
-                                  entry.data.value("heavy"), entry.data.value("super")
+    QVector<QString> weight =    {entry.getData().value("light"), entry.getData().value("medium"),
+                                  entry.getData().value("heavy"), entry.getData().value("super")
                                  };
 
-
     ui->operationComboBox->setCurrentIndex(operation.indexOf("1") + 1);
     ui->ppNumberComboBox->setCurrentIndex(ppNumber.indexOf("1") + 1);
     ui->ppTypeComboBox->setCurrentIndex(ppType.indexOf("1") + 1);
     ui->weightComboBox->setCurrentIndex(weight.indexOf("1") + 1);
 }
+
 /*!
  * \brief NewTail::verify A simple check for empty recommended fields in the form
  * \return true if all reconmmended fields are populated
  */
 bool NewTailDialog::verify()
 {
-    auto recommended_line_edits = parent()->findChildren<QLineEdit *>("registrationLineEdit");
-    recommended_line_edits.append(parent()->findChild<QLineEdit *>("makeLineEdit"));
-    recommended_line_edits.append(parent()->findChild<QLineEdit *>("modelLineEdit"));
+    auto recommended_line_edits = this->findChildren<QLineEdit *>("registrationLineEdit");
+    recommended_line_edits.append(this->findChild<QLineEdit *>("makeLineEdit"));
+    recommended_line_edits.append(this->findChild<QLineEdit *>("modelLineEdit"));
 
-    auto recommended_combo_boxes = parent()->findChildren<QComboBox *>("operationComboBox");
-    recommended_combo_boxes.append(parent()->findChild<QComboBox *>("ppNumberComboBox"));
-    recommended_combo_boxes.append(parent()->findChild<QComboBox *>("ppTypeComboBox"));
+    auto recommended_combo_boxes = this->findChildren<QComboBox *>("operationComboBox");
+    recommended_combo_boxes.append(this->findChild<QComboBox *>("ppNumberComboBox"));
+    recommended_combo_boxes.append(this->findChild<QComboBox *>("ppTypeComboBox"));
 
-    for (const auto le : recommended_line_edits) {
+    for (const auto &le : recommended_line_edits) {
         if (le->text() != "") {
             DEB("Good: " << le);
             recommended_line_edits.removeOne(le);
@@ -165,7 +174,7 @@ bool NewTailDialog::verify()
             DEB("Not Good: " << le);
         }
     }
-    for (const auto cb : recommended_combo_boxes) {
+    for (const auto &cb : recommended_combo_boxes) {
         if (cb->currentIndex() != 0) {
 
             recommended_combo_boxes.removeOne(cb);
@@ -187,19 +196,18 @@ bool NewTailDialog::verify()
  * or updates a database entry and commits or updates the database
  * \param edRole editExisting or createNew
  */
-void NewTailDialog::submitForm(Db::editRole edRole)
+void NewTailDialog::submitForm()
 {
     DEB("Creating Database Object...");
-    QMap<QString, QString> newData;
+    using namespace experimental;
+    TableData new_data;
     //retreive Line Edits
-    auto line_edits = parent()->findChildren<QLineEdit *>();
+    auto line_edits = this->findChildren<QLineEdit *>();
+    line_edits.removeOne(this->findChild<QLineEdit *>("searchLineEdit"));
 
     for (const auto &le : line_edits) {
-        QString name = le->objectName();
-        name.chop(8);//remove "LineEdit"
-        if (!le->text().isEmpty()) {
-            newData.insert(name, le->text());
-        }
+        QString name = le->objectName().remove("LineEdit");
+        new_data.insert(name, le->text());
     }
     //prepare comboboxes
     QVector<QString> operation = {"singlepilot", "multipilot"};
@@ -212,49 +220,26 @@ void NewTailDialog::submitForm(Db::editRole edRole)
                                  };
 
     if (ui->operationComboBox->currentIndex() != 0) {
-        newData.insert(operation[ui->operationComboBox->currentIndex() - 1], QLatin1String("1"));
+        new_data.insert(operation[ui->operationComboBox->currentIndex() - 1], QLatin1String("1"));
     }
     if (ui->ppNumberComboBox->currentIndex() != 0) {
-        newData.insert(ppNumber[ui->ppNumberComboBox->currentIndex() - 1], QLatin1String("1"));
+        new_data.insert(ppNumber[ui->ppNumberComboBox->currentIndex() - 1], QLatin1String("1"));
     }
     if (ui->ppTypeComboBox->currentIndex() != 0) {
-        newData.insert(ppType[ui->ppTypeComboBox->currentIndex() - 1], QLatin1String("1"));
+        new_data.insert(ppType[ui->ppTypeComboBox->currentIndex() - 1], QLatin1String("1"));
     }
     if (ui->weightComboBox->currentIndex() != 0) {
-        newData.insert(weight[ui->weightComboBox->currentIndex() - 1], QLatin1String("1"));
+        new_data.insert(weight[ui->weightComboBox->currentIndex() - 1], QLatin1String("1"));
     }
+
     //create db object
-    switch (edRole) {
-    case Db::createNew: {
-        auto newEntry = Aircraft(newData);;
-        newEntry.commit();
-        break;
-    }
-    case Db::editExisting:
-        oldEntry.setData(newData);
-        oldEntry.commit();
-        ACalc::updateAutoTimes(oldEntry.position.second);
-        break;
-    }
+
+    entry.setData(new_data);
+    aDB()->commit(entry);
 }
 
 /// Slots
 
-void NewTailDialog::on_searchLineEdit_textChanged(const QString &arg1)
-{
-    if (aircraftlist.contains(
-                arg1)) { //equivalent to editing finished for this purpose. todo: consider connecing qcompleter activated signal with editing finished slot.
-
-        DEB("Template Selected. aircraft_id is: " << idMap.value(arg1));
-        //call autofiller for dialog
-        formFiller(Entry_deprecated("aircraft",idMap.value(arg1)));
-        ui->searchLineEdit->setStyleSheet("border: 1px solid green");
-    } else {
-        //for example, editing finished without selecting a result from Qcompleter
-        ui->searchLineEdit->setStyleSheet("border: 1px solid orange");
-    }
-}
-
 void NewTailDialog::on_operationComboBox_currentIndexChanged(int index)
 {
     if (index != 0) {
@@ -290,37 +275,71 @@ void NewTailDialog::on_buttonBox_accepted()
         auto nope = QMessageBox(this);
         nope.setText("Registration cannot be empty.");
         nope.exec();
-    } else {
-        if (verify()) {
-            DEB("Form verified");
-            submitForm(role);
-            accept();
+        return;
+    }
+
+    if (!verify()) {
+        if (!ASettings::read("userdata/acAllowIncomplete").toInt()) {
+            auto nope = QMessageBox(this);
+            nope.setIcon(QMessageBox::Warning);
+            nope.setText("Some or all recommended fields are empty.\nPlease go back and "
+                         "complete the form.\n\nYou can allow logging incomplete tail entries on the settings page.");
+            nope.exec();
+            return;
         } else {
-            if (!ASettings::read("userdata/acAllowIncomplete").toInt()) {
-                auto nope = QMessageBox(this);
-                nope.setText("Some or all fields are empty.\nPlease go back and "
-                              "complete the form.\n\nYou can allow logging incomplete entries on the settings page.");
-                nope.exec();
-            } else {
-                QMessageBox::StandardButton reply;
-                reply = QMessageBox::question(this, "Warning",
-                                              "Some recommended fields are empty.\n\n"
-                                              "If you do not fill out the aircraft details, "
-                                              "it will be impossible to automatically determine Single/Multi Pilot Times or Single/Multi Engine Time."
-                                              "This will also impact statistics and auto-logging capabilites.\n\n"
-                                              "It is highly recommended to fill in all the details.\n\n"
-                                              "Are you sure you want to proceed?",
-                                              QMessageBox::Yes | QMessageBox::No);
-                if (reply == QMessageBox::Yes) {
-                    submitForm(role);
-                    accept();
-                }
+            QMessageBox::StandardButton reply;
+            reply = QMessageBox::question(this, "Warning",
+                                          "Some recommended fields are empty.\n\n"
+                                          "If you do not fill out the aircraft details, "
+                                          "it will be impossible to automatically determine Single/Multi Pilot Times or Single/Multi Engine Time."
+                                          "This will also impact statistics and auto-logging capabilites.\n\n"
+                                          "It is highly recommended to fill in all the details.\n\n"
+                                          "Are you sure you want to proceed?",
+                                          QMessageBox::Yes | QMessageBox::No);
+            if (reply == QMessageBox::Yes) {
+                submitForm();
             }
         }
     }
+    DEB("Form verified");
+    submitForm();
+}
+
+void NewTailDialog::onSearchCompleterActivated()
+{
+    DEB("Search completer activated!");
+    const auto &text = ui->searchLineEdit->text();
+    if (aircraftList.contains(text)) {
+
+            DEB("Template Selected. aircraft_id is: " << idMap.value(text));
+            //call autofiller for dialog
+            using namespace experimental;
+            fillForm(aDB()->getAircraftEntry(idMap.value(text)));
+            ui->searchLineEdit->setStyleSheet("border: 1px solid green");
+            ui->searchLabel->setText(text);
+        } else {
+            //for example, editing finished without selecting a result from Qcompleter
+            ui->searchLineEdit->setStyleSheet("border: 1px solid orange");
+        }
 }
 
 void NewTailDialog::on_registrationLineEdit_textChanged(const QString &arg1)
 {
     ui->registrationLineEdit->setText(arg1.toUpper());
 }
+
+void NewTailDialog::onCommitSuccessful()
+{
+    ACalc::updateAutoTimes(entry.getPosition().second); // To do: update to use new db architecture with new ATailEntry
+    accept();
+}
+
+void NewTailDialog::onCommitUnsuccessful(const QSqlError &sqlError, const QString &)
+{
+    auto mb = QMessageBox(this);
+    mb.setIcon(QMessageBox::Critical);
+    mb.setText("The following error has ocurred.\n\n"
+               + sqlError.text()
+               + "\n\nYour entry has not been saved.");
+    mb.exec();
+}

+ 29 - 23
src/gui/dialogues/newtaildialog.h

@@ -29,6 +29,8 @@
 #include "src/functions/acalc.h"
 #include "src/database/entry_deprecated.h"
 #include "src/experimental/adatabase.h"
+#include "src/experimental/atailentry.h"
+#include "src/experimental/aaircraftentry.h"
 
 namespace Ui {
 class NewTail;
@@ -45,49 +47,53 @@ class NewTailDialog : public QDialog
     Q_OBJECT
 
 public:
-    //to create new tail from scratch
-    explicit NewTailDialog(QString reg, Db::editRole edRole, QWidget *parent = nullptr);
-    //to edit existing tail
-    explicit NewTailDialog(Aircraft dbentry, Db::editRole edRole, QWidget *parent = nullptr);
+    // experimental create new tail
+    explicit NewTailDialog(QString new_registration, QWidget *parent = nullptr);
+    // experimental edit existing tail
+    explicit NewTailDialog(int row_id, QWidget *parent = nullptr);
 
     ~NewTailDialog();
-private slots:
+private:
 
-    void on_searchLineEdit_textChanged(const QString &arg1);
+    Ui::NewTail *ui;
 
-    void on_buttonBox_accepted();
+    experimental::ATailEntry entry;
 
-    void on_operationComboBox_currentIndexChanged(int index);
+    QStringList aircraftList;
 
-    void on_ppTypeComboBox_currentIndexChanged(int index);
+    QMap<QString, int> idMap;
 
-    void on_ppNumberComboBox_currentIndexChanged(int index);
+    void setupCompleter();
 
-    void on_weightComboBox_currentIndexChanged(int index);
+    void setupValidators();
 
-    void on_registrationLineEdit_textChanged(const QString &arg1);
+    void connectSignals();
 
-private:
+    void fillForm(experimental::AEntry entry);
 
-    Ui::NewTail *ui;
+    void submitForm();
 
-    Db::editRole role;
+    bool verify();
 
-    Aircraft oldEntry;
+private slots:
 
-    QStringList aircraftlist;
+    void on_operationComboBox_currentIndexChanged(int index);
 
-    QMap<QString, int> idMap;
+    void on_ppTypeComboBox_currentIndexChanged(int index);
 
-    void submitForm(Db::editRole edRole);
+    void on_ppNumberComboBox_currentIndexChanged(int index);
 
-    void setupCompleter();
+    void on_weightComboBox_currentIndexChanged(int index);
 
-    void setupValidators();
+    void on_registrationLineEdit_textChanged(const QString &arg1);
 
-    void formFiller(Entry_deprecated);
+    void on_buttonBox_accepted();
 
-    bool verify();
+    void onSearchCompleterActivated();
+
+    void onCommitSuccessful();
+
+    void onCommitUnsuccessful(const QSqlError &sqlError, const QString &);
 };
 
 #endif // NEWTAIL_H

+ 2 - 2
src/gui/widgets/aircraftwidget.cpp

@@ -126,7 +126,7 @@ void AircraftWidget::on_deleteButton_clicked()
 
 void AircraftWidget::on_newButton_clicked()
 {
-    auto nt = NewTailDialog(QString(), Db::createNew, this);
+    auto nt = NewTailDialog(QString(), this);
     connect(&nt, SIGNAL(accepted()), this, SLOT(acft_editing_finished()));
     connect(&nt, SIGNAL(rejected()), this, SLOT(acft_editing_finished()));
     nt.exec();
@@ -150,7 +150,7 @@ void AircraftWidget::tableView_selectionChanged()
         DEB("Selected Tails(s) with ID: " << selectedTails);
     }
     if(selectedTails.length() == 1) {
-        auto nt = NewTailDialog(Aircraft(selectedTails.first()), Db::editExisting, this);
+        auto nt = NewTailDialog(selectedTails.first(), this);
         connect(&nt, SIGNAL(accepted()), this, SLOT(acft_editing_finished()));
         connect(&nt, SIGNAL(rejected()), this, SLOT(acft_editing_finished()));
         ui->stackedWidget->addWidget(&nt);