752 lines
22 KiB
C#
752 lines
22 KiB
C#
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<bool> LockStatusChanged { get; set; }
|
|
|
|
public EventHandler<bool> NotepadVisibilityChanged { get; set; }
|
|
|
|
public EventHandler<bool> 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
|
|
|
|
}
|
|
}
|