diff --git a/Filtration.Interface/IDocument.cs b/Filtration.Interface/IDocument.cs index e27b2ec..8f86095 100644 --- a/Filtration.Interface/IDocument.cs +++ b/Filtration.Interface/IDocument.cs @@ -1,9 +1,11 @@ -namespace Filtration.Interface +using System.Threading.Tasks; + +namespace Filtration.Interface { public interface IDocument { bool IsScript { get; } bool IsTheme { get; } - void Close(); + Task Close(); } } diff --git a/Filtration.Interface/IEditableDocument.cs b/Filtration.Interface/IEditableDocument.cs index 7102812..aebdd71 100644 --- a/Filtration.Interface/IEditableDocument.cs +++ b/Filtration.Interface/IEditableDocument.cs @@ -1,9 +1,11 @@ -namespace Filtration.Interface +using System.Threading.Tasks; + +namespace Filtration.Interface { public interface IEditableDocument : IDocument { bool IsDirty { get; } - void Save(); - void SaveAs(); + Task SaveAsync(); + Task SaveAsAsync(); } } diff --git a/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs b/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs index 8ac2d25..d17ec67 100644 --- a/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs +++ b/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs @@ -18,7 +18,7 @@ namespace Filtration.Tests.Repositories var mockPersistenceService = new Mock(); - mockPersistenceService.Setup(p => p.LoadItemFilterScript(testInputPath)).Verifiable(); + mockPersistenceService.Setup(p => p.LoadItemFilterScriptAsync(testInputPath)).Verifiable(); var mockItemFilterScriptViewModel = new Mock(); @@ -28,7 +28,7 @@ namespace Filtration.Tests.Repositories var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); // Act - var result = repository.LoadScriptFromFile(testInputPath); + var result = repository.LoadScriptFromFileAsync(testInputPath); // Assert mockPersistenceService.Verify(); @@ -42,7 +42,7 @@ namespace Filtration.Tests.Repositories var testInputPath = "C:\\TestPath.filter"; var mockPersistenceService = new Mock(); - mockPersistenceService.Setup(p => p.LoadItemFilterScript(testInputPath)).Throws(); + mockPersistenceService.Setup(p => p.LoadItemFilterScriptAsync(testInputPath)).Throws(); var mockItemFilterScriptViewModelFactory = new Mock(); @@ -51,7 +51,7 @@ namespace Filtration.Tests.Repositories // Act // Assert - Assert.Throws(() => repository.LoadScriptFromFile(testInputPath)); + Assert.Throws(() => repository.LoadScriptFromFileAsync(testInputPath)); } [Test] diff --git a/Filtration.Tests/Services/TestItemFilterPersistenceService.cs b/Filtration.Tests/Services/TestItemFilterPersistenceService.cs index 3d8c9e1..c665004 100644 --- a/Filtration.Tests/Services/TestItemFilterPersistenceService.cs +++ b/Filtration.Tests/Services/TestItemFilterPersistenceService.cs @@ -28,7 +28,7 @@ namespace Filtration.Tests.Services var service = new ItemFilterPersistenceService(mockFileSystemService.Object, mockItemFilterScriptTranslator.Object); // Act - var script = service.LoadItemFilterScript(TestInputPath); + var script = service.LoadItemFilterScriptAsync(TestInputPath); // Assert mockFileSystemService.Verify(); @@ -53,7 +53,7 @@ namespace Filtration.Tests.Services var service = new ItemFilterPersistenceService(mockFileSystemService.Object, mockItemFilterScriptTranslator.Object); // Act - service.SaveItemFilterScript(testScript); + service.SaveItemFilterScriptAsync(testScript); // Assert mockFileSystemService.Verify(); diff --git a/Filtration.ThemeEditor/Providers/ThemeProvider.cs b/Filtration.ThemeEditor/Providers/ThemeProvider.cs index 0a0afde..4600200 100644 --- a/Filtration.ThemeEditor/Providers/ThemeProvider.cs +++ b/Filtration.ThemeEditor/Providers/ThemeProvider.cs @@ -1,6 +1,7 @@ using System.Collections.ObjectModel; using System.IO; using System.Linq; +using System.Threading.Tasks; using AutoMapper; using Filtration.ObjectModel; using Filtration.ObjectModel.ThemeEditor; @@ -13,9 +14,9 @@ namespace Filtration.ThemeEditor.Providers { IThemeEditorViewModel NewThemeForScript(ItemFilterScript script); IThemeEditorViewModel MasterThemeForScript(ItemFilterScript script); - IThemeEditorViewModel LoadThemeFromFile(string filePath); - Theme LoadThemeModelFromFile(string filePath); - void SaveTheme(IThemeEditorViewModel themeEditorViewModel, string filePath); + Task LoadThemeFromFile(string filePath); + Task LoadThemeModelFromFile(string filePath); + Task SaveThemeAsync(IThemeEditorViewModel themeEditorViewModel, string filePath); } internal class ThemeProvider : IThemeProvider @@ -54,23 +55,26 @@ namespace Filtration.ThemeEditor.Providers return themeViewModel; } - public IThemeEditorViewModel LoadThemeFromFile(string filePath) + public async Task LoadThemeFromFile(string filePath) { - var model = _themePersistenceService.LoadTheme(filePath); + var model = await _themePersistenceService.LoadThemeAsync(filePath); var viewModel = Mapper.Map(model); viewModel.FilePath = filePath; return viewModel; } - public Theme LoadThemeModelFromFile(string filePath) + public async Task LoadThemeModelFromFile(string filePath) { - return _themePersistenceService.LoadTheme(filePath); + return await _themePersistenceService.LoadThemeAsync(filePath); } - public void SaveTheme(IThemeEditorViewModel themeEditorViewModel, string filePath) + public async Task SaveThemeAsync(IThemeEditorViewModel themeEditorViewModel, string filePath) { - var theme = Mapper.Map(themeEditorViewModel); - _themePersistenceService.SaveTheme(theme, filePath); + await Task.Run(() => + { + var theme = Mapper.Map(themeEditorViewModel); + _themePersistenceService.SaveThemeAsync(theme, filePath); + }); } } } diff --git a/Filtration.ThemeEditor/Services/ThemePersistenceService.cs b/Filtration.ThemeEditor/Services/ThemePersistenceService.cs index a2543de..d0a6ce0 100644 --- a/Filtration.ThemeEditor/Services/ThemePersistenceService.cs +++ b/Filtration.ThemeEditor/Services/ThemePersistenceService.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Threading.Tasks; using System.Xml.Serialization; using Filtration.ObjectModel.ThemeEditor; @@ -6,35 +7,42 @@ namespace Filtration.ThemeEditor.Services { internal interface IThemePersistenceService { - Theme LoadTheme(string filePath); - void SaveTheme(Theme theme, string filePath); + Task LoadThemeAsync(string filePath); + Task SaveThemeAsync(Theme theme, string filePath); } internal class ThemePersistenceService : IThemePersistenceService { - public Theme LoadTheme(string filePath) + public async Task LoadThemeAsync(string filePath) { - var xmlSerializer = new XmlSerializer(typeof(Theme)); + Theme loadedTheme = null; - Theme loadedTheme; - - using (Stream reader = new FileStream(filePath, FileMode.Open)) + await Task.Run(() => { - loadedTheme = (Theme)xmlSerializer.Deserialize(reader); - } - - loadedTheme.FilePath = filePath; + var xmlSerializer = new XmlSerializer(typeof (Theme)); + + using (Stream reader = new FileStream(filePath, FileMode.Open)) + { + loadedTheme = (Theme) xmlSerializer.Deserialize(reader); + } + + loadedTheme.FilePath = filePath; + }); + return loadedTheme; } - public void SaveTheme(Theme theme, string filePath) + public async Task SaveThemeAsync(Theme theme, string filePath) { - var xmlSerializer = new XmlSerializer(typeof(Theme)); - - using (Stream writer = new FileStream(filePath, FileMode.Create)) + await Task.Run(() => { - xmlSerializer.Serialize(writer, theme); - } + var xmlSerializer = new XmlSerializer(typeof (Theme)); + + using (Stream writer = new FileStream(filePath, FileMode.Create)) + { + xmlSerializer.Serialize(writer, theme); + } + }); } } } diff --git a/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs b/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs index aab12ce..c5115a6 100644 --- a/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs +++ b/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; using System.Windows.Media; @@ -55,7 +56,7 @@ namespace Filtration.ThemeEditor.ViewModels AddThemeComponentCommand = new RelayCommand(OnAddThemeComponentCommand, t => IsMasterTheme); DeleteThemeComponentCommand = new RelayCommand(OnDeleteThemeComponentCommand, t => IsMasterTheme && SelectedThemeComponent != null); - CloseCommand = new RelayCommand(OnCloseCommand); + CloseCommand = new RelayCommand(async () => await OnCloseCommand()); var icon = new BitmapImage(); icon.BeginInit(); @@ -123,19 +124,19 @@ namespace Filtration.ThemeEditor.ViewModels } } - public void Save() + public async Task SaveAsync() { if (IsMasterTheme) return; if (_filenameIsFake) { - SaveAs(); + await SaveAsAsync(); return; } try { - _themeProvider.SaveTheme(this, FilePath); + await _themeProvider.SaveThemeAsync(this, FilePath); //RemoveDirtyFlag(); } catch (Exception e) @@ -149,7 +150,7 @@ namespace Filtration.ThemeEditor.ViewModels } } - public void SaveAs() + public async Task SaveAsAsync() { if (IsMasterTheme) return; @@ -167,7 +168,7 @@ namespace Filtration.ThemeEditor.ViewModels try { FilePath = saveDialog.FileName; - _themeProvider.SaveTheme(this, FilePath); + await _themeProvider.SaveThemeAsync(this, FilePath); _filenameIsFake = false; Title = Filename; //RemoveDirtyFlag(); @@ -185,14 +186,16 @@ namespace Filtration.ThemeEditor.ViewModels } } - public void OnCloseCommand() + public async Task OnCloseCommand() { - Close(); + await Close(); } - public void Close() +#pragma warning disable 1998 + public async Task Close() +#pragma warning restore 1998 { - Messenger.Default.Send(new ThemeClosedMessage { ClosedViewModel = this }); + Messenger.Default.Send(new ThemeClosedMessage {ClosedViewModel = this}); } private void OnAddThemeComponentCommand(ThemeComponentType themeComponentType) diff --git a/Filtration/App.xaml.cs b/Filtration/App.xaml.cs index 4be2f28..87ea227 100644 --- a/Filtration/App.xaml.cs +++ b/Filtration/App.xaml.cs @@ -17,7 +17,7 @@ using NLog; namespace Filtration { - public partial class App : Application + public partial class App { private IWindsorContainer _container; private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); diff --git a/Filtration/Filtration.csproj b/Filtration/Filtration.csproj index 998baa6..428357b 100644 --- a/Filtration/Filtration.csproj +++ b/Filtration/Filtration.csproj @@ -94,6 +94,10 @@ + + ..\packages\WpfAnimatedGif.1.4.13\lib\net\WpfAnimatedGif.dll + True + False ..\packages\WPFToolkit.3.5.50211.1\lib\WPFToolkit.dll @@ -365,6 +369,7 @@ Settings.settings True + ResXFileCodeGenerator Resources.Designer.cs diff --git a/Filtration/Repositories/ItemFilterScriptRepository.cs b/Filtration/Repositories/ItemFilterScriptRepository.cs index cc0c0c5..e119daa 100644 --- a/Filtration/Repositories/ItemFilterScriptRepository.cs +++ b/Filtration/Repositories/ItemFilterScriptRepository.cs @@ -1,4 +1,5 @@ -using Filtration.ObjectModel; +using System.Threading.Tasks; +using Filtration.ObjectModel; using Filtration.Services; using Filtration.ViewModels; @@ -6,7 +7,7 @@ namespace Filtration.Repositories { internal interface IItemFilterScriptRepository { - IItemFilterScriptViewModel LoadScriptFromFile(string path); + Task LoadScriptFromFileAsync(string path); IItemFilterScriptViewModel NewScript(); string GetItemFilterScriptDirectory(); void SetItemFilterScriptDirectory(string path); @@ -24,9 +25,9 @@ namespace Filtration.Repositories _itemFilterScriptViewModelFactory = itemFilterScriptViewModelFactory; } - public IItemFilterScriptViewModel LoadScriptFromFile(string path) + public async Task LoadScriptFromFileAsync(string path) { - var loadedScript = _itemFilterPersistenceService.LoadItemFilterScript(path); + var loadedScript = await _itemFilterPersistenceService.LoadItemFilterScriptAsync(path); var newViewModel = _itemFilterScriptViewModelFactory.Create(); newViewModel.Initialise(loadedScript, false); diff --git a/Filtration/Resources/loading_spinner.gif b/Filtration/Resources/loading_spinner.gif new file mode 100644 index 0000000..dfaad2a Binary files /dev/null and b/Filtration/Resources/loading_spinner.gif differ diff --git a/Filtration/Services/ItemFilterPersistenceService.cs b/Filtration/Services/ItemFilterPersistenceService.cs index c42b0af..21ef655 100644 --- a/Filtration/Services/ItemFilterPersistenceService.cs +++ b/Filtration/Services/ItemFilterPersistenceService.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Threading.Tasks; using Filtration.Common.Services; using Filtration.ObjectModel; using Filtration.Properties; @@ -10,8 +11,8 @@ namespace Filtration.Services { void SetItemFilterScriptDirectory(string path); string ItemFilterScriptDirectory { get; } - ItemFilterScript LoadItemFilterScript(string filePath); - void SaveItemFilterScript(ItemFilterScript script); + Task LoadItemFilterScriptAsync(string filePath); + Task SaveItemFilterScriptAsync(ItemFilterScript script); string DefaultPathOfExileDirectory(); } @@ -58,20 +59,30 @@ namespace Filtration.Services Settings.Default.DefaultFilterDirectory = path; } - public ItemFilterScript LoadItemFilterScript(string filePath) + public async Task LoadItemFilterScriptAsync(string filePath) { - var script = - _itemFilterScriptTranslator.TranslateStringToItemFilterScript( + ItemFilterScript loadedScript = null; + await Task.Run(() => + { + loadedScript = _itemFilterScriptTranslator.TranslateStringToItemFilterScript( _fileSystemService.ReadFileAsString(filePath)); + }); - script.FilePath = filePath; - return script; + if (loadedScript != null) + { + loadedScript.FilePath = filePath; + } + + return loadedScript; } - public void SaveItemFilterScript(ItemFilterScript script) + public async Task SaveItemFilterScriptAsync(ItemFilterScript script) { - _fileSystemService.WriteFileFromString(script.FilePath, - _itemFilterScriptTranslator.TranslateItemFilterScriptToString(script)); + await Task.Run(() => + { + _fileSystemService.WriteFileFromString(script.FilePath, + _itemFilterScriptTranslator.TranslateItemFilterScriptToString(script)); + }); } } } diff --git a/Filtration/Services/UpdateCheckService.cs b/Filtration/Services/UpdateCheckService.cs index 8f01cda..cb0c0ed 100644 --- a/Filtration/Services/UpdateCheckService.cs +++ b/Filtration/Services/UpdateCheckService.cs @@ -7,7 +7,7 @@ namespace Filtration.Services { internal interface IUpdateCheckService { - Task GetUpdateData(); + Task GetUpdateDataAsync(); } internal class UpdateCheckService : IUpdateCheckService @@ -20,7 +20,7 @@ namespace Filtration.Services _httpService = httpService; } - public async Task GetUpdateData() + public async Task GetUpdateDataAsync() { var updateXml = await _httpService.GetContentAsync(UpdateDataUrl); return (DeserializeUpdateData(updateXml)); diff --git a/Filtration/ViewModels/AvalonDockWorkspaceViewModel.cs b/Filtration/ViewModels/AvalonDockWorkspaceViewModel.cs index 7d73e95..ee87215 100644 --- a/Filtration/ViewModels/AvalonDockWorkspaceViewModel.cs +++ b/Filtration/ViewModels/AvalonDockWorkspaceViewModel.cs @@ -39,9 +39,9 @@ namespace Filtration.ViewModels private readonly ReadOnlyObservableCollection _readOnlyOpenDocuments; public AvalonDockWorkspaceViewModel(ISectionBrowserViewModel sectionBrowserViewModel, - IBlockGroupBrowserViewModel blockGroupBrowserViewModel, - IStartPageViewModel startPageViewModel, - IBlockOutputPreviewViewModel blockOutputPreviewViewModel) + IBlockGroupBrowserViewModel blockGroupBrowserViewModel, + IStartPageViewModel startPageViewModel, + IBlockOutputPreviewViewModel blockOutputPreviewViewModel) { _sectionBrowserViewModel = sectionBrowserViewModel; _blockGroupBrowserViewModel = blockGroupBrowserViewModel; @@ -122,7 +122,6 @@ namespace Filtration.ViewModels } private List _tools; - public IEnumerable Tools { diff --git a/Filtration/ViewModels/ItemFilterScriptViewModel.cs b/Filtration/ViewModels/ItemFilterScriptViewModel.cs index 54c1711..92000b2 100644 --- a/Filtration/ViewModels/ItemFilterScriptViewModel.cs +++ b/Filtration/ViewModels/ItemFilterScriptViewModel.cs @@ -4,6 +4,7 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Linq; +using System.Threading.Tasks; using System.Windows; using System.Windows.Data; using System.Windows.Forms; @@ -104,7 +105,7 @@ namespace Filtration.ViewModels ToggleShowAdvancedCommand = new RelayCommand(OnToggleShowAdvancedCommand); ClearFilterCommand = new RelayCommand(OnClearFilterCommand, () => BlockFilterPredicate != null); - CloseCommand = new RelayCommand(OnCloseCommand); + CloseCommand = new RelayCommand(async () => await OnCloseCommand()); DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => SelectedBlockViewModel != null); MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => SelectedBlockViewModel != null); MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => SelectedBlockViewModel != null); @@ -351,20 +352,21 @@ namespace Filtration.ViewModels ContentId = "ScriptContentId"; } - public void Save() + public async Task SaveAsync() { if (!ValidateScript()) return; if (!CheckForUnusedThemeComponents()) return; if (_filenameIsFake) { - SaveAs(); + await SaveAsAsync(); return; } + Messenger.Default.Send(new NotificationMessage("ShowLoadingBanner")); try { - _persistenceService.SaveItemFilterScript(Script); + await _persistenceService.SaveItemFilterScriptAsync(Script); RemoveDirtyFlag(); } catch (Exception e) @@ -377,9 +379,15 @@ namespace Filtration.ViewModels _messageBoxService.Show("Save Error", "Error saving filter file - " + e.Message, MessageBoxButton.OK, MessageBoxImage.Error); } + finally + { + Messenger.Default.Send(new NotificationMessage("HideLoadingBanner")); + } + + return; } - public void SaveAs() + public async Task SaveAsAsync() { if (!ValidateScript()) return; if (!CheckForUnusedThemeComponents()) return; @@ -394,12 +402,14 @@ namespace Filtration.ViewModels var result = saveDialog.ShowDialog(); if (result != DialogResult.OK) return; + + Messenger.Default.Send(new NotificationMessage("ShowLoadingBanner")); var previousFilePath = Script.FilePath; try { Script.FilePath = saveDialog.FileName; - _persistenceService.SaveItemFilterScript(Script); + await _persistenceService.SaveItemFilterScriptAsync(Script); _filenameIsFake = false; Title = Filename; RemoveDirtyFlag(); @@ -415,6 +425,10 @@ namespace Filtration.ViewModels MessageBoxImage.Error); Script.FilePath = previousFilePath; } + finally + { + Messenger.Default.Send(new NotificationMessage("HideLoadingBanner")); + } } private bool CheckForUnusedThemeComponents() @@ -480,12 +494,12 @@ namespace Filtration.ViewModels return false; } - private void OnCloseCommand() + private async Task OnCloseCommand() { - Close(); + await Close(); } - public void Close() + public async Task Close() { if (!IsDirty) { @@ -499,20 +513,20 @@ namespace Filtration.ViewModels switch (result) { case MessageBoxResult.Yes: - { - Save(); - CloseScript(); - break; - } + { + await SaveAsync(); + CloseScript(); + break; + } case MessageBoxResult.No: - { - CloseScript(); - break; - } + { + CloseScript(); + break; + } case MessageBoxResult.Cancel: - { - return; - } + { + return; + } } } } @@ -777,6 +791,7 @@ namespace Filtration.ViewModels IsDirty = true; SelectedBlockViewModel = vm; RaisePropertyChanged("ItemFilterSectionViewModels"); + Messenger.Default.Send(new NotificationMessage("SectionsChanged")); } private void OnExpandAllBlocksCommand() @@ -808,9 +823,17 @@ namespace Filtration.ViewModels if (result == MessageBoxResult.Yes) { + var isSection = targetBlockViewModel.Block is ItemFilterSection; + Script.ItemFilterBlocks.Remove(targetBlockViewModel.Block); ItemFilterBlockViewModels.Remove(targetBlockViewModel); IsDirty = true; + + if (isSection) + { + Messenger.Default.Send(new NotificationMessage("SectionsChanged")); + } + } SelectedBlockViewModel = null; } diff --git a/Filtration/ViewModels/MainWindowViewModel.cs b/Filtration/ViewModels/MainWindowViewModel.cs index b2f7648..83ee8a3 100644 --- a/Filtration/ViewModels/MainWindowViewModel.cs +++ b/Filtration/ViewModels/MainWindowViewModel.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; using System.Windows.Media; @@ -34,7 +35,7 @@ namespace Filtration.ViewModels { RelayCommand OpenScriptCommand { get; } RelayCommand NewScriptCommand { get; } - bool CloseAllDocuments(); + Task CloseAllDocuments(); } internal class MainWindowViewModel : FiltrationViewModelBase, IMainWindowViewModel @@ -51,6 +52,7 @@ namespace Filtration.ViewModels private readonly IUpdateCheckService _updateCheckService; private readonly IUpdateAvailableViewModel _updateAvailableViewModel; private readonly IMessageBoxService _messageBoxService; + private bool _showLoadingBanner; public MainWindowViewModel(IItemFilterScriptRepository itemFilterScriptRepository, IItemFilterScriptTranslator itemFilterScriptTranslator, @@ -76,11 +78,11 @@ namespace Filtration.ViewModels NewScriptCommand = new RelayCommand(OnNewScriptCommand); CopyScriptCommand = new RelayCommand(OnCopyScriptCommand, () => ActiveDocumentIsScript); - OpenScriptCommand = new RelayCommand(OnOpenScriptCommand); - OpenThemeCommand = new RelayCommand(OnOpenThemeCommand); + OpenScriptCommand = new RelayCommand(async () => await OnOpenScriptCommand()); + OpenThemeCommand = new RelayCommand(async () => await OnOpenThemeCommand()); - SaveCommand = new RelayCommand(OnSaveDocumentCommand, ActiveDocumentIsEditable); - SaveAsCommand = new RelayCommand(OnSaveAsCommand, ActiveDocumentIsEditable); + SaveCommand = new RelayCommand(async () => await OnSaveDocumentCommand(), ActiveDocumentIsEditable); + SaveAsCommand = new RelayCommand(async () => await OnSaveAsCommand(), ActiveDocumentIsEditable); CloseCommand = new RelayCommand(OnCloseDocumentCommand, ActiveDocumentIsEditable); CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); @@ -104,7 +106,7 @@ namespace Filtration.ViewModels ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, () => ActiveDocumentIsScript); CreateThemeCommand = new RelayCommand(OnCreateThemeCommand, () => ActiveDocumentIsScript); - ApplyThemeToScriptCommand = new RelayCommand(OnApplyThemeToScriptCommand, () => ActiveDocumentIsScript); + ApplyThemeToScriptCommand = new RelayCommand(async () => await OnApplyThemeToScriptCommand(), () => ActiveDocumentIsScript); EditMasterThemeCommand = new RelayCommand(OnEditMasterThemeCommand, () => ActiveDocumentIsScript); AddTextColorThemeComponentCommand = new RelayCommand(OnAddTextColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); @@ -166,7 +168,19 @@ namespace Filtration.ViewModels } case "OpenScript": { +#pragma warning disable 4014 OnOpenScriptCommand(); +#pragma warning restore 4014 + break; + } + case "ShowLoadingBanner": + { + ShowLoadingBanner = true; + break; + } + case "HideLoadingBanner": + { + ShowLoadingBanner = false; break; } } @@ -221,7 +235,7 @@ namespace Filtration.ViewModels try { - var result = await _updateCheckService.GetUpdateData(); + var result = await _updateCheckService.GetUpdateDataAsync(); if (result.LatestVersionMajorPart >= assemblyVersion.FileMajorPart && result.LatestVersionMinorPart > assemblyVersion.FileMinorPart) @@ -279,6 +293,16 @@ namespace Filtration.ViewModels } } + public bool ShowLoadingBanner + { + get { return _showLoadingBanner; } + private set + { + _showLoadingBanner = value; + RaisePropertyChanged(); + } + } + public bool ActiveDocumentIsScript { get { return _avalonDockWorkspaceViewModel.ActiveDocument != null && _avalonDockWorkspaceViewModel.ActiveDocument.IsScript; } @@ -362,7 +386,8 @@ namespace Filtration.ViewModels var aboutWindow = new AboutWindow(); aboutWindow.ShowDialog(); } - private void OnOpenScriptCommand() + + private async Task OnOpenScriptCommand() { var openFileDialog = new OpenFileDialog { @@ -374,12 +399,14 @@ namespace Filtration.ViewModels IItemFilterScriptViewModel loadedViewModel; + Messenger.Default.Send(new NotificationMessage("ShowLoadingBanner")); try { - loadedViewModel = _itemFilterScriptRepository.LoadScriptFromFile(openFileDialog.FileName); + loadedViewModel = await _itemFilterScriptRepository.LoadScriptFromFileAsync(openFileDialog.FileName); } catch(IOException e) { + Messenger.Default.Send(new NotificationMessage("HideLoadingBanner")); if (_logger.IsErrorEnabled) { _logger.Error(e); @@ -390,10 +417,11 @@ namespace Filtration.ViewModels return; } + Messenger.Default.Send(new NotificationMessage("HideLoadingBanner")); _avalonDockWorkspaceViewModel.AddDocument(loadedViewModel); } - private void OnOpenThemeCommand() + private async Task OnOpenThemeCommand() { var filePath = ShowOpenThemeDialog(); @@ -406,7 +434,7 @@ namespace Filtration.ViewModels try { - loadedViewModel = _themeProvider.LoadThemeFromFile(filePath); + loadedViewModel = await _themeProvider.LoadThemeFromFile(filePath); } catch (IOException e) { @@ -423,7 +451,7 @@ namespace Filtration.ViewModels _avalonDockWorkspaceViewModel.AddDocument(loadedViewModel); } - private void OnApplyThemeToScriptCommand() + private async Task OnApplyThemeToScriptCommand() { var filePath = ShowOpenThemeDialog(); if (string.IsNullOrEmpty(filePath)) @@ -435,7 +463,7 @@ namespace Filtration.ViewModels try { - loadedTheme = _themeProvider.LoadThemeModelFromFile(filePath); + loadedTheme = await _themeProvider.LoadThemeModelFromFile(filePath); } catch (IOException e) { @@ -490,14 +518,14 @@ namespace Filtration.ViewModels } } - private void OnSaveDocumentCommand() + private async Task OnSaveDocumentCommand() { - ((IEditableDocument)_avalonDockWorkspaceViewModel.ActiveDocument).Save(); + await ((IEditableDocument)_avalonDockWorkspaceViewModel.ActiveDocument).SaveAsync(); } - private void OnSaveAsCommand() + private async Task OnSaveAsCommand() { - ((IEditableDocument)_avalonDockWorkspaceViewModel.ActiveDocument).SaveAs(); + await ((IEditableDocument)_avalonDockWorkspaceViewModel.ActiveDocument).SaveAsAsync(); } private void OnReplaceColorsCommand() @@ -629,14 +657,14 @@ namespace Filtration.ViewModels _avalonDockWorkspaceViewModel.ActiveThemeViewModel.SelectedThemeComponent); } - public bool CloseAllDocuments() + public async Task CloseAllDocuments() { var openDocuments = _avalonDockWorkspaceViewModel.OpenDocuments.OfType().ToList(); foreach (var document in openDocuments) { var docCount = _avalonDockWorkspaceViewModel.OpenDocuments.OfType().Count(); - document.Close(); + await document.Close(); if (_avalonDockWorkspaceViewModel.OpenDocuments.OfType().Count() == docCount) { return false; diff --git a/Filtration/ViewModels/StartPageViewModel.cs b/Filtration/ViewModels/StartPageViewModel.cs index b5d97df..e66e2fd 100644 --- a/Filtration/ViewModels/StartPageViewModel.cs +++ b/Filtration/ViewModels/StartPageViewModel.cs @@ -1,4 +1,5 @@ -using Filtration.Common.ViewModels; +using System.Threading.Tasks; +using Filtration.Common.ViewModels; using Filtration.Interface; using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.Messaging; @@ -25,7 +26,7 @@ namespace Filtration.ViewModels public bool IsScript { get { return false; } } public bool IsTheme { get { return false; } } - public void Close() + public Task Close() { throw new System.NotImplementedException(); } diff --git a/Filtration/ViewModels/ToolPanes/SectionBrowserViewModel.cs b/Filtration/ViewModels/ToolPanes/SectionBrowserViewModel.cs index 894dc5b..c411a3f 100644 --- a/Filtration/ViewModels/ToolPanes/SectionBrowserViewModel.cs +++ b/Filtration/ViewModels/ToolPanes/SectionBrowserViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Windows.Media.Imaging; +using GalaSoft.MvvmLight.Messaging; namespace Filtration.ViewModels.ToolPanes { @@ -23,6 +24,18 @@ namespace Filtration.ViewModels.ToolPanes icon.UriSource = new Uri("pack://application:,,,/Filtration;component/Resources/Icons/add_section_icon.png"); icon.EndInit(); IconSource = icon; + + Messenger.Default.Register(this, message => + { + switch (message.Notification) + { + case "SectionsChanged": + { + OnActiveDocumentChanged(this, EventArgs.Empty); + break; + } + } + }); } public const string ToolContentId = "SectionBrowserTool"; diff --git a/Filtration/Views/AvalonDock/AvalonDockWorkspaceView.xaml b/Filtration/Views/AvalonDock/AvalonDockWorkspaceView.xaml index 932a7a1..6f78e2c 100644 --- a/Filtration/Views/AvalonDock/AvalonDockWorkspaceView.xaml +++ b/Filtration/Views/AvalonDock/AvalonDockWorkspaceView.xaml @@ -10,9 +10,10 @@ xmlns:converters="clr-namespace:Filtration.Converters" xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock" xmlns:themeEditorViews="clr-namespace:Filtration.ThemeEditor.Views;assembly=Filtration.ThemeEditor" + xmlns:gif="http://wpfanimatedgif.codeplex.com" mc:Ignorable="d" d:DataContext="{d:DesignInstance d:Type=viewModels:AvalonDockWorkspaceViewModel}" - d:DesignHeight="300" d:DesignWidth="300"> + d:DesignHeight="300" d:DesignWidth="700"> diff --git a/Filtration/Views/MainWindow.xaml b/Filtration/Views/MainWindow.xaml index fbbb3f7..43b3e2d 100644 --- a/Filtration/Views/MainWindow.xaml +++ b/Filtration/Views/MainWindow.xaml @@ -8,6 +8,7 @@ xmlns:viewModels="clr-namespace:Filtration.ViewModels" xmlns:viewsAvalonDock="clr-namespace:Filtration.Views.AvalonDock" xmlns:views="clr-namespace:Filtration.Views" + xmlns:gif="http://wpfanimatedgif.codeplex.com" mc:Ignorable="d" d:DataContext="{d:DesignInstance Type=viewModels:MainWindowViewModel}" Title="{Binding WindowTitle}" Height="762" Width="1126" IsIconVisible="True" @@ -18,7 +19,7 @@ - + @@ -118,6 +119,30 @@ + + + + + + + + + + + + + + + + + + + Working... + + + + + diff --git a/Filtration/Views/MainWindow.xaml.cs b/Filtration/Views/MainWindow.xaml.cs index 0109b31..414ab6b 100644 --- a/Filtration/Views/MainWindow.xaml.cs +++ b/Filtration/Views/MainWindow.xaml.cs @@ -1,7 +1,6 @@ -using System; -using System.ComponentModel; +using System.ComponentModel; +using System.Threading.Tasks; using System.Windows; -using Filtration.Annotations; using Filtration.ViewModels; namespace Filtration.Views @@ -13,7 +12,7 @@ namespace Filtration.Views internal partial class MainWindow : IMainWindow { - private IMainWindowViewModel _mainWindowViewModel; + private readonly IMainWindowViewModel _mainWindowViewModel; public MainWindow(IMainWindowViewModel mainWindowViewModel) { @@ -40,11 +39,11 @@ namespace Filtration.Views private void MainWindow_OnClosing(object sender, CancelEventArgs e) { - var allDocumentsClosed = _mainWindowViewModel.CloseAllDocuments(); - + var allDocumentsClosed = _mainWindowViewModel.CloseAllDocuments().Result; if (!allDocumentsClosed) { e.Cancel = true; + } } } diff --git a/Filtration/packages.config b/Filtration/packages.config index 38a0c67..d897cf0 100644 --- a/Filtration/packages.config +++ b/Filtration/packages.config @@ -11,5 +11,6 @@ + \ No newline at end of file