]> git.mxchange.org Git - flightgear.git/commitdiff
Qt launcher: additional arguments UI
authorJames Turner <zakalawe@mac.com>
Mon, 23 Feb 2015 13:41:30 +0000 (13:41 +0000)
committerJames Turner <zakalawe@mac.com>
Mon, 23 Feb 2015 13:41:50 +0000 (13:41 +0000)
Add a plain text edit widget to the launcher to support
custom command line arguments.

src/GUI/Launcher.ui
src/GUI/QtLauncher.cxx

index 05ddb78b37bbbd71b47bd128b27ff4893a22932b..4cd666bd9f1024a9c1d8c04d2e7d12742bdd17c4 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>696</width>
-    <height>711</height>
+    <width>700</width>
+    <height>700</height>
    </rect>
   </property>
   <property name="windowTitle">
       <attribute name="title">
        <string>Settings</string>
       </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout">
-       <item>
+      <layout class="QGridLayout" name="gridLayout_4">
+       <property name="leftMargin">
+        <number>10</number>
+       </property>
+       <property name="rightMargin">
+        <number>10</number>
+       </property>
+       <property name="bottomMargin">
+        <number>10</number>
+       </property>
+       <item row="0" column="0">
         <layout class="QHBoxLayout" name="horizontalLayout_4">
          <item>
           <widget class="QLabel" name="label">
            <property name="text">
             <string>Time of day:</string>
            </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
           </widget>
          </item>
          <item>
          </item>
         </layout>
        </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_8">
-         <item>
-          <widget class="QLabel" name="label_7">
-           <property name="text">
-            <string>Season:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="seasonCombo">
-           <item>
-            <property name="text">
-             <string>Summer</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>Winter</string>
-            </property>
-           </item>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
+       <item row="1" column="0">
         <widget class="QCheckBox" name="msaaCheckbox">
          <property name="text">
           <string>Enable Multi-sample anti-aliasing</string>
          </property>
         </widget>
        </item>
-       <item>
+       <item row="1" column="1" colspan="2">
         <widget class="QCheckBox" name="rembrandtCheckbox">
          <property name="text">
           <string>Enable deferred rendering (Rembrandt)</string>
          </property>
         </widget>
        </item>
-       <item>
+       <item row="2" column="0" colspan="2">
         <widget class="QCheckBox" name="terrasyncCheck">
          <property name="text">
           <string>Enable automatic scenery downloading (TerraSync)</string>
          </property>
         </widget>
        </item>
-       <item>
+       <item row="3" column="0" colspan="3">
         <layout class="QHBoxLayout" name="horizontalLayout_7">
          <item>
           <spacer name="horizontalSpacer_2">
          </item>
         </layout>
        </item>
-       <item>
+       <item row="4" column="0">
         <widget class="QCheckBox" name="fetchRealWxrCheckbox">
          <property name="text">
           <string>Fetch real weather online</string>
          </property>
         </widget>
        </item>
-       <item>
-        <widget class="QCheckBox" name="fullScreenCheckbox">
-         <property name="text">
-          <string>Start full-screen</string>
-         </property>
-        </widget>
-       </item>
-       <item>
+       <item row="5" column="0">
         <widget class="QCheckBox" name="startPausedCheck">
          <property name="text">
           <string>Start paused</string>
          </property>
         </widget>
        </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0">
-         <item>
-          <widget class="QLabel" name="customAircraftDirLabel">
-           <property name="text">
-            <string>Custom aircraft directory:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="openAircraftDirButton">
-           <property name="text">
-            <string>Open in Finder</string>
-           </property>
-           <property name="autoDefault">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
+       <item row="7" column="0" colspan="3">
         <widget class="QGroupBox" name="groupBox">
          <property name="title">
           <string>Additional scenery locations</string>
          </layout>
         </widget>
        </item>
-       <item>
-        <spacer name="verticalSpacer">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
+       <item row="0" column="1" colspan="2">
+        <layout class="QHBoxLayout" name="horizontalLayout_8">
+         <item>
+          <widget class="QLabel" name="label_7">
+           <property name="text">
+            <string>Season:</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="seasonCombo">
+           <item>
+            <property name="text">
+             <string>Summer</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Winter</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item row="4" column="1" colspan="2">
+        <widget class="QCheckBox" name="fullScreenCheckbox">
+         <property name="text">
+          <string>Start full-screen</string>
          </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>40</height>
-          </size>
+        </widget>
+       </item>
+       <item row="6" column="0" colspan="3">
+        <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0">
+         <item>
+          <widget class="QLabel" name="customAircraftDirLabel">
+           <property name="text">
+            <string>Custom aircraft directory:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="openAircraftDirButton">
+           <property name="text">
+            <string>Open in Finder</string>
+           </property>
+           <property name="autoDefault">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item row="8" column="0" colspan="3">
+        <widget class="QGroupBox" name="groupBox_2">
+         <property name="title">
+          <string>Additional options</string>
          </property>
-        </spacer>
+         <layout class="QHBoxLayout" name="horizontalLayout_9">
+          <property name="leftMargin">
+           <number>8</number>
+          </property>
+          <property name="topMargin">
+           <number>8</number>
+          </property>
+          <property name="rightMargin">
+           <number>8</number>
+          </property>
+          <property name="bottomMargin">
+           <number>8</number>
+          </property>
+          <item>
+           <widget class="QPlainTextEdit" name="commandLineArgs">
+            <property name="placeholderText">
+             <string>--option=value --prop:/sim/name=value</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
        </item>
       </layout>
      </widget>
index 815939177f33447f0d566bce37b4d05f7b8604d5..2f1e634451da85550bcc1e369089d3f66c69a5e2 100644 (file)
@@ -396,6 +396,106 @@ private:
     }
 };
 
+class ArgumentsTokenizer
+{
+public:
+    class Arg
+    {
+    public:
+        explicit Arg(QString k, QString v = QString()) : arg(k), value(v) {}
+
+        QString arg;
+        QString value;
+    };
+
+    QList<Arg> tokenize(QString in) const
+    {
+        int index = 0;
+        const int len = in.count();
+        QChar c, nc;
+        State state = Start;
+        QString key, value;
+        QList<Arg> result;
+
+        for (; index < len; ++index) {
+            c = in.at(index);
+            nc = index < (len - 1) ? in.at(index + 1) : QChar();
+
+            switch (state) {
+            case Start:
+                if (c == QChar('-')) {
+                    if (nc == QChar('-')) {
+                        state = Key;
+                        key.clear();
+                        ++index;
+                    } else {
+                        // should we pemit single hyphen arguments?
+                        // choosing to fail for now
+                        return QList<Arg>();
+                    }
+                } else if (c.isSpace()) {
+                    break;
+                }
+                break;
+
+            case Key:
+                if (c == QChar('=')) {
+                    state = Value;
+                    value.clear();
+                } else if (c.isSpace()) {
+                    state = Start;
+                    result.append(Arg(key));
+                } else {
+                    // could check for illegal charatcers here
+                    key.append(c);
+                }
+                break;
+
+            case Value:
+                if (c == QChar('"')) {
+                    state = Quoted;
+                } else if (c.isSpace()) {
+                    state = Start;
+                    result.append(Arg(key, value));
+                } else {
+                    value.append(c);
+                }
+                break;
+
+            case Quoted:
+                if (c == QChar('\\')) {
+                    // check for escaped double-quote inside quoted value
+                    if (nc == QChar('"')) {
+                        ++index;
+                    }
+                } else if (c == QChar('"')) {
+                    state = Value;
+                } else {
+                    value.append(c);
+                }
+                break;
+            } // of state switch
+        } // of character loop
+
+        // ensure last argument isn't lost
+        if (state == Key) {
+            result.append(Arg(key));
+        } else if (state == Value) {
+            result.append(Arg(key, value));
+        }
+
+        return result;
+    }
+
+private:
+    enum State {
+        Start = 0,
+        Key,
+        Value,
+        Quoted
+    };
+};
+
 } // of anonymous namespace
 
 class AirportSearchModel : public QAbstractListModel
@@ -746,6 +846,8 @@ void QtLauncher::restoreSettings()
 
     QStringList sceneryPaths = settings.value("scenery-paths").toStringList();
     m_ui->sceneryPathsList->addItems(sceneryPaths);
+
+    m_ui->commandLineArgs->setPlainText(settings.value("additional-args").toString());
 }
 
 void QtLauncher::saveSettings()
@@ -769,6 +871,7 @@ void QtLauncher::saveSettings()
     }
 
     settings.setValue("scenery-paths", paths);
+    settings.setValue("additional-args", m_ui->commandLineArgs->toPlainText());
 }
 
 void QtLauncher::setEnableDisableOptionFromCheckbox(QCheckBox* cbox, QString name) const
@@ -858,6 +961,17 @@ void QtLauncher::onRun()
         opt->addOption("fg-scenery", path.toStdString());
     }
 
+    // additional arguments
+    ArgumentsTokenizer tk;
+    Q_FOREACH(ArgumentsTokenizer::Arg a, tk.tokenize(m_ui->commandLineArgs->toPlainText())) {
+        if (a.arg.startsWith("prop:")) {
+            QString v = a.arg.mid(5) + "=" + a.value;
+            opt->addOption("prop", v.toStdString());
+        } else {
+            opt->addOption(a.arg.toStdString(), a.value.toStdString());
+        }
+    }
+
     saveSettings();
 }