Work on new download-dir option
- simplify management of a single, user-facing location for large downloaded data.
This commit is contained in:
parent
41ca6bd1de
commit
aa20e0acd8
10 changed files with 744 additions and 150 deletions
|
@ -290,8 +290,6 @@ private:
|
|||
|
||||
emit addedItems();
|
||||
} // of subdir iteration
|
||||
|
||||
qDebug() << "scan of" << path << "took" << t.elapsed();
|
||||
}
|
||||
|
||||
QMutex m_lock;
|
||||
|
|
165
src/GUI/PathsDialog.cxx
Normal file
165
src/GUI/PathsDialog.cxx
Normal file
|
@ -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);
|
||||
}
|
346
src/GUI/PathsDialog.ui
Normal file
346
src/GUI/PathsDialog.ui
Normal file
|
@ -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>
|
|
@ -426,16 +426,84 @@ 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);
|
||||
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()));
|
||||
connect(m_ui->parkingCombo, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(updateAirportDescription()));
|
||||
connect(m_ui->runwayRadio, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateAirportDescription()));
|
||||
connect(m_ui->parkingRadio, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateAirportDescription()));
|
||||
connect(m_ui->onFinalCheckbox, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateAirportDescription()));
|
||||
|
||||
|
||||
connect(m_ui->runButton, SIGNAL(clicked()), this, SLOT(onRun()));
|
||||
connect(m_ui->quitButton, SIGNAL(clicked()), this, SLOT(onQuit()));
|
||||
connect(m_ui->airportEdit, SIGNAL(returnPressed()),
|
||||
this, SLOT(onSearchAirports()));
|
||||
|
||||
connect(m_ui->airportHistory, &QPushButton::clicked,
|
||||
this, &QtLauncher::onPopupAirportHistory);
|
||||
connect(m_ui->aircraftHistory, &QPushButton::clicked,
|
||||
this, &QtLauncher::onPopupAircraftHistory);
|
||||
|
||||
restoreSettings();
|
||||
|
||||
QAction* qa = new QAction(this);
|
||||
qa->setShortcut(QKeySequence("Ctrl+Q"));
|
||||
connect(qa, &QAction::triggered, this, &QtLauncher::onQuit);
|
||||
addAction(qa);
|
||||
|
||||
connect(m_ui->editRatingFilter, &QPushButton::clicked,
|
||||
this, &QtLauncher::onEditRatingsFilter);
|
||||
|
||||
QIcon historyIcon(":/history-icon");
|
||||
m_ui->aircraftHistory->setIcon(historyIcon);
|
||||
m_ui->airportHistory->setIcon(historyIcon);
|
||||
|
||||
m_ui->searchIcon->setPixmap(QPixmap(":/search-icon"));
|
||||
|
||||
connect(m_ui->timeOfDayCombo, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->seasonCombo, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->fetchRealWxrCheckbox, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->rembrandtCheckbox, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->terrasyncCheck, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->startPausedCheck, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->msaaCheckbox, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
|
||||
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,
|
||||
this, &QtLauncher::onAddSceneryPath);
|
||||
connect(m_ui->removeSceneryPath, &QToolButton::clicked,
|
||||
this, &QtLauncher::onRemoveSceneryPath);
|
||||
|
||||
connect(m_ui->addAircraftPath, &QToolButton::clicked,
|
||||
this, &QtLauncher::onAddAircraftPath);
|
||||
connect(m_ui->removeAircraftPath, &QToolButton::clicked,
|
||||
this, &QtLauncher::onRemoveAircraftPath);
|
||||
|
||||
fgInitPackageRoot();
|
||||
simgear::pkg::RootRef r(globals->packageRoot());
|
||||
|
@ -465,81 +533,6 @@ QtLauncher::QtLauncher() :
|
|||
connect(delegate, &AircraftItemDelegate::variantChanged,
|
||||
this, &QtLauncher::onAircraftSelected);
|
||||
|
||||
connect(m_ui->runwayCombo, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(updateAirportDescription()));
|
||||
connect(m_ui->parkingCombo, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(updateAirportDescription()));
|
||||
connect(m_ui->runwayRadio, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateAirportDescription()));
|
||||
connect(m_ui->parkingRadio, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateAirportDescription()));
|
||||
connect(m_ui->onFinalCheckbox, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateAirportDescription()));
|
||||
|
||||
|
||||
connect(m_ui->runButton, SIGNAL(clicked()), this, SLOT(onRun()));
|
||||
connect(m_ui->quitButton, SIGNAL(clicked()), this, SLOT(onQuit()));
|
||||
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,
|
||||
this, &QtLauncher::onPopupAircraftHistory);
|
||||
|
||||
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);
|
||||
addAction(qa);
|
||||
|
||||
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);
|
||||
m_ui->airportHistory->setIcon(historyIcon);
|
||||
|
||||
m_ui->searchIcon->setPixmap(QPixmap(":/search-icon"));
|
||||
|
||||
connect(m_ui->timeOfDayCombo, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->seasonCombo, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->fetchRealWxrCheckbox, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->rembrandtCheckbox, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->terrasyncCheck, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->startPausedCheck, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
connect(m_ui->msaaCheckbox, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateSettingsSummary()));
|
||||
|
||||
connect(m_ui->rembrandtCheckbox, SIGNAL(toggled(bool)),
|
||||
this, SLOT(onRembrandtToggled(bool)));
|
||||
|
||||
updateSettingsSummary();
|
||||
|
||||
connect(m_ui->addSceneryPath, &QToolButton::clicked,
|
||||
this, &QtLauncher::onAddSceneryPath);
|
||||
connect(m_ui->removeSceneryPath, &QToolButton::clicked,
|
||||
this, &QtLauncher::onRemoveSceneryPath);
|
||||
|
||||
connect(m_ui->addAircraftPath, &QToolButton::clicked,
|
||||
this, &QtLauncher::onAddAircraftPath);
|
||||
connect(m_ui->removeAircraftPath, &QToolButton::clicked,
|
||||
this, &QtLauncher::onRemoveAircraftPath);
|
||||
|
||||
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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -67,10 +67,6 @@
|
|||
|
||||
#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
|
||||
|
||||
|
|
|
@ -671,7 +671,8 @@ 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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -231,6 +231,11 @@ 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 )
|
||||
|
@ -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,
|
||||
|
@ -2255,56 +2258,56 @@ OptionResult Options::processOptions()
|
|||
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
|
||||
SGPath p(downloadDir);
|
||||
p.append("TerraSync");
|
||||
terrasyncDir = p.str();
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO,
|
||||
"Using default TerraSync: " << terrasyncDir);
|
||||
fgSetString("/sim/terrasync/scenery-dir", terrasyncDir);
|
||||
simgear::Dir d(terrasyncDir);
|
||||
if (!d.exists()) {
|
||||
d.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);
|
||||
}
|
||||
|
||||
SGPath p(terrasyncDir);
|
||||
// check if we setup a scenery path so far
|
||||
bool addFGDataScenery = globals->get_fg_scenery().empty();
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue