|
25 | 25 | using System.IO;
|
26 | 26 | using System.Linq;
|
27 | 27 | using System.Reflection.Metadata;
|
| 28 | +using System.Text; |
28 | 29 | using System.Threading;
|
29 | 30 | using System.Threading.Tasks;
|
30 | 31 | using System.Windows;
|
@@ -77,6 +78,7 @@ public sealed partial class DecompilerTextView : UserControl, IDisposable, IHave
|
77 | 78 | readonly List<VisualLineElementGenerator?> activeCustomElementGenerators = new List<VisualLineElementGenerator?>();
|
78 | 79 | readonly BracketHighlightRenderer bracketHighlightRenderer;
|
79 | 80 | RichTextColorizer? activeRichTextColorizer;
|
| 81 | + RichTextModel? activeRichTextModel; |
80 | 82 | FoldingManager? foldingManager;
|
81 | 83 | ILSpyTreeNode[]? decompiledNodes;
|
82 | 84 | Uri? currentAddress;
|
@@ -146,6 +148,8 @@ public DecompilerTextView()
|
146 | 148 | textEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.CurrentLineBackgroundProperty, ResourceKeys.CurrentLineBackgroundBrush);
|
147 | 149 | textEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.CurrentLineBorderProperty, ResourceKeys.CurrentLineBorderPen);
|
148 | 150 |
|
| 151 | + DataObject.AddSettingDataHandler(textEditor.TextArea, OnSettingData); |
| 152 | + |
149 | 153 | this.DataContextChanged += DecompilerTextView_DataContextChanged;
|
150 | 154 | }
|
151 | 155 |
|
@@ -714,10 +718,12 @@ void ShowOutput(AvalonEditTextOutput textOutput, IHighlightingDefinition? highli
|
714 | 718 | textEditor.SyntaxHighlighting = highlighting;
|
715 | 719 | textEditor.Options.EnableEmailHyperlinks = textOutput.EnableHyperlinks;
|
716 | 720 | textEditor.Options.EnableHyperlinks = textOutput.EnableHyperlinks;
|
| 721 | + activeRichTextModel = null; |
717 | 722 | if (activeRichTextColorizer != null)
|
718 | 723 | textEditor.TextArea.TextView.LineTransformers.Remove(activeRichTextColorizer);
|
719 | 724 | if (textOutput.HighlightingModel != null)
|
720 | 725 | {
|
| 726 | + activeRichTextModel = textOutput.HighlightingModel; |
721 | 727 | activeRichTextColorizer = new RichTextColorizer(textOutput.HighlightingModel);
|
722 | 728 | textEditor.TextArea.TextView.LineTransformers.Insert(highlighting == null ? 0 : 1, activeRichTextColorizer);
|
723 | 729 | }
|
@@ -1176,6 +1182,58 @@ Task<AvalonEditTextOutput> SaveToDiskAsync(DecompilationContext context, string
|
1176 | 1182 | }
|
1177 | 1183 | #endregion
|
1178 | 1184 |
|
| 1185 | + #region Clipboard |
| 1186 | + private void OnSettingData(object sender, DataObjectSettingDataEventArgs e) |
| 1187 | + { |
| 1188 | + if (e.Format == DataFormats.Html && e.DataObject is DataObject dataObject) |
| 1189 | + { |
| 1190 | + e.CancelCommand(); |
| 1191 | + HtmlClipboard.SetHtml(dataObject, CreateHtmlFragmentFromSelection()); |
| 1192 | + } |
| 1193 | + } |
| 1194 | + |
| 1195 | + private string CreateHtmlFragmentFromSelection() |
| 1196 | + { |
| 1197 | + var options = new HtmlOptions(textEditor.TextArea.Options); |
| 1198 | + var highlighter = textEditor.TextArea.GetService(typeof(IHighlighter)) as IHighlighter; |
| 1199 | + var html = new StringBuilder(); |
| 1200 | + |
| 1201 | + foreach (var segment in textEditor.TextArea.Selection.Segments) |
| 1202 | + { |
| 1203 | + var line = textEditor.Document.GetLineByOffset(segment.StartOffset); |
| 1204 | + |
| 1205 | + while (line != null && line.Offset < segment.EndOffset) |
| 1206 | + { |
| 1207 | + if (html.Length > 0) |
| 1208 | + html.AppendLine("<br>"); |
| 1209 | + |
| 1210 | + var s = GetOverlap(segment, line); |
| 1211 | + var highlightedLine = highlighter?.HighlightLine(line.LineNumber) ?? new HighlightedLine(textEditor.Document, line); |
| 1212 | + |
| 1213 | + if (activeRichTextModel is not null) |
| 1214 | + { |
| 1215 | + var richTextHighlightedLine = new HighlightedLine(textEditor.Document, line); |
| 1216 | + foreach (HighlightedSection richTextSection in activeRichTextModel.GetHighlightedSections(s.Offset, s.Length)) |
| 1217 | + richTextHighlightedLine.Sections.Add(richTextSection); |
| 1218 | + highlightedLine.MergeWith(richTextHighlightedLine); |
| 1219 | + } |
| 1220 | + |
| 1221 | + html.Append(highlightedLine.ToHtml(s.Offset, s.Offset + s.Length, options)); |
| 1222 | + line = line.NextLine; |
| 1223 | + } |
| 1224 | + } |
| 1225 | + |
| 1226 | + return html.ToString(); |
| 1227 | + |
| 1228 | + static (int Offset, int Length) GetOverlap(ISegment segment1, ISegment segment2) |
| 1229 | + { |
| 1230 | + int start = Math.Max(segment1.Offset, segment2.Offset); |
| 1231 | + int end = Math.Min(segment1.EndOffset, segment2.EndOffset); |
| 1232 | + return (start, end - start); |
| 1233 | + } |
| 1234 | + } |
| 1235 | + #endregion |
| 1236 | + |
1179 | 1237 | internal ReferenceSegment? GetReferenceSegmentAtMousePosition()
|
1180 | 1238 | {
|
1181 | 1239 | if (referenceElementGenerator.References == null)
|
|
0 commit comments