From 1b4ae1e46b18c47c1d1f972f74ae4632a036b7e7 Mon Sep 17 00:00:00 2001
From: James Turner <james@flightgear.org>
Date: Wed, 28 Apr 2021 11:25:36 +0100
Subject: [PATCH] Launcher: detect command line scenery/acft paths

---
 src/GUI/AddOnsController.cxx |  35 ++++++++--
 src/GUI/AddOnsController.hxx |   3 +
 src/GUI/QtLauncher.cxx       |   7 ++
 src/GUI/qml/AddOns.qml       | 121 ++++++++++++++++++++---------------
 4 files changed, 106 insertions(+), 60 deletions(-)

diff --git a/src/GUI/AddOnsController.cxx b/src/GUI/AddOnsController.cxx
index 1748ce22b..f334a4f15 100644
--- a/src/GUI/AddOnsController.cxx
+++ b/src/GUI/AddOnsController.cxx
@@ -12,6 +12,7 @@
 #include <simgear/package/Catalog.hxx>
 
 #include <Main/globals.hxx>
+#include <Main/options.hxx>
 #include <Main/sentryIntegration.hxx>
 #include <Network/HTTPClient.hxx>
 
@@ -54,17 +55,12 @@ AddOnsController::AddOnsController(LauncherMainWindow *parent, LaunchConfig* con
     m_aircraftPaths->loadFromSettings("aircraft-paths-v2");
 
     // sync up the aircraft cache now
-    auto aircraftCache = LocalAircraftCache::instance();
-    aircraftCache->setPaths(m_aircraftPaths->enabledPaths());
-    aircraftCache->scanDirs();
+    setLocalAircraftPaths();
 
     // watch for future changes
     connect(m_aircraftPaths, &PathListModel::enabledPathsChanged, [this] () {
         m_aircraftPaths->saveToSettings("aircraft-paths-v2");
-
-        auto aircraftCache = LocalAircraftCache::instance();
-        aircraftCache->setPaths(m_aircraftPaths->enabledPaths());
-        aircraftCache->scanDirs();
+        setLocalAircraftPaths();
     });
 
     QSettings settings;
@@ -102,6 +98,25 @@ AddOnsController::AddOnsController(LauncherMainWindow *parent, LaunchConfig* con
             this, &AddOnsController::collectArgs);
 }
 
+void AddOnsController::setLocalAircraftPaths()
+{
+    auto aircraftCache = LocalAircraftCache::instance();
+
+    QStringList paths;
+
+    const auto commandLineAircraftPaths = flightgear::Options::sharedInstance()->valuesForOption("fg-aircraft");
+    for (const auto& arg : commandLineAircraftPaths) {
+        // inner loop becuase a single arg can define multiple paths
+        for (const auto& p : SGPath::pathsFromUtf8(arg)) {
+            paths.append(QString::fromStdString(p.utf8Str()));
+        }
+    }
+
+    paths.append(m_aircraftPaths->enabledPaths());
+    aircraftCache->setPaths(paths);
+    aircraftCache->scanDirs();
+}
+
 PathListModel* AddOnsController::aircraftPaths() const
 {
     return m_aircraftPaths;
@@ -384,3 +399,9 @@ void AddOnsController::collectArgs()
     }
     settings.endArray();
 }
+
+bool AddOnsController::havePathsFromCommandLine() const
+{
+    const auto options = flightgear::Options::sharedInstance();
+    return options->isOptionSet("fg-scenery") || options->isOptionSet("fg-aircraft");
+}
diff --git a/src/GUI/AddOnsController.hxx b/src/GUI/AddOnsController.hxx
index 2a9dea74e..55ded449c 100644
--- a/src/GUI/AddOnsController.hxx
+++ b/src/GUI/AddOnsController.hxx
@@ -22,6 +22,7 @@ class AddOnsController : public QObject
     Q_PROPERTY(AddonsModel* modules READ modules NOTIFY modulesChanged)
     Q_PROPERTY(bool isOfficialHangarRegistered READ isOfficialHangarRegistered NOTIFY isOfficialHangarRegisteredChanged)
     Q_PROPERTY(bool showNoOfficialHangar READ showNoOfficialHangar NOTIFY showNoOfficialHangarChanged)
+    Q_PROPERTY(bool havePathsFromCommandLine READ havePathsFromCommandLine CONSTANT)
 
 public:
     explicit AddOnsController(LauncherMainWindow *parent, LaunchConfig* config);
@@ -51,6 +52,7 @@ public:
 
     Q_INVOKABLE void officialCatalogAction(QString s);
 
+    bool havePathsFromCommandLine() const;
 signals:
     void modulePathsChanged(QStringList modulePaths);
     void modulesChanged();
@@ -66,6 +68,7 @@ public slots:
     void collectArgs();
 
 private:
+    void setLocalAircraftPaths();
     bool shouldShowOfficialCatalogMessage() const;
     void onCatalogsChanged();
 
diff --git a/src/GUI/QtLauncher.cxx b/src/GUI/QtLauncher.cxx
index ee255ce7c..aff0e7b8f 100644
--- a/src/GUI/QtLauncher.cxx
+++ b/src/GUI/QtLauncher.cxx
@@ -554,6 +554,13 @@ void launcherSetSceneryPaths()
 {
     globals->clear_fg_scenery();
 
+    // process path sthe user supplied on the existing command line
+    const auto commandLineSceneryPaths = flightgear::Options::sharedInstance()->valuesForOption("fg-scenery");
+    for (const auto& arg : commandLineSceneryPaths) {
+        // each arg can be multiple paths
+        globals->append_fg_scenery(SGPath::pathsFromUtf8(arg));
+    }
+
 // mimic what options.cxx does, so we can find airport data for parking
 // positions
     QSettings settings;
diff --git a/src/GUI/qml/AddOns.qml b/src/GUI/qml/AddOns.qml
index ccaf783b6..2679439dd 100644
--- a/src/GUI/qml/AddOns.qml
+++ b/src/GUI/qml/AddOns.qml
@@ -107,59 +107,7 @@ Item {
                 }
             }
 
-    //////////////////////////////////////////////////////////////////
-
-            Item {
-                // spacing item
-                width: parent.width
-                height: Style.margin * 2
-            }
-
-            AddOnsHeader {
-                id: aircraftHeader
-                title: qsTr("Additional aircraft folders")
-                description: qsTr("To use aircraft you download yourself, FlightGear needs to " +
-                                  "know the folder(s) containing the aircraft data.")
-                showAddButton: true
-                onAdd: _addOns.addAircraftPath();
-            }
-
-            Rectangle {
-                width: parent.width
-                height: aircraftPathsColumn.childrenRect.height + 1
-                border.width: 1
-                border.color: Style.frameColor
-                clip: true
-                color: Style.panelBackground
-
-                Column {
-                    id: aircraftPathsColumn
-                    width: parent.width - Style.margin * 2
-                    x: Style.margin
-
-                    Repeater {
-                        id: aircraftPathsRepeater
-                        model: _addOns.aircraftPaths
-                        delegate: PathListDelegate {
-                            width: aircraftPathsColumn.width
-                            deletePromptText: qsTr("Remove the aircraft folder: '%1' from the list? (The folder contents will not be changed)").arg(model.path);
-                            modelCount: _addOns.aircraftPaths.count
-                            onPerformDelete: _addOns.aircraftPaths.removePath(model.index)
-                            onPerformMove: _addOns.aircraftPaths.swapIndices(model.index, newIndex);
-                        }
-                    }
-
-                    StyledText {
-                        visible: (aircraftPathsRepeater.count == 0)
-                        width: parent.width
-                        text : qsTr("No custom aircraft paths are configured.");
-                    }
-                }
-
-
-            }
-
-    //////////////////////////////////////////////////////////////////
+        //////////////////////////////////////////////////////////////////
 
             Item {
                 // spacing item
@@ -231,6 +179,73 @@ Item {
 
             }
 
+    //////////////////////////////////////////////////////////////////
+
+            Item {
+                // spacing item
+                width: parent.width
+                height: Style.margin * 2
+            }
+
+            StyledText {
+                id: commandLineDirsWarning
+                width: parent.width
+                visible: _addOns.havePathsFromCommandLine
+                color: Style.destructiveActionColor
+                text: qsTr("Additional aircraft or scenery folders were specified on the command-line. These are not listed here, but will be used when starting the simulator.")
+            }
+
+            Item {
+                // spacing item
+                width: parent.width
+                height: Style.margin * 2
+                visible: commandLineDirsWarning.visible
+            }
+
+            AddOnsHeader {
+                id: aircraftHeader
+                title: qsTr("Additional aircraft folders")
+                description: qsTr("To use aircraft you download yourself, FlightGear needs to " +
+                                  "know the folder(s) containing the aircraft data.")
+                showAddButton: true
+                onAdd: _addOns.addAircraftPath();
+            }
+
+            Rectangle {
+                width: parent.width
+                height: aircraftPathsColumn.childrenRect.height + 1
+                border.width: 1
+                border.color: Style.frameColor
+                clip: true
+                color: Style.panelBackground
+
+                Column {
+                    id: aircraftPathsColumn
+                    width: parent.width - Style.margin * 2
+                    x: Style.margin
+
+                    Repeater {
+                        id: aircraftPathsRepeater
+                        model: _addOns.aircraftPaths
+                        delegate: PathListDelegate {
+                            width: aircraftPathsColumn.width
+                            deletePromptText: qsTr("Remove the aircraft folder: '%1' from the list? (The folder contents will not be changed)").arg(model.path);
+                            modelCount: _addOns.aircraftPaths.count
+                            onPerformDelete: _addOns.aircraftPaths.removePath(model.index)
+                            onPerformMove: _addOns.aircraftPaths.swapIndices(model.index, newIndex);
+                        }
+                    }
+
+                    StyledText {
+                        visible: (aircraftPathsRepeater.count == 0)
+                        width: parent.width
+                        text : qsTr("No custom aircraft paths are configured.");
+                    }
+                }
+
+
+            }
+
     //////////////////////////////////////////////////////////////////
 
             Item {