]> git.mxchange.org Git - flightgear.git/commitdiff
Very crude work on GUI base package selection.
authorJames Turner <zakalawe@mac.com>
Fri, 6 Mar 2015 18:52:06 +0000 (18:52 +0000)
committerJames Turner <zakalawe@mac.com>
Sun, 8 Mar 2015 00:42:05 +0000 (00:42 +0000)
- feedback on wording greatly appreciated.
- needed to make nightly builds usable without bundled data.

14 files changed:
CMakeLists.txt
src/GUI/CMakeLists.txt
src/GUI/QtLauncher.cxx
src/GUI/QtLauncher.hxx
src/GUI/SetupRootDialog.cxx [new file with mode: 0644]
src/GUI/SetupRootDialog.hxx [new file with mode: 0644]
src/GUI/SetupRootDialog.ui [new file with mode: 0644]
src/GUI/resources.qrc
src/Include/config_cmake.h.in
src/Main/fg_init.cxx
src/Main/fg_init.hxx
src/Main/main.cxx
src/Main/options.cxx
src/Main/options.hxx

index 3ee613db64b304a1e6f4010380cff72f2d390f8b..ccd58ea5549482b557e1032f5fb4340c7d93a062 100644 (file)
@@ -168,6 +168,7 @@ option(SYSTEM_SPEEX      "Set to ON to build IAXClient with the system's speex a
 option(SYSTEM_GSM        "Set to ON to build IAXClient with the system's GSM library" ${SYSTEM_GSM_DEFAULT})
 option(SYSTEM_FLITE      "Set to ON to build Flightgear with the system's Flite library" ${SYSTEM_FLITE_DEFAULT})
 option(SYSTEM_HTS_ENGINE "Set to ON to build Flightgear with the system's HTS Engine library" ${SYSTEM_HTS_ENGINE_DEFAULT})
+option(FG_NIGHTLY        "Set to ON to mark this as a nightly build" OFF)
 
 # additional utilities
 option(ENABLE_FGADMIN    "Set to ON to build the FGADMIN application (default)" ON)
@@ -287,9 +288,6 @@ if (USE_DBUS)
 else()
 endif (USE_DBUS)
 
-# Sqlite always depends on the threading lib
-list(APPEND SQLITE3_LIBRARY ${CMAKE_THREAD_LIBS_INIT})
-
 ##############################################################################
 ## Qt5 setup setup
 if (ENABLE_QT)
index 37c2af62316eae25b77cb54d87325637f159109c..83da4b767662b2676904d149ab7332d36759c182 100644 (file)
@@ -70,7 +70,7 @@ endif()
 
 
 if (HAVE_QT)
-    qt5_wrap_ui(uic_sources Launcher.ui EditRatingsFilterDialog.ui)
+    qt5_wrap_ui(uic_sources Launcher.ui EditRatingsFilterDialog.ui SetupRootDialog.ui)
     qt5_add_resources(qrc_sources resources.qrc)
 
     include_directories(${PROJECT_BINARY_DIR}/src/GUI)
@@ -81,6 +81,8 @@ if (HAVE_QT)
                             AirportDiagram.hxx
                             EditRatingsFilterDialog.cxx
                             EditRatingsFilterDialog.hxx
+                            SetupRootDialog.cxx
+                            SetupRootDialog.hxx
                             ${uic_sources}
                             ${qrc_sources})
 
index 7386f91b6a7f1e70f8de5549e6c438ab442f9aa1..88d1727c36c06b28b263974a85b98754f21217bf 100644 (file)
@@ -27,6 +27,7 @@
 #include <QMessageBox>
 #include <QDataStream>
 #include <QDateTime>
+#include <QApplication>
 
 // Simgear
 #include <simgear/timing/timestamp.hxx>
@@ -42,6 +43,7 @@
 #include <Airports/airport.hxx>
 #include <Airports/dynamics.hxx> // for parking
 #include <Main/options.hxx>
+#include <Viewer/WindowBuilder.hxx>
 
 using namespace flightgear;
 
@@ -1066,9 +1068,26 @@ QtLauncher::~QtLauncher()
     
 }
 
+void QtLauncher::initApp(int argc, char** argv)
+{
+    static bool qtInitDone = false;
+    if (!qtInitDone) {
+        qtInitDone = true;
+
+        QApplication* app = new QApplication(argc, argv);
+        app->setOrganizationName("FlightGear");
+        app->setApplicationName("FlightGear");
+        app->setOrganizationDomain("flightgear.org");
+
+        // avoid double Apple menu and other weirdness if both Qt and OSG
+        // try to initialise various Cocoa structures.
+        flightgear::WindowBuilder::setPoseAsStandaloneApp(false);
+    }
+}
+
 bool QtLauncher::runLauncherDialog()
 {
-     Q_INIT_RESOURCE(resources);
+    Q_INIT_RESOURCE(resources);
 
     // startup the nav-cache now. This pre-empts normal startup of
     // the cache, but no harm done. (Providing scenery paths are consistent)
index 81dab0ee3a9a189dd3f848a0c9e8cf6feca88448..8ee46203597d07a1b33dbc2dd84264e3cf9c82b8 100644 (file)
@@ -22,7 +22,9 @@ class QtLauncher : public QDialog
 public:
     QtLauncher();
     virtual ~QtLauncher();
-    
+
+    static void initApp(int argc, char** argv);
+
     static bool runLauncherDialog();
 
 private slots:
diff --git a/src/GUI/SetupRootDialog.cxx b/src/GUI/SetupRootDialog.cxx
new file mode 100644 (file)
index 0000000..fd3ee5b
--- /dev/null
@@ -0,0 +1,169 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SetupRootDialog.hxx"
+
+#include <QFileDialog>
+#include <QDesktopServices>
+#include <QDir>
+#include <QFileInfo>
+#include <QMessageBox>
+#include <QSettings>
+#include <QDebug>
+#include <QSettings>
+
+#include "ui_SetupRootDialog.h"
+
+#include <Main/globals.hxx>
+#include <Main/fg_init.hxx>
+#include <Include/version.h>
+
+SetupRootDialog::SetupRootDialog(bool usedDefaultPath) :
+    QDialog()
+{
+    m_ui.reset(new Ui::SetupRootDialog);
+    m_ui->setupUi(this);
+
+    connect(m_ui->browseButton, &QPushButton::clicked,
+             this, &SetupRootDialog::onBrowse);
+    connect(m_ui->downloadButton, &QPushButton::clicked,
+            this, &SetupRootDialog::onDownload);
+    connect(m_ui->buttonBox, &QDialogButtonBox::rejected,
+            this, &QDialog::reject);
+
+    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;
+    }
+
+    m_ui->versionLabel->setText(tr("FlightGear version %1").arg(FLIGHTGEAR_VERSION));
+    m_ui->bigIcon->setPixmap(QPixmap(":/app-icon-large"));
+    updatePromptText();
+}
+
+bool SetupRootDialog::restoreUserSelectedRoot()
+{
+    QSettings settings;
+    QString path = settings.value("fg-root").toString();
+    if (validatePath(path) && validateVersion(path)) {
+        qDebug() << "Restoring FG-root:" << path;
+        globals->set_fg_root(path.toStdString());
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool SetupRootDialog::validatePath(QString path)
+{
+    // check assorted files exist in the root location, to avoid any chance of
+    // selecting an incomplete base package. This is probably overkill but does
+    // no harm
+    QStringList files = QStringList()
+        << "version"
+        << "preferences.xml"
+        << "Materials/base/materials-base.xml"
+        << "gui/menubar.xml"
+        << "Timezone/zone.tab";
+
+    QDir d(path);
+    if (!d.exists()) {
+        return false;
+    }
+
+    Q_FOREACH(QString s, files) {
+        if (!d.exists(s)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool SetupRootDialog::validateVersion(QString path)
+{
+    std::string ver = fgBasePackageVersion(SGPath(path.toStdString()));
+    return (ver == FLIGHTGEAR_VERSION);
+}
+
+SetupRootDialog::~SetupRootDialog()
+{
+
+}
+
+void SetupRootDialog::onBrowse()
+{
+    m_browsedPath = QFileDialog::getExistingDirectory(this,
+                                                     tr("Choose FlightGear data folder"));
+    if (m_browsedPath.isEmpty()) {
+        return;
+    }
+
+    if (!validatePath(m_browsedPath)) {
+        m_promptState = ChoseInvalidLocation;
+        updatePromptText();
+        return;
+    }
+
+    if (!validateVersion(m_browsedPath)) {
+        m_promptState = ChoseInvalidVersion;
+        updatePromptText();
+        return;
+    }
+
+    globals->set_fg_root(m_browsedPath.toStdString());
+
+    QSettings settings;
+    settings.setValue("fg-root", m_browsedPath);
+
+    accept(); // we're done
+}
+
+void SetupRootDialog::onDownload()
+{
+    QUrl downloadUrl("http://download.flightgear.org/flightgear/Shared/");
+    QDesktopServices::openUrl(downloadUrl);
+}
+
+void SetupRootDialog::updatePromptText()
+{
+    QString t;
+    QString curRoot = QString::fromStdString(globals->get_fg_root());
+    switch (m_promptState) {
+    case DefaultPathCheckFailed:
+        t = tr("This copy of FlightGear does not include the base data files. " \
+               "Please select a suitable folder containing a previously download set of files.");
+        break;
+
+    case ExplicitPathCheckFailed:
+        t = tr("The requested location '%1' does not appear to be a valid set of data files for FlightGear").arg(curRoot);
+        break;
+
+    case VersionCheckFailed:
+    {
+        QString curVer = QString::fromStdString(fgBasePackageVersion(globals->get_fg_root()));
+        t = tr("Detected incompatible version of the data files: version %1 found, but this is FlightGear %2. " \
+               "(At location: '%3') " \
+               "Please install or select a matching set of data files.").arg(curVer).arg(QString::fromLatin1(FLIGHTGEAR_VERSION)).arg(curRoot);
+        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;
+
+    case ChoseInvalidVersion:
+    {
+        QString curVer = QString::fromStdString(fgBasePackageVersion(m_browsedPath.toStdString()));
+        t = tr("The choosen location (%1) contains files for version %2, but this is FlightGear %3. " \
+               "Please update or try another location").arg(m_browsedPath).arg(curVer).arg(QString::fromLatin1(FLIGHTGEAR_VERSION));
+        break;
+    }
+    }
+
+    m_ui->promptText->setText(t);
+}
+
diff --git a/src/GUI/SetupRootDialog.hxx b/src/GUI/SetupRootDialog.hxx
new file mode 100644 (file)
index 0000000..ba677dc
--- /dev/null
@@ -0,0 +1,44 @@
+
+#include <QDialog>
+#include <QScopedPointer>
+#include <QString>
+
+namespace Ui
+{
+    class SetupRootDialog;
+}
+
+class SetupRootDialog : public QDialog
+{
+    Q_OBJECT
+public:
+    SetupRootDialog(bool usedDefaultPath);
+
+    ~SetupRootDialog();
+
+    static bool restoreUserSelectedRoot();
+private slots:
+
+    void onBrowse();
+
+    void onDownload();
+
+    void updatePromptText();
+private:
+
+    static bool validatePath(QString path);
+    static bool validateVersion(QString path);
+
+    enum PromptState
+    {
+        DefaultPathCheckFailed,
+        ExplicitPathCheckFailed,
+        VersionCheckFailed,
+        ChoseInvalidLocation,
+        ChoseInvalidVersion
+    };
+
+    PromptState m_promptState;
+    QScopedPointer<Ui::SetupRootDialog> m_ui;
+    QString m_browsedPath;
+};
\ No newline at end of file
diff --git a/src/GUI/SetupRootDialog.ui b/src/GUI/SetupRootDialog.ui
new file mode 100644 (file)
index 0000000..572e570
--- /dev/null
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SetupRootDialog</class>
+ <widget class="QDialog" name="SetupRootDialog">
+  <property name="windowModality">
+   <enum>Qt::ApplicationModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>618</width>
+    <height>338</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Setup required data files</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
+   <item row="0" column="0" rowspan="2">
+    <widget class="QLabel" name="bigIcon">
+     <property name="minimumSize">
+      <size>
+       <width>128</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="text">
+      <string>TextLabel</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="1">
+    <widget class="QPushButton" name="downloadButton">
+     <property name="text">
+      <string>Download </string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" 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="wordWrap">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLabel" name="promptText">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>80</height>
+      </size>
+     </property>
+     <property name="text">
+      <string>Replace me</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+     </property>
+     <property name="wordWrap">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <widget class="QPushButton" name="browseButton">
+     <property name="text">
+      <string>Choose folder...</string>
+     </property>
+     <property name="default">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLabel" name="versionLabel">
+     <property name="text">
+      <string>FlightGear version 3.4.5</string>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="0" 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="5" 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>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
index 9415e5b6cd0b0357b1a2d225ad1ab8a5c6f791e5..4cbca391dae800ecbba192719207c288b21110e7 100644 (file)
@@ -4,5 +4,6 @@
         <file alias="search-icon">large-search-icon.png</file>
         <file alias="right-arrow-icon">arrow-right-icon.png</file>
         <file alias="left-arrow-icon">arrow-left-icon.png</file>
+        <file alias="app-icon-large">../../icons/128x128/apps/flightgear.png</file>
     </qresource>
 </RCC>
\ No newline at end of file
index 20a2ca777de8253bc3e0c73165483d529495256c..ec9c1bc0763d1ef3b18b4528807a8e9228373f43 100644 (file)
@@ -1,6 +1,8 @@
 
 
 #cmakedefine FG_NDEBUG
+#cmakedefine FG_NIGHTLY
+
 #cmakedefine ENABLE_SP_FDM
 #cmakedefine JSBSIM_USE_GROUNDREACTIONS
 
index 1d648a83a38c0d992cf6bb0a99feb79b7dde1227..41568a42b340e051fb9f8a1c14d3137a0e8be3a0 100644 (file)
@@ -160,14 +160,14 @@ using namespace simgear::pkg;
 extern osg::ref_ptr<osgViewer::Viewer> viewer;
 
 // Return the current base package version
-string fgBasePackageVersion() {
-    SGPath base_path( globals->get_fg_root() );
-    base_path.append("version");
-    if (!base_path.exists()) {
+string fgBasePackageVersion(const SGPath& base_path) {
+    SGPath p(base_path);
+    p.append("version");
+    if (!p.exists()) {
         return string();
     }
     
-    sg_gzifstream in( base_path.str() );
+    sg_gzifstream in( p.str() );
     if (!in.is_open()) {
         return string();
     }
index ef8a6bd829af12db3a8faed08bc9ea7d8f12ca35..4162af9aafcddf0e6db2e6054a159ddb8faa4e47 100644 (file)
 
 // forward decls
 class SGPropertyNode;
+class SGPath;
 
 // Return the current base package version
-std::string fgBasePackageVersion();
+std::string fgBasePackageVersion(const SGPath& path);
 
 bool fgInitHome();
 
index e77e70e15e1414e7878596af4ece8612a70fe616..d6ab4c5635d2e93f0f976c4285c64042a5a28a0b 100644 (file)
@@ -68,7 +68,6 @@ extern bool global_crashRptEnabled;
 #include <Viewer/WindowSystemAdapter.hxx>
 #include <Navaids/NavDataCache.hxx>
 #include <Include/version.h>
-#include <Viewer/WindowBuilder.hxx>
 
 #include "fg_commands.hxx"
 #include "fg_io.hxx"
@@ -83,7 +82,6 @@ extern bool global_crashRptEnabled;
 #include "options.hxx"
 
 #if defined(HAVE_QT)
-#include <QApplication>
 #include <GUI/QtLauncher.hxx>
 #endif
 
@@ -458,16 +456,8 @@ int fgMainInit( int argc, char **argv )
     // environment variables. This avoids needed a wrapper shell-script on OS-X.
     showLauncher |= (::getenv("FG_LAUNCHER") != 0);
 
-    if (showLauncher) {        
-        QApplication app(argc, argv);
-        app.setOrganizationName("FlightGear");
-        app.setApplicationName("FlightGear");
-        app.setOrganizationDomain("flightgear.org");
-    
-        // avoid double Apple menu and other weirdness if both Qt and OSG
-        // try to initialise various Cocoa structures.
-        flightgear::WindowBuilder::setPoseAsStandaloneApp(false);
-
+    if (showLauncher) {
+        QtLauncher::initApp(argc, argv);
         if (!QtLauncher::runLauncherDialog()) {
             return EXIT_SUCCESS;
         }
index 65419fb2174245ebc933aeb8d0900ad885318102..c4e7fc0ca5a8d2807688845e402d36a0f546535f 100644 (file)
@@ -55,6 +55,8 @@
 
 #include <GUI/gui.h>
 #include <GUI/MessageBox.hxx>
+#include <GUI/QtLauncher.hxx>
+#include <GUI/SetupRootDialog.hxx>
 
 #include <Main/locale.hxx>
 #include "globals.hxx"
 #include "AircraftDirVisitorBase.hxx"
 
 #include <osg/Version>
-
-#if defined( HAVE_VERSION_H ) && HAVE_VERSION_H
-#  include <Include/version.h>
-#  include <simgear/version.h>
-#else
-#  include <Include/no_version.h>
-#endif
+#include <Include/version.h>
+#include <simgear/version.h>
 
 using std::string;
 using std::sort;
@@ -1904,7 +1901,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
   fgOptLogLevel(valueForOption("log-level", "alert").c_str());
 
   if (!p->shouldLoadDefaultConfig) {
-    setupRoot();
+    setupRoot(argc, argv);
     return;
   }
   
@@ -1939,7 +1936,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
   }
   
 // setup FG_ROOT
-  setupRoot();
+  setupRoot(argc, argv);
   
 // system.fgfsrc handling
   if( ! hostname.empty() ) {
@@ -2436,9 +2433,11 @@ string Options::platformDefaultRoot() const
 }
 #endif
   
-void Options::setupRoot()
+void Options::setupRoot(int argc, char **argv)
 {
   string root;
+    bool usingDefaultRoot = false;
+
   if (isOptionSet("fg-root")) {
     root = valueForOption("fg-root"); // easy!
   } else {
@@ -2447,16 +2446,32 @@ void Options::setupRoot()
     if ( envp != NULL ) {
       root = envp;
     } else {
+        usingDefaultRoot = true;
       root = platformDefaultRoot();
     }
   } 
   
-  SG_LOG(SG_INPUT, SG_INFO, "fg_root = " << root );
+  SG_LOG(SG_GENERAL, SG_INFO, "fg_root = " << root );
   globals->set_fg_root(root);
-  
-// validate it
-  static char required_version[] = FLIGHTGEAR_VERSION;
-  string base_version = fgBasePackageVersion();
+    static char required_version[] = FLIGHTGEAR_VERSION;
+    string base_version = fgBasePackageVersion(root);
+
+#if defined(HAVE_QT)
+    if (base_version != required_version) {
+        QtLauncher::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);
+        }
+    }
+#else
+    // validate it
     if (base_version.empty()) {
         flightgear::fatalMessageBox("Base package not found",
                                     "Required data files not found, check your installation.",
@@ -2465,9 +2480,7 @@ void Options::setupRoot()
         exit(-1);
     }
     
- if (base_version != required_version) {
-    // tell the operator how to use this application
-   
+    if (base_version != required_version) {
       flightgear::fatalMessageBox("Base package version mismatch",
                                   "Version check failed: please check your installation.",
                                   "Found data files for version '" + base_version +
@@ -2476,6 +2489,7 @@ void Options::setupRoot()
 
     exit(-1);
   }
+#endif
 }
   
 bool Options::shouldLoadDefaultConfig() const
index 40005363f8cb904e0c0b950d5554977ff58ef21f..5fab50fe7e97e11eac924311c0d8f42eb0e63540 100644 (file)
@@ -131,8 +131,14 @@ private:
   int parseOption(const std::string& s);
   
   void processArgResult(int result);
-  
-  void setupRoot();
+
+    /**
+     * Setup the root base, and check it's valid. Bails out with exit(-1) if
+     * the root package was not found or is the incorrect version. Argv/argv
+     * are passed since we might potentially show a GUI dialog at this point
+     * 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;