1
0
Fork 0

Launcher can save/load configs to disk

Aircraft state is also persisted to configs and on flying
This commit is contained in:
James Turner 2018-06-27 23:06:39 +01:00
parent c013eb74ab
commit 5ebee55632
15 changed files with 290 additions and 103 deletions

View file

@ -7,12 +7,52 @@
#include <QSettings> #include <QSettings>
#include <QDebug> #include <QDebug>
#include <QIODevice>
#include <QDataStream>
static bool static_enableDownloadDirUI = true; static bool static_enableDownloadDirUI = true;
static QSettings::Format static_binaryFormat = QSettings::InvalidFormat;
static bool binaryReadFunc(QIODevice &device, QSettings::SettingsMap &map)
{
QDataStream ds(&device);
int count;
ds >> count;
for (int i=0; i < count; ++i) {
QString k;
QVariant v;
ds >> k >> v;
map.insert(k, v);
}
return true;
}
static bool binaryWriteFunc(QIODevice &device, const QSettings::SettingsMap &map)
{
QDataStream ds(&device);
ds << map.size();
Q_FOREACH(QString key, map.keys()) {
ds << key << map.value(key);
}
return true;
}
LaunchConfig::LaunchConfig(QObject* parent) : LaunchConfig::LaunchConfig(QObject* parent) :
QObject(parent) QObject(parent)
{ {
if (static_binaryFormat == QSettings::InvalidFormat) {
static_binaryFormat = QSettings::registerFormat("fglaunch",
&binaryReadFunc,
&binaryWriteFunc);
}
}
LaunchConfig::~LaunchConfig()
{
} }
void LaunchConfig::reset() void LaunchConfig::reset()
@ -130,11 +170,59 @@ QString LaunchConfig::htmlForCommandLine()
return html; return html;
} }
bool LaunchConfig::saveConfigToINI()
{
// create settings using default type (INI) and path (inside FG_HOME),
// as setup in initQSettings()
m_loadSaveSettings.reset(new QSettings);
emit save();
m_loadSaveSettings->sync();
m_loadSaveSettings.reset();
return true;
}
bool LaunchConfig::loadConfigFromINI()
{
// create settings using default type (INI) and path (inside FG_HOME),
// as setup in initQSettings()
m_loadSaveSettings.reset(new QSettings);
emit restore();
emit postRestore();
m_loadSaveSettings.reset();
return true;
}
bool LaunchConfig::saveConfigToFile(QString path)
{
m_loadSaveSettings.reset(new QSettings(path, static_binaryFormat));
emit save();
m_loadSaveSettings.reset();
return true;
}
bool LaunchConfig::loadConfigFromFile(QString path)
{
m_loadSaveSettings.reset(new QSettings(path, static_binaryFormat));
emit restore();
// some things have an ordering dependency, give them a chance to run
// after other settings have been restored (eg, location or aircraft)
emit postRestore();
m_loadSaveSettings.reset();
return true;
}
QVariant LaunchConfig::getValueForKey(QString group, QString key, QVariant defaultValue) const QVariant LaunchConfig::getValueForKey(QString group, QString key, QVariant defaultValue) const
{ {
QSettings settings; if (!m_loadSaveSettings) {
settings.beginGroup(group); // becuase we load settings on component completion, we need
auto v = settings.value(key, defaultValue); // to create the default implementation (using the INI file)
// on demand
m_loadSaveSettings.reset(new QSettings);
}
m_loadSaveSettings->beginGroup(group);
auto v = m_loadSaveSettings->value(key, defaultValue);
bool convertedOk = v.convert(defaultValue.type()); bool convertedOk = v.convert(defaultValue.type());
if (!convertedOk) { if (!convertedOk) {
qWarning() << "type forcing on loaded value failed:" << key << v << v.typeName() << defaultValue; qWarning() << "type forcing on loaded value failed:" << key << v << v.typeName() << defaultValue;
@ -145,11 +233,11 @@ QVariant LaunchConfig::getValueForKey(QString group, QString key, QVariant defau
void LaunchConfig::setValueForKey(QString group, QString key, QVariant var) void LaunchConfig::setValueForKey(QString group, QString key, QVariant var)
{ {
QSettings settings; Q_ASSERT(m_loadSaveSettings);
settings.beginGroup(group); m_loadSaveSettings->beginGroup(group);
// qInfo() << "saving" << key << "with value" << var << var.typeName(); // qInfo() << "saving" << key << "with value" << var << var.typeName();
settings.setValue(key, var); m_loadSaveSettings->setValue(key, var);
settings.endGroup(); m_loadSaveSettings->endGroup();
} }
QString LaunchConfig::defaultDownloadDir() const QString LaunchConfig::defaultDownloadDir() const

View file

@ -4,6 +4,10 @@
#include <set> #include <set>
#include <QObject> #include <QObject>
#include <QVariant> #include <QVariant>
#include <QScopedPointer>
// forwards decls
class QSettings;
namespace flightgear { class Options; } namespace flightgear { class Options; }
@ -34,6 +38,7 @@ public:
LaunchConfig(QObject* parent = nullptr); LaunchConfig(QObject* parent = nullptr);
~LaunchConfig();
void reset(); void reset();
void applyToOptions() const; void applyToOptions() const;
@ -52,10 +57,12 @@ public:
Q_INVOKABLE QString htmlForCommandLine(); Q_INVOKABLE QString htmlForCommandLine();
bool saveConfigToINI();
bool loadConfigFromINI();
// ensure a property is /not/ set? Q_INVOKABLE bool saveConfigToFile(QString path);
// save and restore API? Q_INVOKABLE bool loadConfigFromFile(QString path);
Q_INVOKABLE QVariant getValueForKey(QString group, QString key, QVariant defaultValue = QVariant()) const; Q_INVOKABLE QVariant getValueForKey(QString group, QString key, QVariant defaultValue = QVariant()) const;
Q_INVOKABLE void setValueForKey(QString group, QString key, QVariant var); Q_INVOKABLE void setValueForKey(QString group, QString key, QVariant var);
@ -72,11 +79,17 @@ public:
signals: signals:
void collect(); void collect();
void save();
void restore();
void postRestore();
private: private:
std::set<std::string> extraArgNames() const; std::set<std::string> extraArgNames() const;
std::vector<Arg> m_values; std::vector<Arg> m_values;
QString m_defaultDownloadDir; QString m_defaultDownloadDir;
mutable QScopedPointer<QSettings> m_loadSaveSettings;
}; };
#endif #endif

View file

@ -11,6 +11,7 @@
#include <QQuickWindow> #include <QQuickWindow>
#include <QQmlComponent> #include <QQmlComponent>
#include <QPushButton> #include <QPushButton>
#include <QFileDialog>
// simgear headers // simgear headers
#include <simgear/package/Install.hxx> #include <simgear/package/Install.hxx>
@ -61,6 +62,8 @@ LauncherController::LauncherController(QObject *parent, QWindow* window) :
m_config = new LaunchConfig(this); m_config = new LaunchConfig(this);
connect(m_config, &LaunchConfig::collect, this, &LauncherController::collectAircraftArgs); connect(m_config, &LaunchConfig::collect, this, &LauncherController::collectAircraftArgs);
connect(m_config, &LaunchConfig::save, this, &LauncherController::saveAircraft);
connect(m_config, &LaunchConfig::restore, this, &LauncherController::restoreAircraft);
m_location->setLaunchConfig(m_config); m_location->setLaunchConfig(m_config);
connect(m_location, &LocationController::descriptionChanged, connect(m_location, &LocationController::descriptionChanged,
@ -165,7 +168,7 @@ bool LauncherController::inAppResult() const
return m_appModeResult; return m_appModeResult;
} }
void LauncherController::restoreSettings() void LauncherController::initialRestoreSettings()
{ {
m_selectedAircraft = m_aircraftHistory->mostRecent(); m_selectedAircraft = m_aircraftHistory->mostRecent();
if (m_selectedAircraft.isEmpty()) { if (m_selectedAircraft.isEmpty()) {
@ -179,8 +182,7 @@ void LauncherController::restoreSettings()
} }
} }
m_location->restoreSearchHistory();
m_location->restoreSettings();
QVariantMap currentLocation = m_locationHistory->mostRecent(); QVariantMap currentLocation = m_locationHistory->mostRecent();
if (currentLocation.isEmpty()) { if (currentLocation.isEmpty()) {
// use the default // use the default
@ -193,19 +195,22 @@ void LauncherController::restoreSettings()
} }
m_location->restoreLocation(currentLocation); m_location->restoreLocation(currentLocation);
emit selectedAircraftChanged(m_selectedAircraft);
updateSelectedAircraft(); updateSelectedAircraft();
m_serversModel->requestRestore(); m_serversModel->requestRestore();
m_aircraftState = m_config->getValueForKey("", "selected-aircraft-state", QString()).toString();
emit selectedAircraftStateChanged();
emit summaryChanged(); emit summaryChanged();
} }
void LauncherController::saveSettings() void LauncherController::saveSettings()
{ {
emit requestSaveState();
QSettings settings; QSettings settings;
settings.setValue("window-geometry", m_window->geometry()); settings.setValue("window-geometry", m_window->geometry());
m_config->saveConfigToINI();
m_aircraftHistory->saveToSettings(); m_aircraftHistory->saveToSettings();
m_locationHistory->saveToSettings(); m_locationHistory->saveToSettings();
} }
@ -230,6 +235,18 @@ void LauncherController::collectAircraftArgs()
} }
} }
if (m_selectedAircraftInfo->hasStates() && !m_aircraftState.isEmpty()) {
QString state = m_aircraftState;
if ((m_aircraftState == "auto") && !m_selectedAircraftInfo->haveExplicitAutoState()) {
state = selectAircraftStateAutomatically();
qInfo() << "doing launcher auto state selection, picked:" + state;
}
if (!state.isEmpty()) {
m_config->setArg("state", state);
}
}
// scenery paths // scenery paths
QSettings settings; QSettings settings;
Q_FOREACH(QString path, settings.value("scenery-paths").toStringList()) { Q_FOREACH(QString path, settings.value("scenery-paths").toStringList()) {
@ -242,6 +259,23 @@ void LauncherController::collectAircraftArgs()
} }
} }
void LauncherController::saveAircraft()
{
m_config->setValueForKey("", "selected-aircraft", m_selectedAircraft);
if (!m_aircraftState.isEmpty()) {
m_config->setValueForKey("", "selected-aircraft-state", m_aircraftState);
}
}
void LauncherController::restoreAircraft()
{
m_selectedAircraft = m_config->getValueForKey("", "selected-aircraft", QUrl()).toUrl();
m_aircraftState = m_config->getValueForKey("", "selected-aircraft-state", QString()).toString();
emit selectedAircraftChanged(m_selectedAircraft);
updateSelectedAircraft();
emit selectedAircraftStateChanged();
}
void LauncherController::doRun() void LauncherController::doRun()
{ {
flightgear::Options* opt = flightgear::Options::sharedInstance(); flightgear::Options* opt = flightgear::Options::sharedInstance();
@ -318,8 +352,13 @@ QString LauncherController::selectAircraftStateAutomatically()
if (!m_selectedAircraftInfo) if (!m_selectedAircraftInfo)
return {}; return {};
if (m_location->isAirborneLocation() && m_selectedAircraftInfo->hasState("approach")) if (m_location->isAirborneLocation() && m_selectedAircraftInfo->hasState("cruise")) {
{ if (m_location->altitudeFt() > 6000) {
return "cruise";
}
}
if (m_location->isAirborneLocation() && m_selectedAircraftInfo->hasState("approach")) {
return "approach"; return "approach";
} }
@ -452,8 +491,11 @@ void LauncherController::setSelectedAircraft(QUrl selectedAircraft)
return; return;
m_selectedAircraft = selectedAircraft; m_selectedAircraft = selectedAircraft;
m_aircraftState.clear();
updateSelectedAircraft(); updateSelectedAircraft();
emit selectedAircraftChanged(m_selectedAircraft); emit selectedAircraftChanged(m_selectedAircraft);
emit selectedAircraftStateChanged();
} }
void LauncherController::setSettingsSearchTerm(QString settingsSearchTerm) void LauncherController::setSettingsSearchTerm(QString settingsSearchTerm)
@ -708,5 +750,24 @@ void LauncherController::requestChangeDataPath()
settings.setValue("fg-root", "!ask"); settings.setValue("fg-root", "!ask");
} // scope the ensure settings are written nicely } // scope the ensure settings are written nicely
flightgear::restartTheApp(); flightgear::restartTheApp();
}
void LauncherController::openConfig()
{
QString file = QFileDialog::getOpenFileName(nullptr, tr("Choose a saved configuration"),
{}, "*.fglaunch");
if (file.isEmpty())
return;
m_config->loadConfigFromFile(file);
}
void LauncherController::saveConfigAs()
{
QString file = QFileDialog::getSaveFileName(nullptr, tr("Save the current configuration"),
{}, "*.fglaunch");
if (file.isEmpty())
return;
m_config->saveConfigToFile(file);
} }

View file

@ -59,6 +59,8 @@ class LauncherController : public QObject
Q_PROPERTY(QmlAircraftInfo* selectedAircraftInfo READ selectedAircraftInfo NOTIFY selectedAircraftChanged) Q_PROPERTY(QmlAircraftInfo* selectedAircraftInfo READ selectedAircraftInfo NOTIFY selectedAircraftChanged)
Q_PROPERTY(QString selectedAircraftState MEMBER m_aircraftState NOTIFY selectedAircraftStateChanged)
Q_PROPERTY(bool isSearchActive READ isSearchActive NOTIFY searchChanged) Q_PROPERTY(bool isSearchActive READ isSearchActive NOTIFY searchChanged)
Q_PROPERTY(QString settingsSearchTerm READ settingsSearchTerm WRITE setSettingsSearchTerm NOTIFY searchChanged) Q_PROPERTY(QString settingsSearchTerm READ settingsSearchTerm WRITE setSettingsSearchTerm NOTIFY searchChanged)
@ -131,7 +133,6 @@ public:
Q_INVOKABLE QVariantList defaultSplashUrls() const; Q_INVOKABLE QVariantList defaultSplashUrls() const;
Q_INVOKABLE QString selectAircraftStateAutomatically();
LaunchConfig* config() const LaunchConfig* config() const
{ return m_config; } { return m_config; }
@ -144,7 +145,7 @@ public:
AircraftItemModel* baseAircraftModel() const AircraftItemModel* baseAircraftModel() const
{ return m_aircraftModel; } { return m_aircraftModel; }
void restoreSettings(); void initialRestoreSettings();
void saveSettings(); void saveSettings();
LocationController* location() const LocationController* location() const
@ -169,18 +170,13 @@ public:
signals: signals:
void selectedAircraftChanged(QUrl selectedAircraft); void selectedAircraftChanged(QUrl selectedAircraft);
void selectedAircraftStateChanged();
void searchChanged(); void searchChanged();
void summaryChanged(); void summaryChanged();
void canFlyChanged(); void canFlyChanged();
/**
* @brief requestSaveState - signal to request QML settings to save their
* state to persistent storage
*/
void requestSaveState();
void viewCommandLine(); void viewCommandLine();
public slots: public slots:
@ -198,11 +194,16 @@ public slots:
void requestRestoreDefaults(); void requestRestoreDefaults();
void requestChangeDataPath(); void requestChangeDataPath();
void openConfig();
void saveConfigAs();
private slots: private slots:
void onAircraftInstalledCompleted(QModelIndex index); void onAircraftInstalledCompleted(QModelIndex index);
void onAircraftInstallFailed(QModelIndex index, QString errorMessage); void onAircraftInstallFailed(QModelIndex index, QString errorMessage);
void saveAircraft();
void restoreAircraft();
private: private:
/** /**
* Check if the passed index is the selected aircraft, and if so, refresh * Check if the passed index is the selected aircraft, and if so, refresh
@ -220,6 +221,8 @@ private:
void collectAircraftArgs(); void collectAircraftArgs();
QString selectAircraftStateAutomatically();
private: private:
QWindow* m_window = nullptr; QWindow* m_window = nullptr;
@ -231,6 +234,7 @@ private:
LocationController* m_location = nullptr; LocationController* m_location = nullptr;
QUrl m_selectedAircraft; QUrl m_selectedAircraft;
QString m_aircraftState;
AircraftType m_aircraftType = Airplane; AircraftType m_aircraftType = Airplane;
int m_ratingFilters[4] = {3, 3, 3, 3}; int m_ratingFilters[4] = {3, 3, 3, 3};
LaunchConfig* m_config = nullptr; LaunchConfig* m_config = nullptr;

View file

@ -39,6 +39,15 @@ LauncherMainWindow::LauncherMainWindow() :
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
QMenuBar* mb = new QMenuBar(); QMenuBar* mb = new QMenuBar();
QMenu* fileMenu = mb->addMenu(tr("File"));
QAction* openAction = fileMenu->addAction(tr("Open saved configuration..."));
connect(openAction, &QAction::triggered,
m_controller, &LauncherController::openConfig);
QAction* saveAction = fileMenu->addAction(tr("Save configuration as..."));
connect(saveAction, &QAction::triggered,
m_controller, &LauncherController::saveConfigAs);
QMenu* toolsMenu = mb->addMenu(tr("Tools")); QMenu* toolsMenu = mb->addMenu(tr("Tools"));
QAction* restoreDefaultsAction = toolsMenu->addAction(tr("Restore defaults...")); QAction* restoreDefaultsAction = toolsMenu->addAction(tr("Restore defaults..."));
connect(restoreDefaultsAction, &QAction::triggered, connect(restoreDefaultsAction, &QAction::triggered,
@ -57,7 +66,7 @@ LauncherMainWindow::LauncherMainWindow() :
qa->setShortcut(QKeySequence("Ctrl+Q")); qa->setShortcut(QKeySequence("Ctrl+Q"));
connect(qa, &QAction::triggered, m_controller, &LauncherController::quit); connect(qa, &QAction::triggered, m_controller, &LauncherController::quit);
m_controller->restoreSettings(); m_controller->initialRestoreSettings();
flightgear::launcherSetSceneryPaths(); flightgear::launcherSetSceneryPaths();
auto addOnsCtl = new AddOnsController(this); auto addOnsCtl = new AddOnsController(this);

View file

@ -391,14 +391,32 @@ void LocationController::setLaunchConfig(LaunchConfig *config)
{ {
m_config = config; m_config = config;
connect(m_config, &LaunchConfig::collect, this, &LocationController::onCollectConfig); connect(m_config, &LaunchConfig::collect, this, &LocationController::onCollectConfig);
connect(m_config, &LaunchConfig::save, this, &LocationController::onSaveCurrentLocation);
connect(m_config, &LaunchConfig::restore, this, &LocationController::onRestoreCurrentLocation);
} }
void LocationController::restoreSettings() void LocationController::restoreSearchHistory()
{ {
QSettings settings; QSettings settings;
m_recentLocations = loadPositionedList(settings.value("recent-locations")); m_recentLocations = loadPositionedList(settings.value("recent-locations"));
} }
void LocationController::onRestoreCurrentLocation()
{
QVariantMap vm = m_config->getValueForKey("", "current-location", QVariantMap()).toMap();
if (vm.empty())
return;
restoreLocation(vm);
}
void LocationController::onSaveCurrentLocation()
{
m_config->setValueForKey("", "current-location", saveLocation());
}
bool LocationController::isParkedLocation() const bool LocationController::isParkedLocation() const
{ {
if (m_airportLocation) { if (m_airportLocation) {
@ -417,24 +435,25 @@ bool LocationController::isAirborneLocation() const
const bool altIsPositive = (m_altitudeFt > 0); const bool altIsPositive = (m_altitudeFt > 0);
if (m_locationIsLatLon) { if (m_locationIsLatLon) {
return altIsPositive; return (m_altitudeType != AltitudeType::Off) && altIsPositive;
} }
if (m_airportLocation) { if (m_airportLocation) {
const bool onRunway = (m_detailLocation && (m_detailLocation->type() == FGPositioned::RUNWAY)); const bool onRunway =
if (onRunway && m_offsetEnabled) { (m_detailLocation && (m_detailLocation->type() == FGPositioned::RUNWAY)) ||
m_useActiveRunway;
if (onRunway && m_onFinal) {
// in this case no altitude might be set, but we assume // in this case no altitude might be set, but we assume
// it's still an airborne pos // it's still an airborne position
return true; return true;
} }
// this allows for people using offsets from a parking position or return false;
// similar weirdness :)
return altIsPositive;
} }
// relative to a navaid or fix - base off altitude. // relative to a navaid or fix - base off altitude.
return altIsPositive; return (m_altitudeType != AltitudeType::Off) && altIsPositive;
} }
int LocationController::offsetRadial() const int LocationController::offsetRadial() const
@ -709,7 +728,7 @@ void LocationController::restoreLocation(QVariantMap l)
if (l.contains("location-apt-runway")) { if (l.contains("location-apt-runway")) {
QString runway = l.value("location-apt-runway").toString().toUpper(); QString runway = l.value("location-apt-runway").toString().toUpper();
if (runway == "ACTIVE") { if (runway == QStringLiteral("ACTIVE")) {
m_useActiveRunway = true; m_useActiveRunway = true;
} else { } else {
m_detailLocation = m_airportLocation->getRunwayByIdent(runway.toStdString()); m_detailLocation = m_airportLocation->getRunwayByIdent(runway.toStdString());

View file

@ -101,7 +101,7 @@ public:
void restoreLocation(QVariantMap l); void restoreLocation(QVariantMap l);
QVariantMap saveLocation() const; QVariantMap saveLocation() const;
void restoreSettings(); void restoreSearchHistory();
/// used to automatically select aircraft state /// used to automatically select aircraft state
bool isParkedLocation() const; bool isParkedLocation() const;
@ -170,6 +170,10 @@ public:
return m_locationIsLatLon; return m_locationIsLatLon;
} }
int altitudeFt() const
{
return m_altitudeFt;
}
public slots: public slots:
void setOffsetRadial(int offsetRadial); void setOffsetRadial(int offsetRadial);
@ -192,6 +196,8 @@ Q_SIGNALS:
private Q_SLOTS: private Q_SLOTS:
void onCollectConfig(); void onCollectConfig();
void onRestoreCurrentLocation();
void onSaveCurrentLocation();
private: private:
void onSearchComplete(); void onSearchComplete();

View file

@ -155,7 +155,6 @@ class StatesModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool hasExplicitAuto READ hasExplicitAuto CONSTANT)
public: public:
StatesModel() StatesModel()
{ {
@ -181,11 +180,15 @@ public:
// we will not run our own selection logic // we will not run our own selection logic
_explicitAutoState = true; _explicitAutoState = true;
} else { } else {
// disabling this code for 2018.1, since it needs more testing
_data.insert(_data.begin(), {{"auto"}, {}, tr("Select state based on startup position.")}); _data.insert(_data.begin(), {{"auto"}, {}, tr("Select state based on startup position.")});
} }
} }
Q_INVOKABLE int indexForTag(QString s) const
{
return indexForTag(s.toStdString());
}
int indexForTag(const std::string &tag) const int indexForTag(const std::string &tag) const
{ {
auto it = std::find_if(_data.begin(), _data.end(), [tag](const StateInfo& i) { auto it = std::find_if(_data.begin(), _data.end(), [tag](const StateInfo& i) {
@ -684,6 +687,11 @@ bool QmlAircraftInfo::hasState(QString name) const
return _statesModel->hasState(name); return _statesModel->hasState(name);
} }
bool QmlAircraftInfo::haveExplicitAutoState() const
{
return _statesModel->hasExplicitAuto();
}
StatesModel *QmlAircraftInfo::statesModel() StatesModel *QmlAircraftInfo::statesModel()
{ {
return _statesModel.data(); return _statesModel.data();

View file

@ -107,6 +107,8 @@ public:
bool hasState(QString name) const; bool hasState(QString name) const;
bool haveExplicitAutoState() const;
static const int StateTagRole; static const int StateTagRole;
static const int StateDescriptionRole; static const int StateDescriptionRole;
static const int StateExplicitRole; static const int StateExplicitRole;

View file

@ -9,14 +9,6 @@ Item {
value: timeOfDay.summary().concat(weatherSettings.summary()); value: timeOfDay.summary().concat(weatherSettings.summary());
} }
Connections {
target: _launcher
onRequestSaveState: {
timeOfDaySettings.saveState();
weatherSettings.saveState();
}
}
Flickable { Flickable {
contentHeight: sectionColumn.childrenRect.height contentHeight: sectionColumn.childrenRect.height
flickableDirection: Flickable.VerticalFlick flickableDirection: Flickable.VerticalFlick

View file

@ -131,8 +131,8 @@ Item {
z: 100 z: 100
items: [ items: [
MenuItem { text:qsTr("Open saved configuration..."); enabled: false }, MenuItem { text:qsTr("Open saved configuration..."); onTriggered: _launcher.openConfig(); },
MenuItem { text:qsTr("Save configuration..."); enabled: false }, MenuItem { text:qsTr("Save configuration as..."); onTriggered: _launcher.saveConfigAs(); },
MenuDivider {}, MenuDivider {},
MenuItem { text:qsTr("View command line"); onTriggered: _launcher.viewCommandLine(); }, MenuItem { text:qsTr("View command line"); onTriggered: _launcher.viewCommandLine(); },
MenuItem { text:qsTr("Select data files location..."); onTriggered: _launcher.requestChangeDataPath(); }, MenuItem { text:qsTr("Select data files location..."); onTriggered: _launcher.requestChangeDataPath(); },

View file

@ -13,8 +13,6 @@ Item {
property bool enabled: true property bool enabled: true
property int currentIndex: 0 property int currentIndex: 0
property bool __dummy: false property bool __dummy: false
property alias header: choicesHeader.sourceComponent
property string headerText: "" property string headerText: ""
implicitHeight: Math.max(label.implicitHeight, currentChoiceFrame.height) implicitHeight: Math.max(label.implicitHeight, currentChoiceFrame.height)
@ -166,20 +164,11 @@ Item {
width: menuWidth width: menuWidth
// optional header component: // optional header component:
Loader { StyledText {
id: choicesHeader text: root.headerText
active: root.haveHeader() visible: root.haveHeader();
height: implicitHeight + Style.margin
// default component is just a plain text element, same as width: choicesColumn.width
// normal items
sourceComponent: StyledText {
text: root.headerText
height: implicitHeight + Style.margin
width: choicesColumn.width
}
height: item ? item.height : 0
width: item ? item.width : 0
// essentially the same mouse area as normal items // essentially the same mouse area as normal items
MouseArea { MouseArea {
@ -191,7 +180,7 @@ Item {
root.select(-1); root.select(-1);
} }
} }
} // of header loader }
function calculateMenuWidth() function calculateMenuWidth()
{ {

View file

@ -43,6 +43,12 @@ Item {
onCollect: apply(); onCollect: apply();
} }
Connections {
target: _config
onRestore: root.restoreState();
onSave: root.saveState();
}
Rectangle { Rectangle {
// this is the 'search hit highlight effect' // this is the 'search hit highlight effect'
anchors.fill: parent anchors.fill: parent

View file

@ -20,26 +20,8 @@ Item {
renderSection.summary()); renderSection.summary());
} }
Connections { Flickable
target: _launcher
onRequestSaveState: settings.saveState();
}
Component.onDestruction: {
settings.saveState();
}
function saveState()
{ {
mpSettings.saveState();
downloadSettings.saveState();
generalSettings.saveState();
renderSection.saveState();
extraArgsSection.saveState();
windowSettings.saveState();
}
Flickable {
id: settingsFlick id: settingsFlick
contentHeight: sectionColumn.childrenRect.height contentHeight: sectionColumn.childrenRect.height
flickableDirection: Flickable.VerticalFlick flickableDirection: Flickable.VerticalFlick

View file

@ -86,7 +86,7 @@ Item {
// dynamic text sizing, so bind it manually // dynamic text sizing, so bind it manually
y: logoText.y + Style.margin + logoText.contentHeight y: logoText.y + Style.margin + logoText.contentHeight
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: "Licenced under the GNU Public License (GPL)- click for more info" text: "Licenced under the GNU Public License (GPL) - click for more info"
baseTextColor: "white" baseTextColor: "white"
style: Text.Outline style: Text.Outline
styleColor: "black" styleColor: "black"
@ -216,12 +216,29 @@ Item {
width: summaryGrid.middleColumnWidth width: summaryGrid.middleColumnWidth
spacing: Style.margin spacing: Style.margin
Component.onCompleted: updateComboFromController();
function updateComboFromController()
{
stateSelectionCombo.currentIndex = _launcher.selectedAircraftInfo.statesModel.indexForTag(_launcher.selectedAircraftState)
}
PopupChoice { PopupChoice {
id: stateSelectionCombo id: stateSelectionCombo
model: _launcher.selectedAircraftInfo.statesModel model: _launcher.selectedAircraftInfo.statesModel
displayRole: "name" displayRole: "name"
label: qsTr("State:") label: qsTr("State:")
width: parent.width width: parent.width
headerText: qsTr("Default state")
function select(index)
{
if (index === -1) {
_launcher.selectedAircraftState = "";
} else {
_launcher.selectedAircraftState = model.tagForState(index);
}
}
} }
StyledText { StyledText {
@ -234,22 +251,13 @@ Item {
} }
Connections { Connections {
target: _config target: _launcher.selectedAircraftInfo
onCollect: { onInfoChanged: stateSelectionGroup.updateComboFromController()
if (!_launcher.selectedAircraftInfo.hasStates) }
return;
var state = _launcher.selectedAircraftInfo.statesModel.tagForState(stateSelectionCombo.currentIndex); Connections {
if (state === "auto" && !_launcher.selectedAircraftInfo.statesModel.hasExplicitAuto) { target: _launcher
// auto state selection if not handled by aircraft onSelectedAircraftStateChanged: stateSelectionGroup.updateComboFromController()
state = _launcher.selectAircraftStateAutomatically();
console.info("launcher auto state selection, picked:" + state)
}
if (state !== "__default__") { // don't set arg in default case
_config.setArg("state", state);
}
}
} // of connections } // of connections
} }