Restructure paths handling in the launcher
- move the dialog into a new ‘add-ons’ tab - separate out ‘restore settings’ from selecting a new fg-data - actually relaunch the app
This commit is contained in:
parent
f837f1e808
commit
5341d327fd
7 changed files with 297 additions and 245 deletions
|
@ -269,6 +269,16 @@
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>8</number>
|
<number>8</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<widget class="QPushButton" name="restoreDefaultsButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Restore Defaults...</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
|
@ -442,7 +452,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0" colspan="2">
|
<item row="7" column="0" colspan="2">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Additional options</string>
|
<string>Additional options</string>
|
||||||
|
@ -470,7 +480,7 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0">
|
<item row="6" column="0">
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
|
@ -483,23 +493,6 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QPushButton" name="pathsButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Configure add-on aircraft and scenery…</string>
|
|
||||||
</property>
|
|
||||||
<property name="startupOnly" stdset="0">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QPushButton" name="changeRootButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Change data files location…</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -537,6 +530,9 @@
|
||||||
<property name="autoDefault">
|
<property name="autoDefault">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -4,18 +4,21 @@
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
#include "CatalogListModel.hxx"
|
#include "CatalogListModel.hxx"
|
||||||
#include "AddCatalogDialog.hxx"
|
#include "AddCatalogDialog.hxx"
|
||||||
#include "AircraftModel.hxx"
|
#include "AircraftModel.hxx"
|
||||||
|
#include "QtLauncher_private.hxx"
|
||||||
|
|
||||||
#include <Main/options.hxx>
|
#include <Main/options.hxx>
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Network/HTTPClient.hxx>
|
#include <Network/HTTPClient.hxx>
|
||||||
|
|
||||||
PathsDialog::PathsDialog(QWidget *parent, simgear::pkg::RootRef root) :
|
AddOnsPage::AddOnsPage(QWidget *parent, simgear::pkg::RootRef root) :
|
||||||
QDialog(parent),
|
QWidget(parent),
|
||||||
m_ui(new Ui::PathsDialog),
|
m_ui(new Ui::AddOnsPage),
|
||||||
m_packageRoot(root)
|
m_packageRoot(root)
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
@ -33,27 +36,30 @@ PathsDialog::PathsDialog(QWidget *parent, simgear::pkg::RootRef root) :
|
||||||
m_ui->aircraftPathsList->setDropIndicatorShown(true);
|
m_ui->aircraftPathsList->setDropIndicatorShown(true);
|
||||||
|
|
||||||
connect(m_ui->addCatalog, &QToolButton::clicked,
|
connect(m_ui->addCatalog, &QToolButton::clicked,
|
||||||
this, &PathsDialog::onAddCatalog);
|
this, &AddOnsPage::onAddCatalog);
|
||||||
connect(m_ui->addDefaultCatalogButton, &QPushButton::clicked,
|
connect(m_ui->addDefaultCatalogButton, &QPushButton::clicked,
|
||||||
this, &PathsDialog::onAddDefaultCatalog);
|
this, &AddOnsPage::onAddDefaultCatalog);
|
||||||
connect(m_ui->removeCatalog, &QToolButton::clicked,
|
connect(m_ui->removeCatalog, &QToolButton::clicked,
|
||||||
this, &PathsDialog::onRemoveCatalog);
|
this, &AddOnsPage::onRemoveCatalog);
|
||||||
|
|
||||||
connect(m_ui->addSceneryPath, &QToolButton::clicked,
|
connect(m_ui->addSceneryPath, &QToolButton::clicked,
|
||||||
this, &PathsDialog::onAddSceneryPath);
|
this, &AddOnsPage::onAddSceneryPath);
|
||||||
connect(m_ui->removeSceneryPath, &QToolButton::clicked,
|
connect(m_ui->removeSceneryPath, &QToolButton::clicked,
|
||||||
this, &PathsDialog::onRemoveSceneryPath);
|
this, &AddOnsPage::onRemoveSceneryPath);
|
||||||
|
|
||||||
connect(m_ui->addAircraftPath, &QToolButton::clicked,
|
connect(m_ui->addAircraftPath, &QToolButton::clicked,
|
||||||
this, &PathsDialog::onAddAircraftPath);
|
this, &AddOnsPage::onAddAircraftPath);
|
||||||
connect(m_ui->removeAircraftPath, &QToolButton::clicked,
|
connect(m_ui->removeAircraftPath, &QToolButton::clicked,
|
||||||
this, &PathsDialog::onRemoveAircraftPath);
|
this, &AddOnsPage::onRemoveAircraftPath);
|
||||||
|
|
||||||
connect(m_ui->changeDownloadDir, &QPushButton::clicked,
|
connect(m_ui->changeDownloadDir, &QPushButton::clicked,
|
||||||
this, &PathsDialog::onChangeDownloadDir);
|
this, &AddOnsPage::onChangeDownloadDir);
|
||||||
|
|
||||||
connect(m_ui->clearDownloadDir, &QPushButton::clicked,
|
connect(m_ui->clearDownloadDir, &QPushButton::clicked,
|
||||||
this, &PathsDialog::onClearDownloadDir);
|
this, &AddOnsPage::onClearDownloadDir);
|
||||||
|
|
||||||
|
connect(m_ui->changeDataDir, &QPushButton::clicked,
|
||||||
|
this, &AddOnsPage::onChangeDataDir);
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
|
@ -71,42 +77,17 @@ PathsDialog::PathsDialog(QWidget *parent, simgear::pkg::RootRef root) :
|
||||||
updateUi();
|
updateUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
PathsDialog::~PathsDialog()
|
AddOnsPage::~AddOnsPage()
|
||||||
{
|
{
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::accept()
|
void AddOnsPage::onAddSceneryPath()
|
||||||
{
|
|
||||||
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"));
|
QString path = QFileDialog::getExistingDirectory(this, tr("Choose scenery folder"));
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
m_ui->sceneryPathsList->addItem(path);
|
m_ui->sceneryPathsList->addItem(path);
|
||||||
|
saveSceneryPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
// work around a Qt OS-X bug - this dialog is ending ordered
|
// work around a Qt OS-X bug - this dialog is ending ordered
|
||||||
|
@ -115,14 +96,15 @@ void PathsDialog::onAddSceneryPath()
|
||||||
window()->raise();
|
window()->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::onRemoveSceneryPath()
|
void AddOnsPage::onRemoveSceneryPath()
|
||||||
{
|
{
|
||||||
if (m_ui->sceneryPathsList->currentItem()) {
|
if (m_ui->sceneryPathsList->currentItem()) {
|
||||||
delete m_ui->sceneryPathsList->currentItem();
|
delete m_ui->sceneryPathsList->currentItem();
|
||||||
|
saveSceneryPaths();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::onAddAircraftPath()
|
void AddOnsPage::onAddAircraftPath()
|
||||||
{
|
{
|
||||||
QString path = QFileDialog::getExistingDirectory(this, tr("Choose aircraft folder"));
|
QString path = QFileDialog::getExistingDirectory(this, tr("Choose aircraft folder"));
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
|
@ -156,6 +138,8 @@ void PathsDialog::onAddAircraftPath()
|
||||||
m_ui->aircraftPathsList->addItem(path);
|
m_ui->aircraftPathsList->addItem(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveAircraftPaths();
|
||||||
}
|
}
|
||||||
// work around a Qt OS-X bug - this dialog is ending ordered
|
// work around a Qt OS-X bug - this dialog is ending ordered
|
||||||
// behind the main settings dialog (consequence of modal-dialog
|
// behind the main settings dialog (consequence of modal-dialog
|
||||||
|
@ -163,14 +147,40 @@ void PathsDialog::onAddAircraftPath()
|
||||||
window()->raise();
|
window()->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::onRemoveAircraftPath()
|
void AddOnsPage::onRemoveAircraftPath()
|
||||||
{
|
{
|
||||||
if (m_ui->aircraftPathsList->currentItem()) {
|
if (m_ui->aircraftPathsList->currentItem()) {
|
||||||
delete m_ui->aircraftPathsList->currentItem();
|
delete m_ui->aircraftPathsList->currentItem();
|
||||||
|
saveAircraftPaths();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::onAddCatalog()
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddOnsPage::onAddCatalog()
|
||||||
{
|
{
|
||||||
QScopedPointer<AddCatalogDialog> dlg(new AddCatalogDialog(this, m_packageRoot));
|
QScopedPointer<AddCatalogDialog> dlg(new AddCatalogDialog(this, m_packageRoot));
|
||||||
dlg->exec();
|
dlg->exec();
|
||||||
|
@ -179,7 +189,7 @@ void PathsDialog::onAddCatalog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::onAddDefaultCatalog()
|
void AddOnsPage::onAddDefaultCatalog()
|
||||||
{
|
{
|
||||||
// check it's not a duplicate somehow
|
// check it's not a duplicate somehow
|
||||||
FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
|
FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
|
||||||
|
@ -196,7 +206,7 @@ void PathsDialog::onAddDefaultCatalog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::onRemoveCatalog()
|
void AddOnsPage::onRemoveCatalog()
|
||||||
{
|
{
|
||||||
QModelIndex mi = m_ui->catalogsList->currentIndex();
|
QModelIndex mi = m_ui->catalogsList->currentIndex();
|
||||||
FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
|
FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
|
||||||
|
@ -228,25 +238,74 @@ void PathsDialog::onRemoveCatalog()
|
||||||
updateUi();
|
updateUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::onChangeDownloadDir()
|
void AddOnsPage::onChangeDownloadDir()
|
||||||
{
|
{
|
||||||
QString path = QFileDialog::getExistingDirectory(this,
|
QString path = QFileDialog::getExistingDirectory(this,
|
||||||
tr("Choose downloads folder"),
|
tr("Choose downloads folder"),
|
||||||
m_downloadDir);
|
m_downloadDir);
|
||||||
if (!path.isEmpty()) {
|
if (path.isEmpty()) {
|
||||||
m_downloadDir = path;
|
return; // user cancelled
|
||||||
updateUi();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_downloadDir = path;
|
||||||
|
setDownloadDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::onClearDownloadDir()
|
void AddOnsPage::onClearDownloadDir()
|
||||||
{
|
{
|
||||||
// does this need an 'are you sure'?
|
// does this need an 'are you sure'?
|
||||||
m_downloadDir.clear();
|
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();
|
updateUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathsDialog::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::updateUi()
|
||||||
{
|
{
|
||||||
QString s = m_downloadDir;
|
QString s = m_downloadDir;
|
||||||
if (s.isEmpty()) {
|
if (s.isEmpty()) {
|
||||||
|
@ -260,6 +319,18 @@ void PathsDialog::updateUi()
|
||||||
QString m = tr("Download location: %1").arg(s);
|
QString m = tr("Download location: %1").arg(s);
|
||||||
m_ui->downloadLocation->setText(m);
|
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>();
|
FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
|
||||||
m_ui->addDefaultCatalogButton->setEnabled(!http->isDefaultCatalogInstalled());
|
m_ui->addDefaultCatalogButton->setEnabled(!http->isDefaultCatalogInstalled());
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,21 +7,22 @@
|
||||||
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class PathsDialog;
|
class AddOnsPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CatalogListModel;
|
class CatalogListModel;
|
||||||
|
|
||||||
class PathsDialog : public QDialog
|
class AddOnsPage : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PathsDialog(QWidget *parent, simgear::pkg::RootRef root);
|
explicit AddOnsPage(QWidget *parent, simgear::pkg::RootRef root);
|
||||||
~PathsDialog();
|
~AddOnsPage();
|
||||||
|
|
||||||
protected:
|
signals:
|
||||||
virtual void accept();
|
void downloadDirChanged();
|
||||||
|
void sceneryPathsChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAddSceneryPath();
|
void onAddSceneryPath();
|
||||||
|
@ -36,10 +37,16 @@ private slots:
|
||||||
|
|
||||||
void onChangeDownloadDir();
|
void onChangeDownloadDir();
|
||||||
void onClearDownloadDir();
|
void onClearDownloadDir();
|
||||||
|
|
||||||
|
void onChangeDataDir();
|
||||||
private:
|
private:
|
||||||
void updateUi();
|
void updateUi();
|
||||||
|
void setDownloadDir();
|
||||||
|
|
||||||
Ui::PathsDialog* m_ui;
|
void saveAircraftPaths();
|
||||||
|
void saveSceneryPaths();
|
||||||
|
|
||||||
|
Ui::AddOnsPage* m_ui;
|
||||||
CatalogListModel* m_catalogsModel;
|
CatalogListModel* m_catalogsModel;
|
||||||
simgear::pkg::RootRef m_packageRoot;
|
simgear::pkg::RootRef m_packageRoot;
|
||||||
QString m_downloadDir;
|
QString m_downloadDir;
|
||||||
|
|
|
@ -1,19 +1,63 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>PathsDialog</class>
|
<class>AddOnsPage</class>
|
||||||
<widget class="QDialog" name="PathsDialog">
|
<widget class="QWidget" name="AddOnsPage">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>600</width>
|
<width>608</width>
|
||||||
<height>600</height>
|
<height>617</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Configure add-ons</string>
|
<string>Configure add-ons</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="dataLocation">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1,0">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>FlightGear needs certain files (sometimes called 'fg-data') to function - these are included as part of stable releases.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="changeDataDir">
|
||||||
|
<property name="text">
|
||||||
|
<string>Change...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="downloadLocation">
|
<widget class="QLabel" name="downloadLocation">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -22,20 +66,30 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0">
|
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,0,0">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>40</width>
|
<width>16</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="changeDownloadDir">
|
<widget class="QPushButton" name="changeDownloadDir">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -46,22 +100,12 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="clearDownloadDir">
|
<widget class="QPushButton" name="clearDownloadDir">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use default location</string>
|
<string>Use default</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<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>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -317,51 +361,8 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<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>
|
</ui>
|
||||||
|
|
|
@ -360,14 +360,8 @@ void initApp(int& argc, char** argv)
|
||||||
Qt::KeyboardModifiers mods = app->queryKeyboardModifiers();
|
Qt::KeyboardModifiers mods = app->queryKeyboardModifiers();
|
||||||
if (mods & (Qt::AltModifier | Qt::ShiftModifier)) {
|
if (mods & (Qt::AltModifier | Qt::ShiftModifier)) {
|
||||||
qWarning() << "Alt/shift pressed during launch";
|
qWarning() << "Alt/shift pressed during launch";
|
||||||
|
|
||||||
// wipe out our settings
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.clear();
|
|
||||||
|
|
||||||
settings.setValue("fg-root", "!ask");
|
settings.setValue("fg-root", "!ask");
|
||||||
|
|
||||||
Options::sharedInstance()->addOption("restore-defaults", "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -504,8 +498,6 @@ QtLauncher::QtLauncher() :
|
||||||
connect(m_ui->runButton, SIGNAL(clicked()), this, SLOT(onRun()));
|
connect(m_ui->runButton, SIGNAL(clicked()), this, SLOT(onRun()));
|
||||||
connect(m_ui->quitButton, SIGNAL(clicked()), this, SLOT(onQuit()));
|
connect(m_ui->quitButton, SIGNAL(clicked()), this, SLOT(onQuit()));
|
||||||
|
|
||||||
connect(m_ui->changeRootButton, SIGNAL(clicked()), this, SLOT(onChangeRoot()));
|
|
||||||
|
|
||||||
connect(m_ui->aircraftHistory, &QPushButton::clicked,
|
connect(m_ui->aircraftHistory, &QPushButton::clicked,
|
||||||
this, &QtLauncher::onPopupAircraftHistory);
|
this, &QtLauncher::onPopupAircraftHistory);
|
||||||
|
|
||||||
|
@ -574,9 +566,17 @@ QtLauncher::QtLauncher() :
|
||||||
this, &QtLauncher::onAircraftInstallFailed);
|
this, &QtLauncher::onAircraftInstallFailed);
|
||||||
connect(m_aircraftModel, &AircraftItemModel::scanCompleted,
|
connect(m_aircraftModel, &AircraftItemModel::scanCompleted,
|
||||||
this, &QtLauncher::updateSelectedAircraft);
|
this, &QtLauncher::updateSelectedAircraft);
|
||||||
connect(m_ui->pathsButton, &QPushButton::clicked,
|
connect(m_ui->restoreDefaultsButton, &QPushButton::clicked,
|
||||||
this, &QtLauncher::onEditPaths);
|
this, &QtLauncher::onRestoreDefaults);
|
||||||
|
|
||||||
|
|
||||||
|
AddOnsPage* addOnsPage = new AddOnsPage(NULL, globals->packageRoot());
|
||||||
|
connect(addOnsPage, &AddOnsPage::downloadDirChanged,
|
||||||
|
this, &QtLauncher::onDownloadDirChanged);
|
||||||
|
connect(addOnsPage, &AddOnsPage::sceneryPathsChanged,
|
||||||
|
this, &QtLauncher::setSceneryPaths);
|
||||||
|
|
||||||
|
m_ui->tabWidget->addTab(addOnsPage, tr("Add-ons"));
|
||||||
// after any kind of reset, try to restore selection and scroll
|
// after any kind of reset, try to restore selection and scroll
|
||||||
// to match the m_selectedAircraft. This needs to be delayed
|
// to match the m_selectedAircraft. This needs to be delayed
|
||||||
// fractionally otherwise the scrollTo seems to be ignored,
|
// fractionally otherwise the scrollTo seems to be ignored,
|
||||||
|
@ -842,6 +842,11 @@ void QtLauncher::onRun()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.contains("restore-defaults-on-run")) {
|
||||||
|
settings.remove("restore-defaults-on-run");
|
||||||
|
opt->addOption("restore-defaults", "");
|
||||||
|
}
|
||||||
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
qApp->exit(0);
|
qApp->exit(0);
|
||||||
|
@ -905,12 +910,9 @@ void QtLauncher::onToggleTerrasync(bool enabled)
|
||||||
if (!info.exists()) {
|
if (!info.exists()) {
|
||||||
QMessageBox msg;
|
QMessageBox msg;
|
||||||
msg.setWindowTitle(tr("Create download folder?"));
|
msg.setWindowTitle(tr("Create download folder?"));
|
||||||
msg.setText(tr("The download folder '%1' does not exist, create it now? "
|
msg.setText(tr("The download folder '%1' does not exist, create it now?").arg(downloadDir));
|
||||||
"Click 'change location' to choose another folder "
|
|
||||||
"to store downloaded files").arg(downloadDir));
|
|
||||||
msg.addButton(QMessageBox::Yes);
|
msg.addButton(QMessageBox::Yes);
|
||||||
msg.addButton(QMessageBox::Cancel);
|
msg.addButton(QMessageBox::Cancel);
|
||||||
msg.addButton(tr("Change location"), QMessageBox::ActionRole);
|
|
||||||
int result = msg.exec();
|
int result = msg.exec();
|
||||||
|
|
||||||
if (result == QMessageBox::Cancel) {
|
if (result == QMessageBox::Cancel) {
|
||||||
|
@ -918,11 +920,6 @@ void QtLauncher::onToggleTerrasync(bool enabled)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == QMessageBox::ActionRole) {
|
|
||||||
onEditPaths();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDir d(downloadDir);
|
QDir d(downloadDir);
|
||||||
d.mkpath(downloadDir);
|
d.mkpath(downloadDir);
|
||||||
}
|
}
|
||||||
|
@ -989,6 +986,30 @@ void QtLauncher::onCancelDownload(const QModelIndex& index)
|
||||||
i->cancelDownload();
|
i->cancelDownload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtLauncher::onRestoreDefaults()
|
||||||
|
{
|
||||||
|
QMessageBox mbox(this);
|
||||||
|
mbox.setText(tr("Restore all settings to defaults?"));
|
||||||
|
mbox.setInformativeText(tr("Restoring settings to their defaults may affect available add-ons such as scenery or aircraft."));
|
||||||
|
QPushButton* quitButton = mbox.addButton(tr("Restore and restart 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;
|
||||||
|
settings.clear();
|
||||||
|
settings.setValue("restore-defaults-on-run", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
restartTheApp(QStringList());
|
||||||
|
}
|
||||||
|
|
||||||
void QtLauncher::maybeUpdateSelectedAircraft(QModelIndex index)
|
void QtLauncher::maybeUpdateSelectedAircraft(QModelIndex index)
|
||||||
{
|
{
|
||||||
QUrl u = index.data(AircraftURIRole).toUrl();
|
QUrl u = index.data(AircraftURIRole).toUrl();
|
||||||
|
@ -1136,91 +1157,25 @@ void QtLauncher::onSubsytemIdleTimeout()
|
||||||
globals->get_subsystem_mgr()->update(0.0);
|
globals->get_subsystem_mgr()->update(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtLauncher::onEditPaths()
|
void QtLauncher::onDownloadDirChanged()
|
||||||
{
|
{
|
||||||
|
// replace existing package root
|
||||||
|
globals->get_subsystem<FGHTTPClient>()->shutdown();
|
||||||
|
globals->setPackageRoot(simgear::pkg::RootRef());
|
||||||
|
|
||||||
|
// create new root with updated download-dir value
|
||||||
|
fgInitPackageRoot();
|
||||||
|
|
||||||
|
globals->get_subsystem<FGHTTPClient>()->init();
|
||||||
|
|
||||||
|
// re-scan the aircraft list
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
QString previousDownloadDir = settings.value("download-dir").toString();
|
m_aircraftModel->setPackageRoot(globals->packageRoot());
|
||||||
|
m_aircraftModel->setPaths(settings.value("aircraft-paths").toStringList());
|
||||||
|
m_aircraftModel->scanDirs();
|
||||||
|
|
||||||
PathsDialog dlg(this, globals->packageRoot());
|
// re-set scenery dirs
|
||||||
dlg.exec();
|
setSceneryPaths();
|
||||||
if (dlg.result() == QDialog::Accepted) {
|
|
||||||
QString dd = settings.value("download-dir").toString();
|
|
||||||
bool downloadDirChanged = (previousDownloadDir != dd);
|
|
||||||
if (downloadDirChanged) {
|
|
||||||
qDebug() << "download dir changed, resetting package root";
|
|
||||||
|
|
||||||
if (dd.isEmpty()) {
|
|
||||||
flightgear::Options::sharedInstance()->clearOption("download-dir");
|
|
||||||
} else {
|
|
||||||
flightgear::Options::sharedInstance()->setOption("download-dir", dd.toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace existing package root
|
|
||||||
globals->get_subsystem<FGHTTPClient>()->shutdown();
|
|
||||||
globals->setPackageRoot(simgear::pkg::RootRef());
|
|
||||||
|
|
||||||
// create new root with updated download-dir value
|
|
||||||
fgInitPackageRoot();
|
|
||||||
|
|
||||||
globals->get_subsystem<FGHTTPClient>()->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
// re-scan the aircraft list
|
|
||||||
m_aircraftModel->setPackageRoot(globals->packageRoot());
|
|
||||||
m_aircraftModel->setPaths(settings.value("aircraft-paths").toStringList());
|
|
||||||
m_aircraftModel->scanDirs();
|
|
||||||
|
|
||||||
// re-set scenery dirs
|
|
||||||
setSceneryPaths();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QtLauncher::onChangeRoot()
|
|
||||||
{
|
|
||||||
QMessageBox mbox(this);
|
|
||||||
mbox.setText(tr("Change the data files location used by FlightGear?"));
|
|
||||||
mbox.setInformativeText(tr("FlightGear cannot work without its data files. "
|
|
||||||
"(Also called the base package) "
|
|
||||||
"To change which files are used, quit FlightGear and open it again, "
|
|
||||||
"while holding down the 'shift' key, and you will be able to choose a "
|
|
||||||
"different data files location, or restore the default setting."));
|
|
||||||
QPushButton* quitButton = mbox.addButton(tr("Quit 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// following code doesn't work reliably, so we take the simpler
|
|
||||||
// option of asking the user to re-launch us while holding down
|
|
||||||
// the hot-key (shift)
|
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
QSettings settings;
|
|
||||||
// set the option to the magic marker value
|
|
||||||
settings.setValue("fg-root", "!ask");
|
|
||||||
} // scope the ensure settings are written nicel
|
|
||||||
|
|
||||||
// Spawn a new instance of myApplication:
|
|
||||||
QProcess proc;
|
|
||||||
#if defined(Q_OS_MAC)
|
|
||||||
QStringList args;
|
|
||||||
|
|
||||||
QDir dir(qApp->applicationDirPath()); // returns the 'MacOS' dir
|
|
||||||
dir.cdUp(); // up to 'contents' dir
|
|
||||||
dir.cdUp(); // up to .app dir
|
|
||||||
args << dir.absolutePath();
|
|
||||||
proc.startDetached("open", args);
|
|
||||||
#else
|
|
||||||
proc.startDetached(qApp->applicationFilePath());
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
qDebug() << "doing app exit";
|
|
||||||
qApp->exit(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
simgear::pkg::PackageRef QtLauncher::packageForAircraftURI(QUrl uri) const
|
simgear::pkg::PackageRef QtLauncher::packageForAircraftURI(QUrl uri) const
|
||||||
|
@ -1234,5 +1189,26 @@ simgear::pkg::PackageRef QtLauncher::packageForAircraftURI(QUrl uri) const
|
||||||
return globals->packageRoot()->getPackageById(ident.toStdString());
|
return globals->packageRoot()->getPackageById(ident.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtLauncher::restartTheApp(QStringList fgArgs)
|
||||||
|
{
|
||||||
|
// Spawn a new instance of myApplication:
|
||||||
|
QProcess proc;
|
||||||
|
QStringList args;
|
||||||
|
|
||||||
|
#if defined(Q_OS_MAC)
|
||||||
|
QDir dir(qApp->applicationDirPath()); // returns the 'MacOS' dir
|
||||||
|
dir.cdUp(); // up to 'contents' dir
|
||||||
|
dir.cdUp(); // up to .app dir
|
||||||
|
// see 'man open' for details, but '-n' ensures we launch a new instance,
|
||||||
|
// and we want to pass remaining arguments to us, not open.
|
||||||
|
args << "-n" << dir.absolutePath() << "--args" << "--launcher" << fgArgs;
|
||||||
|
qDebug() << "args" << args;
|
||||||
|
proc.startDetached("open", args);
|
||||||
|
#else
|
||||||
|
args << "--launcher" << fgArgs;
|
||||||
|
proc.startDetached(qApp->applicationFilePath(), args);
|
||||||
|
#endif
|
||||||
|
qApp->exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
#include "QtLauncher.moc"
|
#include "QtLauncher.moc"
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
|
|
||||||
void setSceneryPaths();
|
void setSceneryPaths();
|
||||||
|
|
||||||
|
static void restartTheApp(QStringList fgArgs);
|
||||||
protected:
|
protected:
|
||||||
virtual void closeEvent(QCloseEvent *event);
|
virtual void closeEvent(QCloseEvent *event);
|
||||||
|
|
||||||
|
@ -85,9 +86,6 @@ private slots:
|
||||||
|
|
||||||
void onSubsytemIdleTimeout();
|
void onSubsytemIdleTimeout();
|
||||||
|
|
||||||
void onEditPaths();
|
|
||||||
void onChangeRoot();
|
|
||||||
|
|
||||||
void onAircraftInstalledCompleted(QModelIndex index);
|
void onAircraftInstalledCompleted(QModelIndex index);
|
||||||
void onAircraftInstallFailed(QModelIndex index, QString errorMessage);
|
void onAircraftInstallFailed(QModelIndex index, QString errorMessage);
|
||||||
|
|
||||||
|
@ -95,6 +93,9 @@ private slots:
|
||||||
|
|
||||||
void maybeRestoreAircraftSelection();
|
void maybeRestoreAircraftSelection();
|
||||||
|
|
||||||
|
void onRestoreDefaults();
|
||||||
|
|
||||||
|
void onDownloadDirChanged();
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
<item row="6" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>To download a compressed archive of the files, click the 'Download' button. Once the download is complete, extract the files to a suitabe location and choose the folder using the button above.</string>
|
<string>To download a compressed archive of the files, click the 'Download' button. Once the download is complete, extract the files to a suitable location and choose the folder using the button above.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|
Loading…
Add table
Reference in a new issue