32d4e8d955
- NEU: Überschriften und pathologische Werte werden fett gedruckt. - FIX: Kleinere Bugfixes.
756 lines
30 KiB
C#
Executable File
756 lines
30 KiB
C#
Executable File
/* SettingsViewModel.cs
|
|
* part of zaaReloaded2
|
|
*
|
|
* Copyright 2015 Daniel Kraus
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Bovender.Mvvm;
|
|
using Bovender.Mvvm.ViewModels;
|
|
using Bovender.Mvvm.Messaging;
|
|
using zaaReloaded2.Controller;
|
|
using zaaReloaded2.Controller.Elements;
|
|
using zaaReloaded2.Formatter;
|
|
using System.Collections.ObjectModel;
|
|
|
|
namespace zaaReloaded2.ViewModels
|
|
{
|
|
/// <summary>
|
|
/// View model for the zaaReloaded2.Controller.Settings class.
|
|
/// </summary>
|
|
public class SettingsViewModel : ViewModelBase, ICloneable
|
|
{
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name of the Settings
|
|
/// </summary>
|
|
public string Name
|
|
{
|
|
[DebuggerStepThrough]
|
|
get
|
|
{
|
|
return _settings.Name;
|
|
}
|
|
[DebuggerStepThrough]
|
|
set
|
|
{
|
|
_settings.Name = value;
|
|
OnPropertyChanged("Name");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Is true if the settings' name is editable.
|
|
/// If the settings' name is a default, preconfigured name,
|
|
/// this will be false.
|
|
/// </summary>
|
|
public bool IsNameEnabled
|
|
{
|
|
get
|
|
{
|
|
return (Name != Properties.Settings.Default.SettingsNameClinic) &&
|
|
(Name != Properties.Settings.Default.SettingsNameWard);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a list of element view models.
|
|
/// </summary>
|
|
public IList<ElementViewModel> Elements { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the currently selected element.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Due to the way the WPF ListBox (for example) is implemented, selecting
|
|
/// a list item will trigger an PropertyChanged event twice: Once for the
|
|
/// item being selected, and once for the item being deselected. Thus we
|
|
/// can only capture the last item that actually was selected. We cannot
|
|
/// howeve capture if an item was deselected without a new selection,
|
|
/// because we cannot logicaly connect two occurrences of the same event
|
|
/// from different objects.
|
|
/// </remarks>
|
|
public ElementViewModel LastSelectedElement
|
|
{
|
|
get { return _selectedElement; }
|
|
set
|
|
{
|
|
_selectedElement = value;
|
|
OnPropertyChanged("SelectedElement");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns an EnumProvider object for the ReferenceStyle
|
|
/// </summary>
|
|
public EnumProvider<ReferenceStyle> ReferenceStyle
|
|
{
|
|
get
|
|
{
|
|
if (_referenceStyle == null)
|
|
{
|
|
_referenceStyle = new EnumProvider<ReferenceStyle>();
|
|
_referenceStyle.AsEnum = _settings.ReferenceStyle;
|
|
_referenceStyle.PropertyChanged += (sender, args) =>
|
|
{
|
|
_settings.ReferenceStyle = _referenceStyle.AsEnum;
|
|
};
|
|
}
|
|
return _referenceStyle;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Constructors
|
|
|
|
public SettingsViewModel()
|
|
: this(new Settings())
|
|
{ }
|
|
|
|
public SettingsViewModel(Settings settings)
|
|
: base()
|
|
{
|
|
_settings = settings;
|
|
Elements = new ObservableCollection<ElementViewModel>();
|
|
foreach (ElementBase element in settings.Elements)
|
|
{
|
|
ElementViewModel vm;
|
|
if (element is FormatElementBase)
|
|
{
|
|
vm = new FormatElementViewModel(element as FormatElementBase);
|
|
}
|
|
else if (element is ControlElementBase)
|
|
{
|
|
vm = new ControlElementViewModel(element as ControlElementBase);
|
|
foreach (FormatElementViewModel childVM in ((ControlElementViewModel)vm).Elements)
|
|
{
|
|
childVM.Parent = vm as ControlElementViewModel;
|
|
childVM.PropertyChanged += ElementViewModel_PropertyChanged;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException(
|
|
"Cannot create ViewModel for " + element.GetType().ToString());
|
|
}
|
|
vm.PropertyChanged += ElementViewModel_PropertyChanged;
|
|
Elements.Add(vm);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Messages
|
|
|
|
public Message<ViewModelMessageContent> AddElementMessage
|
|
{
|
|
get
|
|
{
|
|
if (_addElementMessage == null)
|
|
{
|
|
_addElementMessage = new Message<ViewModelMessageContent>();
|
|
}
|
|
return _addElementMessage;
|
|
}
|
|
}
|
|
|
|
public Message<ViewModelMessageContent> AddChildElementMessage
|
|
{
|
|
get
|
|
{
|
|
if (_addChildElementMessage == null)
|
|
{
|
|
_addChildElementMessage = new Message<ViewModelMessageContent>();
|
|
}
|
|
return _addChildElementMessage;
|
|
}
|
|
}
|
|
|
|
public Message<ViewModelMessageContent> EditElementMessage
|
|
{
|
|
get
|
|
{
|
|
if (_editElementMessage == null)
|
|
{
|
|
_editElementMessage = new Message<ViewModelMessageContent>();
|
|
}
|
|
return _editElementMessage;
|
|
}
|
|
}
|
|
|
|
public Message<ViewModelMessageContent> ChangeControlElementMessage
|
|
{
|
|
get
|
|
{
|
|
if (_changeControlElementMessage == null)
|
|
{
|
|
_changeControlElementMessage = new Message<ViewModelMessageContent>();
|
|
}
|
|
return _changeControlElementMessage;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Commands
|
|
|
|
public DelegatingCommand AddElementCommand
|
|
{
|
|
get
|
|
{
|
|
if (_addElementCommand == null)
|
|
{
|
|
_addElementCommand = new DelegatingCommand(
|
|
param => DoAddElement());
|
|
}
|
|
return _addElementCommand;
|
|
}
|
|
}
|
|
|
|
public DelegatingCommand AddChildElementCommand
|
|
{
|
|
get
|
|
{
|
|
if (_addChildElementCommand == null)
|
|
{
|
|
_addChildElementCommand = new DelegatingCommand(
|
|
param => DoAddChildElement(),
|
|
param => CanAddChildElement());
|
|
}
|
|
return _addChildElementCommand;
|
|
}
|
|
}
|
|
|
|
public DelegatingCommand EditElementCommand
|
|
{
|
|
get
|
|
{
|
|
if (_editElementCommand == null)
|
|
{
|
|
_editElementCommand = new DelegatingCommand(
|
|
param => DoEditElement(),
|
|
param => CanEditElement());
|
|
}
|
|
return _editElementCommand;
|
|
}
|
|
}
|
|
|
|
public DelegatingCommand DeleteElementCommand
|
|
{
|
|
get
|
|
{
|
|
if (_deleteElementCommand == null)
|
|
{
|
|
_deleteElementCommand = new DelegatingCommand(
|
|
param => DoDeleteElement(),
|
|
param => CanDeleteElement());
|
|
}
|
|
return _deleteElementCommand;
|
|
}
|
|
}
|
|
|
|
public DelegatingCommand CopyElementCommand
|
|
{
|
|
get
|
|
{
|
|
if (_copyElementCommand == null)
|
|
{
|
|
_copyElementCommand = new DelegatingCommand(
|
|
param => DoCopyElement(),
|
|
param => CanCopyElement());
|
|
}
|
|
return _copyElementCommand;
|
|
}
|
|
}
|
|
|
|
public DelegatingCommand MoveElementUpCommand
|
|
{
|
|
get
|
|
{
|
|
if (_moveElementUpCommand == null)
|
|
{
|
|
_moveElementUpCommand = new DelegatingCommand(
|
|
param => DoMoveElementUp(),
|
|
param => CanMoveElementUp());
|
|
}
|
|
return _moveElementUpCommand;
|
|
}
|
|
}
|
|
|
|
public DelegatingCommand MoveElementDownCommand
|
|
{
|
|
get
|
|
{
|
|
if (_moveElementDownCommand == null)
|
|
{
|
|
_moveElementDownCommand = new DelegatingCommand(
|
|
param => DoMoveElementDown(),
|
|
param => CanMoveElementDown());
|
|
}
|
|
return _moveElementDownCommand;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public methods
|
|
|
|
/// <summary>
|
|
/// Wires the OnProperty changed event of an ElementViewModel's
|
|
/// wrapped model and adds the view model to the Elements collection.
|
|
/// </summary>
|
|
public void AddElementViewModel(ElementViewModel elementViewModel)
|
|
{
|
|
elementViewModel.PropertyChanged += ElementViewModel_PropertyChanged;
|
|
Elements.Add(elementViewModel);
|
|
_settings.Elements.Add(elementViewModel.RevealModelObject() as ElementBase);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Wires the OnProperty changed event of an ElementViewModel's
|
|
/// wrapped model and adds the view model as a child of another
|
|
/// view model.
|
|
/// </summary>
|
|
public void AddChildElementViewModel(ControlElementViewModel parent, FormatElementViewModel child)
|
|
{
|
|
child.PropertyChanged += ElementViewModel_PropertyChanged;
|
|
parent.AddChildElement(child);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private methods
|
|
|
|
void DoAddElement()
|
|
{
|
|
// Create a new element picker; it will automatically create and
|
|
// send us a new element view model if one is chosen by the view.
|
|
ElementPickerViewModel picker = new ElementPickerViewModel(
|
|
allowControlElements: IsTopLevelElement());
|
|
picker.ElementChosenMessage.Sent += (sender, args) =>
|
|
{
|
|
ElementViewModel newVM = args.Content.ViewModel as ElementViewModel;
|
|
if (LastSelectedElement == null || IsTopLevelElement())
|
|
{
|
|
AddElementViewModel(newVM);
|
|
}
|
|
else
|
|
{
|
|
// If the selected element is on the second level, it
|
|
// must be a FormatElementViewModel.
|
|
ControlElementViewModel parent = ((FormatElementViewModel)LastSelectedElement).Parent;
|
|
AddChildElementViewModel(parent, newVM as FormatElementViewModel);
|
|
}
|
|
newVM.IsSelected = true;
|
|
if (newVM is FormatElementViewModel) DoEditElement();
|
|
};
|
|
AddElementMessage.Send(new ViewModelMessageContent(picker));
|
|
}
|
|
|
|
void DoAddChildElement()
|
|
{
|
|
if (CanAddChildElement())
|
|
{
|
|
// Create a new element picker; it will automatically create and
|
|
// send us a new element view model if one is chosen by the view.
|
|
ElementPickerViewModel picker = new ElementPickerViewModel(false);
|
|
picker.ElementChosenMessage.Sent += (sender, args) =>
|
|
{
|
|
FormatElementViewModel newVM = args.Content.ViewModel as FormatElementViewModel;
|
|
AddChildElementViewModel(LastSelectedElement as ControlElementViewModel, newVM);
|
|
newVM.IsSelected = true;
|
|
DoEditElement();
|
|
};
|
|
AddChildElementMessage.Send(new ViewModelMessageContent(picker));
|
|
}
|
|
}
|
|
|
|
bool CanAddChildElement()
|
|
{
|
|
return LastSelectedElement is ControlElementViewModel &&
|
|
((ControlElementViewModel)LastSelectedElement).CanHaveChildren;
|
|
}
|
|
|
|
void DoEditElement()
|
|
{
|
|
if (CanEditElement())
|
|
{
|
|
if (LastSelectedElement is ControlElementViewModel)
|
|
{
|
|
ElementPickerViewModel picker = new ElementPickerViewModel(
|
|
LastSelectedElement as ControlElementViewModel);
|
|
picker.ElementChosenMessage.Sent += (sender, args) =>
|
|
{
|
|
// Replace the previously selected element with the new
|
|
// one that we get from the ElementPickerViewModel.
|
|
int index = Elements.IndexOf(LastSelectedElement);
|
|
ElementViewModel newVM = args.Content.ViewModel as ElementViewModel;
|
|
ControlElementBase oldModel = LastSelectedElement.RevealModelObject() as ControlElementBase;
|
|
ControlElementBase newModel = newVM.RevealModelObject() as ControlElementBase;
|
|
// Caveat: once we modify the Elements collection, LastSelectedElement will change!
|
|
Elements.RemoveAt(index);
|
|
Elements.Insert(index, newVM);
|
|
newModel.Children = oldModel.Children;
|
|
_settings.Elements.RemoveAt(index);
|
|
_settings.Elements.Insert(index, newModel);
|
|
newVM.PropertyChanged += ElementViewModel_PropertyChanged;
|
|
newVM.IsSelected = true;
|
|
};
|
|
ChangeControlElementMessage.Send(
|
|
new ViewModelMessageContent(picker));
|
|
}
|
|
else
|
|
{
|
|
EditElementMessage.Send(new ViewModelMessageContent(LastSelectedElement));
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CanEditElement()
|
|
{
|
|
return LastSelectedElement != null && LastSelectedElement.IsSelected;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes the selected element.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The following algorithm ist used to find out whether the selected
|
|
/// element is at the first or the second level of the hierarchy:
|
|
/// If the Element is a ControlElement, it must be at the first level.
|
|
/// If the Element is a FormatElement, its Parent property will be
|
|
/// Null if the Element is at the first level.
|
|
/// </remarks>
|
|
void DoDeleteElement()
|
|
{
|
|
if (CanDeleteElement())
|
|
{
|
|
if (IsTopLevelElement())
|
|
{
|
|
// First level of the hierarchy
|
|
int index = Elements.IndexOf(LastSelectedElement);
|
|
Elements.RemoveAt(index);
|
|
_settings.Elements.RemoveAt(index);
|
|
if (index == Elements.Count) index--;
|
|
LastSelectedElement = null;
|
|
if (Elements.Count > 0) Elements[index].IsSelected = true;
|
|
}
|
|
else
|
|
{
|
|
// Second level of the hierarchy
|
|
FormatElementViewModel formatVM = LastSelectedElement as FormatElementViewModel;
|
|
ControlElementViewModel parent = formatVM.Parent;
|
|
int index = parent.Elements.IndexOf(formatVM);
|
|
parent.RemoveChildElement(formatVM);
|
|
if (index == parent.Elements.Count) index--;
|
|
LastSelectedElement = null;
|
|
if (parent.Elements.Count > 0) parent.Elements[index].IsSelected = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CanDeleteElement() { return LastSelectedElement != null && LastSelectedElement.IsSelected; }
|
|
|
|
void DoCopyElement()
|
|
{
|
|
if (CanCopyElement())
|
|
{
|
|
if (IsTopLevelElement())
|
|
{
|
|
ElementViewModel newControlVM = LastSelectedElement.Clone() as ElementViewModel;
|
|
AddElementViewModel(newControlVM);
|
|
newControlVM.IsSelected = true;
|
|
}
|
|
else
|
|
{
|
|
FormatElementViewModel originalVM = LastSelectedElement as FormatElementViewModel;
|
|
FormatElementViewModel newFormatVM = originalVM.Clone() as FormatElementViewModel;
|
|
originalVM.Parent.AddChildElement(newFormatVM);
|
|
newFormatVM.IsSelected = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CanCopyElement() { return LastSelectedElement != null && LastSelectedElement.IsSelected; }
|
|
|
|
void DoMoveElementUp()
|
|
{
|
|
if (CanMoveElementUp())
|
|
{
|
|
// We need to get a hold of the LastSelectedElement because a TreeView
|
|
// might reset the selection when we move elements around.
|
|
ElementViewModel lastSelectedElement = LastSelectedElement;
|
|
// Top-level elements are either control elements or format elements;
|
|
// child elements on the second level however are always format elements
|
|
// and must be treated differently.
|
|
if (IsTopLevelElement())
|
|
{
|
|
int index = Elements.IndexOf(lastSelectedElement);
|
|
if (lastSelectedElement is ControlElementViewModel ||
|
|
Elements[index - 1] is FormatElementViewModel ||
|
|
!((ControlElementViewModel)Elements[index - 1]).CanHaveChildren
|
|
)
|
|
{
|
|
// Simple case: top-level control element -- just move it up;
|
|
// if the selected element is a format element and the element
|
|
// above it is a format element too, just move it up as well.
|
|
// If the element above the selected element is a control element,
|
|
// but cannot have children, move the selected element up as well.
|
|
Elements.RemoveAt(index);
|
|
Elements.Insert(index - 1, lastSelectedElement);
|
|
_settings.Elements.RemoveAt(index);
|
|
_settings.Elements.Insert(
|
|
index - 1,
|
|
lastSelectedElement.RevealModelObject() as ElementBase);
|
|
}
|
|
else
|
|
{
|
|
// If we get here, the selected element is a format element
|
|
// and the element above it is a control element that can
|
|
// have child elements, i.e. the selected element is demoted
|
|
// to a child element of the control element above it.
|
|
ControlElementViewModel controlElementAbove =
|
|
Elements[index - 1] as ControlElementViewModel;
|
|
Elements.RemoveAt(index);
|
|
controlElementAbove.IsExpanded = true;
|
|
controlElementAbove.AddChildElement(
|
|
lastSelectedElement as FormatElementViewModel);
|
|
FormatElementBase model = lastSelectedElement.RevealModelObject() as FormatElementBase;
|
|
ControlElementBase modelAbove = _settings.Elements[index - 1] as ControlElementBase;
|
|
_settings.Elements.RemoveAt(index);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// The selected element is a child element.
|
|
// If it is at the top of the child elements list, promote it
|
|
// to a top-level element; if not, just move it up in the
|
|
// child elements list.
|
|
FormatElementViewModel selected = lastSelectedElement as FormatElementViewModel;
|
|
int index = selected.Parent.Elements.IndexOf(selected);
|
|
if (index == 0)
|
|
{
|
|
// Promote the element from the top of the children list
|
|
// to a top-level element above its parent.
|
|
int parentIndex = Elements.IndexOf(selected.Parent);
|
|
selected.Parent.Elements.RemoveAt(0);
|
|
Elements.Insert(parentIndex, selected);
|
|
FormatElementBase model = selected.RevealModelObject() as FormatElementBase;
|
|
ControlElementBase parentModel = selected.Parent.RevealModelObject() as ControlElementBase;
|
|
parentModel.Children.RemoveAt(0);
|
|
_settings.Elements.Insert(parentIndex, model);
|
|
selected.Parent = null;
|
|
}
|
|
else
|
|
{
|
|
selected.Parent.Elements.Move(index, index - 1);
|
|
ControlElementBase parentModel = selected.Parent.RevealModelObject() as ControlElementBase;
|
|
FormatElementBase selectedModel = parentModel.Children[index];
|
|
parentModel.Children.RemoveAt(index);
|
|
parentModel.Children.Insert(index - 1, selectedModel);
|
|
}
|
|
}
|
|
// Select the last selected element again.
|
|
lastSelectedElement.IsSelected = true;
|
|
}
|
|
}
|
|
|
|
bool CanMoveElementUp()
|
|
{
|
|
if (IsTopLevelElement())
|
|
{
|
|
return Elements.IndexOf(LastSelectedElement) > 0;
|
|
}
|
|
else
|
|
{
|
|
// If the selected element is a child element, it can always be moved
|
|
// up before the parent element.
|
|
return LastSelectedElement != null && LastSelectedElement.IsSelected;
|
|
}
|
|
}
|
|
|
|
void DoMoveElementDown()
|
|
{
|
|
if (CanMoveElementDown())
|
|
{
|
|
// We need to get a hold of the LastSelectedElement because a TreeView
|
|
// might reset the selection when we move elements around.
|
|
ElementViewModel lastSelectedElement = LastSelectedElement;
|
|
// Top-level elements are either control elements or format elements;
|
|
// child elements on the second level however are always format elements
|
|
// and must be treated differently.
|
|
if (IsTopLevelElement())
|
|
{
|
|
int index = Elements.IndexOf(lastSelectedElement);
|
|
if (lastSelectedElement is ControlElementViewModel ||
|
|
Elements[index + 1 ] is FormatElementViewModel ||
|
|
!((ControlElementViewModel)Elements[index + 1]).CanHaveChildren
|
|
)
|
|
{
|
|
// Simple case: top-level control element -- just move it down;
|
|
// if the selected element is a format element and the element
|
|
// below it is a format element too, just move it down as well.
|
|
// If the element below the selected element is a control element,
|
|
// but cannot have children, move the selected element down as well.
|
|
Elements.RemoveAt(index);
|
|
Elements.Insert(index + 1, lastSelectedElement);
|
|
_settings.Elements.RemoveAt(index);
|
|
_settings.Elements.Insert(
|
|
index + 1,
|
|
lastSelectedElement.RevealModelObject() as ElementBase);
|
|
}
|
|
else
|
|
{
|
|
// If we get here, the selected element is a format element
|
|
// and the element below it is a control element that can
|
|
// have child elements, i.e. the selected element is demoted
|
|
// to a child element of the control element below it.
|
|
ControlElementViewModel controlElementBelow =
|
|
Elements[index + 1] as ControlElementViewModel;
|
|
Elements.RemoveAt(index);
|
|
controlElementBelow.IsExpanded = true;
|
|
controlElementBelow.Elements.Insert(
|
|
0,
|
|
lastSelectedElement as FormatElementViewModel);
|
|
((FormatElementViewModel)lastSelectedElement).Parent = controlElementBelow;
|
|
FormatElementBase model = lastSelectedElement.RevealModelObject() as FormatElementBase;
|
|
ControlElementBase modelBelow = _settings.Elements[index + 1] as ControlElementBase;
|
|
_settings.Elements.RemoveAt(index);
|
|
modelBelow.Children.Insert(0, model);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// The selected element is a child element.
|
|
// If it is at the bottom of the child elements list, promote it
|
|
// to a top-level element; if not, just move it down in the
|
|
// child elements list.
|
|
FormatElementViewModel selected = lastSelectedElement as FormatElementViewModel;
|
|
int index = selected.Parent.Elements.IndexOf(selected);
|
|
if (index == selected.Parent.Elements.Count - 1)
|
|
{
|
|
// Promote the element from the bottom of the children list
|
|
// to a top-level element below its parent.
|
|
int parentIndex = Elements.IndexOf(selected.Parent);
|
|
selected.Parent.Elements.RemoveAt(selected.Parent.Elements.Count - 1);
|
|
Elements.Insert(parentIndex + 1, selected);
|
|
FormatElementBase model = selected.RevealModelObject() as FormatElementBase;
|
|
ControlElementBase parentModel = selected.Parent.RevealModelObject() as ControlElementBase;
|
|
parentModel.Children.RemoveAt(parentModel.Children.Count - 1);
|
|
_settings.Elements.Insert(parentIndex + 1, model);
|
|
selected.Parent = null;
|
|
}
|
|
else
|
|
{
|
|
selected.Parent.Elements.Move(index, index + 1);
|
|
ControlElementBase parentModel = selected.Parent.RevealModelObject() as ControlElementBase;
|
|
FormatElementBase selectedModel = parentModel.Children[index];
|
|
parentModel.Children.RemoveAt(index);
|
|
parentModel.Children.Insert(index + 1, selectedModel);
|
|
}
|
|
}
|
|
// Select the last selected element again.
|
|
lastSelectedElement.IsSelected = true;
|
|
}
|
|
|
|
}
|
|
|
|
bool CanMoveElementDown()
|
|
{
|
|
if (IsTopLevelElement())
|
|
{
|
|
return Elements.IndexOf(LastSelectedElement) < Elements.Count - 1;
|
|
}
|
|
else
|
|
{
|
|
// If the selected element is a child element, it can always be moved
|
|
// down after the parent element.
|
|
return LastSelectedElement != null && LastSelectedElement.IsSelected;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets LastSelectedElement property whenever the IsSelected
|
|
/// property of an ElementViewModel changes
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Please see the remarks on the LastSelectedElement property.
|
|
/// </remarks>
|
|
void ElementViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
|
{
|
|
ElementViewModel vm = sender as ElementViewModel;
|
|
if (vm != null && e.PropertyName == "IsSelected")
|
|
{
|
|
if (vm.IsSelected) LastSelectedElement = vm;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if the selected ElementViewModel is at the top
|
|
/// level of the hierarchy.
|
|
/// </summary>
|
|
bool IsTopLevelElement()
|
|
{
|
|
return LastSelectedElement != null &&
|
|
(LastSelectedElement is ControlElementViewModel ||
|
|
((FormatElementViewModel)LastSelectedElement).Parent == null);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Implementation of ViewModelBase
|
|
|
|
public override object RevealModelObject()
|
|
{
|
|
return _settings;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Implementation of ICloneable
|
|
|
|
public object Clone()
|
|
{
|
|
return new SettingsViewModel(_settings.Clone() as Settings);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Fields
|
|
|
|
Settings _settings;
|
|
DelegatingCommand _addElementCommand;
|
|
DelegatingCommand _addChildElementCommand;
|
|
DelegatingCommand _editElementCommand;
|
|
DelegatingCommand _deleteElementCommand;
|
|
DelegatingCommand _copyElementCommand;
|
|
DelegatingCommand _moveElementUpCommand;
|
|
DelegatingCommand _moveElementDownCommand;
|
|
Message<ViewModelMessageContent> _addElementMessage;
|
|
Message<ViewModelMessageContent> _addChildElementMessage;
|
|
Message<ViewModelMessageContent> _editElementMessage;
|
|
Message<ViewModelMessageContent> _changeControlElementMessage;
|
|
ElementViewModel _selectedElement;
|
|
EnumProvider<ReferenceStyle> _referenceStyle;
|
|
|
|
#endregion
|
|
}
|
|
}
|