Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stash and restore clipboard when inserting custom snipet #565

Merged
merged 1 commit into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 8 additions & 5 deletions OneMore/Commands/Snippets/InsertSnippetCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ namespace River.OneMoreAddIn.Commands
using WindowsInput;
using WindowsInput.Native;
using Resx = River.OneMoreAddIn.Properties.Resources;
using Win = System.Windows;


internal class InsertSnippetCommand : Command
Expand Down Expand Up @@ -40,17 +39,21 @@ public override async Task Execute(params object[] args)
return;
}

await SingleThreaded.Invoke(() =>
{
Win.Clipboard.SetText(snippet, Win.TextDataFormat.Html);
});
var clippy = new ClipboardProvider();
await clippy.StashState();

await clippy.SetHtml(snippet);

// both SetText and SendWait are very unpredictable so wait a little
await Task.Delay(200);

//SendKeys.SendWait("^(v)");
new InputSimulator().Keyboard
.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_V);

await Task.Delay(200);

await clippy.RestoreState();
}
}
}
129 changes: 129 additions & 0 deletions OneMore/Helpers/ClipboardProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
//************************************************************************************************
// Copyright © 2022 Steven M Cohn. All rights reserved.
//************************************************************************************************

#pragma warning disable S3267 // Loops should be simplified with "LINQ" expressions

namespace River.OneMoreAddIn
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using Win = System.Windows;


internal class ClipboardProvider
{
private readonly Dictionary<Win.TextDataFormat, string> stash;
private BitmapSource stashedImage;


public ClipboardProvider()
{
stash = new Dictionary<Win.TextDataFormat, string>();
}


public async Task SetHtml(string text)
{
await SingleThreaded.Invoke(() =>
{
Win.Clipboard.SetText(text, Win.TextDataFormat.Html);
});
}


public async Task SetText(string text)
{
await SingleThreaded.Invoke(() =>
{
Win.Clipboard.SetText(text, Win.TextDataFormat.Text);
});
}


public async Task StashState()
{
stash.Clear();
stashedImage = null;

await SingleThreaded.Invoke(() =>
{
// prioritize images
if (Win.Clipboard.ContainsImage())
{
stashedImage = Win.Clipboard.GetImage();
}
else
{
// collect each text format
foreach (Win.TextDataFormat format in Enum.GetValues(typeof(Win.TextDataFormat)))
{
if (Win.Clipboard.ContainsText(format))
{
stash.Add(format, Win.Clipboard.GetText(format));
}
}
}

// TODO: other formats, e.g. files?
});
}


public async Task RestoreState()
{
await SingleThreaded.Invoke(() =>
{
if (stashedImage != null)
{
Win.Clipboard.SetImage(stashedImage);
}
else if (stash.Count > 0)
{
// multiple texxt formats must be collated into a data object
var data = new Win.DataObject();
foreach (var key in stash.Keys)
{
data.SetData(ConvertToDataFormats(key), stash[key]);
}

Win.Clipboard.SetDataObject(data, true);
}
});

stash.Clear();
}


// duplicates the internal System.Windows.DataFormats.ConvertToDataFormats method
private static string ConvertToDataFormats(Win.TextDataFormat textDataformat)
{
var result = Win.DataFormats.UnicodeText;
switch (textDataformat)
{
case Win.TextDataFormat.Text:
result = Win.DataFormats.Text;
break;
case Win.TextDataFormat.UnicodeText:
result = Win.DataFormats.UnicodeText;
break;
case Win.TextDataFormat.Rtf:
result = Win.DataFormats.Rtf;
break;
case Win.TextDataFormat.Html:
result = Win.DataFormats.Html;
break;
case Win.TextDataFormat.CommaSeparatedValue:
result = Win.DataFormats.CommaSeparatedValue;
break;
case Win.TextDataFormat.Xaml:
result = Win.DataFormats.Xaml;
break;
}

return result;
}
}
}
1 change: 1 addition & 0 deletions OneMore/OneMore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@
<DependentUpon>UpdateDialog.cs</DependentUpon>
</Compile>
<Compile Include="Helpers\ApplicationFactory.cs" />
<Compile Include="Helpers\ClipboardProvider.cs" />
<Compile Include="Helpers\ErrorCodes.cs" />
<Compile Include="Helpers\Extensions\ByteExtensions.cs" />
<Compile Include="Helpers\Extensions\ColorMatrixExtensions.cs" />
Expand Down