init
This commit is contained in:
@@ -0,0 +1,555 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Events;
|
||||
using DTS.Common.Events.ISO;
|
||||
using DTS.Common.Interactivity;
|
||||
using DTS.Common.Interface;
|
||||
using DTS.Common.Interface.ISO.ExtraProperties;
|
||||
using ExtraProperties.Model;
|
||||
using ExtraProperties.Resources;
|
||||
using Prism.Events;
|
||||
using Prism.Regions;
|
||||
using Unity;
|
||||
|
||||
namespace ExtraProperties
|
||||
{
|
||||
[PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class ExtraPropertiesListViewModel : IExtraPropertiesListViewModel
|
||||
{
|
||||
public IExtraPropertiesListView View { get; set; }
|
||||
|
||||
private IEventAggregator _eventAggregator { get; }
|
||||
private IUnityContainer UnityContainer { get; }
|
||||
|
||||
public InteractionRequest<Notification> NotificationRequest { get; }
|
||||
public InteractionRequest<Confirmation> ConfirmationRequest { get; }
|
||||
|
||||
#region constructors and initializers
|
||||
private static bool _bAddListeners = false;
|
||||
/// <summary>
|
||||
/// Creates a new instance of the ExtraPropertiesListViewModel
|
||||
/// </summary>
|
||||
/// <param name="view"></param>
|
||||
/// <param name="regionManager">The logical placeholder defined within the application's UI (in the shell or within views) into which views are displayed.</param>
|
||||
/// <param name="eventAggregator">The EventAggregator which allows different components to publish/subscribe to events without being coupled to each other.</param>
|
||||
/// <param name="unityContainer">The unityContainer.</param>
|
||||
public ExtraPropertiesListViewModel(IExtraPropertiesListView view, IRegionManager regionManager,
|
||||
IEventAggregator eventAggregator, IUnityContainer unityContainer)
|
||||
{
|
||||
View = view;
|
||||
View.DataContext = this;
|
||||
|
||||
NotificationRequest = new InteractionRequest<Notification>();
|
||||
ConfirmationRequest = new InteractionRequest<Confirmation>();
|
||||
|
||||
_eventAggregator = eventAggregator;
|
||||
UnityContainer = unityContainer;
|
||||
_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification);
|
||||
_eventAggregator.GetEvent<BusyIndicatorChangeNotification>()
|
||||
.Subscribe(OnBusyIndicatorNotification, ThreadOption.PublisherThread, true);
|
||||
//this is a hack, the app startup is calling this, then the app itself, we only want the
|
||||
//app itself to be handling the listeners
|
||||
if (_bAddListeners)
|
||||
{
|
||||
_eventAggregator.GetEvent<TextPastedEvent>().Subscribe(OnTextPasted);
|
||||
}
|
||||
_bAddListeners = true;
|
||||
}
|
||||
|
||||
private void OnTextPasted(ITextPastedEventArgs args)
|
||||
{
|
||||
if (args.Id != ExtraPropertyModel.PASTE_ID) { return; }
|
||||
|
||||
if (!(args.Sender is IExtraProperty iep))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Paste(iep, args.Text, args.Tag);
|
||||
var last = ExtraProperties.Last();
|
||||
if (!string.IsNullOrWhiteSpace(last.Key) || !string.IsNullOrWhiteSpace(last.Value))
|
||||
{
|
||||
MarkModified(last);
|
||||
}
|
||||
|
||||
_eventAggregator.GetEvent<PageModifiedEvent>()
|
||||
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
|
||||
}
|
||||
|
||||
private void OnBusyIndicatorNotification(bool eventArg)
|
||||
{
|
||||
IsBusy = eventArg;
|
||||
}
|
||||
|
||||
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
|
||||
{
|
||||
// The NotificationRequest.Raise triggers the Invoke() method of the PopupWindowAction object to show the NotificationWindow window
|
||||
// Notification object expects a NotificationContentEventArgsWithoutTitle object and a Title string.
|
||||
var eventArgsWithoutTitle = new NotificationContentEventArgs(eventArgsWithTitle.Message, "",
|
||||
eventArgsWithTitle.Image, string.Empty);
|
||||
|
||||
NotificationRequest.Raise(new Notification
|
||||
{
|
||||
Content = eventArgsWithoutTitle,
|
||||
Title = eventArgsWithTitle.Title
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Occurs when a property value changes.
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
if ("ExtraProperties" == propertyName)
|
||||
{
|
||||
_eventAggregator.GetEvent<ExtraPropertiesChangedEvent>()
|
||||
.Publish(new ExtraPropertiesChangedEventArgs(AllExtraProperties.Where(exp => !string.IsNullOrEmpty(exp.Key)).ToList(), this, Parent));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPage(IDataPROPage page)
|
||||
{
|
||||
Page = page;
|
||||
}
|
||||
|
||||
public void SetParent(object parent)
|
||||
{
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
public Task CleanupAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
public void Initialize(object parameter)
|
||||
{
|
||||
}
|
||||
|
||||
public void Initialize(object parameter, object model)
|
||||
{
|
||||
}
|
||||
|
||||
public Task InitializeAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task InitializeAsync(object parameter)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Activated()
|
||||
{
|
||||
}
|
||||
|
||||
internal void MarkModified(IExtraProperty iep)
|
||||
{
|
||||
if (ExtraProperties.ToList().Last() == iep)
|
||||
{
|
||||
var newXP = new ExtraPropertyModel();
|
||||
ExtraProperties.Add(newXP);
|
||||
AllExtraProperties.Add(newXP);
|
||||
}
|
||||
OnPropertyChanged("ExtraProperties");
|
||||
_eventAggregator.GetEvent<PageModifiedEvent>()
|
||||
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
|
||||
}
|
||||
|
||||
public void Filter(object tag, string term)
|
||||
{
|
||||
if (!(tag is string s))
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (s)
|
||||
{
|
||||
case "Key":
|
||||
_searchTermForField[Fields.Key] = term;
|
||||
Filter();
|
||||
break;
|
||||
case "Value":
|
||||
_searchTermForField[Fields.Key] = term;
|
||||
Filter();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Sort(object columnTag, bool columnClick)
|
||||
{
|
||||
if (!(columnTag is string s)) { return; }
|
||||
switch (s)
|
||||
{
|
||||
case "Key":
|
||||
Sort(Fields.Key, true);
|
||||
Filter();
|
||||
break;
|
||||
case "Value":
|
||||
Sort(Fields.Value, true);
|
||||
Filter();
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void Sort(Fields field, bool bColumnClick)
|
||||
{
|
||||
if (bColumnClick)
|
||||
{
|
||||
if (field != _sortField)
|
||||
{
|
||||
_sortField = field;
|
||||
_sortAscending = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sortAscending = !_sortAscending;
|
||||
}
|
||||
}
|
||||
var comparer = new PropertyComparer();
|
||||
comparer.SortField = _sortField;
|
||||
comparer.SortAscending = _sortAscending;
|
||||
AllExtraProperties.Sort(comparer);
|
||||
}
|
||||
|
||||
public enum Fields
|
||||
{
|
||||
Key,
|
||||
Value
|
||||
}
|
||||
private Fields _sortField = Fields.Key;
|
||||
private bool _sortAscending = true;
|
||||
|
||||
private void Filter()
|
||||
{
|
||||
ExtraProperties.Clear();
|
||||
foreach (var extraProperty in AllExtraProperties)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(extraProperty.Key) && string.IsNullOrWhiteSpace(extraProperty.Value))
|
||||
{
|
||||
ExtraProperties.Add(extraProperty);
|
||||
continue;
|
||||
}
|
||||
if (_searchTermForField.ContainsKey(Fields.Value))
|
||||
{
|
||||
var term = _searchTermForField[Fields.Value];
|
||||
if (!string.IsNullOrEmpty(term))
|
||||
{
|
||||
if (extraProperty.Value.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_searchTermForField.ContainsKey(Fields.Key))
|
||||
{
|
||||
var term = _searchTermForField[Fields.Key];
|
||||
if (!string.IsNullOrWhiteSpace(term))
|
||||
{
|
||||
if (extraProperty.Key.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
ExtraProperties.Add(extraProperty);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Validate(ref List<string> errors, ref List<string> warnings)
|
||||
{
|
||||
var repeatKeys = AllExtraProperties.GroupBy(exp => exp.Key).Where(grp => grp.Count() > 1).Select(exp => exp.Key).ToArray();
|
||||
if (repeatKeys.Length > 0)
|
||||
{
|
||||
var error = StringResources.RepeatKeyError + Environment.NewLine + string.Join(Environment.NewLine, repeatKeys);
|
||||
errors.Add(error);
|
||||
}
|
||||
var noValueKeys = AllExtraProperties.Where(exp => string.IsNullOrWhiteSpace(exp.Value)).Select(exp => exp.Key).ToArray();
|
||||
if (noValueKeys.Length > 0)
|
||||
{
|
||||
var warning = StringResources.NoValueWarning + Environment.NewLine + string.Join(Environment.NewLine, noValueKeys);
|
||||
warnings.Add(warning);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Validate(ref List<string> errors)
|
||||
{
|
||||
var before = errors.Count;
|
||||
var notUsed = new List<string>();
|
||||
Validate(ref errors, ref notUsed);
|
||||
return before == errors.Count;
|
||||
}
|
||||
|
||||
private readonly Dictionary<Fields, string> _searchTermForField = new Dictionary<Fields, string>();
|
||||
|
||||
private IExtraProperty[] _selectedItems = null;
|
||||
|
||||
public IDataPROPage Page { get; private set; }
|
||||
public object Parent { get; private set; }
|
||||
public bool IsDirty { get; private set; }
|
||||
private bool _isBusy = false;
|
||||
public bool IsBusy
|
||||
{
|
||||
get => _isBusy;
|
||||
set
|
||||
{
|
||||
_isBusy = value;
|
||||
OnPropertyChanged("IsBusy");
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isMenuIncluded;
|
||||
|
||||
private void NotifySelectionChanged(int count)
|
||||
{
|
||||
_eventAggregator.GetEvent<PageSelectionChanged>().Publish(new PageSelectionChangedArg(count, Page));
|
||||
}
|
||||
internal void SetSelection(IExtraProperty[] ieps)
|
||||
{
|
||||
_selectedItems = ieps;
|
||||
NotifySelectionChanged(_selectedItems?.Length ?? 0);
|
||||
}
|
||||
|
||||
public bool IsMenuIncluded
|
||||
{
|
||||
get => _isMenuIncluded;
|
||||
set
|
||||
{
|
||||
_isMenuIncluded = value;
|
||||
OnPropertyChanged("IsMenuIncluded");
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isNavigationIncluded;
|
||||
public bool IsNavigationIncluded
|
||||
{
|
||||
get => _isNavigationIncluded;
|
||||
set
|
||||
{
|
||||
_isNavigationIncluded = value;
|
||||
OnPropertyChanged("IsNavigationIncluded");
|
||||
}
|
||||
}
|
||||
|
||||
//FB14098: Ability to disable editing View if user doesn't have the permissions, but still view current data
|
||||
private bool _isReadOnly;
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get => _isReadOnly;
|
||||
set
|
||||
{
|
||||
_isReadOnly = value;
|
||||
OnPropertyChanged("IsReadOnly");
|
||||
}
|
||||
}
|
||||
|
||||
public List<IExtraProperty> AllExtraProperties { get; set; } = new List<IExtraProperty>();
|
||||
|
||||
public ObservableCollection<IExtraProperty> ExtraProperties { get; set; } =
|
||||
new ObservableCollection<IExtraProperty>();
|
||||
|
||||
public IExtraProperty[] SelectedProperties => throw new NotImplementedException();
|
||||
|
||||
private void Paste(IExtraProperty extraProperty, string text, object tag)
|
||||
{
|
||||
bool bKey = tag.Equals("ExtraProperty");
|
||||
var extraProperties = ParseText(text, bKey, out var oneColumn);
|
||||
int index = ExtraProperties.IndexOf(extraProperty);
|
||||
|
||||
foreach (var extraproperty in extraProperties)
|
||||
{
|
||||
if (index > (ExtraProperties.Count - 1))
|
||||
{
|
||||
ExtraProperties.Add(extraProperty);
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
var exp = ExtraProperties[index++];
|
||||
if (oneColumn)
|
||||
{
|
||||
exp.Key = bKey ? extraproperty.Key : exp.Key;
|
||||
exp.Value = bKey ? exp.Value : extraproperty.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
exp.Key = extraproperty.Key;
|
||||
exp.Value = extraproperty.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Sort(_sortField, false);
|
||||
Filter();
|
||||
}
|
||||
|
||||
private IExtraProperty[] ParseText(string text, bool bKey, out bool oneColumn)
|
||||
{
|
||||
oneColumn = false;
|
||||
var list = new List<IExtraProperty>();
|
||||
var errors = new List<string>();
|
||||
var lines = text.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
|
||||
for (var i = 0; i < lines.Length; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var tokens = line.Split(',');
|
||||
if (tokens.Length != 2)
|
||||
{
|
||||
tokens = line.Split('\t');
|
||||
}
|
||||
if (tokens.Length != 2)
|
||||
{
|
||||
tokens = line.Split(';');
|
||||
}
|
||||
|
||||
var newProperty = new ExtraPropertyModel();
|
||||
if (tokens.Length == 1)
|
||||
{
|
||||
oneColumn = true;
|
||||
if (bKey)
|
||||
{
|
||||
newProperty.Key = tokens[0];
|
||||
newProperty.Value = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
newProperty.Value = tokens[0];
|
||||
newProperty.Key = "";
|
||||
}
|
||||
}
|
||||
else if (tokens.Length == 2)
|
||||
{
|
||||
newProperty.Key = tokens[0];
|
||||
newProperty.Value = tokens[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format(Resources.StringResources.InvalidLine, 1 + i));
|
||||
continue;
|
||||
}
|
||||
|
||||
list.Add(newProperty);
|
||||
}
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
public void SetExtraProperties(IList<IExtraProperty> properties)
|
||||
{
|
||||
AllExtraProperties.Clear();
|
||||
|
||||
AllExtraProperties.AddRange(properties.Select(iep => new ExtraPropertyModel(iep)));
|
||||
AllExtraProperties.Add(new ExtraPropertyModel());
|
||||
|
||||
_sortField = Fields.Key;
|
||||
_sortAscending = true;
|
||||
|
||||
Sort(_sortField, false);
|
||||
Filter();
|
||||
}
|
||||
|
||||
public void CopySelected()
|
||||
{
|
||||
if (null == _selectedItems) { return; }
|
||||
|
||||
foreach (var item in _selectedItems)
|
||||
{
|
||||
AllExtraProperties.Insert(AllExtraProperties.Count - 1, new ExtraPropertyModel(item));
|
||||
}
|
||||
Sort(_sortField, false);
|
||||
Filter();
|
||||
_eventAggregator.GetEvent<PageModifiedEvent>()
|
||||
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
|
||||
}
|
||||
|
||||
public void DeleteSelected()
|
||||
{
|
||||
if (null == _selectedItems) { return; }
|
||||
bool bAddLast = false;
|
||||
|
||||
foreach (var exp in _selectedItems)
|
||||
{
|
||||
if (ExtraProperties.Last() == exp)
|
||||
{
|
||||
bAddLast = true;
|
||||
}
|
||||
ExtraProperties.Remove(exp);
|
||||
AllExtraProperties.Remove(exp);
|
||||
}
|
||||
|
||||
if (bAddLast)
|
||||
{
|
||||
var newXP = new ExtraPropertyModel();
|
||||
ExtraProperties.Add(newXP);
|
||||
AllExtraProperties.Add(newXP);
|
||||
}
|
||||
OnPropertyChanged("ExtraProperties");
|
||||
_eventAggregator.GetEvent<PageModifiedEvent>()
|
||||
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
|
||||
}
|
||||
|
||||
public class PropertyComparer : IComparer<IExtraProperty>
|
||||
{
|
||||
public Fields SortField { get; set; }
|
||||
public bool SortAscending { get; set; }
|
||||
public int Compare(IExtraProperty left, IExtraProperty right)
|
||||
{
|
||||
if (left == right)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var a = left; var b = right;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(a.Key) && string.IsNullOrWhiteSpace(a.Value))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(b.Key) && string.IsNullOrWhiteSpace(b.Value))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!SortAscending) { a = right; b = left; }
|
||||
if (null == a)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (null == b)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
switch (SortField)
|
||||
{
|
||||
case Fields.Key:
|
||||
return DTS.Common.Utilities.NaturalStringComparer.StaticCompare(a.Key.ToUpper(), b.Key.ToUpper());
|
||||
case Fields.Value:
|
||||
return DTS.Common.Utilities.NaturalStringComparer.StaticCompare(a.Value.ToUpper(), b.Value.ToUpper());
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user