1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-25 05:29:31 +00:00

Implement copy-to-clipboard

Also, add keyboard shortcuts to toolbar tooltips.  This is particularly
useful for navigate forward/backward, as those aren't part of the
menu structure, and have two keyboard shortcuts apiece.
This commit is contained in:
Andy McFadden 2019-07-11 11:36:07 -07:00
parent 05d61cfebd
commit 2f82ff5b46
4 changed files with 132 additions and 8 deletions

View File

@ -1189,6 +1189,122 @@ namespace SourceGenWPF {
dlg.ShowDialog();
}
/// <summary>
/// Copies the selection to the clipboard as formatted text.
/// </summary>
public void CopyToClipboard() {
const bool addCsv = true;
ClipLineFormat format = (ClipLineFormat)AppSettings.Global.GetEnum(
AppSettings.CLIP_LINE_FORMAT,
typeof(ClipLineFormat),
(int)ClipLineFormat.AssemblerSource);
DisplayListSelection selection = mMainWin.CodeDisplayList.SelectedIndices;
StringBuilder fullText = new StringBuilder(selection.Count * 50);
StringBuilder csv = new StringBuilder(selection.Count * 40);
StringBuilder sb = new StringBuilder(100);
int addrAdj = mProject.CpuDef.HasAddr16 ? 6 : 9;
int disAdj = 0;
int bytesWidth = 0;
if (format == ClipLineFormat.Disassembly) {
// A limit of 8 gets us 4 bytes from dense display ("20edfd60") and 3 if spaces
// are included ("20 ed fd") with no excess. We want to increase it to 11 so
// we can always show 4 bytes.
bytesWidth = (mFormatterConfig.mSpacesBetweenBytes ? 11 : 8);
disAdj = addrAdj + bytesWidth + 2;
}
// Walking through the selected indices can be slow for a large file, so we
// run through the full list and pick out the selected items with our parallel
// structure. (I'm assuming that "select all" will be a common precursor.)
foreach (int index in selection) {
LineListGen.Line line = CodeLineList[index];
DisplayList.FormattedParts parts = CodeLineList.GetFormattedParts(index);
switch (line.LineType) {
case LineListGen.Line.Type.Code:
case LineListGen.Line.Type.Data:
case LineListGen.Line.Type.EquDirective:
case LineListGen.Line.Type.RegWidthDirective:
case LineListGen.Line.Type.OrgDirective:
if (format == ClipLineFormat.Disassembly) {
if (!string.IsNullOrEmpty(parts.Addr)) {
sb.Append(parts.Addr);
sb.Append(": ");
}
// Shorten the "...".
string bytesStr = parts.Bytes;
if (bytesStr != null && bytesStr.Length > bytesWidth) {
bytesStr = bytesStr.Substring(0, bytesWidth) + "+";
}
TextUtil.AppendPaddedString(sb, bytesStr, disAdj);
}
TextUtil.AppendPaddedString(sb, parts.Label, disAdj + 9);
TextUtil.AppendPaddedString(sb, parts.Opcode, disAdj + 9 + 8);
TextUtil.AppendPaddedString(sb, parts.Operand, disAdj + 9 + 8 + 11);
if (string.IsNullOrEmpty(parts.Comment)) {
// Trim trailing spaces off opcode or operand.
TextUtil.TrimEnd(sb);
} else {
sb.Append(parts.Comment);
}
sb.Append("\r\n");
break;
case LineListGen.Line.Type.LongComment:
if (format == ClipLineFormat.Disassembly) {
TextUtil.AppendPaddedString(sb, string.Empty, disAdj);
}
sb.Append(parts.Comment);
sb.Append("\r\n");
break;
case LineListGen.Line.Type.Note:
// don't include notes
break;
case LineListGen.Line.Type.Blank:
sb.Append("\r\n");
break;
default:
Debug.Assert(false);
break;
}
fullText.Append(sb);
if (addCsv) {
csv.Append(TextUtil.EscapeCSV(parts.Offset)); csv.Append(',');
csv.Append(TextUtil.EscapeCSV(parts.Addr)); csv.Append(',');
csv.Append(TextUtil.EscapeCSV(parts.Bytes)); csv.Append(',');
csv.Append(TextUtil.EscapeCSV(parts.Flags)); csv.Append(',');
csv.Append(TextUtil.EscapeCSV(parts.Attr)); csv.Append(',');
csv.Append(TextUtil.EscapeCSV(parts.Label)); csv.Append(',');
csv.Append(TextUtil.EscapeCSV(parts.Opcode)); csv.Append(',');
csv.Append(TextUtil.EscapeCSV(parts.Operand)); csv.Append(',');
csv.Append(TextUtil.EscapeCSV(parts.Comment));
csv.Append("\r\n");
}
sb.Clear();
}
DataObject dataObject = new DataObject();
dataObject.SetText(fullText.ToString());
// We want to have both plain text and CSV data on the clipboard. To add both
// formats we need to stream it to a DataObject. Complicating matters is Excel's
// entirely reasonable desire to have data in UTF-8 rather than UTF-16.
//
// (I'm not sure pasting assembly bits into Excel is actually useful, so this
// should probably be optional.)
//
// https://stackoverflow.com/a/369219/294248
if (addCsv) {
byte[] csvData = Encoding.UTF8.GetBytes(csv.ToString());
MemoryStream stream = new MemoryStream(csvData);
dataObject.SetData(DataFormats.CommaSeparatedValue, stream);
}
Clipboard.SetDataObject(dataObject, true);
}
/// <summary>
/// Opens the application settings dialog. All changes to settings are made directly
/// to the AppSettings.Global object.

View File

@ -40,7 +40,7 @@ limitations under the License.
<Image Grid.Column="0" Grid.Row="0"
Source="/SourceGenWPF;component/Res/Logo.png"/>
<StackPanel Grid.Column="1" Grid.Row="0" Margin="8,0,0,0">
<StackPanel Grid.Column="1" Grid.Row="0" Margin="8,12,0,0">
<TextBlock Text="6502bench SourceGen" FontSize="30"/>
<TextBlock FontSize="24"
Text="{Binding ProgramVersionString, StringFormat={}Version {0},

View File

@ -140,6 +140,8 @@ limitations under the License.
CanExecute="IsProjectOpen" Executed="AssembleCmd_Executed"/>
<CommandBinding Command="{StaticResource CloseCmd}"
CanExecute="IsProjectOpen" Executed="CloseCmd_Executed"/>
<CommandBinding Command="Copy"
CanExecute="IsProjectOpen" Executed="CopyCmd_Executed"/>
<CommandBinding Command="{StaticResource DebugSourceGenerationTestsCmd}"
Executed="DebugSourceGenerationTestsCmd_Executed"/>
<CommandBinding Command="{StaticResource EditAddressCmd}"
@ -282,28 +284,30 @@ limitations under the License.
<ToolBarTray DockPanel.Dock="Top">
<ToolBar RenderOptions.BitmapScalingMode="NearestNeighbor">
<Button ToolTip="Navigate backward" Command="{StaticResource NavigateBackwardCmd}">
<Button Command="{StaticResource NavigateBackwardCmd}"
ToolTip="Navigate backward (Alt+Left, Ctrl+Minus, or back button on mouse)">
<ContentControl Template="{StaticResource icon_StepBackwards}"/>
</Button>
<Button ToolTip="Navigate forward" Command="{StaticResource NavigateForwardCmd}">
<Button Command="{StaticResource NavigateForwardCmd}"
ToolTip="Navigate forward (Alt+Right or Ctrl+Shift+Minus)">
<ContentControl Template="{StaticResource icon_StepForward}"/>
</Button>
<Separator/>
<Button ToolTip="Create new project">
<Button Command="{StaticResource NewProjectCmd}" ToolTip="Create new project">
<ContentControl Template="{StaticResource icon_NewFile}"/>
</Button>
<Button ToolTip="Open project" Command="{StaticResource OpenCmd}">
<Button Command="{StaticResource OpenCmd}" ToolTip="Open project">
<ContentControl Template="{StaticResource icon_OpenFile}"/>
</Button>
<Button ToolTip="Save project" Command="Save">
<Button Command="Save" ToolTip="Save project (Ctrl+S)">
<ContentControl Template="{StaticResource icon_SaveFile}"/>
</Button>
<Separator/>
<Button ToolTip="Copy to clipboard">
<Button Command="Copy" ToolTip="Copy to clipboard (Ctrl+C)">
<ContentControl Template="{StaticResource icon_CopyToClipboard}"/>
</Button>
<Separator/>
<Button ToolTip="Help - open manual in browser" Command="Help">
<Button Command="Help" ToolTip="Help - open manual in browser (F1)">
<ContentControl Template="{StaticResource icon_F1Help}"/>
</Button>
</ToolBar>

View File

@ -835,6 +835,10 @@ namespace SourceGenWPF.WpfGui {
}
}
private void CopyCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.CopyToClipboard();
}
private void DebugSourceGenerationTestsCmd_Executed(object sender,
ExecutedRoutedEventArgs e) {
mMainCtrl.RunSourceGenerationTests();