ClipboardPage.xaml.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Avalonia;
  5. using Avalonia.Controls;
  6. using Avalonia.Controls.Notifications;
  7. using Avalonia.Input;
  8. using Avalonia.Input.Platform;
  9. using Avalonia.Interactivity;
  10. using Avalonia.Media;
  11. using Avalonia.Platform.Storage;
  12. using Avalonia.Threading;
  13. namespace ControlCatalog.Pages
  14. {
  15. public partial class ClipboardPage : UserControl
  16. {
  17. private readonly DataFormat<byte[]> _customBinaryDataFormat =
  18. DataFormat.CreateBytesApplicationFormat("controlcatalog-binary-data");
  19. private INotificationManager? _notificationManager;
  20. private INotificationManager NotificationManager => _notificationManager
  21. ??= new WindowNotificationManager(TopLevel.GetTopLevel(this)!);
  22. private readonly DispatcherTimer _clipboardLastDataObjectChecker;
  23. private DataTransfer? _storedDataTransfer;
  24. public ClipboardPage()
  25. {
  26. InitializeComponent();
  27. _clipboardLastDataObjectChecker =
  28. new DispatcherTimer(TimeSpan.FromSeconds(0.5), default, CheckLastDataObject);
  29. }
  30. private async void CopyText(object? sender, RoutedEventArgs args)
  31. {
  32. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  33. await clipboard.SetTextAsync(ClipboardContent.Text ?? string.Empty);
  34. }
  35. private async void PasteText(object? sender, RoutedEventArgs args)
  36. {
  37. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  38. {
  39. ClipboardContent.Text = await clipboard.TryGetTextAsync();
  40. }
  41. }
  42. private async void CopyFiles(object? sender, RoutedEventArgs args)
  43. {
  44. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  45. {
  46. var storageProvider = TopLevel.GetTopLevel(this)!.StorageProvider;
  47. var filesPath = (ClipboardContent.Text ?? string.Empty)
  48. .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
  49. if (filesPath.Length == 0)
  50. {
  51. return;
  52. }
  53. List<string> invalidFile = new(filesPath.Length);
  54. List<IStorageFile> files = new(filesPath.Length);
  55. for (int i = 0; i < filesPath.Length; i++)
  56. {
  57. var file = await storageProvider.TryGetFileFromPathAsync(filesPath[i]);
  58. if (file is null)
  59. {
  60. invalidFile.Add(filesPath[i]);
  61. }
  62. else
  63. {
  64. files.Add(file);
  65. }
  66. }
  67. if (invalidFile.Count > 0)
  68. {
  69. NotificationManager.Show(new Notification("Warning", "There is one o more invalid path.", NotificationType.Warning));
  70. }
  71. if (files.Count > 0)
  72. {
  73. var dataTransfer = _storedDataTransfer = new DataTransfer();
  74. foreach (var file in files)
  75. dataTransfer.Add(DataTransferItem.Create(DataFormat.File, file));
  76. await clipboard.SetDataAsync(dataTransfer);
  77. NotificationManager.Show(new Notification("Success", "Copy completed.", NotificationType.Success));
  78. }
  79. else
  80. {
  81. NotificationManager.Show(new Notification("Warning", "Any files to copy in Clipboard.", NotificationType.Warning));
  82. }
  83. }
  84. }
  85. private async void PasteFiles(object? sender, RoutedEventArgs args)
  86. {
  87. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  88. {
  89. var files = await clipboard.TryGetFilesAsync();
  90. ClipboardContent.Text = files != null ? string.Join(Environment.NewLine, files.Select(f => f.TryGetLocalPath() ?? f.Name)) : string.Empty;
  91. }
  92. }
  93. private async void GetFormats(object sender, RoutedEventArgs args)
  94. {
  95. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  96. {
  97. var formats = await clipboard.GetDataFormatsAsync();
  98. ClipboardContent.Text = string.Join(Environment.NewLine, formats);
  99. }
  100. }
  101. private async void CopyBinaryData(object? sender, RoutedEventArgs args)
  102. {
  103. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  104. {
  105. var dataTransfer = _storedDataTransfer = new DataTransfer();
  106. var bytes = new byte[10 * 1024 * 1024];
  107. new Random().NextBytes(bytes);
  108. dataTransfer.Add(DataTransferItem.Create(_customBinaryDataFormat, bytes));
  109. await clipboard.SetDataAsync(dataTransfer);
  110. }
  111. }
  112. private async void PasteBinaryData(object? sender, RoutedEventArgs args)
  113. {
  114. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  115. {
  116. var bytes = await clipboard.TryGetValueAsync(_customBinaryDataFormat);
  117. ClipboardContent.Text = bytes is null ? "<null>" : $"{bytes.Length} bytes";
  118. }
  119. }
  120. private async void Clear(object sender, RoutedEventArgs args)
  121. {
  122. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  123. {
  124. await clipboard.ClearAsync();
  125. }
  126. }
  127. protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
  128. {
  129. _clipboardLastDataObjectChecker.Start();
  130. base.OnAttachedToVisualTree(e);
  131. }
  132. protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
  133. {
  134. _clipboardLastDataObjectChecker.Stop();
  135. base.OnDetachedFromVisualTree(e);
  136. }
  137. private bool _checkingClipboardDataTransfer;
  138. private async void CheckLastDataObject(object? sender, EventArgs e)
  139. {
  140. if (_checkingClipboardDataTransfer)
  141. return;
  142. try
  143. {
  144. _checkingClipboardDataTransfer = true;
  145. var owns = false;
  146. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  147. {
  148. var dataTransfer = await clipboard.TryGetInProcessDataAsync();
  149. owns = dataTransfer == _storedDataTransfer && dataTransfer is not null;
  150. }
  151. OwnsClipboardDataObject.Text = owns ? "Yes" : "No";
  152. OwnsClipboardDataObject.Foreground = owns ? Brushes.Green : Brushes.Red;
  153. }
  154. finally
  155. {
  156. _checkingClipboardDataTransfer = false;
  157. }
  158. }
  159. }
  160. }