From 81157b6b4798ac4d08a05b9f1ef91d218e51e5e5 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Thu, 12 Sep 2019 13:57:52 -0700 Subject: [PATCH] Implement text export This feature "exports" the source code in the same format it appears in on screen. The five columns on the left are optional, the four on the right can be resized. Exported text can span the entire file or just the current selection. Output can be plain text or CSV. (I still haven't figured out a good use for CSV.) The old copy-to-clipboard function is now implemented via the export mechanism. This adds a new clipboard mode that includes all columns. Potentially useful for filing bug reports against SourceGen. --- SourceGen/AppSettings.cs | 12 + SourceGen/Exporter.cs | 376 +++++++++++++++++------ SourceGen/LineListGen.cs | 12 +- SourceGen/MainController.cs | 61 +++- SourceGen/Res/Strings.xaml | 8 +- SourceGen/Res/Strings.xaml.cs | 8 + SourceGen/WpfGui/EditAppSettings.xaml.cs | 4 +- SourceGen/WpfGui/Export.xaml | 29 +- SourceGen/WpfGui/Export.xaml.cs | 240 ++++++++++++++- 9 files changed, 638 insertions(+), 112 deletions(-) diff --git a/SourceGen/AppSettings.cs b/SourceGen/AppSettings.cs index f9309d7..3c25e5d 100644 --- a/SourceGen/AppSettings.cs +++ b/SourceGen/AppSettings.cs @@ -115,6 +115,18 @@ namespace SourceGen { // Assembler settings prefix public const string ASM_CONFIG_PREFIX = "asm-config-"; + // Text/HTML export settings. + public const string EXPORT_INCLUDE_NOTES = "export-include-notes"; + public const string EXPORT_SHOW_OFFSET = "export-show-offset"; + public const string EXPORT_SHOW_ADDR = "export-show-addr"; + public const string EXPORT_SHOW_BYTES = "export-show-bytes"; + public const string EXPORT_SHOW_FLAGS = "export-show-flags"; + public const string EXPORT_SHOW_ATTR = "export-show-attr"; + public const string EXPORT_COL_WIDTHS = "export-col-widths"; + public const string EXPORT_TEXT_MODE = "export-text-mode"; + public const string EXPORT_SELECTION_ONLY = "export-selection-only"; + public const string EXPORT_INCLUDE_SYMTAB = "export-include-symtab"; + // Internal debugging features. public const string DEBUG_MENU_ENABLED = "debug-menu-enabled"; diff --git a/SourceGen/Exporter.cs b/SourceGen/Exporter.cs index fb8a97c..06a7b93 100644 --- a/SourceGen/Exporter.cs +++ b/SourceGen/Exporter.cs @@ -14,16 +14,53 @@ * limitations under the License. */ using System; -using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Text; using Asm65; using CommonUtil; -using ClipLineFormat = SourceGen.MainController.ClipLineFormat; namespace SourceGen { + /// + /// Source code export functions. + /// + /// + /// The five columns on the left (offset, address, bytes, flags, attributes) are optional, + /// and have a fixed width. The four columns on the right (label, opcode, operand, comment) + /// are mandatory, and have configurable widths. + /// public class Exporter { + /// + /// Optional selection specifier. If null, the entire file is included. + /// + public DisplayListSelection Selection { get; set; } + + /// + /// Should notes be included in the output? + /// + public bool IncludeNotes { get; set; } + + /// + /// Bit flags, used to indicate which of the optional columns are active. + /// + [FlagsAttribute] + public enum ActiveColumnFlags { + None = 0, + Offset = 1, + Address = 1 << 1, + Bytes = 1 << 2, + Flags = 1 << 3, + Attr = 1 << 4, + + ALL = 0x7f + } + + /// + /// Flags indicating active optional columns. + /// + private ActiveColumnFlags mLeftFlags; + /// /// Project reference. /// @@ -39,117 +76,282 @@ namespace SourceGen { /// private Formatter mFormatter; + /// + /// The cumulative width of the columns determines the end point. + /// + private int[] mColEnd; + + private enum Col { + Offset = 0, + Address = 1, + Bytes = 2, + Flags = 3, + Attr = 4, + Label = 5, + Opcode = 6, + Operand = 7, + Comment = 8, + COUNT // number of elements, must be last + } + /// /// Constructor. /// - public Exporter(DisasmProject project, LineListGen codeLineList, Formatter formatter) { + public Exporter(DisasmProject project, LineListGen codeLineList, Formatter formatter, + ActiveColumnFlags leftFlags, int[] rightWidths) { mProject = project; mCodeLineList = codeLineList; mFormatter = formatter; + mLeftFlags = leftFlags; + + ConfigureColumns(leftFlags, rightWidths); + } + + private void ConfigureColumns(ActiveColumnFlags leftFlags, int[] rightWidths) { + mColEnd = new int[(int)Col.COUNT]; + int total = 0; + int width; + + // offset "+123456" + if ((leftFlags & ActiveColumnFlags.Offset) != 0) { + total = mColEnd[(int)Col.Offset] = total + 7 + 1; + } else { + mColEnd[(int)Col.Offset] = total; + } + + // address "1234:" or "12/4567:" + if ((leftFlags & ActiveColumnFlags.Address) != 0) { + width = mProject.CpuDef.HasAddr16 ? 5 : 8; + total = mColEnd[(int)Col.Address] = total + width + 1; + } else { + mColEnd[(int)Col.Address] = total; + } + + // bytes "12345678+" or "12 45 78 01+" + if ((leftFlags & ActiveColumnFlags.Bytes) != 0) { + // 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. Add one for a trailing "+". + width = mFormatter.Config.mSpacesBetweenBytes ? 12 : 9; + total = mColEnd[(int)Col.Bytes] = total + width + 1; + } else { + mColEnd[(int)Col.Bytes] = total; + } + + // flags "NVMXDIZC" or "NVMXDIZC E" + if ((leftFlags & ActiveColumnFlags.Flags) != 0) { + width = mProject.CpuDef.HasEmuFlag ? 10 : 8; + total = mColEnd[(int)Col.Flags] = total + width + 1; + } else { + mColEnd[(int)Col.Flags] = total; + } + + // attributes "@H!#>" + if ((leftFlags & ActiveColumnFlags.Attr) != 0) { + total = mColEnd[(int)Col.Attr] = total + 5 + 1; + } else { + mColEnd[(int)Col.Attr] = total; + } + + total = mColEnd[(int)Col.Label] = total + rightWidths[0]; + total = mColEnd[(int)Col.Opcode] = total + rightWidths[1]; + total = mColEnd[(int)Col.Operand] = total + rightWidths[2]; + total = mColEnd[(int)Col.Comment] = total + rightWidths[3]; + + //Debug.WriteLine("Export col ends:"); + //for (int i = 0; i < (int)Col.COUNT; i++) { + // Debug.WriteLine(" " + i + "(" + ((Col)i) + ") " + mColEnd[i]); + //} } /// /// Converts the selected lines to formatted text. /// - /// Set of lines to select. - /// Line format. /// Result; holds text of all selected lines. /// Result; holds text of all selected lines, in CSV format. - public void SelectionToText(DisplayListSelection selection, ClipLineFormat lineFormat, - bool addCsv, out string fullText, out string csvText) { - - StringBuilder plainText = new StringBuilder(selection.Count * 50); - StringBuilder sb = new StringBuilder(100); + public void SelectionToString(bool addCsv, out string fullText, out string csvText) { + StringBuilder sb = new StringBuilder(128); + StringBuilder plainText = new StringBuilder(Selection.Count * 50); StringBuilder csv = null; if (addCsv) { - csv = new StringBuilder(selection.Count * 40); + csv = new StringBuilder(Selection.Count * 40); } - int addrAdj = mProject.CpuDef.HasAddr16 ? 6 : 9; - int disAdj = 0; - int bytesWidth = 0; - if (lineFormat == MainController.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 = (mFormatter.Config.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 = mCodeLineList[index]; - DisplayList.FormattedParts parts = mCodeLineList.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: - case LineListGen.Line.Type.LocalVariableTable: - if (lineFormat == 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 (lineFormat == 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; + for (int lineIndex = 0; lineIndex < mCodeLineList.Count; lineIndex++) { + if (!Selection[lineIndex]) { + continue; + } + if (GenerateTextLine(lineIndex, sb)) { + plainText.Append(sb.ToString()); + plainText.Append("\r\n"); } - plainText.Append(sb); sb.Clear(); - 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)); + GenerateCsvLine(lineIndex, sb); + csv.Append(sb.ToString()); csv.Append("\r\n"); + sb.Clear(); } } fullText = plainText.ToString(); - csvText = csv.ToString(); + if (addCsv) { + csvText = csv.ToString(); + } else { + csvText = null; + } + } + + /// + /// Generates a full listing and writes it to the specified file. + /// + /// Full path to output file. + /// Output as Comma Separated Values rather than plain text. + public void OutputToText(string pathName, bool asCsv) { + // Generate UTF-8 text. For plain text we omit the byte-order mark, for CSV + // it appears to be meaningful (tested w/ very old version of Excel). + using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(asCsv))) { + StringBuilder sb = new StringBuilder(128); + for (int lineIndex = 0; lineIndex < mCodeLineList.Count; lineIndex++) { + if (Selection != null && !Selection[lineIndex]) { + continue; + } + + if (asCsv) { + GenerateCsvLine(lineIndex, sb); + sw.WriteLine(sb.ToString()); + } else { + if (GenerateTextLine(lineIndex, sb)) { + sw.WriteLine(sb.ToString()); + } + } + sb.Clear(); + } + } + } + + /// + /// Generates a line of plain text output. The line will not have EOL markers added. + /// + /// Index of line to output. + /// String builder to append text to. Must be cleared before + /// calling here. (This is a minor optimization.) + private bool GenerateTextLine(int index, StringBuilder sb) { + Debug.Assert(sb.Length == 0); + + // Width of "bytes" field, without '+' or trailing space. + int bytesWidth = mColEnd[(int)Col.Bytes] - mColEnd[(int)Col.Address] - 2; + + LineListGen.Line line = mCodeLineList[index]; + DisplayList.FormattedParts parts = mCodeLineList.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: + case LineListGen.Line.Type.LocalVariableTable: + if (parts.IsLongComment) { + // This happens for long comments embedded in LV tables. + if (mColEnd[(int)Col.Attr] != 0) { + TextUtil.AppendPaddedString(sb, string.Empty, mColEnd[(int)Col.Attr]); + } + sb.Append(parts.Comment); + break; + } + + if ((mLeftFlags & ActiveColumnFlags.Offset) != 0) { + TextUtil.AppendPaddedString(sb, parts.Offset, + mColEnd[(int)Col.Offset]); + } + if ((mLeftFlags & ActiveColumnFlags.Address) != 0) { + string str; + if (!string.IsNullOrEmpty(parts.Addr)) { + str = parts.Addr + ":"; + } else { + str = string.Empty; + } + TextUtil.AppendPaddedString(sb, str, mColEnd[(int)Col.Address]); + } + if ((mLeftFlags & ActiveColumnFlags.Bytes) != 0) { + // Shorten the "...". + string bytesStr = parts.Bytes; + if (bytesStr != null && bytesStr.Length > bytesWidth) { + bytesStr = bytesStr.Substring(0, bytesWidth) + "+"; + } + TextUtil.AppendPaddedString(sb, bytesStr, mColEnd[(int)Col.Bytes]); + } + if ((mLeftFlags & ActiveColumnFlags.Flags) != 0) { + TextUtil.AppendPaddedString(sb, parts.Flags, mColEnd[(int)Col.Flags]); + } + if ((mLeftFlags & ActiveColumnFlags.Attr) != 0) { + TextUtil.AppendPaddedString(sb, parts.Attr, mColEnd[(int)Col.Attr]); + } + TextUtil.AppendPaddedString(sb, parts.Label, mColEnd[(int)Col.Label]); + TextUtil.AppendPaddedString(sb, parts.Opcode, mColEnd[(int)Col.Opcode]); + TextUtil.AppendPaddedString(sb, parts.Operand, mColEnd[(int)Col.Operand]); + if (string.IsNullOrEmpty(parts.Comment)) { + // Trim trailing spaces off opcode or operand. Would be more efficient + // to just not generate the spaces, but this is simpler and we're not + // in a hurry. + TextUtil.TrimEnd(sb); + } else { + sb.Append(parts.Comment); + } + break; + case LineListGen.Line.Type.LongComment: + case LineListGen.Line.Type.Note: + if (line.LineType == LineListGen.Line.Type.Note && !IncludeNotes) { + return false; + } + if (mColEnd[(int)Col.Attr] != 0) { + // Long comments aren't the left-most field, so pad it out. + TextUtil.AppendPaddedString(sb, string.Empty, mColEnd[(int)Col.Attr]); + } + sb.Append(parts.Comment); + break; + case LineListGen.Line.Type.Blank: + break; + default: + Debug.Assert(false); + break; + } + return true; + } + + private void GenerateCsvLine(int index, StringBuilder sb) { + LineListGen.Line line = mCodeLineList[index]; + DisplayList.FormattedParts parts = mCodeLineList.GetFormattedParts(index); + + if ((mLeftFlags & ActiveColumnFlags.Offset) != 0) { + sb.Append(TextUtil.EscapeCSV(parts.Offset)); sb.Append(','); + } + if ((mLeftFlags & ActiveColumnFlags.Address) != 0) { + sb.Append(TextUtil.EscapeCSV(parts.Addr)); sb.Append(','); + } + if ((mLeftFlags & ActiveColumnFlags.Bytes) != 0) { + sb.Append(TextUtil.EscapeCSV(parts.Bytes)); sb.Append(','); + } + if ((mLeftFlags & ActiveColumnFlags.Flags) != 0) { + sb.Append(TextUtil.EscapeCSV(parts.Flags)); sb.Append(','); + } + if ((mLeftFlags & ActiveColumnFlags.Attr) != 0) { + sb.Append(TextUtil.EscapeCSV(parts.Attr)); sb.Append(','); + } + if (parts.IsLongComment) { + // put the comment in the Label column + sb.Append(TextUtil.EscapeCSV(parts.Comment)); sb.Append(",,,"); + } else { + sb.Append(TextUtil.EscapeCSV(parts.Label)); sb.Append(','); + sb.Append(TextUtil.EscapeCSV(parts.Opcode)); sb.Append(','); + sb.Append(TextUtil.EscapeCSV(parts.Operand)); sb.Append(','); + sb.Append(TextUtil.EscapeCSV(parts.Comment)); + } + } + + public void OutputToHtml(string pathName, bool overwriteCss) { + Debug.WriteLine("HTML"); // TODO } } } diff --git a/SourceGen/LineListGen.cs b/SourceGen/LineListGen.cs index 1ce2a83..8c434aa 100644 --- a/SourceGen/LineListGen.cs +++ b/SourceGen/LineListGen.cs @@ -1256,9 +1256,17 @@ namespace SourceGen { int cycles = mProject.CpuDef.GetCycles(op.Opcode, attr.StatusFlags, attr.BranchTaken, branchCross); if (cycles > 0) { - eolComment = cycles.ToString() + " " + eolComment; + if (!string.IsNullOrEmpty(eolComment)) { + eolComment = cycles.ToString() + " " + eolComment; + } else { + eolComment = cycles.ToString(); + } } else { - eolComment = (-cycles).ToString() + "+ " + eolComment; + if (!string.IsNullOrEmpty(eolComment)) { + eolComment = (-cycles).ToString() + "+ " + eolComment; + } else { + eolComment = (-cycles).ToString() + "+"; + } } } string commentStr = mFormatter.FormatEolComment(eolComment); diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs index 27039ac..73e4fbe 100644 --- a/SourceGen/MainController.cs +++ b/SourceGen/MainController.cs @@ -185,7 +185,8 @@ namespace SourceGen { public enum ClipLineFormat { Unknown = -1, AssemblerSource = 0, - Disassembly = 1 + Disassembly = 1, + AllColumns = 2 } /// @@ -1291,14 +1292,29 @@ namespace SourceGen { /// public void CopyToClipboard() { DisplayListSelection selection = mMainWin.CodeDisplayList.SelectedIndices; + if (selection.Count == 0) { + Debug.WriteLine("Selection is empty!"); + return; + } + ClipLineFormat format = (ClipLineFormat)AppSettings.Global.GetEnum( AppSettings.CLIP_LINE_FORMAT, typeof(ClipLineFormat), (int)ClipLineFormat.AssemblerSource); - Exporter eport = new Exporter(mProject, CodeLineList, mOutputFormatter); - eport.SelectionToText(selection, format, true, - out string fullText, out string csvText); + int[] rightWidths = new int[] { 9, 8, 11, 100 }; + + Exporter.ActiveColumnFlags colFlags = Exporter.ActiveColumnFlags.None; + if (format == ClipLineFormat.Disassembly) { + colFlags |= Exporter.ActiveColumnFlags.Address | + Exporter.ActiveColumnFlags.Bytes; + } else if (format == ClipLineFormat.AllColumns) { + colFlags = Exporter.ActiveColumnFlags.ALL; + } + Exporter eport = new Exporter(mProject, CodeLineList, mOutputFormatter, + colFlags, rightWidths); + eport.Selection = selection; + eport.SelectionToString(true, out string fullText, out string csvText); DataObject dataObject = new DataObject(); dataObject.SetText(fullText.ToString()); @@ -1954,12 +1970,45 @@ namespace SourceGen { } public void Export() { - Export dlg = new Export(mMainWin); + string outName; + if (string.IsNullOrEmpty(mProjectPathName)) { + outName = Path.GetFileName(mDataPathName); + } else { + outName = Path.GetFileName(mProjectPathName); + } + + Export dlg = new Export(mMainWin, outName); if (dlg.ShowDialog() == false) { return; } - // TODO + int[] rightWidths = new int[] { + dlg.AsmLabelColWidth, dlg.AsmOpcodeColWidth, + dlg.AsmOperandColWidth, dlg.AsmCommentColWidth + }; + Exporter eport = new Exporter(mProject, CodeLineList, mOutputFormatter, + dlg.ColFlags, rightWidths); + eport.IncludeNotes = dlg.IncludeNotes; + if (dlg.SelectionOnly) { + DisplayListSelection selection = mMainWin.CodeDisplayList.SelectedIndices; + if (selection.Count == 0) { + // no selection == select all + selection = null; + } + eport.Selection = selection; + } + + try { + Mouse.OverrideCursor = Cursors.Wait; + + if (dlg.GenType == WpfGui.Export.GenerateFileType.Html) { + eport.OutputToHtml(dlg.PathName, dlg.OverwriteCss); + } else { + eport.OutputToText(dlg.PathName, dlg.TextModeCsv); + } + } finally { + Mouse.OverrideCursor = null; + } } public void Find() { diff --git a/SourceGen/Res/Strings.xaml b/SourceGen/Res/Strings.xaml index 42ae788..ebd26e7 100644 --- a/SourceGen/Res/Strings.xaml +++ b/SourceGen/Res/Strings.xaml @@ -30,6 +30,7 @@ limitations under the License. Assembled output does not match: offset +{0:x6} has value ${1:x2}, expected ${2:x2}. Assembled output does not match: length is {0}, expected {1}. Expected output file wasn't created + All Columns Assembler Source Disassembly 6502bench SourceGen v{0} @@ -64,9 +65,12 @@ limitations under the License. Symbol files and extension scripts must live in the application runtime directory ({0}) or project directory ({1}). File {2} lives elsewhere. File Not In Runtime Directory All files (*.*)|*.* - C# Source Files(*.cs)|*.cs - SourceGen projects(*.dis65)|*.dis65 + C# Source Files (*.cs)|*.cs + CSV files (*.csv)|*.csv + SourceGen projects (*.dis65)|*.dis65 + HTML files (*.html)|*.html SourceGen symbols (*.sym65)|*.sym65 + Text files (*.txt)|*.txt File is {0:N1} KB of raw data. Find reached the starting point of the search. Find... diff --git a/SourceGen/Res/Strings.xaml.cs b/SourceGen/Res/Strings.xaml.cs index ee9cc53..36903ff 100644 --- a/SourceGen/Res/Strings.xaml.cs +++ b/SourceGen/Res/Strings.xaml.cs @@ -53,6 +53,8 @@ namespace SourceGen.Res { (string)Application.Current.FindResource("str_DefaultC64PetsciiDelimPat"); public static string DEFAULT_C64_SCREEN_CODE_DELIM_PAT = (string)Application.Current.FindResource("str_DefaultC64ScreenCodeDelimPat"); + public static string CLIPFORMAT_ALL_COLUMNS = + (string)Application.Current.FindResource("str_ClipformatAllColumns"); public static string CLIPFORMAT_ASSEMBLER_SOURCE = (string)Application.Current.FindResource("str_ClipformatAssemblerSource"); public static string CLIPFORMAT_DISASSEMBLY = @@ -111,10 +113,16 @@ namespace SourceGen.Res { (string)Application.Current.FindResource("str_FileFilterAll"); public static string FILE_FILTER_CS = (string)Application.Current.FindResource("str_FileFilterCs"); + public static string FILE_FILTER_CSV = + (string)Application.Current.FindResource("str_FileFilterCsv"); public static string FILE_FILTER_DIS65 = (string)Application.Current.FindResource("str_FileFilterDis65"); + public static string FILE_FILTER_HTML = + (string)Application.Current.FindResource("str_FileFilterHtml"); public static string FILE_FILTER_SYM65 = (string)Application.Current.FindResource("str_FileFilterSym65"); + public static string FILE_FILTER_TEXT = + (string)Application.Current.FindResource("str_FileFilterText"); public static string FILE_INFO_FMT = (string)Application.Current.FindResource("str_FileInfoFmt"); public static string FIND_REACHED_START = diff --git a/SourceGen/WpfGui/EditAppSettings.xaml.cs b/SourceGen/WpfGui/EditAppSettings.xaml.cs index a845c7a..0be7aec 100644 --- a/SourceGen/WpfGui/EditAppSettings.xaml.cs +++ b/SourceGen/WpfGui/EditAppSettings.xaml.cs @@ -247,7 +247,9 @@ namespace SourceGen.WpfGui { new ClipboardFormatItem(Res.Strings.CLIPFORMAT_ASSEMBLER_SOURCE, MainController.ClipLineFormat.AssemblerSource), new ClipboardFormatItem(Res.Strings.CLIPFORMAT_DISASSEMBLY, - MainController.ClipLineFormat.Disassembly) + MainController.ClipLineFormat.Disassembly), + new ClipboardFormatItem(Res.Strings.CLIPFORMAT_ALL_COLUMNS, + MainController.ClipLineFormat.AllColumns) }; // ItemsSource for combo box public ClipboardFormatItem[] ClipboardFormatItems { diff --git a/SourceGen/WpfGui/Export.xaml b/SourceGen/WpfGui/Export.xaml index 25285b7..6bc33ae 100644 --- a/SourceGen/WpfGui/Export.xaml +++ b/SourceGen/WpfGui/Export.xaml @@ -23,7 +23,8 @@ limitations under the License. mc:Ignorable="d" Title="Export Source" SizeToContent="WidthAndHeight" ResizeMode="NoResize" - ShowInTaskbar="False" WindowStartupLocation="CenterOwner"> + ShowInTaskbar="False" WindowStartupLocation="CenterOwner" + Loaded="Window_Loaded"> @@ -32,12 +33,15 @@ limitations under the License. - + - - - + + + + + + @@ -82,20 +86,23 @@ limitations under the License. + + + - - + + - - + + @@ -107,9 +114,9 @@ limitations under the License.