Files
DP44/DataPRO/Modules/Channels/ChannelCodes/.svn/pristine/cc/ccc0bfaaad921d951397ab2aadc28158c47514e6.svn-base
2026-04-17 14:55:32 -04:00

1268 lines
46 KiB
Plaintext

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 System.Windows;
using ChannelCodes.Model;
using DTS.Common.Enums;
using DTS.Common.Enums.Channels;
using DTS.Common.Events;
using DTS.Common.Events.ChannelCodes;
using DTS.Common.Interface.Channels.ChannelCodes;
using DTS.Common.Utilities.Logging;
using Prism.Events;
using Prism.Regions;
using Unity;
using DTS.Common.Interactivity;
// ReSharper disable CheckNamespace
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable InconsistentNaming
namespace ChannelCodes
{
/// <inheritdoc />
/// <summary>
/// this class handles ChannelCodesList functionality
/// </summary>
[PartCreationPolicy(CreationPolicy.Shared)]
public class ChannelCodesListViewModel : IChannelCodesListViewModel
{
/// <summary>
/// The ChannelCodeList view
/// </summary>
public IChannelCodesListView View { get; set; }
private IEventAggregator _eventAggregator { get; }
private IUnityContainer UnityContainer { get; }
public InteractionRequest<Notification> NotificationRequest { get; }
public InteractionRequest<Confirmation> ConfirmationRequest { get; }
/// <inheritdoc />
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#region constructors and initializers
private static bool _bAddListeners = false;
/// <summary>
/// Creates a new instance of the ChannelCodesListViewModel
/// </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 ChannelCodesListViewModel(IChannelCodesListView view, IRegionManager regionManager,
IEventAggregator eventAggregator, IUnityContainer unityContainer)
{
ChannelCodesFunc = new Func<IList<IChannelCode>>(GetAllChannels);
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);
_eventAggregator.GetEvent<ChannelCodeCommittedEvent>()
.Subscribe(OnChannelCodesCommitted, ThreadOption.PublisherThread, true);
}
_bAddListeners = true;
}
#endregion
#region Methods
private void OnChannelCodesCommitted(ChannelCodeCommittedEventArgs[] args)
{
//if there are no can args that the user can commit anyhow, we are done
if (!Array.Exists(args, a => a.CanUserCommitChannelCodes)) { return; }
var lookup = ChannelCodeType.GetChannelCodeTypeLookup();
var lookup2 = new Dictionary<ChannelEnumsAndConstants.ChannelCodeType, short>();
using (var e = lookup.GetEnumerator())
{
while (e.MoveNext())
{
switch (e.Current.Value)
{
case ChannelEnumsAndConstants.IsoCodeTypeString:
lookup2[ChannelEnumsAndConstants.ChannelCodeType.ISO] = e.Current.Key;
break;
case ChannelEnumsAndConstants.UserCodeTypeString:
lookup2[ChannelEnumsAndConstants.ChannelCodeType.User] = e.Current.Key;
break;
}
}
}
var codes = ChannelCode.ChannelCodes;
var isoLookup = new Dictionary<string, HashSet<string>>();
var userLookup = new Dictionary<string, HashSet<string>>();
foreach (var code in codes)
{
switch (code.CodeType)
{
case ChannelEnumsAndConstants.ChannelCodeType.ISO:
if (!isoLookup.ContainsKey(code.Code))
{
isoLookup[code.Code] = new HashSet<string>();
}
isoLookup[code.Code].Add(code.Name);
break;
case ChannelEnumsAndConstants.ChannelCodeType.User:
if (!userLookup.ContainsKey(code.Code))
{
userLookup[code.Code] = new HashSet<string>();
}
userLookup[code.Code].Add(code.Name);
break;
}
}
foreach (var arg in args)
{
if (!arg.CanUserCommitChannelCodes) { continue; }
if (string.IsNullOrWhiteSpace(arg.Code) || string.IsNullOrWhiteSpace(arg.Name)) { continue; }
var newCode = new ChannelCode() { Code = arg.Code, CodeType = arg.ChannelCodeType, Name = arg.Name };
switch (arg.ChannelCodeType)
{
case ChannelEnumsAndConstants.ChannelCodeType.ISO:
if (!isoLookup.ContainsKey(arg.Code))
{
isoLookup[arg.Code] = new HashSet<string>();
}
if (!isoLookup[arg.Code].Contains(arg.Name))
{
newCode.Insert(lookup2);
isoLookup[arg.Code].Add(arg.Name);
}
break;
case ChannelEnumsAndConstants.ChannelCodeType.User:
if (!userLookup.ContainsKey(arg.Code))
{
userLookup[arg.Code] = new HashSet<string>();
}
if (!userLookup[arg.Code].Contains(arg.Name))
{
newCode.Insert(lookup2);
userLookup[arg.Code].Add(arg.Name);
}
break;
}
}
}
private void OnTextPasted(ITextPastedEventArgs args)
{
if (args.Id != ChannelCode.PASTE_ID) { return; }
if (!(args.Sender is IChannelCode channelCode))
{
return;
}
switch (ViewMode)
{
case ViewModes.ISO:
{
PasteIso(channelCode, args.Text, args.Tag);
var last = ISOChannelCodes.Last();
if (!string.IsNullOrWhiteSpace(last.Code) || !string.IsNullOrWhiteSpace(last.Name))
{
MarkModifiedISO(last);
}
}
break;
case ViewModes.User:
{
PasteUser(channelCode, args.Text, args.Tag);
var last = UserChannelCodes.Last();
if (!string.IsNullOrWhiteSpace(last.Code) || !string.IsNullOrWhiteSpace(last.Name))
{
MarkModifiedUser(last);
}
}
break;
default:
throw new ArgumentOutOfRangeException();
}
_eventAggregator.GetEvent<PageModifiedEvent>()
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
}
private void PasteIso(IChannelCode channelCode, string text, object tag)
{
bool bCode = tag.Equals("ISOCode");
var channelCodes = ParseText(text, true, bCode, out var oneColumn);
var index = ISOChannelCodes.IndexOf(channelCode);
foreach (var code in channelCodes)
{
if (index > (ISOChannelCodes.Count - 1))
{
AllISOChannelCodes.Add(code);
index++;
}
else
{
var ch = ISOChannelCodes[index++];
if (oneColumn)
{
ch.Code = bCode ? code.Code : ch.Code;
ch.Name = bCode ? ch.Name : code.Name;
}
else
{
ch.Code = code.Code;
ch.Name = code.Name;
}
}
}
SortIso(_isoSortField, false);
FilterIso();
}
private void FilterIso()
{
ISOChannelCodes.Clear();
foreach (var channel in AllISOChannelCodes)
{
if (string.IsNullOrWhiteSpace(channel.Code) && string.IsNullOrWhiteSpace(channel.Name))
{
ISOChannelCodes.Add(channel);
continue;
}
if (_searchTermForField.ContainsKey(Fields.IsoChannelName))
{
var term = _searchTermForField[Fields.IsoChannelName];
if (!string.IsNullOrEmpty(term))
{
if (channel.Name.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
{
continue;
}
}
}
if (_searchTermForField.ContainsKey(Fields.IsoCode))
{
var term = _searchTermForField[Fields.IsoCode];
if (!string.IsNullOrWhiteSpace(term))
{
if (channel.Code.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
{
continue;
}
}
}
ISOChannelCodes.Add(channel);
}
}
private void FilterUser()
{
UserChannelCodes.Clear();
foreach (var channel in AllUserChannelCodes)
{
if (string.IsNullOrWhiteSpace(channel.Code) && string.IsNullOrWhiteSpace(channel.Name))
{
UserChannelCodes.Add(channel);
continue;
}
if (_searchTermForField.ContainsKey(Fields.UserChannelName))
{
var term = _searchTermForField[Fields.UserChannelName];
if (!string.IsNullOrEmpty(term))
{
if (channel.Name.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
{
continue;
}
}
}
if (_searchTermForField.ContainsKey(Fields.UserCode))
{
var term = _searchTermForField[Fields.UserCode];
if (!string.IsNullOrWhiteSpace(term))
{
if (channel.Code.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) < 0)
{
continue;
}
}
}
UserChannelCodes.Add(channel);
}
}
public class ChannelComparer : IComparer<IChannelCode>
{
public Fields SortField { get; set; }
public bool SortAscending { get; set; }
public int Compare(IChannelCode left, IChannelCode right)
{
if (left == right)
{
return 0;
}
var a = left; var b = right;
if (string.IsNullOrWhiteSpace(a.Code) && string.IsNullOrWhiteSpace(a.Name))
{
return 1;
}
if (string.IsNullOrWhiteSpace(b.Code) && string.IsNullOrWhiteSpace(b.Name))
{
return -1;
}
if (!SortAscending) { a = right; b = left; }
if (null == a)
{
return -1;
}
if (null == b)
{
return 1;
}
switch (SortField)
{
case Fields.IsoCode:
case Fields.UserCode:
return DTS.Common.Utilities.NaturalStringComparer.StaticCompare(a.Code.ToUpper(), b.Code.ToUpper());
case Fields.IsoChannelName:
case Fields.UserChannelName:
return DTS.Common.Utilities.NaturalStringComparer.StaticCompare(a.Name.ToUpper(), b.Name.ToUpper());
default:
throw new ArgumentOutOfRangeException();
}
}
}
private void SortIso(Fields field, bool bColumnClick)
{
if (bColumnClick)
{
if (field != _isoSortField)
{
_isoSortField = field;
_isoSortAscending = true;
}
else
{
_isoSortAscending = !_isoSortAscending;
}
}
var comparer = new ChannelComparer();
comparer.SortField = _isoSortField;
comparer.SortAscending = _isoSortAscending;
AllISOChannelCodes.Sort(comparer);
}
private void SortUser(Fields field, bool bColumnClick)
{
if (bColumnClick)
{
if (field != _userSortField)
{
_userSortField = field;
_userSortAscending = true;
}
else
{
_userSortAscending = !_userSortAscending;
}
}
var comparer = new ChannelComparer();
comparer.SortField = _userSortField;
comparer.SortAscending = _userSortAscending;
AllUserChannelCodes.Sort(comparer);
}
private void PasteUser(IChannelCode channelCode, string text, object tag)
{
bool bCode = tag.Equals("UserCode");
var channelCodes = ParseText(text, true, bCode, out var oneColumn);
int index = UserChannelCodes.IndexOf(channelCode);
foreach (var code in channelCodes)
{
if (index > (UserChannelCodes.Count - 1))
{
AllUserChannelCodes.Add(code);
index++;
}
else
{
var ch = UserChannelCodes[index++];
if (oneColumn)
{
ch.Code = bCode ? code.Code : ch.Code;
ch.Name = bCode ? ch.Name : code.Name;
}
else
{
ch.Code = code.Code;
ch.Name = code.Name;
}
}
}
SortUser(_userSortField, false);
FilterUser();
}
private IChannelCode[] ParseText(string text, bool bIso, bool bCode, out bool oneColumn)
{
oneColumn = false;
var list = new List<IChannelCode>();
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 newCode = new ChannelCode();
newCode.CodeType = bIso ? ChannelEnumsAndConstants.ChannelCodeType.ISO : ChannelEnumsAndConstants.ChannelCodeType.User;
if (tokens.Length == 1)
{
oneColumn = true;
if (bCode)
{
newCode.Code = tokens[0];
newCode.Name = "";
}
else
{
newCode.Name = tokens[0];
newCode.Code = "";
}
}
else if (tokens.Length == 2)
{
newCode.Code = tokens[0];
newCode.Name = tokens[1];
}
else
{
errors.Add(string.Format(Resources.StringResources.InvalidLine, 1 + i));
continue;
}
if (bIso)
{
if (newCode.Code.Length > 16)
{
newCode.Code = newCode.Code.Substring(0, 16);
}
}
list.Add(newCode);
}
return list.ToArray();
}
public void Remove(IChannelCode channel)
{
if (channel.CodeType == ChannelEnumsAndConstants.ChannelCodeType.ISO)
{
RemoveISOChannel(channel);
}
else
{
RemoveUserChannel(channel);
}
_eventAggregator.GetEvent<PageModifiedEvent>()
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
}
private void RemoveUserChannel(IChannelCode channel)
{
if (UserChannelCodes.ToList().Last() == channel)
{
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.User };
UserChannelCodes.Add(newCh);
AllUserChannelCodes.Add(newCh);
}
AllUserChannelCodes.Remove(channel);
UserChannelCodes.Remove(channel);
OnPropertyChanged("UserChannelCodes");
}
private void RemoveISOChannel(IChannelCode channel)
{
if (ISOChannelCodes.ToList().Last() == channel)
{
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.ISO };
AllISOChannelCodes.Add(newCh);
ISOChannelCodes.Add(newCh);
}
ISOChannelCodes.Remove(channel);
AllISOChannelCodes.Remove(channel);
OnPropertyChanged("ISOChannelCodes");
}
public void MarkModified(IChannelCode channel)
{
if (channel.CodeType == ChannelEnumsAndConstants.ChannelCodeType.ISO)
{
MarkModifiedISO(channel);
}
else
{
MarkModifiedUser(channel);
}
_eventAggregator.GetEvent<PageModifiedEvent>()
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
}
private void MarkModifiedISO(IChannelCode channel)
{
if (ISOChannelCodes.ToList().Last() == channel)
{
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.ISO };
ISOChannelCodes.Add(newCh);
AllISOChannelCodes.Add(newCh);
OnPropertyChanged("ISOChannelCodes");
}
}
private void MarkModifiedUser(IChannelCode channel)
{
if (UserChannelCodes.ToList().Last() == channel)
{
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.User };
UserChannelCodes.Add(newCh);
AllUserChannelCodes.Add(newCh);
OnPropertyChanged("UserChannelCodes");
}
}
public void Unset()
{
AllISOChannelCodes.Clear();
AllUserChannelCodes.Clear();
UserChannelCodes.Clear();
ISOChannelCodes.Clear();
OnPropertyChanged("UserChannelCodes");
OnPropertyChanged("ISOChannelCodes");
}
/// <summary>
/// sets the page this vm is in, this is used in some notifications to identify to consumers
/// which consumer should process the event
/// </summary>
/// <param name="page"></param>
public void SetPage(object page)
{
Page = page;
}
public void OnSetActive()
{
AllUserChannelCodes.Clear();
AllISOChannelCodes.Clear();
try
{
var lookup = ChannelCodeType.GetChannelCodeTypeLookup();
var existingChannelCodes = ChannelCode.GetExistingChannelCodes(lookup);
foreach (var existingChannelCode in existingChannelCodes)
{
if (existingChannelCode.CodeType == ChannelEnumsAndConstants.ChannelCodeType.ISO)
{
AllISOChannelCodes.Add(existingChannelCode);
}
else
{
AllUserChannelCodes.Add(existingChannelCode);
}
}
AllISOChannelCodes.Add(new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.ISO });
AllUserChannelCodes.Add(new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.User });
SortIso(_isoSortField, false);
SortUser(_userSortField, false);
FilterIso();
FilterUser();
}
catch (Exception ex)
{
APILogger.Log(ex);
ReportErrors(new[] { ex.Message });
}
}
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()
{
}
/// <summary>
/// Private Event handler for RaiseNotification event.
/// </summary>
private void OnBusyIndicatorNotification(bool eventArg)
{
IsBusy = eventArg;
}
/// <summary>
/// Private Event handler for RaiseNotification event.
/// </summary>
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
});
}
public void ReportErrors(string[] errors)
{
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(errors, Page));
}
public bool Save()
{
try
{
//note we use multiple steps here to avoid name conflicts between existing/new/deleted channel codes
//step 1, delete any channels not needed anymore
var lookup = ChannelCodeType.GetChannelCodeTypeLookup();
var lookup2 = new Dictionary<ChannelEnumsAndConstants.ChannelCodeType, short>();
using (var e = lookup.GetEnumerator())
{
while (e.MoveNext())
{
switch (e.Current.Value)
{
case ChannelEnumsAndConstants.IsoCodeTypeString:
lookup2[ChannelEnumsAndConstants.ChannelCodeType.ISO] = e.Current.Key;
break;
case ChannelEnumsAndConstants.UserCodeTypeString:
lookup2[ChannelEnumsAndConstants.ChannelCodeType.User] = e.Current.Key;
break;
}
}
}
var channelCodes = new List<IChannelCode>();
channelCodes.AddRange(AllISOChannelCodes);
channelCodes.AddRange(AllUserChannelCodes);
var existingChannelCodes = ChannelCode.GetExistingChannelCodes(lookup);
var keptIds = new HashSet<int>();
foreach (var channelCode in channelCodes)
{
if (!(channelCode is ChannelCode cc)) { continue; }
if (cc.HasValidId())
{
keptIds.Add(cc.Id);
}
}
var toDelete = (from channelCode in existingChannelCodes where !keptIds.Contains(channelCode.Id) select channelCode).ToList();
if (toDelete.Any())
{
foreach (var cc in toDelete)
{
if (cc.HasValidId())
{
cc.Delete();
}
}
}
//step 2, update any existing new channels
foreach (var channelCode in channelCodes)
{
if (!(channelCode is ChannelCode cc)) { continue; }
if (cc.HasValidId())
{
cc.Save(lookup2);
}
}
//step 3, add new channels
foreach (var channelCode in channelCodes)
{
if (!(channelCode is ChannelCode cc))
{
continue;
}
if (!cc.HasValidId() && !cc.IsBlank())
{
cc.Insert(lookup2);
}
}
//step 4, update list ? not really necessary since we've updated the ids already in the insert function above.
}
catch (Exception ex)
{
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(new[] { ex.Message }, Page));
return false;
}
_eventAggregator.GetEvent<PageModifiedEvent>()
.Publish(new PageModifiedArg(PageModifiedArg.Status.Saved, Page));
return true;
}
#endregion
#region Properties
public List<IChannelCode> AllISOChannelCodes { get; set; } = new List<IChannelCode>();
public List<IChannelCode> AllUserChannelCodes { get; set; } = new List<IChannelCode>();
public ObservableCollection<IChannelCode> ISOChannelCodes { get; set; } =
new ObservableCollection<IChannelCode>();
public ObservableCollection<IChannelCode> UserChannelCodes { get; set; } =
new ObservableCollection<IChannelCode>();
private IReadOnlyDictionary<string, List<IChannelCode>> GetDictionary(IChannelCode[] channels)
{
var dictionary = new Dictionary<string, List<IChannelCode>>();
foreach (var channelCode in channels)
{
var code = channelCode.Code;
var name = channelCode.Name;
if (string.IsNullOrWhiteSpace(code) || string.IsNullOrWhiteSpace(name))
{
continue;
}
if (!dictionary.ContainsKey(code)) { dictionary[code] = new List<IChannelCode>(); }
dictionary[code].Add(channelCode);
}
return dictionary;
}
public void ValidateISO(ref List<string> errors, ref List<string> warnings)
{
var codeToChannels = GetDictionary(AllISOChannelCodes.ToArray());
if (!codeToChannels.Any()) return;
foreach (var channelCode in AllISOChannelCodes)
{
CheckChannelCode(ref errors, ref warnings, channelCode, true, codeToChannels);
}
}
public void ValidateUser(ref List<string> errors, ref List<string> warnings)
{
var codeToChannels = GetDictionary(AllUserChannelCodes.ToArray());
foreach (var channelCode in AllUserChannelCodes)
{
CheckChannelCode(ref errors, ref warnings, channelCode, false, codeToChannels);
}
}
public bool Validate(bool bDisplayWindow)
{
var errors = new List<string>();
var warnings = new List<string>();
ValidateISO(ref errors, ref warnings);
ValidateUser(ref errors, ref warnings);
if (bDisplayWindow && (errors.Any() || warnings.Any()))
{
var list = new List<string>(errors.ToArray());
list.AddRange(warnings.ToArray());
_eventAggregator.GetEvent<PageErrorEvent>().Publish(new PageErrorArg(list.ToArray(), Page));
}
return 0 == errors.Count;
}
public void CopySelected()
{
switch (ViewMode)
{
case ViewModes.ISO:
CopySelectedISOCodes();
break;
case ViewModes.User:
CopySelectedUserCodes();
break;
default:
throw new ArgumentOutOfRangeException();
}
_eventAggregator.GetEvent<PageModifiedEvent>()
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
}
private void CopySelectedUserCodes()
{
if (null == _selectedUserItems) { return; }
foreach (var item in _selectedUserItems)
{
AllUserChannelCodes.Insert(AllUserChannelCodes.Count - 1, new ChannelCode(item));
}
SortUser(_userSortField, false);
FilterUser();
}
private void CopySelectedISOCodes()
{
if (null == _selectedISOItems) { return; }
foreach (var item in _selectedISOItems)
{
var newCh = new ChannelCode(item);
AllISOChannelCodes.Insert(AllISOChannelCodes.Count - 1, newCh);
}
SortIso(_isoSortField, false);
FilterIso();
}
public IChannelCode[] SelectedCodes
{
get
{
switch (ViewMode)
{
case ViewModes.ISO:
return GetSelectedISOCodes();
case ViewModes.User:
return GetSelectedUserCodes();
default:
throw new InvalidEnumArgumentException($"Unknown viewmode: SelectedCodes-{ViewMode}");
}
}
}
private IChannelCode[] GetSelectedISOCodes()
{
//FB 18906 Prevent exception when there is no selection
return _selectedISOItems?.ToArray();
}
private IChannelCode[] GetSelectedUserCodes()
{
return _selectedUserItems?.ToArray();
}
public void DeleteSelected()
{
switch (ViewMode)
{
case ViewModes.ISO:
DeleteSelectedISOCodes();
break;
case ViewModes.User:
DeleteSelectedUserCodes();
break;
default:
throw new ArgumentOutOfRangeException();
}
_eventAggregator.GetEvent<PageModifiedEvent>()
.Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, Page));
}
private void DeleteSelectedUserCodes()
{
if (null == _selectedUserItems) { return; }
bool bAddLast = false;
foreach (var code in _selectedUserItems)
{
if (UserChannelCodes.Last() == code)
{
bAddLast = true;
}
UserChannelCodes.Remove(code);
AllUserChannelCodes.Remove(code);
}
if (bAddLast)
{
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.User };
UserChannelCodes.Add(newCh);
AllUserChannelCodes.Add(newCh);
}
_selectedUserItems = null;
OnPropertyChanged("UserChannelCodes");
}
private void DeleteSelectedISOCodes()
{
if (null == _selectedISOItems) { return; }
bool bAddLast = false;
foreach (var code in _selectedISOItems)
{
if (ISOChannelCodes.Last() == code)
{
bAddLast = true;
}
ISOChannelCodes.Remove(code);
AllISOChannelCodes.Remove(code);
}
if (bAddLast)
{
var newCh = new ChannelCode { CodeType = ChannelEnumsAndConstants.ChannelCodeType.ISO };
ISOChannelCodes.Add(newCh);
AllISOChannelCodes.Add(newCh);
}
_selectedISOItems = null;
OnPropertyChanged("ISOChannelCodes");
}
public void SetISOSelection(IChannelCode[] channelCodes)
{
//FB 18906 if the the list is empty, do not set _selectedISOItems
if (!channelCodes.Any())
{
return;
}
_selectedISOItems = channelCodes;
if (ViewMode == ViewModes.ISO)
{
var count = 0;
if (null != channelCodes)
{
count = channelCodes.Length;
}
NotifySelectionChanged(count);
}
}
private void NotifySelectionChanged(int count)
{
_eventAggregator.GetEvent<PageSelectionChanged>().Publish(new PageSelectionChangedArg(count, Page));
}
public void SetUserSelection(IChannelCode[] channelCodes)
{
//FB 18906 if the the list is empty, do not set _selectedISOItems
if (!channelCodes.Any())
{
return;
}
_selectedUserItems = channelCodes;
if (ViewMode == ViewModes.User)
{
var count = 0;
if (null != channelCodes)
{
count = channelCodes.Length;
}
NotifySelectionChanged(count);
}
}
private static void CheckChannelCode(ref List<string> errors,
ref List<string> warnings,
IChannelCode channelCode,
bool iso,
IReadOnlyDictionary<string, List<IChannelCode>> channelCodeToChannels)
{
var channelCodeEmpty = string.IsNullOrWhiteSpace(channelCode.Code);
var channelNameEmpty = string.IsNullOrWhiteSpace(channelCode.Name);
var itemStatus = UIItemStatus.None;
if (channelCodeEmpty && channelNameEmpty)
{
channelCode.ItemStatus = UIItemStatus.None;
return;
}
if (channelCodeEmpty)
{
var msg = iso ? Resources.StringResources.MissingISOCode : Resources.StringResources.MissingUserCode;
msg = string.Format(msg, channelCode.Name);
if (!errors.Contains(msg))
{
errors.Add(msg);
itemStatus = UIItemStatus.Error;
}
}
else if (channelNameEmpty)
{
var msg = iso
? Resources.StringResources.MissingISOChannelName
: Resources.StringResources.MissingUserChannelName;
msg = string.Format(msg, channelCode.Code);
if (!errors.Contains(msg))
{
itemStatus = UIItemStatus.Error;
errors.Add(msg);
}
}
else
{
var list = channelCodeToChannels[channelCode.Code];
if (list.Count > 1)
{
//either duplicated code or duplicated everything
var matches = from ch in list where ch.Name == channelCode.Name && ch != channelCode select ch;
if (matches.Any())
{
var msg = iso ? Resources.StringResources.DuplicateISOChannelCode : Resources.StringResources.DuplicateUserChannelCode;
if (!string.IsNullOrWhiteSpace(channelCode.Name))
{
msg = string.Format(msg, channelCode.Name);
}
else
{
msg = string.Format(msg, channelCode.Code);
}
if (!errors.Contains(msg)) { errors.Add(msg); }
itemStatus = UIItemStatus.Error;
}
}
}
channelCode.ItemStatus = itemStatus;
}
public void Filter(object columnTag, string searchTerm)
{
if (!(columnTag is string s))
{
return;
}
switch (s)
{
case "ISOCode":
_searchTermForField[Fields.IsoCode] = searchTerm;
FilterIso();
break;
case "ISOChannelName":
_searchTermForField[Fields.IsoChannelName] = searchTerm;
FilterIso();
break;
case "UserCode":
_searchTermForField[Fields.UserCode] = searchTerm;
FilterUser();
break;
case "UserChannelName":
_searchTermForField[Fields.UserChannelName] = searchTerm;
FilterUser();
break;
}
}
public void Sort(object columnTag, bool bColumnClick)
{
if (!(columnTag is string s)) { return; }
switch (s)
{
case "ISOCode":
SortIso(Fields.IsoCode, true);
FilterIso();
break;
case "ISOChannelName":
SortIso(Fields.IsoChannelName, true);
FilterIso();
break;
case "UserCode":
SortUser(Fields.UserCode, true);
FilterUser();
break;
case "UserChannelName":
SortUser(Fields.UserChannelName, true);
FilterUser();
break;
}
}
public enum Fields
{
IsoCode,
IsoChannelName,
UserCode,
UserChannelName
}
private Fields _isoSortField = Fields.IsoCode;
private bool _isoSortAscending = true;
private Fields _userSortField = Fields.UserCode;
private bool _userSortAscending = true;
private readonly Dictionary<Fields, string> _searchTermForField = new Dictionary<Fields, string>();
private IChannelCode[] _selectedISOItems = null;
private IChannelCode[] _selectedUserItems = null;
public object Page { 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;
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");
}
}
#endregion Properties
public enum ViewModes
{
ISO,
User
}
private ViewModes _viewMode = ViewModes.ISO;
public ViewModes ViewMode
{
get => _viewMode;
set
{
_viewMode = value;
OnPropertyChanged("ISOVisibility");
OnPropertyChanged("UserVisibility");
var count = 0;
switch (value)
{
case ViewModes.ISO:
if (null != _selectedISOItems) { count = _selectedISOItems.Length; }
NotifySelectionChanged(count);
break;
case ViewModes.User:
if (null != _selectedUserItems) { count = _selectedUserItems.Length; }
NotifySelectionChanged(count);
break;
default:
throw new ArgumentOutOfRangeException(nameof(value), value, null);
}
}
}
public Visibility ISOVisibility => ViewMode == ViewModes.ISO ? Visibility.Visible : Visibility.Collapsed;
public Visibility UserVisibility => ViewMode == ViewModes.User ? Visibility.Visible : Visibility.Collapsed;
private IList<IChannelCode> GetAllChannels()
{
return ChannelCode.ChannelCodes;
}
public Func<IList<IChannelCode>> ChannelCodesFunc { get; }
private bool _showISOStringBuilder = true;
public bool ShowISOStringBuilder
{
get => _showISOStringBuilder;
set
{
_showISOStringBuilder = value;
OnPropertyChanged("ShowISOStringBuilder");
}
}
private bool _uniqueISOCodesRequired;
public bool UniqueISOCodesRequired
{
get => _uniqueISOCodesRequired;
set
{
_uniqueISOCodesRequired = value;
OnPropertyChanged("UniqueISOCodesRequired");
}
}
private bool _showChannelCodeLookupHelper = true;
public bool ShowChannelCodeLookupHelper
{
get => _showChannelCodeLookupHelper;
set
{
_showChannelCodeLookupHelper = value;
OnPropertyChanged("ShowChannelCodeLookupHelper");
}
}
#region Commands
#endregion
}
}