using C4IT.F4SD.DisplayFormatting; using C4IT.F4SD.SupportCaseProtocoll.Models; using C4IT.FASD.Base; using C4IT.MultiLanguage; using F4SD_AdaptableIcon.Enums; using FasdDesktopUi.Basics.Converter; using FasdDesktopUi.Basics.Models; using FasdDesktopUi.Basics.Services.ProtocollService; using FasdDesktopUi.Basics.UiActions; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; using System.Windows.Media; using static C4IT.Logging.cLogManager; namespace FasdDesktopUi.Basics.UserControls { public partial class QuickActionStatusMonitor : UserControl, IBlurInvoker { private const string veiledText = "********"; private bool secretsAreShown = false; private readonly IRawValueFormatter _rawValueFormatter = new RawValueFormatter(); #region Helperclasses QuickAction Output public abstract class cQuickActionOutput { protected readonly IRawValueFormatter _rawValueFormatter = new RawValueFormatter(); public cQuickActionOutput(cF4sdQuickActionRevision.cOutput scriptOutput) { _rawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage)); _rawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local); ErrorCode = scriptOutput.ErrorCode; ErrorDescription = scriptOutput.ErrorDescription; ResultCode = scriptOutput.ResultCode.GetValueOrDefault(); IsError = HasError(scriptOutput); } public cSupportCaseDataProvider DataProvider { get; private set; } public enumQuickActionSuccess? ResultCode { get; set; } public int? ErrorCode { get; set; } public string ErrorDescription { get; set; } public bool IsError { get; private set; } internal static KeyValuePair GetDisplayType(dynamic columnTypeObject) { var output = new KeyValuePair(); try { var columnType = columnTypeObject.ToObject(); string name = string.Empty; RawValueType type = RawValueType.STRING; if (columnType.Name != null) if (columnType.Name is Newtonsoft.Json.Linq.JValue nameJValue) name = nameJValue.Value.ToString(); if (columnType.Type != null) if (columnType.Type is Newtonsoft.Json.Linq.JValue typeJValue) if (Enum.TryParse(typeJValue.Value.ToString(), out RawValueType typeJValueType)) type = typeJValueType; output = new KeyValuePair(name, type); } catch (Exception E) { LogException(E); } return output; } public static cQuickActionOutput GetQuickActionOutput(cF4sdQuickActionRevision.cOutput scriptOutput, cSupportCaseDataProvider dataProvider) { if (scriptOutput == null) return null; try { if (scriptOutput?.Values == null) { var output = new cQuickActionOutputSingle(scriptOutput) { DataProvider = dataProvider }; return output; } else if (scriptOutput.Values is JArray scriptValueJArray) { var scriptValues = scriptValueJArray.ToObject>(); if (scriptValues != null && scriptValues.Count > 0) { var output = new cQuickActionOutputList(scriptOutput) { DataProvider = dataProvider }; foreach (var scriptValue in scriptValues) { if (scriptValue is JObject scriptValueJObject) { try { var scriptValueHelperDictionary = scriptValueJObject.ToObject>(); output.Values.Add(scriptValueHelperDictionary.ToList()); } catch (Exception E) { LogException(E); } } } return output; } } else if (scriptOutput.Values is JObject scriptValueJObject) { try { var output = new cQuickActionOutputObject(scriptOutput) { DataProvider = dataProvider }; return output; } catch (Exception E) { LogException(E); } } else { return new cQuickActionOutputSingle(scriptOutput) { DataProvider = dataProvider }; } } catch (Exception E) { LogException(E); } return null; } public static bool HasError(cF4sdQuickActionRevision.cOutput quickActionOutput) { if ((quickActionOutput?.ResultCode == null || quickActionOutput?.ResultCode == enumQuickActionSuccess.finished || quickActionOutput?.ResultCode == enumQuickActionSuccess.successfull) && (quickActionOutput?.ErrorCode == null || quickActionOutput?.ErrorCode == 0) && string.IsNullOrEmpty(quickActionOutput?.ErrorDescription)) return false; return true; } } public class cQuickActionOutputSingle : cQuickActionOutput { public cQuickActionOutputSingle(cF4sdQuickActionRevision.cOutput scriptOutput) : base(scriptOutput) { Instantiate(scriptOutput); } public RawValueType DisplayType { get; set; } public string Key { get; set; } public object Value { get; set; } private void Instantiate(cF4sdQuickActionRevision.cOutput scriptOutput) { try { Value = scriptOutput.Values; if (scriptOutput.Values is JObject scriptValueJObject) { string scriptValueKey = null; try { var scriptValueHelperDictionary = scriptValueJObject.ToObject>(); scriptValueKey = scriptValueHelperDictionary.Keys.ToList()[0]; Key = scriptValueKey; Value = scriptValueHelperDictionary[scriptValueKey]; } catch (Exception E) { LogException(E); } if (scriptOutput.ColumnTypes is JArray columnTypeJArray) { var columnTypes = columnTypeJArray.ToObject>(); if (columnTypes != null && columnTypes.Count > 0) { foreach (var columnTypeObject in columnTypes) { var displayType = cQuickActionOutput.GetDisplayType(columnTypeObject); if (displayType.Key == scriptValueKey) DisplayType = displayType.Value; } } } else if (scriptOutput.ColumnTypes is JObject columnTypeJObject) { try { var dispayType = cQuickActionOutput.GetDisplayType(columnTypeJObject); DisplayType = dispayType.Value; } catch (Exception E) { LogException(E); } } } } catch (Exception E) { LogException(E); } } public string GetDisplayValue(Dictionary columnOutputFormattings, bool getSecretValue = false) { string output = null; try { output = _rawValueFormatter.GetDisplayValue(Value, DisplayType); cColumnOutputFormatting outputFormatting = null; if (string.IsNullOrEmpty(Key)) outputFormatting = columnOutputFormattings?.Values.FirstOrDefault(); else columnOutputFormattings?.TryGetValue(Key, out outputFormatting); if (outputFormatting != null) { if (outputFormatting.IsSecret && !getSecretValue) return veiledText; if (outputFormatting.DisplayType != null) output = _rawValueFormatter.GetDisplayValue(Value, outputFormatting.DisplayType.Value); if (outputFormatting.Translation != null) { var abstractTranslation = cF4SDHealthCardConfig.GetTranslationsWithName(DataProvider?.HealthCardDataHelper?.SelectedHealthCard, outputFormatting.Translation); if (abstractTranslation != null && abstractTranslation is cHealthCardTranslator translator) { output = translator.DefaultTranslation?.Translation.GetValue() ?? Value.ToString(); foreach (var translation in translator.Translations) { if (translation.Values.Any(value => value.Equals(Value.ToString(), StringComparison.InvariantCultureIgnoreCase))) output = translation.Translation.GetValue(); } } } } } catch (Exception E) { LogException(E); } return output; } } public class cQuickActionOutputObject : cQuickActionOutput { public Dictionary DisplayTypes { get; set; } = new Dictionary(); public List> Values { get; set; } = new List>(); public cQuickActionOutputObject(cF4sdQuickActionRevision.cOutput scriptOutput) : base(scriptOutput) { try { InstantiateDisplayTypes(scriptOutput); InstantiateValues(scriptOutput); } catch (Exception E) { LogException(E); } } private void InstantiateDisplayTypes(cF4sdQuickActionRevision.cOutput scriptOutput) { try { if (scriptOutput.ColumnTypes is Newtonsoft.Json.Linq.JArray columnTypeJArray) { var columnTypes = columnTypeJArray.ToObject>(); if (columnTypes != null && columnTypes.Count > 0) { foreach (var columnTypeObject in columnTypes) { var displayType = GetDisplayType(columnTypeObject); DisplayTypes[displayType.Key] = displayType.Value; } } } else if (scriptOutput.ColumnTypes is Newtonsoft.Json.Linq.JObject columnTypeJObject) { try { var displayType = GetDisplayType(columnTypeJObject); DisplayTypes[displayType.Key] = displayType.Value; } catch (Exception E) { LogException(E); } } } catch (Exception E) { LogException(E); } } private void InstantiateValues(cF4sdQuickActionRevision.cOutput scriptOutput) { try { if (!(scriptOutput.Values is JObject valuesJObject)) return; if (valuesJObject.Properties() == null) return; foreach (var property in valuesJObject.Properties()) { Values.Add(new KeyValuePair(property.Name, property.Value)); } } catch (Exception E) { LogException(E); } } public string GetDisplayValue(int index, Dictionary columnOutputFormattings, bool getSecretValue = false) { string output = null; try { if (Values.Count <= index) return null; var selectedItem = Values[index]; RawValueType displayType = RawValueType.STRING; DisplayTypes.TryGetValue(selectedItem.Key, out displayType); output = _rawValueFormatter.GetDisplayValue(selectedItem.Value, displayType); if (columnOutputFormattings != null && columnOutputFormattings.TryGetValue(selectedItem.Key, out var outputFormatting)) { if (outputFormatting.Hidden) return string.Empty; if (outputFormatting.IsSecret && !getSecretValue) return veiledText; if (outputFormatting.DisplayType != null) output = _rawValueFormatter.GetDisplayValue(selectedItem.Value, outputFormatting.DisplayType.Value); if (outputFormatting.Translation != null) { var abstractTranslation = cF4SDHealthCardConfig.GetTranslationsWithName(DataProvider?.HealthCardDataHelper?.SelectedHealthCard, outputFormatting.Translation); if (abstractTranslation != null && abstractTranslation is cHealthCardTranslator translator) { output = translator.DefaultTranslation?.Translation.GetValue() ?? selectedItem.Value.ToString(); foreach (var translation in translator.Translations) { if (translation.Values.Any(value => value.Equals(selectedItem.Value.ToString(), StringComparison.InvariantCultureIgnoreCase))) output = translation.Translation.GetValue(); } } } } } catch (Exception E) { LogException(E); } return output; } } public class cQuickActionOutputList : cQuickActionOutput { public cQuickActionOutputList(cF4sdQuickActionRevision.cOutput scriptOutput) : base(scriptOutput) { InstantiateDisplayTypes(scriptOutput); } public Dictionary DisplayTypes { get; set; } = new Dictionary(); public List>> Values { get; set; } = new List>>(); private void InstantiateDisplayTypes(cF4sdQuickActionRevision.cOutput scriptOutput) { try { if (scriptOutput.ColumnTypes is Newtonsoft.Json.Linq.JArray columnTypeJArray) { var columnTypes = columnTypeJArray.ToObject>(); if (columnTypes != null && columnTypes.Count > 0) { foreach (var columnTypeObject in columnTypes) { var displayType = GetDisplayType(columnTypeObject); DisplayTypes[displayType.Key] = displayType.Value; } } } else if (scriptOutput.ColumnTypes is Newtonsoft.Json.Linq.JObject columnTypeJObject) { try { var displayType = GetDisplayType(columnTypeJObject); DisplayTypes[displayType.Key] = displayType.Value; } catch (Exception E) { LogException(E); } } } catch (Exception E) { LogException(E); } } public string GetDisplayValue(int row, int column, Dictionary columnOutputFormattings, bool getSecretValue = false) { string output = null; try { RawValueType displayType = RawValueType.STRING; DisplayTypes.TryGetValue(Values[row][column].Key, out displayType); output = _rawValueFormatter.GetDisplayValue(Values[row][column].Value, displayType); if (columnOutputFormattings != null && columnOutputFormattings.TryGetValue(Values[row][column].Key, out var outputFormatting)) { if (outputFormatting.Hidden) return string.Empty; if (outputFormatting.IsSecret && !getSecretValue) return veiledText; if (outputFormatting.DisplayType != null) output = _rawValueFormatter.GetDisplayValue(Values[row][column].Value, outputFormatting.DisplayType.Value); if (outputFormatting.Translation != null) { var abstractTranslation = cF4SDHealthCardConfig.GetTranslationsWithName(DataProvider?.HealthCardDataHelper?.SelectedHealthCard, outputFormatting.Translation); if (abstractTranslation != null && abstractTranslation is cHealthCardTranslator translator) { output = translator.DefaultTranslation?.Translation.GetValue() ?? Values[row].ToList()[column].Value.ToString(); foreach (var translation in translator.Translations) { if (translation.Values.Any(value => value.Equals(Values[row].ToList()[column].Value.ToString(), StringComparison.InvariantCultureIgnoreCase))) output = translation.Translation.GetValue(); } } } } } catch (Exception E) { LogException(E); } return output; } } public class cQuickActionMeasureValue { public int Id { get; set; } public cMultiLanguageDictionary Names { get; set; } public object Value { get; set; } public object PostValue { get; set; } public object Difference { get { switch (Display) { case RawValueType.INTEGER: case RawValueType.PERCENT: case RawValueType.PERCENT100: case RawValueType.PERCENT1000: case RawValueType.BYTES: var valueDouble = cF4SDHealthCardRawData.GetDouble(Value); var postValueDouble = cF4SDHealthCardRawData.GetDouble(PostValue); if (valueDouble != null && postValueDouble != null) return postValueDouble - valueDouble; break; } return null; } } public RawValueType Display { get; set; } } #endregion #region Properties private CancellationTokenSource tokenSource; private bool quickActionIsRunning = false; private cQuickActionStatusMonitorModel tempQuickActionData; private readonly RevisionStatusToAdaptableIconConverter revisionStatusToIconConverter = new RevisionStatusToAdaptableIconConverter(); public cSupportCaseDataProvider DataProvider { get; set; } public bool HasQuickActionDataChangedSinceRun { get => QuickActionData == null || !QuickActionData.Equals(tempQuickActionData); } #region QuickActionData private static void QuickActionDataChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is QuickActionStatusMonitor _me && e.NewValue is cQuickActionStatusMonitorModel quickActionData) { _me.SetQuickActionCompletionSteps(quickActionData.ActionSteps); _me.CopyButton.Visibility = Visibility.Collapsed; _me.secretsAreShown = false; _me.SecretButton.SelectedMaterialIcon = MaterialIcons.MaterialIconType.ic_visibility; _me.SecretButton.Visibility = Visibility.Collapsed; _me.AdjustableParameterSectionUc.ToggleIsActive(true); } } public static readonly DependencyProperty QuickActionDataProperty = DependencyProperty.Register("QuickActionData", typeof(cQuickActionStatusMonitorModel), typeof(QuickActionStatusMonitor), new PropertyMetadata(new cQuickActionStatusMonitorModel(), new PropertyChangedCallback(QuickActionDataChangedCallback))); public cQuickActionStatusMonitorModel QuickActionData { get { return (cQuickActionStatusMonitorModel)GetValue(QuickActionDataProperty); } set { SetValue(QuickActionDataProperty, value); } } #endregion #region IsCloseButtonVisible public static readonly DependencyProperty IsCloseButtonVisibleProperty = DependencyProperty.Register("IsCloseButtonVisible", typeof(bool), typeof(QuickActionStatusMonitor), new PropertyMetadata(false)); public bool IsCloseButtonVisible { get { return (bool)GetValue(IsCloseButtonVisibleProperty); } set { SetValue(IsCloseButtonVisibleProperty, value); } } #endregion #region QuickActionOutputs private ObservableCollection quickActionOutputs = new ObservableCollection(); public ObservableCollection QuickActionOutputs { get { return quickActionOutputs; } set { QuickActionResultStack.Children.Clear(); quickActionOutputs.CollectionChanged -= QuickActionOutputsChanged; quickActionOutputs = value; quickActionOutputs.CollectionChanged += QuickActionOutputsChanged; } } private void QuickActionOutputsChanged(object sender, NotifyCollectionChangedEventArgs e) { try { if (e.Action is NotifyCollectionChangedAction.Reset) QuickActionResultStack.Children.Clear(); if (e.Action is NotifyCollectionChangedAction.Add) { foreach (cF4sdQuickActionRevision.cOutput quickActionOutput in e.NewItems) { try { if (!cQuickActionOutput.HasError(quickActionOutput)) { if (quickActionOutput?.Values is null) continue; var helperQuickActionOutput = cQuickActionOutput.GetQuickActionOutput(quickActionOutput, DataProvider); if (helperQuickActionOutput is null) continue; if (helperQuickActionOutput is cQuickActionOutputObject outObj && outObj.Values.Count <= 0) continue; if (helperQuickActionOutput is cQuickActionOutputList outList && outList.Values.Count <= 0) continue; } var outputElement = new QuickActionStatusMonitorResultElement(); outputElement.SetQuickActionOutputData(quickActionOutput, DataProvider, QuickActionData.QuickActionDefinition); QuickActionResultStack.Children.Add(outputElement); } catch (Exception E) { LogException(E); } } } } catch (Exception E) { LogException(E); } } #endregion #region QuickActionMeasureValues private static void QuickActionMeasureValuesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!(d is QuickActionStatusMonitor _me)) return; if (!(e.NewValue is List newValue)) return; _me.UpdateQuickActionMeasureValues(newValue); } public static readonly DependencyProperty MeasureValuesProperty = DependencyProperty.Register("MeasureValues", typeof(List), typeof(QuickActionStatusMonitor), new PropertyMetadata(null, new PropertyChangedCallback(QuickActionMeasureValuesChanged))); public List MeasureValues { get { return (List)GetValue(MeasureValuesProperty); } set { SetValue(MeasureValuesProperty, value); } } #endregion public Action CloseButtonClickedAction { get; set; } #endregion public QuickActionStatusMonitor() { InitializeComponent(); tokenSource = new CancellationTokenSource(); quickActionOutputs.CollectionChanged += QuickActionOutputsChanged; } public void BlurInvoker_IsActiveChanged(object sender, DependencyPropertyChangedEventArgs e) { BlurInvoker.InvokeVisibilityChanged(this, new EventArgs()); } public bool BlurInvoker_IsActive => IsVisible; public void SetQuickActionCompletionSteps(List ActionSteps) { try { ResetExecuteButton(); //required to prevent binding errors //todo: add clean way to remove bindings of Quick Action Steps foreach (var child in CompletionStatusPanel.Children) { if (!(child is Panel panelElement)) continue; foreach (var childElement in panelElement.Children) { if (childElement is AdaptableIcon.AdaptableIcon childIcon) { BindingOperations.ClearBinding(childIcon, AdaptableIcon.AdaptableIcon.SelectedInternIconProperty); BindingOperations.ClearBinding(childIcon, AdaptableIcon.AdaptableIcon.SelectedInternGifProperty); BindingOperations.ClearBinding(childIcon, AdaptableIcon.AdaptableIcon.SelectedMaterialIconProperty); } if (childElement is Panel childPanel) { foreach (var panelChildElement in childPanel.Children) { if (panelChildElement is AdaptableIcon.AdaptableIcon panelChildIcon) { BindingOperations.ClearBinding(panelChildIcon, AdaptableIcon.AdaptableIcon.SelectedInternIconProperty); BindingOperations.ClearBinding(panelChildIcon, AdaptableIcon.AdaptableIcon.SelectedInternGifProperty); BindingOperations.ClearBinding(panelChildIcon, AdaptableIcon.AdaptableIcon.SelectedMaterialIconProperty); } } } } } CompletionStatusPanel.Children.Clear(); if (ActionSteps == null || ActionSteps.Count < 1) return; foreach (var step in ActionSteps) { DockPanel actionStepStatusPanel = new DockPanel() { Margin = new Thickness(0, 2.5, 0, 2.5), LastChildFill = false }; DockPanel.SetDock(actionStepStatusPanel, Dock.Top); AdaptableIcon.AdaptableIcon completionIcon = new AdaptableIcon.AdaptableIcon() { IconHeight = 12, IconWidth = 12, BorderPadding = new Thickness(0) }; Binding adaptableIconBinding = new Binding($"QuickActionData.ActionSteps[{ActionSteps.IndexOf(step)}].Status") { ElementName = nameof(QuickActionStatusMonitorUc), Converter = revisionStatusToIconConverter }; completionIcon.SetBinding(AdaptableIcon.AdaptableIcon.SelectedInternIconProperty, adaptableIconBinding); completionIcon.SetBinding(AdaptableIcon.AdaptableIcon.SelectedInternGifProperty, adaptableIconBinding); completionIcon.SetBinding(AdaptableIcon.AdaptableIcon.SelectedMaterialIconProperty, adaptableIconBinding); TextBlock actionStepTextBlock = new TextBlock() { Text = step.DisplayName, Margin = new Thickness(5, 0, 5, 0) }; DockPanel.SetDock(completionIcon, Dock.Left); DockPanel.SetDock(actionStepTextBlock, Dock.Left); actionStepStatusPanel.Children.Add(completionIcon); actionStepStatusPanel.Children.Add(actionStepTextBlock); CompletionStatusPanel.Children.Add(actionStepStatusPanel); if (step.SubSteps?.Count > 0) { StackPanel subStackPanel = new StackPanel() { Margin = new Thickness(25, 0, 0, 0), Visibility = Visibility.Collapsed, Tag = step.QuickActionName }; DockPanel.SetDock(subStackPanel, Dock.Top); foreach (var subStep in step.SubSteps) { DockPanel subActionStepStatusPanel = new DockPanel() { Margin = new Thickness(0, 2.5, 0, 2.5), LastChildFill = false }; DockPanel.SetDock(subActionStepStatusPanel, Dock.Top); AdaptableIcon.AdaptableIcon subCompletionIcon = new AdaptableIcon.AdaptableIcon() { IconHeight = 12, IconWidth = 12, BorderPadding = new Thickness(0) }; Binding subAdaptableIconBinding = new Binding($"QuickActionData.ActionSteps[{ActionSteps.IndexOf(step)}].SubSteps[{step.SubSteps.IndexOf(subStep)}].Status") { ElementName = nameof(QuickActionStatusMonitorUc), Converter = revisionStatusToIconConverter }; subCompletionIcon.SetBinding(AdaptableIcon.AdaptableIcon.SelectedInternIconProperty, subAdaptableIconBinding); subCompletionIcon.SetBinding(AdaptableIcon.AdaptableIcon.SelectedInternGifProperty, subAdaptableIconBinding); subCompletionIcon.SetBinding(AdaptableIcon.AdaptableIcon.SelectedMaterialIconProperty, subAdaptableIconBinding); TextBlock subActionStepTextBlock = new TextBlock() { Text = subStep.DisplayName, Margin = new Thickness(5, 0, 5, 0) }; DockPanel.SetDock(subCompletionIcon, Dock.Left); DockPanel.SetDock(subActionStepTextBlock, Dock.Left); subActionStepStatusPanel.Children.Add(subCompletionIcon); subActionStepStatusPanel.Children.Add(subActionStepTextBlock); subStackPanel.Children.Add(subActionStepStatusPanel); } CompletionStatusPanel.Children.Add(subStackPanel); } } } catch (Exception E) { LogException(E); } } private void UpdateQuickActionMeasureValues(List measureValues) { try { MeasureValueGrid.Children.Clear(); MeasureValueGrid.RowDefinitions.Clear(); if (measureValues?.Count <= 0) return; _rawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage)); _rawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local); for (int i = 0; i < measureValues.Count; i++) { var measureValue = measureValues[i]; MeasureValueGrid.RowDefinitions.Add(new RowDefinition()); WrapPanel wrapPanel = new WrapPanel() { Orientation = Orientation.Horizontal }; Border titleBorder = new Border() { Padding = new Thickness(5, 2.5, 5, 2.5) }; TextBlock titleTextBlock = new TextBlock() { Text = measureValue.Names.GetValue(), TextWrapping = TextWrapping.Wrap, VerticalAlignment = VerticalAlignment.Center, Style = (Style)FindResource("DetailsPage.DataHistory.TitleColumn.OverviewTitle") }; titleBorder.Child = titleTextBlock; wrapPanel.Children.Add(titleBorder); TextBlock valueTextBlock = new TextBlock() { Text = _rawValueFormatter.GetDisplayValue(measureValue.Value, measureValue.Display), Margin = new Thickness(5, 2.5, 5, 2.5), VerticalAlignment = VerticalAlignment.Center, FontWeight = FontWeights.Normal, Style = (Style)FindResource("DetailsPage.DataHistory.TitleColumn.OverviewTitle") }; wrapPanel.Children.Add(valueTextBlock); TextBlock arrowTextBlock = new TextBlock() { Text = "➜", VerticalAlignment = VerticalAlignment.Center, Style = (Style)FindResource("DetailsPage.DataHistory.TitleColumn.OverviewTitle") }; wrapPanel.Children.Add(arrowTextBlock); TextBlock postValueTextBlock = new TextBlock() { Text = _rawValueFormatter.GetDisplayValue(measureValue.PostValue, measureValue.Display), Margin = new Thickness(5, 2.5, 5, 2.5), VerticalAlignment = VerticalAlignment.Center, FontWeight = FontWeights.Bold, Style = (Style)FindResource("DetailsPage.DataHistory.TitleColumn.OverviewTitle") }; wrapPanel.Children.Add(postValueTextBlock); if (measureValue.Difference != null) { TextBlock differenceTextBlock = new TextBlock() { Text = $"(∆ {_rawValueFormatter.GetDisplayValue(measureValue.Difference, measureValue.Display)})", VerticalAlignment = VerticalAlignment.Center, FontWeight = FontWeights.Normal, Style = (Style)FindResource("DetailsPage.DataHistory.TitleColumn.OverviewTitle") }; wrapPanel.Children.Add(differenceTextBlock); } Grid.SetRow(wrapPanel, i); MeasureValueGrid.Children.Add(wrapPanel); } } catch (Exception E) { LogException(E); } } #region Events #region CloseButton_Click private void CloseButton_Click() { CloseButtonClickedAction?.Invoke(); } private void CloseButton_MouseUp(object sender, MouseButtonEventArgs e) { CloseButton_Click(); } private void CloseButton_TouchDown(object sender, TouchEventArgs e) { CloseButton_Click(); } #endregion #region ExecuteButton_Click private void ResetExecuteButton() { try { ExecuteButton.SelectedInternIcon = enumInternIcons.misc_play; ExecuteButton.SelectedMaterialIcon = null; ExecuteButton.BorderPadding = new Thickness(2.5); ExecuteButton.ClearValue(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty); ExecuteButton.ClearValue(CursorProperty); ExecuteButton.ClearValue(IsHitTestVisibleProperty); } catch (Exception E) { LogException(E); } } public void CancelQuickAction() { try { tokenSource.Cancel(true); quickActionIsRunning = false; ResetExecuteButton(); } catch (Exception E) { LogException(E); } } private void VisualizeQuickActionStart() { try { ExecuteButton.ClearValue(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty); ExecuteButton.SelectedInternIcon = null; ExecuteButton.SelectedMaterialIcon = MaterialIcons.MaterialIconType.ic_stop; ExecuteButton.BorderPadding = new Thickness(0); cQuickActionStatusMonitorModel.cQuickActionStep.SetAllQuickActionStepStatuses(QuickActionData.ActionSteps, enumQuickActionRevisionStatus.inProgress); } catch (Exception E) { LogException(E); } } public void VisualizeQuickActionFinish(enumQuickActionRevisionStatus status) { if (HasQuickActionDataChangedSinceRun) //todo: think about better solution return; switch (status) { case enumQuickActionRevisionStatus.finishedSuccessfull: ExecuteButton.SelectedMaterialIcon = null; ExecuteButton.SelectedInternIcon = enumInternIcons.status_good; ExecuteButton.PrimaryIconColor = (SolidColorBrush)FindResource("Color.Green"); ExecuteButton.IsHitTestVisible = false; break; case enumQuickActionRevisionStatus.finishedWithError: ExecuteButton.SelectedMaterialIcon = null; ExecuteButton.SelectedInternIcon = enumInternIcons.status_bad; ExecuteButton.PrimaryIconColor = (SolidColorBrush)FindResource("Color.Red"); ExecuteButton.IsHitTestVisible = false; break; case enumQuickActionRevisionStatus.canceled: default: ResetExecuteButton(); break; } } public async Task RunQuickActionAsync() { var status = enumQuickActionRevisionStatus.unknown; try { tokenSource.Dispose(); tokenSource = new CancellationTokenSource(); quickActionIsRunning = true; VisualizeQuickActionStart(); tempQuickActionData = QuickActionData; Dictionary parameterValues = null; if (QuickActionData.QuickActionParameters != null) { parameterValues = AdjustableParameterSectionUc.ParameterValues; AdjustableParameterSectionUc.ToggleIsActive(false); } List result = await QuickActionData.RunQuickAction.Invoke(tokenSource.Token, parameterValues); if (QuickActionData.ActionSteps.Any(step => step.Status == enumQuickActionRevisionStatus.finishedWithError)) status = enumQuickActionRevisionStatus.finishedWithError; else if (QuickActionData.ActionSteps.Any(step => step.Status == enumQuickActionRevisionStatus.canceled)) status = enumQuickActionRevisionStatus.canceled; else if (QuickActionData.ActionSteps.All(step => step.Status == enumQuickActionRevisionStatus.finishedSuccessfull)) status = enumQuickActionRevisionStatus.finishedSuccessfull; RaiseEvent(new QuickActionEventArgs(QuickActionFinishedEvent, this) { QuickActionResult = result, QuickActionStatus = status, QuickAction = QuickActionData.QuickActionDefinition}); CopyButton.Visibility = Visibility.Visible; if (QuickActionData.QuickActionDefinition.ColumnOutputFormattings?.Values.Any(formatting => formatting.IsSecret) ?? false) SecretButton.Visibility = Visibility.Visible; quickActionIsRunning = false; } catch (Exception E) { LogException(E); } finally { VisualizeQuickActionFinish(status); } } private async void ExecuteButton_Click() { try { if (quickActionIsRunning) { CancelQuickAction(); } else { await RunQuickActionAsync(); } } catch (Exception E) { LogException(E); } } private void ExecuteButton_MouseUp(object sender, MouseButtonEventArgs e) { ExecuteButton_Click(); } private void ExecuteButton_TouchDown(object sender, TouchEventArgs e) { ExecuteButton_Click(); } #endregion #region CopyButton_Click private async Task CopyButton_ClickAsync() { try { if (quickActionIsRunning || DataProvider is null) return; if (CopyButton.SelectedInternIcon == enumInternIcons.misc_check) return; DataObject copyObject = null; if (QuickActionData.QuickActionDefinition is cF4sdQuickActionChained chainedQuickAction) { int protocollCount = QuickActionData.ActionSteps.Count(step => step.Status == enumQuickActionRevisionStatus.finishedSuccessfull); if (QuickActionData.ActionSteps.Count > protocollCount) if (QuickActionData.ActionSteps[protocollCount].Status != enumQuickActionRevisionStatus.canceled) protocollCount++; copyObject = F4SDProtocoll.Instance.GetOfTypeAsDataObject(false, protocollCount); } else copyObject = F4SDProtocoll.Instance.GetLatestOfTypeAsDataObject(false); System.Windows.Forms.Clipboard.SetDataObject(copyObject); await cUtility.ChangeIconToCheckAsync(CopyButton); } catch (Exception E) { LogException(E); } } private async void CopyButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) => await CopyButton_ClickAsync(); private async void CopyButton_TouchDown(object sender, TouchEventArgs e) => await CopyButton_ClickAsync(); #endregion #region VisbilityButton_Click private void SecretButton_Click(object sender) { secretsAreShown = !secretsAreShown; foreach (var resultElement in QuickActionResultStack.Children.OfType()) { resultElement.ToggleSecretVisibility(secretsAreShown); } if (sender is AdaptableIcon.AdaptableIcon icon) icon.SelectedMaterialIcon = secretsAreShown ? MaterialIcons.MaterialIconType.ic_visibility_off : MaterialIcons.MaterialIconType.ic_visibility; } private void SecretButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) => SecretButton_Click(sender); private void SecretButton_TouchDown(object sender, TouchEventArgs e) => SecretButton_Click(sender); #endregion #region QuickActionFinished RoutedEvent public delegate void UiActionEventHandlerDelegate(object sender, QuickActionEventArgs args); public static readonly RoutedEvent QuickActionFinishedEvent = EventManager.RegisterRoutedEvent("QuickActionFinished", RoutingStrategy.Bubble, typeof(UiActionEventHandlerDelegate), typeof(QuickActionStatusMonitor)); public event RoutedEventHandler QuickActionFinished { add { AddHandler(QuickActionFinishedEvent, value); } remove { RemoveHandler(QuickActionFinishedEvent, value); } } #endregion #endregion } public class QuickActionEventArgs : RoutedEventArgs { public List QuickActionResult { get; set; } public cFasdQuickAction QuickAction { get; set; } public enumQuickActionRevisionStatus QuickActionStatus { get; set; } public QuickActionEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source) { } } }