]> git.mxchange.org Git - flightgear.git/commitdiff
Improved fg-root control from the Qt Launcher
authorJames Turner <zakalawe@mac.com>
Sun, 17 Jan 2016 19:10:22 +0000 (13:10 -0600)
committerJames Turner <zakalawe@mac.com>
Tue, 19 Jan 2016 01:06:43 +0000 (20:06 -0500)
- add a button to the main dialog, explaining how to adjust the
  fg-root path via the GUI
- tweak the GUI flow to support explicitly changing the path even
  when the default path is acceptable.

src/GUI/Launcher.ui
src/GUI/QtLauncher.cxx
src/GUI/QtLauncher_private.hxx
src/GUI/SetupRootDialog.cxx
src/GUI/SetupRootDialog.hxx
src/GUI/SetupRootDialog.ui
src/Main/options.cxx
src/Main/options.hxx

index b10749fd2c11d2861e1c55096d171e534fe6a0af..3ba4e55a51aff83367a95af0e38bff9b481fde95 100644 (file)
        <property name="bottomMargin">
         <number>4</number>
        </property>
-       <item>
-        <widget class="QListView" name="aircraftList"/>
-       </item>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_2">
          <property name="spacing">
          </item>
         </layout>
        </item>
+       <item>
+        <widget class="QListView" name="aircraftList"/>
+       </item>
       </layout>
      </widget>
      <widget class="QWidget" name="locationTab">
        <item row="6" column="0">
         <widget class="QPushButton" name="pathsButton">
          <property name="text">
-          <string>Configure add-on aircraft and scenery</string>
+          <string>Configure add-on aircraft and scenery…</string>
          </property>
          <property name="startupOnly" stdset="0">
           <bool>true</bool>
          </property>
         </widget>
        </item>
+       <item row="6" column="1">
+        <widget class="QPushButton" name="changeRootButton">
+         <property name="text">
+          <string>Change data files location…</string>
+         </property>
+        </widget>
+       </item>
       </layout>
      </widget>
     </widget>
index 367527c34acc441bed744309bd2199fc149571e5..f8aad70adb674a26a14a21a91cac7ea2ea50b879 100644 (file)
@@ -44,6 +44,7 @@
 #include <QApplication>
 #include <QSpinBox>
 #include <QDoubleSpinBox>
+#include <QProcess>
 
 // Simgear
 #include <simgear/timing/timestamp.hxx>
@@ -353,13 +354,14 @@ void initApp(int& argc, char** argv)
         flightgear::WindowBuilder::setPoseAsStandaloneApp(false);
 
         Qt::KeyboardModifiers mods = app->queryKeyboardModifiers();
-        if (mods & Qt::AltModifier) {
-            qWarning() << "Alt pressed during launch";
+        if (mods & (Qt::AltModifier | Qt::ShiftModifier)) {
+            qWarning() << "Alt/shift pressed during launch";
 
             // wipe out our settings
             QSettings settings;
             settings.clear();
 
+            settings.setValue("fg-root", "!ask");
 
             Options::sharedInstance()->addOption("restore-defaults", "");
         }
@@ -418,10 +420,12 @@ bool runLauncherDialog()
     loadNaturalEarthData();
 
     QtLauncher dlg;
-    dlg.exec();
+    dlg.show();
 
-    if (dlg.result() != QDialog::Accepted) {
-        return false;
+    int appResult = qApp->exec();
+    qDebug() << "App result:" << appResult;
+    if (appResult < 0) {
+        return false; // quit
     }
 
     // don't set scenery paths twice
@@ -487,6 +491,8 @@ QtLauncher::QtLauncher() :
     connect(m_ui->runButton, SIGNAL(clicked()), this, SLOT(onRun()));
     connect(m_ui->quitButton, SIGNAL(clicked()), this, SLOT(onQuit()));
 
+    connect(m_ui->changeRootButton, SIGNAL(clicked()), this, SLOT(onChangeRoot()));
+
     connect(m_ui->aircraftHistory, &QPushButton::clicked,
           this, &QtLauncher::onPopupAircraftHistory);
 
@@ -713,8 +719,6 @@ void QtLauncher::setEnableDisableOptionFromCheckbox(QCheckBox* cbox, QString nam
 
 void QtLauncher::onRun()
 {
-    accept();
-
     flightgear::Options* opt = flightgear::Options::sharedInstance();
     setEnableDisableOptionFromCheckbox(m_ui->terrasyncCheck, "terrasync");
     setEnableDisableOptionFromCheckbox(m_ui->fetchRealWxrCheckbox, "real-weather-fetch");
@@ -820,6 +824,8 @@ void QtLauncher::onRun()
     }
 
     saveSettings();
+
+    qApp->exit(0);
 }
 
 
@@ -864,7 +870,7 @@ void QtLauncher::onApply()
 
 void QtLauncher::onQuit()
 {
-    reject();
+    qApp->exit(-1);
 }
 
 void QtLauncher::onToggleTerrasync(bool enabled)
@@ -1126,6 +1132,54 @@ void QtLauncher::onEditPaths()
     }
 }
 
+void QtLauncher::onChangeRoot()
+{
+    QMessageBox mbox(this);
+    mbox.setText(tr("Change the data files location used by FlightGear?"));
+    mbox.setInformativeText(tr("FlightGear cannot work without its data files. "
+                               "(Also called the base package) "
+                               "To change which files are used, quit FlightGear and open it again, "
+                               "while holding down the 'shift' key, and you will be able to choose a "
+                               "different data files location, or restore the default setting."));
+    QPushButton* quitButton = mbox.addButton(tr("Quit FlightGear now"), QMessageBox::YesRole);
+    mbox.addButton(QMessageBox::Cancel);
+    mbox.setDefaultButton(QMessageBox::Cancel);
+    mbox.setIconPixmap(QPixmap(":/app-icon-large"));
+
+    mbox.exec();
+    if (mbox.clickedButton() != quitButton) {
+        return;
+    }
+
+    // following code doesn't work reliably, so we take the simpler
+    // option of asking the user to re-launch us while holding down
+    // the hot-key (shift)
+#if 0
+    {
+        QSettings settings;
+        // set the option to the magic marker value
+        settings.setValue("fg-root", "!ask");
+    } // scope the ensure settings are written nicel
+
+    // Spawn a new instance of myApplication:
+    QProcess proc;
+#if defined(Q_OS_MAC)
+    QStringList args;
+
+    QDir dir(qApp->applicationDirPath()); // returns the 'MacOS' dir
+    dir.cdUp(); // up to 'contents' dir
+    dir.cdUp(); // up to .app dir
+    args << dir.absolutePath();
+    proc.startDetached("open", args);
+#else
+    proc.startDetached(qApp->applicationFilePath());
+#endif
+#endif
+
+    qDebug() << "doing app exit";
+    qApp->exit(-1);
+}
+
 simgear::pkg::PackageRef QtLauncher::packageForAircraftURI(QUrl uri) const
 {
     if (uri.scheme() != "package") {
index 104c8ddb5c2c801b7d9e2a93203572b875102310..f5eea7adeab3022a46f90cd89267884139517dee 100644 (file)
@@ -82,7 +82,7 @@ private slots:
     void onSubsytemIdleTimeout();
 
     void onEditPaths();
-
+    void onChangeRoot();
 
     void onAircraftInstalledCompleted(QModelIndex index);
     void onAircraftInstallFailed(QModelIndex index, QString errorMessage);
index 707bc0962e0adc9af4f4007b90900581eaf459ac..93999f47666648ac167b6bf8637abd573c99ff3c 100644 (file)
 
 #include <Main/globals.hxx>
 #include <Main/fg_init.hxx>
+#include <Main/options.hxx>
 #include <Include/version.h>
 
-SetupRootDialog::SetupRootDialog(bool usedDefaultPath) :
-    QDialog()
+SetupRootDialog::SetupRootDialog(PromptState prompt) :
+    QDialog(),
+    m_promptState(prompt)
 {
     m_ui.reset(new Ui::SetupRootDialog);
     m_ui->setupUi(this);
@@ -52,28 +54,63 @@ SetupRootDialog::SetupRootDialog(bool usedDefaultPath) :
             this, &SetupRootDialog::onDownload);
     connect(m_ui->buttonBox, &QDialogButtonBox::rejected,
             this, &QDialog::reject);
+    connect(m_ui->useDefaultsButton, &QPushButton::clicked,
+            this, &SetupRootDialog::onUseDefaults);
 
-    m_promptState = usedDefaultPath ? DefaultPathCheckFailed : ExplicitPathCheckFailed;
-    std::string ver = fgBasePackageVersion(globals->get_fg_root());
-    if (!ver.empty()) {
-        Q_ASSERT(ver != FLIGHTGEAR_VERSION); // otherwise what are we doing in here?!
-        m_promptState = VersionCheckFailed;
-    }
+    // decide if the 'use defaults' button should be enabled or not
+    bool ok = defaultRootAcceptable();
+    m_ui->useDefaultsButton->setEnabled(ok);
+    m_ui->useDefaultLabel->setEnabled(ok);
 
     m_ui->versionLabel->setText(tr("FlightGear version %1").arg(FLIGHTGEAR_VERSION));
     m_ui->bigIcon->setPixmap(QPixmap(":/app-icon-large"));
     updatePromptText();
 }
 
-bool SetupRootDialog::restoreUserSelectedRoot()
+bool SetupRootDialog::runDialog(bool usingDefaultRoot)
+{
+    SetupRootDialog::PromptState prompt =
+        usingDefaultRoot ? DefaultPathCheckFailed : ExplicitPathCheckFailed;
+    return runDialog(prompt);
+}
+
+bool SetupRootDialog::runDialog(PromptState prompt)
+{
+    SetupRootDialog dlg(prompt);
+    dlg.exec();
+    if (dlg.result() != QDialog::Accepted) {
+        exit(-1);
+    }
+
+    return true;
+}
+
+std::string SetupRootDialog::restoreUserSelectedRoot()
 {
     QSettings settings;
     QString path = settings.value("fg-root").toString();
+    if (path == "!ask") {
+        bool ok = runDialog(ManualChoiceRequested);
+        Q_ASSERT(ok);
+        // run dialog either exit()s or sets fg_root, so this
+        // behaviour is safe and correct.
+        return globals->get_fg_root();
+    }
+
+    if (path.isEmpty()) {
+        return std::string(); // use the default path
+    }
+
     if (validatePath(path) && validateVersion(path)) {
-        globals->set_fg_root(path.toStdString());
-        return true;
+        return path.toStdString();
     } else {
-        return false;
+        // we have an existing path but it's invalid. Let's ask the
+        // user what they want
+        bool ok = runDialog(VersionCheckFailed);
+        Q_ASSERT(ok);
+        // run dialog either exit()s or sets fg_root, so this
+        // behaviour is safe and correct.
+        return globals->get_fg_root();
     }
 }
 
@@ -109,6 +146,13 @@ bool SetupRootDialog::validateVersion(QString path)
     return (ver == FLIGHTGEAR_VERSION);
 }
 
+bool SetupRootDialog::defaultRootAcceptable()
+{
+    std::string r = flightgear::Options::sharedInstance()->platformDefaultRoot();
+    QString defaultRoot = QString::fromStdString(r);
+    return validatePath(defaultRoot) && validateVersion(defaultRoot);
+}
+
 SetupRootDialog::~SetupRootDialog()
 {
 
@@ -148,6 +192,16 @@ void SetupRootDialog::onDownload()
     QDesktopServices::openUrl(downloadUrl);
 }
 
+void SetupRootDialog::onUseDefaults()
+{
+    std::string r = flightgear::Options::sharedInstance()->platformDefaultRoot();
+    m_browsedPath = QString::fromStdString(r);
+    globals->set_fg_root(r);
+    QSettings settings;
+    settings.remove("fg-root"); // remove any setting
+    accept();
+}
+
 void SetupRootDialog::updatePromptText()
 {
     QString t;
@@ -171,6 +225,10 @@ void SetupRootDialog::updatePromptText()
         break;
     }
 
+    case ManualChoiceRequested:
+        t = tr("Please select or download a copy of the FlightGear data files.");
+        break;
+
     case ChoseInvalidLocation:
         t = tr("The choosen location (%1) does not appear to contain FlightGear data files. Please try another location.").arg(m_browsedPath);
         break;
index 9d01b724741b9148daf9a651bfd826d7834ad06e..2a1d4eae300c4ad1e1e0be0e6d526a795bad14df 100644 (file)
@@ -22,6 +22,8 @@
 #include <QScopedPointer>
 #include <QString>
 
+#include <string>
+
 namespace Ui
 {
     class SetupRootDialog;
@@ -31,33 +33,43 @@ class SetupRootDialog : public QDialog
 {
     Q_OBJECT
 public:
-    SetupRootDialog(bool usedDefaultPath);
 
     ~SetupRootDialog();
 
-    static bool restoreUserSelectedRoot();
+    static bool runDialog(bool usingDefaultRoot);
+
+    static std::string restoreUserSelectedRoot();
 private slots:
 
     void onBrowse();
 
     void onDownload();
 
+    void onUseDefaults();
+
     void updatePromptText();
 private:
-
-    static bool validatePath(QString path);
-    static bool validateVersion(QString path);
-
     enum PromptState
     {
         DefaultPathCheckFailed,
         ExplicitPathCheckFailed,
         VersionCheckFailed,
+        ManualChoiceRequested,
         ChoseInvalidLocation,
         ChoseInvalidVersion
     };
+    
+    SetupRootDialog(PromptState prompt);
+
+    static bool runDialog(PromptState prompt);
+
+    static bool validatePath(QString path);
+    static bool validateVersion(QString path);
+
+    static bool defaultRootAcceptable();
+
 
     PromptState m_promptState;
     QScopedPointer<Ui::SetupRootDialog> m_ui;
     QString m_browsedPath;
-};
\ No newline at end of file
+};
index 572e570cba593850df442c7649a2b9fe6a3f23ee..9e8465a560ef5611d44e33da6ca9a7b587455d11 100644 (file)
@@ -9,14 +9,27 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>618</width>
-    <height>338</height>
+    <width>627</width>
+    <height>392</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Setup required data files</string>
   </property>
-  <layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
+  <layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0">
+   <item row="7" column="1">
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
    <item row="0" column="0" rowspan="2">
     <widget class="QLabel" name="bigIcon">
      <property name="minimumSize">
      </property>
     </widget>
    </item>
-   <item row="4" column="1">
-    <widget class="QPushButton" name="downloadButton">
+   <item row="8" column="1" colspan="2">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel</set>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1" colspan="2">
+    <widget class="QLabel" name="versionLabel">
      <property name="text">
-      <string>Download </string>
+      <string>FlightGear version 3.4.5</string>
      </property>
     </widget>
    </item>
-   <item row="3" column="1">
-    <widget class="QLabel" name="label_2">
+   <item row="3" column="2" alignment="Qt::AlignTop">
+    <widget class="QPushButton" name="useDefaultsButton">
      <property name="text">
-      <string>To download a compressed archive of the files, click the 'Download' button. Once the download is complete, extract the files to a suitabe location and choose the folder using the button above.</string>
+      <string>Use built-in data files</string>
      </property>
-     <property name="wordWrap">
-      <bool>true</bool>
+    </widget>
+   </item>
+   <item row="6" column="2" alignment="Qt::AlignTop">
+    <widget class="QPushButton" name="downloadButton">
+     <property name="text">
+      <string>Download </string>
      </property>
     </widget>
    </item>
-   <item row="1" column="1">
+   <item row="1" column="1" colspan="2">
     <widget class="QLabel" name="promptText">
      <property name="minimumSize">
       <size>
@@ -66,7 +93,7 @@
      </property>
     </widget>
    </item>
-   <item row="2" column="1">
+   <item row="2" column="2" alignment="Qt::AlignTop">
     <widget class="QPushButton" name="browseButton">
      <property name="text">
       <string>Choose folder...</string>
      </property>
     </widget>
    </item>
-   <item row="0" column="1">
-    <widget class="QLabel" name="versionLabel">
+   <item row="3" column="1">
+    <widget class="QLabel" name="useDefaultLabel">
      <property name="text">
-      <string>FlightGear version 3.4.5</string>
+      <string>To use the files included with this copy of FlightGear, click this button</string>
+     </property>
+     <property name="wordWrap">
+      <bool>true</bool>
      </property>
     </widget>
    </item>
-   <item row="6" column="0" colspan="2">
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
+   <item row="6" column="1">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>To download a compressed archive of the files, click the 'Download' button. Once the download is complete, extract the files to a suitabe location and choose the folder using the button above.</string>
      </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel</set>
+     <property name="wordWrap">
+      <bool>true</bool>
      </property>
     </widget>
    </item>
-   <item row="5" column="1">
-    <spacer name="verticalSpacer">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
+   <item row="2" column="1">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>To browse to a downloaded copy of the files on your computer, click this button</string>
      </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
+     <property name="wordWrap">
+      <bool>true</bool>
      </property>
-    </spacer>
+    </widget>
    </item>
   </layout>
  </widget>
index 9cfbb6c9df607e5db5dca8126050baf102984c99..2c01e0203c7cfefe00526d9cead47deb2593d2c8 100644 (file)
@@ -2493,19 +2493,26 @@ string Options::platformDefaultRoot() const
   
 void Options::setupRoot(int argc, char **argv)
 {
-  string root;
+    string root;
     bool usingDefaultRoot = false;
 
+#if defined(HAVE_QT)
+    flightgear::initApp(argc, argv);
+    root = SetupRootDialog::restoreUserSelectedRoot();
+#endif
+
   if (isOptionSet("fg-root")) {
     root = valueForOption("fg-root"); // easy!
   } else {
+
   // Next check if fg-root is set as an env variable
     char *envp = ::getenv( "FG_ROOT" );
     if ( envp != NULL ) {
       root = envp;
-    } else {
+// if we didn't restore a path from the Qt launcher, use the default here
+    } else if (root.empty()) {
         usingDefaultRoot = true;
-      root = platformDefaultRoot();
+        root = platformDefaultRoot();
     }
   } 
   
@@ -2515,18 +2522,12 @@ void Options::setupRoot(int argc, char **argv)
     string base_version = fgBasePackageVersion(root);
 
 #if defined(HAVE_QT)
+    // note we never end up here is resotring a user selected root via
+    // the Qt GUI, since that code pre-validates the path. But if we're using
+    // a command-line, env-var or default root this check can fail and
+    // we still want to use the GUI in that case
     if (base_version != required_version) {
-        flightgear::initApp(argc, argv);
-        if (SetupRootDialog::restoreUserSelectedRoot()) {
-            SG_LOG(SG_GENERAL, SG_INFO, "restored user selected fg_root = " << globals->get_fg_root() );
-            return;
-        }
-
-        SetupRootDialog dlg(usingDefaultRoot);
-        dlg.exec();
-        if (dlg.result() != QDialog::Accepted) {
-            exit(-1);
-        }
+        SetupRootDialog::runDialog(usingDefaultRoot);
     }
 #else
     // validate it
index a74e1a15bf2d82797cdc982653c667b41a01c564..f6f23b0d420b337a44c124b94c81435f718143af 100644 (file)
@@ -134,6 +134,8 @@ public:
    * Used by early startup code before Options object is created
    */
   static bool checkForArg(int argc, char* argv[], const char* arg);
+
+      std::string platformDefaultRoot() const;
 private:
   void showUsage() const;
   
@@ -148,8 +150,7 @@ private:
      * to help the user our (finding a base package), and hence need to init Qt.
      */
   void setupRoot(int argc, char **argv);
-  
-  std::string platformDefaultRoot() const;
+
   
   class OptionsPrivate;
   std::auto_ptr<OptionsPrivate> p;