From bd730dd518d65267bca6afb9021f8dc66f2cead4 Mon Sep 17 00:00:00 2001 From: azakhi Date: Fri, 10 Aug 2018 16:02:12 +0300 Subject: [PATCH] Add section features --- .../MoveSectionToIndexCommand.cs | 49 +++ .../ItemFilterScript/PasteSectionCommand.cs | 49 +++ .../ItemFilterScript/RemoveSectionCommand.cs | 42 ++ .../Filtration.ObjectModel.csproj | 3 + .../ItemFilterBlockViewModelBase.cs | 16 +- .../ItemFilterCommentBlockViewModel.cs | 37 +- .../ViewModels/ItemFilterScriptViewModel.cs | 379 +++++++++++++++++- Filtration/ViewModels/MainWindowViewModel.cs | 31 ++ Filtration/Views/ItemFilterBlockView.xaml | 2 +- .../Views/ItemFilterCommentBlockView.xaml | 22 + Filtration/Views/MainWindow.xaml | 4 + 11 files changed, 616 insertions(+), 18 deletions(-) create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/MoveSectionToIndexCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/PasteSectionCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/RemoveSectionCommand.cs diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/MoveSectionToIndexCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveSectionToIndexCommand.cs new file mode 100644 index 0000000..40d0bae --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveSectionToIndexCommand.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class MoveSectionToIndexCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private int _sectionStart; + private int _sectionSize; + private int _index; + + public MoveSectionToIndexCommand(IItemFilterScript itemFilterScript, int sectionStart, int sectionSize, int index) + { + _itemFilterScript = itemFilterScript; + _sectionStart = sectionStart; + _sectionSize = sectionSize; + _index = index; + } + public void Execute() + { + List blocksToMove = new List(); + for(var i = 0; i < _sectionSize; i++) + { + blocksToMove.Add(_itemFilterScript.ItemFilterBlocks[_sectionStart]); + _itemFilterScript.ItemFilterBlocks.RemoveAt(_sectionStart); + } + for (var i = 0; i < _sectionSize; i++) + { + _itemFilterScript.ItemFilterBlocks.Insert(_index + i, blocksToMove[i]); + } + } + + public void Undo() + { + List blocksToMove = new List(); + for (var i = 0; i < _sectionSize; i++) + { + blocksToMove.Add(_itemFilterScript.ItemFilterBlocks[_index]); + _itemFilterScript.ItemFilterBlocks.RemoveAt(_index); + } + for (var i = 0; i < _sectionSize; i++) + { + _itemFilterScript.ItemFilterBlocks.Insert(_sectionStart + i, blocksToMove[i]); + } + } + + public void Redo() => Execute(); + } +} \ No newline at end of file diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/PasteSectionCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/PasteSectionCommand.cs new file mode 100644 index 0000000..52458c6 --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/PasteSectionCommand.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class PasteSectionCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private readonly List _pastedItemFilterBlocks; + private readonly IItemFilterBlockBase _addAfterItemFilterBlock; + + public PasteSectionCommand(IItemFilterScript itemFilterScript, List pastedItemFilterBlocks, IItemFilterBlockBase addAfterItemFilterBlock) + { + _itemFilterScript = itemFilterScript; + _pastedItemFilterBlocks = pastedItemFilterBlocks; + _addAfterItemFilterBlock = addAfterItemFilterBlock; + } + + public void Execute() + { + if (_addAfterItemFilterBlock != null) + { + var lastAddedBlock = _addAfterItemFilterBlock; + foreach(var block in _pastedItemFilterBlocks) + { + _itemFilterScript.ItemFilterBlocks.Insert(_itemFilterScript.ItemFilterBlocks.IndexOf(lastAddedBlock) + 1, block); + lastAddedBlock = block; + } + } + else + { + foreach (var block in _pastedItemFilterBlocks) + { + _itemFilterScript.ItemFilterBlocks.Add(block); + } + } + } + + public void Undo() + { + foreach (var block in _pastedItemFilterBlocks) + { + _itemFilterScript.ItemFilterBlocks.Remove(block); + } + } + + public void Redo() => Execute(); + } +} \ No newline at end of file diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/RemoveSectionCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/RemoveSectionCommand.cs new file mode 100644 index 0000000..2718eb3 --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/RemoveSectionCommand.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class RemoveSectionCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private List _removedItemFilterBlocks; + private int _sectionStart; + private int _sectionSize; + + public RemoveSectionCommand(IItemFilterScript itemFilterScript, int sectionStart, int sectionSize) + { + _itemFilterScript = itemFilterScript; + _sectionStart = sectionStart; + _sectionSize = sectionSize; + _removedItemFilterBlocks = new List(); + for(var i = 0; i < _sectionSize; i++) + { + _removedItemFilterBlocks.Add(_itemFilterScript.ItemFilterBlocks[_sectionStart + i]); + } + } + public void Execute() + { + for (var i = 0; i < _sectionSize; i++) + { + _itemFilterScript.ItemFilterBlocks.RemoveAt(_sectionStart); + } + } + + public void Undo() + { + for (var i = 0; i < _sectionSize; i++) + { + _itemFilterScript.ItemFilterBlocks.Insert(_sectionStart + i, _removedItemFilterBlocks[i]); + } + } + + public void Redo() => Execute(); + } +} diff --git a/Filtration.ObjectModel/Filtration.ObjectModel.csproj b/Filtration.ObjectModel/Filtration.ObjectModel.csproj index 6d7ae71..8db75c7 100644 --- a/Filtration.ObjectModel/Filtration.ObjectModel.csproj +++ b/Filtration.ObjectModel/Filtration.ObjectModel.csproj @@ -86,12 +86,15 @@ + + + diff --git a/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs b/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs index 86dcfcb..395bbe1 100644 --- a/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs +++ b/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs @@ -9,13 +9,15 @@ namespace Filtration.ViewModels { void Initialise(IItemFilterBlockBase itemfilterBlock, IItemFilterScriptViewModel itemFilterScriptViewModel); IItemFilterBlockBase BaseBlock { get; } - bool IsDirty { get; set; } + bool IsDirty { get; set; } + bool IsVisible { get; set; } event EventHandler BlockBecameDirty; } internal abstract class ItemFilterBlockViewModelBase : ViewModelBase, IItemFilterBlockViewModelBase { private bool _isDirty; + private bool _isVisible; public ItemFilterBlockViewModelBase() { @@ -28,6 +30,8 @@ namespace Filtration.ViewModels MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand); MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand); MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand); + + _isVisible = true; } @@ -64,6 +68,16 @@ namespace Filtration.ViewModels BlockBecameDirty?.Invoke(this, EventArgs.Empty); } } + } + + public bool IsVisible + { + get => _isVisible; + set + { + _isVisible = value; + RaisePropertyChanged(); + } } private void OnCopyBlockCommand() diff --git a/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs b/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs index 08f5f23..3516348 100644 --- a/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs +++ b/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs @@ -1,15 +1,26 @@ -using Filtration.ObjectModel; +using Filtration.ObjectModel; +using GalaSoft.MvvmLight.CommandWpf; namespace Filtration.ViewModels { internal interface IItemFilterCommentBlockViewModel : IItemFilterBlockViewModelBase { IItemFilterCommentBlock ItemFilterCommentBlock { get; } - string Comment { get; } + string Comment { get; } + bool IsExpanded { get; set; } } internal class ItemFilterCommentBlockViewModel : ItemFilterBlockViewModelBase, IItemFilterCommentBlockViewModel - { + { + private bool _isExpanded; + + public ItemFilterCommentBlockViewModel() + { + _isExpanded = true; + + ToggleSectionCommand = new RelayCommand(OnToggleSectionCommand); + } + public override void Initialise(IItemFilterBlockBase itemfilterBlock, IItemFilterScriptViewModel itemFilterScriptViewModel) { _parentScriptViewModel = itemFilterScriptViewModel; @@ -17,7 +28,9 @@ namespace Filtration.ViewModels BaseBlock = ItemFilterCommentBlock; base.Initialise(itemfilterBlock, itemFilterScriptViewModel); - } + } + + public RelayCommand ToggleSectionCommand { get; } public IItemFilterCommentBlock ItemFilterCommentBlock { get; private set; } @@ -36,6 +49,22 @@ namespace Filtration.ViewModels RaisePropertyChanged(); } } + } + + + public bool IsExpanded + { + get => _isExpanded; + set + { + _isExpanded = value; + RaisePropertyChanged(); + } + } + + private void OnToggleSectionCommand() + { + _parentScriptViewModel.ToggleSection(this); } } } \ No newline at end of file diff --git a/Filtration/ViewModels/ItemFilterScriptViewModel.cs b/Filtration/ViewModels/ItemFilterScriptViewModel.cs index e76f10f..4cf2522 100644 --- a/Filtration/ViewModels/ItemFilterScriptViewModel.cs +++ b/Filtration/ViewModels/ItemFilterScriptViewModel.cs @@ -44,11 +44,16 @@ namespace Filtration.ViewModels void SetDirtyFlag(); bool HasSelectedEnabledBlock(); bool HasSelectedDisabledBlock(); + bool HasSelectedCommentBlock(); RelayCommand AddBlockCommand { get; } RelayCommand AddSectionCommand { get; } RelayCommand DisableBlockCommand { get; } RelayCommand EnableBlockCommand { get; } + RelayCommand DisableSectionCommand { get; } + RelayCommand EnableSectionCommand { get; } + RelayCommand ExpandSectionCommand { get; } + RelayCommand CollapseSectionCommand { get; } RelayCommand DeleteBlockCommand { get; } RelayCommand MoveBlockUpCommand { get; } RelayCommand MoveBlockDownCommand { get; } @@ -74,6 +79,7 @@ namespace Filtration.ViewModels void MoveBlockUp(IItemFilterBlockViewModelBase targetBlockViewModelBase); void MoveBlockDown(IItemFilterBlockViewModelBase targetBlockViewModelBase); void MoveBlockToBottom(IItemFilterBlockViewModelBase targetBlockViewModelBase); + void ToggleSection(IItemFilterCommentBlockViewModel targetCommentBlockViewModelBase); } internal class ItemFilterScriptViewModel : PaneViewModel, IItemFilterScriptViewModel @@ -131,6 +137,10 @@ namespace Filtration.ViewModels AddSectionCommand = new RelayCommand(OnAddCommentBlockCommand, () => SelectedBlockViewModel != null); DisableBlockCommand = new RelayCommand(OnDisableBlockCommand, HasSelectedEnabledBlock); EnableBlockCommand = new RelayCommand(OnEnableBlockCommand, HasSelectedDisabledBlock); + DisableSectionCommand = new RelayCommand(OnDisableSectionCommand, HasSelectedCommentBlock); + EnableSectionCommand = new RelayCommand(OnEnableSectionCommand, HasSelectedCommentBlock); + ExpandSectionCommand = new RelayCommand(OnExpandSectionCommand, HasSelectedCommentBlock); + CollapseSectionCommand = new RelayCommand(OnCollapseSectionCommand, HasSelectedCommentBlock); CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => SelectedBlockViewModel != null); CopyBlockStyleCommand = new RelayCommand(OnCopyBlockStyleCommand, () => SelectedBlockViewModel != null); PasteBlockCommand = new RelayCommand(OnPasteBlockCommand, () => SelectedBlockViewModel != null); @@ -245,6 +255,10 @@ namespace Filtration.ViewModels public RelayCommand AddSectionCommand { get; } public RelayCommand EnableBlockCommand { get; } public RelayCommand DisableBlockCommand { get; } + public RelayCommand DisableSectionCommand { get; } + public RelayCommand EnableSectionCommand { get; } + public RelayCommand ExpandSectionCommand { get; } + public RelayCommand CollapseSectionCommand { get; } public RelayCommand CopyBlockCommand { get; } public RelayCommand CopyBlockStyleCommand { get; } public RelayCommand PasteBlockCommand { get; } @@ -359,6 +373,13 @@ namespace Filtration.ViewModels return SelectedBlockViewModel != null; } + public bool HasSelectedCommentBlock() + { + var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + + return selectedBlockViewModel != null; + } + public IItemFilterBlockViewModelBase SelectedBlockViewModel { get => _selectedBlockViewModel; @@ -634,7 +655,15 @@ namespace Filtration.ViewModels private void OnCopyBlockCommand() { - CopyBlock(SelectedBlockViewModel); + var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded) + { + CopyBlock(SelectedBlockViewModel); + } + else + { + CopySection(commentBlockViewModel); + } } public void CopyBlock(IItemFilterBlockViewModelBase targetBlockViewModel) @@ -649,6 +678,26 @@ namespace Filtration.ViewModels } } + public void CopySection(IItemFilterCommentBlockViewModel targetCommentBlockViewModel) + { + var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel) + 1; + var copyText = _blockTranslator.TranslateItemFilterBlockBaseToString(targetCommentBlockViewModel.BaseBlock); + while (sectionStart < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionStart] as IItemFilterCommentBlockViewModel == null) + { + copyText += Environment.NewLine + "##CopySection##" + Environment.NewLine + _blockTranslator.TranslateItemFilterBlockBaseToString(ItemFilterBlockViewModels[sectionStart].BaseBlock); + sectionStart++; + } + + try + { + _clipboardService.SetClipboardText(copyText); + } + catch + { + _messageBoxService.Show("Clipboard Error", "Failed to access the clipboard, copy command not completed.", MessageBoxButton.OK, MessageBoxImage.Error); + } + } + private void OnCopyBlockStyleCommand() { var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterBlockViewModel; @@ -713,11 +762,78 @@ namespace Filtration.ViewModels { var clipboardText = _clipboardService.GetClipboardText(); if (string.IsNullOrEmpty(clipboardText)) return; - - var translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(clipboardText, Script, true); // TODO: Doesn't handle pasting comment blocks? - if (translatedBlock == null) return; - _scriptCommandManager.ExecuteCommand(new PasteBlockCommand(Script, translatedBlock, targetBlockViewModelBase.BaseBlock)); + string[] blockTexts = clipboardText.Split(new string[] { Environment.NewLine + "##CopySection##" + Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); + + var previousBlock = targetBlockViewModelBase.BaseBlock; + var pastedSection = false; + List blocksToPaste = new List(); + List isBlockDisabled = new List(); + foreach (var curBlock in blockTexts) + { + IItemFilterBlockBase translatedBlock; + var pastedDisabledBlock = false; + if (!curBlock.StartsWith(@"#Disabled Block Start") && curBlock.StartsWith(@"#")) + { + translatedBlock = _blockTranslator.TranslateStringToItemFilterCommentBlock(curBlock, Script); + pastedSection = true; + } + else if (curBlock.StartsWith(@"#Disabled Block Start")) + { + pastedDisabledBlock = true; + string[] textLines = curBlock.Split(new[] { Environment.NewLine }, StringSplitOptions.None); + if (textLines.Length < 3) + continue; + + string cleanBlock = textLines[1].Substring(1); + for(int i = 2; i < (textLines.Length - 1); i++) + { + cleanBlock += Environment.NewLine + textLines[i].Substring(1); + } + translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(cleanBlock, Script, true); + } + else + { + translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(curBlock, Script, true); + } + + if (translatedBlock == null) continue; + + blocksToPaste.Add(translatedBlock); + + isBlockDisabled.Add(pastedDisabledBlock); + } + + if(pastedSection) + { + var blockIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase) + 1; + _scriptCommandManager.ExecuteCommand(new PasteSectionCommand(Script, blocksToPaste, targetBlockViewModelBase.BaseBlock)); + SelectedBlockViewModel = ItemFilterBlockViewModels[blockIndex]; + foreach (var isDisabled in isBlockDisabled) + { + var block = ItemFilterBlockViewModels[blockIndex++] as IItemFilterBlockViewModel; + if(block != null) + { + block.BlockEnabled = !isDisabled; + } + } + OnCollapseSectionCommand(); + } + else + { + var blockIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase) + 1; + for (var i = 0; i < blocksToPaste.Count; i++) + { + _scriptCommandManager.ExecuteCommand(new PasteBlockCommand(Script, blocksToPaste[i], previousBlock)); + previousBlock = blocksToPaste[i]; + + var block = ItemFilterBlockViewModels[blockIndex + i] as IItemFilterBlockViewModel; + if (block != null) + { + block.BlockEnabled = !isBlockDisabled[i]; + } + } + } } catch (Exception e) { @@ -730,32 +846,151 @@ namespace Filtration.ViewModels private void OnMoveBlockToTopCommand() { - MoveBlockToTop(SelectedBlockViewModel); + var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded) + { + MoveBlockToTop(SelectedBlockViewModel); + } + else + { + MoveSectionToTop(commentBlockViewModel); + } } private void OnMoveBlockUpCommand() { - MoveBlockUp(SelectedBlockViewModel); + var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if(commentBlockViewModel == null || commentBlockViewModel.IsExpanded) + { + MoveBlockUp(SelectedBlockViewModel); + } + else + { + MoveSectionUp(commentBlockViewModel); + } } public void MoveBlockUp(IItemFilterBlockViewModelBase targetBlockViewModelBase) { - _scriptCommandManager.ExecuteCommand(new MoveBlockUpCommand(Script, targetBlockViewModelBase?.BaseBlock)); + var blockIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase); + if (ItemFilterBlockViewModels[blockIndex - 1].IsVisible) + { + _scriptCommandManager.ExecuteCommand(new MoveBlockUpCommand(Script, targetBlockViewModelBase?.BaseBlock)); + } + else + { + var aboveSectionStart = blockIndex - 1; + while(ItemFilterBlockViewModels[aboveSectionStart] as IItemFilterCommentBlockViewModel == null) + { + aboveSectionStart--; + } + _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, blockIndex, 1, aboveSectionStart)); + } + } + + public void MoveSectionUp(IItemFilterCommentBlockViewModel targetCommentBlockViewModel) + { + var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel); + var sectionEnd = sectionStart + 1; + while(sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null) + { + sectionEnd++; + } + + var newLocation = sectionStart - 1; + if (ItemFilterBlockViewModels[newLocation].IsVisible) + { + _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation)); + } + else + { + while (ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel == null) + { + newLocation--; + } + _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation)); + } + + ToggleSection(ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel); + SelectedBlockViewModel = ItemFilterBlockViewModels[newLocation]; } private void OnMoveBlockDownCommand() { - MoveBlockDown(SelectedBlockViewModel); + var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded) + { + MoveBlockDown(SelectedBlockViewModel); + } + else + { + MoveSectionDown(commentBlockViewModel); + } } public void MoveBlockDown(IItemFilterBlockViewModelBase targetBlockViewModelBase) { - _scriptCommandManager.ExecuteCommand(new MoveBlockDownCommand(Script, targetBlockViewModelBase?.BaseBlock)); + var blockIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase); + var beloveBlockAsComment = ItemFilterBlockViewModels[blockIndex + 1] as IItemFilterCommentBlockViewModel; + if (beloveBlockAsComment == null || beloveBlockAsComment.IsExpanded) + { + _scriptCommandManager.ExecuteCommand(new MoveBlockDownCommand(Script, targetBlockViewModelBase?.BaseBlock)); + } + else + { + var beloveSectionEnd = blockIndex + 2; + while (beloveSectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[beloveSectionEnd] as IItemFilterCommentBlockViewModel == null) + { + beloveSectionEnd++; + } + _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, blockIndex, 1, beloveSectionEnd - 1)); + } + } + + public void MoveSectionDown(IItemFilterCommentBlockViewModel targetCommentBlockViewModel) + { + var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel); + var sectionEnd = sectionStart + 1; + while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null) + { + sectionEnd++; + } + + if (sectionEnd >= ItemFilterBlockViewModels.Count) + return; + + var sectionSize = sectionEnd - sectionStart; + + var newLocation = sectionStart + 1; + var beloveBlockAsComment = ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel; + if (beloveBlockAsComment == null || beloveBlockAsComment.IsExpanded) + { + _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionSize, newLocation)); + } + else + { + while ((newLocation + sectionSize) < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[newLocation + sectionSize] as IItemFilterCommentBlockViewModel == null) + { + newLocation++; + } + _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation)); + } + + ToggleSection(ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel); + SelectedBlockViewModel = ItemFilterBlockViewModels[newLocation]; } private void OnMoveBlockToBottomCommand() { - MoveBlockToBottom(SelectedBlockViewModel); + var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded) + { + MoveBlockToBottom(SelectedBlockViewModel); + } + else + { + MoveSectionToBottom(commentBlockViewModel); + } } private void OnAddBlockCommand() @@ -776,7 +1011,22 @@ namespace Filtration.ViewModels public void DeleteBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase) { - _scriptCommandManager.ExecuteCommand(new RemoveBlockCommand(Script, targetBlockViewModelBase.BaseBlock)); + var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded) + { + _scriptCommandManager.ExecuteCommand(new RemoveBlockCommand(Script, targetBlockViewModelBase.BaseBlock)); + } + else + { + var sectionStart = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase); + var sectionEnd = sectionStart + 1; + while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null) + { + sectionEnd++; + } + + _scriptCommandManager.ExecuteCommand(new RemoveSectionCommand(Script, sectionStart, sectionEnd - sectionStart)); + } } public void MoveBlockToBottom(IItemFilterBlockViewModelBase targetBlockViewModelBase) @@ -784,11 +1034,43 @@ namespace Filtration.ViewModels _scriptCommandManager.ExecuteCommand(new MoveBlockToBottomCommand(Script, targetBlockViewModelBase.BaseBlock)); } + public void MoveSectionToBottom(IItemFilterCommentBlockViewModel targetCommentBlockViewModel) + { + var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel); + var sectionEnd = sectionStart + 1; + while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null) + { + sectionEnd++; + } + + var newLocation = ItemFilterBlockViewModels.Count - (sectionEnd - sectionStart); + _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation)); + + ToggleSection(ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel); + SelectedBlockViewModel = ItemFilterBlockViewModels[newLocation]; + } + public void MoveBlockToTop(IItemFilterBlockViewModelBase targetBlockViewModelBase) { _scriptCommandManager.ExecuteCommand(new MoveBlockToTopCommand(Script, targetBlockViewModelBase.BaseBlock)); } + public void MoveSectionToTop(IItemFilterCommentBlockViewModel targetCommentBlockViewModel) + { + var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel); + var sectionEnd = sectionStart + 1; + while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null) + { + sectionEnd++; + } + + var newLocation = 0; + _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation)); + + ToggleSection(ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel); + SelectedBlockViewModel = ItemFilterBlockViewModels[newLocation]; + } + private void OnBlockBecameDirty(object sender, EventArgs e) { SetDirtyFlag(); @@ -837,5 +1119,78 @@ namespace Filtration.ViewModels selectedBlockViewModel.BlockEnabled = true; } } + + private void OnDisableSectionCommand() + { + var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if (selectedBlockViewModel != null) + { + var sectionIndex = ItemFilterBlockViewModels.IndexOf(selectedBlockViewModel); + for (int i = sectionIndex + 1; i < ItemFilterBlockViewModels.Count; i++) + { + var block = ItemFilterBlockViewModels[i] as IItemFilterBlockViewModel; + if (block != null) + { + block.BlockEnabled = false; + } + else + break; + } + } + } + + private void OnEnableSectionCommand() + { + var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if (selectedBlockViewModel != null) + { + var sectionIndex = ItemFilterBlockViewModels.IndexOf(selectedBlockViewModel); + for (int i = sectionIndex + 1; i < ItemFilterBlockViewModels.Count; i++) + { + var block = ItemFilterBlockViewModels[i] as IItemFilterBlockViewModel; + if (block != null) + { + block.BlockEnabled = true; + } + else + break; + } + } + } + + private void OnExpandSectionCommand() + { + var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if (selectedBlockViewModel != null && !selectedBlockViewModel.IsExpanded) + { + ToggleSection(selectedBlockViewModel); + } + } + + private void OnCollapseSectionCommand() + { + var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel; + if (selectedBlockViewModel != null && selectedBlockViewModel.IsExpanded) + { + ToggleSection(selectedBlockViewModel); + } + } + + public void ToggleSection(IItemFilterCommentBlockViewModel targetCommentBlockViewModelBase) + { + var newState = !targetCommentBlockViewModelBase.IsExpanded; + targetCommentBlockViewModelBase.IsExpanded = newState; + var sectionIndex = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModelBase); + for (int i = sectionIndex + 1; i < ItemFilterBlockViewModels.Count; i++) + { + var block = ItemFilterBlockViewModels[i] as IItemFilterBlockViewModel; + if (block != null) + { + block.IsVisible = newState; + } + else + break; + } + } } } diff --git a/Filtration/ViewModels/MainWindowViewModel.cs b/Filtration/ViewModels/MainWindowViewModel.cs index 7fe247c..bd77aea 100644 --- a/Filtration/ViewModels/MainWindowViewModel.cs +++ b/Filtration/ViewModels/MainWindowViewModel.cs @@ -100,6 +100,10 @@ namespace Filtration.ViewModels DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); DisableBlockCommand = new RelayCommand(OnDisableBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedEnabledBlock); EnableBlockCommand = new RelayCommand(OnEnableBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedDisabledBlock); + DisableSectionCommand = new RelayCommand(OnDisableSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock); + EnableSectionCommand = new RelayCommand(OnEnableSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock); + ExpandSectionCommand = new RelayCommand(OnExpandSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock); + CollapseSectionCommand = new RelayCommand(OnCollapseSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock); OpenAboutWindowCommand = new RelayCommand(OnOpenAboutWindowCommand); ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, () => ActiveDocumentIsScript); @@ -213,6 +217,10 @@ namespace Filtration.ViewModels public RelayCommand DeleteBlockCommand { get; } public RelayCommand DisableBlockCommand { get; } public RelayCommand EnableBlockCommand { get; } + public RelayCommand DisableSectionCommand { get; } + public RelayCommand EnableSectionCommand { get; } + public RelayCommand ExpandSectionCommand { get; } + public RelayCommand CollapseSectionCommand { get; } public RelayCommand MoveBlockUpCommand { get; } public RelayCommand MoveBlockDownCommand { get; } @@ -260,6 +268,9 @@ namespace Filtration.ViewModels public bool ActiveScriptHasSelectedDisabledBlock => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.HasSelectedDisabledBlock(); + public bool ActiveScriptHasSelectedCommentBlock => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.HasSelectedCommentBlock(); + + public bool ActiveThemeIsEditable => AvalonDockWorkspaceViewModel.ActiveThemeViewModel.IsMasterTheme; private bool ActiveDocumentIsEditable() @@ -595,6 +606,26 @@ namespace Filtration.ViewModels _avalonDockWorkspaceViewModel.ActiveScriptViewModel.EnableBlockCommand.Execute(null); } + private void OnDisableSectionCommand() + { + _avalonDockWorkspaceViewModel.ActiveScriptViewModel.DisableSectionCommand.Execute(null); + } + + private void OnEnableSectionCommand() + { + _avalonDockWorkspaceViewModel.ActiveScriptViewModel.EnableSectionCommand.Execute(null); + } + + private void OnExpandSectionCommand() + { + _avalonDockWorkspaceViewModel.ActiveScriptViewModel.ExpandSectionCommand.Execute(null); + } + + private void OnCollapseSectionCommand() + { + _avalonDockWorkspaceViewModel.ActiveScriptViewModel.CollapseSectionCommand.Execute(null); + } + private void OnExpandAllBlocksCommand() { _avalonDockWorkspaceViewModel.ActiveScriptViewModel.ExpandAllBlocksCommand.Execute(null); diff --git a/Filtration/Views/ItemFilterBlockView.xaml b/Filtration/Views/ItemFilterBlockView.xaml index 98b941c..816cc71 100644 --- a/Filtration/Views/ItemFilterBlockView.xaml +++ b/Filtration/Views/ItemFilterBlockView.xaml @@ -11,7 +11,7 @@ xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase" mc:Ignorable="d" d:DataContext="{d:DesignInstance Type=viewModels:ItemFilterBlockViewModel}" - d:DesignHeight="200" d:DesignWidth="800"> + d:DesignHeight="200" d:DesignWidth="800" Visibility="{Binding IsVisible, Converter={StaticResource BooleanVisibilityConverter}}"> diff --git a/Filtration/Views/ItemFilterCommentBlockView.xaml b/Filtration/Views/ItemFilterCommentBlockView.xaml index 8846a50..2e561c8 100644 --- a/Filtration/Views/ItemFilterCommentBlockView.xaml +++ b/Filtration/Views/ItemFilterCommentBlockView.xaml @@ -77,6 +77,28 @@ + + diff --git a/Filtration/Views/MainWindow.xaml b/Filtration/Views/MainWindow.xaml index 1d9aa46..ec8e882 100644 --- a/Filtration/Views/MainWindow.xaml +++ b/Filtration/Views/MainWindow.xaml @@ -101,6 +101,10 @@ + + + +