From 2d663f2509d50b156cee303611987d4c2053100b Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 15 Nov 2017 21:46:57 +0000 Subject: [PATCH] Fix crash with adding catalogs in the launcher Change how we get notified about catalog changes, so we can remove our hook and hence not leave a dangling pointer. Fixes https://sourceforge.net/p/flightgear/codetickets/1994/ --- src/GUI/AddCatalogDialog.cxx | 28 ++++++++++++++++++++++++++-- src/GUI/AddCatalogDialog.hxx | 11 +++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/GUI/AddCatalogDialog.cxx b/src/GUI/AddCatalogDialog.cxx index 6a89ba769..72b14ac92 100644 --- a/src/GUI/AddCatalogDialog.cxx +++ b/src/GUI/AddCatalogDialog.cxx @@ -30,6 +30,23 @@ using namespace simgear::pkg; +class AddCatalogDialog::AddCatalogDelegate : public simgear::pkg::Delegate +{ +public: + AddCatalogDelegate(AddCatalogDialog* outer) : p(outer) {} + + void catalogRefreshed(CatalogRef catalog, StatusCode) override + { + p->onCatalogStatusChanged(catalog); + } + + void startInstall(InstallRef) override {} + void installProgress(InstallRef, unsigned int, unsigned int) override {} + void finishInstall(InstallRef, StatusCode ) override {} +private: + AddCatalogDialog* p = nullptr; +}; + AddCatalogDialog::AddCatalogDialog(QWidget *parent, RootRef root) : QDialog(parent, Qt::Dialog | Qt::CustomizeWindowHint @@ -37,7 +54,6 @@ AddCatalogDialog::AddCatalogDialog(QWidget *parent, RootRef root) : | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint), - m_state(STATE_START), ui(new Ui::AddCatalogDialog), m_packageRoot(root) { @@ -51,6 +67,9 @@ AddCatalogDialog::AddCatalogDialog(QWidget *parent, RootRef root) : AddCatalogDialog::~AddCatalogDialog() { + if (m_delegate) { + m_packageRoot->removeDelegate(m_delegate.get()); + } delete ui; } @@ -137,8 +156,9 @@ void AddCatalogDialog::startDownload() { Q_ASSERT(m_catalogUrl.isValid()); + m_delegate.reset(new AddCatalogDelegate{this}); + m_packageRoot->addDelegate(m_delegate.get()); 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); @@ -175,6 +195,10 @@ void AddCatalogDialog::reject() void AddCatalogDialog::onCatalogStatusChanged(Catalog* cat) { + if (cat != m_result) { + return; + } + Delegate::StatusCode s = cat->status(); switch (s) { case Delegate::STATUS_REFRESHED: diff --git a/src/GUI/AddCatalogDialog.hxx b/src/GUI/AddCatalogDialog.hxx index a8593860c..fcea7313e 100644 --- a/src/GUI/AddCatalogDialog.hxx +++ b/src/GUI/AddCatalogDialog.hxx @@ -21,6 +21,8 @@ #ifndef FG_GUI_ADDCATALOGDIALOG_HXX #define FG_GUI_ADDCATALOGDIALOG_HXX +#include + #include #include @@ -31,6 +33,7 @@ namespace Ui { class AddCatalogDialog; } + class AddCatalogDialog : public QDialog { Q_OBJECT @@ -56,10 +59,12 @@ private slots: void onUrlTextChanged(); private: + class AddCatalogDelegate; + friend class AddCatalogDelegate; + void startDownload(); void updateUi(); - // callback from the catalog void onCatalogStatusChanged(simgear::pkg::Catalog* cat); enum State { @@ -70,13 +75,15 @@ private: }; - State m_state; + State m_state = STATE_START; Ui::AddCatalogDialog *ui; simgear::pkg::RootRef m_packageRoot; QUrl m_catalogUrl; simgear::pkg::CatalogRef m_result; bool m_nonInteractiveMode = false; + + std::unique_ptr m_delegate; }; #endif // FG_GUI_ADDCATALOGDIALOG_HXX