Summary page converted to QtQuick
This commit is contained in:
parent
eaf89ab23b
commit
19ae26164a
18 changed files with 939 additions and 448 deletions
|
@ -140,6 +140,10 @@ if (HAVE_QT)
|
|||
MPServersModel.h
|
||||
PathUrlHelper.cxx
|
||||
PathUrlHelper.hxx
|
||||
RecentAircraftModel.cxx
|
||||
RecentAircraftModel.hxx
|
||||
RecentLocationsModel.cxx
|
||||
RecentLocationsModel.hxx
|
||||
${uic_sources}
|
||||
${qrc_sources}
|
||||
${qml_sources})
|
||||
|
|
|
@ -34,6 +34,20 @@ std::string defaultAirportICAO()
|
|||
return airportCode;
|
||||
}
|
||||
|
||||
string_list defaultSplashScreenPaths()
|
||||
{
|
||||
string_list result;
|
||||
SGPath tpath = globals->get_fg_root() / "Textures";
|
||||
simgear::Dir d(tpath);
|
||||
for (auto c : d.children(simgear::Dir::TYPE_FILE, ".png")) {
|
||||
if (c.file_base().find("Splash") == 0) {
|
||||
result.push_back(c.utf8Str());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DefaultAircraftLocator::DefaultAircraftLocator()
|
||||
{
|
||||
SGPropertyNode_ptr root = loadXMLDefaults();
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace flightgear
|
|||
|
||||
std::string defaultAirportICAO();
|
||||
|
||||
string_list defaultSplashScreenPaths();
|
||||
|
||||
/**
|
||||
* we don't want to rely on the main AircraftModel threaded scan, to find the
|
||||
* default aircraft, so we do a synchronous scan here, on the assumption that
|
||||
|
|
|
@ -250,231 +250,31 @@
|
|||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="summaryPage">
|
||||
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,0,0,0,0,0,0,0,0,0,0" columnstretch="0,0,0,1,0">
|
||||
<item row="0" column="3" colspan="2">
|
||||
<widget class="QLabel" name="appTitleLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>48</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>FlightGear 2017.1.0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QPushButton" name="aircraftHistory">
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="stateLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>State:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLabel" name="aircraftName">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>aircraft</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Settings:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Aircraft:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<widget class="QLabel" name="locationDescription">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>location</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3" colspan="2">
|
||||
<widget class="QLabel" name="thumbnail">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>171</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="3" colspan="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>294</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="3" colspan="2">
|
||||
<widget class="QLabel" name="aircraftDescription">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3" colspan="2">
|
||||
<widget class="QComboBox" name="stateCombo"/>
|
||||
</item>
|
||||
<item row="1" column="3" colspan="2">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>©2017 FlightGear contributors. Licensed under the GNU Public License. See <a href="http://www.flightgear.org"><span style=" text-decoration: underline; color:#0000ff;">here</span></a> for more information</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Location:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="2">
|
||||
<widget class="QLabel" name="logoIcon">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="resources.qrc">:/app-icon-large</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="4">
|
||||
<widget class="QPushButton" name="locationHistory">
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="3" colspan="2">
|
||||
<widget class="QLabel" name="settingsDescription">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>settings</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3" colspan="2">
|
||||
<widget class="QLabel" name="stateDescription">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
|
||||
<widget class="QWidget" name="summaryPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QQuickWidget" name="summary"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
|
||||
<widget class="QWidget" name="aircraftPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#include <QMenu>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkDiskCache>
|
||||
#include <QPushButton>
|
||||
#include <QStandardItemModel>
|
||||
#include <QDesktopServices>
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QQmlEngine>
|
||||
|
@ -49,11 +52,11 @@
|
|||
#include "LauncherArgumentTokenizer.hxx"
|
||||
#include "PathUrlHelper.hxx"
|
||||
#include "PopupWindowTracker.hxx"
|
||||
#include "RecentAircraftModel.hxx"
|
||||
#include "RecentLocationsModel.hxx"
|
||||
|
||||
#include "ui_Launcher.h"
|
||||
|
||||
const int MAX_RECENT_AIRCRAFT = 20;
|
||||
|
||||
using namespace simgear::pkg;
|
||||
|
||||
extern void restartTheApp(QStringList fgArgs);
|
||||
|
@ -75,14 +78,11 @@ QQmlPrivate::AutoParentResult launcher_autoParent(QObject* thing, QObject* paren
|
|||
|
||||
LauncherMainWindow::LauncherMainWindow() :
|
||||
QMainWindow(),
|
||||
m_ui(NULL),
|
||||
m_subsystemIdleTimer(NULL)
|
||||
{
|
||||
m_ui.reset(new Ui::Launcher);
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->appTitleLabel->setText(tr("FlightGear %1").arg(FLIGHTGEAR_VERSION));
|
||||
|
||||
QMenuBar* mb = menuBar();
|
||||
|
||||
#if !defined(Q_OS_MAC)
|
||||
|
@ -108,15 +108,7 @@ LauncherMainWindow::LauncherMainWindow() :
|
|||
|
||||
m_serversModel = new MPServersModel(this);
|
||||
|
||||
// keep the description QLabel in sync as the current item changes
|
||||
connect(m_ui->stateCombo,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
[this](int)
|
||||
{
|
||||
auto v = m_ui->stateCombo->currentData(QmlAircraftInfo::StateDescriptionRole);
|
||||
m_ui->stateDescription->setText(v.toString());
|
||||
m_ui->stateDescription->setVisible(!v.toString().isEmpty());
|
||||
});
|
||||
m_locationHistory = new RecentLocationsModel(this);
|
||||
|
||||
m_selectedAircraftInfo = new QmlAircraftInfo(this);
|
||||
initQML();
|
||||
|
@ -135,23 +127,14 @@ LauncherMainWindow::LauncherMainWindow() :
|
|||
connect(m_ui->settingsButton, &QAbstractButton::clicked, this, &LauncherMainWindow::onClickToolboxButton);
|
||||
connect(m_ui->addOnsButton, &QAbstractButton::clicked, this, &LauncherMainWindow::onClickToolboxButton);
|
||||
|
||||
connect(m_ui->aircraftHistory, &QPushButton::clicked,
|
||||
this, &LauncherMainWindow::onPopupAircraftHistory);
|
||||
connect(m_ui->locationHistory, &QPushButton::clicked,
|
||||
this, &LauncherMainWindow::onPopupLocationHistory);
|
||||
|
||||
connect(m_ui->location, &LocationWidget::descriptionChanged,
|
||||
m_ui->locationDescription, &QLabel::setText);
|
||||
this, &LauncherMainWindow::summaryChanged);
|
||||
|
||||
QAction* qa = new QAction(this);
|
||||
qa->setShortcut(QKeySequence("Ctrl+Q"));
|
||||
connect(qa, &QAction::triggered, this, &LauncherMainWindow::onQuit);
|
||||
addAction(qa);
|
||||
|
||||
QIcon historyIcon(":/history-icon");
|
||||
m_ui->aircraftHistory->setIcon(historyIcon);
|
||||
m_ui->locationHistory->setIcon(historyIcon);
|
||||
|
||||
m_aircraftModel = new AircraftItemModel(this);
|
||||
m_installedAircraftModel = new AircraftProxyModel(this, m_aircraftModel);
|
||||
m_installedAircraftModel->setInstalledFilterEnabled(true);
|
||||
|
@ -161,40 +144,13 @@ LauncherMainWindow::LauncherMainWindow() :
|
|||
|
||||
m_aircraftSearchModel = new AircraftProxyModel(this, m_aircraftModel);
|
||||
|
||||
m_ui->aircraftList->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
|
||||
m_ui->aircraftList->engine()->addImportPath("qrc:///");
|
||||
m_ui->aircraftList->engine()->rootContext()->setContextProperty("_launcher", this);
|
||||
m_ui->aircraftList->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
|
||||
m_ui->aircraftList->setSource(QUrl("qrc:///qml/AircraftList.qml"));
|
||||
|
||||
m_ui->settings->engine()->addImportPath("qrc:///");
|
||||
m_ui->settings->engine()->rootContext()->setContextProperty("_launcher", this);
|
||||
m_ui->settings->engine()->rootContext()->setContextProperty("_mpServers", m_serversModel);
|
||||
|
||||
m_ui->settings->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
|
||||
m_ui->settings->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
m_ui->settings->setSource(QUrl("qrc:///qml/Settings.qml"));
|
||||
|
||||
m_ui->environmentPage->engine()->addImportPath("qrc:///");
|
||||
m_ui->environmentPage->engine()->rootContext()->setContextProperty("_launcher", this);
|
||||
auto weatherScenariosModel = new flightgear::WeatherScenariosModel(this);
|
||||
m_ui->environmentPage->engine()->rootContext()->setContextProperty("_weatherScenarios", weatherScenariosModel);
|
||||
|
||||
m_ui->environmentPage->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
m_ui->environmentPage->engine()->rootContext()->setContextProperty("_config", m_config);
|
||||
|
||||
m_ui->environmentPage->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
m_ui->environmentPage->setSource(QUrl("qrc:///qml/Environment.qml"));
|
||||
m_aircraftHistory = new RecentAircraftModel(m_aircraftModel, this);
|
||||
|
||||
connect(m_aircraftModel, &AircraftItemModel::aircraftInstallCompleted,
|
||||
this, &LauncherMainWindow::onAircraftInstalledCompleted);
|
||||
connect(m_aircraftModel, &AircraftItemModel::aircraftInstallFailed,
|
||||
this, &LauncherMainWindow::onAircraftInstallFailed);
|
||||
|
||||
|
||||
connect(LocalAircraftCache::instance(),
|
||||
&LocalAircraftCache::scanCompleted,
|
||||
this, &LauncherMainWindow::updateSelectedAircraft);
|
||||
|
@ -219,8 +175,50 @@ LauncherMainWindow::LauncherMainWindow() :
|
|||
m_ui->stack->addWidget(m_viewCommandLinePage);
|
||||
|
||||
restoreSettings();
|
||||
updateSettingsSummary();
|
||||
|
||||
emit summaryChanged();
|
||||
emit showNoOfficialHangarChanged();
|
||||
|
||||
/////////////
|
||||
// aircraft
|
||||
m_ui->aircraftList->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
|
||||
m_ui->aircraftList->engine()->addImportPath("qrc:///");
|
||||
m_ui->aircraftList->engine()->rootContext()->setContextProperty("_launcher", this);
|
||||
m_ui->aircraftList->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
|
||||
m_ui->aircraftList->setSource(QUrl("qrc:///qml/AircraftList.qml"));
|
||||
|
||||
// settings
|
||||
m_ui->settings->engine()->addImportPath("qrc:///");
|
||||
m_ui->settings->engine()->rootContext()->setContextProperty("_launcher", this);
|
||||
m_ui->settings->engine()->rootContext()->setContextProperty("_mpServers", m_serversModel);
|
||||
|
||||
m_ui->settings->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
|
||||
m_ui->settings->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
m_ui->settings->setSource(QUrl("qrc:///qml/Settings.qml"));
|
||||
|
||||
// environemnt
|
||||
m_ui->environmentPage->engine()->addImportPath("qrc:///");
|
||||
m_ui->environmentPage->engine()->rootContext()->setContextProperty("_launcher", this);
|
||||
auto weatherScenariosModel = new flightgear::WeatherScenariosModel(this);
|
||||
m_ui->environmentPage->engine()->rootContext()->setContextProperty("_weatherScenarios", weatherScenariosModel);
|
||||
|
||||
m_ui->environmentPage->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
m_ui->environmentPage->engine()->rootContext()->setContextProperty("_config", m_config);
|
||||
|
||||
m_ui->environmentPage->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
m_ui->environmentPage->setSource(QUrl("qrc:///qml/Environment.qml"));
|
||||
|
||||
// summary
|
||||
m_ui->summary->engine()->addImportPath("qrc:///");
|
||||
m_ui->summary->engine()->rootContext()->setContextProperty("_launcher", this);
|
||||
m_ui->summary->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
m_ui->summary->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
m_ui->summary->setSource(QUrl("qrc:///qml/Summary.qml"));
|
||||
//////////////////////////
|
||||
|
||||
}
|
||||
|
||||
void LauncherMainWindow::initQML()
|
||||
|
@ -240,6 +238,9 @@ void LauncherMainWindow::initQML()
|
|||
qmlRegisterUncreatableType<QAbstractItemModel>("FlightGear.Launcher", 1, 0, "QAIM", "no");
|
||||
qmlRegisterUncreatableType<AircraftProxyModel>("FlightGear.Launcher", 1, 0, "AircraftProxyModel", "no");
|
||||
|
||||
qmlRegisterUncreatableType<RecentAircraftModel>("FlightGear.Launcher", 1, 0, "RecentAircraftModel", "no");
|
||||
qmlRegisterUncreatableType<RecentLocationsModel>("FlightGear.Launcher", 1, 0, "RecentLocationsModel", "no");
|
||||
|
||||
qmlRegisterUncreatableType<SettingsControl>("FlightGear.Launcher", 1, 0, "Control", "Base class");
|
||||
qmlRegisterUncreatableType<LaunchConfig>("FlightGear.Launcher", 1, 0, "LaunchConfig", "Singleton API");
|
||||
qmlRegisterType<FileDialogWrapper>("FlightGear.Launcher", 1, 0, "FileDialog");
|
||||
|
@ -265,6 +266,9 @@ void LauncherMainWindow::initQML()
|
|||
settingsContext->setContextProperty("_config", m_config);
|
||||
settingsContext->setContextProperty("_osName", osName);
|
||||
|
||||
QQmlContext* summaryContext = m_ui->summary->engine()->rootContext();
|
||||
summaryContext->setContextProperty("_config", m_config);
|
||||
|
||||
qmlRegisterUncreatableType<LocalAircraftCache>("FlightGear.Launcher", 1, 0, "LocalAircraftCache", "Aircraft cache");
|
||||
qmlRegisterUncreatableType<AircraftItemModel>("FlightGear.Launcher", 1, 0, "AircraftModel", "Built-in model");
|
||||
qmlRegisterType<ThumbnailImageItem>("FlightGear.Launcher", 1, 0, "ThumbnailImage");
|
||||
|
@ -311,12 +315,8 @@ void LauncherMainWindow::restoreSettings()
|
|||
|
||||
restoreGeometry(settings.value("window-geometry").toByteArray());
|
||||
|
||||
// full paths to -set.xml files
|
||||
m_recentAircraft = QUrl::fromStringList(settings.value("recent-aircraft").toStringList());
|
||||
|
||||
if (!m_recentAircraft.empty()) {
|
||||
m_selectedAircraft = m_recentAircraft.front();
|
||||
} else {
|
||||
m_selectedAircraft = m_aircraftHistory->mostRecent();
|
||||
if (m_selectedAircraft.isEmpty()) {
|
||||
// select the default aircraft specified in defaults.xml
|
||||
flightgear::DefaultAircraftLocator da;
|
||||
if (da.foundPath().exists()) {
|
||||
|
@ -332,22 +332,16 @@ void LauncherMainWindow::restoreSettings()
|
|||
}
|
||||
|
||||
m_ui->location->restoreSettings();
|
||||
m_recentLocations = settings.value("recent-location-sets").toList();
|
||||
QVariantMap currentLocation;
|
||||
if (m_recentLocations.isEmpty()) {
|
||||
QVariantMap currentLocation = m_locationHistory->mostRecent();
|
||||
if (currentLocation.isEmpty()) {
|
||||
// use the default
|
||||
std::string defaultAirport = flightgear::defaultAirportICAO();
|
||||
FGAirportRef apt = FGAirport::findByIdent(defaultAirport);
|
||||
if (apt) {
|
||||
currentLocation["location-id"] = static_cast<qlonglong>(apt->guid());
|
||||
currentLocation["location-apt-runway"] = "active";
|
||||
qDebug() << "restored default airport:" << QString::fromStdString(defaultAirport);
|
||||
} // otherwise we failed to find the default airport in the nav-db :(
|
||||
} else {
|
||||
// we have a valid current location
|
||||
currentLocation = m_recentLocations.front().toMap();
|
||||
}
|
||||
|
||||
m_ui->location->restoreLocation(currentLocation);
|
||||
|
||||
updateSelectedAircraft();
|
||||
|
@ -363,9 +357,10 @@ void LauncherMainWindow::saveSettings()
|
|||
{
|
||||
emit requestSaveState();
|
||||
|
||||
m_aircraftHistory->saveToSettings();
|
||||
m_locationHistory->saveToSettings();
|
||||
|
||||
QSettings settings;
|
||||
settings.setValue("recent-aircraft", QUrl::toStringList(m_recentAircraft));
|
||||
settings.setValue("recent-location-sets", m_recentLocations);
|
||||
settings.setValue("window-geometry", saveGeometry());
|
||||
|
||||
Q_FOREACH(SettingsSection* ss, findChildren<SettingsSection*>()) {
|
||||
|
@ -416,41 +411,13 @@ void LauncherMainWindow::onRun()
|
|||
m_config->reset();
|
||||
m_config->collect();
|
||||
|
||||
// aircraft
|
||||
if (!m_selectedAircraft.isEmpty()) {
|
||||
// manage aircraft history
|
||||
if (m_recentAircraft.contains(m_selectedAircraft))
|
||||
m_recentAircraft.removeOne(m_selectedAircraft);
|
||||
m_recentAircraft.prepend(m_selectedAircraft);
|
||||
if (m_recentAircraft.size() > MAX_RECENT_AIRCRAFT)
|
||||
m_recentAircraft.pop_back();
|
||||
}
|
||||
m_aircraftHistory->insert(m_selectedAircraft);
|
||||
|
||||
if (m_ui->stateCombo->isVisible()) {
|
||||
// apply state setting
|
||||
std::string tag = m_ui->stateCombo->currentData(QmlAircraftInfo::StateTagRole).
|
||||
toString().toStdString();
|
||||
|
||||
// implicit auto behaviour disabled for 2018.1, since it
|
||||
// needs a bit more work
|
||||
#if 0
|
||||
if (tag == "auto") {
|
||||
bool isExplictAuto = m_ui->stateCombo->currentData(QmlAircraftInfo::StateExplicitRole).toBool();
|
||||
if (!isExplictAuto) {
|
||||
tag = selectStateAutomatically();
|
||||
qInfo() << "automatic state selection: picked:" << QString::fromStdString(tag);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!tag.empty() && (tag != "__default__")) {
|
||||
m_config->setArg("state", tag);
|
||||
}
|
||||
} // of applying state selection
|
||||
QVariant locSet = m_ui->location->saveLocation();
|
||||
m_locationHistory->insert(locSet);
|
||||
|
||||
// aircraft paths
|
||||
QSettings settings;
|
||||
updateLocationHistory();
|
||||
|
||||
QString downloadDir = settings.value("downloadSettings/downloadDir").toString();
|
||||
if (!downloadDir.isEmpty()) {
|
||||
QDir d(downloadDir);
|
||||
|
@ -480,7 +447,7 @@ void LauncherMainWindow::onRun()
|
|||
qApp->exit(1);
|
||||
}
|
||||
|
||||
std::string LauncherMainWindow::selectStateAutomatically()
|
||||
QString LauncherMainWindow::selectAircraftStateAutomatically()
|
||||
{
|
||||
if (m_ui->location->isAirborneLocation()) {
|
||||
return "approach";
|
||||
|
@ -517,13 +484,7 @@ void LauncherMainWindow::onApply()
|
|||
qWarning() << "unsupported aircraft launch URL" << m_selectedAircraft;
|
||||
}
|
||||
|
||||
// manage aircraft history
|
||||
if (m_recentAircraft.contains(m_selectedAircraft))
|
||||
m_recentAircraft.removeOne(m_selectedAircraft);
|
||||
m_recentAircraft.prepend(m_selectedAircraft);
|
||||
if (m_recentAircraft.size() > MAX_RECENT_AIRCRAFT)
|
||||
m_recentAircraft.pop_back();
|
||||
|
||||
m_aircraftHistory->insert(m_selectedAircraft);
|
||||
globals->get_props()->setStringValue("/sim/aircraft", aircraftPropValue);
|
||||
globals->get_props()->setStringValue("/sim/aircraft-dir", aircraftDir);
|
||||
}
|
||||
|
@ -536,23 +497,6 @@ void LauncherMainWindow::onApply()
|
|||
m_runInApp = false;
|
||||
}
|
||||
|
||||
void LauncherMainWindow::updateLocationHistory()
|
||||
{
|
||||
QVariant locSet = m_ui->location->saveLocation();
|
||||
|
||||
// check for existing; let's use description to imply uniqueness. This means
|
||||
// 'A1111' parkings get merged but I prefer that to keep the menu usable
|
||||
QVariant locDesc = locSet.toMap().value("text");
|
||||
auto it = std::remove_if(m_recentLocations.begin(), m_recentLocations.end(),
|
||||
[locDesc](QVariant v) { return v.toMap().value("text") == locDesc; });
|
||||
m_recentLocations.erase(it, m_recentLocations.end());
|
||||
|
||||
// now we can always prepend
|
||||
m_recentLocations.prepend(locSet);
|
||||
if (m_recentLocations.size() > MAX_RECENT_AIRCRAFT)
|
||||
m_recentLocations.pop_back();
|
||||
}
|
||||
|
||||
void LauncherMainWindow::onQuit()
|
||||
{
|
||||
if (m_inAppMode) {
|
||||
|
@ -628,6 +572,7 @@ void LauncherMainWindow::updateSelectedAircraft()
|
|||
m_selectedAircraftInfo->setUri(m_selectedAircraft);
|
||||
QModelIndex index = m_aircraftModel->indexOfAircraftURI(m_selectedAircraft);
|
||||
if (index.isValid()) {
|
||||
#if 0
|
||||
QPixmap pm = index.data(Qt::DecorationRole).value<QPixmap>();
|
||||
m_ui->thumbnail->setPixmap(pm);
|
||||
|
||||
|
@ -640,7 +585,7 @@ void LauncherMainWindow::updateSelectedAircraft()
|
|||
QVariant longDesc = index.data(AircraftLongDescriptionRole);
|
||||
m_ui->aircraftDescription->setVisible(!longDesc.isNull());
|
||||
m_ui->aircraftDescription->setText(longDesc.toString());
|
||||
|
||||
#endif
|
||||
int status = index.data(AircraftPackageStatusRole).toInt();
|
||||
bool canRun = (status == LocalAircraftCache::PackageInstalled);
|
||||
m_ui->flyButton->setEnabled(canRun);
|
||||
|
@ -655,6 +600,7 @@ void LauncherMainWindow::updateSelectedAircraft()
|
|||
m_ui->location->setAircraftType(aircraftType);
|
||||
|
||||
const bool hasStates = m_selectedAircraftInfo->hasStates();
|
||||
#if 0
|
||||
m_ui->stateCombo->setVisible(hasStates);
|
||||
m_ui->stateLabel->setVisible(hasStates);
|
||||
m_ui->stateDescription->setVisible(false);
|
||||
|
@ -664,13 +610,16 @@ void LauncherMainWindow::updateSelectedAircraft()
|
|||
// hiden when no description is present
|
||||
m_ui->stateDescription->setVisible(!m_ui->stateDescription->text().isEmpty());
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if 0
|
||||
m_ui->thumbnail->setPixmap(QPixmap());
|
||||
m_ui->aircraftName->setText("");
|
||||
m_ui->aircraftDescription->hide();
|
||||
m_ui->stateCombo->hide();
|
||||
m_ui->stateLabel->hide();
|
||||
m_ui->stateDescription->hide();
|
||||
#endif
|
||||
m_ui->flyButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
@ -690,58 +639,6 @@ void LauncherMainWindow::setSceneryPaths()
|
|||
flightgear::launcherSetSceneryPaths();
|
||||
}
|
||||
|
||||
void LauncherMainWindow::onPopupAircraftHistory()
|
||||
{
|
||||
if (m_recentAircraft.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu m;
|
||||
Q_FOREACH(QUrl uri, m_recentAircraft) {
|
||||
QString nm = m_aircraftModel->nameForAircraftURI(uri);
|
||||
if (nm.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QAction* act = m.addAction(nm);
|
||||
act->setData(uri);
|
||||
}
|
||||
|
||||
QPoint popupPos = m_ui->aircraftHistory->mapToGlobal(m_ui->aircraftHistory->rect().bottomLeft());
|
||||
QAction* triggered = m.exec(popupPos);
|
||||
if (triggered) {
|
||||
setSelectedAircraft(triggered->data().toUrl());
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherMainWindow::onPopupLocationHistory()
|
||||
{
|
||||
if (m_recentLocations.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu m;
|
||||
Q_FOREACH(QVariant loc, m_recentLocations) {
|
||||
QString summary = loc.toMap().value("text").toString();
|
||||
QAction* act = m.addAction(summary);
|
||||
act->setData(loc);
|
||||
}
|
||||
|
||||
QPoint popupPos = m_ui->locationHistory->mapToGlobal(m_ui->locationHistory->rect().bottomLeft());
|
||||
QAction* triggered = m.exec(popupPos);
|
||||
if (triggered) {
|
||||
m_ui->location->restoreLocation(triggered->data().toMap());
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherMainWindow::updateSettingsSummary()
|
||||
{
|
||||
const QStringList summary = m_settingsSummary + m_environmentSummary;
|
||||
QString s = summary.join(", ");
|
||||
s[0] = s[0].toUpper();
|
||||
m_ui->settingsDescription->setText(s);
|
||||
}
|
||||
|
||||
void LauncherMainWindow::onSubsytemIdleTimeout()
|
||||
{
|
||||
globals->get_subsystem_mgr()->update(0.0);
|
||||
|
@ -836,6 +733,11 @@ QmlAircraftInfo *LauncherMainWindow::selectedAircraftInfo() const
|
|||
return m_selectedAircraftInfo;
|
||||
}
|
||||
|
||||
void LauncherMainWindow::restoreLocation(QVariant var)
|
||||
{
|
||||
m_ui->location->restoreLocation(var.toMap());
|
||||
}
|
||||
|
||||
bool LauncherMainWindow::matchesSearch(QString term, QStringList keywords) const
|
||||
{
|
||||
Q_FOREACH(QString s, keywords) {
|
||||
|
@ -888,7 +790,6 @@ void LauncherMainWindow::setSettingsSummary(QStringList settingsSummary)
|
|||
|
||||
m_settingsSummary = settingsSummary;
|
||||
emit summaryChanged();
|
||||
updateSettingsSummary();
|
||||
}
|
||||
|
||||
void LauncherMainWindow::setEnvironmentSummary(QStringList environmentSummary)
|
||||
|
@ -898,7 +799,16 @@ void LauncherMainWindow::setEnvironmentSummary(QStringList environmentSummary)
|
|||
|
||||
m_environmentSummary = environmentSummary;
|
||||
emit summaryChanged();
|
||||
updateSettingsSummary();
|
||||
}
|
||||
|
||||
QStringList LauncherMainWindow::combinedSummary() const
|
||||
{
|
||||
return m_settingsSummary + m_environmentSummary;
|
||||
}
|
||||
|
||||
QString LauncherMainWindow::locationDescription() const
|
||||
{
|
||||
return m_ui->location->locationDescription();
|
||||
}
|
||||
|
||||
simgear::pkg::PackageRef LauncherMainWindow::packageForAircraftURI(QUrl uri) const
|
||||
|
@ -1040,3 +950,34 @@ bool LauncherMainWindow::showNoOfficialHanger() const
|
|||
return shouldShowOfficialCatalogMessage();
|
||||
}
|
||||
|
||||
QString LauncherMainWindow::versionString() const
|
||||
{
|
||||
return FLIGHTGEAR_VERSION;
|
||||
}
|
||||
|
||||
RecentAircraftModel *LauncherMainWindow::aircraftHistory()
|
||||
{
|
||||
return m_aircraftHistory;
|
||||
}
|
||||
|
||||
RecentLocationsModel *LauncherMainWindow::locationHistory()
|
||||
{
|
||||
return m_locationHistory;
|
||||
}
|
||||
|
||||
void LauncherMainWindow::launchUrl(QUrl url)
|
||||
{
|
||||
QDesktopServices::openUrl(url);
|
||||
}
|
||||
|
||||
QVariantList LauncherMainWindow::defaultSplashUrls() const
|
||||
{
|
||||
QVariantList urls;
|
||||
|
||||
for (auto path : flightgear::defaultSplashScreenPaths()) {
|
||||
QUrl url = QUrl::fromLocalFile(QString::fromStdString(path));
|
||||
urls.append(url);
|
||||
}
|
||||
|
||||
return urls;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ class ViewCommandLinePage;
|
|||
class MPServersModel;
|
||||
class QQuickItem;
|
||||
class QmlAircraftInfo;
|
||||
class QStandardItemModel;
|
||||
class RecentAircraftModel;
|
||||
class RecentLocationsModel;
|
||||
|
||||
class LauncherMainWindow : public QMainWindow
|
||||
{
|
||||
|
@ -72,6 +75,14 @@ class LauncherMainWindow : public QMainWindow
|
|||
Q_PROPERTY(QStringList settingsSummary READ settingsSummary WRITE setSettingsSummary NOTIFY summaryChanged)
|
||||
Q_PROPERTY(QStringList environmentSummary READ environmentSummary WRITE setEnvironmentSummary NOTIFY summaryChanged)
|
||||
|
||||
Q_PROPERTY(QString locationDescription READ locationDescription NOTIFY summaryChanged)
|
||||
Q_PROPERTY(QStringList combinedSummary READ combinedSummary NOTIFY summaryChanged)
|
||||
|
||||
Q_PROPERTY(QString versionString READ versionString CONSTANT)
|
||||
|
||||
Q_PROPERTY(RecentAircraftModel* aircraftHistory READ aircraftHistory CONSTANT)
|
||||
Q_PROPERTY(RecentLocationsModel* locationHistory READ locationHistory CONSTANT)
|
||||
|
||||
public:
|
||||
LauncherMainWindow();
|
||||
virtual ~LauncherMainWindow();
|
||||
|
@ -105,6 +116,8 @@ public:
|
|||
|
||||
QmlAircraftInfo* selectedAircraftInfo() const;
|
||||
|
||||
Q_INVOKABLE void restoreLocation(QVariant var);
|
||||
|
||||
Q_INVOKABLE bool matchesSearch(QString term, QStringList keywords) const;
|
||||
|
||||
bool isSearchActive() const;
|
||||
|
@ -118,6 +131,25 @@ public:
|
|||
|
||||
QStringList environmentSummary() const;
|
||||
|
||||
QStringList combinedSummary() const;
|
||||
|
||||
QString locationDescription() const;
|
||||
|
||||
QString versionString() const;
|
||||
|
||||
RecentAircraftModel* aircraftHistory();
|
||||
|
||||
RecentLocationsModel* locationHistory();
|
||||
|
||||
Q_INVOKABLE void launchUrl(QUrl url);
|
||||
|
||||
// list of QUrls containing the default splash images from FGData.
|
||||
// used on the summary screen
|
||||
Q_INVOKABLE QVariantList defaultSplashUrls() const;
|
||||
|
||||
|
||||
Q_INVOKABLE QString selectAircraftStateAutomatically();
|
||||
|
||||
public slots:
|
||||
void setSelectedAircraft(QUrl selectedAircraft);
|
||||
|
||||
|
@ -155,11 +187,6 @@ private slots:
|
|||
|
||||
void onQuit();
|
||||
|
||||
void onPopupAircraftHistory();
|
||||
void onPopupLocationHistory();
|
||||
|
||||
void updateSettingsSummary();
|
||||
|
||||
void onSubsytemIdleTimeout();
|
||||
|
||||
void onAircraftInstalledCompleted(QModelIndex index);
|
||||
|
@ -192,13 +219,11 @@ private:
|
|||
// scrolling, to give the view time it seems.
|
||||
void delayedAircraftModelReset();
|
||||
|
||||
void updateLocationHistory();
|
||||
bool shouldShowOfficialCatalogMessage() const;
|
||||
|
||||
void collectAircraftArgs();
|
||||
void initQML();
|
||||
|
||||
std::string selectStateAutomatically();
|
||||
|
||||
QScopedPointer<Ui::Launcher> m_ui;
|
||||
AircraftProxyModel* m_installedAircraftModel;
|
||||
|
@ -208,21 +233,20 @@ private:
|
|||
MPServersModel* m_serversModel = nullptr;
|
||||
|
||||
QUrl m_selectedAircraft;
|
||||
QList<QUrl> m_recentAircraft;
|
||||
QTimer* m_subsystemIdleTimer;
|
||||
bool m_inAppMode = false;
|
||||
bool m_runInApp = false;
|
||||
bool m_accepted = false;
|
||||
int m_ratingFilters[4] = {3, 3, 3, 3};
|
||||
QVariantList m_recentLocations;
|
||||
QQmlEngine* m_qmlEngine = nullptr;
|
||||
LaunchConfig* m_config = nullptr;
|
||||
ExtraSettingsSection* m_extraSettings = nullptr;
|
||||
ViewCommandLinePage* m_viewCommandLinePage = nullptr;
|
||||
QmlAircraftInfo* m_selectedAircraftInfo = nullptr;
|
||||
QString m_settingsSearchTerm;
|
||||
QStringList m_settingsSummary,
|
||||
m_environmentSummary;
|
||||
m_environmentSummary;
|
||||
RecentAircraftModel* m_aircraftHistory = nullptr;
|
||||
RecentLocationsModel* m_locationHistory = nullptr;
|
||||
};
|
||||
|
||||
#endif // of LAUNCHER_MAIN_WINDOW_HXX
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <QVariant>
|
||||
#include <QDebug>
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <simgear/package/Install.hxx>
|
||||
#include <simgear/package/Root.hxx>
|
||||
|
@ -86,9 +87,12 @@ private:
|
|||
|
||||
struct StateInfo
|
||||
{
|
||||
std::string tag; // internal XML name
|
||||
string_list tags;
|
||||
QString name; // human-readable name, or blank if we auto-generate this
|
||||
QString description; // human-readable description
|
||||
|
||||
std::string primaryTag() const
|
||||
{ return tags.front(); }
|
||||
};
|
||||
|
||||
using AircraftStateVec = std::vector<StateInfo>;
|
||||
|
@ -111,12 +115,20 @@ static AircraftStateVec readAircraftStates(const SGPath& setXMLPath)
|
|||
AircraftStateVec result;
|
||||
result.reserve(nodes.size());
|
||||
for (auto cn : nodes) {
|
||||
result.push_back({cn->getStringValue("name"),
|
||||
string_list stateNames;
|
||||
for (auto nameNode : cn->getChildren("name")) {
|
||||
stateNames.push_back(nameNode->getStringValue());
|
||||
}
|
||||
|
||||
if (stateNames.empty()) {
|
||||
qWarning() << "state with no names defined, skipping";
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push_back({stateNames,
|
||||
QString::fromStdString(cn->getStringValue("readable-name")),
|
||||
QString::fromStdString(cn->getStringValue("description"))
|
||||
});
|
||||
|
||||
qInfo() << QString::fromStdString(result.back().tag) << result.back().description;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -141,35 +153,34 @@ QString humanNameFromStateTag(const std::string& tag)
|
|||
class StatesModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool hasExplicitAuto READ hasExplicitAuto CONSTANT)
|
||||
public:
|
||||
StatesModel(const AircraftStateVec& states) :
|
||||
_data(states)
|
||||
{
|
||||
// sort which places 'auto' item at the front if it exists
|
||||
std::sort(_data.begin(), _data.end(), [](const StateInfo& a, const StateInfo& b) {
|
||||
if (a.tag == "auto") return true;
|
||||
if (b.tag == "auto") return false;
|
||||
return a.tag < b.tag;
|
||||
if (a.primaryTag() == "auto") return true;
|
||||
if (b.primaryTag() == "auto") return false;
|
||||
return a.primaryTag() < b.primaryTag();
|
||||
});
|
||||
|
||||
if (_data.front().tag == "auto") {
|
||||
if (_data.front().primaryTag() == "auto") {
|
||||
// track if the aircraft supplied an 'auto' state, in which case
|
||||
// we will not run our own selection logic
|
||||
_explicitAutoState = true;
|
||||
} else {
|
||||
// disabling this code for 2018.1, since it needs more testing
|
||||
#if 0
|
||||
_data.insert(_data.begin(), {"auto", {}, tr("Select state based on startup position.")});
|
||||
#else
|
||||
_data.insert(_data.begin(), {"__default__", tr("Parked"), tr("Default state for the aircraft (usually cold and dark)")});
|
||||
#endif
|
||||
_data.insert(_data.begin(), {{"auto"}, {}, tr("Select state based on startup position.")});
|
||||
}
|
||||
}
|
||||
|
||||
int indexForTag(const std::string &tag) const
|
||||
{
|
||||
auto it = std::find_if(_data.begin(), _data.end(), [tag](const StateInfo& i) {
|
||||
return i.tag == tag;
|
||||
auto tagIt = std::find(i.tags.begin(), i.tags.end(), tag);
|
||||
return (tagIt != i.tags.end());
|
||||
});
|
||||
|
||||
if (it == _data.end())
|
||||
|
@ -186,18 +197,17 @@ public:
|
|||
QVariant data(const QModelIndex &index, int role) const override
|
||||
{
|
||||
const StateInfo& s = _data.at(index.row());
|
||||
// qInfo() << index.row() << s.name << QString::fromStdString(s.tag);
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (s.name.isEmpty()) {
|
||||
return humanNameFromStateTag(s.tag);
|
||||
return humanNameFromStateTag(s.primaryTag());
|
||||
}
|
||||
return s.name;
|
||||
} else if (role == QmlAircraftInfo::StateTagRole) {
|
||||
return QString::fromStdString(s.tag);
|
||||
return QString::fromStdString(s.primaryTag());
|
||||
} else if (role == QmlAircraftInfo::StateDescriptionRole) {
|
||||
return s.description;
|
||||
} else if (role == QmlAircraftInfo::StateExplicitRole) {
|
||||
if (s.tag == "auto")
|
||||
if (s.primaryTag() == "auto")
|
||||
return _explicitAutoState;
|
||||
return true;
|
||||
}
|
||||
|
@ -213,6 +223,28 @@ public:
|
|||
result[QmlAircraftInfo::StateDescriptionRole] = "description";
|
||||
return result;
|
||||
}
|
||||
|
||||
Q_INVOKABLE QString descriptionForState(int row) const
|
||||
{
|
||||
if ((row < 0) || (row >= _data.size()))
|
||||
return {};
|
||||
|
||||
const StateInfo& s = _data.at(row);
|
||||
return s.description;
|
||||
}
|
||||
|
||||
Q_INVOKABLE QString tagForState(int row) const
|
||||
{
|
||||
if ((row < 0) || (row >= _data.size()))
|
||||
return {};
|
||||
|
||||
return QString::fromStdString(_data.at(row).primaryTag());
|
||||
}
|
||||
|
||||
bool hasExplicitAuto() const
|
||||
{
|
||||
return _explicitAutoState;
|
||||
}
|
||||
private:
|
||||
AircraftStateVec _data;
|
||||
bool _explicitAutoState = false;
|
||||
|
@ -224,6 +256,7 @@ QmlAircraftInfo::QmlAircraftInfo(QObject *parent)
|
|||
: QObject(parent)
|
||||
, _delegate(new Delegate(this))
|
||||
{
|
||||
qmlRegisterUncreatableType<StatesModel>("FlightGear.Launcher", 1, 0, "StatesModel", "no");
|
||||
}
|
||||
|
||||
QmlAircraftInfo::~QmlAircraftInfo()
|
||||
|
@ -621,7 +654,7 @@ bool QmlAircraftInfo::isPackaged() const
|
|||
return _package != PackageRef();
|
||||
}
|
||||
|
||||
QAbstractListModel *QmlAircraftInfo::statesModel()
|
||||
StatesModel *QmlAircraftInfo::statesModel()
|
||||
{
|
||||
if (!hasStates())
|
||||
return nullptr;
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
struct AircraftItem;
|
||||
typedef QSharedPointer<AircraftItem> AircraftItemPtr;
|
||||
|
||||
class StatesModel;
|
||||
|
||||
class QmlAircraftInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -57,7 +59,7 @@ class QmlAircraftInfo : public QObject
|
|||
|
||||
Q_PROPERTY(bool hasStates READ hasStates NOTIFY infoChanged)
|
||||
|
||||
Q_PROPERTY(QAbstractListModel* statesModel READ statesModel NOTIFY infoChanged)
|
||||
Q_PROPERTY(StatesModel* statesModel READ statesModel NOTIFY infoChanged)
|
||||
|
||||
public:
|
||||
explicit QmlAircraftInfo(QObject *parent = nullptr);
|
||||
|
@ -110,7 +112,7 @@ public:
|
|||
static const int StateDescriptionRole;
|
||||
static const int StateExplicitRole;
|
||||
|
||||
QAbstractListModel* statesModel();
|
||||
StatesModel* statesModel();
|
||||
signals:
|
||||
void uriChanged();
|
||||
void infoChanged();
|
||||
|
@ -134,7 +136,7 @@ private:
|
|||
AircraftItemPtr _item;
|
||||
int _variant = 0;
|
||||
int _downloadBytes = 0;
|
||||
QScopedPointer<QAbstractListModel> _statesModel;
|
||||
QScopedPointer<StatesModel> _statesModel;
|
||||
};
|
||||
|
||||
#endif // QMLAIRCRAFTINFO_HXX
|
||||
|
|
92
src/GUI/RecentAircraftModel.cxx
Normal file
92
src/GUI/RecentAircraftModel.cxx
Normal file
|
@ -0,0 +1,92 @@
|
|||
#include "RecentAircraftModel.hxx"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QDebug>
|
||||
|
||||
#include "AircraftModel.hxx"
|
||||
|
||||
const int MAX_RECENT_AIRCRAFT = 20;
|
||||
|
||||
|
||||
RecentAircraftModel::RecentAircraftModel(AircraftItemModel* acModel, QObject* pr) :
|
||||
QAbstractListModel(pr),
|
||||
m_aircraftModel(acModel)
|
||||
{
|
||||
QSettings settings;
|
||||
const QStringList urls = settings.value("recent-aircraft").toStringList();
|
||||
m_data = QUrl::fromStringList(urls);
|
||||
}
|
||||
|
||||
void RecentAircraftModel::saveToSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("recent-aircraft", QUrl::toStringList(m_data));
|
||||
}
|
||||
|
||||
QUrl RecentAircraftModel::uriAt(int index) const
|
||||
{
|
||||
return m_data.at(index);
|
||||
}
|
||||
|
||||
QVariant RecentAircraftModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
const QUrl uri = m_data.at(index.row());
|
||||
if (role == Qt::DisplayRole) {
|
||||
return m_aircraftModel->nameForAircraftURI(uri);
|
||||
} else if (role == Qt::UserRole) {
|
||||
return uri;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
int RecentAircraftModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> RecentAircraftModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> result = QAbstractListModel::roleNames();
|
||||
result[Qt::DisplayRole] = "display";
|
||||
result[Qt::UserRole] = "uri";
|
||||
return result;
|
||||
}
|
||||
|
||||
QUrl RecentAircraftModel::mostRecent() const
|
||||
{
|
||||
if (m_data.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return m_data.front();
|
||||
}
|
||||
|
||||
void RecentAircraftModel::insert(QUrl aircraftUrl)
|
||||
{
|
||||
if (aircraftUrl.isEmpty())
|
||||
return;
|
||||
|
||||
int existingIndex = m_data.indexOf(aircraftUrl);
|
||||
if (existingIndex == 0) {
|
||||
// special, common case - nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
if (existingIndex >= 0) {
|
||||
beginRemoveRows(QModelIndex(), existingIndex, existingIndex);
|
||||
m_data.removeAt(existingIndex);
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
beginInsertRows(QModelIndex(), 0, 0);
|
||||
m_data.push_front(aircraftUrl);
|
||||
endInsertRows();
|
||||
|
||||
if (m_data.size() > MAX_RECENT_AIRCRAFT) {
|
||||
beginRemoveRows(QModelIndex(), MAX_RECENT_AIRCRAFT, m_data.size() - 1);
|
||||
// truncate the data at the correct size
|
||||
m_data = m_data.mid(0, MAX_RECENT_AIRCRAFT);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
34
src/GUI/RecentAircraftModel.hxx
Normal file
34
src/GUI/RecentAircraftModel.hxx
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef RECENTAIRCRAFTMODEL_HXX
|
||||
#define RECENTAIRCRAFTMODEL_HXX
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QUrl>
|
||||
|
||||
// forward decls
|
||||
class AircraftItemModel;
|
||||
|
||||
class RecentAircraftModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RecentAircraftModel(AircraftItemModel *acModel, QObject* pr = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
QUrl mostRecent() const;
|
||||
|
||||
void insert(QUrl aircraftUrl);
|
||||
|
||||
void saveToSettings();
|
||||
|
||||
Q_INVOKABLE QUrl uriAt(int index) const;
|
||||
private:
|
||||
AircraftItemModel* m_aircraftModel;
|
||||
QList<QUrl> m_data;
|
||||
};
|
||||
|
||||
#endif // RECENTAIRCRAFTMODEL_HXX
|
91
src/GUI/RecentLocationsModel.cxx
Normal file
91
src/GUI/RecentLocationsModel.cxx
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include "RecentLocationsModel.hxx"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
const int MAX_RECENT_LOCATIONS = 20;
|
||||
|
||||
RecentLocationsModel::RecentLocationsModel(QObject* pr) :
|
||||
QAbstractListModel(pr)
|
||||
{
|
||||
QSettings settings;
|
||||
m_data = settings.value("recent-location-sets").toList();
|
||||
}
|
||||
|
||||
void RecentLocationsModel::saveToSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("recent-location-sets", m_data);
|
||||
}
|
||||
|
||||
QVariantMap RecentLocationsModel::locationAt(int index) const
|
||||
{
|
||||
return m_data.at(index).toMap();
|
||||
}
|
||||
|
||||
QVariant RecentLocationsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
const QVariantMap loc = m_data.at(index.row()).toMap();
|
||||
if (role == Qt::DisplayRole) {
|
||||
return loc.value("text");
|
||||
} else if (role == Qt::UserRole) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
int RecentLocationsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> RecentLocationsModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> result = QAbstractListModel::roleNames();
|
||||
result[Qt::DisplayRole] = "display";
|
||||
// result[Qt::UserRole] = "uri";
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariantMap RecentLocationsModel::mostRecent() const
|
||||
{
|
||||
if (m_data.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return m_data.front().toMap();
|
||||
}
|
||||
|
||||
void RecentLocationsModel::insert(QVariant location)
|
||||
{
|
||||
if (location.toMap().isEmpty())
|
||||
return;
|
||||
|
||||
QVariant locDesc = location.toMap().value("text");
|
||||
auto it = std::find_if(m_data.begin(), m_data.end(),
|
||||
[locDesc](QVariant v) { return v.toMap().value("text") == locDesc; });
|
||||
if (it == m_data.begin()) {
|
||||
// special, common case - nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
if (it != m_data.end()) {
|
||||
int existingIndex = std::distance(m_data.begin(), it);
|
||||
beginRemoveRows(QModelIndex(), existingIndex, existingIndex);
|
||||
m_data.erase(it);
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
beginInsertRows(QModelIndex(), 0, 0);
|
||||
m_data.push_front(location);
|
||||
endInsertRows();
|
||||
|
||||
if (m_data.size() > MAX_RECENT_LOCATIONS) {
|
||||
beginRemoveRows(QModelIndex(), MAX_RECENT_LOCATIONS, m_data.size() - 1);
|
||||
// truncate the data at the correct size
|
||||
m_data = m_data.mid(0, MAX_RECENT_LOCATIONS);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
31
src/GUI/RecentLocationsModel.hxx
Normal file
31
src/GUI/RecentLocationsModel.hxx
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef RECENTLOCATIONSMODEL_HXX
|
||||
#define RECENTLOCATIONSMODEL_HXX
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QvariantList>
|
||||
|
||||
|
||||
class RecentLocationsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RecentLocationsModel(QObject* pr = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
QVariantMap mostRecent() const;
|
||||
|
||||
void insert(QVariant location);
|
||||
|
||||
void saveToSettings();
|
||||
|
||||
Q_INVOKABLE QVariantMap locationAt(int index) const;
|
||||
private:
|
||||
QVariantList m_data;
|
||||
};
|
||||
|
||||
#endif // RECENTLOCATIONSMODEL_HXX
|
|
@ -4,7 +4,8 @@ import "."
|
|||
Text {
|
||||
signal clicked();
|
||||
|
||||
color: mouse.containsMouse ? Style.themeColor : Style.baseTextColor
|
||||
property color baseTextColor: Style.baseTextColor
|
||||
color: mouse.containsMouse ? Style.themeColor : baseTextColor
|
||||
|
||||
MouseArea {
|
||||
id: mouse
|
||||
|
@ -12,5 +13,7 @@ Text {
|
|||
anchors.fill: parent
|
||||
|
||||
onClicked: parent.clicked();
|
||||
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
}
|
||||
|
|
100
src/GUI/qml/HistoryPopup.qml
Normal file
100
src/GUI/qml/HistoryPopup.qml
Normal file
|
@ -0,0 +1,100 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Window 2.0
|
||||
import FlightGear.Launcher 1.0
|
||||
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property var model: undefined
|
||||
property string displayRole: "display"
|
||||
property bool enabled: true
|
||||
|
||||
implicitHeight: button.height
|
||||
implicitWidth: button.width
|
||||
|
||||
signal selected(var index);
|
||||
|
||||
Rectangle {
|
||||
id: button
|
||||
|
||||
width: icon.width
|
||||
height: icon.height
|
||||
radius: Style.roundRadius
|
||||
|
||||
color: enabled ? (mouse.containsMouse ? Style.activeColor : Style.themeColor) : Style.disabledThemeColor
|
||||
|
||||
Image {
|
||||
id: icon
|
||||
source: "qrc:///history-icon"
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
id: mouse
|
||||
hoverEnabled: true
|
||||
enabled: root.enabled
|
||||
onClicked: {
|
||||
var screenPos = _launcher.mapToGlobal(button, Qt.point(-popupFrame.width, 0))
|
||||
popupFrame.x = screenPos.x;
|
||||
popupFrame.y = screenPos.y;
|
||||
popupFrame.visible = true
|
||||
tracker.window = popupFrame
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PopupWindowTracker {
|
||||
id: tracker
|
||||
}
|
||||
|
||||
Window {
|
||||
id: popupFrame
|
||||
|
||||
flags: Qt.Popup
|
||||
height: choicesColumn.childrenRect.height + Style.margin * 2
|
||||
width: choicesColumn.childrenRect.width + Style.margin * 2
|
||||
visible: false
|
||||
color: "white"
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
border.color: Style.minorFrameColor
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
// text repeater
|
||||
Column {
|
||||
id: choicesColumn
|
||||
spacing: Style.margin
|
||||
x: Style.margin
|
||||
y: Style.margin
|
||||
|
||||
Repeater {
|
||||
id: choicesRepeater
|
||||
model: root.model
|
||||
delegate:
|
||||
Text {
|
||||
id: choiceText
|
||||
|
||||
// Taken from TableViewItemDelegateLoader.qml to follow QML role conventions
|
||||
text: model && model.hasOwnProperty(displayRole) ? model[displayRole] // Qml ListModel and QAbstractItemModel
|
||||
: modelData && modelData.hasOwnProperty(displayRole) ? modelData[displayRole] // QObjectList / QObject
|
||||
: modelData != undefined ? modelData : "" // Models without role
|
||||
height: implicitHeight + Style.margin
|
||||
|
||||
MouseArea {
|
||||
width: popupFrame.width // full width of the popup
|
||||
height: parent.height
|
||||
onClicked: {
|
||||
popupFrame.visible = false
|
||||
root.selected(model.index);
|
||||
}
|
||||
}
|
||||
} // of Text delegate
|
||||
} // text repeater
|
||||
} // text column
|
||||
} // of popup Window
|
||||
}
|
|
@ -14,7 +14,7 @@ Item {
|
|||
property int currentIndex: 0
|
||||
property bool __dummy: false
|
||||
|
||||
implicitHeight: label.implicitHeight
|
||||
implicitHeight: Math.max(label.implicitHeight, currentChoiceFrame.height)
|
||||
|
||||
Item {
|
||||
Repeater {
|
||||
|
@ -40,6 +40,10 @@ Item {
|
|||
__dummy = !__dummy
|
||||
}
|
||||
|
||||
onModelChanged: {
|
||||
__dummy = !__dummy // force update of currentText
|
||||
}
|
||||
|
||||
function currentText()
|
||||
{
|
||||
var foo = __dummy; // fake propery dependency to update this
|
||||
|
|
|
@ -21,6 +21,10 @@ QtObject
|
|||
readonly property string baseTextColor: "#3f3f3f"
|
||||
|
||||
readonly property int baseFontPixelSize: 12
|
||||
readonly property int headingFontPixelSize: 18
|
||||
|
||||
readonly property string disabledTextColor: "#5f5f5f"
|
||||
|
||||
readonly property double panelOpacity: 0.8
|
||||
}
|
||||
|
||||
|
|
321
src/GUI/qml/Summary.qml
Normal file
321
src/GUI/qml/Summary.qml
Normal file
|
@ -0,0 +1,321 @@
|
|||
import QtQuick 2.0
|
||||
import FlightGear.Launcher 1.0
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#7f7f7f"
|
||||
}
|
||||
|
||||
property string __aircraftDescription
|
||||
|
||||
// conditional bindings on aircraft description
|
||||
Binding {
|
||||
when: _launcher.selectedAircraftInfo != undefined
|
||||
target: root
|
||||
property: "__aircraftDescription"
|
||||
value: _launcher.selectedAircraftInfo.description
|
||||
}
|
||||
|
||||
Binding {
|
||||
when: _launcher.selectedAircraftInfo == undefined
|
||||
target: root
|
||||
property: "__aircraftDescription"
|
||||
value: ""
|
||||
}
|
||||
|
||||
// base image when preview not available
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "magenta"
|
||||
}
|
||||
|
||||
PreviewImage {
|
||||
id: preview
|
||||
anchors.centerIn: parent
|
||||
|
||||
// over-zoom the preview to fill the entire space available
|
||||
readonly property double scale: Math.max(root.width / sourceSize.width,
|
||||
root.height / sourceSize.height)
|
||||
|
||||
width: height * aspectRatio
|
||||
height: scale * sourceSize.height
|
||||
|
||||
property var urlsList: []
|
||||
property int __currentUrl: 0
|
||||
|
||||
onUrlsListChanged: {
|
||||
__currentUrl = 0;
|
||||
}
|
||||
|
||||
Timer {
|
||||
running: true
|
||||
interval: 8000
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
var len = preview.urlsList.length
|
||||
preview.__currentUrl = (preview.__currentUrl + 1) % len
|
||||
}
|
||||
}
|
||||
|
||||
visible: imageUrl != ""
|
||||
imageUrl: urlsList[__currentUrl]
|
||||
|
||||
// conditional binding when we have valid previews
|
||||
Binding {
|
||||
when: _launcher.selectedAircraftInfo != undefined &&
|
||||
(_launcher.selectedAircraftInfo.previews.length > 0)
|
||||
target: preview
|
||||
property: "urlsList"
|
||||
value: _launcher.selectedAircraftInfo.previews
|
||||
}
|
||||
|
||||
Binding {
|
||||
when: _launcher.selectedAircraftInfo == undefined ||
|
||||
_launcher.selectedAircraftInfo.previews.length == 0
|
||||
target: preview
|
||||
property: "urlsList"
|
||||
value: _launcher.defaultSplashUrls()
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: logoText
|
||||
font.pointSize: Style.strutSize * 2
|
||||
font.italic: true
|
||||
font.bold: true
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
margins: Style.strutSize
|
||||
}
|
||||
fontSizeMode: Text.Fit
|
||||
text: "FlightGear " + _launcher.versionString
|
||||
color: "white"
|
||||
style: Text.Outline
|
||||
styleColor: "black"
|
||||
}
|
||||
|
||||
ClickableText {
|
||||
anchors {
|
||||
left: logoText.left
|
||||
right: logoText.right
|
||||
}
|
||||
|
||||
// anchoring to logoText bottom doesn't work as expected because of
|
||||
// dynamic text sizing, so bind it manually
|
||||
y: logoText.y + Style.margin + logoText.contentHeight
|
||||
wrapMode: Text.WordWrap
|
||||
text: "Licenced under the GNU Public License (GPL) version 2.0 - click for more info"
|
||||
baseTextColor: "white"
|
||||
style: Text.Outline
|
||||
styleColor: "black"
|
||||
|
||||
onClicked: {
|
||||
_launcher.launchUrl("http://flightgear.org/license.html");
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: summaryPanel
|
||||
|
||||
color: "white"
|
||||
opacity: Style.panelOpacity
|
||||
// radius: Style.roundRadius
|
||||
border.width: 1
|
||||
border.color: Style.frameColor
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
margins: Style.strutSize
|
||||
}
|
||||
|
||||
height: summaryGrid.height + Style.margin * 2
|
||||
|
||||
Grid {
|
||||
id: summaryGrid
|
||||
columns: 3
|
||||
columnSpacing: Style.margin
|
||||
rowSpacing: Style.margin
|
||||
|
||||
readonly property int middleColumnWidth: summaryGrid.width - (locationLabel.width + Style.margin * 2 + aircraftHistoryPopup.width)
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
margins: Style.margin
|
||||
}
|
||||
|
||||
// aircraft name row
|
||||
Text {
|
||||
text: qsTr("Aircraft:")
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pixelSize: Style.headingFontPixelSize
|
||||
}
|
||||
|
||||
// TODO - make clickable, jump to to the aircraft in the installed
|
||||
// aircraft list
|
||||
Text {
|
||||
text: _launcher.selectedAircraftInfo.name
|
||||
font.pixelSize: Style.headingFontPixelSize
|
||||
}
|
||||
|
||||
HistoryPopup {
|
||||
id: aircraftHistoryPopup
|
||||
model: _launcher.aircraftHistory
|
||||
onSelected: {
|
||||
_launcher.selectedAircraft = _launcher.aircraftHistory.uriAt(index)
|
||||
}
|
||||
}
|
||||
|
||||
// empty space in next row (thumbnail, long aircraft description)
|
||||
Item {
|
||||
width: 1; height: 1
|
||||
}
|
||||
|
||||
Item {
|
||||
id: aircraftDetailsRow
|
||||
width: summaryGrid.middleColumnWidth
|
||||
height: Math.max(thumbnail.height, aircraftDescriptionText.height)
|
||||
|
||||
ThumbnailImage {
|
||||
id: thumbnail
|
||||
aircraftUri: _launcher.selectedAircraft
|
||||
maximumSize.width: 172
|
||||
maximumSize.height: 128
|
||||
}
|
||||
|
||||
Text {
|
||||
id: aircraftDescriptionText
|
||||
anchors {
|
||||
left: thumbnail.right
|
||||
leftMargin: Style.margin
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
text: root.__aircraftDescription
|
||||
visible: root.__aircraftDescription != ""
|
||||
wrapMode: Text.WordWrap
|
||||
maximumLineCount: 5
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Item {
|
||||
width: 1; height: 1
|
||||
}
|
||||
|
||||
// aircraft state row, if enabled
|
||||
|
||||
Item {
|
||||
width: 1; height: 1
|
||||
visible: stateSelectionGroup.visible
|
||||
}
|
||||
|
||||
Column {
|
||||
id: stateSelectionGroup
|
||||
visible: _launcher.selectedAircraftInfo.hasStates
|
||||
width: summaryGrid.middleColumnWidth
|
||||
spacing: Style.margin
|
||||
|
||||
PopupChoice {
|
||||
id: stateSelectionCombo
|
||||
model: _launcher.selectedAircraftInfo.statesModel
|
||||
displayRole: "name"
|
||||
label: qsTr("State:")
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Text {
|
||||
id: stateDescriptionText
|
||||
wrapMode: Text.WordWrap
|
||||
maximumLineCount: 5
|
||||
elide: Text.ElideRight
|
||||
width: parent.width
|
||||
|
||||
Binding {
|
||||
when: _launcher.selectedAircraftInfo.statesModel != null
|
||||
target: stateDescriptionText
|
||||
property: "text"
|
||||
value: _launcher.selectedAircraftInfo.statesModel.descriptionForState(stateSelectionCombo.currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: _config
|
||||
onCollect: {
|
||||
if (!_launcher.selectedAircraftInfo.hasStates)
|
||||
return;
|
||||
|
||||
var state = _launcher.selectedAircraftInfo.statesModel.tagForState(stateSelectionCombo.currentIndex);
|
||||
if (state === "auto" && !_launcher.selectedAircraftInfo.statesModel.hasExplicitAuto) {
|
||||
// auto state selection if not handled by aircraft
|
||||
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
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 1; height: 1
|
||||
visible: stateSelectionGroup.visible
|
||||
}
|
||||
|
||||
// location summary row
|
||||
Text {
|
||||
id: locationLabel
|
||||
text: qsTr("Location:")
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pixelSize: Style.headingFontPixelSize
|
||||
}
|
||||
|
||||
// TODO - make clickable, jump to the location page
|
||||
Text {
|
||||
text: _launcher.locationDescription
|
||||
font.pixelSize: Style.headingFontPixelSize
|
||||
}
|
||||
|
||||
HistoryPopup {
|
||||
id: locationHistoryPopup
|
||||
model: _launcher.locationHistory
|
||||
onSelected: {
|
||||
_launcher.restoreLocation(_launcher.locationHistory.locationAt(index))
|
||||
}
|
||||
}
|
||||
|
||||
// settings summary row
|
||||
Text {
|
||||
text: qsTr("Settings:")
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pixelSize: Style.headingFontPixelSize
|
||||
}
|
||||
|
||||
Text {
|
||||
text: _launcher.combinedSummary.join(", ")
|
||||
font.pixelSize: Style.headingFontPixelSize
|
||||
wrapMode: Text.WordWrap
|
||||
maximumLineCount: 2
|
||||
elide: Text.ElideRight
|
||||
width: summaryGrid.middleColumnWidth
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 1; height: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,21 +71,12 @@
|
|||
<file>qml/DateTimeEdit.qml</file>
|
||||
<file>qml/DateTimeValueEdit.qml</file>
|
||||
<file>qml/SettingsDateTimePicker.qml</file>
|
||||
<file>qml/Summary.qml</file>
|
||||
<file>qml/HistoryPopup.qml</file>
|
||||
</qresource>
|
||||
<qresource prefix="/preview">
|
||||
<file alias="close-icon">preview-close.png</file>
|
||||
<file alias="left-arrow-icon">preview-left-arrow.png</file>
|
||||
<file alias="right-arrow-icon">preview-right-arrow.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/settings">
|
||||
<file alias="downloads">DownloadSettings.qml</file>
|
||||
<file alias="general">GeneralSettings.qml</file>
|
||||
<file alias="mp">MPSettings.qml</file>
|
||||
<file alias="render">RenderSettings.qml</file>
|
||||
<file alias="view">ViewSettings.qml</file>
|
||||
</qresource>
|
||||
<qresource prefix="/environment">
|
||||
<file alias="time">TimeSettings.qml</file>
|
||||
<file alias="weather">Weather.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Loading…
Reference in a new issue