diff --git a/src/GUI/CMakeLists.txt b/src/GUI/CMakeLists.txt index ab968b9d4..adbd667b8 100644 --- a/src/GUI/CMakeLists.txt +++ b/src/GUI/CMakeLists.txt @@ -132,6 +132,10 @@ if (HAVE_QT) FavouriteAircraftData.hxx UpdateChecker.cxx UpdateChecker.hxx + LauncherPackageDelegate.hxx + LauncherPackageDelegate.cxx + LauncherNotificationsController.hxx + LauncherNotificationsController.cxx ${uic_sources} ${qrc_sources} ${qml_sources}) diff --git a/src/GUI/LauncherMainWindow.cxx b/src/GUI/LauncherMainWindow.cxx index 22ed5bcee..6a9b65416 100755 --- a/src/GUI/LauncherMainWindow.cxx +++ b/src/GUI/LauncherMainWindow.cxx @@ -17,14 +17,16 @@ #include // launcher headers -#include "QtLauncher.hxx" #include "AddOnsController.hxx" -#include "AircraftItemModel.hxx" +#include "AircraftModel.hxx" #include "DefaultAircraftLocator.hxx" #include "LaunchConfig.hxx" -#include "LocalAircraftCache.hxx" #include "LauncherController.hxx" +#include "LauncherNotificationsController.hxx" +#include "LauncherPackageDelegate.hxx" +#include "LocalAircraftCache.hxx" #include "LocationController.hxx" +#include "QtLauncher.hxx" #include "UpdateChecker.hxx" ////////////////////////////////////////////////////////////////////////////// @@ -80,6 +82,8 @@ LauncherMainWindow::LauncherMainWindow(bool inSimMode) : QQuickView() connect(qa, &QAction::triggered, m_controller, &LauncherController::quit); } + connect(this, &QQuickView::statusChanged, this, &LauncherMainWindow::onQuickStatusChanged); + m_controller->initialRestoreSettings(); //////////// @@ -103,6 +107,12 @@ LauncherMainWindow::LauncherMainWindow(bool inSimMode) : QQuickView() auto updater = new UpdateChecker(this); ctx->setContextProperty("_updates", updater); + auto packageDelegate = new LauncherPackageDelegate(this); + ctx->setContextProperty("_packages", packageDelegate); + + auto notifications = new LauncherNotificationsController{this, engine()}; + ctx->setContextProperty("_notifications", notifications); + if (!inSimMode) { auto addOnsCtl = new AddOnsController(this, m_controller->config()); ctx->setContextProperty("_addOns", addOnsCtl); @@ -120,25 +130,22 @@ LauncherMainWindow::LauncherMainWindow(bool inSimMode) : QQuickView() setSource(QUrl("qrc:///qml/Launcher.qml")); } -#if 0 -void LauncherMainWindow::onQuickStatusChanged(QQuickWidget::Status status) +void LauncherMainWindow::onQuickStatusChanged(QQuickView::Status status) { - if (status == QQuickWidget::Error) { - QQuickWidget* qw = qobject_cast(sender()); + if (status == QQuickView::Error) { QString errorString; - Q_FOREACH(auto err, qw->errors()) { + Q_FOREACH (auto err, errors()) { errorString.append("\n" + err.toString()); } - QMessageBox::critical(this, "UI loading failures.", - tr("Problems occurred loading the user interface. This is often due to missing modules on your system. " + QMessageBox::critical(nullptr, "UI loading failures.", + tr("Problems occurred loading the user interface. This is usually due to missing modules on your system. " "Please report this error to the FlightGear developer list or forum, and take care to mention your system " - "distribution, etc. Please also include the information provided below.\n") - + errorString); + "distribution, etc. Please also include the information provided below.\n") + + errorString); } } -#endif LauncherMainWindow::~LauncherMainWindow() { diff --git a/src/GUI/LauncherMainWindow.hxx b/src/GUI/LauncherMainWindow.hxx index b8c8289ad..051fb2cb4 100644 --- a/src/GUI/LauncherMainWindow.hxx +++ b/src/GUI/LauncherMainWindow.hxx @@ -48,6 +48,10 @@ public: bool wasRejected(); bool event(QEvent *event) override; + +private slots: + void onQuickStatusChanged(QQuickView::Status status); + private: LauncherController* m_controller; }; diff --git a/src/GUI/LauncherNotificationsController.cxx b/src/GUI/LauncherNotificationsController.cxx new file mode 100644 index 000000000..760693437 --- /dev/null +++ b/src/GUI/LauncherNotificationsController.cxx @@ -0,0 +1,167 @@ +// Written by James Turner, started October 2020 +// +// Copyright (C) 2020 James Turner +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#include "LauncherNotificationsController.hxx" + +#include +#include +#include +#include + +static LauncherNotificationsController* static_instance = nullptr; + +namespace { + +const int IdRole = Qt::UserRole + 1; +const int SourceRole = Qt::UserRole + 2; +const int ArgsRole = Qt::UserRole + 3; + +} // namespace + +class LauncherNotificationsController::NotificationsModel : public QAbstractListModel +{ +public: + int rowCount(const QModelIndex&) const override + { + return static_cast(_data.size()); + } + + QVariant data(const QModelIndex& index, int role) const override + { + const int row = index.row(); + if ((row < 0) || (row >= static_cast(_data.size()))) { + return {}; + } + + const auto& d = _data.at(row); + switch (role) { + case IdRole: return d.id; + case SourceRole: return d.source; + case ArgsRole: return QVariant::fromValue(d.args); + default: + break; + } + + return {}; + } + + QHash roleNames() const override + { + QHash result = QAbstractListModel::roleNames(); + result[IdRole] = "id"; + result[SourceRole] = "source"; + result[ArgsRole] = "args"; + return result; + } + + void removeIndex(int index) + { + beginRemoveRows({}, index, index); + _data.erase(_data.begin() + index); + endRemoveRows(); + } + + void append(QString id, QUrl source, QJSValue args) + { + const int newRow = static_cast(_data.size()); + beginInsertRows({}, newRow, newRow); + _data.push_back({id, source, args}); + endInsertRows(); + } + + struct Data { + QString id; + QUrl source; + QJSValue args; + }; + + std::vector _data; +}; + +LauncherNotificationsController::LauncherNotificationsController(QObject* pr, QQmlEngine* engine) : QObject(pr) +{ + Q_ASSERT(static_instance == nullptr); + static_instance = this; + + _model = new NotificationsModel; + + _qmlEngine = engine; +} + +LauncherNotificationsController::~LauncherNotificationsController() +{ + static_instance = nullptr; +} + +LauncherNotificationsController* LauncherNotificationsController::instance() +{ + return static_instance; +} + +QAbstractItemModel* LauncherNotificationsController::notifications() const +{ + return _model; +} + +QJSValue LauncherNotificationsController::argsForIndex(int index) const +{ + if ((index < 0) || (index >= static_cast(_model->_data.size()))) { + return {}; + } + const auto& d = _model->_data.at(index); + qDebug() << Q_FUNC_INFO << index; + return d.args; +} + +QJSEngine* LauncherNotificationsController::jsEngine() +{ + return _qmlEngine; +} + +void LauncherNotificationsController::dismissIndex(int index) +{ + const auto& d = _model->_data.at(index); + + // if the notificsation supports persistent dismissal, then record this + // fact in the global settings, so we don't show it again. + // restore defaults will of course clear these settings, but that's + // desirable anyway. + if (d.args.property("persistent-dismiss").toBool()) { + QSettings settings; + settings.beginGroup("dismissed-notifications"); + settings.setValue(d.id, true); + } + + _model->removeIndex(index); +} + +void LauncherNotificationsController::postNotification(QString id, QUrl source, QJSValue args) +{ + const bool supportsPersistentDismiss = args.property("persistent-dismiss").toBool(); + if (supportsPersistentDismiss) { + QSettings settings; + settings.beginGroup("dismissed-notifications"); + bool alreadyDimissed = settings.value(id).toBool(); + if (alreadyDimissed) { + qWarning() << "Skipping notification" << id << ", was previousl dimissed by user"; + return; + } + } + + _model->append(id, source, args); +} diff --git a/src/GUI/LauncherNotificationsController.hxx b/src/GUI/LauncherNotificationsController.hxx new file mode 100644 index 000000000..63180942b --- /dev/null +++ b/src/GUI/LauncherNotificationsController.hxx @@ -0,0 +1,59 @@ +// Written by James Turner, started October 2020 +// +// Copyright (C) 2020 James Turner +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#pragma once + +#include +#include +#include + +// forward decls +class QAbstractItemModel; +class QJSEngine; +class QQmlEngine; + +class LauncherNotificationsController : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QAbstractItemModel* active READ notifications CONSTANT) +public: + LauncherNotificationsController(QObject* pr, QQmlEngine* qmlEngine); + ~LauncherNotificationsController(); + + static LauncherNotificationsController* instance(); + + QAbstractItemModel* notifications() const; + + Q_INVOKABLE QJSValue argsForIndex(int index) const; + + QJSEngine* jsEngine(); +public slots: + void dismissIndex(int index); + + void postNotification(QString id, QUrl source, QJSValue args = {}); + +signals: + + +private: + class NotificationsModel; + + NotificationsModel* _model = nullptr; + QQmlEngine* _qmlEngine = nullptr; +}; diff --git a/src/GUI/LauncherPackageDelegate.cxx b/src/GUI/LauncherPackageDelegate.cxx new file mode 100644 index 000000000..d7fa815d2 --- /dev/null +++ b/src/GUI/LauncherPackageDelegate.cxx @@ -0,0 +1,73 @@ + +// Copyright (C) 2020 James Turner +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#include "config.h" + +#include "LauncherPackageDelegate.hxx" + +#include +#include + +#include + +#include
+#include + +#include "LauncherNotificationsController.hxx" + +LauncherPackageDelegate::LauncherPackageDelegate(QObject* parent) : QObject(parent) +{ + globals->packageRoot()->addDelegate(this); + const auto http = globals->get_subsystem(); + _defaultCatalogId = http->getDefaultCatalogId(); +} + +LauncherPackageDelegate::~LauncherPackageDelegate() +{ + globals->packageRoot()->removeDelegate(this); +} + +void LauncherPackageDelegate::catalogRefreshed(simgear::pkg::CatalogRef aCatalog, simgear::pkg::Delegate::StatusCode aReason) +{ + if ((aReason != Delegate::STATUS_REFRESHED) || !aCatalog) { + return; + } + + auto nc = LauncherNotificationsController::instance(); + + if (aCatalog->migratedFrom() != simgear::pkg::CatalogRef{}) { + QJSValue args = nc->jsEngine()->newObject(); + + args.setProperty("newCatalogName", QString::fromStdString(aCatalog->name())); + + if (aCatalog->id() == _defaultCatalogId) { + nc->postNotification("did-migrate-official-catalog-to-" + QString::fromStdString(_defaultCatalogId), + QUrl{"qrc:///qml/DidMigrateOfficialCatalogNotification.qml"}, + args); + } else { + nc->postNotification("did-migrate-catalog-to-" + QString::fromStdString(aCatalog->id()), + QUrl{"qrc:///qml/DidMigrateOtherCatalogNotification.qml"}, + args); + } + } +} + +void LauncherPackageDelegate::finishInstall(simgear::pkg::InstallRef ref, simgear::pkg::Delegate::StatusCode status) +{ + Q_UNUSED(ref) + Q_UNUSED(status) +} diff --git a/src/GUI/LauncherPackageDelegate.hxx b/src/GUI/LauncherPackageDelegate.hxx new file mode 100644 index 000000000..66a4c61e4 --- /dev/null +++ b/src/GUI/LauncherPackageDelegate.hxx @@ -0,0 +1,37 @@ +#ifndef LAUNCHERPACKAGEDELEGATE_HXX +#define LAUNCHERPACKAGEDELEGATE_HXX + +#include + +#include + +#include +#include +#include +#include + +class LauncherPackageDelegate : public QObject, + public simgear::pkg::Delegate +{ + Q_OBJECT + +public: + explicit LauncherPackageDelegate(QObject* parent = nullptr); + ~LauncherPackageDelegate(); + +protected: + void catalogRefreshed(simgear::pkg::CatalogRef aCatalog, StatusCode aReason) override; + + // mandatory overrides, not actually needed here. + void startInstall(simgear::pkg::InstallRef) override {} + void installProgress(simgear::pkg::InstallRef, unsigned int, unsigned int) override{}; + void finishInstall(simgear::pkg::InstallRef ref, StatusCode status) override; + +signals: + void didMigrateOfficialHangarChanged(); + +private: + std::string _defaultCatalogId; +}; + +#endif // LAUNCHERPACKAGEDELEGATE_HXX diff --git a/src/GUI/UpdateChecker.cxx b/src/GUI/UpdateChecker.cxx index 35414df8e..9fe769f80 100644 --- a/src/GUI/UpdateChecker.cxx +++ b/src/GUI/UpdateChecker.cxx @@ -135,6 +135,7 @@ void UpdateChecker::receivedUpdateXML(QByteArray body) const auto s = body.toStdString(); QSettings settings; + auto nc = LauncherNotificationsController::instance(); try { const char* buffer = s.c_str(); @@ -156,6 +157,8 @@ void UpdateChecker::receivedUpdateXML(QByteArray body) m_updateUri = QUrl(QString::fromStdString(newVersionUri)); emit statusChanged(m_status); + nc->postNotification("flightgear-update-major", QUrl{"qrc:///qml/NewVersionNotification.qml"}); + return; // don't consider minor updates } } @@ -172,6 +175,8 @@ void UpdateChecker::receivedUpdateXML(QByteArray body) const std::string newVersionUri = props->getStringValue("download-uri"); m_updateUri = QUrl(QString::fromStdString(newVersionUri)); emit statusChanged(m_status); + + nc->postNotification("flightgear-update-point", QUrl{"qrc:///qml/NewVersionNotification.qml"}); } } } catch (const sg_exception &e) { diff --git a/src/GUI/assets/white-cross-icon.png b/src/GUI/assets/white-cross-icon.png new file mode 100644 index 000000000..db6b5f715 Binary files /dev/null and b/src/GUI/assets/white-cross-icon.png differ diff --git a/src/GUI/qml/DidMigrateOfficialCatalogNotification.qml b/src/GUI/qml/DidMigrateOfficialCatalogNotification.qml new file mode 100644 index 000000000..09d240174 --- /dev/null +++ b/src/GUI/qml/DidMigrateOfficialCatalogNotification.qml @@ -0,0 +1,21 @@ +import QtQuick 2.4 +import "." + +Text { + signal dismiss(); + + readonly property string updateAllLink: "\"launcher:update-all\""; + readonly property string newName: _notifications.argsForIndex(model.index).newCatalogName + + text: qsTr("An updated version of the official aircraft hangar '%2' was automatically installed. " + + "Existing aircraft have been marked for update, click here to update them all").arg(updateAllLink).arg(newName) + + wrapMode: Text.WordWrap + font.pixelSize: Style.subHeadingFontPixelSize + color: "white" + + onLinkActivated: { + _launcher.requestUpdateAllAircraft(); + dismiss(); // request our dismissal + } +} diff --git a/src/GUI/qml/DidMigrateOtherCatalogNotification.qml b/src/GUI/qml/DidMigrateOtherCatalogNotification.qml new file mode 100644 index 000000000..6f0b8be44 --- /dev/null +++ b/src/GUI/qml/DidMigrateOtherCatalogNotification.qml @@ -0,0 +1,21 @@ +import QtQuick 2.4 +import "." + +Text { + signal dismiss(); + + readonly property string updateAllLink: "\"launcher:update-all\""; + readonly property string newName: _notifications.argsForIndex(model.index).newCatalogName + + text: qsTr("An updated version of the hangar '%2' was automatically installed. " + + "Existing aircraft have been marked for update, click here to update them all").arg(updateAllLink).arg(newName) + + wrapMode: Text.WordWrap + font.pixelSize: Style.subHeadingFontPixelSize + color: "white" + + onLinkActivated: { + _launcher.requestUpdateAllAircraft(); + dismiss(); // request our dismissal + } +} diff --git a/src/GUI/qml/Launcher.qml b/src/GUI/qml/Launcher.qml index 748961837..ddfe07282 100644 --- a/src/GUI/qml/Launcher.qml +++ b/src/GUI/qml/Launcher.qml @@ -1,4 +1,5 @@ import QtQuick 2.4 +import QtQml 2.4 import FlightGear 1.0 import "." @@ -149,6 +150,18 @@ Item { source: "qrc:///qml/Summary.qml" } + NotificationArea { + id: notifications + // only show on the summary page + visible: sidebar.selectedPage === 0 + + anchors { + right: parent.right + top: parent.top + bottom: parent.bottom + } + } + function selectPage(index) { sidebar.setSelectedPage(index); diff --git a/src/GUI/qml/NewVersionNotification.qml b/src/GUI/qml/NewVersionNotification.qml new file mode 100644 index 000000000..b997f6ce1 --- /dev/null +++ b/src/GUI/qml/NewVersionNotification.qml @@ -0,0 +1,28 @@ + +import QtQuick 2.4 +import FlightGear.Launcher 1.0 +import "." + +ClickableText { + signal dismiss(); + + text: msg.arg(_updates.updateVersion) + readonly property string msg: (_updates.status == UpdateChecker.MajorUpdate) ? + qsTr("A new release of FlightGear is available (%1): click for more information") + : qsTr("Updated version %1 is available: click here to download") + + + wrapMode: Text.WordWrap + font.pixelSize: Style.subHeadingFontPixelSize + color: "white" + + onClicked: { + _launcher.launchUrl(_updates.updateUri); + } + + function dismissed() + { + _updates.ignoreUpdate(); + } +} + diff --git a/src/GUI/qml/NotificationArea.qml b/src/GUI/qml/NotificationArea.qml new file mode 100644 index 000000000..ebaf8dcbb --- /dev/null +++ b/src/GUI/qml/NotificationArea.qml @@ -0,0 +1,111 @@ +import QtQuick 2.4 +import QtQml 2.4 + +import FlightGear.Launcher 1.0 +import ".." + +Item { + id: root + width: 500 + + readonly property int ourMargin: Style.margin * 2 + + + Component { + id: notificationBox + + Rectangle { + id: boxRoot + + property alias content: contentLoader.sourceComponent + + width: notificationsColumn.width + height: contentLoader.height + (ourMargin * 2) + + clip: true + color: Style.themeColor + border.width: 1 + border.color: Qt.darker(Style.themeColor) + + Rectangle { + id: background + anchors.fill: parent + z: -1 + opacity: Style.panelOpacity + color: "white" + } + + Loader { + // height is not anchored, can float + anchors { + top: parent.top + left: parent.left + right: closeButton.left + margins: ourMargin + } + + id: contentLoader + source: model.source + + // don't set height, comes from content + } + + Connections { + target: contentLoader.item + onDismiss: { + _notifications.dismissIndex(model.index) + } + } + + Image { + id: closeButton + source: "qrc:///white-delete-icon" + + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + margins: ourMargin + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + + onClicked: { + if (contentLoader.item.dismissed) { + contentLoader.item.dismissed(); + } + + _notifications.dismissIndex(model.index) + } + } + } + } // of notification box + } + + // ensure clicks 'near' the notifications don't go to other UI + MouseArea { + width: parent.width + height: notificationsColumn.height + } + + Column { + id: notificationsColumn + + anchors { + right: parent.right + top: parent.top + bottom: parent.bottom + left: parent.left + margins: Style.strutSize + } + + spacing: Style.strutSize + + Repeater { + model: _notifications.active + delegate: notificationBox + } + } // of boxes column + +} diff --git a/src/GUI/qml/Summary.qml b/src/GUI/qml/Summary.qml index 7445bc781..22f7673b5 100644 --- a/src/GUI/qml/Summary.qml +++ b/src/GUI/qml/Summary.qml @@ -1,4 +1,5 @@ import QtQuick 2.4 +import QtQml 2.4 import FlightGear.Launcher 1.0 import "." @@ -77,54 +78,7 @@ Item { styleColor: "black" } - Row { - spacing: Style.margin - 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 - - id: updateMessage - - visible: _updates.status != UpdateChecker.NoUpdate - - readonly property string msg: (_updates.status == UpdateChecker.MajorUpdate) ? - qsTr("A new release of FlightGear is available (%1): click for more information") - : qsTr("Updated version %1 is available: click here to download") - - ClickableText { - text: parent.msg.arg(_updates.updateVersion) - baseTextColor: "white" - style: Text.Outline - styleColor: "black" - font.bold: true - font.pixelSize: Style.headingFontPixelSize - - onClicked: { - _launcher.launchUrl(_updates.updateUri); - } - } - - ClickableText { - text: qsTr("(or click to ignore this)") - baseTextColor: "white" - style: Text.Outline - styleColor: "black" - font.bold: true - font.pixelSize: Style.headingFontPixelSize - - onClicked: { - _updates.ignoreUpdate(); - } - } - } - ClickableText { - visible: !updateMessage.visible anchors { left: logoText.left right: logoText.right @@ -360,5 +314,5 @@ Item { width: 1; height: 1 } } - } + } // of summary box } diff --git a/src/GUI/resources.qrc b/src/GUI/resources.qrc index 107fff5d4..75c88a154 100644 --- a/src/GUI/resources.qrc +++ b/src/GUI/resources.qrc @@ -110,6 +110,7 @@ qml/LocationAltitudeRow.qml qml/CatalogDelegate.qml assets/icons8-clear-symbol-26.png + assets/white-cross-icon.png qml/FlightPlan.qml qml/PlainTextEditBox.qml qml/HeaderBox.qml @@ -136,6 +137,11 @@ assets/icons8-christmas-star-outline.png qml/FirstRun.qml qml/HelpSupport.qml + qml/NotificationArea.qml + qml/NewVersionNotification.qml + qml/DidMigrateOfficialCatalogNotification.qml + qml/DidMigrateOtherCatalogNotification.qml + assets/preview-close.png diff --git a/src/Network/HTTPClient.cxx b/src/Network/HTTPClient.cxx index 1015c9169..f06b4c8f3 100644 --- a/src/Network/HTTPClient.cxx +++ b/src/Network/HTTPClient.cxx @@ -124,12 +124,15 @@ bool FGHTTPClient::isDefaultCatalogInstalled() const return getDefaultCatalog().valid(); } -void FGHTTPClient::addDefaultCatalog() +pkg::CatalogRef FGHTTPClient::addDefaultCatalog() { pkg::CatalogRef defaultCatalog = getDefaultCatalog(); if (!defaultCatalog.valid()) { - pkg::Catalog::createFromUrl(globals->packageRoot(), getDefaultCatalogUrl()); + auto cat = pkg::Catalog::createFromUrl(globals->packageRoot(), getDefaultCatalogUrl()); + return cat; } + + return defaultCatalog; } std::string FGHTTPClient::getDefaultCatalogId() const diff --git a/src/Network/HTTPClient.hxx b/src/Network/HTTPClient.hxx index 640fff7b3..07be3a452 100644 --- a/src/Network/HTTPClient.hxx +++ b/src/Network/HTTPClient.hxx @@ -21,8 +21,10 @@ #ifndef FG_HTTP_CLIENT_HXX #define FG_HTTP_CLIENT_HXX -#include #include +#include +#include + #include class FGHTTPClient : public SGSubsystem @@ -46,7 +48,7 @@ public: simgear::HTTP::Client const* client() const { return _http.get(); } bool isDefaultCatalogInstalled() const; - void addDefaultCatalog(); + simgear::pkg::CatalogRef addDefaultCatalog(); std::string getDefaultCatalogId() const; std::string getDefaultCatalogUrl() const;