inital
This commit is contained in:
@@ -0,0 +1,496 @@
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.MultiLanguage;
|
||||
using F4SD_AdaptableIcon;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using FasdDesktopUi.Basics.CustomEvents;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using FasdDesktopUi.Basics.UserControls.SearchResult;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
public partial class CustomSearchResultCollection : UserControl
|
||||
{
|
||||
private Dictionary<enumFasdInformationClass, SearchResultCategory> _searchCategories;
|
||||
|
||||
#region IndexOfSelectedResultItem
|
||||
|
||||
private int _indexOfSelectedResultItem = int.MinValue;
|
||||
|
||||
public int IndexOfSelectedResultItem
|
||||
{
|
||||
get { return _indexOfSelectedResultItem; }
|
||||
set
|
||||
{
|
||||
if (_indexOfSelectedResultItem == value)
|
||||
return;
|
||||
|
||||
if (value < -1)
|
||||
_indexOfSelectedResultItem = int.MinValue;
|
||||
else if (value == -1)
|
||||
_indexOfSelectedResultItem = GetSearchResultCount() - 1;
|
||||
else if (value == GetSearchResultCount())
|
||||
_indexOfSelectedResultItem = 0;
|
||||
else
|
||||
_indexOfSelectedResultItem = value;
|
||||
|
||||
HandleIndexOfSelectedResultItemChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private cMenuDataBase _lastSelectedMenuData = null;
|
||||
|
||||
public bool ShowSearchResultDetails
|
||||
{
|
||||
get { return cFasdCockpitConfig.Instance.ShowSearchResultDetails; }
|
||||
set
|
||||
{
|
||||
cFasdCockpitConfig.Instance.ShowSearchResultDetails = value;
|
||||
cFasdCockpitConfig.Instance.Save("ShowSearchResultDetails");
|
||||
}
|
||||
}
|
||||
|
||||
public CustomSearchResultCollection()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnInitialized(EventArgs e)
|
||||
{
|
||||
base.OnInitialized(e);
|
||||
AddHandler(CustomEventManager.IndexChangedEvent, new CustomEventManager.IndexChangedHandlerDelegate(UpdateIndexOfSelectedResultItem));
|
||||
AddHandler(CustomEventManager.MenuDataChangedEvent, new CustomEventManager.MenuDataChangedHandlerDelegate((_, args) => _lastSelectedMenuData = args.MenuData));
|
||||
}
|
||||
|
||||
private void UpdateIndexOfSelectedResultItem(object sender, IndexEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!(args.OriginalSource is SearchResultCategory category))
|
||||
return;
|
||||
|
||||
var indexOfSender = _searchCategories.Values.ToList().IndexOf(category);
|
||||
|
||||
int updatedIndex = args.NewValue;
|
||||
for (int i = 0; i < indexOfSender; i++)
|
||||
{
|
||||
updatedIndex += _searchCategories.Values.ToList()[i].GetItemCount();
|
||||
}
|
||||
|
||||
IndexOfSelectedResultItem = updatedIndex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool IsEmpty() => MainStackPanel.Children.Count == 0;
|
||||
|
||||
internal int GetSearchResultCount()
|
||||
{
|
||||
int itemCount = 0;
|
||||
|
||||
foreach (var resultCategory in _searchCategories.Values)
|
||||
{
|
||||
itemCount += resultCategory.GetItemCount();
|
||||
}
|
||||
|
||||
return itemCount;
|
||||
}
|
||||
|
||||
private void HandleIndexOfSelectedResultItemChanged()
|
||||
{
|
||||
try
|
||||
{
|
||||
int totalResultItemCount = 0;
|
||||
|
||||
foreach (var category in _searchCategories.Values)
|
||||
{
|
||||
int categoryItemCount = category.GetItemCount();
|
||||
|
||||
if (IndexOfSelectedResultItem > totalResultItemCount)
|
||||
category.HiglightItemAt(-1);
|
||||
|
||||
if (IndexOfSelectedResultItem < totalResultItemCount + categoryItemCount)
|
||||
category.HiglightItemAt(IndexOfSelectedResultItem - totalResultItemCount);
|
||||
|
||||
totalResultItemCount += categoryItemCount;
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetHeaderText(string headerText, bool hideDetailsCheckbox = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
HeaderTextBlock.Text = headerText;
|
||||
HeaderTextBlock.Visibility = string.IsNullOrEmpty(headerText) ? Visibility.Collapsed : Visibility.Visible;
|
||||
ShowDetailsCheckBox.Visibility = string.IsNullOrEmpty(headerText) || hideDetailsCheckbox ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessNewItems()
|
||||
{
|
||||
UpdateCornerRadius();
|
||||
UpdateSearchResultDetailsShown(ShowSearchResultDetails);
|
||||
}
|
||||
|
||||
public void ShowLoadingTextItem(string itemText)
|
||||
{
|
||||
try
|
||||
{
|
||||
ClearControl();
|
||||
|
||||
var menuItem = new CustomMenuItem(false) { MenuData = new cMenuDataLoading(itemText) };
|
||||
MainStackPanel.Children.Add(menuItem);
|
||||
|
||||
ProcessNewItems();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowSearchResults(cFilteredResults SearchResults, string headerText, ISearchUiProvider searchUiProvider)
|
||||
{
|
||||
try
|
||||
{
|
||||
ClearControl();
|
||||
SetHeaderText(headerText);
|
||||
|
||||
if (SearchResults?.Results is null || SearchResults.Results.Count == 0)
|
||||
ProcessNoSearchResults();
|
||||
else
|
||||
ProcessSearchResults();
|
||||
|
||||
ProcessNewItems();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
void ProcessNoSearchResults()
|
||||
{
|
||||
var resultItemControl = new CustomMenuItem(false)
|
||||
{
|
||||
MenuData = new cMenuDataBase()
|
||||
{
|
||||
MenuText = cMultiLanguageSupport.GetItem("SearchBar.NoResults"),
|
||||
MenuIcon = new IconData(enumInternIcons.menuBar_search_noResults)
|
||||
}
|
||||
};
|
||||
MainStackPanel.Children.Add(resultItemControl);
|
||||
}
|
||||
|
||||
void ProcessSearchResults()
|
||||
{
|
||||
if (!_searchCategories.TryGetValue(enumFasdInformationClass.Main, out var mainCategory))
|
||||
return;
|
||||
|
||||
List<cMenuDataBase> menuDataList = new List<cMenuDataBase>();
|
||||
mainCategory.UpdateSearchResults(SearchResults.Results, searchUiProvider);
|
||||
UpdatePendingInformationClasses(new HashSet<enumFasdInformationClass>());
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowSearchHistory()
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
ClearControl();
|
||||
SetHeaderText(cMultiLanguageSupport.GetItem("Searchbar.History.Title"), true);
|
||||
|
||||
if (cSearchManager.Instance.HistoryList.Count <= 0)
|
||||
{
|
||||
this.Visibility = Visibility.Collapsed;
|
||||
return;
|
||||
}
|
||||
|
||||
this.Visibility = Visibility.Visible;
|
||||
|
||||
foreach (var historyEntry in cSearchManager.Instance.HistoryList)
|
||||
{
|
||||
var menuData = new cMenuDataBase() { MenuText = historyEntry.DisplayText, UiAction = new cUiProcessSearchHistoryEntry(historyEntry) };
|
||||
if (historyEntry.isSeen)
|
||||
{
|
||||
menuData.MenuIcon = new IconData(MaterialIcons.MaterialIconType.ic_visibility);
|
||||
menuData.MenuIconSize = 0.75;
|
||||
}
|
||||
|
||||
MainStackPanel.Children.Add(new CustomMenuItem(true) { MenuData = menuData });
|
||||
}
|
||||
|
||||
ProcessNewItems();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateSearchRelations(ILookup<enumFasdInformationClass, cMenuDataBase> relations)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_searchCategories is null)
|
||||
return;
|
||||
|
||||
int indexOfMenuData = -1;
|
||||
int indexOfMenuDataCategory = -1;
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
if (!_searchCategories.TryGetValue(relation.Key, out var category))
|
||||
continue;
|
||||
|
||||
category.UpdateSearchRelations(relation);
|
||||
|
||||
if (indexOfMenuData != -1)
|
||||
continue;
|
||||
|
||||
indexOfMenuData = GetIndexOf(relation.Select(value => value.Data), _lastSelectedMenuData?.Data);
|
||||
|
||||
if (indexOfMenuData != -1)
|
||||
indexOfMenuDataCategory = GetIndexOf(_searchCategories.Values, category);
|
||||
}
|
||||
|
||||
ProcessNewItems();
|
||||
|
||||
if (indexOfMenuData == -1)
|
||||
return;
|
||||
|
||||
IndexOfSelectedResultItem = indexOfMenuData + _searchCategories.Take(indexOfMenuDataCategory).Sum(category => category.Value.GetItemCount());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
|
||||
// even if not ideal, seems to be the most performant solution for retrieving the index of IEnumerable
|
||||
int GetIndexOf(IEnumerable<object> data, object value)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
foreach (var item in data)
|
||||
{
|
||||
if (item.Equals(value))
|
||||
return index;
|
||||
index++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearControl()
|
||||
{
|
||||
MainStackPanel.Children.Clear();
|
||||
|
||||
var mainCategory = new SearchResultCategory() { IsPending = false };
|
||||
_searchCategories = new Dictionary<enumFasdInformationClass, SearchResultCategory>() { [enumFasdInformationClass.Main] = mainCategory };
|
||||
MainStackPanel.Children.Add(mainCategory);
|
||||
|
||||
_lastSelectedMenuData = null;
|
||||
IndexOfSelectedResultItem = int.MinValue;
|
||||
HandleIndexOfSelectedResultItemChanged();
|
||||
}
|
||||
|
||||
public void SelectCurrentResultItem()
|
||||
{
|
||||
try
|
||||
{
|
||||
int totalResultItemCount = 0;
|
||||
|
||||
foreach (var category in _searchCategories.Values)
|
||||
{
|
||||
int categoryItemCount = category.GetItemCount();
|
||||
|
||||
if (IndexOfSelectedResultItem < totalResultItemCount + categoryItemCount)
|
||||
{
|
||||
category.SelectItemAt(IndexOfSelectedResultItem - totalResultItemCount);
|
||||
return;
|
||||
}
|
||||
|
||||
totalResultItemCount += categoryItemCount;
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCornerRadius()
|
||||
{
|
||||
try
|
||||
{
|
||||
const double cornerRadius = 10;
|
||||
|
||||
if (MainStackPanel.Children.Count <= 0)
|
||||
return;
|
||||
|
||||
if (MainStackPanel.Children[0] is CustomMenuItem resultItemFirst)
|
||||
{
|
||||
var tempCornerRadius = resultItemFirst.MenuItemBorder.CornerRadius;
|
||||
tempCornerRadius.TopLeft = cornerRadius;
|
||||
tempCornerRadius.TopRight = cornerRadius;
|
||||
resultItemFirst.MenuItemBorder.CornerRadius = tempCornerRadius;
|
||||
}
|
||||
|
||||
if (MainStackPanel.Children[MainStackPanel.Children.Count - 1] is CustomMenuItem resultItemLast)
|
||||
{
|
||||
var tempCornerRadiusLast = resultItemLast.MenuItemBorder.CornerRadius;
|
||||
tempCornerRadiusLast.BottomLeft = cornerRadius;
|
||||
tempCornerRadiusLast.BottomRight = cornerRadius;
|
||||
resultItemLast.MenuItemBorder.CornerRadius = tempCornerRadiusLast;
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowDetailsCheckBox_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!(sender is CheckBox checkBox))
|
||||
return;
|
||||
|
||||
cFasdCockpitConfig.Instance.ShowSearchResultDetails = checkBox.IsChecked == true;
|
||||
cFasdCockpitConfig.Instance.Save("ShowSearchResultDetails");
|
||||
UpdateSearchResultDetailsShown(checkBox.IsChecked);
|
||||
}
|
||||
|
||||
private void UpdateSearchResultDetailsShown(bool? showDetailHeadings)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (showDetailHeadings is null)
|
||||
return;
|
||||
|
||||
if (MainStackPanel?.Children is null || MainStackPanel.Children.Count <= 0)
|
||||
return;
|
||||
|
||||
foreach (var searchResult in MainStackPanel.Children.OfType<CustomMenuItem>())
|
||||
{
|
||||
searchResult.ShowDetailHeadings(showDetailHeadings.Value);
|
||||
}
|
||||
|
||||
foreach (var searchResult in MainStackPanel.Children.OfType<SearchResultCategory>())
|
||||
{
|
||||
searchResult.ShowDetailHeadings(showDetailHeadings.Value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPendingInformationClasses(HashSet<enumFasdInformationClass> informationClasses)
|
||||
{
|
||||
try
|
||||
{
|
||||
MainStackPanel.Children.Clear();
|
||||
_searchCategories = new Dictionary<enumFasdInformationClass, SearchResultCategory>();
|
||||
|
||||
foreach (var informationClass in informationClasses.Reverse())
|
||||
{
|
||||
var searchResultCategory = new SearchResultCategory()
|
||||
{
|
||||
Title = string.Format(cMultiLanguageSupport.GetItem("Searchbar.Relations.SearchFor"), informationClass),
|
||||
IsPending = true,
|
||||
TitleIcon = GetIconFrom(informationClass),
|
||||
Margin = new Thickness(0, 7.5, 0, 0)
|
||||
};
|
||||
|
||||
_searchCategories.Add(informationClass, searchResultCategory);
|
||||
MainStackPanel.Children.Add(searchResultCategory);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
|
||||
IconData GetIconFrom(enumFasdInformationClass informationClass)
|
||||
{
|
||||
switch (informationClass)
|
||||
{
|
||||
case enumFasdInformationClass.Computer:
|
||||
return new IconData(enumInternIcons.misc_computer);
|
||||
case enumFasdInformationClass.User:
|
||||
return new IconData(enumInternIcons.misc_user);
|
||||
case enumFasdInformationClass.Ticket:
|
||||
return new IconData(enumInternIcons.menuBar_mail);
|
||||
case enumFasdInformationClass.VirtualSession:
|
||||
return new IconData(MaterialIcons.MaterialIconType.ic_cloud_queue);
|
||||
case enumFasdInformationClass.MobileDevice:
|
||||
return new IconData(MaterialIcons.MaterialIconType.ic_smartphone);
|
||||
default:
|
||||
return new IconData(enumInternIcons.f4sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdatePendingInformationClasses(HashSet<enumFasdInformationClass> informationClasses)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_searchCategories is null)
|
||||
return;
|
||||
|
||||
var finishedInformationClasses = _searchCategories.Where(category => !informationClasses.Contains(category.Key)).Select(category => category.Value);
|
||||
foreach (var pendingCategory in finishedInformationClasses)
|
||||
{
|
||||
pendingCategory.IsPending = false;
|
||||
|
||||
if (pendingCategory.GetItemCount() == 0)
|
||||
pendingCategory.Margin = new Thickness(0);
|
||||
else
|
||||
pendingCategory.Margin = new Thickness(0, 7.5, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
if (IndexOfSelectedResultItem != int.MinValue)
|
||||
return;
|
||||
|
||||
if (_searchCategories.Values.Any(c => c.IsPending))
|
||||
return;
|
||||
|
||||
IndexOfSelectedResultItem = _searchCategories.Values.Sum(c => c.GetItemCount()) - 1;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user