1
0
Fork 0
flightgear/src/GUI/PathsDialog.cxx
Florent Rougon 9eb56fc9f1 Add tooltips in built-in launcher: remind to restart after changing scenery paths
Maybe this won't be necessary anymore in the future, but for now it is.
2016-10-17 12:10:03 +01:00

379 lines
12 KiB
C++

#include "PathsDialog.hxx"
#include "ui_PathsDialog.h"
#include <QSettings>
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>
#include <QProcess>
#include "CatalogListModel.hxx"
#include "AddCatalogDialog.hxx"
#include "AircraftModel.hxx"
#include "QtLauncher_private.hxx"
#include "InstallSceneryDialog.hxx"
#include <Main/options.hxx>
#include <Main/globals.hxx>
#include <Network/HTTPClient.hxx>
AddOnsPage::AddOnsPage(QWidget *parent, simgear::pkg::RootRef root) :
QWidget(parent),
m_ui(new Ui::AddOnsPage),
m_packageRoot(root)
{
m_ui->setupUi(this);
m_catalogsModel = new CatalogListModel(this, m_packageRoot);
m_ui->catalogsList->setModel(m_catalogsModel);
// enable drag-drop to re-order the paths
m_ui->sceneryPathsList->setDragEnabled(true);
m_ui->sceneryPathsList->setDragDropMode(QAbstractItemView::InternalMove);
m_ui->sceneryPathsList->setDropIndicatorShown(true);
m_ui->aircraftPathsList->setDragEnabled(true);
m_ui->aircraftPathsList->setDragDropMode(QAbstractItemView::InternalMove);
m_ui->aircraftPathsList->setDropIndicatorShown(true);
connect(m_ui->addCatalog, &QToolButton::clicked,
this, &AddOnsPage::onAddCatalog);
connect(m_ui->addDefaultCatalogButton, &QPushButton::clicked,
this, &AddOnsPage::onAddDefaultCatalog);
connect(m_ui->removeCatalog, &QToolButton::clicked,
this, &AddOnsPage::onRemoveCatalog);
connect(m_ui->addSceneryPath, &QToolButton::clicked,
this, &AddOnsPage::onAddSceneryPath);
connect(m_ui->removeSceneryPath, &QToolButton::clicked,
this, &AddOnsPage::onRemoveSceneryPath);
connect(m_ui->addAircraftPath, &QToolButton::clicked,
this, &AddOnsPage::onAddAircraftPath);
connect(m_ui->removeAircraftPath, &QToolButton::clicked,
this, &AddOnsPage::onRemoveAircraftPath);
connect(m_ui->changeDownloadDir, &QPushButton::clicked,
this, &AddOnsPage::onChangeDownloadDir);
connect(m_ui->clearDownloadDir, &QPushButton::clicked,
this, &AddOnsPage::onClearDownloadDir);
connect(m_ui->changeDataDir, &QPushButton::clicked,
this, &AddOnsPage::onChangeDataDir);
connect(m_ui->installSceneryButton, &QPushButton::clicked,
this, &AddOnsPage::onInstallScenery);
m_ui->sceneryPathsList->setToolTip(
tr("After changing this list, please restart the launcher to avoid "
"possibly inconsistent behavior."));
m_ui->changeDownloadDir->setToolTip(
tr("After changing this location, you may have to restart the launcher "
"to avoid inconsistent behavior."));
m_ui->clearDownloadDir->setToolTip(
tr("If you use this button, you may have to restart the launcher "
"to avoid inconsistent behavior."));
m_ui->installSceneryButton->setToolTip(
tr("After installing scenery, you may have to restart the launcher "
"to avoid inconsistent behavior."));
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();
}
AddOnsPage::~AddOnsPage()
{
delete m_ui;
}
void AddOnsPage::onAddSceneryPath()
{
QString path = QFileDialog::getExistingDirectory(this, tr("Choose scenery folder"));
if (!path.isEmpty()) {
m_ui->sceneryPathsList->addItem(path);
saveSceneryPaths();
}
// work around a Qt OS-X bug - this dialog is ending ordered
// behind the main settings dialog (consequence of modal-dialog
// showing a modla dialog showing a modial dialog)
window()->raise();
}
void AddOnsPage::onRemoveSceneryPath()
{
if (m_ui->sceneryPathsList->currentItem()) {
delete m_ui->sceneryPathsList->currentItem();
saveSceneryPaths();
}
}
void AddOnsPage::onAddAircraftPath()
{
QString path = QFileDialog::getExistingDirectory(this, tr("Choose aircraft folder"));
if (!path.isEmpty()) {
// the user might add a directory containing an 'Aircraft' subdir. Let's attempt
// to check for that case and handle it gracefully.
bool pathOk = false;
if (AircraftItemModel::isCandidateAircraftPath(path)) {
m_ui->aircraftPathsList->addItem(path);
pathOk = true;
} else {
// no aircraft in speciied path, look for Aircraft/ subdir
QDir d(path);
if (d.exists("Aircraft")) {
QString p2 = d.filePath("Aircraft");
if (AircraftItemModel::isCandidateAircraftPath(p2)) {
m_ui->aircraftPathsList->addItem(p2);
pathOk = true;
}
}
}
if (!pathOk) {
QMessageBox mb;
mb.setText(QString("No aircraft found in the folder '%1' - add anyway?").arg(path));
mb.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
mb.setDefaultButton(QMessageBox::No);
mb.exec();
if (mb.result() == QMessageBox::Yes) {
m_ui->aircraftPathsList->addItem(path);
}
}
saveAircraftPaths();
}
// work around a Qt OS-X bug - this dialog is ending ordered
// behind the main settings dialog (consequence of modal-dialog
// showing a modla dialog showing a modial dialog)
window()->raise();
}
void AddOnsPage::onRemoveAircraftPath()
{
if (m_ui->aircraftPathsList->currentItem()) {
delete m_ui->aircraftPathsList->currentItem();
saveAircraftPaths();
}
}
void AddOnsPage::saveAircraftPaths()
{
QSettings settings;
QStringList paths;
for (int i=0; i<m_ui->aircraftPathsList->count(); ++i) {
paths.append(m_ui->aircraftPathsList->item(i)->text());
}
settings.setValue("aircraft-paths", paths);
}
void AddOnsPage::saveSceneryPaths()
{
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);
emit sceneryPathsChanged();
}
bool AddOnsPage::haveSceneryPath(QString path) const
{
for (int i=0; i<m_ui->sceneryPathsList->count(); ++i) {
if (m_ui->sceneryPathsList->item(i)->text() == path) {
return true;
}
}
return false;
}
void AddOnsPage::onAddCatalog()
{
QScopedPointer<AddCatalogDialog> dlg(new AddCatalogDialog(this, m_packageRoot));
dlg->exec();
if (dlg->result() == QDialog::Accepted) {
m_catalogsModel->refresh();
}
}
void AddOnsPage::onAddDefaultCatalog()
{
addDefaultCatalog(this);
m_catalogsModel->refresh();
updateUi();
}
void AddOnsPage::addDefaultCatalog(QWidget* pr)
{
// check it's not a duplicate somehow
FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
if (http->isDefaultCatalogInstalled())
return;
QScopedPointer<AddCatalogDialog> dlg(new AddCatalogDialog(pr, globals->packageRoot()));
QUrl url(QString::fromStdString(http->getDefaultCatalogUrl()));
dlg->setUrlAndDownload(url);
dlg->exec();
}
void AddOnsPage::onRemoveCatalog()
{
QModelIndex mi = m_ui->catalogsList->currentIndex();
FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
if (mi.isValid()) {
QString s = QString("Remove aircraft hangar '%1'? All installed aircraft from this "
"hangar will be removed.");
QString pkgId = mi.data(CatalogIdRole).toString();
if (pkgId.toStdString() == http->getDefaultCatalogId()) {
s = QString("Remove the default aircraft hangar? "
"This hangar contains all the default aircraft included with FlightGear. "
"If you change your mind in the future, click the 'restore' button.");
} else {
s = s.arg(mi.data(Qt::DisplayRole).toString());
}
QMessageBox mb;
mb.setText(s);
mb.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
mb.setDefaultButton(QMessageBox::No);
mb.exec();
if (mb.result() == QMessageBox::Yes) {
m_packageRoot->removeCatalogById(pkgId.toStdString());
}
}
updateUi();
}
void AddOnsPage::onChangeDownloadDir()
{
QString path = QFileDialog::getExistingDirectory(this,
tr("Choose downloads folder"),
m_downloadDir);
if (path.isEmpty()) {
return; // user cancelled
}
m_downloadDir = path;
setDownloadDir();
}
void AddOnsPage::onClearDownloadDir()
{
// does this need an 'are you sure'?
m_downloadDir.clear();
setDownloadDir();
}
void AddOnsPage::setDownloadDir()
{
QSettings settings;
if (m_downloadDir.isEmpty()) {
settings.remove("download-dir");
} else {
settings.setValue("download-dir", m_downloadDir);
}
if (m_downloadDir.isEmpty()) {
flightgear::Options::sharedInstance()->clearOption("download-dir");
} else {
flightgear::Options::sharedInstance()->setOption("download-dir", m_downloadDir.toStdString());
}
emit downloadDirChanged();
updateUi();
}
void AddOnsPage::onChangeDataDir()
{
QMessageBox mbox(this);
mbox.setText(tr("Change the data files used by FlightGear?"));
mbox.setInformativeText(tr("FlightGear requires additional files to operate. "
"(Also called the base package, or fg-data) "
"You can restart FlightGear and choose a "
"different data files location, or restore the default setting."));
QPushButton* quitButton = mbox.addButton(tr("Restart FlightGear now"), QMessageBox::YesRole);
mbox.addButton(QMessageBox::Cancel);
mbox.setDefaultButton(QMessageBox::Cancel);
mbox.setIconPixmap(QPixmap(":/app-icon-large"));
mbox.exec();
if (mbox.clickedButton() != quitButton) {
return;
}
{
QSettings settings;
// set the option to the magic marker value
settings.setValue("fg-root", "!ask");
} // scope the ensure settings are written nicely
QtLauncher::restartTheApp(QStringList());
}
void AddOnsPage::onInstallScenery()
{
InstallSceneryDialog dlg(this, m_downloadDir);
if (dlg.exec() == QDialog::Accepted) {
if (!haveSceneryPath(dlg.sceneryPath())) {
m_ui->sceneryPathsList->addItem(dlg.sceneryPath());
saveSceneryPaths();
}
}
}
void AddOnsPage::updateUi()
{
QString s = m_downloadDir;
if (s.isEmpty()) {
s = QString::fromStdString(flightgear::defaultDownloadDir().utf8Str());
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);
QString dataLoc;
QSettings settings;
QString root = settings.value("fg-root").toString();
if (root.isNull()) {
dataLoc = tr("built-in");
} else {
dataLoc = root;
}
m_ui->dataLocation->setText(tr("Data location: %1").arg(dataLoc));
FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
m_ui->addDefaultCatalogButton->setEnabled(!http->isDefaultCatalogInstalled());
}