7#include <QDesktopServices>
11#include <QNetworkAccessManager>
12#include <QNetworkDiskCache>
14#include <QQmlComponent>
15#include <QQuickWindow>
19#include <simgear/package/Install.hxx>
20#include <simgear/environment/metar.hxx>
21#include <simgear/structure/exception.hxx>
70#include <flightgearBuildId.h>
90 m_location->setLaunchConfig(m_config);
96 m_installedAircraftModel->setInstalledFilterEnabled(
true);
99 m_aircraftWithUpdatesModel->setInstalledFilterEnabled(
true);
100 m_aircraftWithUpdatesModel->setHaveUpdateFilterEnabled(
true);
103 m_browseAircraftModel->setRatingFilterEnabled(
true);
108 m_favouriteAircraftModel->setShowFavourites(
true);
113 this, &LauncherController::onAircraftInstalledCompleted);
115 this, &LauncherController::onAircraftInstallFailed);
119 this, &LauncherController::updateSelectedAircraft);
122 m_aircraftModel->setPackageRoot(
globals->packageRoot());
124 m_aircraftGridMode = settings.value(
"aircraftGridMode").toBool();
126 m_subsystemIdleTimer =
new QTimer(
this);
127 m_subsystemIdleTimer->setInterval(5);
128 connect(m_subsystemIdleTimer, &QTimer::timeout, []()
129 {
globals->get_subsystem_mgr()->update(0.0);});
130 m_subsystemIdleTimer->start();
132 QRect winRect = settings.value(
"window-geometry").toRect();
134 if (winRect.isValid()) {
135 m_window->setGeometry(winRect);
137 m_window->setWidth(600);
138 m_window->setHeight(800);
141 if (settings.contains(
"window-state")) {
142 const auto ws =
static_cast<Qt::WindowState
>(settings.value(
"window-state").toInt());
144 if (ws == Qt::WindowState::WindowFullScreen &&
options->isBoolOptionDisable(
"fullscreen")) {
146 m_window->setWindowState(Qt::WindowState::WindowNoState);
149 m_window->setWindowState(ws);
155 m_launchCount = settings.value(
"launch-count", 0).toInt();
156 settings.setValue(
"launch-count", m_launchCount + 1);
158 std::ostringstream os;
159 string_list versionParts = simgear::strutils::split(FLIGHTGEAR_VERSION,
".");
160 if (versionParts.size() >= 2) {
162 QString versionedCountKey = QString::fromStdString(
"launch-count-" + versionParts.at(0) +
"-" + versionParts.at(1));
163 m_versionLaunchCount = settings.value(versionedCountKey, 0).toInt();
164 settings.setValue(versionedCountKey, m_versionLaunchCount + 1);
167 QTimer::singleShot(2000,
this, &LauncherController::checkForOldDownloadDir);
172 qmlRegisterUncreatableType<LauncherController>(
"FlightGear.Launcher", 1, 0,
"LauncherController",
"no");
173 qmlRegisterUncreatableType<LocationController>(
"FlightGear.Launcher", 1, 0,
"LocationController",
"no");
174 qmlRegisterUncreatableType<FlightPlanController>(
"FlightGear.Launcher", 1, 0,
"FlightPlanController",
"no");
175 qmlRegisterUncreatableType<UpdateChecker>(
"FlightGear.Launcher", 1, 0,
"UpdateChecker",
"for enums");
177 qmlRegisterType<LauncherArgumentTokenizer>(
"FlightGear.Launcher", 1, 0,
"ArgumentTokenizer");
178 qmlRegisterUncreatableType<QAbstractItemModel>(
"FlightGear.Launcher", 1, 0,
"QAIM",
"no");
179 qmlRegisterUncreatableType<AircraftProxyModel>(
"FlightGear.Launcher", 1, 0,
"AircraftProxyModel",
"no");
180 qmlRegisterUncreatableType<RecentAircraftModel>(
"FlightGear.Launcher", 1, 0,
"RecentAircraftModel",
"no");
181 qmlRegisterUncreatableType<RecentLocationsModel>(
"FlightGear.Launcher", 1, 0,
"RecentLocationsModel",
"no");
182 qmlRegisterUncreatableType<LaunchConfig>(
"FlightGear.Launcher", 1, 0,
"LaunchConfig",
"Singleton API");
183 qmlRegisterUncreatableType<MPServersModel>(
"FlightGear.Launcher", 1, 0,
"MPServers",
"Singleton API");
185 qmlRegisterType<NavaidSearchModel>(
"FlightGear", 1, 0,
"NavaidSearch");
186 qmlRegisterType<CarriersLocationModel>(
"FlightGear", 1, 0,
"CarriersModel");
188 qmlRegisterUncreatableType<Units>(
"FlightGear", 1, 0,
"Units",
"Only for enum");
189 qmlRegisterType<UnitsModel>(
"FlightGear", 1, 0,
"UnitsModel");
191 qmlRegisterType<FileDialogWrapper>(
"FlightGear", 1, 0,
"FileDialog");
192 qmlRegisterType<QmlAircraftInfo>(
"FlightGear.Launcher", 1, 0,
"AircraftInfo");
194 qmlRegisterUncreatableType<LocalAircraftCache>(
"FlightGear.Launcher", 1, 0,
"LocalAircraftCache",
"Aircraft cache");
195 qmlRegisterUncreatableType<AircraftItemModel>(
"FlightGear.Launcher", 1, 0,
"AircraftModel",
"Built-in model");
196 qmlRegisterType<ThumbnailImageItem>(
"FlightGear.Launcher", 1, 0,
"ThumbnailImage");
197 qmlRegisterType<PreviewImageItem>(
"FlightGear.Launcher", 1, 0,
"PreviewImage");
199 qmlRegisterType<QmlPositioned>(
"FlightGear", 1, 0,
"Positioned");
201 qRegisterMetaType<QmlGeod>();
203 qmlRegisterType<PixmapImageItem>(
"FlightGear", 1, 0,
"PixmapImage");
204 qmlRegisterType<AirportDiagram>(
"FlightGear", 1, 0,
"AirportDiagram");
205 qmlRegisterType<CarrierDiagram>(
"FlightGear", 1, 0,
"CarrierDiagram");
206 qmlRegisterType<NavaidDiagram>(
"FlightGear", 1, 0,
"NavaidDiagram");
207 qmlRegisterType<RouteDiagram>(
"FlightGear", 1, 0,
"RouteDiagram");
208 qmlRegisterType<QmlRadioButtonGroup>(
"FlightGear", 1, 0,
"RadioButtonGroup");
209 qmlRegisterType<HoverArea>(
"FlightGear", 1, 0,
"HoverArea");
210 qmlRegisterType<StackController>(
"FlightGear", 1, 0,
"StackController");
212 qmlRegisterType<ModelDataExtractor>(
"FlightGear", 1, 0,
"ModelDataExtractor");
213 qmlRegisterType<QmlStringListModel>(
"FlightGear", 1, 0,
"StringListModel");
216 qmlRegisterSingletonType(QUrl(
"qrc:/qml/OverlayShared.qml"),
"FlightGear", 1, 0,
"OverlayShared");
217 styleTypeId = qmlRegisterSingletonType(QUrl(
"qrc:/qml/Style.qml"),
"FlightGear", 1, 0,
"Style");
219 qmlRegisterType<GettingStartedScope>(
"FlightGear", 1, 0,
"GettingStartedScope");
220 qmlRegisterType<GettingStartedTipsController>(
"FlightGear", 1, 0,
"GettingStartedController");
221 qmlRegisterType<GettingStartedTip>(
"FlightGear", 1, 0,
"GettingStartedTip");
222 qmlRegisterType<TipBackgroundBox>(
"FlightGear", 1, 0,
"TipBackgroundBox");
224 QNetworkDiskCache* diskCache =
new QNetworkDiskCache(
this);
225 SGPath cachePath =
globals->get_fg_home() /
"PreviewsCache";
226 diskCache->setCacheDirectory(QString::fromStdString(cachePath.utf8Str()));
228 QNetworkAccessManager* netAccess =
new QNetworkAccessManager(
this);
229 netAccess->setCache(diskCache);
236 m_keepRunningInAppMode =
true;
237 m_appModeResult =
true;
243 return m_keepRunningInAppMode;
248 return m_appModeResult;
253 m_selectedAircraft = m_aircraftHistory->mostRecent();
254 if (m_selectedAircraft.isEmpty()) {
258 m_selectedAircraft = QUrl::fromLocalFile(QString::fromStdString(da.
foundPath().utf8Str()));
259 qDebug() <<
"Restored default aircraft:" << m_selectedAircraft;
261 qWarning() <<
"Completely failed to find the default aircraft";
265 m_location->restoreSearchHistory();
266 QVariantMap currentLocation = m_locationHistory->mostRecent();
267 if (currentLocation.isEmpty()) {
272 currentLocation[
"location-id"] =
static_cast<qlonglong
>(apt->guid());
273 currentLocation[
"location-apt-runway"] =
"ACTIVE";
276 m_location->restoreLocation(currentLocation);
280 updateSelectedAircraft();
281 m_serversModel->requestRestore();
282 m_aircraftState = m_config->getValueForKey(
"",
"selected-aircraft-state", QString()).toString();
291 if (m_window->windowState() != Qt::WindowMaximized) {
292 settings.setValue(
"window-geometry", m_window->geometry());
294 settings.setValue(
"window-state", m_window->windowState());
296 m_config->saveConfigToINI();
297 m_aircraftHistory->saveToSettings();
298 m_locationHistory->saveToSettings();
301void LauncherController::collectAircraftArgs()
303 if (m_skipAircraftFromArgs)
307 if (!m_selectedAircraft.isEmpty()) {
308 if (m_selectedAircraft.isLocalFile()) {
309 QFileInfo setFileInfo(m_selectedAircraft.toLocalFile());
310 m_config->
setArg(
"aircraft-dir", setFileInfo.dir().absolutePath());
311 QString setFile = setFileInfo.fileName();
312 Q_ASSERT(setFile.endsWith(
"-set.xml"));
313 setFile.truncate(setFile.size() - 8);
314 m_config->
setArg(
"aircraft", setFile);
315 }
else if (m_selectedAircraft.scheme() ==
"package") {
318 m_config->setArg(
"aircraft", m_selectedAircraft.path());
320 qWarning() <<
"unsupported aircraft launch URL" << m_selectedAircraft;
324 if (m_selectedAircraftInfo->hasStates() && !m_aircraftState.isEmpty()) {
325 QString state = m_aircraftState;
326 if ((m_aircraftState ==
"auto") && !m_selectedAircraftInfo->haveExplicitAutoState()) {
327 state = selectAircraftStateAutomatically();
330 if (!state.isEmpty()) {
331 m_config->setArg(
"state", state);
336void LauncherController::saveAircraft()
338 m_config->setValueForKey(
"",
"selected-aircraft", m_selectedAircraft);
339 if (!m_aircraftState.isEmpty()) {
340 m_config->setValueForKey(
"",
"selected-aircraft-state", m_aircraftState);
344void LauncherController::restoreAircraft()
346 m_selectedAircraft = m_config->getValueForKey(
"",
"selected-aircraft", QUrl()).toUrl();
347 m_aircraftState = m_config->getValueForKey(
"",
"selected-aircraft-state", QString()).toString();
349 updateSelectedAircraft();
360 m_aircraftHistory->insert(m_selectedAircraft);
362 QVariant locSet = m_location->saveLocation();
363 m_locationHistory->insert(locSet);
369 QString downloadDir = settings.value(
"downloadSettings/downloadDir").toString();
370 if (!downloadDir.isEmpty()) {
373 int result = QMessageBox::question(
nullptr, tr(
"Create download folder?"),
374 tr(
"The selected location for downloads does not exist. (%1) Create it?").arg(downloadDir),
375 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
376 if (result == QMessageBox::Cancel) {
380 if (result == QMessageBox::Yes) {
381 d.mkpath(downloadDir);
386 if (settings.contains(
"restore-defaults-on-run")) {
387 settings.remove(
"restore-defaults-on-run");
391 m_config->applyToOptions();
398 if (!m_selectedAircraft.isEmpty()) {
399 std::string aircraftPropValue,
402 if (m_selectedAircraft.isLocalFile()) {
403 QFileInfo setFileInfo(m_selectedAircraft.toLocalFile());
404 QString setFile = setFileInfo.fileName();
405 Q_ASSERT(setFile.endsWith(
"-set.xml"));
406 setFile.truncate(setFile.size() - 8);
407 aircraftDir = setFileInfo.dir().absolutePath().toStdString();
408 aircraftPropValue = setFile.toStdString();
409 }
else if (m_selectedAircraft.scheme() ==
"package") {
412 aircraftPropValue = m_selectedAircraft.path().toStdString();
414 qWarning() <<
"unsupported aircraft launch URL" << m_selectedAircraft;
417 m_aircraftHistory->insert(m_selectedAircraft);
418 globals->get_props()->setStringValue(
"/sim/aircraft", aircraftPropValue);
419 globals->get_props()->setStringValue(
"/sim/aircraft-dir", aircraftDir);
422 m_location->setLocationProperties();
427QString LauncherController::selectAircraftStateAutomatically()
429 if (!m_selectedAircraftInfo)
432 if (m_location->isAirborneLocation() && m_selectedAircraftInfo->hasState(
"cruise")) {
433 const double altitudeFt = m_location->altitude().convertToUnit(
Units::FeetMSL).value;
434 if (altitudeFt > 6000) {
439 if (m_location->isCarrier() && m_location->isAirborneLocation() && m_selectedAircraftInfo->hasState(
"carrier-approach")) {
440 return "carrier-approach";
443 if (m_location->isAirborneLocation() && m_selectedAircraftInfo->hasState(
"approach")) {
447 if (m_location->isParkedLocation()) {
448 if (m_selectedAircraftInfo->hasState(
"parked")) {
451 if (m_selectedAircraftInfo->hasState(
"parking")) {
456 if (m_location->isCarrier() && m_selectedAircraftInfo->hasState(
"carrier-take-off")) {
457 return "carrier-take-off";
460 if (m_selectedAircraftInfo->hasState(
"take-off")) {
467void LauncherController::maybeUpdateSelectedAircraft(QModelIndex index)
470 if (u == m_selectedAircraft) {
472 updateSelectedAircraft();
476void LauncherController::updateSelectedAircraft()
478 m_selectedAircraftInfo->setUri(m_selectedAircraft);
479 QModelIndex index = m_aircraftModel->indexOfAircraftURI(m_selectedAircraft);
480 if (index.isValid()) {
491 if (!m_aircraftState.isEmpty()) {
492 if (!m_selectedAircraftInfo->hasState(m_aircraftState)) {
493 m_aircraftState.clear();
503 QModelIndex index = m_aircraftModel->indexOfAircraftURI(m_selectedAircraft);
504 if (!index.isValid()) {
517 if (!m_config->enableDownloadDirUI()) {
522 if (path == m_config->defaultDownloadDir()) {
527 if (
options->valueForOption(
"download-dir") == path.toStdString()) {
535 if (!path.isEmpty()) {
536 options->setOption(
"download-dir", path.toStdString());
538 options->clearOption(
"download-dir");
541 m_config->setValueForKey(
"",
"download-dir", path);
548 return m_selectedAircraftInfo;
553 m_location->restoreLocation(var.toMap());
558 return m_selectedAircraft;
563 Q_FOREACH(QString s, keywords) {
564 if (s.contains(term, Qt::CaseInsensitive)) {
574 return !m_settingsSearchTerm.isEmpty();
579 return m_settingsSummary;
584 return m_environmentSummary;
594 m_aircraftState.clear();
596 updateSelectedAircraft();
635 m_flyRequested =
true;
639 m_keepRunningInAppMode =
false;
640 m_appModeResult =
true;
650 m_keepRunningInAppMode =
false;
651 m_appModeResult =
false;
660 return m_settingsSummary + m_environmentSummary;
663simgear::pkg::PackageRef LauncherController::packageForAircraftURI(QUrl uri)
const
665 if (uri.scheme() !=
"package") {
666 qWarning() <<
"invalid URL scheme:" << uri;
667 return simgear::pkg::PackageRef();
670 QString ident = uri.path();
676 if (metar.isEmpty()) {
681 std::string s = metar.toStdString();
683 }
catch (sg_io_exception&) {
692 simgear::pkg::PackageRef pref = packageForAircraftURI(aircraftUri);
694 if (pref->isInstalled()) {
695 InstallRef install = pref->existingInstall();
696 if (install->hasUpdate()) {
697 globals->packageRoot()->scheduleToUpdate(install);
707 simgear::pkg::PackageRef pref = packageForAircraftURI(aircraftUri);
709 simgear::pkg::InstallRef
i = pref->existingInstall();
718 simgear::pkg::PackageRef pref = packageForAircraftURI(aircraftUri);
720 simgear::pkg::InstallRef
i = pref->existingInstall();
729 const auto pkgRoot =
globals->packageRoot();
730 const PackageList& toBeUpdated = pkgRoot->packagesNeedingUpdate();
731 std::for_each(toBeUpdated.begin(), toBeUpdated.end(), [pkgRoot](PackageRef
pkg) {
732 const auto ins = pkg->install();
733 if (!pkgRoot->isInstallQueued(ins)) {
734 pkgRoot->scheduleToUpdate(ins);
741 m_serversModel->refresh();
746 if (strcmp(FG_BUILD_TYPE,
"Nightly") == 0) {
747 return " Nightly " BUILD_DATE;
750 if (strcmp(FG_BUILD_TYPE,
"Dev") == 0) {
754 return FLIGHTGEAR_VERSION;
759 return m_aircraftHistory;
764 return m_locationHistory;
769 QDesktopServices::openUrl(url);
777 QUrl url = QUrl::fromLocalFile(QString::fromStdString(path));
787 if (!settings.contains(
name))
789 return settings.value(
name);
795 settings.setValue(
name, value);
798void LauncherController::onAircraftInstalledCompleted(QModelIndex index)
800 maybeUpdateSelectedAircraft(index);
803void LauncherController::onAircraftInstallFailed(QModelIndex index, QString errorMessage)
805 qWarning() << Q_FUNC_INFO << index.data(
AircraftURIRole) << errorMessage;
808 msg.setWindowTitle(tr(
"Aircraft installation failed"));
809 msg.setText(tr(
"An error occurred installing the aircraft %1: %2").
810 arg(index.data(Qt::DisplayRole).toString()).arg(errorMessage));
811 msg.addButton(QMessageBox::Ok);
814 maybeUpdateSelectedAircraft(index);
820 QPointF scenePos = item->mapToScene(pos);
821 QQuickWindow* win = item->window();
822 return win->mapToGlobal(scenePos.toPoint());
828 mbox.setText(tr(
"Restore all settings to defaults?"));
829 mbox.setInformativeText(tr(
"Restoring settings to their defaults may affect available add-ons such as scenery or aircraft."));
830 QPushButton* quitButton = mbox.addButton(tr(
"Restore and restart now"), QMessageBox::YesRole);
831 mbox.addButton(QMessageBox::Cancel);
832 mbox.setDefaultButton(QMessageBox::Cancel);
833 mbox.setIconPixmap(QPixmap(
":/app-icon-large"));
836 if (mbox.clickedButton() != quitButton) {
843 settings.setValue(
"restore-defaults-on-run",
true);
851 QString currentLocText;
855 currentLocText = tr(
"Currently the built-in data files are being used");
858 currentLocText = tr(
"Currently using location: %1").arg(root);
862 mbox.setText(tr(
"Change the data files used by FlightGear?"));
863 mbox.setInformativeText(tr(
"FlightGear requires additional files to operate. "
864 "(Also called the base package, or fg-data) "
865 "You can restart FlightGear and choose a "
866 "different data files location, or restore the default setting. %1").arg(currentLocText));
867 QPushButton* quitButton = mbox.addButton(tr(
"Restart FlightGear now"), QMessageBox::YesRole);
868 mbox.addButton(QMessageBox::Cancel);
869 mbox.setDefaultButton(QMessageBox::Cancel);
870 mbox.setIconPixmap(QPixmap(
":/app-icon-large"));
873 if (mbox.clickedButton() != quitButton) {
883 QString file = QFileDialog::getOpenFileName(
nullptr, tr(
"Choose a saved configuration"),
888 m_config->loadConfigFromFile(file);
893 QString file = QFileDialog::getSaveFileName(
nullptr, tr(
"Save the current configuration"),
897 if (!file.endsWith(
".fglaunch")) {
901 m_config->saveConfigToFile(file);
919 settings.beginGroup(
"GettingStarted-DontShow");
929 if (sz == m_minWindowSize)
932 m_window->setMinimumSize(sz);
939 return QUrl{
"image://colored-icon/toolbox-fly-heli"};
940 }
else if (m_selectedAircraftInfo) {
941 if (m_selectedAircraftInfo->hasTag(
"spaceship")) {
942 return QUrl{
"image://colored-icon/toolbox-fly-alt"};
946 return QUrl{
"image://colored-icon/toolbox-fly"};
952 return tr(
"Fly!",
"For a helicopter");
953 }
else if (m_selectedAircraftInfo) {
954 if (m_selectedAircraftInfo->hasTag(
"spaceship")) {
955 return tr(
"Fly!",
"For a spaceship");
964 QString absFilePath = QString::fromStdString(
globals->get_fg_root().utf8Str());
965 if (!relPath.startsWith(
"/")) {
966 relPath.prepend(
"/");
968 return QUrl::fromLocalFile(absFilePath + relPath);
971void LauncherController::checkForOldDownloadDir()
975 if (
options->valueForOption(
"download-dir") != std::string{}) {
979 if (haveOldWindowsDownloadDir()) {
983 QJSValue args = nc->jsEngine()->newObject();
985 const auto oldPath = SGPath::documents() /
"FlightGear";
988 const QUrl oldLocURI = QUrl::fromLocalFile(QString::fromStdString(oldPath.utf8Str()));
989 const QUrl newLocURI = QUrl::fromLocalFile(QString::fromStdString(newPath.utf8Str()));
991 args.setProperty(
"oldLocation", oldLocURI.toString());
992 args.setProperty(
"newLocation", newLocURI.toString());
993 args.setProperty(
"persistent-dismiss",
true);
995 nc->postNotification(
"have-old-downloads-location", QUrl{
"qrc:///qml/DownloadsInDocumentsWarning.qml"}, args);
1000bool LauncherController::haveOldWindowsDownloadDir()
const
1002 const SGPath
p = SGPath::documents() /
"FlightGear";
1003 if ((
p /
"TerraSync").exists() || (
p /
"Aircraft").exists()) {
1008 simgear::Dir texCacheDir(
p /
"TextureCache");
1009 return (texCacheDir.exists() && !texCacheDir.isEmpty());
const int AircraftIsSeaplaneRole
const int AircraftIsHelicopterRole
const int AircraftURIRole
const int AircraftPackageStatusRole
bool options(int, char **)
SGSharedPtr< FGAirport > FGAirportRef
void aircraftInstallFailed(QModelIndex index, QString errorMessage)
void aircraftInstallCompleted(QModelIndex index)
static FGAirportRef findByIdent(const std::string &aIdent)
Helper to look up an FGAirport instance by unique ident.
simgear::pkg::Root * packageRoot()
Q_INVOKABLE void setArg(QString name, QString value=QString(), Origin origin=Launcher)
Q_INVOKABLE QVariant loadUISetting(QString name, QVariant defaultValue) const
QStringList settingsSummary
RecentAircraftModel * aircraftHistory
Q_INVOKABLE QUrl urlToDataPath(QString relPath) const
urlToDataPath - convetr a FGData path into a gloabl file:/// URL suitable for Qt.openExternally()
Q_INVOKABLE void requestInstallUpdate(QUrl aircraftUri)
bool keepRunningInAppMode() const
Q_INVOKABLE void launchUrl(QUrl url)
Q_INVOKABLE QPointF mapToGlobal(QQuickItem *item, const QPointF &pos) const
void setSettingsSummary(QStringList settingsSummary)
Q_INVOKABLE void requestUpdateAllAircraft()
void setEnvironmentSummary(QStringList environmentSummary)
void initialRestoreSettings()
Q_INVOKABLE void requestInstallCancel(QUrl aircraftUri)
void setSelectedAircraft(QUrl selectedAircraft)
QmlAircraftInfo * selectedAircraftInfo
Q_INVOKABLE bool matchesSearch(QString term, QStringList keywords) const
Q_INVOKABLE QVariantList defaultSplashUrls() const
void selectedAircraftStateChanged()
void aircraftGridModeChanged(bool aircraftGridMode)
QStringList environmentSummary
Q_INVOKABLE void downloadDirChanged(QString path)
void minWindowSizeChanged()
QString settingsSearchTerm
void requestChangeDataPath()
void selectedAircraftChanged(QUrl selectedAircraft)
Q_INVOKABLE void requestUninstall(QUrl aircraftUri)
void initQML(int &styleTypeId)
QStringList combinedSummary
Q_INVOKABLE void queryMPServers()
void resetGettingStartedTips()
RecentLocationsModel * locationHistory
Q_INVOKABLE void restoreLocation(QVariant var)
void didResetGettingStartedTips()
Q_INVOKABLE bool validateMetarString(QString metar)
void setMinWindowSize(QSize sz)
void setAircraftGridMode(bool aircraftGridMode)
void setSettingsSearchTerm(QString settingsSearchTerm)
void requestRestoreDefaults()
LauncherController(QObject *parent, QWindow *win)
Q_INVOKABLE void saveUISetting(QString name, QVariant value) const
static LauncherNotificationsController * instance()
static LocalAircraftCache * instance()
void descriptionChanged()
static void setGlobalNetworkAccess(QNetworkAccessManager *netAccess)
static QString rootPathKey()
static void askRootOnNextLaunch()
we don't want to rely on the main AircraftModel threaded scan, to find the default aircraft,...
int addOption(const std::string &key, const std::string &value)
set an option value, assuming it is not already set (or multiple values are permitted) This can be us...
static Options * sharedInstance()
std::vector< std::string > string_list
SGPath defaultDownloadDir()
return the default platform dependant download directory.
void restartTheApp()
restartTheApp quit the application and relaunch it, passing the –launcher flag explicitly.
void addSentryBreadcrumb(const std::string &, const std::string &)
string_list defaultSplashScreenPaths()
std::string defaultAirportICAO()