This commit is contained in:
Meik
2025-11-11 11:03:42 +01:00
commit dc3e8a2e4c
582 changed files with 191465 additions and 0 deletions

View File

@@ -0,0 +1,192 @@
using C4IT.FASD.Base;
using C4IT.FASD.Cockpit.Communication;
using C4IT.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.Helper
{
public class cDirectConnectionHelper
{
#region Properties and Fields
private int? isTryingToConnectToDevice = null;
private readonly cSupportCaseDataProvider dataProvider;
private Guid directConnectionId = Guid.Empty;
private readonly System.Timers.Timer directConnectionRenewTimer = new System.Timers.Timer();
public bool IsDirectConnectionActive { get => directConnectionId.Equals(Guid.Empty) is false; }
#endregion
public event EventHandler DirectConnectionChanged;
public cDirectConnectionHelper(cSupportCaseDataProvider dataProvider)
{
try
{
this.dataProvider = dataProvider;
directConnectionRenewTimer.Interval = 1000 * 60 * 3;
directConnectionRenewTimer.Elapsed += async (sender, e) => await DirectConnectionExtendDurationAsync(60 * 5);
}
catch (Exception E)
{
LogException(E);
}
}
public void Reset()
{
try
{
directConnectionId = Guid.Empty;
isTryingToConnectToDevice = null;
DirectConnectionChanged?.Invoke(this, EventArgs.Empty);
}
catch (Exception E)
{
LogException(E);
}
}
public async Task DirectConnectionStartAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
const int maxRetries = 60;
int retryCount = 0;
bool shouldTryStartDirectConnection = true;
while (shouldTryStartDirectConnection && retryCount < maxRetries)
{
shouldTryStartDirectConnection = !(await CouldStartDirectConnectionAsync());
if (shouldTryStartDirectConnection)
await Task.Delay(1000 * 5);
retryCount++;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
}
private async Task<bool> CouldStartDirectConnectionAsync()
{
try
{
if (dataProvider.Identities.Any(identity => identity.Class == enumFasdInformationClass.Computer) is false)
{
LogEntry("Direct Connection - There was no information class of type computer found.", LogLevels.Error);
return true;
}
if (!dataProvider.NamedParameterEntries.TryGetValue("AgentDeviceId", out var agentDeviceIdParameter))
{
LogEntry("Direct Connection - NamedParameter 'AgentDeviceId' could not be found.", LogLevels.Error);
}
if (agentDeviceIdParameter == null || !int.TryParse(agentDeviceIdParameter.GetValue(), out int agentDeviceId))
{
LogEntry("Direct Connection - There was no valid AgentDeviceId found.", LogLevels.Error);
return true;
}
if (isTryingToConnectToDevice == agentDeviceId)
return true;
isTryingToConnectToDevice = agentDeviceId;
var tempConnectionId = await cFasdCockpitCommunicationBase.Instance.TryActivateDirectConnection(agentDeviceId);
if (tempConnectionId is null)
{
LogEntry("Direct Connection - Failed to receive connection status.", LogLevels.Error);
isTryingToConnectToDevice = null;
return false;
}
directConnectionId = tempConnectionId.Value;
if (isTryingToConnectToDevice != agentDeviceId)
return true;
isTryingToConnectToDevice = null;
await DirectConnectionExtendDurationAsync(60 * 5);
directConnectionRenewTimer.Start();
DirectConnectionChanged?.Invoke(this, EventArgs.Empty);
return true;
}
catch (Exception E)
{
LogException(E);
}
return true;
}
public async Task DirectConnectionStopAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
directConnectionRenewTimer.Stop();
if (directConnectionId.Equals(Guid.Empty))
return;
await cFasdCockpitCommunicationBase.Instance.StopDirectConnection(directConnectionId);
Reset();
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
}
public async Task<bool> DirectConnectionExtendDurationAsync(int durationInSeconds)
{
try
{
if (directConnectionId.Equals(Guid.Empty))
return false;
var output = await cFasdCockpitCommunicationBase.Instance.DirectConnectionExtendDuration(directConnectionId, durationInSeconds);
if (output is false)
Reset();
return output;
}
catch (Exception E)
{
LogException(E);
}
return false;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
using F4SD_AdaptableIcon;
using FasdDesktopUi.Basics.UserControls.AdaptableIcon;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.Helper
{
public static class IconHelper
{
public static void SetIconValue(AdaptableIcon icon, IconData iconData)
{
try
{
if (iconData.Intern != null)
icon.SelectedInternIcon = iconData.Intern;
else if(iconData.Material != null)
icon.SelectedMaterialIcon = iconData.Material;
else if(iconData.Gif != null)
icon.SelectedInternGif = iconData.Gif;
}
catch (Exception E)
{
LogException(E);
}
}
}
}

View File

@@ -0,0 +1,239 @@
using C4IT.FASD.Base;
using FasdDesktopUi.Basics.Enums;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UiActions;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.Helper
{
internal class MenuItemDataProvider
{
private readonly cSupportCaseDataProvider _dataProvider;
private const int defaultPinnedActionCount = 3; //search, notepad, copyTicketInformation
public MenuItemDataProvider(cSupportCaseDataProvider dataProvider)
{
_dataProvider = dataProvider;
}
public List<cMenuDataBase> GetMenuItemData()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
List<cMenuDataBase> menuItemData = new List<cMenuDataBase>();
try
{
foreach (var menuItemConfig in cF4SDCockpitXmlConfig.Instance.MenuItems.Values)
{
cMenuDataBase menuItem = GetMenuItem(menuItemConfig);
if (menuItem is null)
continue;
int pinnedIndex = cF4SDCockpitXmlConfig.Instance.HealthCardConfig.QuickActionsPinned.IndexOf(menuItemConfig.Name);
if (pinnedIndex > -1)
pinnedIndex += defaultPinnedActionCount;
menuItem.IconPositionIndex = pinnedIndex;
menuItemData.Add(menuItem);
}
FillMenuSection(menuItemData);
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return menuItemData;
}
private cMenuDataBase GetMenuItem(cFasdBaseConfigMenuItem menuItemConfig)
{
try
{
cMenuDataBase menuItem = null;
switch (menuItemConfig)
{
case cFasdQuickTip quickTip:
menuItem = GetQuickTipMenuItem(quickTip);
break;
case cFasdQuickAction quickAction:
menuItem = GetQuickActionMenuItem(quickAction);
break;
case cFasdMenuSection section:
menuItem = GetSectionMenuItem(section);
break;
case cCopyTemplate copyTemplate:
menuItem = GetCopyTemplateMenuItem(copyTemplate);
break;
}
if (menuItem != null)
{
if (!cHealthCardDataHelper.IsUiVisible(menuItemConfig, _dataProvider.NamedParameterEntries))
menuItem.SetUiActionDisplayType(enumActionDisplayType.hidden);
}
return menuItem;
}
catch (Exception E)
{
LogException(E);
}
return null;
}
private cMenuDataBase GetCopyTemplateMenuItem(cCopyTemplate copyTemplate)
{
cMenuDataBase menuItem = new cMenuDataBase(copyTemplate);
enumActionDisplayType displayType = HasRequiredInformationClasses(copyTemplate.InformationClasses)
? enumActionDisplayType.enabled : enumActionDisplayType.disabled;
menuItem.SetUiActionDisplayType(displayType);
return menuItem;
}
private cMenuDataBase GetSectionMenuItem(cFasdMenuSection section)
{
return new cMenuDataContainer(section);
}
private cMenuDataBase GetQuickActionMenuItem(cFasdQuickAction quickAction)
{
cMenuDataBase menuItem = new cMenuDataBase(quickAction);
enumActionDisplayType displayType = HasAllRequirements(quickAction)
? enumActionDisplayType.enabled : enumActionDisplayType.disabled;
menuItem.SetUiActionDisplayType(displayType);
return menuItem;
}
private cMenuDataBase GetQuickTipMenuItem(cFasdQuickTip quickTip)
{
return new cMenuDataBase(quickTip);
//TODO: Quick Actions einfügen
//TODO: DisplayType prüfen + setzen
}
private bool HasRequiredInformationClasses(List<enumFasdInformationClass> required)
{
return !(required.Any(informationClass => _dataProvider.Identities.Any(identity => identity.Class == informationClass) == false));
}
private bool HasAllRequirements(cFasdQuickAction quickAction)
{
try
{
if (!HasRequiredInformationClasses(quickAction.InformationClasses))
return false;
// if CheckNamedParamter the value of NamedParameter is set and if required equals one of the necessary values
bool hasRequiredNamedParameter = quickAction.CheckNamedParameter is null
|| (_dataProvider.NamedParameterEntries.TryGetValue(quickAction.CheckNamedParameter, out var namedParameterEntry)
&& (quickAction.CheckNamedParameterValues is null || quickAction.CheckNamedParameterValues.Count == 0 || quickAction.CheckNamedParameterValues.Contains(namedParameterEntry.GetValue())));
if (!hasRequiredNamedParameter)
return false;
if (quickAction.CheckFilePath != null && !HasRequiredFilePath(quickAction.CheckFilePath))
return false;
if (quickAction.CheckRegistryEntry != null && !HasRequiredRegistryEntry(quickAction.CheckRegistryEntry))
return false;
return true;
}
catch (Exception E)
{
LogException(E);
}
return false;
}
private bool HasRequiredFilePath(string filePath)
{
try
{
if (string.IsNullOrWhiteSpace(filePath))
{
return true;
}
var specialFolders = Enum.GetValues(typeof(Environment.SpecialFolder)).Cast<Environment.SpecialFolder>();
foreach (var specialFolder in specialFolders)
{
var specialFolderName = "%" + specialFolder.ToString() + "%";
var specialFolderPath = Environment.GetFolderPath(specialFolder);
filePath = filePath.Replace(specialFolderName, specialFolderPath);
}
filePath = Environment.ExpandEnvironmentVariables(filePath);
return File.Exists(filePath);
}
catch (Exception E)
{
LogException(E);
}
return false;
}
private bool HasRequiredRegistryEntry(string registryEntry)
{
try
{
if (string.IsNullOrWhiteSpace(registryEntry))
{
return true;
}
var registryRootPath = registryEntry.Split('\\')[0];
registryEntry = registryEntry.Replace(registryRootPath, "").Remove(0, 1);
switch (registryRootPath)
{
case "HKEY_LOCAL_MACHINE":
case "HKLM":
return Registry.LocalMachine.OpenSubKey(registryEntry) != null;
case "HKEY_CURRENT_USER":
case "HKCU":
return Registry.CurrentUser.OpenSubKey(registryEntry) != null;
default:
return false;
}
}
catch (Exception E)
{
LogException(E);
}
return false;
}
private void FillMenuSection(List<cMenuDataBase> menuItemData)
{
try
{
foreach (var section in menuItemData.OfType<cMenuDataContainer>())
{
List<cMenuDataBase> subMenuData = menuItemData.Where(data =>
(data?.UiAction?.DisplayType != enumActionDisplayType.hidden) && (data?.MenuSections?.Contains(section.ContainerName) ?? false)).ToList();
section.SubMenuData = subMenuData;
if (section.UiAction is cSubMenuAction subMenuAction)
subMenuAction.SubMenuData = subMenuData;
}
}
catch (Exception E)
{
LogException(E);
}
}
}
}

View File

@@ -0,0 +1,74 @@
using C4IT.FASD.Base;
using C4IT.FASD.Cockpit.Communication;
using C4IT.MultiLanguage;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UserControls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.Helper
{
public class cQuickActionProtocollHelper
{
private readonly cSupportCaseDataProvider dataProvider;
public cQuickActionProtocollHelper(cSupportCaseDataProvider dataProvider)
{
this.dataProvider = dataProvider;
}
public async Task<List<List<object>>> GetQuickActionHistoryAsync(string QuickActionName)
{
try
{
int agentDeviceId = int.MinValue;
int? agentUserIdNullable = null;
if (dataProvider.NamedParameterEntries.TryGetValue("AgentDeviceId", out var agentDeviceIdParameter))
_ = int.TryParse(agentDeviceIdParameter.GetValue(), out agentDeviceId);
if (dataProvider.NamedParameterEntries.TryGetValue("AgentUserId", out var agentUserIdParameter))
if (int.TryParse(agentUserIdParameter.GetValue(), out int agentUserId))
agentUserIdNullable = agentUserId;
var output = await cFasdCockpitCommunicationBase.Instance.GetQuickActionHistory(QuickActionName, cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode.Value, agentDeviceId, agentUserIdNullable);
foreach (var historyLine in output)
{
var historyStatus = historyLine.FirstOrDefault();
if (historyStatus is null || !(historyStatus is enumQuickActionRevisionStatus revisionStatus))
continue;
switch (revisionStatus)
{
case enumQuickActionRevisionStatus.unknown:
historyLine[0] = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.Unknown");
break;
case enumQuickActionRevisionStatus.inProgress:
historyLine[0] = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.InProgress");
break;
case enumQuickActionRevisionStatus.finishedSuccessfull:
historyLine[0] = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedSuccessfull");
break;
case enumQuickActionRevisionStatus.finishedWithError:
historyLine[0] = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedWithError");
break;
}
}
output.Reverse();
return output;
}
catch (Exception E)
{
LogException(E);
}
return null;
}
}
}

View File

@@ -0,0 +1,306 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using static C4IT.Logging.cLogManager;
using static System.Net.Mime.MediaTypeNames;
namespace FasdDesktopUi.Basics.Helper
{
public static class cRichTextBoxHelper
{
#region Unicode
public static void TraverseBlockAsUnicode(BlockCollection blocks, StringBuilder stringBuilder, bool isBlockFromList = false)
{
try
{
foreach (Block block in blocks)
{
if (block is Paragraph paragraph)
{
TraverseParagraphAsUnicode(paragraph, stringBuilder);
stringBuilder.AppendLine();
}
else if (block is List list)
{
TraverseListAsUnicode(list, stringBuilder);
stringBuilder.AppendLine();
}
else if (block is BlockUIContainer container)
{
if (container.Child is System.Windows.Controls.Image image)
{
TraverseImageAsUnicode(image, stringBuilder);
stringBuilder.AppendLine();
}
}
}
}
catch (Exception E)
{
LogException(E);
}
}
private static void TraverseParagraphAsUnicode(Paragraph paragraph, StringBuilder stringBuilder)
{
try
{
foreach (var inline in paragraph.Inlines)
{
if (inline is Run run)
{
stringBuilder.Append(run.Text);
}
}
}
catch (Exception E)
{
LogException(E);
}
}
private static void TraverseListAsUnicode(List list, StringBuilder stringBuilder)
{
try
{
if (list.MarkerStyle == TextMarkerStyle.Decimal)
{
for (int i = 0; i < list.ListItems.Count; i++)
{
stringBuilder.Append(i + 1 + ". ");
TraverseBlockAsUnicode(list.ListItems.ElementAt(i).Blocks, stringBuilder, true);
}
}
else
{
foreach (var item in list.ListItems)
{
stringBuilder.Append("- ");
TraverseBlockAsUnicode(item.Blocks, stringBuilder, true);
}
}
}
catch (Exception E)
{
LogException(E);
}
}
private static void TraverseImageAsUnicode(System.Windows.Controls.Image image, StringBuilder stringBuilder)
{
try
{
stringBuilder.Append("[Image]");
}
catch (Exception E)
{
LogException(E);
}
}
#endregion
#region Html
public static void TraverseBlockAsHtml(BlockCollection blocks, StringBuilder stringBuilder, bool isBlockFromList = false)
{
try
{
foreach (var block in blocks)
{
if (block is Paragraph paragraph)
{
if (!isBlockFromList)
stringBuilder.Append("<p>");
TraverseParagraphAsHtml(paragraph, stringBuilder);
if (!isBlockFromList)
stringBuilder.Append("</p>");
}
else if (block is List list)
{
stringBuilder.Append(list.MarkerStyle == TextMarkerStyle.Decimal ? "<ol>" : "<ul>");
TraverseListAsHtml(list, stringBuilder);
stringBuilder.Append(list.MarkerStyle == TextMarkerStyle.Decimal ? "</ol>" : "</ul>");
}
else if (block is BlockUIContainer container)
{
if (container.Child is System.Windows.Controls.Image image)
{
TraverseImageAsHtml(image, stringBuilder);
}
}
}
}
catch (Exception E)
{
LogException(E);
}
}
private static void TraverseParagraphAsHtml(Paragraph paragraph, StringBuilder stringBuilder)
{
try
{
foreach (var inline in paragraph.Inlines)
{
TraverseInlineAsHtml(inline, stringBuilder);
}
}
catch (Exception E)
{
LogException(E);
}
}
private static void TraverseInlineAsHtml(Inline inline, StringBuilder stringBuilder)
{
try
{
if (inline is Run run)
TraverseRunAsHtml(run, stringBuilder);
else if (inline is Span span)
{
foreach (var spanInline in span.Inlines)
{
TraverseInlineAsHtml(spanInline, stringBuilder);
}
}
}
catch (Exception E)
{
LogException(E);
}
}
private static void TraverseListAsHtml(List list, StringBuilder stringBuilder)
{
try
{
foreach (var listItem in list.ListItems)
{
stringBuilder.AppendLine("<li>");
TraverseBlockAsHtml(listItem.Blocks, stringBuilder, true);
stringBuilder.Append("</li>");
}
}
catch (Exception E)
{
LogException(E);
}
}
private static void TraverseImageAsHtml(System.Windows.Controls.Image image, StringBuilder stringBuilder)
{
try
{
byte[] arr;
using (MemoryStream ms = new MemoryStream())
{
var bmp = image.Source as BitmapImage;
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
encoder.Save(ms);
arr = ms.ToArray();
}
stringBuilder.AppendLine("<img src=\"data:image/png;base64,");
stringBuilder.Append(Convert.ToBase64String(arr));
stringBuilder.Append("\"/>");
}
catch (Exception E)
{
LogException(E);
}
}
public static void TraverseRunAsHtml(Run run, StringBuilder stringBuilder)
{
try
{
string styleString = string.Empty;
string runString = run.Text;
if (run.FontWeight == FontWeights.Bold)
{
runString = runString.Insert(0, "<strong>");
runString += "</strong>";
}
if (run.FontStyle == FontStyles.Italic)
{
runString = runString.Insert(0, "<em>");
runString += "</em>";
}
if (run.TextDecorations != null && run.TextDecorations.Count > 0)
{
if (run.TextDecorations.FirstOrDefault()?.Location == TextDecorationLocation.Underline)
{
runString = runString.Insert(0, "<u>");
runString += "</u>";
}
}
if (run.FontSize != 12)
styleString += $"font-size: {run.FontSize}px; ";
// default font size
//if (run.FontFamily != null)
// styleString += $"font-family: {run.FontFamily}; ";
//default color instead null:
//if (run.Foreground != null)
// styleString += $"color: {run.Foreground}; ";
if (!string.IsNullOrWhiteSpace(styleString))
{
styleString = styleString.Insert(0, "style=\"");
styleString += "\"";
}
stringBuilder.AppendLine("<span " + styleString + ">");
stringBuilder.Append(runString);
stringBuilder.Append("</span>");
}
catch (Exception E)
{
LogException(E);
}
}
#endregion
}
}

View File

@@ -0,0 +1,210 @@
using C4IT.Graphics;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.Helper
{
internal sealed class TrayTicketNotificationManager
{
private readonly NotifyIcon _notifyIcon;
private readonly object _syncRoot = new object();
private string _baseTooltip;
private string _currentTooltip;
private bool _overlayInitialized;
private const string OverlayKey = "TicketChanges";
private const string OverlaySetName = "OverlayTicketChanges";
public TrayTicketNotificationManager(NotifyIcon notifyIcon)
{
_notifyIcon = notifyIcon ?? throw new ArgumentNullException(nameof(notifyIcon));
}
public bool HasNotification
{
get
{
lock (_syncRoot)
return !string.IsNullOrWhiteSpace(_currentTooltip);
}
}
public void CaptureBaseTooltip()
{
lock (_syncRoot)
{
_baseTooltip = _notifyIcon.Text;
}
}
public void Show(string message)
{
if (string.IsNullOrWhiteSpace(message))
{
Clear();
return;
}
EnsureOverlaySet();
lock (_syncRoot)
{
_currentTooltip = BuildTooltip(message);
}
NotifyerSupport.SetNotifyIconOverlay(OverlayKey, OverlaySetName, NotifyerSupport.enumIconAlignment.TopRight, priority: 100);
ApplyTooltip();
}
public void Clear()
{
lock (_syncRoot)
{
_currentTooltip = null;
}
NotifyerSupport.SetNotifyIconOverlay(OverlayKey, null, NotifyerSupport.enumIconAlignment.TopRight);
ApplyTooltip();
}
public void ApplyTooltip()
{
if (_notifyIcon == null)
return;
string tooltip;
lock (_syncRoot)
{
tooltip = string.IsNullOrWhiteSpace(_currentTooltip)
? _baseTooltip
: $"F4SD - {_currentTooltip}";
}
_notifyIcon.Text = TrimTooltip(tooltip);
}
private void EnsureOverlaySet()
{
if (_overlayInitialized)
return;
try
{
var overlayFactories = new Dictionary<int, Func<Bitmap>>();
var sizeMap = new SortedDictionary<int, int>();
foreach (var size in NotifyerSupport.DefaultIconSizes)
{
var overlaySize = CalculateOverlayDiameter(size);
if (overlaySize <= 0)
continue;
sizeMap[size] = overlaySize;
if (!overlayFactories.ContainsKey(overlaySize))
{
var localSize = overlaySize;
overlayFactories[localSize] = () => CreateBadgeBitmap(localSize);
}
}
var iconSet = NotifyerSupport.RegisterDynamicSet(OverlaySetName, overlayFactories, NoRefresh: true)
?? NotifyerSupport.GetIconSet(OverlaySetName);
if (iconSet != null)
{
iconSet.SizeMap = sizeMap;
_overlayInitialized = true;
}
}
catch (Exception ex)
{
LogException(ex);
}
}
private static string BuildTooltip(string message)
{
try
{
var parts = message
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Select(part => part.Trim())
.Where(part => part.Length > 0);
var summary = string.Join(" | ", parts);
if (summary.Length > 140)
summary = summary.Substring(0, 139) + "…";
return summary;
}
catch
{
return message;
}
}
private static string TrimTooltip(string tooltip)
{
if (string.IsNullOrWhiteSpace(tooltip))
return tooltip;
tooltip = tooltip.Replace("\r", " ").Replace("\n", " ");
tooltip = tooltip.Trim();
return tooltip.Length <= 63
? tooltip
: tooltip.Substring(0, 63);
}
private static int CalculateOverlayDiameter(int baseSize)
{
if (baseSize <= 0)
return 0;
if (baseSize <= 18)
return 8;
if (baseSize <= 26)
return 10;
if (baseSize <= 36)
return 11;
var diameter = (int)Math.Round(baseSize * 0.22f);
return Math.Max(9, Math.Min(diameter, baseSize));
}
private static Bitmap CreateBadgeBitmap(int size)
{
var diameter = Math.Max(2, size);
var bitmap = new Bitmap(diameter, diameter, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
bitmap.SetResolution(96f, 96f);
using (var graphics = Graphics.FromImage(bitmap))
{
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.Clear(Color.Transparent);
int margin = 0;
if (diameter >= 12)
margin = Math.Max(1, (int)Math.Round(diameter * 0.08f));
else if (diameter >= 9)
margin = 1;
var circleSize = Math.Max(1, diameter - (margin * 2));
var circleRect = new Rectangle(margin, margin, circleSize, circleSize);
using (var brush = new SolidBrush(Color.FromArgb(235, 220, 0, 0)))
{
graphics.FillEllipse(brush, circleRect);
}
}
return bitmap;
}
}
}

View File

@@ -0,0 +1,316 @@
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UserControls.AdaptableIcon;
using MaterialIcons;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows;
using System.Reflection;
using static C4IT.Logging.cLogManager;
using F4SD_AdaptableIcon.Enums;
using FasdDesktopUi.Basics.Enums;
using System.Windows.Media;
namespace FasdDesktopUi.Basics.Helper
{
public class cUiElementHelper
{
public static FrameworkElement GetEditableControl(cEditableValueInformationBase editableValueInformation, bool isEditOnly, FrameworkElement parent, double? fontSize = null, FontWeight? fontWeight = null)
{
FrameworkElement output = null;
var textBlockStyle = (Style)Application.Current.FindResource("DetailsPage.Widget.Title");
var textBoxStyle = (Style)Application.Current.FindResource("Customizable.Editable.TextBox");
try
{
switch (editableValueInformation)
{
case cEditValueInformationText editValueText:
output = GetEditTextBox(editableValueInformation.CurrentValue.ToString(), string.Empty, fontSize ?? 12, fontWeight ?? FontWeights.Normal, false, true);
break;
case cEditValueInformationSelection editValueSelection:
{
if (editValueSelection.SelectionValues is null || editValueSelection.SelectionValues?.Count <= 0)
return null;
ComboBox editComboBox = new ComboBox();
foreach (var listValue in editValueSelection.SelectionValues)
{
ComboBoxItem tempComboBoxItem = new ComboBoxItem() { Content = listValue.Value, Tag = listValue.Key };
editComboBox.Items.Add(tempComboBoxItem);
}
var currentSelectedValue = editValueSelection.SelectionValues.FirstOrDefault(value => value.Key?.Equals(editValueSelection.CurrentValue) ?? false);
editComboBox.SelectedIndex = editValueSelection.SelectionValues.IndexOf(currentSelectedValue);
editComboBox.DropDownOpened += (sender, e) => cFocusInvoker.InvokeGotFocus(parent, e);
editComboBox.DropDownClosed += (sender, e) => cFocusInvoker.InvokeLostFocus(parent, e);
output = editComboBox;
if (!isEditOnly)
break;
StackPanel tempStackPanel = new StackPanel();
TextBlock tempTextBlock = new TextBlock() { Text = editValueSelection.Description, Style = textBlockStyle };
tempStackPanel.Children.Add(tempTextBlock);
tempStackPanel.Children.Add(editComboBox);
output = tempStackPanel;
}
break;
default:
break;
}
}
catch (Exception E)
{
LogException(E);
}
return output;
}
private static FrameworkElement GetEditTextBox(string contentText, string placeHolderText, double fontSize, FontWeight fontWeight, bool isPrimaryContent, bool isEditOnly)
{
ScrollViewer output = new ScrollViewer() { HorizontalScrollBarVisibility = ScrollBarVisibility.Auto, VerticalScrollBarVisibility = ScrollBarVisibility.Auto };
try
{
Grid mainGrid = new Grid();
var textBoxStyle = (Style)Application.Current.FindResource("Customizable.Editable.TextBox");
var textBoxStylePrimary = (Style)Application.Current.FindResource("Customizable.Editable.TextBox.Background");
var textBoxStyleEditOnly = (Style)Application.Current.FindResource("Customizable.Editable.TextBox.EditOnly");
TextBlock placeHolderTextBlock = new TextBlock() { Text = placeHolderText, FontSize = fontSize, FontWeight = fontWeight, IsHitTestVisible = false, Opacity = 0.7, Margin = new Thickness(13, 16, 13, 14) };
placeHolderTextBlock.SetResourceReference(TextBlock.ForegroundProperty, "FontColor.Menu.Categories");
TextBox contentTextBox = new TextBox() { Text = contentText, FontSize = fontSize, FontWeight = fontWeight, Style = textBoxStyle };
if (isPrimaryContent)
contentTextBox.Style = textBoxStylePrimary;
if (isEditOnly)
contentTextBox.Style = textBoxStyleEditOnly;
contentTextBox.TextChanged += (sender, e) => placeHolderTextBlock.Visibility = string.IsNullOrEmpty(contentTextBox.Text) ? Visibility.Visible : Visibility.Collapsed;
AdaptableIcon editIcon = new AdaptableIcon() { SelectedMaterialIcon = MaterialIconType.ic_edit, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Top, Visibility = isEditOnly ? Visibility.Visible : Visibility.Hidden, BorderPadding = new Thickness(7.5, 7.5, 0, 7.5) };
editIcon.SetResourceReference(AdaptableIcon.PrimaryIconColorProperty, "Color.Menu.Icon");
mainGrid.Children.Add(contentTextBox);
mainGrid.Children.Add(placeHolderTextBlock);
mainGrid.Children.Add(editIcon);
output.Content = mainGrid;
}
catch (Exception E)
{
LogException(E);
}
return output;
}
public static bool DrawCustomizableContainerComponent(IContainerData data, FrameworkElement parentElement, out FrameworkElement createdControl, Action<(FrameworkElement valueControl, FrameworkElement editControl)> addEditableControls = null)
{
createdControl = null;
try
{
var textBlockStyle = (Style)Application.Current.FindResource("DetailsPage.Widget.Title");
var textBoxStyle = (Style)Application.Current.FindResource("Customizable.Editable.TextBox");
switch (data)
{
case cContainerIcon containerIconData:
{
enumInternIcons? internIcon = null;
enumInternGif? internGif = null;
MaterialIconType? materialIcon = null;
if (Enum.TryParse<enumInternIcons>(containerIconData.IconName, out var tempInternIcon))
internIcon = tempInternIcon;
if (Enum.TryParse<enumInternGif>(containerIconData.IconName, out var tempInternGif))
internGif = tempInternGif;
if (Enum.TryParse<MaterialIconType>(containerIconData.IconName, out var tempMaterialIcon))
materialIcon = tempMaterialIcon;
createdControl = new AdaptableIcon()
{
SelectedInternIcon = internIcon,
SelectedInternGif = internGif,
SelectedMaterialIcon = materialIcon,
ToolTip = containerIconData.ToolTipText,
BorderPadding = new Thickness(0),
IconHeight = 14,
IconWidth = 14,
Margin = new Thickness(0, 0, 5, 0)
};
string iconResourceName = "Color.Menu.Icon";
switch (containerIconData.HighlightColor)
{
case enumHighlightColor.blue:
iconResourceName = "Color.Blue";
break;
case enumHighlightColor.green:
iconResourceName = "Color.Green";
break;
case enumHighlightColor.orange:
iconResourceName = "Color.Orange";
break;
case enumHighlightColor.red:
iconResourceName = "Color.Red";
break;
}
if (createdControl is AdaptableIcon createdAdaptable)
createdAdaptable.SetResourceReference(AdaptableIcon.PrimaryIconColorProperty, iconResourceName);
break;
}
case cContainerPrimaryContent primaryContentData:
{
if (primaryContentData.Value is cContainerValue primaryContentValueData)
{
string contentText = primaryContentValueData.IsEditOnly ? string.Empty : primaryContentValueData.DisplayValue;
string placeHolderText = primaryContentValueData.IsEditOnly ? primaryContentValueData.DisplayValue : string.Empty;
createdControl = GetEditTextBox(contentText, placeHolderText, primaryContentValueData.FontSize, primaryContentValueData.FontWeight, true, primaryContentValueData.IsEditOnly);
if (primaryContentValueData.IsEditOnly)
break;
if (primaryContentValueData.EditableValueInformation is null)
break;
var editControl = GetEditableControl(primaryContentValueData.EditableValueInformation, true, parentElement, primaryContentValueData.FontSize, primaryContentValueData.FontWeight);
editControl.Visibility = Visibility.Collapsed;
Grid tempCreatedControl = new Grid();
tempCreatedControl.Children.Add(createdControl);
tempCreatedControl.Children.Add(editControl);
addEditableControls?.Invoke((createdControl, editControl));
createdControl = tempCreatedControl;
}
else
{
var tempCreatedControl = new Border()
{
Padding = new Thickness(10),
Margin = new Thickness(0, 5, 0, 5),
CornerRadius = new CornerRadius(7.5)
};
tempCreatedControl.SetResourceReference(Control.BackgroundProperty, "BackgroundColor.DetailsPage.Widget.Title");
DrawCustomizableContainerComponent(primaryContentData.Value, parentElement, out var childElement, addEditableControls);
tempCreatedControl.Child = childElement;
createdControl = tempCreatedControl;
}
break;
}
case cContainerStackPanel stackPanelData:
{
var tempCreatedControl = new StackPanel() { Orientation = stackPanelData.Orientation };
foreach (var stackPanelElement in stackPanelData.StackPanelData)
{
bool wasAbleToDraw = DrawCustomizableContainerComponent(stackPanelElement, parentElement, out var childElement, addEditableControls);
if (!wasAbleToDraw)
continue;
tempCreatedControl.Children.Add(childElement);
}
createdControl = tempCreatedControl;
break;
}
case cContainerValue containerValueData:
{
var tempCreatedControl = new Grid();
if (containerValueData.IsEditOnly)
{
createdControl = cUiElementHelper.GetEditableControl(containerValueData.EditableValueInformation, true, parentElement);
break;
}
var valueControl = new TextBlock()
{
Text = containerValueData.DisplayValue,
TextWrapping = TextWrapping.Wrap,
FontSize = containerValueData.FontSize,
FontWeight = containerValueData.FontWeight,
Margin = new Thickness(0, 0, 5, 0),
Style = textBlockStyle
};
if (!string.IsNullOrEmpty(containerValueData.Description))
valueControl.ToolTip = containerValueData.Description;
if (containerValueData.EditableValueInformation != null)
{
var editControl = cUiElementHelper.GetEditableControl(containerValueData.EditableValueInformation, false, parentElement, containerValueData.FontSize, containerValueData.FontWeight);
addEditableControls?.Invoke((valueControl, editControl));
tempCreatedControl.Children.Add(editControl);
}
tempCreatedControl.Children.Add(valueControl);
createdControl = tempCreatedControl;
break;
}
}
return createdControl != null;
}
catch (Exception E)
{
LogException(E);
}
return false;
}
public static void AddChildToFrameworkElement(FrameworkElement parentElement, FrameworkElement childElement)
{
try
{
if (parentElement is Panel parentPanel)
parentPanel.Children.Add(childElement);
else if (parentElement is Decorator parentDecorator)
parentDecorator.Child = childElement;
}
catch (Exception E)
{
LogException(E);
}
}
public static T GetFirstParentOfType<T>(FrameworkElement element) where T : UIElement
{
try
{
if (element.Parent is null)
return null;
if (element.Parent is T parentElement)
return parentElement;
if (element.Parent is FrameworkElement parentFrameworkElement)
return GetFirstParentOfType<T>(parentFrameworkElement);
}
catch (Exception E)
{
LogException(E);
}
return null;
}
}
}