using F4SD_AdaptableIcon.Enums; using FasdDesktopUi.Basics.Helper; using System; using System.IO; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Threading; using static C4IT.Logging.cLogManager; namespace FasdDesktopUi.Basics.UserControls { public partial class Notepad : UserControl { #region Variables private bool IsBold = false; private bool IsItalic = false; private bool IsUnderline = false; private bool IsDecimal = false; private bool IsBullet = false; private bool CanUndo = false; private bool CanRedo = false; #endregion #region Properties and Fields private static DispatcherTimer saveTimer; public EventHandler LockStatusChanged { get; set; } public EventHandler NotepadVisibilityChanged { get; set; } public EventHandler IsUndockedChanged { get; set; } #region DataProvider private cSupportCaseDataProvider DataProvider; /* { get { return (cDataProviderBase)GetValue(DataProviderProperty); } set { SetValue(DataProviderProperty, value); } } */ /* private static readonly DependencyProperty DataProviderProperty = DependencyProperty.Register("DataProvider", typeof(cDataProviderBase), typeof(Notepad), new PropertyMetadata(null)); */ #endregion #region IsUndocked public bool IsUndocked { get { return (bool)GetValue(IsUndockedProperty); } set { SetValue(IsUndockedProperty, value); } } public static readonly DependencyProperty IsUndockedProperty = DependencyProperty.Register("IsUndocked", typeof(bool), typeof(Notepad), new PropertyMetadata(new PropertyChangedCallback(HandleUndockedChanged))); private static void HandleUndockedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { try { if (!(d is Notepad _me)) return; _me.ToggleIconVisibility(); } catch (Exception E) { LogException(E); } } #endregion #region IsLocked public bool IsLocked { get { return (bool)GetValue(IsLockedProperty); } set { SetValue(IsLockedProperty, value); } } public static readonly DependencyProperty IsLockedProperty = DependencyProperty.Register("IsLocked", typeof(bool), typeof(Notepad), new PropertyMetadata(new PropertyChangedCallback(HandleLockedChanged))); private static void HandleLockedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { try { if (!(d is Notepad _me)) { return; } _me.LockNotepadIcon.SelectedInternIcon = _me.IsLocked ? F4SD_AdaptableIcon.Enums.enumInternIcons.lock_closed : F4SD_AdaptableIcon.Enums.enumInternIcons.lock_open; _me.CloseNotepadIcon.IsEnabled = _me.IsLocked ? false : true; } catch (Exception E) { LogException(E); } } #endregion #region IsTicketDialog //public bool IsTicketDialog { get; set; } public bool IsTicketDialog { get { return (bool)GetValue(IsTicketDialogProperty); } set { SetValue(IsTicketDialogProperty, value); } } // Using a DependencyProperty as the backing store for IsTicketDialog. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsTicketDialogProperty = DependencyProperty.Register("IsTicketDialog", typeof(bool), typeof(Notepad), new PropertyMetadata(new PropertyChangedCallback(HandleTicketDialogChanged))); private static void HandleTicketDialogChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { try { if (!(d is Notepad _me)) { return; } } catch(Exception E) { LogException(E); } } #endregion #endregion #region Constructor public Notepad(cSupportCaseDataProvider dataProvider) { DataProvider = dataProvider; InitializeComponent(); saveTimer = new DispatcherTimer(TimeSpan.FromSeconds(0.75), DispatcherPriority.Render, SaveNotes, Dispatcher.CurrentDispatcher); IsLocked = cFasdCockpitConfig.Instance.IsNotepadVisibleDocked; } #endregion #region Methods private void NotepadRichTextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { try { if (DataProvider is null) return; if (DataProvider?.CaseNotes?.Parent is RichTextBox parentBox) parentBox.Document = new FlowDocument(); if (!(sender is RichTextBox senderElement)) return; senderElement.Document = DataProvider.CaseNotes; senderElement.CaretPosition = senderElement.CaretPosition.DocumentEnd; } catch (Exception E) { LogException(E); } } private async void NotepadRichTextBox_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { try { if (!(e.NewValue is bool isVisible && isVisible)) return; await Task.Delay(50); NotepadRichTextBox.Focus(); Keyboard.Focus(NotepadRichTextBox); NotepadRichTextBox_GotKeyboardFocus(sender, null); } catch (Exception E) { LogException(E); } } #region CopyIcon Click private async void CopyIcon_Click(object sender) { try { DataObject copyObject = new DataObject(); StringBuilder stringBuilderUnicode = new StringBuilder(); cRichTextBoxHelper.TraverseBlockAsUnicode(NotepadRichTextBox.Document.Blocks, stringBuilderUnicode); copyObject.SetData(DataFormats.UnicodeText, stringBuilderUnicode.ToString()); StringBuilder stringBuilderHtml = new StringBuilder(); cRichTextBoxHelper.TraverseBlockAsHtml(NotepadRichTextBox.Document.Blocks, stringBuilderHtml); var copyText = cUtility.GetHtmlFrame(stringBuilderHtml.ToString()); copyObject.SetData(DataFormats.Html, copyText); TextRange tr = new TextRange(NotepadRichTextBox.Document.ContentStart, NotepadRichTextBox.Document.ContentEnd); using (MemoryStream ms = new MemoryStream()) { tr.Save(ms, DataFormats.Rtf); string rtfText = ASCIIEncoding.Default.GetString(ms.ToArray()); copyObject.SetData(DataFormats.Rtf, rtfText); } Clipboard.SetDataObject(copyObject); await cUtility.ChangeIconToCheckAsync(CopyIcon); } catch (Exception E) { LogException(E); } } private void CopyIcon_TouchDown(object sender, TouchEventArgs e) { CopyIcon_Click(sender); } private void CopyIcon_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { CopyIcon_Click(sender); } #endregion #region Popout private void ToggleDockButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { try { IsUndocked = !IsUndocked; IsUndockedChanged?.Invoke(this, IsUndocked); } catch (Exception E) { LogException(E); } } private void ToggleDockButton_TouchDown(object sender, TouchEventArgs e) { try { IsUndocked = !IsUndocked; IsUndockedChanged?.Invoke(this, IsUndocked); } catch (Exception E) { LogException(E); } } #endregion #region Save Notes private void SaveNotes(object sender, EventArgs e) { try { saveTimer?.Stop(); if (DataProvider is null) return; Dispatcher.Invoke(() => DataProvider.SaveCaseNotes()); } catch (Exception E) { LogException(E); } } private void NotepadRichTextBox_TextChanged(object sender, TextChangedEventArgs e) { saveTimer?.Stop(); saveTimer?.Start(); CheckUndo_TextChanged(sender, e); } #endregion #region RichTextBox SelectionChanged private void NotepadRichTextBox_SelectionChanged(object sender, RoutedEventArgs e) { try { var selection = NotepadRichTextBox.Selection; if (selection != null) { if ((FontWeight)selection.GetPropertyValue(TextElement.FontWeightProperty) == FontWeights.Bold) { if (IsBold == false) { SelectedTextIsBold(true); IsBold = true; } } else { if (IsBold == true) { SelectedTextIsBold(false); IsBold = false; } } if ((FontStyle)selection.GetPropertyValue(TextElement.FontStyleProperty) == FontStyles.Italic) { if (IsItalic == false) { SelectedTextIsItalic(true); IsItalic = true; } } else { if (IsItalic == true) { SelectedTextIsItalic(false); IsItalic = false; } } if ((TextDecorationCollection)selection.GetPropertyValue(Inline.TextDecorationsProperty) == TextDecorations.Underline) { if (IsUnderline == false) { SelectedTextIsUnderlined(true); IsUnderline = true; } } else { if (IsUnderline == true) { SelectedTextIsUnderlined(false); IsUnderline = false; } } if (selection.Start != null && selection.Start.Paragraph != null) { if (selection.Start.Paragraph.Parent is ListItem listItem) { if (listItem.List != null && listItem.List.MarkerStyle == TextMarkerStyle.Decimal) { if (IsDecimal == false) { SelectedTextIsDecimal(true); IsDecimal = true; } } else { if (IsDecimal == true) { SelectedTextIsDecimal(false); IsDecimal = false; } } } else { if (IsDecimal == true) { SelectedTextIsDecimal(false); IsDecimal = false; } } } if (selection.Start != null && selection.Start.Paragraph != null) { if (selection.Start.Paragraph.Parent is ListItem listItem) { if (listItem.List != null && listItem.List.MarkerStyle == TextMarkerStyle.Disc) { if (IsBullet == false) { SelectedTextIsDisc(true); IsBullet = true; } } else { if (IsBullet == true) { SelectedTextIsDisc(false); IsBullet = false; } } } else { if (IsBullet == true) { SelectedTextIsDisc(false); IsBullet = false; } } } } } catch (Exception E) { LogException(E); } } private void SelectedTextIsBold(bool isActive) { try { if (isActive != true) { BoldIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon"); return; } BoldIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon.Pinned"); } catch (Exception E) { LogException(E); } } private void SelectedTextIsItalic(bool isActive) { try { if (isActive != true) { ItalicIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon"); return; } ItalicIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon.Pinned"); } catch (Exception E) { LogException(E); } } private void SelectedTextIsUnderlined(bool isActive) { try { if (isActive != true) { UnderlineIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon"); return; } UnderlineIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon.Pinned"); } catch (Exception E) { LogException(E); } } private void SelectedTextIsDecimal(bool isActive) { try { if (isActive != true) { NumberingIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon"); return; } NumberingIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon.Pinned"); } catch (Exception E) { LogException(E); } } private void SelectedTextIsDisc(bool isActive) { try { if (isActive != true) { BulletsIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon"); return; } BulletsIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon.Pinned"); } catch (Exception E) { LogException(E); } } private void TextBoxIcon_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { NotepadRichTextBox_SelectionChanged(sender, e); } #endregion #region Undo/Redo private void CheckUndo_TextChanged(object sender, TextChangedEventArgs e) { if (NotepadRichTextBox.CanUndo == true && CanUndo == false) { UndoIcon.IsEnabled = true; UndoIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon"); CanUndo = true; } else if (NotepadRichTextBox.CanUndo == false && CanUndo == true) { UndoIcon.IsEnabled = false; UndoIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon.Disabled"); CanUndo = false; } if (NotepadRichTextBox.CanRedo == true && CanRedo == false) { RedoIcon.IsEnabled = true; RedoIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon"); CanRedo = true; } else if (NotepadRichTextBox.CanRedo == false && CanRedo == true) { RedoIcon.IsEnabled = false; RedoIcon.Style = (Style)FindResource("Menu.MenuBar.PinnedIcon.Disabled"); CanRedo = false; } } #endregion #region Control Icons #region Visibility private void ToggleIconVisibility() { try { ToggleDockButton.Visibility = IsUndocked ? Visibility.Collapsed : Visibility.Visible; LockNotepadIcon.Visibility = IsUndocked ? Visibility.Collapsed : Visibility.Visible; CloseNotepadIcon.IsEnabled = IsUndocked ? true : !IsLocked; } catch (Exception E) { LogException(E); } } #endregion private void NotepadIcon_Click(object sender, InputEventArgs e) { try { if (!(sender is FrameworkElement senderElement)) return; switch (senderElement.Tag) { case "lock": LockNotepad(); break; case "close": CloseNotepad(); break; default: break; } } catch (Exception E) { LogException(E); } } private void CloseNotepadIcon_MouseUp(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left) CloseNotepad(); } private void CloseNotepadIcon_TouchDown(object sender, TouchEventArgs e) { CloseNotepad(); } private void LockNotepad() { try { if (IsLocked) { LockNotepadIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "Color.SoftContrast"); LockNotepadIcon.SelectedInternIcon = enumInternIcons.lock_open; } else { LockNotepadIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "Color.Menu.Icon"); LockNotepadIcon.SelectedInternIcon = enumInternIcons.lock_closed; } LockNotepadIcon.BorderPadding = new Thickness(5.5); IsLocked = !IsLocked; LockStatusChanged?.Invoke(this, IsLocked); } catch (Exception E) { LogException(E); } } private void LockNotepadIcon_MouseUp(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left) LockNotepad(); } private void LockNotepadIcon_TouchDown(object sender, TouchEventArgs e) { LockNotepad(); } private void LockNotepadIcon_MouseLeave(object sender, MouseEventArgs e) { (sender as AdaptableIcon.AdaptableIcon).ClearValue(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty); (sender as AdaptableIcon.AdaptableIcon).ClearValue(AdaptableIcon.AdaptableIcon.SelectedInternIconProperty); (sender as AdaptableIcon.AdaptableIcon).ClearValue(AdaptableIcon.AdaptableIcon.BorderPaddingProperty); } private void CloseNotepad() { try { if (IsUndocked == true) { IsUndocked = !IsUndocked; IsUndockedChanged?.Invoke(this, IsUndocked); return; } NotepadVisibilityChanged?.Invoke(this, true); } catch (Exception E) { LogException(E); } } #endregion #endregion } }