55using System . Diagnostics ;
66using System . IO ;
77using System . Linq ;
8+ using System . Text ;
89using System . Text . RegularExpressions ;
910using System . Windows ;
1011using System . Windows . Controls ;
1415using System . Windows . Threading ;
1516using DiscordRPC ;
1617using MahApps . Metro ;
18+ using MahApps . Metro . Controls . Dialogs ;
1719using SPCode . Interop ;
1820using SPCode . Interop . Updater ;
1921using SPCode . UI . Components ;
@@ -34,6 +36,7 @@ public partial class MainWindow
3436 private readonly Storyboard EnableServerAnim ;
3537 public readonly List < MenuItem > MenuItems ;
3638
39+ private bool ClosingBuffer ;
3740 private readonly bool FullyInitialized ;
3841
3942 private ObservableCollection < string > ActionButtonDict = new ( )
@@ -177,60 +180,60 @@ private void DockingPaneGroup_ChildrenTreeChanged(object sender, ChildrenTreeCha
177180 }
178181 }
179182
180- private void MetroWindow_Closing ( object sender , CancelEventArgs e )
183+ private async void MetroWindow_Closing ( object sender , CancelEventArgs e )
181184 {
182- if ( ServerIsRunning )
185+ if ( ! ClosingBuffer )
183186 {
184- ServerCheckThread . Abort ( ) ;
185- ServerProcess . Kill ( ) ;
186- }
187- var lastOpenFiles = new List < string > ( ) ;
188- var editors = GetAllEditorElements ( ) ;
189- bool ? SaveUnsaved = null ;
190- if ( editors != null )
191- {
192- foreach ( var editor in editors )
187+ // Close directly if no files need to be saved
188+ var editors = GetAllEditorElements ( ) ? . ToList ( ) ;
189+
190+ if ( editors == null || ( editors != null && ! editors . Any ( x => x . NeedsSave ) ) )
193191 {
194- if ( File . Exists ( editor . FullFilePath ) )
195- {
196- lastOpenFiles . Add ( editor . FullFilePath ) ;
197- if ( editor . NeedsSave )
198- {
199- if ( SaveUnsaved == null )
200- {
201- var result = MessageBox . Show ( this , Program . Translations . GetLanguage ( "SavingUFiles" ) ,
202- Program . Translations . GetLanguage ( "Saving" ) , MessageBoxButton . YesNo ,
203- MessageBoxImage . Question ) ;
204- SaveUnsaved = result == MessageBoxResult . Yes ;
205- }
192+ ClosingBuffer = true ;
193+ CloseProgram ( true ) ;
194+ }
195+ else
196+ {
197+ // Cancel closing to handle it manually
198+ e . Cancel = true ;
206199
207- if ( SaveUnsaved . Value )
208- {
209- editor . Close ( true ) ;
210- }
211- else
212- {
213- editor . Close ( false , false ) ;
214- }
215- }
216- else
217- {
218- editor . Close ( false , false ) ;
219- }
200+ // Build dialog buttons
201+ var closeMetroDialogOptions = new MetroDialogSettings ( )
202+ {
203+ AffirmativeButtonText = Program . Translations . GetLanguage ( "Yes" ) ,
204+ NegativeButtonText = Program . Translations . GetLanguage ( "No" ) ,
205+ FirstAuxiliaryButtonText = Program . Translations . GetLanguage ( "Cancel" ) ,
206+ AnimateHide = false ,
207+ AnimateShow = false ,
208+ DefaultButtonFocus = MessageDialogResult . SecondAuxiliary
209+ } ;
210+
211+ // Build list of unsaved files to show
212+ var sb = new StringBuilder ( ) ;
213+ editors . Where ( x => x . NeedsSave ) . ToList ( ) . ForEach ( y => sb . AppendLine ( $ " - { y . Parent . Title . Substring ( 1 ) } ") ) ;
214+
215+ var result = await this . ShowMessageAsync ( "Save all files?" , $ "Unsaved files:\n { sb } ",
216+ MessageDialogStyle . AffirmativeAndNegativeAndSingleAuxiliary , closeMetroDialogOptions ) ;
217+
218+ switch ( result )
219+ {
220+ case MessageDialogResult . Affirmative :
221+ ClosingBuffer = true ;
222+ CloseProgram ( true ) ;
223+ Close ( ) ;
224+ break ;
225+
226+ case MessageDialogResult . Negative :
227+ ClosingBuffer = true ;
228+ CloseProgram ( false ) ;
229+ Close ( ) ;
230+ break ;
231+
232+ case MessageDialogResult . FirstAuxiliary :
233+ return ;
220234 }
221235 }
222236 }
223-
224- Program . OptionsObject . LastOpenFiles = lastOpenFiles . ToArray ( ) ;
225-
226- Program . DiscordClient . Dispose ( ) ;
227- #if ! DEBUG
228- if ( Program . UpdateStatus . IsAvailable )
229- {
230- var updateWin = new UpdateWindow ( Program . UpdateStatus ) { Owner = this } ;
231- updateWin . ShowDialog ( ) ;
232- }
233- #endif
234237 }
235238
236239 private void MetroWindow_Drop ( object sender , DragEventArgs e )
@@ -256,6 +259,7 @@ private void EditorObjectBrowserGridRow_WidthChanged(object sender, EventArgs e)
256259 {
257260 Program . OptionsObject . Program_ObjectbrowserWidth = ObjectBrowserColumn . Width . Value ;
258261 }
262+
259263 }
260264 #endregion
261265
@@ -461,5 +465,47 @@ public void UpdateWindowTitle()
461465
462466 Title = outString ;
463467 }
468+
469+ private void CloseProgram ( bool saveAll )
470+ {
471+ // Save all the last open files
472+ var lastOpenFiles = new List < string > ( ) ;
473+ var editors = GetAllEditorElements ( ) ? . ToList ( ) ;
474+
475+ editors ? . ForEach ( x =>
476+ {
477+ if ( File . Exists ( x . FullFilePath ) )
478+ {
479+ lastOpenFiles . Add ( x . FullFilePath ) ;
480+ }
481+ } ) ;
482+ Program . OptionsObject . LastOpenFiles = lastOpenFiles . ToArray ( ) ;
483+
484+ if ( saveAll )
485+ {
486+ editors ? . ForEach ( x => x . Close ( true ) ) ;
487+ }
488+ else
489+ {
490+ editors ? . ForEach ( x => x . Close ( false , false ) ) ;
491+ }
492+
493+ // Kill children process from "Server Start" feature
494+ if ( ServerIsRunning )
495+ {
496+ ServerCheckThread . Abort ( ) ;
497+ ServerProcess . Kill ( ) ;
498+ }
499+
500+ // Kill Discord RPC
501+ Program . DiscordClient . Dispose ( ) ;
502+
503+ // Check for updates in production
504+ if ( ! Debugger . IsAttached && Program . UpdateStatus . IsAvailable )
505+ {
506+ var updateWin = new UpdateWindow ( Program . UpdateStatus ) { Owner = this } ;
507+ updateWin . ShowDialog ( ) ;
508+ }
509+ }
464510 #endregion
465511}
0 commit comments