using C4IT.F4SD.DisplayFormatting; using C4IT.FASD.Base; using C4IT.MultiLanguage; using F4SD_AdaptableIcon.Enums; using FasdDesktopUi.Basics.Models; using FasdDesktopUi.Basics.UserControls; using FasdDesktopUi.Basics.UserControls.AdaptableIcon; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Animation; using static C4IT.Logging.cLogManager; namespace FasdDesktopUi.Basics { public static class cUtility { public static readonly IRawValueFormatter RawValueFormatter = new RawValueFormatter(); internal static RawValueType GetRawValueType(enumHealthCardDisplayTypes displayType) { switch (displayType) { case enumHealthCardDisplayTypes.STRING: return RawValueType.STRING; case enumHealthCardDisplayTypes.INTEGER: return RawValueType.INTEGER; case enumHealthCardDisplayTypes.PERCENT: return RawValueType.PERCENT; case enumHealthCardDisplayTypes.PERCENT100: return RawValueType.PERCENT100; case enumHealthCardDisplayTypes.PERCENT1000: return RawValueType.PERCENT1000; case enumHealthCardDisplayTypes.TIME: return RawValueType.TIME; case enumHealthCardDisplayTypes.DATE: return RawValueType.DATE; case enumHealthCardDisplayTypes.DATE_CALC: return RawValueType.DATE_CALC; case enumHealthCardDisplayTypes.DATETIME: return RawValueType.DATETIME; case enumHealthCardDisplayTypes.DURATION_DAY: return RawValueType.DURATION_DAY; case enumHealthCardDisplayTypes.DURATION_HOUR: return RawValueType.DURATION_HOUR; case enumHealthCardDisplayTypes.DURATION_MINUTE: return RawValueType.DURATION_MINUTE; case enumHealthCardDisplayTypes.DURATION_SECOND: return RawValueType.DURATION_SECOND; case enumHealthCardDisplayTypes.DURATION_MILLI: return RawValueType.DURATION_MILLI; case enumHealthCardDisplayTypes.DURATION_MICRO: return RawValueType.DURATION_MICRO; case enumHealthCardDisplayTypes.DURATION_DAY_SINCE_NOW: return RawValueType.DURATION_DAY_SINCE_NOW; case enumHealthCardDisplayTypes.BITS_PERSECOND: return RawValueType.BITS_PERSECOND; case enumHealthCardDisplayTypes.BYTES: return RawValueType.BYTES; case enumHealthCardDisplayTypes.HERTZ: return RawValueType.HERTZ; case enumHealthCardDisplayTypes.MEGA_HERTZ: return RawValueType.MEGA_HERTZ; default: return RawValueType.STRING; } } public static int SmoothedInt(int oldValue, int newValue) { if (oldValue < newValue) { return newValue - oldValue < 20 ? newValue : oldValue + 20; } else if (oldValue > newValue) { double flattenValue = (oldValue - newValue) / 7.0; return Convert.ToInt32(oldValue - Math.Ceiling(flattenValue)); } else { return oldValue; } } public static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { const int WM_GETMINMAXINFO = 0x0024; switch (msg) { case WM_GETMINMAXINFO: WmGetMinMaxInfo(hwnd, lParam, 300, 200); handled = true; break; } return IntPtr.Zero; } public static async Task ChangeIconToCheckAsync(AdaptableIcon copyIcon, int transitionTimeInMilliSeconds = 500) { try { if (copyIcon.SelectedInternIcon == enumInternIcons.misc_check) return; var currentPrimaryIconColorValue = copyIcon.ReadLocalValue(AdaptableIcon.PrimaryIconColorProperty); var tempSelectedIcon = copyIcon.GetCurrentIcon(); copyIcon.SetIcon((enumInternIcons.misc_check, null, null, null)); copyIcon.PrimaryIconColor = (SolidColorBrush)Application.Current.FindResource("Color.Green"); await Task.Delay(transitionTimeInMilliSeconds); copyIcon.SetIcon(tempSelectedIcon); copyIcon.SetValue(AdaptableIcon.PrimaryIconColorProperty, currentPrimaryIconColorValue); } catch (Exception E) { LogException(E); } } #region SetTickerTextAnimation public static void SetTickerTextAnimation(FrameworkElement TickerElement, FrameworkElement ParentElement) { try { const double marginPerSecond = 60.0; const double pauseDurationInSeconds = 0.5; ParentElement.Width = ParentElement.ActualWidth; if (TickerElement is TextBlock TickerTextBlock) TickerTextBlock.TextTrimming = TextTrimming.None; TickerElement.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var resultDesiredSize = TickerElement.DesiredSize; var missingSpace = resultDesiredSize.Width - ParentElement.ActualWidth; if (missingSpace <= 0) return; var animDurationInSeconds = missingSpace / marginPerSecond + pauseDurationInSeconds; ThicknessAnimationUsingKeyFrames thicknessAnimationUsingKeyFrames = new ThicknessAnimationUsingKeyFrames() { RepeatBehavior = RepeatBehavior.Forever, AutoReverse = true }; _ = thicknessAnimationUsingKeyFrames.KeyFrames.Add(new LinearThicknessKeyFrame(new Thickness(0), KeyTime.FromTimeSpan(TimeSpan.FromSeconds(pauseDurationInSeconds)))); _ = thicknessAnimationUsingKeyFrames.KeyFrames.Add(new LinearThicknessKeyFrame(new Thickness(-missingSpace, 0, 0, 0), KeyTime.FromTimeSpan(TimeSpan.FromSeconds(animDurationInSeconds)))); _ = thicknessAnimationUsingKeyFrames.KeyFrames.Add(new LinearThicknessKeyFrame(new Thickness(-missingSpace, 0, 0, 0), KeyTime.FromTimeSpan(TimeSpan.FromSeconds(animDurationInSeconds + pauseDurationInSeconds)))); TickerElement.BeginAnimation(FrameworkElement.MarginProperty, thicknessAnimationUsingKeyFrames); } catch (Exception E) { LogException(E); } finally { } } #endregion #region SizeRegulation public static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam, int MinX, int MinY) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); int MONITOR_DEFAULTTONEAREST = 0x00000002; IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); mmi.ptMinTrackSize.x = MinX; mmi.ptMinTrackSize.y = MinY; mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x; mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y; } Marshal.StructureToPtr(mmi, lParam, true); } [StructLayout(LayoutKind.Sequential)] public struct POINT { /// x coordinate of point. public int x; /// y coordinate of point. public int y; /// Construct a point of coordinates (x,y). public POINT(int x, int y) { this.x = x; this.y = y; } } [StructLayout(LayoutKind.Sequential)] public struct MINMAXINFO { public POINT ptReserved; public POINT ptMaxSize; public POINT ptMaxPosition; public POINT ptMinTrackSize; public POINT ptMaxTrackSize; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class MONITORINFO { public int cbSize = Marshal.SizeOf(typeof(MONITORINFO)); public RECT rcMonitor = new RECT(); public RECT rcWork = new RECT(); public int dwFlags = 0; } [StructLayout(LayoutKind.Sequential, Pack = 0)] public struct RECT { public int left; public int top; public int right; public int bottom; public static readonly RECT Empty = new RECT(); public int Width { get { return Math.Abs(right - left); } } public int Height { get { return bottom - top; } } public RECT(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } public RECT(RECT rcSrc) { left = rcSrc.left; top = rcSrc.top; right = rcSrc.right; bottom = rcSrc.bottom; } public bool IsEmpty { get { return left >= right || top >= bottom; } } public override string ToString() { if (this == Empty) { return "RECT {Empty}"; } return "RECT { left : " + left + " / top : " + top + " / right : " + right + " / bottom : " + bottom + " }"; } public override bool Equals(object obj) { if (!(obj is Rect)) { return false; } return (this == (RECT)obj); } /// Return the HashCode for this struct (not garanteed to be unique) public override int GetHashCode() => left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode(); /// Determine if 2 RECT are equal (deep compare) public static bool operator ==(RECT rect1, RECT rect2) { return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom); } /// Determine if 2 RECT are different(deep compare) public static bool operator !=(RECT rect1, RECT rect2) { return !(rect1 == rect2); } } [DllImport("user32")] internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi); [DllImport("User32")] internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags); #endregion public static System.Windows.Size GetDpiFactor() { using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero)) { double dpiX = graphics.DpiX / 96; double dpiY = graphics.DpiY / 96; dpiX = dpiX == 0 ? 1.0 : dpiX; dpiY = dpiY == 0 ? 1.0 : dpiY; var result = new Size { Width = dpiX, Height = dpiY }; return result; } } #region SetCurrentTextToClipboard [DllImport("User32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); public static void BringWindowToFront(Window w) { var hWnd = new WindowInteropHelper(w).Handle; SetForegroundWindow(hWnd); w.Focus(); } public static void SendCtrlCToCurrentWindow() { var hWnd = GetForegroundWindow(); uint KEYEVENTF_KEYUP = 2; byte VK_CONTROL = 0x11; SetForegroundWindow(hWnd); keybd_event(VK_CONTROL, 0, 0, 0); keybd_event(0x43, 0, 0, 0); //Send the C key (43 is "C") keybd_event(0x43, 0, KEYEVENTF_KEYUP, 0); keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);// 'Left Control Up } #endregion #region String Manipulation public static string CleanPhoneString(string input) { string output = input; try { if (input.Any(inputChar => char.IsLetter(inputChar))) return output; output = input.Replace(" ", ""); if (output.StartsWith("+")) output = output.Remove(0, 3); output = new string(output.Where(inputChar => char.IsDigit(inputChar)).ToArray()); } catch (Exception E) { LogException(E); } return output; } #endregion #region GetQuickActionCopyStrings internal static bool ShouldHideQuickActionOutput(string outputValueKey, cFasdQuickAction quickActionDefinition) { try { if (quickActionDefinition.ColumnOutputFormattings is null) return false; if (!quickActionDefinition.ShowAllOutputContent && !quickActionDefinition.ColumnOutputFormattings.ContainsKey(outputValueKey)) return true; if (quickActionDefinition.ColumnOutputFormattings.TryGetValue(outputValueKey, out var columnFormatting)) return columnFormatting.Hidden; } catch (Exception ex) { LogException(ex); } return false; } public static string GetHtmlFrame(string Content) { var strLen1 = (Content.Length + 142).ToString("D10"); var strLen2 = (Content.Length + 173).ToString("D10"); var RetVal = "Version:0.9\n"; RetVal += "StartHTML:0000000105\n"; RetVal += "EndHTML:" + strLen2 + "\n"; RetVal += "StartFragment:0000000139\n"; RetVal += "EndFragment:" + strLen1 + "\n"; RetVal += "\n"; RetVal += Content + "\n"; RetVal += ""; return RetVal; } #endregion #region ToolTipHandling public static void FillTresholdToolTip(cStateThresholdValues _v, StatusTreshholdTooltip _t) { try { FormattingOptions options = new FormattingOptions() { ReferenceDate = DateTime.UtcNow.AddDays(_v.ReferenceDays) }; RawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage)); var _strVal = RawValueFormatter.GetDisplayValue(_v.Value, GetRawValueType(_v.StateDefinition.DisplayType), options); _t.rawValue.Text = _strVal; if (_v.StateDefinition is cHealthCardStateLevel _sl) { _strVal = RawValueFormatter.GetDisplayValue(_sl.Warning, GetRawValueType(_v.StateDefinition.DisplayType), options); _t.tresholdWarning.Text = _strVal; _strVal = RawValueFormatter.GetDisplayValue(_sl.Error, GetRawValueType(_v.StateDefinition.DisplayType), options); _t.tresholdError.Text = _strVal; } else if (_v.StateDefinition is cHealthCardStateVersion _sv) { _strVal = RawValueFormatter.GetDisplayValue(_sv.Warning, GetRawValueType(_v.StateDefinition.DisplayType), options); _t.tresholdWarning.Text = _strVal; _strVal = RawValueFormatter.GetDisplayValue(_sv.Error, GetRawValueType(_v.StateDefinition.DisplayType), options); _t.tresholdError.Text = _strVal; } else if (_v.StateDefinition is cHealthCardStateDateTime _sd) { _strVal = RawValueFormatter.GetDisplayValue(_sd.WarningHours, RawValueType.DURATION_HOUR, options); _t.tresholdWarning.Text = _strVal; _strVal = RawValueFormatter.GetDisplayValue(_sd.ErrorHours, RawValueType.DURATION_HOUR, options); _t.tresholdError.Text = _strVal; } else if (_v.StateDefinition is cHealthCardStateTranslation _st) { var _trans = cF4SDHealthCardConfig.GetTranslationsWithName(_st, _st.Translation); var strVal = _v.Value.ToString(); if (_trans is cHealthCardTranslator _trans2) { _strVal = null; cHealthCardTranslator.cEntry tEntry = null; foreach (var _trans3 in _trans2.Translations) { if (_trans3.Values.Any(v => v.Equals(strVal, StringComparison.InvariantCultureIgnoreCase))) { tEntry = _trans3; break; } } if (tEntry == null) { tEntry = _trans2.DefaultTranslation; _strVal = _trans2.DefaultTranslation.Translation.GetValue(_v.Value.ToString()); } if (tEntry == null) _strVal = _v.Value.ToString(); else _strVal = tEntry.Translation.GetValue(Default: _v.Value.ToString()); _t.rawValue.Text = _strVal; var _Warning = ""; foreach (var trEntry in _trans2.Translations.Where(v => v.StateLevel == enumHealthCardStateLevel.Warning)) { if (_Warning != "") _Warning += " "; _Warning += trEntry.Translation.GetValue(); } var _Error = ""; foreach (var trEntry in _trans2.Translations.Where(v => v.StateLevel == enumHealthCardStateLevel.Error)) { if (_Error != "") _Error += " "; _Error += trEntry.Translation.GetValue(); } if (_trans2.DefaultTranslation.StateLevel == enumHealthCardStateLevel.Warning) { if (_Warning != "") _Warning += " "; _Warning += _trans2.DefaultTranslation.Translation.GetValue(); } if (_trans2.DefaultTranslation.StateLevel == enumHealthCardStateLevel.Error) { if (_Error != "") _Error += " "; _Error += _trans2.DefaultTranslation.Translation.GetValue(); } _t.tresholdWarning.Text = _Warning; _t.tresholdError.Text = _Error; } } else { _t.tresholdWarning.Text = ""; _t.tresholdError.Text = ""; } } catch (Exception E) { LogException(E); } } #endregion } }