Vereinsmeisterschaften  22aa7800eae54b428d40e835886cefe1fdefdfdf
This is a software that can be used to manage the internal competition of the swimming club Illertissen called "Vereinsmeisterschaften".
Loading...
Searching...
No Matches
WorkspaceManagerViewModel.cs
1using System.Collections.ObjectModel;
2using System.IO;
3using System.IO.Compression;
4using System.Resources;
5using System.Windows.Input;
6using CommunityToolkit.Mvvm.ComponentModel;
7using CommunityToolkit.Mvvm.Input;
8using MahApps.Metro.Controls.Dialogs;
9using Microsoft.Win32;
18
20
25{
29 public const string DEFAULT_TEMPLATE_ZIP_FILE_NAME = "DefaultTemplates.zip";
30
31 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32
33 #region Properties
34
36 public string CurrentWorkspaceFolder => _workspaceService.PersistentPath;
37
39 public bool HasUnsavedChanges => _workspaceService.HasUnsavedChanges;
40
42 public ObservableCollection<string> LastWorkspacePaths => _workspaceService.LastWorkspacePaths;
43
44 #endregion
45
46 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47
48 #region Commands: Close / Save / Load / New
49
50 private ICommand _closeWorkspaceCommand;
52 public ICommand CloseWorkspaceCommand => _closeWorkspaceCommand ?? (_closeWorkspaceCommand = new RelayCommand(async() =>
53 {
54 try
55 {
56 bool save = true, cancel = false;
57 (save, cancel) = await _shellVM.CheckForUnsavedChangesAndQueryUserAction();
58
59 if (!cancel)
60 {
61 await _workspaceService?.CloseWorkspace(CancellationToken.None, save);
62
63 // Only navigate to the main page, when the current page isn't main page or workspace page
64 if (!(_navigationService?.CurrentFrameViewModel is MainViewModel) && !(_navigationService?.CurrentFrameViewModel is WorkspaceViewModel))
65 {
66 // Open the main page
67 _navigationService.NavigateTo<MainViewModel>();
68 }
69 }
70 }
71 catch (Exception ex)
72 {
73 await _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, ex.Message);
74 }
75 }, () => _workspaceService.IsWorkspaceOpen));
76
77 // ----------------------------------------------------------------------------------------------------------------------------------------------
78
79 private ICommand _saveWorkspaceCommand;
81 public ICommand SaveWorkspaceCommand => _saveWorkspaceCommand ?? (_saveWorkspaceCommand = new RelayCommand(async() =>
82 {
83 try
84 {
85 await _workspaceService?.Save(CancellationToken.None);
86 }
87 catch (Exception ex)
88 {
89 await _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, ex.Message);
90 }
91 }, () => _workspaceService.IsWorkspaceOpen));
92
93 // ----------------------------------------------------------------------------------------------------------------------------------------------
94
95 private ICommand _loadWorkspaceCommand;
97 public ICommand LoadWorkspaceCommand => _loadWorkspaceCommand ?? (_loadWorkspaceCommand = new RelayCommand(async() =>
98 {
99 bool save = true, cancel = false;
100 (save, cancel) = await _shellVM.CheckForUnsavedChangesAndQueryUserAction();
101
102 if (!cancel)
103 {
104 try
105 {
106 OpenFolderDialog folderDialog = new OpenFolderDialog();
107 folderDialog.Multiselect = false;
108 folderDialog.InitialDirectory = CurrentWorkspaceFolder;
109 if (folderDialog.ShowDialog() == true)
110 {
111 if (_workspaceService?.IsWorkspaceOpen ?? false)
112 {
113 await _workspaceService?.CloseWorkspace(CancellationToken.None, save);
114 }
115 bool result = await _workspaceService?.Load(folderDialog.FolderName, CancellationToken.None);
116 OnWorkspaceLoaded?.Invoke(this, folderDialog.FolderName);
117 OnPropertyChanged(nameof(LastWorkspacePaths));
118
119 _navigationService.ReloadCurrent(); // Navigate to the current page to trigger the reload of the page
120
121 if (!result)
122 {
123 await _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, Resources.WorkspaceNotLoadedString);
124 }
125 }
126 }
127 catch (Exception ex)
128 {
129 await _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, ex.Message);
130 }
131 }
132 }));
133
134 // ----------------------------------------------------------------------------------------------------------------------------------------------
135
136 private ICommand _loadLastWorkspaceCommand;
138 public ICommand LoadLastWorkspaceCommand => _loadLastWorkspaceCommand ?? (_loadLastWorkspaceCommand = new RelayCommand<string>(async (param) =>
139 {
140 bool save = true, cancel = false;
141 (save, cancel) = await _shellVM.CheckForUnsavedChangesAndQueryUserAction();
142
143 if (!cancel)
144 {
145 try
146 {
147 string path = param as string;
148 if (_workspaceService?.IsWorkspaceOpen ?? false)
149 {
150 await _workspaceService?.CloseWorkspace(CancellationToken.None, save);
151 }
152 bool result = await _workspaceService?.Load(path, CancellationToken.None);
153 OnWorkspaceLoaded?.Invoke(this, path);
154 OnPropertyChanged(nameof(LastWorkspacePaths));
155
156 _navigationService.ReloadCurrent(); // Navigate to the current page to trigger the reload of the page
157
158 if (!result)
159 {
160 await _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, Resources.WorkspaceNotLoadedString);
161 }
162 }
163 catch (Exception ex)
164 {
165 await _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, ex.Message);
166 }
167 }
168 }));
169
170 // ----------------------------------------------------------------------------------------------------------------------------------------------
171
172 private ICommand _openWorkspaceFolderCommand;
174 public ICommand OpenWorkspaceFolderCommand => _openWorkspaceFolderCommand ?? (_openWorkspaceFolderCommand = new RelayCommand(() =>
175 {
176 try
177 {
178 System.Diagnostics.Process.Start("explorer.exe", CurrentWorkspaceFolder);
179 }
180 catch (Exception ex)
181 {
182 _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, ex.Message);
183 }
184 }, () => _workspaceService.IsWorkspaceOpen));
185
186 // ----------------------------------------------------------------------------------------------------------------------------------------------
187
188 private ICommand _createNewWorkspaceCommand;
190 public ICommand CreateNewWorkspaceCommand => _createNewWorkspaceCommand ?? (_createNewWorkspaceCommand = new RelayCommand(async () =>
191 {
192 bool save = true, cancel = false;
193 (save, cancel) = await _shellVM.CheckForUnsavedChangesAndQueryUserAction();
194
195 if (!cancel)
196 {
197 try
198 {
200 dialog.PreviousWorkspaceFolder = CurrentWorkspaceFolder;
201 await _dialogCoordinator.ShowMetroDialogAsync(_shellVM, dialog);
202 MessageDialogResult dialogResult = await dialog.WaitForDialogButtonPressAsync();
203 await _dialogCoordinator.HideMetroDialogAsync(_shellVM, dialog);
204
205 if(dialogResult == MessageDialogResult.Affirmative)
206 {
207 if (_workspaceService?.IsWorkspaceOpen ?? false)
208 {
209 await _workspaceService?.CloseWorkspace(CancellationToken.None, save);
210 }
211
212 // Copy files from the old workspace
213 if (!string.IsNullOrEmpty(dialog.PreviousWorkspaceFolder) && dialog.CopyCompetitions)
214 {
215 copyFilesFromOldWorkspace(dialog.PreviousWorkspaceFolder, dialog.NewWorkspaceFolder, WorkspaceService.KEY_FILENAME_COMPETITIONS);
216 }
217 if (!string.IsNullOrEmpty(dialog.PreviousWorkspaceFolder) && dialog.CopyCompetitionDistanceRules)
218 {
219 copyFilesFromOldWorkspace(dialog.PreviousWorkspaceFolder, dialog.NewWorkspaceFolder, WorkspaceService.KEY_FILENAME_COMPETITIONDISTANCERULES);
220 }
221 if (!string.IsNullOrEmpty(dialog.PreviousWorkspaceFolder) && dialog.CopyTemplates)
222 {
223 copyTemplatesFolderFromOldWorkspace(dialog.PreviousWorkspaceFolder, dialog.NewWorkspaceFolder);
224 }
225
226 bool result = await _workspaceService?.Load(dialog.NewWorkspaceFolder, CancellationToken.None);
227 OnWorkspaceLoaded?.Invoke(this, dialog.NewWorkspaceFolder);
228 OnPropertyChanged(nameof(LastWorkspacePaths));
229
230 if (!result)
231 {
232 await _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, Resources.WorkspaceNotLoadedString);
233 return;
234 }
235
236 // Save the workspace to create the workspace files
237 await _workspaceService.Save(CancellationToken.None);
238
239 if (dialog.CopyDefaultTemplates)
240 {
241 // Extract the default templates from the ZIP file to the workspace folder (subfolder for the templates)
242 string templateZipPath = Path.Combine(Path.GetDirectoryName(Environment.ProcessPath), DEFAULT_TEMPLATE_ZIP_FILE_NAME);
243 string zipExtractPath = Path.Combine(_workspaceService.PersistentPath, WorkspaceSettings.DEFAULT_TEMPLATE_FOLDER_NAME);
244 if (File.Exists(templateZipPath))
245 {
246 if (Directory.Exists(zipExtractPath))
247 {
248 Directory.Delete(zipExtractPath, true);
249 }
250 ZipFile.ExtractToDirectory(templateZipPath, Path.Combine(_workspaceService.PersistentPath, WorkspaceSettings.DEFAULT_TEMPLATE_FOLDER_NAME));
251 }
252 }
253
254 // Open the workspace page
255 _navigationService.NavigateTo<WorkspaceViewModel>();
256 }
257 }
258 catch (Exception ex)
259 {
260 await _dialogCoordinator.ShowMessageAsync(_shellVM, Resources.ErrorString, ex.Message);
261 }
262 }
263 }));
264
265 // ----------------------------------------------------------------------------------------------------------------------------------------------
266
274 private void copyFilesFromOldWorkspace(string oldWorkspacePath, string newWorkspacePath, string fileNameResourceKey)
275 {
276 if (!Directory.Exists(oldWorkspacePath) || string.IsNullOrEmpty(newWorkspacePath) || oldWorkspacePath == newWorkspacePath) { return; }
277
278 ResourceManager fileNameResources = new ResourceManager(typeof(Core.Properties.Resources));
279
280 // Get all supported file names that are searched in the old workspace path and combine them to full pathes
281 List<string> localizedFileNames = GeneralLocalizationHelper.GetAllTranslationsForKey(fileNameResources, fileNameResourceKey).Values.ToList();
282 List<string> localizedFilePaths = localizedFileNames.Select(f => Path.Combine(oldWorkspacePath, f)).ToList();
283 foreach (string localizedFilePath in localizedFilePaths)
284 {
285 if (File.Exists(localizedFilePath))
286 {
287 string newFileName = fileNameResources.GetString(fileNameResourceKey);
288 // Copy the file to the new workspace
289 File.Copy(localizedFilePath, Path.Combine(newWorkspacePath, newFileName), true);
290 continue;
291 }
292 }
293 }
294
295 // ----------------------------------------------------------------------------------------------------------------------------------------------
296
302 private void copyTemplatesFolderFromOldWorkspace(string oldWorkspacePath, string newWorkspacePath)
303 {
304 if (!Directory.Exists(oldWorkspacePath) || string.IsNullOrEmpty(newWorkspacePath) || oldWorkspacePath == newWorkspacePath) { return; }
305
306 string oldTemplateFolder = Path.Combine(oldWorkspacePath, WorkspaceSettings.DEFAULT_TEMPLATE_FOLDER_NAME);
307 string newTemplateFolder = Path.Combine(newWorkspacePath, WorkspaceSettings.DEFAULT_TEMPLATE_FOLDER_NAME);
308
309 if(!Directory.Exists(oldTemplateFolder)) { return; }
310 if(Directory.Exists(newTemplateFolder))
311 {
312 Directory.Delete(newTemplateFolder, true);
313 }
314 Directory.CreateDirectory(newTemplateFolder);
315
316 // https://stackoverflow.com/questions/58744/copy-the-entire-contents-of-a-directory-in-c-sharp
317 // create all of the directories (if nested ones exist)
318 foreach (string dirPath in Directory.GetDirectories(oldTemplateFolder, "*", SearchOption.AllDirectories))
319 {
320 Directory.CreateDirectory(dirPath.Replace(oldTemplateFolder, newTemplateFolder));
321 }
322 //Copy all the files & Replaces any files with the same name
323 foreach (string newPath in Directory.GetFiles(oldTemplateFolder, "*.*", SearchOption.AllDirectories))
324 {
325 File.Copy(newPath, newPath.Replace(oldTemplateFolder, newTemplateFolder), true);
326 }
327 }
328
329 #endregion
330
331 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
332
333 private ICommand _clearAllLastWorkspacePathsCommand;
335 public ICommand ClearAllLastWorkspacePathsCommand => _clearAllLastWorkspacePathsCommand ?? (_clearAllLastWorkspacePathsCommand = new RelayCommand(() =>
336 {
337 _workspaceService?.ClearAllLastWorkspacePaths();
338 }));
339
340 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
341
342 #region Events
343
346
347 #endregion
348
349 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
350
351 private IWorkspaceService _workspaceService;
352 private IDialogCoordinator _dialogCoordinator;
353 private ShellViewModel _shellVM;
354 private INavigationService _navigationService;
355
363 public WorkspaceManagerViewModel(IWorkspaceService workspaceService, IDialogCoordinator dialogCoordinator, ShellViewModel shellVM, INavigationService navigationService)
364 {
365 _workspaceService = workspaceService;
366 _dialogCoordinator = dialogCoordinator;
367 _shellVM = shellVM;
368 _navigationService = navigationService;
369
370 _workspaceService.PropertyChanged -= _workspaceService_PropertyChanged;
371 _workspaceService.PropertyChanged += _workspaceService_PropertyChanged;
372 }
373
374 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
375
376 private void _workspaceService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
377 {
378 switch (e.PropertyName)
379 {
380 case nameof(IWorkspaceService.HasUnsavedChanges): OnPropertyChanged(nameof(HasUnsavedChanges)); break;
381 case nameof(IWorkspaceService.PersistentPath): OnPropertyChanged(nameof(CurrentWorkspaceFolder)); break;
382 case nameof(IWorkspaceService.LastWorkspacePaths): OnPropertyChanged(nameof(LastWorkspacePaths)); break;
384 {
385 OnPropertyChanged(nameof(CurrentWorkspaceFolder));
386 ((RelayCommand)LoadWorkspaceCommand).NotifyCanExecuteChanged();
387 ((RelayCommand)SaveWorkspaceCommand).NotifyCanExecuteChanged();
388 ((RelayCommand)CloseWorkspaceCommand).NotifyCanExecuteChanged();
389 ((RelayCommand)OpenWorkspaceFolderCommand).NotifyCanExecuteChanged();
390 break;
391 }
392 default: break;
393 }
394 }
395}
Interaktionslogik für NewWorkspaceSettingsDialog.xaml.
Task< MessageDialogResult > WaitForDialogButtonPressAsync()
Wait until the cancel or ok button is pressed.
Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
const string DEFAULT_TEMPLATE_FOLDER_NAME
Folder name where the document templates are located per default (e.g.
Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
static string WorkspaceNotLoadedString
Sucht eine lokalisierte Zeichenfolge, die The workspace couldn't be loaded.
static string ErrorString
Sucht eine lokalisierte Zeichenfolge, die Error ähnelt.
View model for the main view of the application.
ViewModel for the main shell of the application.
ObservableCollection< string > LastWorkspacePaths
List with previous workspace paths.
ICommand OpenWorkspaceFolderCommand
Command to open the current workspace folder in the file explorer.
ICommand LoadLastWorkspaceCommand
Command to load a previous workspace from the selected folder (command parameter).
WorkspaceManagerViewModel(IWorkspaceService workspaceService, IDialogCoordinator dialogCoordinator, ShellViewModel shellVM, INavigationService navigationService)
Constructor of the workspace view model.
const string DEFAULT_TEMPLATE_ZIP_FILE_NAME
This is the file name for the default templates ZIP (this name should match the name used in the Post...
void copyFilesFromOldWorkspace(string oldWorkspacePath, string newWorkspacePath, string fileNameResourceKey)
Copy the file identified by the fileNameResourceKey from the oldWorkspacePath to the newWorkspacePa...
ICommand CloseWorkspaceCommand
Command to close the current workspace.
IWorkspaceManagerViewModel.WorkspaceLoadedDelegate OnWorkspaceLoaded
ICommand SaveWorkspaceCommand
Command to save the current workspace to a folder.
ICommand LoadWorkspaceCommand
Command to load a workspace from a folder.
void copyTemplatesFolderFromOldWorkspace(string oldWorkspacePath, string newWorkspacePath)
Copy the templates folder from the oldWorkspacePath to the newWorkspacePath
ICommand CreateNewWorkspaceCommand
Command to create a new workspace (add all configuration files to the folder and optionally add defau...
bool HasUnsavedChanges
True if the workspace has unsaved changes, false otherwise.
ViewModel for the workspace, managing the current workspace folder, settings, and commands to load,...
Interface for a service for handling navigation within the application.
delegate void WorkspaceLoadedDelegate(WorkspaceManagerViewModel workspaceManagerViewModel, string currentWorkspacePath)
Delegate void for the OnWorkspaceLoaded event.
bool HasUnsavedChanges
Check if there are unsave changes.
Definition ISaveable.cs:44
Interface for a service used to manage a workspace.
bool IsWorkspaceOpen
If true, a workspace is loaded; if false, not workspace is loaded.
ObservableCollection< string > LastWorkspacePaths
List with previous workspace paths.