Browse Source

Guards against escaping FirstRun

- FirstRun must be accepted to continue to main app
- Downloads and dir creation moved to ADataBaseSetup
- More stringliterals
Felix Turo 4 years ago
parent
commit
22ea8704be

+ 11 - 4
main.cpp

@@ -50,13 +50,20 @@ int main(int argc, char *argv[])
     ASettings::setup();
 
     aDB()->connect();
-    if (!ASettings::read("setup/setup_complete").toBool()) {
+    if (!ASettings::read(QStringLiteral("setup/setup_complete")).toBool()) {
         FirstRunDialog dialog;
-        dialog.exec();
+        if(dialog.exec() == QDialog::Accepted) {
+            qApp->quit();
+            QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
+        } else {
+            DEB "First run not accepted.";
+            return 0;
+        }
+
     }
 
     //Theming
-    switch (ASettings::read("main/theme").toInt()) {
+    switch (ASettings::read(QStringLiteral("main/theme")).toInt()) {
     case 1:{
         DEB << "main :: Loading light theme";
         QFile file(":light.qss");
@@ -78,7 +85,7 @@ int main(int argc, char *argv[])
     }
 
     //sqlite does not deal well with multiple connections, ensure only one instance is running
-    ARunGuard guard("opl_single_key");
+    ARunGuard guard(QStringLiteral("opl_single_key"));
         if ( !guard.tryToRun() ){
             DEB << "Another Instance is already running. Exiting.";
             return 0;

+ 47 - 1
src/database/adatabasesetup.cpp

@@ -19,7 +19,10 @@
 #include "src/database/adatabase.h"
 #include "src/testing/adebug.h"
 #include "src/functions/areadcsv.h"
+#include "src/astandardpaths.h"
+#include "src/classes/adownload.h"
 
+const auto TEMPLATE_URL = QStringLiteral("https://raw.githubusercontent.com/fiffty-50/openpilotlog/develop/assets/database/templates/");
 
 // Statements for creation of database tables, Revision 15
 
@@ -278,6 +281,46 @@ bool ADataBaseSetup::createDatabase()
     return true;
 }
 
+/*!
+ * \brief create template directory or verify exists
+ */
+bool ADataBaseSetup::setupTemplateDir()
+{
+    QDir dir(AStandardPaths::getPath(QStandardPaths::AppDataLocation)
+             % QStringLiteral("/templates"));
+    if (dir.exists()) {
+        return true;
+    } else {
+        if(dir.mkpath(".")) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+/*!
+ * \brief Download up-to-date database templates
+ */
+bool ADataBaseSetup::downloadTemplates()
+{
+    DEB << "Downloading templates...";
+    for (const auto& table : templateTables) {
+        QEventLoop loop;
+        ADownload* dl = new ADownload;
+        QObject::connect(dl, &ADownload::done,
+                         &loop, &QEventLoop::quit );
+        dl->setTarget(QUrl(TEMPLATE_URL % table % QStringLiteral(".csv")));
+        dl->setFileName(AStandardPaths::getPath(QStandardPaths::AppDataLocation)
+                        % QStringLiteral("/templates/")
+                        % table % QStringLiteral(".csv"));
+        dl->download();
+        loop.exec(); // event loop waits for download done signal before allowing loop to continue
+        dl->deleteLater(); // schedule dl object for deletion
+    }
+    DEB << "Downloading templates complete";
+    return true;
+}
+
 
 bool ADataBaseSetup::importDefaultData()
 {
@@ -290,7 +333,10 @@ bool ADataBaseSetup::importDefaultData()
             DEB << "Error: " << query.lastError().text();
         }
         //fill with data from csv
-        if (!commitData(aReadCsv("data/templates/" + table + ".csv"), table)) {
+        if (!commitData(aReadCsv(AStandardPaths::getPath(QStandardPaths::AppDataLocation)
+                                 % QStringLiteral("/templates/")
+                                 % table % QStringLiteral(".csv")),
+                        table)) {
             DEB << "Error importing data.";
             return false;
         }

+ 6 - 0
src/database/adatabasesetup.h

@@ -19,6 +19,8 @@
 #define DBSETUP_H
 
 #include <QCoreApplication>
+#include <QStringBuilder>
+#include <QEventLoop>
 
 /*!
  * \brief The ADataBaseSetup class is responsible for the inital setup of the database when
@@ -33,6 +35,10 @@ public:
 
     static bool createDatabase();
 
+    static bool setupTemplateDir();
+
+    static bool downloadTemplates();
+
     static bool fillTemplates();
 
     static bool importDefaultData();

+ 91 - 78
src/gui/dialogues/firstrundialog.cpp

@@ -6,7 +6,7 @@
 #include "src/classes/apilotentry.h"
 #include "src/classes/adownload.h"
 #include "src/classes/asettings.h"
-const auto TEMPLATE_URL = QStringLiteral("https://raw.githubusercontent.com/fiffty-50/openpilotlog/develop/assets/database/templates/");
+#include "src/astandardpaths.h"
 
 static inline
 void prompt_error_box(QString title, QString text, QWidget* parent = nullptr)
@@ -64,7 +64,8 @@ void FirstRunDialog::on_nextPushButton_clicked()
         if(ui->firstnameLineEdit->text().isEmpty()
            || ui->lastnameLineEdit->text().isEmpty())
         {
-            prompt_error_box(QStringLiteral("Error"), QStringLiteral("Please enter first and last name"));
+            prompt_error_box(QStringLiteral("Error"),
+                             QStringLiteral("Please enter first and last name"));
             return;
         }
         ui->previousPushButton->setEnabled(true);
@@ -81,132 +82,144 @@ void FirstRunDialog::on_nextPushButton_clicked()
 
 void FirstRunDialog::on_themeGroup_toggled(int id)
 {
-    ASettings::write("main/theme", id);
+    ASettings::write(QStringLiteral("main/theme"), id);
 }
 
 void FirstRunDialog::finish()
 {
     if(ui->lastnameLineEdit->text().isEmpty() || ui->firstnameLineEdit->text().isEmpty()){
         auto mb = QMessageBox(this);
-        mb.setText("You have to enter a valid first and last name for the logbook.");
+        mb.setText(QStringLiteral("You have to enter a valid first and last name for the logbook."));
         mb.show();
     } else {
         ASettings::write("userdata/lastname", ui->lastnameLineEdit->text());
-        ASettings::write("userdata/firstname", ui->firstnameLineEdit->text());
-        ASettings::write("userdata/employeeid", ui->employeeidLineEdit->text());
-        ASettings::write("userdata/phone", ui->phoneLineEdit->text());
-        ASettings::write("userdata/email", ui->emailLineEdit->text());
+        ASettings::write(QStringLiteral("userdata/firstname"), ui->firstnameLineEdit->text());
+        ASettings::write(QStringLiteral("userdata/employeeid"), ui->employeeidLineEdit->text());
+        ASettings::write(QStringLiteral("userdata/phone"), ui->phoneLineEdit->text());
+        ASettings::write(QStringLiteral("userdata/email"), ui->emailLineEdit->text());
 
-        ASettings::write("flightlogging/function", ui->functionComboBox->currentText());
-        ASettings::write("flightlogging/approach", ui->approachComboBox->currentText());
-        ASettings::write("flightlogging/nightlogging", ui->nightComboBox->currentIndex());
-        ASettings::write("flightlogging/logIfr", ui->rulesComboBox->currentIndex());
-        ASettings::write("flightlogging/flightnumberPrefix", ui->prefixLineEdit->text());
+        ASettings::write(QStringLiteral("flightlogging/function"), ui->functionComboBox->currentText());
+        ASettings::write(QStringLiteral("flightlogging/approach"), ui->approachComboBox->currentText());
+        ASettings::write(QStringLiteral("flightlogging/nightlogging"), ui->nightComboBox->currentIndex());
+        ASettings::write(QStringLiteral("flightlogging/logIfr"), ui->rulesComboBox->currentIndex());
+        ASettings::write(QStringLiteral("flightlogging/flightnumberPrefix"), ui->prefixLineEdit->text());
 
-        ASettings::write("flightlogging/numberTakeoffs", 1);
-        ASettings::write("flightlogging/numberLandings", 1);
-        ASettings::write("flightlogging/popupCalendar", true);
-        ASettings::write("flightlogging/pilotFlying", true);
+        ASettings::write(QStringLiteral("flightlogging/numberTakeoffs"), 1);
+        ASettings::write(QStringLiteral("flightlogging/numberLandings"), 1);
+        ASettings::write(QStringLiteral("flightlogging/popupCalendar"), true);
+        ASettings::write(QStringLiteral("flightlogging/pilotFlying"), true);
 
 
         QMap<QString, QVariant> data;
         switch (ui->aliasComboBox->currentIndex()) {
         case 0:
-            ASettings::write("userdata/displayselfas", ui->aliasComboBox->currentIndex());
+            ASettings::write(QStringLiteral("userdata/displayselfas"), ui->aliasComboBox->currentIndex());
             break;
         case 1:
-            ASettings::write("userdata/displayselfas", ui->aliasComboBox->currentIndex());
+            ASettings::write(QStringLiteral("userdata/displayselfas"), ui->aliasComboBox->currentIndex());
             break;
         case 2:
-            ASettings::write("userdata/displayselfas", ui->aliasComboBox->currentIndex());
+            ASettings::write(QStringLiteral("userdata/displayselfas"), ui->aliasComboBox->currentIndex());
             break;
         default:
             break;
         }
-        data.insert("lastname", ui->lastnameLineEdit->text());
-        data.insert("firstname", ui->firstnameLineEdit->text());
-        data.insert("alias", "self");
-        data.insert("employeeid", ui->employeeidLineEdit->text());
-        data.insert("phone", ui->phoneLineEdit->text());
-        data.insert("email", ui->emailLineEdit->text());
-
-        if (!finishSetup()) {
+        data.insert(QStringLiteral("lastname"), ui->lastnameLineEdit->text());
+        data.insert(QStringLiteral("firstname"), ui->firstnameLineEdit->text());
+        data.insert(QStringLiteral("alias"), QStringLiteral("self"));
+        data.insert(QStringLiteral("employeeid"), ui->employeeidLineEdit->text());
+        data.insert(QStringLiteral("phone"), ui->phoneLineEdit->text());
+        data.insert(QStringLiteral("email"), ui->emailLineEdit->text());
+
+        if (!setupDatabase()) {
             QMessageBox message_box(this);
-            message_box.setText("Errors have ocurred creating the database. Without a working database The application will not be usable.");
+            message_box.setText(QStringLiteral("Errors have ocurred creating the database. "
+                                               "Without a working database The application will "
+                                               "not be usable."));
         }
-        ASettings::write("setup/setup_complete", true);
+        ASettings::write(QStringLiteral("setup/setup_complete"), true);
         aDB()->disconnect(); // reset db connection to refresh layout after initial setup.
         aDB()->connect();
         auto pilot = APilotEntry(1);
         pilot.setData(data);
         if (aDB()->commit(pilot)) {
-            qApp->quit();
-            QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
+            QDialog::accept();
         } else {
             QMessageBox message_box(this);
-            message_box.setText("Errors have ocurred creating the database. Without a working database The application will not be usable.");
+            message_box.setText(QStringLiteral("Errors have ocurred creating the database. "
+                                               "Without a working database The application will "
+                                               "not be usable."));
         }
-
     }
 }
 
-bool FirstRunDialog::finishSetup()
+bool FirstRunDialog::setupDatabase()
 {
-
     //check if template dir exists and create if needed.
-    QDir dir("data/templates");
-    DEB << dir.path();
-    if (!dir.exists())
-        dir.mkpath(".");
 
     QMessageBox confirm;
     confirm.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
     confirm.setDefaultButton(QMessageBox::No);
     confirm.setIcon(QMessageBox::Question);
-    confirm.setWindowTitle("Create Database");
-    confirm.setText("We are now going to create the database. Would you like to download the latest database information?\n(Recommended, Internet connection required)\n");
+    confirm.setWindowTitle(QStringLiteral("Create Database"));
+    confirm.setText(QStringLiteral("We are now going to create the database. "
+                                   "Would you like to download the latest database information?\n"
+                                   "(Recommended, Internet connection required)\n"));
     int reply = confirm.exec();
-    if (reply == QMessageBox::Yes) {
-        // download latest csv
-        QStringList templateTables = {"aircraft", "airports", "changelog"};
-        QString linkStub = TEMPLATE_URL;
-        for (const auto& table : templateTables) {
-            QEventLoop loop;
-            ADownload* dl = new ADownload;
-            connect(dl, &ADownload::done, &loop, &QEventLoop::quit );
-            dl->setTarget(QUrl(linkStub + table + ".csv"));
-            dl->setFileName("data/templates/" + table + ".csv");
-            dl->download();
-            loop.exec(); // event loop waits for download done signal before allowing loop to continue
-            dl->deleteLater();
+    if (reply == QMessageBox::Yes) {// to do: else use local copy that shipped with the release
+        //close database connection
+        aDB()->disconnect();
+        // back up old database if exists
+        auto oldDatabase = QFile(AStandardPaths::getPath(QStandardPaths::AppDataLocation)
+                                 % QStringLiteral("/logbook.db"));
+
+        if (oldDatabase.exists()) {
+            auto dateString = QDateTime::currentDateTime().toString(Qt::ISODate);
+            DEB << "Backing up old database as: " << "logbook-backup-" + dateString;
+            if (!oldDatabase.rename(AStandardPaths::getPath(QStandardPaths::AppDataLocation)
+                                    % QStringLiteral("/logbook-backup-") % dateString
+                                    % QStringLiteral(".db"))) {
+                DEB << "Warning: Creating backup of old database has failed.";
+            }
         }
-    }
-
-    //close database connection
-    aDB()->disconnect();
-
-    // back up old database
-    auto oldDatabase = QFile("data/logbook.db");
-    if (oldDatabase.exists()) {
-        auto dateString = QDateTime::currentDateTime().toString(Qt::ISODate);
-        DEB << "Backing up old database as: " << "logbook-backup-" + dateString;
-        if (!oldDatabase.rename("data/logbook-backup-" + dateString)) {
-            DEB << "Warning: Creating backup of old database has failed.";
-        }
-    }
-    // re-connect and create new database
-    aDB()->connect();
+        // re-connect and create new database
+        aDB()->connect();
 
-    if (ADataBaseSetup::createDatabase()) {
-        if (ADataBaseSetup::importDefaultData()) {
-            ASettings::write("setup/setup_complete", true);
-            return true;
-        } else {
+        if(! ADataBaseSetup::createDatabase()) {
+            DEB << "Error creating Database";
             return false;
         }
-    } else {
-        return false;
+        if(! ADataBaseSetup::setupTemplateDir()) {
+                    DEB << "Error setting up template dir";
+                    return false;
+                }
+        if(! ADataBaseSetup::downloadTemplates()) {
+                    DEB << "Download Error";
+                    return false;
+                }
+        if(! ADataBaseSetup::importDefaultData()) {
+                    DEB << "Error importing default data";
+                    return false;
+                }
+        ASettings::write(QStringLiteral("setup/setup_complete"), true);
     }
+    return true;
 }
 
+void FirstRunDialog::reject()
+{
+
 
+    auto confirm = QMessageBox(this);
+    confirm.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+    confirm.setDefaultButton(QMessageBox::No);
+    confirm.setIcon(QMessageBox::Question);
+    confirm.setWindowTitle("Delete Flight");
+    confirm.setText(QStringLiteral("Without completing the initial setup"
+                                   " you cannot use the application.<br><br>"
+                                   "Quit anyway?"));
+    if (confirm.exec() == QMessageBox::Yes) {
+        DEB << "rejected.";
+        QDialog::reject();
+        }
+}

+ 4 - 3
src/gui/dialogues/firstrundialog.h

@@ -4,6 +4,7 @@
 #include <QDialog>
 #include <QButtonGroup>
 #include <QMessageBox>
+#include <QStringBuilder>
 
 namespace Ui {
 class FirstRunDialog;
@@ -25,14 +26,14 @@ private slots:
 
     void on_themeGroup_toggled(int id);
 
-
-
 private:
     Ui::FirstRunDialog *ui;
     // [G]: finish is the old signal.
     // finishSetup does something with template of database which
     // goes over my head but everything works for now. Better naming needed
-    bool finishSetup();
+
+    void reject() override;
+    bool setupDatabase();
     void finish();
 
 };