@@ -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
163164void 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
200205void 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
250266void 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
268286QSurface* FredView::getRenderSurface () {
269287 return ui->centralWidget ->getRenderSurface ();
270288}
271289void FredView::newMission () {
290+ if (!maybePromptToSaveMissionChanges (tr (" creating a new mission" ))) {
291+ return ;
292+ }
293+
272294 fred->createNewMission ();
273295}
274296void 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+ }
391442void 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+ }
585644void FredView::windowActivated () {
586645 key_got_focus ();
587646
0 commit comments