1
0
mirror of https://github.com/fadden/6502bench.git synced 2025-04-10 05:38:54 +00:00

Add first pass at source export dialog

Ported the column width stuff from EditAppSettings, which it turns
out can be simplified slightly.

Moved the clipboard copy code out into its own class.

Disabled "File > Print", which has never done anything and isn't
likely to do anything in the near future.

Also, added a note to 2019-local-variables about a test case it
should probably have.
This commit is contained in:
Andy McFadden 2019-09-10 17:43:31 -07:00
parent 2d5bdd27a8
commit e5104dc2e7
10 changed files with 441 additions and 110 deletions

155
SourceGen/Exporter.cs Normal file
View File

@ -0,0 +1,155 @@
/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Asm65;
using CommonUtil;
using ClipLineFormat = SourceGen.MainController.ClipLineFormat;
namespace SourceGen {
public class Exporter {
/// <summary>
/// Project reference.
/// </summary>
private DisasmProject mProject;
/// <summary>
/// List of formatted parts.
/// </summary>
private LineListGen mCodeLineList;
/// <summary>
/// Text formatter.
/// </summary>
private Formatter mFormatter;
/// <summary>
/// Constructor.
/// </summary>
public Exporter(DisasmProject project, LineListGen codeLineList, Formatter formatter) {
mProject = project;
mCodeLineList = codeLineList;
mFormatter = formatter;
}
/// <summary>
/// Converts the selected lines to formatted text.
/// </summary>
/// <param name="selection">Set of lines to select.</param>
/// <param name="lineFormat">Line format.</param>
/// <param name="fullText">Result; holds text of all selected lines.</param>
/// <param name="csvText">Result; holds text of all selected lines, in CSV format.</param>
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);
StringBuilder csv = null;
if (addCsv) {
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;
}
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));
csv.Append("\r\n");
}
}
fullText = plainText.ToString();
csvText = csv.ToString();
}
}
}

View File

@ -1290,99 +1290,15 @@ namespace SourceGen {
/// Copies the selection to the clipboard as formatted text.
/// </summary>
public void CopyToClipboard() {
const bool addCsv = true;
DisplayListSelection selection = mMainWin.CodeDisplayList.SelectedIndices;
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:
case LineListGen.Line.Type.LocalVariableTable:
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();
}
Exporter eport = new Exporter(mProject, CodeLineList, mOutputFormatter);
eport.SelectionToText(selection, format, true,
out string fullText, out string csvText);
DataObject dataObject = new DataObject();
dataObject.SetText(fullText.ToString());
@ -1395,8 +1311,9 @@ namespace SourceGen {
// should probably be optional.)
//
// https://stackoverflow.com/a/369219/294248
const bool addCsv = true;
if (addCsv) {
byte[] csvData = Encoding.UTF8.GetBytes(csv.ToString());
byte[] csvData = Encoding.UTF8.GetBytes(csvText.ToString());
MemoryStream stream = new MemoryStream(csvData);
dataObject.SetData(DataFormats.CommaSeparatedValue, stream);
}
@ -2036,6 +1953,15 @@ namespace SourceGen {
}
}
public void Export() {
Export dlg = new Export(mMainWin);
if (dlg.ShowDialog() == false) {
return;
}
// TODO
}
public void Find() {
FindBox dlg = new FindBox(mMainWin, mFindString);
if (dlg.ShowDialog() == true) {

View File

@ -2,7 +2,7 @@
{
"_ContentVersion":2,"FileDataLength":137,"FileDataCrc32":708791740,"ProjectProps":{
"CpuName":"65816","IncludeUndocumentedInstr":false,"EntryFlags":32702671,"AutoLabelStyle":"Simple","AnalysisParams":{
"AnalyzeUncategorizedData":true,"DefaultTextScanMode":"LowHighAscii","MinCharsForString":4,"SeekNearbyTargets":true},
"AnalyzeUncategorizedData":true,"DefaultTextScanMode":"LowHighAscii","MinCharsForString":4,"SeekNearbyTargets":true,"SmartPlpHandling":false},
"PlatformSymbolFileIdentifiers":[],"ExtensionScriptFileIdentifiers":[],"ProjectSyms":{
"CONST_ONE":{
"DataDescriptor":{
@ -38,7 +38,8 @@
"81":{
"Text":"Test name redefinition. This is mostly of interest for assemblers without redefinable variables, but also of interest to the cross-reference window.","BoxMode":false,"MaxWidth":80,"BackgroundColor":0}},
"Notes":{
},
"0":{
"Text":"Should add a variable that conflicts with an auto-label.","BoxMode":false,"MaxWidth":80,"BackgroundColor":-256}},
"UserLabels":{
"87":{
"Label":"PTR_1","Value":4183,"Source":"User","Type":"LocalOrGlobalAddr"},

View File

@ -76,6 +76,7 @@
<Compile Include="AsmGen\IAssembler.cs" />
<Compile Include="AsmGen\IGenerator.cs" />
<Compile Include="AsmGen\LabelLocalizer.cs" />
<Compile Include="Exporter.cs" />
<Compile Include="FormattedOperandCache.cs" />
<Compile Include="LocalVariableLookup.cs" />
<Compile Include="Tests\GenTest.cs" />
@ -127,6 +128,9 @@
<Compile Include="WpfGui\EditProjectProperties.xaml.cs">
<DependentUpon>EditProjectProperties.xaml</DependentUpon>
</Compile>
<Compile Include="WpfGui\Export.xaml.cs">
<DependentUpon>Export.xaml</DependentUpon>
</Compile>
<Compile Include="WpfGui\FindBox.xaml.cs">
<DependentUpon>FindBox.xaml</DependentUpon>
</Compile>
@ -290,6 +294,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="WpfGui\Export.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="WpfGui\FindBox.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -88,7 +88,7 @@ limitations under the License.
<GroupBox Grid.Column="1" Grid.Row="1" Header="Upper Case Display"
Margin="5,0,5,0" Padding="2,4">
<StackPanel>
<CheckBox Content="Hexadecimal Values" Margin="0,4"
<CheckBox Content="Hexadecimal values" Margin="0,4"
IsChecked="{Binding UpperHexValues}"/>
<CheckBox Content="Opcodes" Margin="0,4"
IsChecked="{Binding UpperOpcodes}"/>
@ -444,8 +444,7 @@ limitations under the License.
<TextBlock Grid.Column="0" Grid.Row="2" Text="Column widths:"
HorizontalAlignment="Right" Margin="0,0,4,0"/>
<StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal">
<TextBox Name="asmLabelColWidthTextBox" Width="60" Margin="0,0,4,0"
TextChanged="AsmColWidthTextBox_TextChanged">
<TextBox Name="asmLabelColWidthTextBox" Width="60" Margin="0,0,4,0">
<TextBox.Text>
<Binding Path="AsmLabelColWidth" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
@ -454,8 +453,7 @@ limitations under the License.
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="asmOpcodeColWidthTextBox" Width="60" Margin="0,0,4,0"
TextChanged="AsmColWidthTextBox_TextChanged">
<TextBox Name="asmOpcodeColWidthTextBox" Width="60" Margin="0,0,4,0">
<TextBox.Text>
<Binding Path="AsmOpcodeColWidth" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
@ -464,8 +462,7 @@ limitations under the License.
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="asmOperandColWidthTextBox" Width="60" Margin="0,0,4,0"
TextChanged="AsmColWidthTextBox_TextChanged">
<TextBox Name="asmOperandColWidthTextBox" Width="60" Margin="0,0,4,0">
<TextBox.Text>
<Binding Path="AsmOperandColWidth" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
@ -474,8 +471,7 @@ limitations under the License.
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="asmCommentColWidthTextBox" Width="60" Margin="0,0,8,0"
TextChanged="AsmColWidthTextBox_TextChanged">
<TextBox Name="asmCommentColWidthTextBox" Width="60" Margin="0,0,8,0">
<TextBox.Text>
<Binding Path="AsmCommentColWidth" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>

View File

@ -577,6 +577,11 @@ namespace SourceGen.WpfGui {
// Apply/OK buttons when invalid input is present. Instead we just set the width to
// the minimum value when validation fails.
//
// Note that the "set" property is only called when the value changes, which only
// happens when a valid integer is typed. If you enter garbage, the dirty flag doesn't
// get set. That's just fine for us, but if you need to disable an "is valid" flag
// on bad input you can't rely on updating it at "set" time.
//
// See also https://stackoverflow.com/a/44586784/294248
//
private int mAsmLabelColWidth;
@ -586,7 +591,7 @@ namespace SourceGen.WpfGui {
if (mAsmLabelColWidth != value) {
mAsmLabelColWidth = value;
OnPropertyChanged();
IsDirty = true;
AsmColWidthTextChanged();
}
}
}
@ -597,7 +602,7 @@ namespace SourceGen.WpfGui {
if (mAsmOpcodeColWidth != value) {
mAsmOpcodeColWidth = value;
OnPropertyChanged();
IsDirty = true;
AsmColWidthTextChanged();
}
}
}
@ -608,7 +613,7 @@ namespace SourceGen.WpfGui {
if (mAsmOperandColWidth != value) {
mAsmOperandColWidth = value;
OnPropertyChanged();
IsDirty = true;
AsmColWidthTextChanged();
}
}
}
@ -619,7 +624,7 @@ namespace SourceGen.WpfGui {
if (mAsmCommentColWidth != value) {
mAsmCommentColWidth = value;
OnPropertyChanged();
IsDirty = true;
AsmColWidthTextChanged();
}
}
}
@ -711,7 +716,7 @@ namespace SourceGen.WpfGui {
/// populated. That means we'll have incorrect intermediate states, but should
/// finish up correctly.
/// </remarks>
private void AsmColWidthTextBox_TextChanged(object sender, TextChangedEventArgs e) {
private void AsmColWidthTextChanged() {
AssemblerInfo asm = (AssemblerInfo)asmConfigComboBox.SelectedItem;
if (asm == null) {
// fires during dialog initialization, before anything is selected

View File

@ -0,0 +1,117 @@
<!--
Copyright 2019 faddenSoft
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Window x:Class="SourceGen.WpfGui.Export"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SourceGen.WpfGui"
mc:Ignorable="d"
Title="Export Source"
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
ShowInTaskbar="False" WindowStartupLocation="CenterOwner">
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Header="General Options" Padding="2,4">
<StackPanel>
<CheckBox Content="Include notes"/>
<CheckBox Content="Show address column" Margin="0,2,0,0"/>
<CheckBox Content="Show bytes column" Margin="0,2,0,0"/>
<TextBlock Text="Column widths (label, opcode, operand, comment):" Margin="0,4,0,0"/>
<StackPanel Orientation="Horizontal" Margin="0,4,0,0">
<TextBox Name="asmLabelColWidthTextBox" Width="60" Margin="0,0,4,0"
TextChanged="AsmColWidthTextBox_TextChanged">
<TextBox.Text>
<Binding Path="AsmLabelColWidth" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="asmOpcodeColWidthTextBox" Width="60" Margin="0,0,4,0"
TextChanged="AsmColWidthTextBox_TextChanged">
<TextBox.Text>
<Binding Path="AsmOpcodeColWidth" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="asmOperandColWidthTextBox" Width="60" Margin="0,0,4,0"
TextChanged="AsmColWidthTextBox_TextChanged">
<TextBox.Text>
<Binding Path="AsmOperandColWidth" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="asmCommentColWidthTextBox" Width="60" Margin="0,0,8,0"
TextChanged="AsmColWidthTextBox_TextChanged">
<TextBox.Text>
<Binding Path="AsmCommentColWidth" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
</StackPanel>
</GroupBox>
<GroupBox Grid.Row="1" Header="Text Options" Padding="2,4">
<StackPanel>
<RadioButton Content="Plain text (UTF-8)" GroupName="TextMode"/>
<RadioButton Content="CSV" GroupName="TextMode" Margin="0,2,0,0"/>
</StackPanel>
</GroupBox>
<GroupBox Grid.Row="2" Header="HTML Options" Padding="2,4">
<StackPanel>
<CheckBox Content="Include symbol table"/>
<CheckBox Content="Overwrite CSS file" Margin="0,2,0,0"/>
</StackPanel>
</GroupBox>
<Grid Grid.Row="3" Margin="0,8,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="Generate HTML" Width="100"
IsEnabled="{Binding IsValid}"/>
<Button Grid.Column="1" Content="Generate Text" Width="100" Margin="8,0,0,0"
IsEnabled="{Binding IsValid}"/>
<Button Grid.Column="2" Content="Cancel" IsCancel="True" Width="70" Margin="8,0,0,0"
HorizontalAlignment="Right"/>
</Grid>
</Grid>
</Window>

View File

@ -0,0 +1,115 @@
/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
namespace SourceGen.WpfGui {
/// <summary>
/// Export selection dialog.
/// </summary>
public partial class Export : Window, INotifyPropertyChanged {
//
// Numeric input fields, bound directly to TextBox.Text. These rely on a TextChanged
// field to update the IsValid flag, because the "set" method is only called when the
// field contains a valid integer.
//
private int mAsmLabelColWidth;
public int AsmLabelColWidth {
get { return mAsmLabelColWidth; }
set {
if (mAsmLabelColWidth != value) {
mAsmLabelColWidth = value;
OnPropertyChanged();
}
}
}
private int mAsmOpcodeColWidth;
public int AsmOpcodeColWidth {
get { return mAsmOpcodeColWidth; }
set {
if (mAsmOpcodeColWidth != value) {
mAsmOpcodeColWidth = value;
OnPropertyChanged();
}
}
}
private int mAsmOperandColWidth;
public int AsmOperandColWidth {
get { return mAsmOperandColWidth; }
set {
if (mAsmOperandColWidth != value) {
mAsmOperandColWidth = value;
OnPropertyChanged();
}
}
}
private int mAsmCommentColWidth;
public int AsmCommentColWidth {
get { return mAsmCommentColWidth; }
set {
if (mAsmCommentColWidth != value) {
mAsmCommentColWidth = value;
OnPropertyChanged();
}
}
}
/// <summary>
/// Valid flag, used to enable the "generate" buttons.
/// </summary>
public bool IsValid {
get { return mIsValid; }
set { mIsValid = value; OnPropertyChanged(); }
}
private bool mIsValid;
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public Export(Window owner) {
InitializeComponent();
Owner = owner;
DataContext = this;
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
// TODO
}
private void UpdateControls() {
bool isValid = true;
isValid &= !Validation.GetHasError(asmLabelColWidthTextBox);
isValid &= !Validation.GetHasError(asmOpcodeColWidthTextBox);
isValid &= !Validation.GetHasError(asmOperandColWidthTextBox);
isValid &= !Validation.GetHasError(asmCommentColWidthTextBox);
IsValid = isValid;
}
private void AsmColWidthTextBox_TextChanged(object sender, TextChangedEventArgs e) {
UpdateControls();
}
}
}

View File

@ -94,6 +94,7 @@ limitations under the License.
<RoutedUICommand x:Key="EditProjectSymbolCmd" Text="Edit Project Symbol..."/>
<RoutedUICommand x:Key="EditStatusFlagsCmd" Text="Override Status Flags..."/>
<RoutedUICommand x:Key="ExitCmd" Text="Exit"/>
<RoutedUICommand x:Key="ExportCmd" Text="Export..."/>
<RoutedUICommand x:Key="FindNextCmd" Text="Find Next">
<RoutedUICommand.InputGestures>
<KeyGesture>F3</KeyGesture>
@ -207,6 +208,8 @@ limitations under the License.
CanExecute="CanEditStatusFlags" Executed="EditStatusFlagsCmd_Executed"/>
<CommandBinding Command="{StaticResource ExitCmd}"
Executed="ExitCmd_Executed"/>
<CommandBinding Command="{StaticResource ExportCmd}"
CanExecute="IsProjectOpen" Executed="ExportCmd_Executed"/>
<CommandBinding Command="Find"
CanExecute="IsProjectOpen" Executed="FindCmd_Executed"/>
<CommandBinding Command="{StaticResource FindNextCmd}"
@ -291,7 +294,8 @@ limitations under the License.
<MenuItem Command="{StaticResource CloseCmd}"/>
<Separator/>
<MenuItem Command="{StaticResource AssembleCmd}"/>
<MenuItem Command="Print"/>
<!--<MenuItem Command="Print"/>-->
<MenuItem Command="{StaticResource ExportCmd}"/>
<Separator/>
<MenuItem Name="recentProjectsMenu" Header="Recent Projects" SubmenuOpened="RecentProjectsMenu_SubmenuOpened">
<MenuItem Header="(none)"/>

View File

@ -1101,6 +1101,10 @@ namespace SourceGen.WpfGui {
mMainCtrl.EditOperand();
}
private void EditProjectPropertiesCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.EditProjectProperties();
}
private void EditProjectSymbolCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.EditProjectSymbol();
}
@ -1113,6 +1117,10 @@ namespace SourceGen.WpfGui {
Close();
}
private void ExportCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.Export();
}
private void FindCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.Find();
}
@ -1168,10 +1176,6 @@ namespace SourceGen.WpfGui {
mMainCtrl.OpenProject();
}
private void EditProjectPropertiesCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.EditProjectProperties();
}
private void RecentProjectCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
int recentIndex;
if (e.Parameter is int) {