Skip to content

Commit 7adcf9f

Browse files
authored
track mission modified and prompt to save (scp-fs2open#7305)
1 parent ff28a9c commit 7adcf9f

2 files changed

Lines changed: 72 additions & 5 deletions

File tree

qtfred/src/ui/FredView.cpp

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ void FredView::setEditor(Editor* editor, EditorViewport* viewport) {
129129
connect(_propClassBox.get(), &PropComboBox::propClassSelected, this, &FredView::onPropClassSelected);
130130

131131
connect(fred, &Editor::missionLoaded, this, &FredView::on_mission_loaded);
132+
connect(fred, &Editor::missionChanged, this, [this]() { _missionModified = true; });
132133

133134
// Sets the initial window title
134135
on_mission_loaded("");
@@ -161,6 +162,10 @@ void FredView::setEditor(Editor* editor, EditorViewport* viewport) {
161162
}
162163

163164
void FredView::loadMissionFile(const QString& pathName) {
165+
if (!maybePromptToSaveMissionChanges(tr("loading another mission"))) {
166+
return;
167+
}
168+
164169
statusBar()->showMessage(tr("Loading mission %1").arg(pathName));
165170
try {
166171
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
@@ -198,6 +203,14 @@ void FredView::on_actionExit_triggered(bool) {
198203
}
199204

200205
void FredView::on_actionSave_triggered(bool state) {
206+
Q_UNUSED(state);
207+
saveMissionToCurrentPath();
208+
}
209+
void FredView::on_actionSave_As_triggered(bool) {
210+
saveMissionAs();
211+
}
212+
213+
bool FredView::saveMissionToCurrentPath() {
201214
Fred_mission_save save;
202215
// TODO FredView save format actions currently don't do anything
203216
// will need to wire this up when those are finalized
@@ -215,13 +228,14 @@ void FredView::on_actionSave_triggered(bool state) {
215228
save.set_fred_callsigns(Fred_callsigns);
216229

217230
if (saveName.isEmpty()) {
218-
on_actionSave_As_triggered(state);
219-
return;
231+
return saveMissionAs();
220232
}
221233

222234
save.save_mission_file(saveName.replace('/', DIR_SEPARATOR_CHAR).toUtf8().constData());
235+
_missionModified = false;
236+
return true;
223237
}
224-
void FredView::on_actionSave_As_triggered(bool) {
238+
bool FredView::saveMissionAs() {
225239
Fred_mission_save save;
226240
// TODO FredView save format actions currently don't do anything
227241
// will need to wire this up when those are finalized
@@ -241,10 +255,12 @@ void FredView::on_actionSave_As_triggered(bool) {
241255
saveName = QFileDialog::getSaveFileName(this, tr("Save mission"), QString(), tr("FS2 missions (*.fs2)"));
242256

243257
if (saveName.isEmpty()) {
244-
return;
258+
return false;
245259
}
246260

247261
save.save_mission_file(saveName.replace('/',DIR_SEPARATOR_CHAR).toUtf8().constData());
262+
_missionModified = false;
263+
return true;
248264
}
249265

250266
void FredView::on_mission_loaded(const std::string& filepath) {
@@ -263,12 +279,18 @@ void FredView::on_mission_loaded(const std::string& filepath) {
263279
if (!filepath.empty()) {
264280
addToRecentFiles(QString::fromStdString(filepath));
265281
}
282+
283+
_missionModified = false;
266284
}
267285

268286
QSurface* FredView::getRenderSurface() {
269287
return ui->centralWidget->getRenderSurface();
270288
}
271289
void FredView::newMission() {
290+
if (!maybePromptToSaveMissionChanges(tr("creating a new mission"))) {
291+
return;
292+
}
293+
272294
fred->createNewMission();
273295
}
274296
void FredView::addToRecentFiles(const QString& path) {
@@ -379,6 +401,7 @@ void FredView::updateUI() {
379401
}
380402

381403
_statusBarUnitsLabel->setText(tr("Units = %1 Meters").arg(_viewport->The_grid->square_size));
404+
setWindowModified(isMissionModified());
382405

383406
if (_viewport->viewpoint == 1) {
384407
_statusBarViewmode->setText(tr("Viewpoint: %1").arg(object_name(_viewport->view_obj)));
@@ -388,6 +411,34 @@ void FredView::updateUI() {
388411

389412
viewIdle();
390413
}
414+
bool FredView::isMissionModified() const {
415+
return _missionModified;
416+
}
417+
418+
bool FredView::maybePromptToSaveMissionChanges(const QString& actionDescription) {
419+
if (!isMissionModified()) {
420+
return true;
421+
}
422+
423+
QMessageBox confirmationDialog(this);
424+
confirmationDialog.setIcon(QMessageBox::Warning);
425+
confirmationDialog.setWindowTitle(tr("Unsaved Changes"));
426+
confirmationDialog.setText(tr("The current mission has unsaved changes."));
427+
confirmationDialog.setInformativeText(tr("Do you want to save your changes before %1?").arg(actionDescription));
428+
confirmationDialog.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
429+
confirmationDialog.setDefaultButton(QMessageBox::Save);
430+
confirmationDialog.setEscapeButton(QMessageBox::Cancel);
431+
432+
switch (confirmationDialog.exec()) {
433+
case QMessageBox::Save:
434+
return saveMissionToCurrentPath();
435+
case QMessageBox::Discard:
436+
return true;
437+
case QMessageBox::Cancel:
438+
default:
439+
return false;
440+
}
441+
}
391442
void FredView::connectActionToViewSetting(QAction* option, bool* destination) {
392443
Q_ASSERT(option->isCheckable());
393444

@@ -582,6 +633,14 @@ bool FredView::event(QEvent* event) {
582633
return QMainWindow::event(event);
583634
}
584635
}
636+
void FredView::closeEvent(QCloseEvent* event) {
637+
if (!maybePromptToSaveMissionChanges(tr("closing QtFRED"))) {
638+
event->ignore();
639+
return;
640+
}
641+
642+
QMainWindow::closeEvent(event);
643+
}
585644
void FredView::windowActivated() {
586645
key_got_focus();
587646

qtfred/src/ui/FredView.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <QtWidgets/QLabel>
77
#include <QtWidgets/QComboBox>
88
#include <QtGui/QSurface>
9+
#include <QCloseEvent>
910

1011
#include <mission/FredRenderer.h>
1112
#include <mission/IDialogProvider.h>
@@ -169,14 +170,20 @@ class FredView: public QMainWindow, public IDialogProvider {
169170
*/
170171
void viewWindowActivated();
171172
protected:
172-
bool event(QEvent* event) override;
173+
bool event(QEvent* event) override;
174+
void closeEvent(QCloseEvent* event) override;
173175

174176
void keyPressEvent(QKeyEvent* event) override;
175177
void keyReleaseEvent(QKeyEvent* event) override;
176178

177179
void mouseDoubleClickEvent(QMouseEvent* event) override;
178180

179181
private:
182+
bool saveMissionToCurrentPath();
183+
bool saveMissionAs();
184+
bool maybePromptToSaveMissionChanges(const QString& actionDescription);
185+
bool isMissionModified() const;
186+
180187
void on_mission_loaded(const std::string& filepath);
181188

182189
void connectActionToViewSetting(QAction* option, bool* destination);
@@ -232,6 +239,7 @@ class FredView: public QMainWindow, public IDialogProvider {
232239

233240
bool _inKeyPressHandler = false;
234241
bool _inKeyReleaseHandler = false;
242+
bool _missionModified = false;
235243

236244
void onUpdateConstrains();
237245
void onUpdateEditingMode();

0 commit comments

Comments
 (0)