From 217db33b9932a433752ac8cd71d4de3b214bd7c4 Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 12 Mar 2015 23:43:58 +0100 Subject: [PATCH] Working on adding catalogs from the GUI --- src/GUI/AddCatalogDialog.cxx | 175 +++++++++++++++++++++++++++++++++++ src/GUI/AddCatalogDialog.hxx | 73 +++++++++++++++ src/GUI/AddCatalogDialog.ui | 152 ++++++++++++++++++++++++++++++ src/GUI/CMakeLists.txt | 7 +- src/GUI/CatalogListModel.cxx | 12 +++ src/GUI/CatalogListModel.hxx | 4 + src/GUI/QtLauncher.cxx | 12 ++- 7 files changed, 433 insertions(+), 2 deletions(-) create mode 100644 src/GUI/AddCatalogDialog.cxx create mode 100644 src/GUI/AddCatalogDialog.hxx create mode 100644 src/GUI/AddCatalogDialog.ui diff --git a/src/GUI/AddCatalogDialog.cxx b/src/GUI/AddCatalogDialog.cxx new file mode 100644 index 000000000..6d7665a6e --- /dev/null +++ b/src/GUI/AddCatalogDialog.cxx @@ -0,0 +1,175 @@ +// AddCatalogDialog.cxx - part of GUI launcher using Qt5 +// +// Written by James Turner, started March 2015. +// +// Copyright (C) 2015 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 "AddCatalogDialog.hxx" +#include "ui_AddCatalogDialog.h" + +#include +#include + +#include + +using namespace simgear::pkg; + +AddCatalogDialog::AddCatalogDialog(QWidget *parent, RootRef root) : + QDialog(parent), + m_state(STATE_START), + ui(new Ui::AddCatalogDialog), + m_packageRoot(root) +{ + ui->setupUi(this); + + connect(ui->urlEdit, &QLineEdit::textEdited, + this, &AddCatalogDialog::onUrlTextChanged); + + updateUi(); +} + +AddCatalogDialog::~AddCatalogDialog() +{ + delete ui; +} + +CatalogRef AddCatalogDialog::addedCatalog() +{ + return m_result; +} + +void AddCatalogDialog::onUrlTextChanged() +{ + m_catalogUrl = QUrl::fromUserInput(ui->urlEdit->text()); + updateUi(); +} + +void AddCatalogDialog::updateUi() +{ + QPushButton* b = ui->buttonBox->button(QDialogButtonBox::Ok); + + switch (m_state) { + case STATE_START: + b->setText(tr("Next")); + b->setEnabled(m_catalogUrl.isValid() && !m_catalogUrl.isRelative()); + break; + + case STATE_DOWNLOADING: + b->setEnabled(false); + break; + + case STATE_DOWNLOAD_FAILED: + b->setEnabled(false); + break; + + case STATE_FINISHED: + b->setEnabled(true); + b->setText(tr("Okay")); + break; + } + + if (m_state == STATE_FINISHED) { + QString catDesc = QString::fromStdString(m_result->description()); + QString s = tr("Successfully retrieved aircraft information from '%1'. " + "%2 aircraft are included in this hangar.").arg(catDesc).arg(m_result->packages().size()); + ui->resultsSummaryLabel->setText(s); + } else if (m_state == STATE_DOWNLOAD_FAILED) { + Delegate::FailureCode code = m_result->status(); + qWarning() << Q_FUNC_INFO << "failed with code" << code; + QString s; + switch (code) { + case Delegate::FAIL_DOWNLOAD: + s = tr("Failed to download aircraft descriptions from '%1'. " + "Check the address (URL) and your network connection.").arg(m_catalogUrl.toString()); + break; + + case Delegate::FAIL_VERSION: + s = tr("The provided hangar is for a different version of FLightGear. " + "(This is version %1)").arg(QString::fromUtf8(FLIGHTGEAR_VERSION)); + break; + + default: + s = tr("Unknown error occured trying to set up the hangar."); + } + + ui->resultsSummaryLabel->setText(s); + } +} + +void AddCatalogDialog::startDownload() +{ + Q_ASSERT(m_catalogUrl.isValid()); + + m_result = Catalog::createFromUrl(m_packageRoot, m_catalogUrl.toString().toStdString()); + m_result->addStatusCallback(this, &AddCatalogDialog::onCatalogStatusChanged); + m_state = STATE_DOWNLOADING; + updateUi(); + ui->stack->setCurrentIndex(STATE_DOWNLOADING); +} + +void AddCatalogDialog::accept() +{ + switch (m_state) { + case STATE_START: + startDownload(); + break; + + case STATE_DOWNLOADING: + case STATE_DOWNLOAD_FAILED: + // can't happen, button is disabled + break; + + case STATE_FINISHED: + QDialog::accept(); + break; + } +} + +void AddCatalogDialog::reject() +{ + if (m_result && !m_result->id().empty()) { + // user may have successfully download the catalog, but choosen + // not to add it. so remove it here + m_packageRoot->removeCatalogById(m_result->id()); + } + + QDialog::reject(); +} + +void AddCatalogDialog::onCatalogStatusChanged(Catalog* cat) +{ + Delegate::FailureCode s = cat->status(); + qDebug() << Q_FUNC_INFO << "cat status:" << s; + switch (s) { + case Delegate::CATALOG_REFRESHED: + m_state = STATE_FINISHED; + break; + + case Delegate::FAIL_IN_PROGRESS: + // don't jump to STATE_FINISHED + return; + + // all the actual failure codes + default: + m_state = STATE_DOWNLOAD_FAILED; + break; + } + + ui->stack->setCurrentIndex(STATE_FINISHED); + updateUi(); +} + diff --git a/src/GUI/AddCatalogDialog.hxx b/src/GUI/AddCatalogDialog.hxx new file mode 100644 index 000000000..d67393dfa --- /dev/null +++ b/src/GUI/AddCatalogDialog.hxx @@ -0,0 +1,73 @@ +// AddCatalogDialog.hxx - part of GUI launcher using Qt5 +// +// Written by James Turner, started March 2015. +// +// Copyright (C) 2015 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. + +#ifndef FG_GUI_ADDCATALOGDIALOG_HXX +#define FG_GUI_ADDCATALOGDIALOG_HXX + +#include +#include + +#include +#include + +namespace Ui { +class AddCatalogDialog; +} + +class AddCatalogDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AddCatalogDialog(QWidget *parent, + simgear::pkg::RootRef root); + ~AddCatalogDialog(); + + simgear::pkg::CatalogRef addedCatalog(); + +private slots: + virtual void reject(); + virtual void accept(); + + void onUrlTextChanged(); +private: + void startDownload(); + void updateUi(); + + // callback from the catalog + void onCatalogStatusChanged(simgear::pkg::Catalog* cat); + + enum State { + STATE_START = 0, // awaiting user input on first screen + STATE_DOWNLOADING = 1, // in-progress, showing progress page + STATE_FINISHED = 2, // catalog added ok, showing summary page + STATE_DOWNLOAD_FAILED // download checks failed for some reason + + }; + + State m_state; + + Ui::AddCatalogDialog *ui; + simgear::pkg::RootRef m_packageRoot; + QUrl m_catalogUrl; + simgear::pkg::CatalogRef m_result; +}; + +#endif // FG_GUI_ADDCATALOGDIALOG_HXX diff --git a/src/GUI/AddCatalogDialog.ui b/src/GUI/AddCatalogDialog.ui new file mode 100644 index 000000000..fd20fd99a --- /dev/null +++ b/src/GUI/AddCatalogDialog.ui @@ -0,0 +1,152 @@ + + + AddCatalogDialog + + + + 0 + 0 + 500 + 200 + + + + Add aircraft hangar + + + + + + 0 + + + + + + + Enter the URL of an aircraft hangar: + + + + + + + http://www.somesite.com/flightgear-aircraft.xml + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 0 + 0 + + + + Please waiting, downloading and checking the hangar information. + + + + + + + + 0 + 0 + + + + 0 + + + -1 + + + + + + + + + + + Lorem Ipsum + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AddCatalogDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AddCatalogDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/GUI/CMakeLists.txt b/src/GUI/CMakeLists.txt index 542e41107..8773aa2b4 100644 --- a/src/GUI/CMakeLists.txt +++ b/src/GUI/CMakeLists.txt @@ -70,7 +70,10 @@ endif() if (HAVE_QT) - qt5_wrap_ui(uic_sources Launcher.ui EditRatingsFilterDialog.ui SetupRootDialog.ui) + qt5_wrap_ui(uic_sources Launcher.ui + EditRatingsFilterDialog.ui + SetupRootDialog.ui + AddCatalogDialog.ui) qt5_add_resources(qrc_sources resources.qrc) include_directories(${PROJECT_BINARY_DIR}/src/GUI) @@ -89,6 +92,8 @@ if (HAVE_QT) AircraftModel.cxx CatalogListModel.cxx CatalogListModel.hxx + AddCatalogDialog.cxx + AddCatalogDialog.hxx ${uic_sources} ${qrc_sources}) diff --git a/src/GUI/CatalogListModel.cxx b/src/GUI/CatalogListModel.cxx index 9b7d264e2..a6533efb9 100644 --- a/src/GUI/CatalogListModel.cxx +++ b/src/GUI/CatalogListModel.cxx @@ -28,6 +28,8 @@ #include #include +#include + // FlightGear #include
@@ -41,6 +43,12 @@ CatalogListModel::~CatalogListModel() { } +void CatalogListModel::refresh() +{ + beginResetModel(); + endResetModel(); +} + int CatalogListModel::rowCount(const QModelIndex& parent) const { return m_packageRoot->catalogs().size(); @@ -58,6 +66,10 @@ QVariant CatalogListModel::data(const QModelIndex& index, int role) const return QUrl(QString::fromStdString(cat->url())); } else if (role == CatalogIdRole) { return QString::fromStdString(cat->id()); + } else if (role == CatalogPackageCountRole) { + return static_cast(cat->packages().size()); + } else if (role == CatalogInstallCountRole) { + return static_cast(cat->installedPackages().size()); } return QVariant(); diff --git a/src/GUI/CatalogListModel.hxx b/src/GUI/CatalogListModel.hxx index dfbe724ad..8b3fc4723 100644 --- a/src/GUI/CatalogListModel.hxx +++ b/src/GUI/CatalogListModel.hxx @@ -32,6 +32,8 @@ const int CatalogUrlRole = Qt::UserRole + 1; const int CatalogIdRole = Qt::UserRole + 2; +const int CatalogPackageCountRole = Qt::UserRole + 3; +const int CatalogInstallCountRole = Qt::UserRole + 4; class CatalogListModel : public QAbstractListModel { @@ -41,6 +43,8 @@ public: ~CatalogListModel(); + void refresh(); + virtual int rowCount(const QModelIndex& parent) const; virtual QVariant data(const QModelIndex& index, int role) const; diff --git a/src/GUI/QtLauncher.cxx b/src/GUI/QtLauncher.cxx index 82e55d0e9..8d2d8b28e 100644 --- a/src/GUI/QtLauncher.cxx +++ b/src/GUI/QtLauncher.cxx @@ -54,6 +54,7 @@ #include "AircraftItemDelegate.hxx" #include "AircraftModel.hxx" #include "CatalogListModel.hxx" +#include "AddCatalogDialog.hxx" #include
#include @@ -543,6 +544,11 @@ QtLauncher::QtLauncher() : m_catalogsModel = new CatalogListModel(this, r); m_ui->catalogsList->setModel(m_catalogsModel); + connect(m_ui->addCatalog, &QToolButton::clicked, + this, &QtLauncher::onAddCatalog); + connect(m_ui->removeCatalog, &QToolButton::clicked, + this, &QtLauncher::onRemoveCatalog); + QSettings settings; m_aircraftModel->setPaths(settings.value("aircraft-paths").toStringList()); m_aircraftModel->scanDirs(); @@ -1143,7 +1149,11 @@ void QtLauncher::onSubsytemIdleTimeout() void QtLauncher::onAddCatalog() { - + AddCatalogDialog* dlg = new AddCatalogDialog(this, globals->packageRoot()); + dlg->exec(); + if (dlg->result() == QDialog::Accepted) { + m_catalogsModel->refresh(); + } } void QtLauncher::onRemoveCatalog() -- 2.39.5