Refactored AvalonDock workspace into separate ViewModel

This commit is contained in:
Ben
2015-06-11 20:33:45 +01:00
parent f4eaba016f
commit 6d9edbda98
20 changed files with 456 additions and 436 deletions

View File

@@ -1,86 +1,83 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;
using Castle.Core;
using Filtration.Models;
using Filtration.Services;
using Filtration.Translators;
using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using Clipboard = System.Windows.Clipboard;
using MessageBox = System.Windows.Forms.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
namespace Filtration.ViewModels
{
internal interface IMainWindowViewModel
{
IDocument ActiveDocument { get; set; }
IItemFilterScriptViewModel ActiveScriptViewModel { get; }
event EventHandler ActiveDocumentChanged;
void LoadScriptFromFile(string path);
RelayCommand OpenScriptCommand { get; }
RelayCommand NewScriptCommand { get; }
void Close(IDocument scriptToClose);
}
internal class MainWindowViewModel : FiltrationViewModelBase, IMainWindowViewModel
{
private ItemFilterScript _loadedScript;
private readonly IItemFilterScriptViewModelFactory _itemFilterScriptViewModelFactory;
private readonly IItemFilterPersistenceService _persistenceService;
private readonly IItemFilterScriptTranslator _itemFilterScriptTranslator;
private readonly IReplaceColorsViewModel _replaceColorsViewModel;
private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel;
private IDocument _activeDocument;
private IItemFilterScriptViewModel _activeScriptViewModel;
private readonly ObservableCollection<IDocument> _openDocuments;
private readonly ISectionBrowserViewModel _sectionBrowserViewModel;
private readonly IBlockGroupBrowserViewModel _blockGroupBrowserViewModel;
private readonly IStartPageViewModel _startPageViewModel;
public MainWindowViewModel(IItemFilterScriptViewModelFactory itemFilterScriptViewModelFactory,
IItemFilterPersistenceService persistenceService,
IItemFilterScriptTranslator itemFilterScriptTranslator,
IReplaceColorsViewModel replaceColorsViewModel,
ISectionBrowserViewModel sectionBrowserViewModel,
IBlockGroupBrowserViewModel blockGroupBrowserViewModel,
IStartPageViewModel startPageViewModel)
IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel)
{
_itemFilterScriptViewModelFactory = itemFilterScriptViewModelFactory;
_persistenceService = persistenceService;
_itemFilterScriptTranslator = itemFilterScriptTranslator;
_replaceColorsViewModel = replaceColorsViewModel;
_sectionBrowserViewModel = sectionBrowserViewModel;
_blockGroupBrowserViewModel = blockGroupBrowserViewModel;
_startPageViewModel = startPageViewModel;
_avalonDockWorkspaceViewModel = avalonDockWorkspaceViewModel;
_sectionBrowserViewModel.Initialise(this);
_blockGroupBrowserViewModel.Initialise(this);
_startPageViewModel.Initialise(this);
_openDocuments = new ObservableCollection<IDocument>();
OpenAboutWindowCommand = new RelayCommand(OnOpenAboutWindowCommand);
OpenScriptCommand = new RelayCommand(OnOpenScriptCommand);
SaveScriptCommand = new RelayCommand(OnSaveScriptCommand, () => ActiveDocument != null && ActiveDocument.IsScript);
SaveScriptAsCommand = new RelayCommand(OnSaveScriptAsCommand, () => ActiveDocument != null && ActiveDocument.IsScript);
CopyScriptCommand = new RelayCommand(OnCopyScriptCommand, () => ActiveDocument != null && ActiveDocument.IsScript);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => ActiveDocument != null && ActiveDocument.IsScript && ((IItemFilterScriptViewModel)ActiveDocument).SelectedBlockViewModel != null);
PasteCommand = new RelayCommand(OnPasteCommand, () => ActiveDocument != null && ActiveDocument.IsScript && ((IItemFilterScriptViewModel)ActiveDocument).SelectedBlockViewModel != null);
SaveScriptCommand = new RelayCommand(OnSaveScriptCommand, ActiveDocumentIsScript);
SaveScriptAsCommand = new RelayCommand(OnSaveScriptAsCommand, ActiveDocumentIsScript);
CopyScriptCommand = new RelayCommand(OnCopyScriptCommand, ActiveDocumentIsScript);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => ActiveDocumentIsScript() && (_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel != null));
PasteCommand = new RelayCommand(OnPasteCommand, () => ActiveDocumentIsScript() && (_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel != null));
NewScriptCommand = new RelayCommand(OnNewScriptCommand);
CloseScriptCommand = new RelayCommand<IDocument>(OnCloseScriptCommand, v => ActiveDocument != null && ActiveDocument.IsScript);
ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, () => ActiveDocument != null && ActiveDocument.IsScript);
CloseScriptCommand = new RelayCommand(OnCloseScriptCommand, ActiveDocumentIsScript);
ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, ActiveDocumentIsScript);
//LoadScriptFromFile("C:\\ThioleLootFilter.txt");
SetItemFilterScriptDirectory();
_openDocuments.Add(_startPageViewModel);
ActiveDocument = startPageViewModel;
Messenger.Default.Register<NotificationMessage>(this, message =>
{
switch (message.Notification)
{
case "ActiveDocumentChanged":
{
_activeDocument = _avalonDockWorkspaceViewModel.ActiveDocument;
SaveScriptCommand.RaiseCanExecuteChanged();
SaveScriptAsCommand.RaiseCanExecuteChanged();
CopyScriptCommand.RaiseCanExecuteChanged();
CopyBlockCommand.RaiseCanExecuteChanged();
PasteCommand.RaiseCanExecuteChanged();
NewScriptCommand.RaiseCanExecuteChanged();
CloseScriptCommand.RaiseCanExecuteChanged();
ReplaceColorsCommand.RaiseCanExecuteChanged();
break;
}
}
});
}
public RelayCommand OpenScriptCommand { get; private set; }
@@ -90,28 +87,13 @@ namespace Filtration.ViewModels
public RelayCommand PasteCommand { get; private set; }
public RelayCommand CopyScriptCommand { get; private set; }
public RelayCommand NewScriptCommand { get; private set; }
public RelayCommand<IDocument> CloseScriptCommand { get; private set; }
public RelayCommand CloseScriptCommand { get; private set; }
public RelayCommand OpenAboutWindowCommand { get; private set; }
public RelayCommand ReplaceColorsCommand { get; private set; }
public ObservableCollection<IDocument> OpenDocuments
public IAvalonDockWorkspaceViewModel AvalonDockWorkspaceViewModel
{
get { return _openDocuments; }
}
private List<IToolViewModel> _tools;
public IEnumerable<IToolViewModel> Tools
{
get
{
if (_tools == null)
{
_tools = new List<IToolViewModel> {_sectionBrowserViewModel, _blockGroupBrowserViewModel};
}
return _tools;
}
get { return _avalonDockWorkspaceViewModel; }
}
public string WindowTitle
@@ -124,43 +106,11 @@ namespace Filtration.ViewModels
}
}
public IDocument ActiveDocument
private bool ActiveDocumentIsScript()
{
get { return _activeDocument; }
set
{
_activeDocument = value;
RaisePropertyChanged();
if (value.IsScript)
{
_activeScriptViewModel = (IItemFilterScriptViewModel)value;
}
if (ActiveDocumentChanged != null)
{
ActiveDocumentChanged(this, EventArgs.Empty);
}
RaisePropertyChanged("NoScriptsOpen");
SaveScriptCommand.RaiseCanExecuteChanged();
SaveScriptAsCommand.RaiseCanExecuteChanged();
}
}
public IItemFilterScriptViewModel ActiveScriptViewModel
{
get { return _activeScriptViewModel; }
return _activeDocument != null && _activeDocument.IsScript;
}
public event EventHandler ActiveDocumentChanged;
public bool NoScriptsOpen
{
get { return _activeDocument == null; }
}
private void OnOpenAboutWindowCommand()
{
var aboutWindow = new AboutWindow();
@@ -182,9 +132,10 @@ namespace Filtration.ViewModels
public void LoadScriptFromFile(string path)
{
var loadedScript = _persistenceService.LoadItemFilterScript(path);
try
{
_loadedScript = _persistenceService.LoadItemFilterScript(path);
}
catch (Exception e)
{
@@ -194,10 +145,8 @@ namespace Filtration.ViewModels
}
var newViewModel = _itemFilterScriptViewModelFactory.Create();
newViewModel.Initialise(_loadedScript);
_activeScriptViewModel = newViewModel;
OpenDocuments.Add((IDocument)newViewModel);
ActiveDocument = (IDocument)newViewModel;
newViewModel.Initialise(loadedScript);
_avalonDockWorkspaceViewModel.AddDocument(newViewModel);
}
private void SetItemFilterScriptDirectory()
@@ -225,96 +174,34 @@ namespace Filtration.ViewModels
private void OnSaveScriptCommand()
{
if (!ValidateScript()) return;
if (string.IsNullOrEmpty(_activeScriptViewModel.Script.FilePath))
{
OnSaveScriptAsCommand();
return;
}
try
{
_persistenceService.SaveItemFilterScript(_activeScriptViewModel.Script);
_activeScriptViewModel.RemoveDirtyFlag();
}
catch (Exception e)
{
MessageBox.Show(@"Error saving filter file - " + e.Message, @"Save Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SaveScript();
}
private void OnSaveScriptAsCommand()
{
if (!ValidateScript()) return;
var saveDialog = new SaveFileDialog
{
DefaultExt = ".filter",
Filter = @"Filter Files (*.filter)|*.filter|All Files (*.*)|*.*",
InitialDirectory = _persistenceService.ItemFilterScriptDirectory
};
var result = saveDialog.ShowDialog();
if (result != DialogResult.OK) return;
var previousFilePath = _activeScriptViewModel.Script.FilePath;
try
{
_activeScriptViewModel.Script.FilePath = saveDialog.FileName;
_persistenceService.SaveItemFilterScript(_activeScriptViewModel.Script);
_activeScriptViewModel.RemoveDirtyFlag();
}
catch (Exception e)
{
MessageBox.Show(@"Error saving filter file - " + e.Message, @"Save Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
_activeScriptViewModel.Script.FilePath = previousFilePath;
}
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SaveScriptAs();
}
private void OnReplaceColorsCommand()
{
_replaceColorsViewModel.Initialise(_activeScriptViewModel.Script);
_replaceColorsViewModel.Initialise(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script);
var replaceColorsWindow = new ReplaceColorsWindow {DataContext = _replaceColorsViewModel};
replaceColorsWindow.ShowDialog();
}
private bool ValidateScript()
{
var result = _activeScriptViewModel.Script.Validate();
if (result.Count == 0) return true;
var failures = string.Empty;
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (string failure in result)
{
failures += failure + Environment.NewLine;
}
MessageBox.Show(@"The following script validation errors occurred:" + Environment.NewLine + failures,
@"Script Validation Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
private void OnCopyScriptCommand()
{
Clipboard.SetText(_itemFilterScriptTranslator.TranslateItemFilterScriptToString(_activeScriptViewModel.Script));
Clipboard.SetText(_itemFilterScriptTranslator.TranslateItemFilterScriptToString(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script));
}
private void OnCopyBlockCommand()
{
_activeScriptViewModel.CopyBlock(_activeScriptViewModel.SelectedBlockViewModel);
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.CopyBlock(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel);
}
private void OnPasteCommand()
{
_activeScriptViewModel.PasteBlock(_activeScriptViewModel.SelectedBlockViewModel);
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.PasteBlock(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel);
}
private void OnNewScriptCommand()
@@ -323,66 +210,12 @@ namespace Filtration.ViewModels
var newViewModel = _itemFilterScriptViewModelFactory.Create();
newViewModel.Initialise(newScript);
newViewModel.Description = "New Script";
_activeScriptViewModel = newViewModel;
OpenDocuments.Add((IDocument)newViewModel);
ActiveDocument = (IDocument)newViewModel;
_avalonDockWorkspaceViewModel.AddDocument(newViewModel);
}
private void OnCloseScriptCommand(IDocument documentToClose)
private void OnCloseScriptCommand()
{
Close(documentToClose);
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Close();
}
public void Close(IDocument documentToClose)
{
ActiveDocument = documentToClose;
if (ActiveDocument.IsScript)
{
if (!_activeScriptViewModel.IsDirty)
{
RemoveDocument(ActiveDocument);
}
else
{
var result = MessageBox.Show(@"Want to save your changes to this script?",
@"Filtration", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
switch (result)
{
case DialogResult.Yes:
{
OnSaveScriptCommand();
RemoveDocument(ActiveDocument);
break;
}
case DialogResult.No:
{
RemoveDocument(ActiveDocument);
break;
}
case DialogResult.Cancel:
{
return;
}
}
}
}
else
{
RemoveDocument(documentToClose);
}
}
private void RemoveDocument(IDocument documentToRemove)
{
if (documentToRemove.IsScript)
{
_sectionBrowserViewModel.ClearDown();
}
OpenDocuments.Remove(documentToRemove);
}
}
}