diff --git a/qtfred/src/ui/FredView.cpp b/qtfred/src/ui/FredView.cpp index 4cba59ffbeb..41062c6b5dc 100644 --- a/qtfred/src/ui/FredView.cpp +++ b/qtfred/src/ui/FredView.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -448,6 +449,7 @@ bool FredView::saveMissionToCurrentPath() { save.save_mission_file(saveName.replace('/', DIR_SEPARATOR_CHAR).toUtf8().constData()); _missionModified = false; + setLastSaved(QDateTime::currentDateTime()); if (fixCount > 0) QMessageBox::information(this, tr("Auto-corrections Applied"), @@ -488,6 +490,7 @@ bool FredView::saveMissionAs() { save.save_mission_file(saveName.replace('/', DIR_SEPARATOR_CHAR).toUtf8().constData()); _missionModified = false; + setLastSaved(QDateTime::currentDateTime()); if (fixCount > 0) QMessageBox::information(this, tr("Auto-corrections Applied"), @@ -747,6 +750,9 @@ void FredView::on_mission_loaded(const std::string& filepath) { // Clear browsed head ANIs so the new mission's message scan starts fresh. fso::fred::dialogs::MissionEventsDialogModel::clearBrowsedHeadAnis(); + // A freshly loaded or newly created mission has not been saved this session yet. + setLastSaved(QDateTime()); + if (_errorCheckerDialog) { _errorCheckerDialog->clearErrors(); } @@ -903,6 +909,12 @@ void FredView::initializeStatusBar() { _statusBarObjectCount->setAlignment(Qt::AlignCenter); statusBar()->addWidget(_statusBarObjectCount, 1); + // Sits just right of the (centered, stretched) object count, near the middle. + _statusBarLastSaved = new QLabel(); + _statusBarLastSaved->setContentsMargins(16, 0, 0, 0); + statusBar()->addWidget(_statusBarLastSaved); + setLastSaved(QDateTime()); + _statusBarViewmode = new QLabel(); _statusBarViewmode->setContentsMargins(8, 0, 0, 0); statusBar()->addPermanentWidget(_statusBarViewmode); @@ -912,6 +924,17 @@ void FredView::initializeStatusBar() { statusBar()->addPermanentWidget(_statusBarUnitsLabel); } +void FredView::setLastSaved(const QDateTime& when) { + if (!_statusBarLastSaved) + return; + + if (when.isValid()) { + _statusBarLastSaved->setText(tr("Last Saved: %1").arg(when.toString(QStringLiteral("MMM d, yyyy h:mm:ss AP")))); + } else { + _statusBarLastSaved->setText(tr("Last Saved: Never")); + } +} + // --------------------------------------------------------------------------- // Context toolbar (top, below the primary toolbar) // --------------------------------------------------------------------------- @@ -2507,6 +2530,7 @@ void FredView::on_actionLoadout_triggered(bool) { } void FredView::on_actionVariables_triggered(bool) { auto editorDialog = new dialogs::VariableDialog(this, _viewport); + editorDialog->setAttribute(Qt::WA_DeleteOnClose); editorDialog->show(); } diff --git a/qtfred/src/ui/FredView.h b/qtfred/src/ui/FredView.h index fda7d73e8fa..31e09e7665f 100644 --- a/qtfred/src/ui/FredView.h +++ b/qtfred/src/ui/FredView.h @@ -21,6 +21,7 @@ #include class waypoint_list; +class QDateTime; namespace fso { namespace fred { @@ -247,9 +248,13 @@ class FredView: public QMainWindow, public IDialogProvider { void onSetGroup(int group); QLabel* _statusBarObjectCount = nullptr; + QLabel* _statusBarLastSaved = nullptr; QLabel* _statusBarViewmode = nullptr; QLabel* _statusBarUnitsLabel = nullptr; + // Updates the "Last Saved" status bar label: pass an empty time to show "Never". + void setLastSaved(const QDateTime& when); + SceneBrowserPanel* _browserPanel = nullptr; QMenu* _viewPopup = nullptr; diff --git a/qtfred/src/ui/dialogs/AsteroidEditorDialog.cpp b/qtfred/src/ui/dialogs/AsteroidEditorDialog.cpp index 0349af77c61..14fedc3e2df 100644 --- a/qtfred/src/ui/dialogs/AsteroidEditorDialog.cpp +++ b/qtfred/src/ui/dialogs/AsteroidEditorDialog.cpp @@ -68,7 +68,15 @@ void AsteroidEditorDialog::reject() void AsteroidEditorDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void AsteroidEditorDialog::initializeUi() diff --git a/qtfred/src/ui/dialogs/BriefingEditorDialog.cpp b/qtfred/src/ui/dialogs/BriefingEditorDialog.cpp index 651b94c8f17..c9ce6707793 100644 --- a/qtfred/src/ui/dialogs/BriefingEditorDialog.cpp +++ b/qtfred/src/ui/dialogs/BriefingEditorDialog.cpp @@ -135,7 +135,15 @@ void BriefingEditorDialog::reject() void BriefingEditorDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void BriefingEditorDialog::setupMapWidget() diff --git a/qtfred/src/ui/dialogs/CommandBriefingDialog.cpp b/qtfred/src/ui/dialogs/CommandBriefingDialog.cpp index 529346e6120..245426036e1 100644 --- a/qtfred/src/ui/dialogs/CommandBriefingDialog.cpp +++ b/qtfred/src/ui/dialogs/CommandBriefingDialog.cpp @@ -56,7 +56,15 @@ void CommandBriefingDialog::reject() void CommandBriefingDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void CommandBriefingDialog::initializeUi() diff --git a/qtfred/src/ui/dialogs/DebriefingDialog.cpp b/qtfred/src/ui/dialogs/DebriefingDialog.cpp index cbcf3523899..0652f6306a3 100644 --- a/qtfred/src/ui/dialogs/DebriefingDialog.cpp +++ b/qtfred/src/ui/dialogs/DebriefingDialog.cpp @@ -60,7 +60,15 @@ void DebriefingDialog::reject() void DebriefingDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void DebriefingDialog::initializeUi() diff --git a/qtfred/src/ui/dialogs/FictionViewerDialog.cpp b/qtfred/src/ui/dialogs/FictionViewerDialog.cpp index 632f17b0600..7ab0d4bd193 100644 --- a/qtfred/src/ui/dialogs/FictionViewerDialog.cpp +++ b/qtfred/src/ui/dialogs/FictionViewerDialog.cpp @@ -58,7 +58,15 @@ void FictionViewerDialog::reject() void FictionViewerDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void FictionViewerDialog::initializeUi() diff --git a/qtfred/src/ui/dialogs/MissionCutscenesDialog.cpp b/qtfred/src/ui/dialogs/MissionCutscenesDialog.cpp index ebe3f99c8aa..37d603506e1 100644 --- a/qtfred/src/ui/dialogs/MissionCutscenesDialog.cpp +++ b/qtfred/src/ui/dialogs/MissionCutscenesDialog.cpp @@ -58,7 +58,15 @@ void MissionCutscenesDialog::reject() void MissionCutscenesDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void MissionCutscenesDialog::updateUi() diff --git a/qtfred/src/ui/dialogs/MissionEventsDialog.cpp b/qtfred/src/ui/dialogs/MissionEventsDialog.cpp index ecd56b83099..be9fa022da4 100644 --- a/qtfred/src/ui/dialogs/MissionEventsDialog.cpp +++ b/qtfred/src/ui/dialogs/MissionEventsDialog.cpp @@ -288,7 +288,15 @@ bool MissionEventsDialog::hasDefaultMessageParameter() void MissionEventsDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void MissionEventsDialog::initMessageWidgets() { @@ -701,7 +709,7 @@ void MissionEventsDialog::on_chainedCheckBox_stateChanged(int state) updateEventUi(); } -void MissionEventsDialog::on_chainedDelayBox_valueChanged(int value) +void MissionEventsDialog::on_chainDelayBox_valueChanged(int value) { _model->setChainDelay(value); } diff --git a/qtfred/src/ui/dialogs/MissionEventsDialog.h b/qtfred/src/ui/dialogs/MissionEventsDialog.h index 15cd5561c67..296ec70410d 100644 --- a/qtfred/src/ui/dialogs/MissionEventsDialog.h +++ b/qtfred/src/ui/dialogs/MissionEventsDialog.h @@ -51,7 +51,7 @@ private slots: void on_triggerCountBox_valueChanged(int value); void on_intervalTimeBox_valueChanged(int value); void on_chainedCheckBox_stateChanged(int state); - void on_chainedDelayBox_valueChanged(int value); + void on_chainDelayBox_valueChanged(int value); void on_useMsecsCheckBox_stateChanged(int state); void on_scoreBox_valueChanged(int value); void on_teamCombo_currentIndexChanged(int index); diff --git a/qtfred/src/ui/dialogs/MissionGoalsDialog.cpp b/qtfred/src/ui/dialogs/MissionGoalsDialog.cpp index 6eaf4cc61c0..52588017119 100644 --- a/qtfred/src/ui/dialogs/MissionGoalsDialog.cpp +++ b/qtfred/src/ui/dialogs/MissionGoalsDialog.cpp @@ -56,7 +56,15 @@ void MissionGoalsDialog::reject() void MissionGoalsDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void MissionGoalsDialog::updateUi() diff --git a/qtfred/src/ui/dialogs/MissionSpecDialog.cpp b/qtfred/src/ui/dialogs/MissionSpecDialog.cpp index 9d21a454617..4cf2c3ffccd 100644 --- a/qtfred/src/ui/dialogs/MissionSpecDialog.cpp +++ b/qtfred/src/ui/dialogs/MissionSpecDialog.cpp @@ -62,7 +62,15 @@ void MissionSpecDialog::reject() void MissionSpecDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void MissionSpecDialog::initializeUi() diff --git a/qtfred/src/ui/dialogs/MissionSpecs/CustomDataDialog.cpp b/qtfred/src/ui/dialogs/MissionSpecs/CustomDataDialog.cpp index 2fc980a5cc9..2a8d5f5fc3b 100644 --- a/qtfred/src/ui/dialogs/MissionSpecs/CustomDataDialog.cpp +++ b/qtfred/src/ui/dialogs/MissionSpecs/CustomDataDialog.cpp @@ -71,7 +71,15 @@ void CustomDataDialog::reject() void CustomDataDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void CustomDataDialog::setInitial(const SCP_map& items) diff --git a/qtfred/src/ui/dialogs/MissionSpecs/CustomStringsDialog.cpp b/qtfred/src/ui/dialogs/MissionSpecs/CustomStringsDialog.cpp index 8c844b2e977..064dcd4c85c 100644 --- a/qtfred/src/ui/dialogs/MissionSpecs/CustomStringsDialog.cpp +++ b/qtfred/src/ui/dialogs/MissionSpecs/CustomStringsDialog.cpp @@ -70,7 +70,15 @@ void CustomStringsDialog::reject() void CustomStringsDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void CustomStringsDialog::setInitial(const SCP_vector& items) diff --git a/qtfred/src/ui/dialogs/MissionSpecs/CustomWingNamesDialog.cpp b/qtfred/src/ui/dialogs/MissionSpecs/CustomWingNamesDialog.cpp index 5ca0a24b94c..14fcbb7a242 100644 --- a/qtfred/src/ui/dialogs/MissionSpecs/CustomWingNamesDialog.cpp +++ b/qtfred/src/ui/dialogs/MissionSpecs/CustomWingNamesDialog.cpp @@ -67,7 +67,15 @@ void CustomWingNamesDialog::reject() void CustomWingNamesDialog::closeEvent(QCloseEvent * e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void CustomWingNamesDialog::setInitialStartingWings(const std::array& startingWings) { diff --git a/qtfred/src/ui/dialogs/MissionSpecs/SoundEnvironmentDialog.cpp b/qtfred/src/ui/dialogs/MissionSpecs/SoundEnvironmentDialog.cpp index 3793b69df4c..9bfa58b26f0 100644 --- a/qtfred/src/ui/dialogs/MissionSpecs/SoundEnvironmentDialog.cpp +++ b/qtfred/src/ui/dialogs/MissionSpecs/SoundEnvironmentDialog.cpp @@ -78,7 +78,15 @@ void SoundEnvironmentDialog::closeEvent(QCloseEvent* e) reject(); closeWave(); disableEnvPreview(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void SoundEnvironmentDialog::enableOrDisableFields() diff --git a/qtfred/src/ui/dialogs/MissionSpecs/SupportRearmDialog.cpp b/qtfred/src/ui/dialogs/MissionSpecs/SupportRearmDialog.cpp index 87a93d50252..6b1c66b66bf 100644 --- a/qtfred/src/ui/dialogs/MissionSpecs/SupportRearmDialog.cpp +++ b/qtfred/src/ui/dialogs/MissionSpecs/SupportRearmDialog.cpp @@ -33,7 +33,15 @@ SupportRearmSettings SupportRearmDialog::settings() const void SupportRearmDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } QString SupportRearmDialog::weaponEntryText(int weaponClass) const diff --git a/qtfred/src/ui/dialogs/ObjectOrientEditorDialog.cpp b/qtfred/src/ui/dialogs/ObjectOrientEditorDialog.cpp index 625c12425da..ad1c0d484f7 100644 --- a/qtfred/src/ui/dialogs/ObjectOrientEditorDialog.cpp +++ b/qtfred/src/ui/dialogs/ObjectOrientEditorDialog.cpp @@ -49,7 +49,15 @@ void ObjectOrientEditorDialog::reject() void ObjectOrientEditorDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void ObjectOrientEditorDialog::initializeUi() diff --git a/qtfred/src/ui/dialogs/ReinforcementsEditorDialog.cpp b/qtfred/src/ui/dialogs/ReinforcementsEditorDialog.cpp index 02c58862f97..5493ac3c8e5 100644 --- a/qtfred/src/ui/dialogs/ReinforcementsEditorDialog.cpp +++ b/qtfred/src/ui/dialogs/ReinforcementsEditorDialog.cpp @@ -53,7 +53,15 @@ void ReinforcementsDialog::reject() void ReinforcementsDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } diff --git a/qtfred/src/ui/dialogs/ShipEditor/ShipAltShipClass.cpp b/qtfred/src/ui/dialogs/ShipEditor/ShipAltShipClass.cpp index 2e3bfc60547..3271e416c5c 100644 --- a/qtfred/src/ui/dialogs/ShipEditor/ShipAltShipClass.cpp +++ b/qtfred/src/ui/dialogs/ShipEditor/ShipAltShipClass.cpp @@ -46,7 +46,15 @@ void ShipAltShipClass::reject() void ShipAltShipClass::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void ShipAltShipClass::on_buttonBox_accepted() diff --git a/qtfred/src/ui/dialogs/ShipEditor/ShipCustomWarpDialog.cpp b/qtfred/src/ui/dialogs/ShipEditor/ShipCustomWarpDialog.cpp index a22b4f7676c..32d6906aae5 100644 --- a/qtfred/src/ui/dialogs/ShipEditor/ShipCustomWarpDialog.cpp +++ b/qtfred/src/ui/dialogs/ShipEditor/ShipCustomWarpDialog.cpp @@ -144,7 +144,15 @@ void ShipCustomWarpDialog::reject() void ShipCustomWarpDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void ShipCustomWarpDialog::updateUi(const bool firstrun) { diff --git a/qtfred/src/ui/dialogs/ShipEditor/ShipFlagsDialog.cpp b/qtfred/src/ui/dialogs/ShipEditor/ShipFlagsDialog.cpp index a6459a63fa0..bc3cff2785b 100644 --- a/qtfred/src/ui/dialogs/ShipEditor/ShipFlagsDialog.cpp +++ b/qtfred/src/ui/dialogs/ShipEditor/ShipFlagsDialog.cpp @@ -73,7 +73,15 @@ void ShipFlagsDialog::reject() { void ShipFlagsDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void ShipFlagsDialog::on_okAndCancelButtons_accepted() { diff --git a/qtfred/src/ui/dialogs/ShipEditor/ShipGoalsDialog.cpp b/qtfred/src/ui/dialogs/ShipEditor/ShipGoalsDialog.cpp index 4efbcb3ffe4..3a7645af712 100644 --- a/qtfred/src/ui/dialogs/ShipEditor/ShipGoalsDialog.cpp +++ b/qtfred/src/ui/dialogs/ShipEditor/ShipGoalsDialog.cpp @@ -87,7 +87,15 @@ void ShipGoalsDialog::reject() void ShipGoalsDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void ShipGoalsDialog::on_okButton_clicked() { diff --git a/qtfred/src/ui/dialogs/ShipEditor/ShipInitialStatusDialog.cpp b/qtfred/src/ui/dialogs/ShipEditor/ShipInitialStatusDialog.cpp index 5125ce587f7..1d28b170af9 100644 --- a/qtfred/src/ui/dialogs/ShipEditor/ShipInitialStatusDialog.cpp +++ b/qtfred/src/ui/dialogs/ShipEditor/ShipInitialStatusDialog.cpp @@ -55,7 +55,15 @@ void ShipInitialStatusDialog::reject() void ShipInitialStatusDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void ShipInitialStatusDialog::on_velocitySpinBox_valueChanged(int value) { diff --git a/qtfred/src/ui/dialogs/ShipEditor/ShipSpecialStatsDialog.cpp b/qtfred/src/ui/dialogs/ShipEditor/ShipSpecialStatsDialog.cpp index e905c4e5397..a6833909283 100644 --- a/qtfred/src/ui/dialogs/ShipEditor/ShipSpecialStatsDialog.cpp +++ b/qtfred/src/ui/dialogs/ShipEditor/ShipSpecialStatsDialog.cpp @@ -46,7 +46,15 @@ void ShipSpecialStatsDialog::reject() void ShipSpecialStatsDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void ShipSpecialStatsDialog::on_buttonBox_accepted() diff --git a/qtfred/src/ui/dialogs/ShipEditor/ShipTextureReplacementDialog.cpp b/qtfred/src/ui/dialogs/ShipEditor/ShipTextureReplacementDialog.cpp index 909e0af73d2..7c84582f503 100644 --- a/qtfred/src/ui/dialogs/ShipEditor/ShipTextureReplacementDialog.cpp +++ b/qtfred/src/ui/dialogs/ShipEditor/ShipTextureReplacementDialog.cpp @@ -115,7 +115,15 @@ void ShipTextureReplacementDialog::reject() void ShipTextureReplacementDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void ShipTextureReplacementDialog::on_buttonBox_accepted() { diff --git a/qtfred/src/ui/dialogs/ShipEditor/ShipWeaponsDialog.cpp b/qtfred/src/ui/dialogs/ShipEditor/ShipWeaponsDialog.cpp index cb05100761c..00f3adc5d50 100644 --- a/qtfred/src/ui/dialogs/ShipEditor/ShipWeaponsDialog.cpp +++ b/qtfred/src/ui/dialogs/ShipEditor/ShipWeaponsDialog.cpp @@ -279,7 +279,15 @@ void ShipWeaponsDialog::reject() void ShipWeaponsDialog::closeEvent(QCloseEvent* event) { reject(); - event->ignore(); + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + event->ignore(); + } else { + event->accept(); + } } void ShipWeaponsDialog::on_okAndCancelButtons_accepted() diff --git a/qtfred/src/ui/dialogs/TeamLoadoutDialog.cpp b/qtfred/src/ui/dialogs/TeamLoadoutDialog.cpp index baf83130e21..1b20e099907 100644 --- a/qtfred/src/ui/dialogs/TeamLoadoutDialog.cpp +++ b/qtfred/src/ui/dialogs/TeamLoadoutDialog.cpp @@ -64,7 +64,15 @@ void TeamLoadoutDialog::reject() void TeamLoadoutDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void TeamLoadoutDialog::initializeUi() diff --git a/qtfred/src/ui/dialogs/VariableDialog.cpp b/qtfred/src/ui/dialogs/VariableDialog.cpp index 2e8b1c89f7b..46cf2bafe9a 100644 --- a/qtfred/src/ui/dialogs/VariableDialog.cpp +++ b/qtfred/src/ui/dialogs/VariableDialog.cpp @@ -88,7 +88,15 @@ void VariableDialog::reject() void VariableDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void VariableDialog::initializeUi() diff --git a/qtfred/src/ui/dialogs/VolumetricNebulaDialog.cpp b/qtfred/src/ui/dialogs/VolumetricNebulaDialog.cpp index d186dfc0508..d9a7deffeeb 100644 --- a/qtfred/src/ui/dialogs/VolumetricNebulaDialog.cpp +++ b/qtfred/src/ui/dialogs/VolumetricNebulaDialog.cpp @@ -51,7 +51,15 @@ void VolumetricNebulaDialog::reject() void VolumetricNebulaDialog::closeEvent(QCloseEvent* e) { reject(); - e->ignore(); // Don't let the base class close the window + // reject() hides the dialog when it actually closes. Let that close + // proceed (so a dialog created with WA_DeleteOnClose is destroyed), + // and only veto it when reject() decided to keep the dialog open (e.g. + // the user cancelled the unsaved-changes prompt). + if (isVisible()) { + e->ignore(); + } else { + e->accept(); + } } void VolumetricNebulaDialog::initializeUi()