diff --git a/Tests/ViewModels/SettingsViewModelTest.cs b/Tests/ViewModels/SettingsViewModelTest.cs index 0fbd160..0ea9ad9 100755 --- a/Tests/ViewModels/SettingsViewModelTest.cs +++ b/Tests/ViewModels/SettingsViewModelTest.cs @@ -156,7 +156,33 @@ namespace Tests.ViewModels [Test] public void CopyElement() { - throw new NotImplementedException(); + string testString = "this text should be duplicated"; + _settingsVM.AddElementViewModel( + new ControlElementViewModel(new SelectEachDay(new Items(testString)))); + int oldCount = _settingsVM.Elements.Count; + _settingsVM.Elements.First().IsSelected = true; + Assert.IsTrue(_settingsVM.CopyElementCommand.CanExecute(null), + "CopyElementCommand should be enabled."); + _settingsVM.CopyElementCommand.Execute(null); + Assert.AreEqual(oldCount + 1, _settingsVM.Elements.Count); + + // Access the first element + ControlElementViewModel controlVM = _settingsVM.Elements.First() as ControlElementViewModel; + FormatElementViewModel formatVM = controlVM.Elements.First() as FormatElementViewModel; + Items items = formatVM.RevealModelObject() as Items; + Assert.IsNotNull(items, + "Child ViewModel of first ControlElementViewModel does not wrap Items object."); + Assert.AreEqual(testString, items.Content, + "First control element's child element has incorrect Content string."); + + // Access the second element + controlVM = _settingsVM.Elements.Last() as ControlElementViewModel; + formatVM = controlVM.Elements.First() as FormatElementViewModel; + items = formatVM.RevealModelObject() as Items; + Assert.IsNotNull(items, + "Child ViewModel of last ControlElementViewModel does not wrap Items object."); + Assert.AreEqual(testString, items.Content, + "First control element's child element has incorrect Content string."); } } } diff --git a/zaaReloaded2/ViewModels/ControlElementViewModel.cs b/zaaReloaded2/ViewModels/ControlElementViewModel.cs index ada4589..88b3969 100755 --- a/zaaReloaded2/ViewModels/ControlElementViewModel.cs +++ b/zaaReloaded2/ViewModels/ControlElementViewModel.cs @@ -81,5 +81,18 @@ namespace zaaReloaded2.ViewModels } #endregion + + public override object Clone() + { + ControlElementViewModel clone = new ControlElementViewModel(); + clone.Element = Element; + clone.Elements = new ObservableCollection( + Elements.Select(evm => evm.Clone() as ElementViewModel)); + foreach (FormatElementViewModel evm in clone.Elements) + { + evm.Parent = clone; + } + return clone; + } } } diff --git a/zaaReloaded2/ViewModels/ElementViewModel.cs b/zaaReloaded2/ViewModels/ElementViewModel.cs index a14a865..add2138 100755 --- a/zaaReloaded2/ViewModels/ElementViewModel.cs +++ b/zaaReloaded2/ViewModels/ElementViewModel.cs @@ -26,7 +26,7 @@ using System.Collections.ObjectModel; namespace zaaReloaded2.ViewModels { - public abstract class ElementViewModel : ViewModelBase + public abstract class ElementViewModel : ViewModelBase, ICloneable { #region Properties @@ -69,5 +69,11 @@ namespace zaaReloaded2.ViewModels } #endregion + + #region Implementation of ICloneable + + public abstract object Clone(); + + #endregion } } diff --git a/zaaReloaded2/ViewModels/FormatElementViewModel.cs b/zaaReloaded2/ViewModels/FormatElementViewModel.cs index 27e491e..21483f2 100755 --- a/zaaReloaded2/ViewModels/FormatElementViewModel.cs +++ b/zaaReloaded2/ViewModels/FormatElementViewModel.cs @@ -58,5 +58,13 @@ namespace zaaReloaded2.ViewModels } #endregion + + public override object Clone() + { + FormatElementViewModel clone = new FormatElementViewModel(); + clone.Parent = Parent; + clone.Element = Element; + return clone; + } } } diff --git a/zaaReloaded2/ViewModels/SettingsViewModel.cs b/zaaReloaded2/ViewModels/SettingsViewModel.cs index 927d04d..8eb178c 100755 --- a/zaaReloaded2/ViewModels/SettingsViewModel.cs +++ b/zaaReloaded2/ViewModels/SettingsViewModel.cs @@ -314,8 +314,7 @@ namespace zaaReloaded2.ViewModels { if (CanDeleteElement()) { - if (LastSelectedElement is ControlElementViewModel || - ((FormatElementViewModel)LastSelectedElement).Parent == null) + if (IsTopLevelElement()) { // First level of the hierarchy Elements.Remove(LastSelectedElement); @@ -335,7 +334,21 @@ namespace zaaReloaded2.ViewModels bool CanDeleteElement() { return LastSelectedElement != null && LastSelectedElement.IsSelected; } - void DoCopyElement() { } + void DoCopyElement() + { + if (CanCopyElement()) + { + if (IsTopLevelElement()) + { + AddElementViewModel(LastSelectedElement.Clone() as ElementViewModel); + } + else + { + FormatElementViewModel formatVM = LastSelectedElement as FormatElementViewModel; + formatVM.Parent.AddChildElement(formatVM.Clone() as FormatElementViewModel); + } + } + } bool CanCopyElement() { return LastSelectedElement != null && LastSelectedElement.IsSelected; } @@ -355,6 +368,16 @@ namespace zaaReloaded2.ViewModels } } + /// + /// Returns true if the selected ElementViewModel is at the top + /// level of the hierarchy. + /// + bool IsTopLevelElement() + { + return (LastSelectedElement is ControlElementViewModel || + ((FormatElementViewModel)LastSelectedElement).Parent == null); + } + #endregion #region Implementation of ViewModelBase