]> git.mxchange.org Git - flightgear.git/commitdiff
Work on new download-dir option
authorJames Turner <zakalawe@mac.com>
Tue, 17 Mar 2015 22:10:49 +0000 (22:10 +0000)
committerJames Turner <zakalawe@mac.com>
Fri, 10 Apr 2015 14:01:54 +0000 (15:01 +0100)
- simplify management of a single, user-facing
  location for large downloaded data.

src/GUI/AircraftModel.cxx
src/GUI/PathsDialog.cxx [new file with mode: 0644]
src/GUI/PathsDialog.ui [new file with mode: 0644]
src/GUI/QtLauncher.cxx
src/GUI/QtLauncher.hxx
src/Main/bootstrap.cxx
src/Main/fg_init.cxx
src/Main/main.cxx
src/Main/options.cxx
src/Main/options.hxx

index e357bb02ed24a2916dcce75c6014bdea13b9e8f7..16b9007c184ae7216084e1465de9ae366f77b636 100644 (file)
@@ -290,8 +290,6 @@ private:
 
             emit addedItems();
         } // of subdir iteration
-
-        qDebug() << "scan of" << path << "took" << t.elapsed();
     }
 
     QMutex m_lock;
diff --git a/src/GUI/PathsDialog.cxx b/src/GUI/PathsDialog.cxx
new file mode 100644 (file)
index 0000000..725d38d
--- /dev/null
@@ -0,0 +1,165 @@
+#include "PathsDialog.hxx"
+#include "ui_PathsDialog.h"
+
+#include <QSettings>
+#include <QFileDialog>
+
+#include "CatalogListModel.hxx"
+#include "AddCatalogDialog.hxx"
+
+#include <Main/options.hxx>
+
+PathsDialog::PathsDialog(QWidget *parent, simgear::pkg::RootRef root) :
+    QDialog(parent),
+    m_ui(new Ui::PathsDialog),
+    m_packageRoot(root)
+{
+    m_ui->setupUi(this);
+    
+    m_catalogsModel = new CatalogListModel(this, m_packageRoot);
+    m_ui->catalogsList->setModel(m_catalogsModel);
+
+    connect(m_ui->addCatalog, &QToolButton::clicked,
+            this, &PathsDialog::onAddCatalog);
+    connect(m_ui->removeCatalog, &QToolButton::clicked,
+            this, &PathsDialog::onRemoveCatalog);
+            
+    connect(m_ui->addSceneryPath, &QToolButton::clicked,
+            this, &PathsDialog::onAddSceneryPath);
+    connect(m_ui->removeSceneryPath, &QToolButton::clicked,
+            this, &PathsDialog::onRemoveSceneryPath);
+
+    connect(m_ui->addAircraftPath, &QToolButton::clicked,
+            this, &PathsDialog::onAddAircraftPath);
+    connect(m_ui->removeAircraftPath, &QToolButton::clicked,
+            this, &PathsDialog::onRemoveAircraftPath);
+
+    connect(m_ui->changeDownloadDir, &QPushButton::clicked,
+            this, &PathsDialog::onChangeDownloadDir);
+
+    connect(m_ui->clearDownloadDir, &QPushButton::clicked,
+            this, &PathsDialog::onClearDownloadDir);
+
+    QSettings settings;
+            
+    QStringList sceneryPaths = settings.value("scenery-paths").toStringList();
+    m_ui->sceneryPathsList->addItems(sceneryPaths);
+
+    QStringList aircraftPaths = settings.value("aircraft-paths").toStringList();
+    m_ui->aircraftPathsList->addItems(aircraftPaths);
+
+    QVariant downloadDir = settings.value("download-dir");
+    if (downloadDir.isValid()) {
+        m_downloadDir = downloadDir.toString();
+    }
+
+    updateUi();
+}
+
+PathsDialog::~PathsDialog()
+{
+    delete m_ui;
+}
+
+void PathsDialog::accept()
+{
+    QSettings settings;
+    QStringList paths;
+    for (int i=0; i<m_ui->sceneryPathsList->count(); ++i) {
+        paths.append(m_ui->sceneryPathsList->item(i)->text());
+    }
+
+    settings.setValue("scenery-paths", paths);
+    paths.clear();
+
+    for (int i=0; i<m_ui->aircraftPathsList->count(); ++i) {
+        paths.append(m_ui->aircraftPathsList->item(i)->text());
+    }
+
+    settings.setValue("aircraft-paths", paths);
+
+    if (m_downloadDir.isEmpty()) {
+        settings.remove("download-dir");
+    } else {
+        settings.setValue("download-dir", m_downloadDir);
+    }
+    
+    QDialog::accept();
+}
+
+void PathsDialog::onAddSceneryPath()
+{
+    QString path = QFileDialog::getExistingDirectory(this, tr("Choose scenery folder"));
+    if (!path.isEmpty()) {
+        m_ui->sceneryPathsList->addItem(path);
+    }
+}
+
+void PathsDialog::onRemoveSceneryPath()
+{
+    if (m_ui->sceneryPathsList->currentItem()) {
+        delete m_ui->sceneryPathsList->currentItem();
+    }
+}
+
+void PathsDialog::onAddAircraftPath()
+{
+    QString path = QFileDialog::getExistingDirectory(this, tr("Choose aircraft folder"));
+    if (!path.isEmpty()) {
+        m_ui->aircraftPathsList->addItem(path);
+    }
+}
+
+void PathsDialog::onRemoveAircraftPath()
+{
+    if (m_ui->aircraftPathsList->currentItem()) {
+        delete m_ui->aircraftPathsList->currentItem();
+    }
+}
+
+void PathsDialog::onAddCatalog()
+{
+    AddCatalogDialog* dlg = new AddCatalogDialog(this, m_packageRoot);
+    dlg->exec();
+    if (dlg->result() == QDialog::Accepted) {
+        m_catalogsModel->refresh();
+    }
+}
+
+void PathsDialog::onRemoveCatalog()
+{
+    
+}
+
+void PathsDialog::onChangeDownloadDir()
+{
+    QString path = QFileDialog::getExistingDirectory(this,
+                                                     tr("Choose downloads folder"),
+                                                     m_downloadDir);
+    if (!path.isEmpty()) {
+        m_downloadDir = path;
+        updateUi();
+    }
+}
+
+void PathsDialog::onClearDownloadDir()
+{
+    // does this need an 'are you sure'?
+    m_downloadDir.clear();
+    updateUi();
+}
+
+void PathsDialog::updateUi()
+{
+    QString s = m_downloadDir;
+    if (s.isEmpty()) {
+        s = QString::fromStdString(flightgear::defaultDownloadDir());
+        s.append(tr(" (default)"));
+        m_ui->clearDownloadDir->setEnabled(false);
+    } else {
+        m_ui->clearDownloadDir->setEnabled(true);
+    }
+
+    QString m = tr("Download location: %1").arg(s);
+    m_ui->downloadLocation->setText(m);
+}
diff --git a/src/GUI/PathsDialog.ui b/src/GUI/PathsDialog.ui
new file mode 100644 (file)
index 0000000..76a64ef
--- /dev/null
@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PathsDialog</class>
+ <widget class="QDialog" name="PathsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>600</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Configure add-ons</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0" colspan="3">
+      <widget class="QLabel" name="downloadLocation">
+       <property name="text">
+        <string>TextLabel</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QPushButton" name="changeDownloadDir">
+       <property name="text">
+        <string>Change...</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QPushButton" name="clearDownloadDir">
+       <property name="text">
+        <string>Use default location</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="2">
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item row="2" column="0" colspan="3">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Aircraft hangars and automatic scenery downloads may cause this location to contain large numbers of files. Changing this location will cause files to be downloaded again.</string>
+       </property>
+       <property name="wordWrap">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Additional scenery locations</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_3">
+      <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>
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <item row="1" column="0">
+       <spacer name="horizontalSpacer_3">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>567</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="1" column="1">
+       <widget class="QToolButton" name="addSceneryPath">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>+</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0" colspan="3">
+       <widget class="QListWidget" name="sceneryPathsList"/>
+      </item>
+      <item row="1" column="2">
+       <widget class="QToolButton" name="removeSceneryPath">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>-</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox_4">
+     <property name="title">
+      <string>Aircraft hangar locations</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_6">
+      <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>
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <item row="1" column="0">
+       <spacer name="horizontalSpacer_5">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>567</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="1" column="2">
+       <widget class="QToolButton" name="removeCatalog">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>-</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QToolButton" name="addCatalog">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>+</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0" colspan="3">
+       <widget class="QListView" name="catalogsList"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox_3">
+     <property name="title">
+      <string>Additional aircraft locations</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_4">
+      <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>
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <item row="0" column="0" colspan="3">
+       <widget class="QListWidget" name="aircraftPathsList"/>
+      </item>
+      <item row="1" column="0">
+       <spacer name="horizontalSpacer_4">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>567</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="1" column="2">
+       <widget class="QToolButton" name="removeAircraftPath">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>-</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QToolButton" name="addAircraftPath">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>+</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>PathsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>PathsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
index 8d2d8b28e3ee3e752b9582bdc69b6763ffc314fe..82fd293c7aa864ac22d3358e807cf28d31d6561c 100644 (file)
@@ -426,44 +426,15 @@ QtLauncher::QtLauncher() :
     connect(m_airportsModel, &AirportSearchModel::searchComplete,
             this, &QtLauncher::onAirportSearchComplete);
 
-    SGPath p = SGPath::documents();
-    p.append("FlightGear");
-    p.append("Aircraft");
-    m_customAircraftDir = QString::fromStdString(p.str());
-    m_ui->customAircraftDirLabel->setText(QString("Custom aircraft folder: %1").arg(m_customAircraftDir));
-
-    globals->append_aircraft_path(m_customAircraftDir.toStdString());
+    // default value, restoreSettings() will override
+    m_downloadDir = QString();
 
     // create and configure the proxy model
     m_aircraftProxy = new AircraftProxyModel(this);
-
-    fgInitPackageRoot();
-    simgear::pkg::RootRef r(globals->packageRoot());
-
-    FGHTTPClient* http = new FGHTTPClient;
-    globals->add_subsystem("http", http);
-
-    // we guard against re-init in the global phase; bind and postinit
-    // will happen as normal
-    http->init();
-
-    m_aircraftModel = new AircraftItemModel(this, r);
-    m_aircraftProxy->setSourceModel(m_aircraftModel);
-
-    m_aircraftProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
-    m_aircraftProxy->setSortCaseSensitivity(Qt::CaseInsensitive);
-    m_aircraftProxy->setSortRole(Qt::DisplayRole);
-    m_aircraftProxy->setDynamicSortFilter(true);
-
-    m_ui->aircraftList->setModel(m_aircraftProxy);
-    m_ui->aircraftList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-    AircraftItemDelegate* delegate = new AircraftItemDelegate(m_ui->aircraftList);
-    m_ui->aircraftList->setItemDelegate(delegate);
-    m_ui->aircraftList->setSelectionMode(QAbstractItemView::SingleSelection);
-    connect(m_ui->aircraftList, &QListView::clicked,
-            this, &QtLauncher::onAircraftSelected);
-    connect(delegate, &AircraftItemDelegate::variantChanged,
-            this, &QtLauncher::onAircraftSelected);
+    connect(m_ui->ratingsFilterCheck, &QAbstractButton::toggled,
+            m_aircraftProxy, &AircraftProxyModel::setRatingFilterEnabled);
+    connect(m_ui->aircraftFilter, &QLineEdit::textChanged,
+            m_aircraftProxy, &QSortFilterProxyModel::setFilterFixedString);
 
     connect(m_ui->runwayCombo, SIGNAL(currentIndexChanged(int)),
             this, SLOT(updateAirportDescription()));
@@ -482,9 +453,6 @@ QtLauncher::QtLauncher() :
     connect(m_ui->airportEdit, SIGNAL(returnPressed()),
             this, SLOT(onSearchAirports()));
 
-    connect(m_ui->aircraftFilter, &QLineEdit::textChanged,
-            m_aircraftProxy, &QSortFilterProxyModel::setFilterFixedString);
-
     connect(m_ui->airportHistory, &QPushButton::clicked,
             this, &QtLauncher::onPopupAirportHistory);
     connect(m_ui->aircraftHistory, &QPushButton::clicked,
@@ -492,9 +460,6 @@ QtLauncher::QtLauncher() :
 
     restoreSettings();
 
-    connect(m_ui->openAircraftDirButton, &QPushButton::clicked,
-          this, &QtLauncher::onOpenCustomAircraftDir);
-
     QAction* qa = new QAction(this);
     qa->setShortcut(QKeySequence("Ctrl+Q"));
     connect(qa, &QAction::triggered, this, &QtLauncher::onQuit);
@@ -502,8 +467,6 @@ QtLauncher::QtLauncher() :
 
     connect(m_ui->editRatingFilter, &QPushButton::clicked,
             this, &QtLauncher::onEditRatingsFilter);
-    connect(m_ui->ratingsFilterCheck, &QAbstractButton::toggled,
-            m_aircraftProxy, &AircraftProxyModel::setRatingFilterEnabled);
 
     QIcon historyIcon(":/history-icon");
     m_ui->aircraftHistory->setIcon(historyIcon);
@@ -528,7 +491,8 @@ QtLauncher::QtLauncher() :
 
     connect(m_ui->rembrandtCheckbox, SIGNAL(toggled(bool)),
             this, SLOT(onRembrandtToggled(bool)));
-
+    connect(m_ui->terrasyncCheck, &QCheckBox::toggled,
+            this, &QtLauncher::onToggleTerrasync);
     updateSettingsSummary();
 
     connect(m_ui->addSceneryPath, &QToolButton::clicked,
@@ -541,6 +505,35 @@ QtLauncher::QtLauncher() :
     connect(m_ui->removeAircraftPath, &QToolButton::clicked,
             this, &QtLauncher::onRemoveAircraftPath);
 
+    fgInitPackageRoot();
+    simgear::pkg::RootRef r(globals->packageRoot());
+
+    FGHTTPClient* http = new FGHTTPClient;
+    globals->add_subsystem("http", http);
+
+    // we guard against re-init in the global phase; bind and postinit
+    // will happen as normal
+    http->init();
+
+    m_aircraftModel = new AircraftItemModel(this, r);
+    m_aircraftProxy->setSourceModel(m_aircraftModel);
+
+    m_aircraftProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
+    m_aircraftProxy->setSortCaseSensitivity(Qt::CaseInsensitive);
+    m_aircraftProxy->setSortRole(Qt::DisplayRole);
+    m_aircraftProxy->setDynamicSortFilter(true);
+
+    m_ui->aircraftList->setModel(m_aircraftProxy);
+    m_ui->aircraftList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    AircraftItemDelegate* delegate = new AircraftItemDelegate(m_ui->aircraftList);
+    m_ui->aircraftList->setItemDelegate(delegate);
+    m_ui->aircraftList->setSelectionMode(QAbstractItemView::SingleSelection);
+    connect(m_ui->aircraftList, &QListView::clicked,
+            this, &QtLauncher::onAircraftSelected);
+    connect(delegate, &AircraftItemDelegate::variantChanged,
+            this, &QtLauncher::onAircraftSelected);
+
+
     m_catalogsModel = new CatalogListModel(this, r);
     m_ui->catalogsList->setModel(m_catalogsModel);
 
@@ -630,6 +623,11 @@ void QtLauncher::restoreSettings()
         // select the default C172p
     }
 
+    QVariant downloadDir = settings.value("download-dir");
+    if (downloadDir.isValid()) {
+        m_downloadDir = downloadDir.toString();
+    }
+
     updateSelectedAircraft();
 
     // ICAO identifiers
@@ -687,6 +685,12 @@ void QtLauncher::saveSettings()
 
     settings.setValue("aircraft-paths", paths);
     settings.setValue("additional-args", m_ui->commandLineArgs->toPlainText());
+
+    if (m_downloadDir.isEmpty()) {
+        settings.remove("download-dir");
+    } else {
+        settings.setValue("download-dir", m_downloadDir);
+    }
 }
 
 void QtLauncher::setEnableDisableOptionFromCheckbox(QCheckBox* cbox, QString name) const
@@ -770,6 +774,25 @@ void QtLauncher::onRun()
         opt->addOption("season", dayval.toStdString());
     }
 
+    if (!m_downloadDir.isEmpty()) {
+        QDir d(m_downloadDir);
+        if (!d.exists()) {
+            int result = QMessageBox::question(this, tr("Create download folder?"),
+                                  tr("The selected location for downloads does not exist. Create it?"),
+                                               QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
+            if (result == QMessageBox::Cancel) {
+                return;
+            }
+
+            if (result == QMessageBox::Yes) {
+                d.mkpath(m_downloadDir);
+            }
+        }
+
+        qDebug() << "Download dir is:" << downloadDir;
+        opt->addOption("download-dir", downloadDir.toStdString());
+    }
+
     // scenery paths
     for (int i=0; i<m_ui->sceneryPathsList->count(); ++i) {
         QString path = m_ui->sceneryPathsList->item(i)->text();
@@ -879,6 +902,39 @@ void QtLauncher::onAirportChanged()
     }
 }
 
+void QtLauncher::onToggleTerrasync(bool enabled)
+{
+    if (enabled) {
+        QFileInfo info(m_downloadDir);
+        if (!info.exists()) {
+            QMessageBox msg;
+            msg.setWindowTitle(tr("Create download folder?"));
+            msg.setText(tr("The current download folder '%1' does not exist, create it now? "
+                           "Click 'change location' to choose another folder "
+                           "to store downloaded files").arg(m_downloadDir));
+            msg.addButton(QMessageBox::Yes);
+            msg.addButton(QMessageBox::Cancel);
+            msg.addButton(tr("Change location"), QMessageBox::ActionRole);
+            int result = msg.exec();
+  
+            if (result == QMessageBox::Cancel) {
+                m_ui->terrasyncCheck->setChecked(false);
+                return;
+            }
+
+            if (result == QMessageBox::ActionRole) {
+                qDebug() << "Change location!";
+                // open the prefrences dialog?
+                return;
+            }
+
+            QDir d(m_downloadDir);
+            d.mkpath(m_downloadDir);
+        }
+
+    }
+}
+
 void QtLauncher::updateAirportDescription()
 {
     if (!m_selectedAirport) {
@@ -1024,6 +1080,7 @@ void QtLauncher::setAirport(FGAirportRef ref)
     updateAirportDescription();
 }
 
+#if 0
 void QtLauncher::onOpenCustomAircraftDir()
 {
     QFileInfo info(m_customAircraftDir);
@@ -1043,6 +1100,7 @@ void QtLauncher::onOpenCustomAircraftDir()
   QUrl u = QUrl::fromLocalFile(m_customAircraftDir);
   QDesktopServices::openUrl(u);
 }
+#endif
 
 void QtLauncher::onEditRatingsFilter()
 {
@@ -1136,6 +1194,22 @@ void QtLauncher::onRemoveAircraftPath()
     }
 }
 
+void QtLauncher::onChangeDownloadDir()
+{
+    QString path = QFileDialog::getExistingDirectory(this, tr("Choose downloads folder"));
+    if (!path.isEmpty()) {
+        m_downloadDir = path;
+        saveSettings();
+    }
+}
+
+void QtLauncher::onClearDownloadDir()
+{
+    // does this need an 'are you sure'?
+    m_downloadDir.clear();
+    saveSettings();
+}
+
 void QtLauncher::onRembrandtToggled(bool b)
 {
     // Rembrandt and multi-sample are exclusive
index 33de985f05454080e16d17a161b36bff1ab07790..9c504217e704343ea08f7474aa95f36d1cd8fed0 100644 (file)
@@ -66,8 +66,6 @@ private slots:
     void onPopupAirportHistory();
     void onPopupAircraftHistory();
 
-    void onOpenCustomAircraftDir();
-
     void onEditRatingsFilter();
 
     void updateAirportDescription();
@@ -85,8 +83,12 @@ private slots:
     void onRemoveCatalog();
 
     void onRembrandtToggled(bool b);
+    void onToggleTerrasync(bool enabled);
 
     void onSubsytemIdleTimeout();
+
+    void onChangeDownloadDir();
+    void onClearDownloadDir();
 private:
     void setAirport(FGAirportRef ref);
     void updateSelectedAircraft();
@@ -110,7 +112,7 @@ private:
     QString m_selectedAircraft;
     QStringList m_recentAircraft,
         m_recentAirports;
-    QString m_customAircraftDir;
+    QString m_downloadDir;
     QTimer* m_subsystemIdleTimer;
 
     int m_ratingFilters[4];
index af643da7899416f2e18a42cdfc952d3988f3ab62..a59fdb47e29c8c255925db199c1921b98542e1b0 100644 (file)
 
 #include "fg_os.hxx"
 
-#if defined(SG_MAC)
-    #include <GUI/CocoaHelpers.h> // for transformToForegroundApp
-#endif
-
 #if defined(HAVE_CRASHRPT)
        #include <CrashRpt.h>
 
@@ -208,6 +204,10 @@ int main ( int argc, char **argv )
                char buf[16];
                ::snprintf(buf, 16, "%d", HUDSON_BUILD_NUMBER);
                crAddProperty("hudson-build-number", buf);
+        crAddProperty("git-revision", REVISION);
+#if defined(FG_NIGHTLY)
+        crAddProperty("nightly-build", "true");
+#endif
        }
 #endif
 
index e7b391862f3ea52c785d8f7dbe9a5a7d00461e91..30ffa0e67a580fbb5464f38354f970941923baff 100644 (file)
@@ -671,8 +671,9 @@ void fgOutputSettings()
     
     SG_LOG( SG_GENERAL, SG_INFO, "aircraft-dir = " << '"' << fgGetString("/sim/aircraft-dir") << '"' );
     SG_LOG( SG_GENERAL, SG_INFO, "fghome-dir = " << '"' << globals->get_fg_home() << '"');
-    SG_LOG( SG_GENERAL, SG_INFO, "aircraft-dir = " << '"' << fgGetString("/sim/aircraft-dir") << '"');
-    
+    SG_LOG( SG_GENERAL, SG_INFO, "download-dir = " << '"' << fgGetString("/sim/paths/download-dir") << '"' );
+    SG_LOG( SG_GENERAL, SG_INFO, "terrasync-dir = " << '"' << fgGetString("/sim/terrasync/scenery-dir") << '"' );
+
     SG_LOG( SG_GENERAL, SG_INFO, "aircraft-search-paths = \n\t" << simgear::strutils::join(globals->get_aircraft_paths(), "\n\t") );
     SG_LOG( SG_GENERAL, SG_INFO, "scenery-search-paths = \n\t" << simgear::strutils::join(globals->get_fg_scenery(), "\n\t") );
 }
@@ -1132,11 +1133,7 @@ void fgInitPackageRoot()
         return;
     }
     
-    // there is some debate if we should be using FG_HOME here (hidden
-    // location) vs a user-visible location inside Documents (especially on
-    // Windows and Mac). Really this location should be managed by FG, not
-    // the user, but it can potentially grow large.
-    SGPath packageAircraftDir = globals->get_fg_home();
+    SGPath packageAircraftDir = flightgear::defaultDownloadDir();
     packageAircraftDir.append("Aircraft");
 
     SGSharedPtr<Root> pkgRoot(new Root(packageAircraftDir, FLIGHTGEAR_VERSION));
index 30edd654eac4676ba39621eefa915c33a1b1d91b..0901577620f98c5b37827431a83297328e02947c 100644 (file)
@@ -127,7 +127,7 @@ static void initTerrasync()
     
     // start TerraSync up now, so it can be synchronizing shared models
     // and airports data in parallel with a nav-cache rebuild.
-    SGPath tsyncCache(globals->get_fg_home());
+    SGPath tsyncCache(terraSyncDir);
     tsyncCache.append("terrasync-cache.xml");
     
     // wipe the cache file if requested
index 4b168fd6818155855a5684d98da282be04703c9a..937e0071aa9e906d51545ccd9430dab6dadd8f40 100644 (file)
@@ -231,7 +231,12 @@ void fgSetDefaults ()
     v->setValueReadOnly("build-number", HUDSON_BUILD_NUMBER);
     v->setValueReadOnly("build-id", HUDSON_BUILD_ID);
     v->setValueReadOnly("hla-support", bool(FG_HAVE_HLA));
-
+#if defined(FG_NIGHTLY)
+    v->setValueReadOnly("nightly-build", true);
+#else
+    v->setValueReadOnly("nightly-build", false);
+#endif
+    
     char* envp = ::getenv( "http_proxy" );
     if( envp != NULL )
       fgSetupProxy( envp );
@@ -1599,6 +1604,7 @@ struct OptionDesc {
     {"disable-terrasync",            false, OPTION_BOOL,   "/sim/terrasync/enabled", false, "", 0 },
     {"enable-terrasync",             false, OPTION_BOOL,   "/sim/terrasync/enabled", true, "", 0 },
     {"terrasync-dir",                true,  OPTION_STRING, "/sim/terrasync/scenery-dir", false, "", 0 },
+    {"download-dir",                 true,  OPTION_STRING, "/sim/paths/download-dir", false, "", 0 },
     {"geometry",                     true,  OPTION_FUNC,   "", false, "", fgOptGeometry },
     {"bpp",                          true,  OPTION_FUNC,   "", false, "", fgOptBpp },
     {"units-feet",                   false, OPTION_STRING, "/sim/startup/units", false, "feet", 0 },
@@ -2186,20 +2192,17 @@ string_list Options::valuesForOption(const std::string& key) const
   return result;
 }
 
-
-static string defaultTerrasyncDir()
+string defaultDownloadDir()
 {
 #if defined(SG_WINDOWS)
-       SGPath p(SGPath::documents());
-       p.append("FlightGear");
+    SGPath p(SGPath::documents());
+    p.append("FlightGear");
 #else
     SGPath p(globals->get_fg_home());
 #endif
-       p.append("TerraSync");
-       return p.str();
+    return p.str();
 }
 
-
 OptionResult Options::processOptions()
 {
   // establish locale before showing help (this selects the default locale,
@@ -2254,58 +2257,58 @@ OptionResult Options::processOptions()
   if (envp) {
     globals->append_fg_scenery(envp);
   }
-    
+
+// download dir fix-up
+    string downloadDir = simgear::strutils::strip(fgGetString("/sim/paths/download-dir"));
+    if (downloadDir.empty()) {
+        downloadDir = defaultDownloadDir();
+        SG_LOG(SG_GENERAL, SG_INFO, "Using default download dir: " << downloadDir);
+    } else {
+        simgear::Dir d(downloadDir);
+        if (!d.exists()) {
+            SG_LOG(SG_GENERAL, SG_INFO, "Creating requested download dir: " << downloadDir);
+            d.create(0755);
+        }
+    }
+
 // terrasync directory fixup
     string terrasyncDir = simgear::strutils::strip(fgGetString("/sim/terrasync/scenery-dir"));
   if (terrasyncDir.empty()) {
-         terrasyncDir = defaultTerrasyncDir();
-         // auto-save it for next time
-         
-         SG_LOG(SG_GENERAL, SG_INFO,
-                 "Using default TerraSync: " << terrasyncDir);
-      fgSetString("/sim/terrasync/scenery-dir", terrasyncDir);
-  }
+      SGPath p(downloadDir);
+      p.append("TerraSync");
+      terrasyncDir = p.str();
 
-  SGPath p(terrasyncDir);
+      simgear::Dir d(terrasyncDir);
+      if (!d.exists()) {
+          d.create(0755);
+      }
 
-  // following is necessary to ensure NavDataCache sees stable scenery paths from
-  // terrasync. Ensure the Terrain and Objects subdirs exist immediately, rather
-  // than waiting for the first tiles to be scheduled.
-  simgear::Dir terrainDir(SGPath(p, "Terrain")),
-    objectsDir(SGPath(p, "Objects"));
-  if (!terrainDir.exists()) {
-      terrainDir.create(0755);
-  }
-  
-  if (!objectsDir.exists()) {
-      objectsDir.create(0755);
+         SG_LOG(SG_GENERAL, SG_INFO, "Using default TerraSync: " << terrasyncDir);
+      fgSetString("/sim/terrasync/scenery-dir", p.str());
+  } else {
+      SG_LOG(SG_GENERAL, SG_INFO, "Using explicit TerraSync dir: " << terrasyncDir);
   }
 
-    // check the above actuall worked
-    if (!objectsDir.exists() || !terrainDir.exists()) {
-        std::stringstream ss;
-        ss << "Scenery download will be disabled. The configured location is '" << terrasyncDir << "'.";
-        flightgear::modalMessageBox("Invalid scenery download location",
-                                    "Automatic scenery download is configured to use a location (path) which invalid.",
-                                    ss.str());
-        fgSetBool("/sim/terrasync/enabled", false);
-    }
+    // check if we setup a scenery path so far
+    bool addFGDataScenery = globals->get_fg_scenery().empty();
 
-  if (fgGetBool("/sim/terrasync/enabled")) {
+    // always add the terrasync location, regardless of whether terrasync
+    // is enabled or not. This allows us to toggle terrasync on/off at
+    // runtime and have things work as expected
     const string_list& scenery_paths(globals->get_fg_scenery());
     if (std::find(scenery_paths.begin(), scenery_paths.end(), terrasyncDir) == scenery_paths.end()) {
-      // terrasync dir is not in the scenery paths, add it
-      globals->append_fg_scenery(terrasyncDir);
+        // terrasync dir is not in the scenery paths, add it
+        globals->append_fg_scenery(terrasyncDir);
     }
-  }
-  
-  if (globals->get_fg_scenery().empty()) {
-    // no scenery paths set *at all*, use the data in FG_ROOT
-    SGPath root(globals->get_fg_root());
-    root.append("Scenery");
-    globals->append_fg_scenery(root.str());
-  }
-    
+
+    if (addFGDataScenery) {
+        // no scenery paths set at all, use the data in FG_ROOT
+        // ensure this path is added last
+        SGPath root(globals->get_fg_root());
+        root.append("Scenery");
+        globals->append_fg_scenery(root.str());
+    }
+
   return FG_OPTIONS_OK;
 }
   
index 5fab50fe7e97e11eac924311c0d8f42eb0e63540..a74e1a15bf2d82797cdc982653c667b41a01c564 100644 (file)
@@ -35,6 +35,15 @@ class SGPath;
 namespace flightgear
 {
 
+    /**
+     * return the default platform dependant download directory.
+     * This must be a user-writeable location, the question is if it should
+     * be a user visible location. On Windows we default to a subdir of
+     * Documents (FlightGear), on Unixes we default to FG_HOME, which is
+     * typically invisible.
+     */
+    std::string defaultDownloadDir();
+
 /// option processing can have various result values
 /// depending on what the user requested. Note processOptions only
 /// returns a subset of these.