# # # patch "notes/TODO" # from [cbc759fde6bf8f2a54dee3ca9bac88e695235fda] # to [f5963ff348fad78dca6a2303e68eaed6d3e544eb] # # patch "src/view/MainWindow.cpp" # from [d90f84228175d6b63f614248e511611bcf167cf3] # to [72d33bd2fe71dbcffcd818e7fdbd13bcd6692cf7] # # patch "src/view/MainWindow.h" # from [627db714e8b3f00acd00cd164015dffc4c3f3075] # to [7ea22986b3ba2005db4b604c592a91365ba78122] # # patch "src/view/dialogs/Dialog.cpp" # from [e9ecf89d39050a297c2aa5717aad76f1a8601a8f] # to [961d379997e820b54efd31f638161d2ea84e5558] # # patch "src/view/dialogs/Dialog.h" # from [ce52b7c6e4c2dba2ae4b83fdf37cbf1bcda2b0bb] # to [8e41006355f2b99dd3dc6a50d520b8e5782e6d14] # ============================================================ --- notes/TODO cbc759fde6bf8f2a54dee3ca9bac88e695235fda +++ notes/TODO f5963ff348fad78dca6a2303e68eaed6d3e544eb @@ -1,7 +1,3 @@ -Current TODO, for "long-term" stuff see IDEAS: +Current TODO, for "long-term" stuff see IDEAS. +nothing to do before 0.6 hit the streets -* get rid of this nasty bug which crashes the app if a dialog is opened and the - main window in the background is closed (some invalid pointer issue) -* make Sparkle work properly on OSX, alternatively display the common update - dialog - ============================================================ --- src/view/MainWindow.cpp d90f84228175d6b63f614248e511611bcf167cf3 +++ src/view/MainWindow.cpp 72d33bd2fe71dbcffcd818e7fdbd13bcd6692cf7 @@ -53,7 +53,7 @@ MainWindow::MainWindow() #include MainWindow::MainWindow() - : QMainWindow() + : QMainWindow(), closeCounter(0) { setAttribute(Qt::WA_MacMetalStyle); @@ -212,6 +212,10 @@ void MainWindow::closeEvent(QCloseEvent void MainWindow::closeEvent(QCloseEvent *event) { + Q_ASSERT(closeCounter >= 0); + // ignore the close event if there are still open dialog windows + if (closeCounter > 0) return; + // the last closed window sets the geometry for the next one which is opened Settings::setWindowGeometry(saveGeometry(), "MainWindow_mode" + mode); event->accept(); @@ -590,7 +594,7 @@ void MainWindow::on_actionCheck_for_upda void MainWindow::on_actionCheck_for_updates_triggered() { -#ifdef Q_WS_MAC +#ifdef Q_WS_MACX CocoaUtil::checkForUpdates(); #else ApplicationUpdate dlg(this); @@ -629,3 +633,22 @@ void MainWindow::invalidWorkspaceFormat( close(); } +// FIXME: These two functions are actually a hack: we block the closing of this +// window if a non-blocking (non-modal) dialog is still open which expects that +// its parent window pointer is still valid at some point. As dialogs can be +// nested, a simple boolean value wouldn't be sufficient since the close action +// of the main window would get enabled again as soon as the first subsequent +// dialog has been closed, which would lead to segfaults for the one opened in +// first place. Of course the underlying bug (that the app segfaults at all) +// should be fixed someday... +void MainWindow::enableClosing() +{ + Q_ASSERT(closeCounter > 0); + closeCounter--; +} + +void MainWindow::disableClosing() +{ + closeCounter++; +} + ============================================================ --- src/view/MainWindow.h 627db714e8b3f00acd00cd164015dffc4c3f3075 +++ src/view/MainWindow.h 7ea22986b3ba2005db4b604c592a91365ba78122 @@ -42,7 +42,9 @@ public: bool doLoadWorkspace(QString); bool doLoadDatabase(QString); - + void enableClosing(); + void disableClosing(); + public slots: void doUpdatePreviousWorkspacesMenu(); void doUpdatePreviousDatabasesMenu(); @@ -88,6 +90,7 @@ private: InventoryProxyModel *proxyModelFolderTree; InventoryProxyModel *proxyModelFileList; Mode mode; + int closeCounter; }; ============================================================ --- src/view/dialogs/Dialog.cpp e9ecf89d39050a297c2aa5717aad76f1a8601a8f +++ src/view/dialogs/Dialog.cpp 961d379997e820b54efd31f638161d2ea84e5558 @@ -21,16 +21,16 @@ #include "Dialog.h" #include "Settings.h" #include "SignalWaiter.h" +#include "MainWindow.h" -#include #include -Dialog::Dialog(QWidget* parent) : QDialog(parent) +Dialog::Dialog(QWidget * parent) : QDialog(parent) { setAttribute(Qt::WA_MacMetalStyle); } -Dialog::Dialog(QWidget* parent, QString objName) +Dialog::Dialog(QWidget * parent, QString objName) : QDialog(parent) { setObjectName(objName); @@ -68,12 +68,17 @@ int Dialog::execDocumentModal() // ensure that this is only called from top level windows QWidget * parent = parentWidget(); Q_ASSERT(parent && parent->inherits("QMainWindow")); + MainWindow * wnd = qobject_cast(parent); + Q_ASSERT(wnd); + // disable the close button's functionality in the MainWindow + wnd->disableClosing(); + QMap enableState; // disable all menu actions (for some reason disabling the menuBar itself // does not result in the desired effect under OSX) - QList list = qobject_cast(parent)->menuBar()->actions(); + QList list = wnd->menuBar()->actions(); foreach(QAction * act, list) { QList innerList = act->menu()->actions(); @@ -100,6 +105,9 @@ int Dialog::execDocumentModal() act->setEnabled(enableState.value(act)); } + // enable the close button's functionality in the MainWindow again + wnd->enableClosing(); + return result(); } ============================================================ --- src/view/dialogs/Dialog.h ce52b7c6e4c2dba2ae4b83fdf37cbf1bcda2b0bb +++ src/view/dialogs/Dialog.h 8e41006355f2b99dd3dc6a50d520b8e5782e6d14 @@ -28,8 +28,8 @@ public: Q_OBJECT public: - Dialog(QWidget*); - Dialog(QWidget*, QString); + Dialog(QWidget *); + Dialog(QWidget *, QString); ~Dialog(); void init(); void setStayOnTop();