From bd730dd518d65267bca6afb9021f8dc66f2cead4 Mon Sep 17 00:00:00 2001 From: azakhi Date: Fri, 10 Aug 2018 16:02:12 +0300 Subject: [PATCH 01/22] 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 @@ + + + + From 38053666a06102f0374142018189530f0aaf9e46 Mon Sep 17 00:00:00 2001 From: azakhi Date: Fri, 10 Aug 2018 22:22:25 +0300 Subject: [PATCH 02/22] Fix collapsed section height --- .../BooleanToBlockMarginConverter.cs | 27 +++++++++++++++++++ Filtration/Filtration.csproj | 1 + Filtration/Views/ItemFilterBlockView.xaml | 3 ++- .../Views/ItemFilterCommentBlockView.xaml | 2 +- Filtration/Views/ItemFilterScriptView.xaml | 2 +- 5 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 Filtration/Converters/BooleanToBlockMarginConverter.cs diff --git a/Filtration/Converters/BooleanToBlockMarginConverter.cs b/Filtration/Converters/BooleanToBlockMarginConverter.cs new file mode 100644 index 0000000..416d4c2 --- /dev/null +++ b/Filtration/Converters/BooleanToBlockMarginConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Filtration.Converters +{ + public class BooleanToBlockMarginConverter : IValueConverter + { + public double Length { get; set; } + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var item = (bool)value; + + if (!item) + return new Thickness(2, 0, 2, 0); + + return new Thickness(2, 2, 2, 2); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return ((Thickness)value) == new Thickness(0, 0, 0, 0); + } + } +} diff --git a/Filtration/Filtration.csproj b/Filtration/Filtration.csproj index 4e0f402..fc275ee 100644 --- a/Filtration/Filtration.csproj +++ b/Filtration/Filtration.csproj @@ -167,6 +167,7 @@ + diff --git a/Filtration/Views/ItemFilterBlockView.xaml b/Filtration/Views/ItemFilterBlockView.xaml index 816cc71..ce00d76 100644 --- a/Filtration/Views/ItemFilterBlockView.xaml +++ b/Filtration/Views/ItemFilterBlockView.xaml @@ -18,6 +18,7 @@ + - + + + + + + + + diff --git a/Filtration/App.xaml.cs b/Filtration/App.xaml.cs index 6690e58..61ab85d 100644 --- a/Filtration/App.xaml.cs +++ b/Filtration/App.xaml.cs @@ -46,6 +46,7 @@ namespace Filtration cfg.ConstructServicesUsing(_container.Resolve); cfg.CreateMap().ConstructUsingServiceLocator(); cfg.CreateMap().ReverseMap(); + cfg.CreateMap().ReverseMap(); cfg.CreateMap(); }); diff --git a/Filtration/UserControls/BlockItemControl.xaml.cs b/Filtration/UserControls/BlockItemControl.xaml.cs index 70d9d0d..43a9ca7 100644 --- a/Filtration/UserControls/BlockItemControl.xaml.cs +++ b/Filtration/UserControls/BlockItemControl.xaml.cs @@ -6,6 +6,7 @@ using System.Windows; using Filtration.Annotations; using Filtration.ObjectModel; using Filtration.ObjectModel.BlockItemBaseTypes; +using Filtration.ObjectModel.ThemeEditor; using Filtration.Views; using GalaSoft.MvvmLight.CommandWpf; using Xceed.Wpf.Toolkit; @@ -97,7 +98,7 @@ namespace Filtration.UserControls var blockItem = BlockItem as ColorBlockItem; if (blockItem?.ThemeComponent == null) return; - blockItem.Color = blockItem.ThemeComponent.Color; + blockItem.Color = ((ColorThemeComponent)blockItem.ThemeComponent).Color; } public event PropertyChangedEventHandler PropertyChanged; From bc5a005ee7ddbedb4a40ebe46fc55ae0319bda23 Mon Sep 17 00:00:00 2001 From: azakhi Date: Sat, 25 Aug 2018 15:52:16 +0300 Subject: [PATCH 21/22] Add font size theme support & improve theme system --- .../BlockItemBaseTypes/ColorBlockItem.cs | 2 +- .../BlockItemBaseTypes/IntegerBlockItem.cs | 42 ++++++++++- .../Enums/ThemeComponentType.cs | 4 +- .../Filtration.ObjectModel.csproj | 2 + Filtration.ObjectModel/IBlockItemWithTheme.cs | 9 +++ .../ThemeEditor/ColorThemeComponent.cs | 4 - .../ThemeEditor/IntegerThemeComponent.cs | 35 +++++++++ Filtration.ObjectModel/ThemeEditor/Theme.cs | 5 ++ .../ThemeEditor/ThemeComponentCollection.cs | 19 +++-- .../Services/ItemFilterBlockTranslator.cs | 12 ++- .../ThemeComponentTypeToStringConverter.cs | 4 + .../Filtration.ThemeEditor.csproj | 1 + .../Providers/ThemeProvider.cs | 3 + .../Services/ThemeService.cs | 23 ++++++ .../ColorThemeComponentViewModel.cs | 1 - .../IntegerThemeComponentViewModel.cs | 7 ++ .../ViewModels/ThemeEditorViewModel.cs | 3 + .../Views/ThemeComponentControl.xaml | 5 ++ Filtration/App.xaml.cs | 1 + .../AvailableThemeComponentsConverter.cs | 6 +- Filtration/UserControls/BlockItemControl.xaml | 18 ++++- .../UserControls/BlockItemControl.xaml.cs | 28 +++++-- .../ThemeComponentSelectionControl.xaml | 73 +++++++++---------- .../ViewModels/ItemFilterScriptViewModel.cs | 2 +- Filtration/ViewModels/MainWindowViewModel.cs | 7 ++ Filtration/Views/MainWindow.xaml | 1 + 26 files changed, 247 insertions(+), 70 deletions(-) create mode 100644 Filtration.ObjectModel/IBlockItemWithTheme.cs create mode 100644 Filtration.ObjectModel/ThemeEditor/IntegerThemeComponent.cs create mode 100644 Filtration.ThemeEditor/ViewModels/IntegerThemeComponentViewModel.cs diff --git a/Filtration.ObjectModel/BlockItemBaseTypes/ColorBlockItem.cs b/Filtration.ObjectModel/BlockItemBaseTypes/ColorBlockItem.cs index 7f6efc9..7592642 100644 --- a/Filtration.ObjectModel/BlockItemBaseTypes/ColorBlockItem.cs +++ b/Filtration.ObjectModel/BlockItemBaseTypes/ColorBlockItem.cs @@ -4,7 +4,7 @@ using Filtration.ObjectModel.ThemeEditor; namespace Filtration.ObjectModel.BlockItemBaseTypes { - public abstract class ColorBlockItem : BlockItemBase, IAudioVisualBlockItem + public abstract class ColorBlockItem : BlockItemBase, IAudioVisualBlockItem, IBlockItemWithTheme { private Color _color; private ThemeComponent _themeComponent; diff --git a/Filtration.ObjectModel/BlockItemBaseTypes/IntegerBlockItem.cs b/Filtration.ObjectModel/BlockItemBaseTypes/IntegerBlockItem.cs index 6beb767..2299140 100644 --- a/Filtration.ObjectModel/BlockItemBaseTypes/IntegerBlockItem.cs +++ b/Filtration.ObjectModel/BlockItemBaseTypes/IntegerBlockItem.cs @@ -1,10 +1,13 @@ -using System.Windows.Media; +using System; +using System.Windows.Media; +using Filtration.ObjectModel.ThemeEditor; namespace Filtration.ObjectModel.BlockItemBaseTypes { - public abstract class IntegerBlockItem : BlockItemBase, IAudioVisualBlockItem + public abstract class IntegerBlockItem : BlockItemBase, IAudioVisualBlockItem, IBlockItemWithTheme { private int _value; + private ThemeComponent _themeComponent; protected IntegerBlockItem() { @@ -15,7 +18,7 @@ namespace Filtration.ObjectModel.BlockItemBaseTypes Value = value; } - public override string OutputText => PrefixText + " " + Value; + public override string OutputText => PrefixText + " " + Value + (ThemeComponent != null ? " # " + ThemeComponent.ComponentName : string.Empty); public override string SummaryText => string.Empty; public override Color SummaryBackgroundColor => Colors.Transparent; @@ -24,6 +27,29 @@ namespace Filtration.ObjectModel.BlockItemBaseTypes public abstract int Minimum { get; } public abstract int Maximum { get; } + public ThemeComponent ThemeComponent + { + get { return _themeComponent; } + set + { + if (_themeComponent == value) { return; } + + if (_themeComponent != null) + { + _themeComponent.ThemeComponentUpdated -= OnThemeComponentUpdated; + _themeComponent.ThemeComponentDeleted -= OnThemeComponentDeleted; + } + if (value != null) + { + value.ThemeComponentUpdated += OnThemeComponentUpdated; + value.ThemeComponentDeleted += OnThemeComponentDeleted; + } + + _themeComponent = value; + OnPropertyChanged(); + } + } + public int Value { get { return _value; } @@ -34,5 +60,15 @@ namespace Filtration.ObjectModel.BlockItemBaseTypes OnPropertyChanged(); } } + + private void OnThemeComponentUpdated(object sender, EventArgs e) + { + Value = ((IntegerBlockItem)sender).Value; + } + + private void OnThemeComponentDeleted(object sender, EventArgs e) + { + ThemeComponent = null; + } } } diff --git a/Filtration.ObjectModel/Enums/ThemeComponentType.cs b/Filtration.ObjectModel/Enums/ThemeComponentType.cs index 4f17dc5..48c20a0 100644 --- a/Filtration.ObjectModel/Enums/ThemeComponentType.cs +++ b/Filtration.ObjectModel/Enums/ThemeComponentType.cs @@ -9,6 +9,8 @@ namespace Filtration.ObjectModel.Enums [Description("Background")] BackgroundColor, [Description("Border")] - BorderColor + BorderColor, + [Description("Font Size")] + FontSize } } diff --git a/Filtration.ObjectModel/Filtration.ObjectModel.csproj b/Filtration.ObjectModel/Filtration.ObjectModel.csproj index 89582ac..bcc1cef 100644 --- a/Filtration.ObjectModel/Filtration.ObjectModel.csproj +++ b/Filtration.ObjectModel/Filtration.ObjectModel.csproj @@ -115,6 +115,7 @@ + @@ -130,6 +131,7 @@ + diff --git a/Filtration.ObjectModel/IBlockItemWithTheme.cs b/Filtration.ObjectModel/IBlockItemWithTheme.cs new file mode 100644 index 0000000..5971eb0 --- /dev/null +++ b/Filtration.ObjectModel/IBlockItemWithTheme.cs @@ -0,0 +1,9 @@ +using Filtration.ObjectModel.ThemeEditor; + +namespace Filtration.ObjectModel +{ + public interface IBlockItemWithTheme : IItemFilterBlockItem + { + ThemeComponent ThemeComponent { get; } + } +} diff --git a/Filtration.ObjectModel/ThemeEditor/ColorThemeComponent.cs b/Filtration.ObjectModel/ThemeEditor/ColorThemeComponent.cs index de1ae3d..044f468 100644 --- a/Filtration.ObjectModel/ThemeEditor/ColorThemeComponent.cs +++ b/Filtration.ObjectModel/ThemeEditor/ColorThemeComponent.cs @@ -1,8 +1,5 @@ using System; -using System.ComponentModel; -using System.Runtime.CompilerServices; using System.Windows.Media; -using Filtration.ObjectModel.Annotations; using Filtration.ObjectModel.Enums; namespace Filtration.ObjectModel.ThemeEditor @@ -11,7 +8,6 @@ namespace Filtration.ObjectModel.ThemeEditor public class ColorThemeComponent : ThemeComponent { private Color _color; - private readonly object _eventLock = new object(); public ColorThemeComponent(ThemeComponentType componentType, string componentName, Color componentColor) { diff --git a/Filtration.ObjectModel/ThemeEditor/IntegerThemeComponent.cs b/Filtration.ObjectModel/ThemeEditor/IntegerThemeComponent.cs new file mode 100644 index 0000000..a72d822 --- /dev/null +++ b/Filtration.ObjectModel/ThemeEditor/IntegerThemeComponent.cs @@ -0,0 +1,35 @@ +using System; +using System.Windows.Media; +using Filtration.ObjectModel.Enums; + +namespace Filtration.ObjectModel.ThemeEditor +{ + [Serializable] + public class IntegerThemeComponent : ThemeComponent + { + private int _value; + + public IntegerThemeComponent(ThemeComponentType componentType, string componentName, int componentValue) + { + if (componentName == null) + { + throw new ArgumentException("Null parameters not allowed in IntegerThemeComponent constructor"); + } + + ComponentType = componentType; + Value = componentValue; + ComponentName = componentName; + } + + public int Value + { + get { return _value; } + set + { + _value = value; + OnPropertyChanged(); + _themeComponentUpdatedEventHandler?.Invoke(this, EventArgs.Empty); + } + } + } +} diff --git a/Filtration.ObjectModel/ThemeEditor/Theme.cs b/Filtration.ObjectModel/ThemeEditor/Theme.cs index 34b8cbc..a765e30 100644 --- a/Filtration.ObjectModel/ThemeEditor/Theme.cs +++ b/Filtration.ObjectModel/ThemeEditor/Theme.cs @@ -34,5 +34,10 @@ namespace Filtration.ObjectModel.ThemeEditor { _components.Add(new ColorThemeComponent(componentType, componentName, componentColor)); } + + public void AddComponent(ThemeComponentType componentType, string componentName, int componentValue) + { + _components.Add(new IntegerThemeComponent(componentType, componentName, componentValue)); + } } } diff --git a/Filtration.ObjectModel/ThemeEditor/ThemeComponentCollection.cs b/Filtration.ObjectModel/ThemeEditor/ThemeComponentCollection.cs index d2d88fe..605a62c 100644 --- a/Filtration.ObjectModel/ThemeEditor/ThemeComponentCollection.cs +++ b/Filtration.ObjectModel/ThemeEditor/ThemeComponentCollection.cs @@ -16,15 +16,20 @@ namespace Filtration.ObjectModel.ThemeEditor return Items.FirstOrDefault(t => t.ComponentName == componentName && t.ComponentType == componentType); } - ThemeComponent component = null; - switch(componentType) + var component = new ColorThemeComponent(componentType, componentName, componentColor); + Items.Add(component); + + return component; + } + + public ThemeComponent AddComponent(ThemeComponentType componentType, string componentName, int componentValue) + { + if (ComponentExists(componentType, componentName)) { - case ThemeComponentType.BackgroundColor: - case ThemeComponentType.BorderColor: - case ThemeComponentType.TextColor: - component = new ColorThemeComponent(componentType, componentName, componentColor); - break; + return Items.FirstOrDefault(t => t.ComponentName == componentName && t.ComponentType == componentType); } + + var component = new IntegerThemeComponent(componentType, componentName, componentValue); Items.Add(component); return component; diff --git a/Filtration.Parser/Services/ItemFilterBlockTranslator.cs b/Filtration.Parser/Services/ItemFilterBlockTranslator.cs index 3545227..fb1d755 100644 --- a/Filtration.Parser/Services/ItemFilterBlockTranslator.cs +++ b/Filtration.Parser/Services/ItemFilterBlockTranslator.cs @@ -217,11 +217,15 @@ namespace Filtration.Parser.Services // Only ever use the last SetFontSize item encountered as multiples aren't valid. RemoveExistingBlockItemsOfType(block); - var match = Regex.Match(trimmedLine, @"\s+(\d+)"); - if (match.Success) + var match = Regex.Matches(trimmedLine, @"(\s+(\d+)\s*)([#]?)(.*)"); + if (match.Count > 0) { - var blockItemValue = new FontSizeBlockItem(Convert.ToInt16(match.Value)); - block.BlockItems.Add(blockItemValue); + var blockItem = new FontSizeBlockItem(Convert.ToInt16(match[0].Groups[2].Value)); + if(match[0].Groups[3].Value == "#" && !string.IsNullOrWhiteSpace(match[0].Groups[4].Value)) + { + blockItem.ThemeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.FontSize, match[0].Groups[4].Value.Trim(), blockItem.Value); + } + block.BlockItems.Add(blockItem); } break; } diff --git a/Filtration.ThemeEditor/Converters/ThemeComponentTypeToStringConverter.cs b/Filtration.ThemeEditor/Converters/ThemeComponentTypeToStringConverter.cs index 37c9829..2ae7c2d 100644 --- a/Filtration.ThemeEditor/Converters/ThemeComponentTypeToStringConverter.cs +++ b/Filtration.ThemeEditor/Converters/ThemeComponentTypeToStringConverter.cs @@ -31,6 +31,10 @@ namespace Filtration.ThemeEditor.Converters { return "Background Color Theme Components"; } + case "Font Size": + { + return "Font Size Theme Components"; + } } return type.GetAttributeDescription(); diff --git a/Filtration.ThemeEditor/Filtration.ThemeEditor.csproj b/Filtration.ThemeEditor/Filtration.ThemeEditor.csproj index 4a5d93d..d64952d 100644 --- a/Filtration.ThemeEditor/Filtration.ThemeEditor.csproj +++ b/Filtration.ThemeEditor/Filtration.ThemeEditor.csproj @@ -109,6 +109,7 @@ + diff --git a/Filtration.ThemeEditor/Providers/ThemeProvider.cs b/Filtration.ThemeEditor/Providers/ThemeProvider.cs index 18fb0ed..2c9bec3 100644 --- a/Filtration.ThemeEditor/Providers/ThemeProvider.cs +++ b/Filtration.ThemeEditor/Providers/ThemeProvider.cs @@ -42,6 +42,9 @@ namespace Filtration.ThemeEditor.Providers case ThemeComponentType.TextColor: c.Add(new ColorThemeComponent(component.ComponentType, component.ComponentName, ((ColorThemeComponent)component).Color)); break; + case ThemeComponentType.FontSize: + c.Add(new IntegerThemeComponent(component.ComponentType, component.ComponentName, ((IntegerThemeComponent)component).Value)); + break; } return c; }); diff --git a/Filtration.ThemeEditor/Services/ThemeService.cs b/Filtration.ThemeEditor/Services/ThemeService.cs index 4e3e23d..2885dd0 100644 --- a/Filtration.ThemeEditor/Services/ThemeService.cs +++ b/Filtration.ThemeEditor/Services/ThemeService.cs @@ -42,6 +42,9 @@ namespace Filtration.ThemeEditor.Services case ThemeComponentType.BorderColor: mismatchedComponents = ApplyColorTheme(blocks, typeof(BorderColorBlockItem), component); break; + case ThemeComponentType.FontSize: + mismatchedComponents = ApplyIntegerTheme(blocks, typeof(FontSizeBlockItem), component); + break; } } @@ -72,5 +75,25 @@ namespace Filtration.ThemeEditor.Services return !componentMatched; } + + private bool ApplyIntegerTheme(IEnumerable blocks, Type type, ThemeComponent component) + { + var componentMatched = false; + foreach (var block in blocks) + { + foreach (var blockItem in block.BlockItems.Where(i => i.GetType() == type)) + { + var colorBlockItem = (IntegerBlockItem)blockItem; + if (colorBlockItem.ThemeComponent != null && + colorBlockItem.ThemeComponent.ComponentName == component.ComponentName) + { + colorBlockItem.Value = ((IntegerThemeComponent)component).Value; + componentMatched = true; + } + } + } + + return !componentMatched; + } } } diff --git a/Filtration.ThemeEditor/ViewModels/ColorThemeComponentViewModel.cs b/Filtration.ThemeEditor/ViewModels/ColorThemeComponentViewModel.cs index 81c196b..849d61d 100644 --- a/Filtration.ThemeEditor/ViewModels/ColorThemeComponentViewModel.cs +++ b/Filtration.ThemeEditor/ViewModels/ColorThemeComponentViewModel.cs @@ -1,5 +1,4 @@ using System.Windows.Media; -using Filtration.ObjectModel.Enums; namespace Filtration.ThemeEditor.ViewModels { diff --git a/Filtration.ThemeEditor/ViewModels/IntegerThemeComponentViewModel.cs b/Filtration.ThemeEditor/ViewModels/IntegerThemeComponentViewModel.cs new file mode 100644 index 0000000..64d71e4 --- /dev/null +++ b/Filtration.ThemeEditor/ViewModels/IntegerThemeComponentViewModel.cs @@ -0,0 +1,7 @@ +namespace Filtration.ThemeEditor.ViewModels +{ + public class IntegerThemeComponentViewModel : ThemeComponentViewModel + { + public int Value { get; set; } + } +} diff --git a/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs b/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs index 9552e32..b342082 100644 --- a/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs +++ b/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs @@ -202,6 +202,9 @@ namespace Filtration.ThemeEditor.ViewModels Components.Add(new ColorThemeComponent(themeComponentType, "Untitled Component", new Color { A = 255, R = 255, G = 255, B = 255 })); break; + case ThemeComponentType.FontSize: + Components.Add(new IntegerThemeComponent(themeComponentType, "Untitled Component", 35)); + break; } } diff --git a/Filtration.ThemeEditor/Views/ThemeComponentControl.xaml b/Filtration.ThemeEditor/Views/ThemeComponentControl.xaml index bcd5453..231561b 100644 --- a/Filtration.ThemeEditor/Views/ThemeComponentControl.xaml +++ b/Filtration.ThemeEditor/Views/ThemeComponentControl.xaml @@ -64,6 +64,11 @@ + + + + + diff --git a/Filtration/App.xaml.cs b/Filtration/App.xaml.cs index 61ab85d..192f000 100644 --- a/Filtration/App.xaml.cs +++ b/Filtration/App.xaml.cs @@ -47,6 +47,7 @@ namespace Filtration cfg.CreateMap().ConstructUsingServiceLocator(); cfg.CreateMap().ReverseMap(); cfg.CreateMap().ReverseMap(); + cfg.CreateMap().ReverseMap(); cfg.CreateMap(); }); diff --git a/Filtration/Converters/AvailableThemeComponentsConverter.cs b/Filtration/Converters/AvailableThemeComponentsConverter.cs index 0d4b3f3..33a1a2b 100644 --- a/Filtration/Converters/AvailableThemeComponentsConverter.cs +++ b/Filtration/Converters/AvailableThemeComponentsConverter.cs @@ -16,7 +16,7 @@ namespace Filtration.Converters var themeComponentsList = values[0] as ThemeComponentCollection; if (themeComponentsList == null || themeComponentsList.Count == 0) return null; - var blockItem = values[1] as ColorBlockItem; + var blockItem = values[1] as BlockItemBase; if (blockItem == null) return null; ThemeComponentType themeComponentType; @@ -33,6 +33,10 @@ namespace Filtration.Converters { themeComponentType = ThemeComponentType.BorderColor; } + else if (blockItem.GetType() == typeof(FontSizeBlockItem)) + { + themeComponentType = ThemeComponentType.FontSize; + } else { return null; diff --git a/Filtration/UserControls/BlockItemControl.xaml b/Filtration/UserControls/BlockItemControl.xaml index 18ae6ac..abf7363 100644 --- a/Filtration/UserControls/BlockItemControl.xaml +++ b/Filtration/UserControls/BlockItemControl.xaml @@ -116,9 +116,21 @@ - - - + + + + + + + + + + + + + + + diff --git a/Filtration/UserControls/BlockItemControl.xaml.cs b/Filtration/UserControls/BlockItemControl.xaml.cs index 43a9ca7..e312c3d 100644 --- a/Filtration/UserControls/BlockItemControl.xaml.cs +++ b/Filtration/UserControls/BlockItemControl.xaml.cs @@ -6,6 +6,7 @@ using System.Windows; using Filtration.Annotations; using Filtration.ObjectModel; using Filtration.ObjectModel.BlockItemBaseTypes; +using Filtration.ObjectModel.Enums; using Filtration.ObjectModel.ThemeEditor; using Filtration.Views; using GalaSoft.MvvmLight.CommandWpf; @@ -21,10 +22,10 @@ namespace Filtration.UserControls // ReSharper disable once PossibleNullReferenceException (Content as FrameworkElement).DataContext = this; - SetBlockColorCommand = new RelayCommand(OnSetBlockColorCommmand); + SetBlockValueCommand = new RelayCommand(OnSetBlockValueCommmand); } - public RelayCommand SetBlockColorCommand { get; private set; } + public RelayCommand SetBlockValueCommand { get; private set; } public static readonly DependencyProperty BlockItemProperty = DependencyProperty.Register( "BlockItem", @@ -93,12 +94,25 @@ namespace Filtration.UserControls "Icon1", "Icon2", "Icon3", "Icon4", "Icon5", "Icon6" }; - private void OnSetBlockColorCommmand() - { - var blockItem = BlockItem as ColorBlockItem; - if (blockItem?.ThemeComponent == null) return; + private void OnSetBlockValueCommmand() + { + var blockItemWithTheme = BlockItem as IBlockItemWithTheme; + if (blockItemWithTheme?.ThemeComponent == null) return; - blockItem.Color = ((ColorThemeComponent)blockItem.ThemeComponent).Color; + var componentType = ((IBlockItemWithTheme)BlockItem).ThemeComponent.ComponentType; + switch(componentType) + { + case ThemeComponentType.BackgroundColor: + case ThemeComponentType.BorderColor: + case ThemeComponentType.TextColor: + var colorBlockItem = BlockItem as ColorBlockItem; + colorBlockItem.Color = ((ColorThemeComponent)colorBlockItem.ThemeComponent).Color; + break; + case ThemeComponentType.FontSize: + var integerBlockItem = BlockItem as IntegerBlockItem; + integerBlockItem.Value = ((IntegerThemeComponent)integerBlockItem.ThemeComponent).Value; + break; + } } public event PropertyChangedEventHandler PropertyChanged; diff --git a/Filtration/UserControls/ThemeComponentSelectionControl.xaml b/Filtration/UserControls/ThemeComponentSelectionControl.xaml index 19d17ab..97ac25b 100644 --- a/Filtration/UserControls/ThemeComponentSelectionControl.xaml +++ b/Filtration/UserControls/ThemeComponentSelectionControl.xaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:userControls="clr-namespace:Filtration.UserControls" + xmlns:themeEditor="clr-namespace:Filtration.ObjectModel.ThemeEditor;assembly=Filtration.ObjectModel" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" mc:Ignorable="d" d:DataContext="{d:DesignInstance Type=userControls:ThemeComponentSelectionControl}" @@ -21,7 +22,7 @@ - + @@ -32,44 +33,42 @@ Visibility="{Binding ShowThemeComponentComboBox, Converter={StaticResource BooleanToVisibilityConverter}}"> - + - - - - - - - - - + + + + + + + + + diff --git a/Filtration/ViewModels/ItemFilterScriptViewModel.cs b/Filtration/ViewModels/ItemFilterScriptViewModel.cs index b6cc5d2..01564a4 100644 --- a/Filtration/ViewModels/ItemFilterScriptViewModel.cs +++ b/Filtration/ViewModels/ItemFilterScriptViewModel.cs @@ -563,7 +563,7 @@ namespace Filtration.ViewModels Script.ThemeComponents.Where( t => Script.ItemFilterBlocks.OfType().Count( - b => b.BlockItems.OfType().Count(i => i.ThemeComponent == t) > 0) == 0).ToList(); + b => b.BlockItems.OfType().Count(i => i.ThemeComponent == t) > 0) == 0).ToList(); if (unusedThemeComponents.Count <= 0) return true; diff --git a/Filtration/ViewModels/MainWindowViewModel.cs b/Filtration/ViewModels/MainWindowViewModel.cs index 358e797..168f006 100644 --- a/Filtration/ViewModels/MainWindowViewModel.cs +++ b/Filtration/ViewModels/MainWindowViewModel.cs @@ -114,6 +114,7 @@ namespace Filtration.ViewModels AddTextColorThemeComponentCommand = new RelayCommand(OnAddTextColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); AddBackgroundColorThemeComponentCommand = new RelayCommand(OnAddBackgroundColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); AddBorderColorThemeComponentCommand = new RelayCommand(OnAddBorderColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); + AddFontSizeThemeComponentCommand = new RelayCommand(OnAddFontSizeThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); DeleteThemeComponentCommand = new RelayCommand(OnDeleteThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable && _avalonDockWorkspaceViewModel.ActiveThemeViewModel.SelectedThemeComponent != null); ExpandAllBlocksCommand = new RelayCommand(OnExpandAllBlocksCommand, () => ActiveDocumentIsScript); @@ -213,6 +214,7 @@ namespace Filtration.ViewModels public RelayCommand AddTextColorThemeComponentCommand { get; } public RelayCommand AddBackgroundColorThemeComponentCommand { get; } public RelayCommand AddBorderColorThemeComponentCommand { get; } + public RelayCommand AddFontSizeThemeComponentCommand { get; } public RelayCommand DeleteThemeComponentCommand { get; } public RelayCommand AddBlockCommand { get; } @@ -677,6 +679,11 @@ namespace Filtration.ViewModels _avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.BorderColor); } + private void OnAddFontSizeThemeComponentCommand() + { + _avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.FontSize); + } + private void OnDeleteThemeComponentCommand() { _avalonDockWorkspaceViewModel.ActiveThemeViewModel.DeleteThemeComponentCommand.Execute( diff --git a/Filtration/Views/MainWindow.xaml b/Filtration/Views/MainWindow.xaml index 6120def..2fd013b 100644 --- a/Filtration/Views/MainWindow.xaml +++ b/Filtration/Views/MainWindow.xaml @@ -129,6 +129,7 @@ + From d92d34af05c3d71ffcb7bb644ba9ef95c7ce7cff Mon Sep 17 00:00:00 2001 From: azakhi Date: Sun, 26 Aug 2018 20:24:13 +0300 Subject: [PATCH 22/22] Add alert sound theme support --- .../BlockItemBaseTypes/StrIntBlockItem.cs | 87 +++++++++++++++++++ .../BlockItemBaseTypes/StringIntBlockItem.cs | 50 ----------- .../Enums/ThemeComponentType.cs | 4 +- .../Filtration.ObjectModel.csproj | 3 +- .../ThemeEditor/StrIntThemeComponent.cs | 48 ++++++++++ Filtration.ObjectModel/ThemeEditor/Theme.cs | 5 ++ .../ThemeEditor/ThemeComponentCollection.cs | 13 +++ .../Services/ItemFilterBlockTranslator.cs | 10 ++- .../ThemeComponentTypeToStringConverter.cs | 4 + .../Filtration.ThemeEditor.csproj | 1 + .../Providers/ThemeProvider.cs | 3 + .../Services/ThemeService.cs | 25 ++++++ .../StrIntThemeComponentViewModel.cs | 8 ++ .../ViewModels/ThemeEditorViewModel.cs | 3 + .../Views/ThemeComponentControl.xaml | 12 +++ Filtration/App.xaml.cs | 1 + .../AvailableThemeComponentsConverter.cs | 4 + Filtration/UserControls/BlockItemControl.xaml | 16 ++++ .../UserControls/BlockItemControl.xaml.cs | 5 ++ .../ThemeComponentSelectionControl.xaml | 5 ++ Filtration/ViewModels/MainWindowViewModel.cs | 7 ++ Filtration/Views/MainWindow.xaml | 1 + 22 files changed, 262 insertions(+), 53 deletions(-) create mode 100644 Filtration.ObjectModel/BlockItemBaseTypes/StrIntBlockItem.cs delete mode 100644 Filtration.ObjectModel/BlockItemBaseTypes/StringIntBlockItem.cs create mode 100644 Filtration.ObjectModel/ThemeEditor/StrIntThemeComponent.cs create mode 100644 Filtration.ThemeEditor/ViewModels/StrIntThemeComponentViewModel.cs diff --git a/Filtration.ObjectModel/BlockItemBaseTypes/StrIntBlockItem.cs b/Filtration.ObjectModel/BlockItemBaseTypes/StrIntBlockItem.cs new file mode 100644 index 0000000..2f66db2 --- /dev/null +++ b/Filtration.ObjectModel/BlockItemBaseTypes/StrIntBlockItem.cs @@ -0,0 +1,87 @@ +using System; +using System.Windows.Media; +using Filtration.ObjectModel.ThemeEditor; + +namespace Filtration.ObjectModel.BlockItemBaseTypes +{ + public abstract class StrIntBlockItem : BlockItemBase, IAudioVisualBlockItem, IBlockItemWithTheme + { + private string _value; + private int _secondValue; + private ThemeComponent _themeComponent; + + protected StrIntBlockItem() + { + } + + protected StrIntBlockItem(string value, int secondValue) + { + Value = value; + SecondValue = secondValue; + Value = value; + SecondValue = secondValue; + } + + public override string OutputText => PrefixText + " " + Value + " " + SecondValue + (ThemeComponent != null ? " # " + ThemeComponent.ComponentName : string.Empty); + + public override string SummaryText => string.Empty; + public override Color SummaryBackgroundColor => Colors.Transparent; + public override Color SummaryTextColor => Colors.Transparent; + + public ThemeComponent ThemeComponent + { + get { return _themeComponent; } + set + { + if (_themeComponent == value) { return; } + + if (_themeComponent != null) + { + _themeComponent.ThemeComponentUpdated -= OnThemeComponentUpdated; + _themeComponent.ThemeComponentDeleted -= OnThemeComponentDeleted; + } + if (value != null) + { + value.ThemeComponentUpdated += OnThemeComponentUpdated; + value.ThemeComponentDeleted += OnThemeComponentDeleted; + } + + _themeComponent = value; + OnPropertyChanged(); + } + } + + public string Value + { + get { return _value; } + set + { + _value = value; + IsDirty = true; + OnPropertyChanged(); + } + } + + public int SecondValue + { + get { return _secondValue; } + set + { + _secondValue = value; + IsDirty = true; + OnPropertyChanged(); + } + } + + private void OnThemeComponentUpdated(object sender, EventArgs e) + { + Value = ((StrIntBlockItem)sender).Value; + SecondValue = ((StrIntBlockItem)sender).SecondValue; + } + + private void OnThemeComponentDeleted(object sender, EventArgs e) + { + ThemeComponent = null; + } + } +} \ No newline at end of file diff --git a/Filtration.ObjectModel/BlockItemBaseTypes/StringIntBlockItem.cs b/Filtration.ObjectModel/BlockItemBaseTypes/StringIntBlockItem.cs deleted file mode 100644 index 405879c..0000000 --- a/Filtration.ObjectModel/BlockItemBaseTypes/StringIntBlockItem.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Windows.Media; - -namespace Filtration.ObjectModel.BlockItemBaseTypes -{ - public abstract class StrIntBlockItem : BlockItemBase, IAudioVisualBlockItem - { - private string _value; - private int _secondValue; - - protected StrIntBlockItem() - { - } - - protected StrIntBlockItem(string value, int secondValue) - { - Value = value; - SecondValue = secondValue; - Value = value; - SecondValue = secondValue; - } - - public override string OutputText => PrefixText + " " + Value + " " + SecondValue; - - public override string SummaryText => string.Empty; - public override Color SummaryBackgroundColor => Colors.Transparent; - public override Color SummaryTextColor => Colors.Transparent; - - public string Value - { - get { return _value; } - set - { - _value = value; - IsDirty = true; - OnPropertyChanged(); - } - } - - public int SecondValue - { - get { return _secondValue; } - set - { - _secondValue = value; - IsDirty = true; - OnPropertyChanged(); - } - } - } -} \ No newline at end of file diff --git a/Filtration.ObjectModel/Enums/ThemeComponentType.cs b/Filtration.ObjectModel/Enums/ThemeComponentType.cs index 48c20a0..ac3b70b 100644 --- a/Filtration.ObjectModel/Enums/ThemeComponentType.cs +++ b/Filtration.ObjectModel/Enums/ThemeComponentType.cs @@ -11,6 +11,8 @@ namespace Filtration.ObjectModel.Enums [Description("Border")] BorderColor, [Description("Font Size")] - FontSize + FontSize, + [Description("Alert Sound")] + AlertSound } } diff --git a/Filtration.ObjectModel/Filtration.ObjectModel.csproj b/Filtration.ObjectModel/Filtration.ObjectModel.csproj index bcc1cef..b7f55d5 100644 --- a/Filtration.ObjectModel/Filtration.ObjectModel.csproj +++ b/Filtration.ObjectModel/Filtration.ObjectModel.csproj @@ -55,7 +55,7 @@ - + @@ -131,6 +131,7 @@ + diff --git a/Filtration.ObjectModel/ThemeEditor/StrIntThemeComponent.cs b/Filtration.ObjectModel/ThemeEditor/StrIntThemeComponent.cs new file mode 100644 index 0000000..a959d70 --- /dev/null +++ b/Filtration.ObjectModel/ThemeEditor/StrIntThemeComponent.cs @@ -0,0 +1,48 @@ +using System; +using System.Windows.Media; +using Filtration.ObjectModel.Enums; + +namespace Filtration.ObjectModel.ThemeEditor +{ + [Serializable] + public class StrIntThemeComponent : ThemeComponent + { + private string _value; + private int _secondValue; + + public StrIntThemeComponent(ThemeComponentType componentType, string componentName, string componentValue, int componentSecondValue) + { + if (componentName == null || componentValue == null) + { + throw new ArgumentException("Null parameters not allowed in StrIntThemeComponent constructor"); + } + + ComponentType = componentType; + Value = componentValue; + SecondValue = componentSecondValue; + ComponentName = componentName; + } + + public string Value + { + get { return _value; } + set + { + _value = value; + OnPropertyChanged(); + _themeComponentUpdatedEventHandler?.Invoke(this, EventArgs.Empty); + } + } + + public int SecondValue + { + get { return _secondValue; } + set + { + _secondValue = value; + OnPropertyChanged(); + _themeComponentUpdatedEventHandler?.Invoke(this, EventArgs.Empty); + } + } + } +} diff --git a/Filtration.ObjectModel/ThemeEditor/Theme.cs b/Filtration.ObjectModel/ThemeEditor/Theme.cs index a765e30..7d9d3fc 100644 --- a/Filtration.ObjectModel/ThemeEditor/Theme.cs +++ b/Filtration.ObjectModel/ThemeEditor/Theme.cs @@ -39,5 +39,10 @@ namespace Filtration.ObjectModel.ThemeEditor { _components.Add(new IntegerThemeComponent(componentType, componentName, componentValue)); } + + public void AddComponent(ThemeComponentType componentType, string componentName, string componentValue, int componentSecondValue) + { + _components.Add(new StrIntThemeComponent(componentType, componentName, componentValue, componentSecondValue)); + } } } diff --git a/Filtration.ObjectModel/ThemeEditor/ThemeComponentCollection.cs b/Filtration.ObjectModel/ThemeEditor/ThemeComponentCollection.cs index 605a62c..50510e0 100644 --- a/Filtration.ObjectModel/ThemeEditor/ThemeComponentCollection.cs +++ b/Filtration.ObjectModel/ThemeEditor/ThemeComponentCollection.cs @@ -35,6 +35,19 @@ namespace Filtration.ObjectModel.ThemeEditor return component; } + public ThemeComponent AddComponent(ThemeComponentType componentType, string componentName, string componentValue, int componentSecondValue) + { + if (ComponentExists(componentType, componentName)) + { + return Items.FirstOrDefault(t => t.ComponentName == componentName && t.ComponentType == componentType); + } + + var component = new StrIntThemeComponent(componentType, componentName, componentValue, componentSecondValue); + Items.Add(component); + + return component; + } + private bool ComponentExists(ThemeComponentType componentType, string componentName) { var componentCount = diff --git a/Filtration.Parser/Services/ItemFilterBlockTranslator.cs b/Filtration.Parser/Services/ItemFilterBlockTranslator.cs index fb1d755..ee1ff18 100644 --- a/Filtration.Parser/Services/ItemFilterBlockTranslator.cs +++ b/Filtration.Parser/Services/ItemFilterBlockTranslator.cs @@ -236,7 +236,7 @@ namespace Filtration.Parser.Services RemoveExistingBlockItemsOfType(block); RemoveExistingBlockItemsOfType(block); - var match = Regex.Match(trimmedLine, @"\S+\s+(\S+)\s?(\d+)?"); + var match = Regex.Match(trimmedLine, @"\S+\s+(\S+)\s?(\d+)?\s*([#]?)(.*)"); if (match.Success) { @@ -250,6 +250,12 @@ namespace Filtration.Parser.Services else { secondValue = 79; + } + + ThemeComponent themeComponent = null; + if(match.Groups[3].Value == "#" && !string.IsNullOrWhiteSpace(match.Groups[4].Value)) + { + themeComponent = _masterComponentCollection.AddComponent(ThemeComponentType.AlertSound, match.Groups[4].Value.Trim(), firstValue, secondValue); } if (lineOption == "PlayAlertSound") @@ -259,6 +265,7 @@ namespace Filtration.Parser.Services Value = firstValue, SecondValue = secondValue }; + blockItemValue.ThemeComponent = themeComponent; block.BlockItems.Add(blockItemValue); } else @@ -268,6 +275,7 @@ namespace Filtration.Parser.Services Value = firstValue, SecondValue = secondValue }; + blockItemValue.ThemeComponent = themeComponent; block.BlockItems.Add(blockItemValue); } } diff --git a/Filtration.ThemeEditor/Converters/ThemeComponentTypeToStringConverter.cs b/Filtration.ThemeEditor/Converters/ThemeComponentTypeToStringConverter.cs index 2ae7c2d..a3fe4f4 100644 --- a/Filtration.ThemeEditor/Converters/ThemeComponentTypeToStringConverter.cs +++ b/Filtration.ThemeEditor/Converters/ThemeComponentTypeToStringConverter.cs @@ -35,6 +35,10 @@ namespace Filtration.ThemeEditor.Converters { return "Font Size Theme Components"; } + case "Alert Sound": + { + return "Alert Sound Theme Components"; + } } return type.GetAttributeDescription(); diff --git a/Filtration.ThemeEditor/Filtration.ThemeEditor.csproj b/Filtration.ThemeEditor/Filtration.ThemeEditor.csproj index d64952d..8644cd7 100644 --- a/Filtration.ThemeEditor/Filtration.ThemeEditor.csproj +++ b/Filtration.ThemeEditor/Filtration.ThemeEditor.csproj @@ -109,6 +109,7 @@ + diff --git a/Filtration.ThemeEditor/Providers/ThemeProvider.cs b/Filtration.ThemeEditor/Providers/ThemeProvider.cs index 2c9bec3..4e8fe20 100644 --- a/Filtration.ThemeEditor/Providers/ThemeProvider.cs +++ b/Filtration.ThemeEditor/Providers/ThemeProvider.cs @@ -45,6 +45,9 @@ namespace Filtration.ThemeEditor.Providers case ThemeComponentType.FontSize: c.Add(new IntegerThemeComponent(component.ComponentType, component.ComponentName, ((IntegerThemeComponent)component).Value)); break; + case ThemeComponentType.AlertSound: + c.Add(new StrIntThemeComponent(component.ComponentType, component.ComponentName, ((StrIntThemeComponent)component).Value, ((StrIntThemeComponent)component).SecondValue)); + break; } return c; }); diff --git a/Filtration.ThemeEditor/Services/ThemeService.cs b/Filtration.ThemeEditor/Services/ThemeService.cs index 2885dd0..392abcd 100644 --- a/Filtration.ThemeEditor/Services/ThemeService.cs +++ b/Filtration.ThemeEditor/Services/ThemeService.cs @@ -45,6 +45,10 @@ namespace Filtration.ThemeEditor.Services case ThemeComponentType.FontSize: mismatchedComponents = ApplyIntegerTheme(blocks, typeof(FontSizeBlockItem), component); break; + case ThemeComponentType.AlertSound: + mismatchedComponents = ApplyStrIntTheme(blocks, typeof(SoundBlockItem), component); + mismatchedComponents = ApplyStrIntTheme(blocks, typeof(PositionalSoundBlockItem), component); + break; } } @@ -95,5 +99,26 @@ namespace Filtration.ThemeEditor.Services return !componentMatched; } + + private bool ApplyStrIntTheme(IEnumerable blocks, Type type, ThemeComponent component) + { + var componentMatched = false; + foreach (var block in blocks) + { + foreach (var blockItem in block.BlockItems.Where(i => i.GetType() == type)) + { + var colorBlockItem = (StrIntBlockItem)blockItem; + if (colorBlockItem.ThemeComponent != null && + colorBlockItem.ThemeComponent.ComponentName == component.ComponentName) + { + colorBlockItem.Value = ((StrIntThemeComponent)component).Value; + colorBlockItem.SecondValue = ((StrIntThemeComponent)component).SecondValue; + componentMatched = true; + } + } + } + + return !componentMatched; + } } } diff --git a/Filtration.ThemeEditor/ViewModels/StrIntThemeComponentViewModel.cs b/Filtration.ThemeEditor/ViewModels/StrIntThemeComponentViewModel.cs new file mode 100644 index 0000000..a1bfe6d --- /dev/null +++ b/Filtration.ThemeEditor/ViewModels/StrIntThemeComponentViewModel.cs @@ -0,0 +1,8 @@ +namespace Filtration.ThemeEditor.ViewModels +{ + public class StrIntThemeComponentViewModel : ThemeComponentViewModel + { + public int Value { get; set; } + public int SecondValue { get; set; } + } +} diff --git a/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs b/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs index b342082..18e5657 100644 --- a/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs +++ b/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs @@ -205,6 +205,9 @@ namespace Filtration.ThemeEditor.ViewModels case ThemeComponentType.FontSize: Components.Add(new IntegerThemeComponent(themeComponentType, "Untitled Component", 35)); break; + case ThemeComponentType.AlertSound: + Components.Add(new StrIntThemeComponent(themeComponentType, "Untitled Component", "1", 100)); + break; } } diff --git a/Filtration.ThemeEditor/Views/ThemeComponentControl.xaml b/Filtration.ThemeEditor/Views/ThemeComponentControl.xaml index 231561b..0065087 100644 --- a/Filtration.ThemeEditor/Views/ThemeComponentControl.xaml +++ b/Filtration.ThemeEditor/Views/ThemeComponentControl.xaml @@ -69,6 +69,18 @@ + + + + + + + + + + + + diff --git a/Filtration/App.xaml.cs b/Filtration/App.xaml.cs index 192f000..e5cb90a 100644 --- a/Filtration/App.xaml.cs +++ b/Filtration/App.xaml.cs @@ -48,6 +48,7 @@ namespace Filtration cfg.CreateMap().ReverseMap(); cfg.CreateMap().ReverseMap(); cfg.CreateMap().ReverseMap(); + cfg.CreateMap().ReverseMap(); cfg.CreateMap(); }); diff --git a/Filtration/Converters/AvailableThemeComponentsConverter.cs b/Filtration/Converters/AvailableThemeComponentsConverter.cs index 33a1a2b..537ba56 100644 --- a/Filtration/Converters/AvailableThemeComponentsConverter.cs +++ b/Filtration/Converters/AvailableThemeComponentsConverter.cs @@ -37,6 +37,10 @@ namespace Filtration.Converters { themeComponentType = ThemeComponentType.FontSize; } + else if (blockItem.GetType() == typeof(SoundBlockItem) || blockItem.GetType() == typeof(PositionalSoundBlockItem)) + { + themeComponentType = ThemeComponentType.AlertSound; + } else { return null; diff --git a/Filtration/UserControls/BlockItemControl.xaml b/Filtration/UserControls/BlockItemControl.xaml index abf7363..606e780 100644 --- a/Filtration/UserControls/BlockItemControl.xaml +++ b/Filtration/UserControls/BlockItemControl.xaml @@ -141,6 +141,14 @@ + + + + + + + + @@ -152,6 +160,14 @@ + + + + + + + + diff --git a/Filtration/UserControls/BlockItemControl.xaml.cs b/Filtration/UserControls/BlockItemControl.xaml.cs index e312c3d..bb90bd1 100644 --- a/Filtration/UserControls/BlockItemControl.xaml.cs +++ b/Filtration/UserControls/BlockItemControl.xaml.cs @@ -112,6 +112,11 @@ namespace Filtration.UserControls var integerBlockItem = BlockItem as IntegerBlockItem; integerBlockItem.Value = ((IntegerThemeComponent)integerBlockItem.ThemeComponent).Value; break; + case ThemeComponentType.AlertSound: + var strIntBlockItem = BlockItem as StrIntBlockItem; + strIntBlockItem.Value = ((StrIntThemeComponent)strIntBlockItem.ThemeComponent).Value; + strIntBlockItem.SecondValue = ((StrIntThemeComponent)strIntBlockItem.ThemeComponent).SecondValue; + break; } } diff --git a/Filtration/UserControls/ThemeComponentSelectionControl.xaml b/Filtration/UserControls/ThemeComponentSelectionControl.xaml index 97ac25b..862390f 100644 --- a/Filtration/UserControls/ThemeComponentSelectionControl.xaml +++ b/Filtration/UserControls/ThemeComponentSelectionControl.xaml @@ -55,9 +55,14 @@ + + + + + diff --git a/Filtration/ViewModels/MainWindowViewModel.cs b/Filtration/ViewModels/MainWindowViewModel.cs index 168f006..6e4fcce 100644 --- a/Filtration/ViewModels/MainWindowViewModel.cs +++ b/Filtration/ViewModels/MainWindowViewModel.cs @@ -115,6 +115,7 @@ namespace Filtration.ViewModels AddBackgroundColorThemeComponentCommand = new RelayCommand(OnAddBackgroundColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); AddBorderColorThemeComponentCommand = new RelayCommand(OnAddBorderColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); AddFontSizeThemeComponentCommand = new RelayCommand(OnAddFontSizeThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); + AddAlertSoundThemeComponentCommand = new RelayCommand(OnAddAlertSoundThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); DeleteThemeComponentCommand = new RelayCommand(OnDeleteThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable && _avalonDockWorkspaceViewModel.ActiveThemeViewModel.SelectedThemeComponent != null); ExpandAllBlocksCommand = new RelayCommand(OnExpandAllBlocksCommand, () => ActiveDocumentIsScript); @@ -215,6 +216,7 @@ namespace Filtration.ViewModels public RelayCommand AddBackgroundColorThemeComponentCommand { get; } public RelayCommand AddBorderColorThemeComponentCommand { get; } public RelayCommand AddFontSizeThemeComponentCommand { get; } + public RelayCommand AddAlertSoundThemeComponentCommand { get; } public RelayCommand DeleteThemeComponentCommand { get; } public RelayCommand AddBlockCommand { get; } @@ -684,6 +686,11 @@ namespace Filtration.ViewModels _avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.FontSize); } + private void OnAddAlertSoundThemeComponentCommand() + { + _avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.AlertSound); + } + private void OnDeleteThemeComponentCommand() { _avalonDockWorkspaceViewModel.ActiveThemeViewModel.DeleteThemeComponentCommand.Execute( diff --git a/Filtration/Views/MainWindow.xaml b/Filtration/Views/MainWindow.xaml index 2fd013b..ed97dc0 100644 --- a/Filtration/Views/MainWindow.xaml +++ b/Filtration/Views/MainWindow.xaml @@ -130,6 +130,7 @@ +