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
|
MPServersModel.h
|
||||||
PathUrlHelper.cxx
|
PathUrlHelper.cxx
|
||||||
PathUrlHelper.hxx
|
PathUrlHelper.hxx
|
||||||
|
RecentAircraftModel.cxx
|
||||||
|
RecentAircraftModel.hxx
|
||||||
|
RecentLocationsModel.cxx
|
||||||
|
RecentLocationsModel.hxx
|
||||||
${uic_sources}
|
${uic_sources}
|
||||||
${qrc_sources}
|
${qrc_sources}
|
||||||
${qml_sources})
|
${qml_sources})
|
||||||
|
|
|
@ -34,6 +34,20 @@ std::string defaultAirportICAO()
|
||||||
return airportCode;
|
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()
|
DefaultAircraftLocator::DefaultAircraftLocator()
|
||||||
{
|
{
|
||||||
SGPropertyNode_ptr root = loadXMLDefaults();
|
SGPropertyNode_ptr root = loadXMLDefaults();
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace flightgear
|
||||||
|
|
||||||
std::string defaultAirportICAO();
|
std::string defaultAirportICAO();
|
||||||
|
|
||||||
|
string_list defaultSplashScreenPaths();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* we don't want to rely on the main AircraftModel threaded scan, to find the
|
* 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
|
* default aircraft, so we do a synchronous scan here, on the assumption that
|
||||||
|
|
|
@ -250,231 +250,31 @@
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</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">
|
<widget class="QWidget" name="summaryPage">
|
||||||
<item row="0" column="3" colspan="2">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<widget class="QLabel" name="appTitleLabel">
|
<property name="spacing">
|
||||||
<property name="font">
|
<number>4</number>
|
||||||
<font>
|
</property>
|
||||||
<pointsize>48</pointsize>
|
<property name="leftMargin">
|
||||||
<weight>75</weight>
|
<number>4</number>
|
||||||
<bold>true</bold>
|
</property>
|
||||||
</font>
|
<property name="topMargin">
|
||||||
</property>
|
<number>4</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>FlightGear 2017.1.0</string>
|
<property name="rightMargin">
|
||||||
</property>
|
<number>4</number>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="bottomMargin">
|
||||||
<item row="3" column="4">
|
<number>4</number>
|
||||||
<widget class="QPushButton" name="aircraftHistory">
|
</property>
|
||||||
<property name="autoDefault">
|
<item>
|
||||||
<bool>false</bool>
|
<widget class="QQuickWidget" name="summary"/>
|
||||||
</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>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
||||||
|
|
||||||
<widget class="QWidget" name="aircraftPage">
|
<widget class="QWidget" name="aircraftPage">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QNetworkDiskCache>
|
#include <QNetworkDiskCache>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
@ -49,11 +52,11 @@
|
||||||
#include "LauncherArgumentTokenizer.hxx"
|
#include "LauncherArgumentTokenizer.hxx"
|
||||||
#include "PathUrlHelper.hxx"
|
#include "PathUrlHelper.hxx"
|
||||||
#include "PopupWindowTracker.hxx"
|
#include "PopupWindowTracker.hxx"
|
||||||
|
#include "RecentAircraftModel.hxx"
|
||||||
|
#include "RecentLocationsModel.hxx"
|
||||||
|
|
||||||
#include "ui_Launcher.h"
|
#include "ui_Launcher.h"
|
||||||
|
|
||||||
const int MAX_RECENT_AIRCRAFT = 20;
|
|
||||||
|
|
||||||
using namespace simgear::pkg;
|
using namespace simgear::pkg;
|
||||||
|
|
||||||
extern void restartTheApp(QStringList fgArgs);
|
extern void restartTheApp(QStringList fgArgs);
|
||||||
|
@ -75,14 +78,11 @@ QQmlPrivate::AutoParentResult launcher_autoParent(QObject* thing, QObject* paren
|
||||||
|
|
||||||
LauncherMainWindow::LauncherMainWindow() :
|
LauncherMainWindow::LauncherMainWindow() :
|
||||||
QMainWindow(),
|
QMainWindow(),
|
||||||
m_ui(NULL),
|
|
||||||
m_subsystemIdleTimer(NULL)
|
m_subsystemIdleTimer(NULL)
|
||||||
{
|
{
|
||||||
m_ui.reset(new Ui::Launcher);
|
m_ui.reset(new Ui::Launcher);
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
m_ui->appTitleLabel->setText(tr("FlightGear %1").arg(FLIGHTGEAR_VERSION));
|
|
||||||
|
|
||||||
QMenuBar* mb = menuBar();
|
QMenuBar* mb = menuBar();
|
||||||
|
|
||||||
#if !defined(Q_OS_MAC)
|
#if !defined(Q_OS_MAC)
|
||||||
|
@ -108,15 +108,7 @@ LauncherMainWindow::LauncherMainWindow() :
|
||||||
|
|
||||||
m_serversModel = new MPServersModel(this);
|
m_serversModel = new MPServersModel(this);
|
||||||
|
|
||||||
// keep the description QLabel in sync as the current item changes
|
m_locationHistory = new RecentLocationsModel(this);
|
||||||
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_selectedAircraftInfo = new QmlAircraftInfo(this);
|
m_selectedAircraftInfo = new QmlAircraftInfo(this);
|
||||||
initQML();
|
initQML();
|
||||||
|
@ -135,23 +127,14 @@ LauncherMainWindow::LauncherMainWindow() :
|
||||||
connect(m_ui->settingsButton, &QAbstractButton::clicked, this, &LauncherMainWindow::onClickToolboxButton);
|
connect(m_ui->settingsButton, &QAbstractButton::clicked, this, &LauncherMainWindow::onClickToolboxButton);
|
||||||
connect(m_ui->addOnsButton, &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,
|
connect(m_ui->location, &LocationWidget::descriptionChanged,
|
||||||
m_ui->locationDescription, &QLabel::setText);
|
this, &LauncherMainWindow::summaryChanged);
|
||||||
|
|
||||||
QAction* qa = new QAction(this);
|
QAction* qa = new QAction(this);
|
||||||
qa->setShortcut(QKeySequence("Ctrl+Q"));
|
qa->setShortcut(QKeySequence("Ctrl+Q"));
|
||||||
connect(qa, &QAction::triggered, this, &LauncherMainWindow::onQuit);
|
connect(qa, &QAction::triggered, this, &LauncherMainWindow::onQuit);
|
||||||
addAction(qa);
|
addAction(qa);
|
||||||
|
|
||||||
QIcon historyIcon(":/history-icon");
|
|
||||||
m_ui->aircraftHistory->setIcon(historyIcon);
|
|
||||||
m_ui->locationHistory->setIcon(historyIcon);
|
|
||||||
|
|
||||||
m_aircraftModel = new AircraftItemModel(this);
|
m_aircraftModel = new AircraftItemModel(this);
|
||||||
m_installedAircraftModel = new AircraftProxyModel(this, m_aircraftModel);
|
m_installedAircraftModel = new AircraftProxyModel(this, m_aircraftModel);
|
||||||
m_installedAircraftModel->setInstalledFilterEnabled(true);
|
m_installedAircraftModel->setInstalledFilterEnabled(true);
|
||||||
|
@ -161,40 +144,13 @@ LauncherMainWindow::LauncherMainWindow() :
|
||||||
|
|
||||||
m_aircraftSearchModel = new AircraftProxyModel(this, m_aircraftModel);
|
m_aircraftSearchModel = new AircraftProxyModel(this, m_aircraftModel);
|
||||||
|
|
||||||
m_ui->aircraftList->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_aircraftHistory = new RecentAircraftModel(m_aircraftModel, this);
|
||||||
|
|
||||||
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"));
|
|
||||||
|
|
||||||
connect(m_aircraftModel, &AircraftItemModel::aircraftInstallCompleted,
|
connect(m_aircraftModel, &AircraftItemModel::aircraftInstallCompleted,
|
||||||
this, &LauncherMainWindow::onAircraftInstalledCompleted);
|
this, &LauncherMainWindow::onAircraftInstalledCompleted);
|
||||||
connect(m_aircraftModel, &AircraftItemModel::aircraftInstallFailed,
|
connect(m_aircraftModel, &AircraftItemModel::aircraftInstallFailed,
|
||||||
this, &LauncherMainWindow::onAircraftInstallFailed);
|
this, &LauncherMainWindow::onAircraftInstallFailed);
|
||||||
|
|
||||||
|
|
||||||
connect(LocalAircraftCache::instance(),
|
connect(LocalAircraftCache::instance(),
|
||||||
&LocalAircraftCache::scanCompleted,
|
&LocalAircraftCache::scanCompleted,
|
||||||
this, &LauncherMainWindow::updateSelectedAircraft);
|
this, &LauncherMainWindow::updateSelectedAircraft);
|
||||||
|
@ -219,8 +175,50 @@ LauncherMainWindow::LauncherMainWindow() :
|
||||||
m_ui->stack->addWidget(m_viewCommandLinePage);
|
m_ui->stack->addWidget(m_viewCommandLinePage);
|
||||||
|
|
||||||
restoreSettings();
|
restoreSettings();
|
||||||
updateSettingsSummary();
|
|
||||||
|
emit summaryChanged();
|
||||||
emit showNoOfficialHangarChanged();
|
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()
|
void LauncherMainWindow::initQML()
|
||||||
|
@ -240,6 +238,9 @@ void LauncherMainWindow::initQML()
|
||||||
qmlRegisterUncreatableType<QAbstractItemModel>("FlightGear.Launcher", 1, 0, "QAIM", "no");
|
qmlRegisterUncreatableType<QAbstractItemModel>("FlightGear.Launcher", 1, 0, "QAIM", "no");
|
||||||
qmlRegisterUncreatableType<AircraftProxyModel>("FlightGear.Launcher", 1, 0, "AircraftProxyModel", "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<SettingsControl>("FlightGear.Launcher", 1, 0, "Control", "Base class");
|
||||||
qmlRegisterUncreatableType<LaunchConfig>("FlightGear.Launcher", 1, 0, "LaunchConfig", "Singleton API");
|
qmlRegisterUncreatableType<LaunchConfig>("FlightGear.Launcher", 1, 0, "LaunchConfig", "Singleton API");
|
||||||
qmlRegisterType<FileDialogWrapper>("FlightGear.Launcher", 1, 0, "FileDialog");
|
qmlRegisterType<FileDialogWrapper>("FlightGear.Launcher", 1, 0, "FileDialog");
|
||||||
|
@ -265,6 +266,9 @@ void LauncherMainWindow::initQML()
|
||||||
settingsContext->setContextProperty("_config", m_config);
|
settingsContext->setContextProperty("_config", m_config);
|
||||||
settingsContext->setContextProperty("_osName", osName);
|
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<LocalAircraftCache>("FlightGear.Launcher", 1, 0, "LocalAircraftCache", "Aircraft cache");
|
||||||
qmlRegisterUncreatableType<AircraftItemModel>("FlightGear.Launcher", 1, 0, "AircraftModel", "Built-in model");
|
qmlRegisterUncreatableType<AircraftItemModel>("FlightGear.Launcher", 1, 0, "AircraftModel", "Built-in model");
|
||||||
qmlRegisterType<ThumbnailImageItem>("FlightGear.Launcher", 1, 0, "ThumbnailImage");
|
qmlRegisterType<ThumbnailImageItem>("FlightGear.Launcher", 1, 0, "ThumbnailImage");
|
||||||
|
@ -311,12 +315,8 @@ void LauncherMainWindow::restoreSettings()
|
||||||
|
|
||||||
restoreGeometry(settings.value("window-geometry").toByteArray());
|
restoreGeometry(settings.value("window-geometry").toByteArray());
|
||||||
|
|
||||||
// full paths to -set.xml files
|
m_selectedAircraft = m_aircraftHistory->mostRecent();
|
||||||
m_recentAircraft = QUrl::fromStringList(settings.value("recent-aircraft").toStringList());
|
if (m_selectedAircraft.isEmpty()) {
|
||||||
|
|
||||||
if (!m_recentAircraft.empty()) {
|
|
||||||
m_selectedAircraft = m_recentAircraft.front();
|
|
||||||
} else {
|
|
||||||
// select the default aircraft specified in defaults.xml
|
// select the default aircraft specified in defaults.xml
|
||||||
flightgear::DefaultAircraftLocator da;
|
flightgear::DefaultAircraftLocator da;
|
||||||
if (da.foundPath().exists()) {
|
if (da.foundPath().exists()) {
|
||||||
|
@ -332,22 +332,16 @@ void LauncherMainWindow::restoreSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui->location->restoreSettings();
|
m_ui->location->restoreSettings();
|
||||||
m_recentLocations = settings.value("recent-location-sets").toList();
|
QVariantMap currentLocation = m_locationHistory->mostRecent();
|
||||||
QVariantMap currentLocation;
|
if (currentLocation.isEmpty()) {
|
||||||
if (m_recentLocations.isEmpty()) {
|
|
||||||
// use the default
|
// use the default
|
||||||
std::string defaultAirport = flightgear::defaultAirportICAO();
|
std::string defaultAirport = flightgear::defaultAirportICAO();
|
||||||
FGAirportRef apt = FGAirport::findByIdent(defaultAirport);
|
FGAirportRef apt = FGAirport::findByIdent(defaultAirport);
|
||||||
if (apt) {
|
if (apt) {
|
||||||
currentLocation["location-id"] = static_cast<qlonglong>(apt->guid());
|
currentLocation["location-id"] = static_cast<qlonglong>(apt->guid());
|
||||||
currentLocation["location-apt-runway"] = "active";
|
currentLocation["location-apt-runway"] = "active";
|
||||||
qDebug() << "restored default airport:" << QString::fromStdString(defaultAirport);
|
|
||||||
} // otherwise we failed to find the default airport in the nav-db :(
|
} // 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);
|
m_ui->location->restoreLocation(currentLocation);
|
||||||
|
|
||||||
updateSelectedAircraft();
|
updateSelectedAircraft();
|
||||||
|
@ -363,9 +357,10 @@ void LauncherMainWindow::saveSettings()
|
||||||
{
|
{
|
||||||
emit requestSaveState();
|
emit requestSaveState();
|
||||||
|
|
||||||
|
m_aircraftHistory->saveToSettings();
|
||||||
|
m_locationHistory->saveToSettings();
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.setValue("recent-aircraft", QUrl::toStringList(m_recentAircraft));
|
|
||||||
settings.setValue("recent-location-sets", m_recentLocations);
|
|
||||||
settings.setValue("window-geometry", saveGeometry());
|
settings.setValue("window-geometry", saveGeometry());
|
||||||
|
|
||||||
Q_FOREACH(SettingsSection* ss, findChildren<SettingsSection*>()) {
|
Q_FOREACH(SettingsSection* ss, findChildren<SettingsSection*>()) {
|
||||||
|
@ -416,41 +411,13 @@ void LauncherMainWindow::onRun()
|
||||||
m_config->reset();
|
m_config->reset();
|
||||||
m_config->collect();
|
m_config->collect();
|
||||||
|
|
||||||
// aircraft
|
m_aircraftHistory->insert(m_selectedAircraft);
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_ui->stateCombo->isVisible()) {
|
QVariant locSet = m_ui->location->saveLocation();
|
||||||
// apply state setting
|
m_locationHistory->insert(locSet);
|
||||||
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
|
|
||||||
|
|
||||||
// aircraft paths
|
// aircraft paths
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
updateLocationHistory();
|
|
||||||
|
|
||||||
QString downloadDir = settings.value("downloadSettings/downloadDir").toString();
|
QString downloadDir = settings.value("downloadSettings/downloadDir").toString();
|
||||||
if (!downloadDir.isEmpty()) {
|
if (!downloadDir.isEmpty()) {
|
||||||
QDir d(downloadDir);
|
QDir d(downloadDir);
|
||||||
|
@ -480,7 +447,7 @@ void LauncherMainWindow::onRun()
|
||||||
qApp->exit(1);
|
qApp->exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LauncherMainWindow::selectStateAutomatically()
|
QString LauncherMainWindow::selectAircraftStateAutomatically()
|
||||||
{
|
{
|
||||||
if (m_ui->location->isAirborneLocation()) {
|
if (m_ui->location->isAirborneLocation()) {
|
||||||
return "approach";
|
return "approach";
|
||||||
|
@ -517,13 +484,7 @@ void LauncherMainWindow::onApply()
|
||||||
qWarning() << "unsupported aircraft launch URL" << m_selectedAircraft;
|
qWarning() << "unsupported aircraft launch URL" << m_selectedAircraft;
|
||||||
}
|
}
|
||||||
|
|
||||||
// manage aircraft history
|
m_aircraftHistory->insert(m_selectedAircraft);
|
||||||
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();
|
|
||||||
|
|
||||||
globals->get_props()->setStringValue("/sim/aircraft", aircraftPropValue);
|
globals->get_props()->setStringValue("/sim/aircraft", aircraftPropValue);
|
||||||
globals->get_props()->setStringValue("/sim/aircraft-dir", aircraftDir);
|
globals->get_props()->setStringValue("/sim/aircraft-dir", aircraftDir);
|
||||||
}
|
}
|
||||||
|
@ -536,23 +497,6 @@ void LauncherMainWindow::onApply()
|
||||||
m_runInApp = false;
|
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()
|
void LauncherMainWindow::onQuit()
|
||||||
{
|
{
|
||||||
if (m_inAppMode) {
|
if (m_inAppMode) {
|
||||||
|
@ -628,6 +572,7 @@ void LauncherMainWindow::updateSelectedAircraft()
|
||||||
m_selectedAircraftInfo->setUri(m_selectedAircraft);
|
m_selectedAircraftInfo->setUri(m_selectedAircraft);
|
||||||
QModelIndex index = m_aircraftModel->indexOfAircraftURI(m_selectedAircraft);
|
QModelIndex index = m_aircraftModel->indexOfAircraftURI(m_selectedAircraft);
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
|
#if 0
|
||||||
QPixmap pm = index.data(Qt::DecorationRole).value<QPixmap>();
|
QPixmap pm = index.data(Qt::DecorationRole).value<QPixmap>();
|
||||||
m_ui->thumbnail->setPixmap(pm);
|
m_ui->thumbnail->setPixmap(pm);
|
||||||
|
|
||||||
|
@ -640,7 +585,7 @@ void LauncherMainWindow::updateSelectedAircraft()
|
||||||
QVariant longDesc = index.data(AircraftLongDescriptionRole);
|
QVariant longDesc = index.data(AircraftLongDescriptionRole);
|
||||||
m_ui->aircraftDescription->setVisible(!longDesc.isNull());
|
m_ui->aircraftDescription->setVisible(!longDesc.isNull());
|
||||||
m_ui->aircraftDescription->setText(longDesc.toString());
|
m_ui->aircraftDescription->setText(longDesc.toString());
|
||||||
|
#endif
|
||||||
int status = index.data(AircraftPackageStatusRole).toInt();
|
int status = index.data(AircraftPackageStatusRole).toInt();
|
||||||
bool canRun = (status == LocalAircraftCache::PackageInstalled);
|
bool canRun = (status == LocalAircraftCache::PackageInstalled);
|
||||||
m_ui->flyButton->setEnabled(canRun);
|
m_ui->flyButton->setEnabled(canRun);
|
||||||
|
@ -655,6 +600,7 @@ void LauncherMainWindow::updateSelectedAircraft()
|
||||||
m_ui->location->setAircraftType(aircraftType);
|
m_ui->location->setAircraftType(aircraftType);
|
||||||
|
|
||||||
const bool hasStates = m_selectedAircraftInfo->hasStates();
|
const bool hasStates = m_selectedAircraftInfo->hasStates();
|
||||||
|
#if 0
|
||||||
m_ui->stateCombo->setVisible(hasStates);
|
m_ui->stateCombo->setVisible(hasStates);
|
||||||
m_ui->stateLabel->setVisible(hasStates);
|
m_ui->stateLabel->setVisible(hasStates);
|
||||||
m_ui->stateDescription->setVisible(false);
|
m_ui->stateDescription->setVisible(false);
|
||||||
|
@ -664,13 +610,16 @@ void LauncherMainWindow::updateSelectedAircraft()
|
||||||
// hiden when no description is present
|
// hiden when no description is present
|
||||||
m_ui->stateDescription->setVisible(!m_ui->stateDescription->text().isEmpty());
|
m_ui->stateDescription->setVisible(!m_ui->stateDescription->text().isEmpty());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if 0
|
||||||
m_ui->thumbnail->setPixmap(QPixmap());
|
m_ui->thumbnail->setPixmap(QPixmap());
|
||||||
m_ui->aircraftName->setText("");
|
m_ui->aircraftName->setText("");
|
||||||
m_ui->aircraftDescription->hide();
|
m_ui->aircraftDescription->hide();
|
||||||
m_ui->stateCombo->hide();
|
m_ui->stateCombo->hide();
|
||||||
m_ui->stateLabel->hide();
|
m_ui->stateLabel->hide();
|
||||||
m_ui->stateDescription->hide();
|
m_ui->stateDescription->hide();
|
||||||
|
#endif
|
||||||
m_ui->flyButton->setEnabled(false);
|
m_ui->flyButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -690,58 +639,6 @@ void LauncherMainWindow::setSceneryPaths()
|
||||||
flightgear::launcherSetSceneryPaths();
|
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()
|
void LauncherMainWindow::onSubsytemIdleTimeout()
|
||||||
{
|
{
|
||||||
globals->get_subsystem_mgr()->update(0.0);
|
globals->get_subsystem_mgr()->update(0.0);
|
||||||
|
@ -836,6 +733,11 @@ QmlAircraftInfo *LauncherMainWindow::selectedAircraftInfo() const
|
||||||
return m_selectedAircraftInfo;
|
return m_selectedAircraftInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LauncherMainWindow::restoreLocation(QVariant var)
|
||||||
|
{
|
||||||
|
m_ui->location->restoreLocation(var.toMap());
|
||||||
|
}
|
||||||
|
|
||||||
bool LauncherMainWindow::matchesSearch(QString term, QStringList keywords) const
|
bool LauncherMainWindow::matchesSearch(QString term, QStringList keywords) const
|
||||||
{
|
{
|
||||||
Q_FOREACH(QString s, keywords) {
|
Q_FOREACH(QString s, keywords) {
|
||||||
|
@ -888,7 +790,6 @@ void LauncherMainWindow::setSettingsSummary(QStringList settingsSummary)
|
||||||
|
|
||||||
m_settingsSummary = settingsSummary;
|
m_settingsSummary = settingsSummary;
|
||||||
emit summaryChanged();
|
emit summaryChanged();
|
||||||
updateSettingsSummary();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherMainWindow::setEnvironmentSummary(QStringList environmentSummary)
|
void LauncherMainWindow::setEnvironmentSummary(QStringList environmentSummary)
|
||||||
|
@ -898,7 +799,16 @@ void LauncherMainWindow::setEnvironmentSummary(QStringList environmentSummary)
|
||||||
|
|
||||||
m_environmentSummary = environmentSummary;
|
m_environmentSummary = environmentSummary;
|
||||||
emit summaryChanged();
|
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
|
simgear::pkg::PackageRef LauncherMainWindow::packageForAircraftURI(QUrl uri) const
|
||||||
|
@ -1040,3 +950,34 @@ bool LauncherMainWindow::showNoOfficialHanger() const
|
||||||
return shouldShowOfficialCatalogMessage();
|
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 MPServersModel;
|
||||||
class QQuickItem;
|
class QQuickItem;
|
||||||
class QmlAircraftInfo;
|
class QmlAircraftInfo;
|
||||||
|
class QStandardItemModel;
|
||||||
|
class RecentAircraftModel;
|
||||||
|
class RecentLocationsModel;
|
||||||
|
|
||||||
class LauncherMainWindow : public QMainWindow
|
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 settingsSummary READ settingsSummary WRITE setSettingsSummary NOTIFY summaryChanged)
|
||||||
Q_PROPERTY(QStringList environmentSummary READ environmentSummary WRITE setEnvironmentSummary 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:
|
public:
|
||||||
LauncherMainWindow();
|
LauncherMainWindow();
|
||||||
virtual ~LauncherMainWindow();
|
virtual ~LauncherMainWindow();
|
||||||
|
@ -105,6 +116,8 @@ public:
|
||||||
|
|
||||||
QmlAircraftInfo* selectedAircraftInfo() const;
|
QmlAircraftInfo* selectedAircraftInfo() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void restoreLocation(QVariant var);
|
||||||
|
|
||||||
Q_INVOKABLE bool matchesSearch(QString term, QStringList keywords) const;
|
Q_INVOKABLE bool matchesSearch(QString term, QStringList keywords) const;
|
||||||
|
|
||||||
bool isSearchActive() const;
|
bool isSearchActive() const;
|
||||||
|
@ -118,6 +131,25 @@ public:
|
||||||
|
|
||||||
QStringList environmentSummary() const;
|
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:
|
public slots:
|
||||||
void setSelectedAircraft(QUrl selectedAircraft);
|
void setSelectedAircraft(QUrl selectedAircraft);
|
||||||
|
|
||||||
|
@ -155,11 +187,6 @@ private slots:
|
||||||
|
|
||||||
void onQuit();
|
void onQuit();
|
||||||
|
|
||||||
void onPopupAircraftHistory();
|
|
||||||
void onPopupLocationHistory();
|
|
||||||
|
|
||||||
void updateSettingsSummary();
|
|
||||||
|
|
||||||
void onSubsytemIdleTimeout();
|
void onSubsytemIdleTimeout();
|
||||||
|
|
||||||
void onAircraftInstalledCompleted(QModelIndex index);
|
void onAircraftInstalledCompleted(QModelIndex index);
|
||||||
|
@ -192,13 +219,11 @@ private:
|
||||||
// scrolling, to give the view time it seems.
|
// scrolling, to give the view time it seems.
|
||||||
void delayedAircraftModelReset();
|
void delayedAircraftModelReset();
|
||||||
|
|
||||||
void updateLocationHistory();
|
|
||||||
bool shouldShowOfficialCatalogMessage() const;
|
bool shouldShowOfficialCatalogMessage() const;
|
||||||
|
|
||||||
void collectAircraftArgs();
|
void collectAircraftArgs();
|
||||||
void initQML();
|
void initQML();
|
||||||
|
|
||||||
std::string selectStateAutomatically();
|
|
||||||
|
|
||||||
QScopedPointer<Ui::Launcher> m_ui;
|
QScopedPointer<Ui::Launcher> m_ui;
|
||||||
AircraftProxyModel* m_installedAircraftModel;
|
AircraftProxyModel* m_installedAircraftModel;
|
||||||
|
@ -208,21 +233,20 @@ private:
|
||||||
MPServersModel* m_serversModel = nullptr;
|
MPServersModel* m_serversModel = nullptr;
|
||||||
|
|
||||||
QUrl m_selectedAircraft;
|
QUrl m_selectedAircraft;
|
||||||
QList<QUrl> m_recentAircraft;
|
|
||||||
QTimer* m_subsystemIdleTimer;
|
QTimer* m_subsystemIdleTimer;
|
||||||
bool m_inAppMode = false;
|
bool m_inAppMode = false;
|
||||||
bool m_runInApp = false;
|
bool m_runInApp = false;
|
||||||
bool m_accepted = false;
|
bool m_accepted = false;
|
||||||
int m_ratingFilters[4] = {3, 3, 3, 3};
|
int m_ratingFilters[4] = {3, 3, 3, 3};
|
||||||
QVariantList m_recentLocations;
|
|
||||||
QQmlEngine* m_qmlEngine = nullptr;
|
QQmlEngine* m_qmlEngine = nullptr;
|
||||||
LaunchConfig* m_config = nullptr;
|
LaunchConfig* m_config = nullptr;
|
||||||
ExtraSettingsSection* m_extraSettings = nullptr;
|
|
||||||
ViewCommandLinePage* m_viewCommandLinePage = nullptr;
|
ViewCommandLinePage* m_viewCommandLinePage = nullptr;
|
||||||
QmlAircraftInfo* m_selectedAircraftInfo = nullptr;
|
QmlAircraftInfo* m_selectedAircraftInfo = nullptr;
|
||||||
QString m_settingsSearchTerm;
|
QString m_settingsSearchTerm;
|
||||||
QStringList m_settingsSummary,
|
QStringList m_settingsSummary,
|
||||||
m_environmentSummary;
|
m_environmentSummary;
|
||||||
|
RecentAircraftModel* m_aircraftHistory = nullptr;
|
||||||
|
RecentLocationsModel* m_locationHistory = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // of LAUNCHER_MAIN_WINDOW_HXX
|
#endif // of LAUNCHER_MAIN_WINDOW_HXX
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
|
||||||
#include <simgear/package/Install.hxx>
|
#include <simgear/package/Install.hxx>
|
||||||
#include <simgear/package/Root.hxx>
|
#include <simgear/package/Root.hxx>
|
||||||
|
@ -86,9 +87,12 @@ private:
|
||||||
|
|
||||||
struct StateInfo
|
struct StateInfo
|
||||||
{
|
{
|
||||||
std::string tag; // internal XML name
|
string_list tags;
|
||||||
QString name; // human-readable name, or blank if we auto-generate this
|
QString name; // human-readable name, or blank if we auto-generate this
|
||||||
QString description; // human-readable description
|
QString description; // human-readable description
|
||||||
|
|
||||||
|
std::string primaryTag() const
|
||||||
|
{ return tags.front(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
using AircraftStateVec = std::vector<StateInfo>;
|
using AircraftStateVec = std::vector<StateInfo>;
|
||||||
|
@ -111,12 +115,20 @@ static AircraftStateVec readAircraftStates(const SGPath& setXMLPath)
|
||||||
AircraftStateVec result;
|
AircraftStateVec result;
|
||||||
result.reserve(nodes.size());
|
result.reserve(nodes.size());
|
||||||
for (auto cn : nodes) {
|
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("readable-name")),
|
||||||
QString::fromStdString(cn->getStringValue("description"))
|
QString::fromStdString(cn->getStringValue("description"))
|
||||||
});
|
});
|
||||||
|
|
||||||
qInfo() << QString::fromStdString(result.back().tag) << result.back().description;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -141,35 +153,34 @@ QString humanNameFromStateTag(const std::string& tag)
|
||||||
class StatesModel : public QAbstractListModel
|
class StatesModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(bool hasExplicitAuto READ hasExplicitAuto CONSTANT)
|
||||||
public:
|
public:
|
||||||
StatesModel(const AircraftStateVec& states) :
|
StatesModel(const AircraftStateVec& states) :
|
||||||
_data(states)
|
_data(states)
|
||||||
{
|
{
|
||||||
// sort which places 'auto' item at the front if it exists
|
// sort which places 'auto' item at the front if it exists
|
||||||
std::sort(_data.begin(), _data.end(), [](const StateInfo& a, const StateInfo& b) {
|
std::sort(_data.begin(), _data.end(), [](const StateInfo& a, const StateInfo& b) {
|
||||||
if (a.tag == "auto") return true;
|
if (a.primaryTag() == "auto") return true;
|
||||||
if (b.tag == "auto") return false;
|
if (b.primaryTag() == "auto") return false;
|
||||||
return a.tag < b.tag;
|
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
|
// track if the aircraft supplied an 'auto' state, in which case
|
||||||
// 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
|
// 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.")});
|
||||||
_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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
return i.tag == tag;
|
auto tagIt = std::find(i.tags.begin(), i.tags.end(), tag);
|
||||||
|
return (tagIt != i.tags.end());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (it == _data.end())
|
if (it == _data.end())
|
||||||
|
@ -186,18 +197,17 @@ public:
|
||||||
QVariant data(const QModelIndex &index, int role) const override
|
QVariant data(const QModelIndex &index, int role) const override
|
||||||
{
|
{
|
||||||
const StateInfo& s = _data.at(index.row());
|
const StateInfo& s = _data.at(index.row());
|
||||||
// qInfo() << index.row() << s.name << QString::fromStdString(s.tag);
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
if (s.name.isEmpty()) {
|
if (s.name.isEmpty()) {
|
||||||
return humanNameFromStateTag(s.tag);
|
return humanNameFromStateTag(s.primaryTag());
|
||||||
}
|
}
|
||||||
return s.name;
|
return s.name;
|
||||||
} else if (role == QmlAircraftInfo::StateTagRole) {
|
} else if (role == QmlAircraftInfo::StateTagRole) {
|
||||||
return QString::fromStdString(s.tag);
|
return QString::fromStdString(s.primaryTag());
|
||||||
} else if (role == QmlAircraftInfo::StateDescriptionRole) {
|
} else if (role == QmlAircraftInfo::StateDescriptionRole) {
|
||||||
return s.description;
|
return s.description;
|
||||||
} else if (role == QmlAircraftInfo::StateExplicitRole) {
|
} else if (role == QmlAircraftInfo::StateExplicitRole) {
|
||||||
if (s.tag == "auto")
|
if (s.primaryTag() == "auto")
|
||||||
return _explicitAutoState;
|
return _explicitAutoState;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -213,6 +223,28 @@ public:
|
||||||
result[QmlAircraftInfo::StateDescriptionRole] = "description";
|
result[QmlAircraftInfo::StateDescriptionRole] = "description";
|
||||||
return result;
|
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:
|
private:
|
||||||
AircraftStateVec _data;
|
AircraftStateVec _data;
|
||||||
bool _explicitAutoState = false;
|
bool _explicitAutoState = false;
|
||||||
|
@ -224,6 +256,7 @@ QmlAircraftInfo::QmlAircraftInfo(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, _delegate(new Delegate(this))
|
, _delegate(new Delegate(this))
|
||||||
{
|
{
|
||||||
|
qmlRegisterUncreatableType<StatesModel>("FlightGear.Launcher", 1, 0, "StatesModel", "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlAircraftInfo::~QmlAircraftInfo()
|
QmlAircraftInfo::~QmlAircraftInfo()
|
||||||
|
@ -621,7 +654,7 @@ bool QmlAircraftInfo::isPackaged() const
|
||||||
return _package != PackageRef();
|
return _package != PackageRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractListModel *QmlAircraftInfo::statesModel()
|
StatesModel *QmlAircraftInfo::statesModel()
|
||||||
{
|
{
|
||||||
if (!hasStates())
|
if (!hasStates())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
struct AircraftItem;
|
struct AircraftItem;
|
||||||
typedef QSharedPointer<AircraftItem> AircraftItemPtr;
|
typedef QSharedPointer<AircraftItem> AircraftItemPtr;
|
||||||
|
|
||||||
|
class StatesModel;
|
||||||
|
|
||||||
class QmlAircraftInfo : public QObject
|
class QmlAircraftInfo : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -57,7 +59,7 @@ class QmlAircraftInfo : public QObject
|
||||||
|
|
||||||
Q_PROPERTY(bool hasStates READ hasStates NOTIFY infoChanged)
|
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:
|
public:
|
||||||
explicit QmlAircraftInfo(QObject *parent = nullptr);
|
explicit QmlAircraftInfo(QObject *parent = nullptr);
|
||||||
|
@ -110,7 +112,7 @@ public:
|
||||||
static const int StateDescriptionRole;
|
static const int StateDescriptionRole;
|
||||||
static const int StateExplicitRole;
|
static const int StateExplicitRole;
|
||||||
|
|
||||||
QAbstractListModel* statesModel();
|
StatesModel* statesModel();
|
||||||
signals:
|
signals:
|
||||||
void uriChanged();
|
void uriChanged();
|
||||||
void infoChanged();
|
void infoChanged();
|
||||||
|
@ -134,7 +136,7 @@ private:
|
||||||
AircraftItemPtr _item;
|
AircraftItemPtr _item;
|
||||||
int _variant = 0;
|
int _variant = 0;
|
||||||
int _downloadBytes = 0;
|
int _downloadBytes = 0;
|
||||||
QScopedPointer<QAbstractListModel> _statesModel;
|
QScopedPointer<StatesModel> _statesModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QMLAIRCRAFTINFO_HXX
|
#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 {
|
Text {
|
||||||
signal clicked();
|
signal clicked();
|
||||||
|
|
||||||
color: mouse.containsMouse ? Style.themeColor : Style.baseTextColor
|
property color baseTextColor: Style.baseTextColor
|
||||||
|
color: mouse.containsMouse ? Style.themeColor : baseTextColor
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouse
|
id: mouse
|
||||||
|
@ -12,5 +13,7 @@ Text {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
onClicked: parent.clicked();
|
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 int currentIndex: 0
|
||||||
property bool __dummy: false
|
property bool __dummy: false
|
||||||
|
|
||||||
implicitHeight: label.implicitHeight
|
implicitHeight: Math.max(label.implicitHeight, currentChoiceFrame.height)
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Repeater {
|
Repeater {
|
||||||
|
@ -40,6 +40,10 @@ Item {
|
||||||
__dummy = !__dummy
|
__dummy = !__dummy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onModelChanged: {
|
||||||
|
__dummy = !__dummy // force update of currentText
|
||||||
|
}
|
||||||
|
|
||||||
function currentText()
|
function currentText()
|
||||||
{
|
{
|
||||||
var foo = __dummy; // fake propery dependency to update this
|
var foo = __dummy; // fake propery dependency to update this
|
||||||
|
|
|
@ -21,6 +21,10 @@ QtObject
|
||||||
readonly property string baseTextColor: "#3f3f3f"
|
readonly property string baseTextColor: "#3f3f3f"
|
||||||
|
|
||||||
readonly property int baseFontPixelSize: 12
|
readonly property int baseFontPixelSize: 12
|
||||||
|
readonly property int headingFontPixelSize: 18
|
||||||
|
|
||||||
readonly property string disabledTextColor: "#5f5f5f"
|
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/DateTimeEdit.qml</file>
|
||||||
<file>qml/DateTimeValueEdit.qml</file>
|
<file>qml/DateTimeValueEdit.qml</file>
|
||||||
<file>qml/SettingsDateTimePicker.qml</file>
|
<file>qml/SettingsDateTimePicker.qml</file>
|
||||||
|
<file>qml/Summary.qml</file>
|
||||||
|
<file>qml/HistoryPopup.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/preview">
|
<qresource prefix="/preview">
|
||||||
<file alias="close-icon">preview-close.png</file>
|
<file alias="close-icon">preview-close.png</file>
|
||||||
<file alias="left-arrow-icon">preview-left-arrow.png</file>
|
<file alias="left-arrow-icon">preview-left-arrow.png</file>
|
||||||
<file alias="right-arrow-icon">preview-right-arrow.png</file>
|
<file alias="right-arrow-icon">preview-right-arrow.png</file>
|
||||||
</qresource>
|
</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>
|
</RCC>
|
||||||
|
|
Loading…
Reference in a new issue