diff --git a/SourceGenWPF/MainController.cs b/SourceGenWPF/MainController.cs
index 30c4d14..aec5279 100644
--- a/SourceGenWPF/MainController.cs
+++ b/SourceGenWPF/MainController.cs
@@ -966,7 +966,10 @@ namespace SourceGenWPF {
return false;
}
- // Save the project. If it hasn't been saved before, use save-as behavior instead.
+ ///
+ /// Save the project. If it hasn't been saved before, use save-as behavior instead.
+ ///
+ /// True on success, false if the save attempt failed.
private bool DoSave() {
if (string.IsNullOrEmpty(mProjectPathName)) {
return DoSaveAs();
@@ -1054,6 +1057,7 @@ namespace SourceGenWPF {
}
mDataPathName = null;
mProjectPathName = null;
+ mTargetHighlightIndex = -1;
#if false
mSymbolSubset = new SymbolTableSubset(new SymbolTable());
#endif
@@ -1101,11 +1105,9 @@ namespace SourceGenWPF {
}
break;
case LineListGen.Line.Type.RegWidthDirective:
-#if false
- if (overrideStatusFlagsToolStripMenuItem.Enabled) {
- EditStatusFlags_Click(sender, e);
+ if (CanEditStatusFlags()) {
+ EditStatusFlags();
}
-#endif
break;
case LineListGen.Line.Type.LongComment:
#if false
@@ -1143,11 +1145,9 @@ namespace SourceGenWPF {
#endif
break;
case ColumnIndex.Flags:
-#if false
- if (overrideStatusFlagsToolStripMenuItem.Enabled) {
- EditStatusFlags_Click(sender, e);
+ if (CanEditStatusFlags()) {
+ EditStatusFlags();
}
-#endif
break;
case ColumnIndex.Attributes:
// does nothing
@@ -1230,8 +1230,7 @@ namespace SourceGenWPF {
Anattrib attr = mProject.GetAnattrib(offset);
EditAddress dlg = new EditAddress(mMainWin, attr.Address, mProject.CpuDef.MaxAddressValue);
- bool? ok = dlg.ShowDialog();
- if (ok != true) {
+ if (dlg.ShowDialog() != true) {
return;
}
@@ -1258,6 +1257,34 @@ namespace SourceGenWPF {
}
}
+ public bool CanEditStatusFlags() {
+ if (SelectionAnalysis.mNumItemsSelected != 1) {
+ return false;
+ }
+ EntityCounts counts = SelectionAnalysis.mEntityCounts;
+ // Line must be code, or a RegWidth directive.
+ return (SelectionAnalysis.mLineType == LineListGen.Line.Type.Code ||
+ SelectionAnalysis.mLineType == LineListGen.Line.Type.RegWidthDirective);
+ }
+
+ public void EditStatusFlags() {
+ int selIndex = mMainWin.CodeListView_GetFirstSelectedIndex();
+ int offset = CodeLineList[selIndex].FileOffset;
+
+ EditStatusFlags dlg = new EditStatusFlags(mMainWin,
+ mProject.StatusFlagOverrides[offset], mProject.CpuDef.HasEmuFlag);
+ if (dlg.ShowDialog() != true) {
+ return;
+ }
+
+ if (dlg.FlagValue != mProject.StatusFlagOverrides[offset]) {
+ UndoableChange uc = UndoableChange.CreateStatusFlagChange(offset,
+ mProject.StatusFlagOverrides[offset], dlg.FlagValue);
+ ChangeSet cs = new ChangeSet(uc);
+ ApplyUndoableChanges(cs);
+ }
+ }
+
///
/// Moves the view and selection to the specified offset. We want to select stuff
/// differently if we're jumping to a note vs. jumping to an instruction.
@@ -1318,23 +1345,6 @@ namespace SourceGenWPF {
}
}
- ///
- /// Scrolls the code list so that the specified label is shown.
- ///
- /// Label symbol.
- public void GoToLabel(Symbol sym) {
- if (sym.IsInternalLabel) {
- int offset = mProject.FindLabelOffsetByName(sym.Label);
- if (offset >= 0) {
- GoToOffset(offset, false, true);
- } else {
- Debug.WriteLine("DClick symbol: " + sym + ": label not found");
- }
- } else {
- Debug.WriteLine("DClick symbol: " + sym + ": not label");
- }
- }
-
public bool CanNavigateBackward() {
return mNavStack.HasBackward;
}
@@ -1353,6 +1363,23 @@ namespace SourceGenWPF {
GoToOffset(fwdOff, false, false);
}
+ ///
+ /// Scrolls the code list so that the specified label is shown.
+ ///
+ /// Label symbol.
+ public void GoToLabel(Symbol sym) {
+ if (sym.IsInternalLabel) {
+ int offset = mProject.FindLabelOffsetByName(sym.Label);
+ if (offset >= 0) {
+ GoToOffset(offset, false, true);
+ } else {
+ Debug.WriteLine("DClick symbol: " + sym + ": label not found");
+ }
+ } else {
+ Debug.WriteLine("DClick symbol: " + sym + ": not label");
+ }
+ }
+
public void SelectionChanged() {
SelectionAnalysis = UpdateSelectionState();
diff --git a/SourceGenWPF/ProjWin/DiscardChanges.xaml b/SourceGenWPF/ProjWin/DiscardChanges.xaml
index 7d31d58..38e16ee 100644
--- a/SourceGenWPF/ProjWin/DiscardChanges.xaml
+++ b/SourceGenWPF/ProjWin/DiscardChanges.xaml
@@ -22,15 +22,20 @@ limitations under the License.
xmlns:local="clr-namespace:SourceGenWPF.ProjWin"
mc:Ignorable="d"
Title="Discard Changes?"
+ FocusManager.FocusedElement="{Binding ElementName=cancelButton}"
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
ShowInTaskbar="False" WindowStartupLocation="CenterOwner">
+
-
-
-
+
+
+
diff --git a/SourceGenWPF/ProjWin/DiscardChanges.xaml.cs b/SourceGenWPF/ProjWin/DiscardChanges.xaml.cs
index 191dcc1..cb91621 100644
--- a/SourceGenWPF/ProjWin/DiscardChanges.xaml.cs
+++ b/SourceGenWPF/ProjWin/DiscardChanges.xaml.cs
@@ -36,10 +36,6 @@ namespace SourceGenWPF.ProjWin {
Owner = owner;
}
- // TODO:
- // https://stackoverflow.com/questions/817610/wpf-and-initial-focus
- // FocusManager.FocusedElement={Binding ElementName=cancelButton}"
-
private void SaveButton_Click(object sender, RoutedEventArgs e) {
UserChoice = Choice.SaveAndContinue;
DialogResult = true;
diff --git a/SourceGenWPF/ProjWin/EditStatusFlags.xaml b/SourceGenWPF/ProjWin/EditStatusFlags.xaml
new file mode 100644
index 0000000..dc457d2
--- /dev/null
+++ b/SourceGenWPF/ProjWin/EditStatusFlags.xaml
@@ -0,0 +1,242 @@
+
+
+
+
+
+
+
+
+
+ Override the processor state values determined by the code analyzer.
+
+
+
+
+ Default
+ Zero
+ One
+ Indeterminate
+
+
+
+
+ N
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ V
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ M
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ X
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ D
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ I
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Z
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ E
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tip: to configure 16-bit wide regs on 65802/65816, set M, X, and E to 0.
+
+
+
+
+
+
+
+
+
diff --git a/SourceGenWPF/ProjWin/EditStatusFlags.xaml.cs b/SourceGenWPF/ProjWin/EditStatusFlags.xaml.cs
new file mode 100644
index 0000000..270bd09
--- /dev/null
+++ b/SourceGenWPF/ProjWin/EditStatusFlags.xaml.cs
@@ -0,0 +1,169 @@
+/*
+ * 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.Windows;
+using System.Windows.Controls;
+
+using Asm65;
+
+namespace SourceGenWPF.ProjWin {
+ ///
+ /// Edit Status Flags dialog.
+ ///
+ public partial class EditStatusFlags : Window {
+ ///
+ /// Edited status flag value.
+ ///
+ public StatusFlags FlagValue { get; private set; }
+
+ ///
+ /// Set this if the CPU has an emulation flag (65802/65816). If this isn't
+ /// set, the M, X, and E flag buttons will be disabled.
+ ///
+ private bool mHasEmuFlag;
+
+
+ public EditStatusFlags(Window owner, StatusFlags flagValue, bool hasEmuFlag) {
+ InitializeComponent();
+
+ FlagValue = flagValue;
+ mHasEmuFlag = hasEmuFlag;
+ }
+
+ private void Window_Loaded(object sender, RoutedEventArgs e) {
+ if (!mHasEmuFlag) {
+ panelM.IsEnabled = false;
+ panelX.IsEnabled = false;
+ panelE.IsEnabled = false;
+
+ // I'm not going to force the M/X/E flags to have a particular value based
+ // on the CPU definition. The flags aren't used for non-65802/65816, so
+ // the values are irrelevant. If somebody is switching between CPUs I think
+ // it'd be weird to force the values during editing but leave any non-edited
+ // values alone. If they want to switch to 65816, set M/X/E, and then switch
+ // back, they're welcome to do so.
+ }
+
+ SetCheckedButtons();
+ }
+
+ private void OkButton_Click(object sender, RoutedEventArgs e) {
+ StatusFlags flags = new StatusFlags();
+
+ flags.N = GetChecked(radioNDefault, radioNZero, radioNOne, radioNIndeterminate);
+ flags.V = GetChecked(radioVDefault, radioVZero, radioVOne, radioVIndeterminate);
+ flags.M = GetChecked(radioMDefault, radioMZero, radioMOne, radioMIndeterminate);
+ flags.X = GetChecked(radioXDefault, radioXZero, radioXOne, radioXIndeterminate);
+ flags.D = GetChecked(radioDDefault, radioDZero, radioDOne, radioDIndeterminate);
+ flags.I = GetChecked(radioIDefault, radioIZero, radioIOne, radioIIndeterminate);
+ flags.Z = GetChecked(radioZDefault, radioZZero, radioZOne, radioZIndeterminate);
+ flags.C = GetChecked(radioCDefault, radioCZero, radioCOne, radioCIndeterminate);
+ flags.E = GetChecked(radioEDefault, radioEZero, radioEOne, radioEIndeterminate);
+
+ //// If they're setting emulation mode, also set M/X to 1. This is implicitly
+ //// true, but things are a bit clearer if we make it explicit.
+ //if (flags.E == 1) {
+ // flags.M = flags.X = 1;
+ //}
+
+ FlagValue = flags;
+ DialogResult = true;
+ }
+
+ private void ResetButton_Click(object sender, EventArgs e) {
+ FlagValue = new StatusFlags();
+ SetCheckedButtons();
+ }
+
+ ///
+ /// Calls SetChecked() for each flag.
+ ///
+ private void SetCheckedButtons() {
+ SetChecked(FlagValue.N, radioNDefault, radioNZero, radioNOne, radioNIndeterminate);
+ SetChecked(FlagValue.V, radioVDefault, radioVZero, radioVOne, radioVIndeterminate);
+ SetChecked(FlagValue.M, radioMDefault, radioMZero, radioMOne, radioMIndeterminate);
+ SetChecked(FlagValue.X, radioXDefault, radioXZero, radioXOne, radioXIndeterminate);
+ SetChecked(FlagValue.D, radioDDefault, radioDZero, radioDOne, radioDIndeterminate);
+ SetChecked(FlagValue.I, radioIDefault, radioIZero, radioIOne, radioIIndeterminate);
+ SetChecked(FlagValue.Z, radioZDefault, radioZZero, radioZOne, radioZIndeterminate);
+ SetChecked(FlagValue.C, radioCDefault, radioCZero, radioCOne, radioCIndeterminate);
+ SetChecked(FlagValue.E, radioEDefault, radioEZero, radioEOne, radioEIndeterminate);
+ }
+
+ ///
+ /// Sets the "checked" flag on the appropriate radio button.
+ ///
+ private void SetChecked(int value, RadioButton def, RadioButton zero, RadioButton one,
+ RadioButton indeterminate) {
+ switch (value) {
+ case TriState16.UNSPECIFIED:
+ def.IsChecked = true;
+ break;
+ case TriState16.INDETERMINATE:
+ indeterminate.IsChecked = true;
+ break;
+ case 0:
+ zero.IsChecked = true;
+ break;
+ case 1:
+ one.IsChecked = true;
+ break;
+ default:
+ throw new Exception("Unexpected value " + value);
+ }
+ }
+
+ private void okButton_Click(object sender, EventArgs e) {
+ StatusFlags flags = new StatusFlags();
+
+ flags.N = GetChecked(radioNDefault, radioNZero, radioNOne, radioNIndeterminate);
+ flags.V = GetChecked(radioVDefault, radioVZero, radioVOne, radioVIndeterminate);
+ flags.M = GetChecked(radioMDefault, radioMZero, radioMOne, radioMIndeterminate);
+ flags.X = GetChecked(radioXDefault, radioXZero, radioXOne, radioXIndeterminate);
+ flags.D = GetChecked(radioDDefault, radioDZero, radioDOne, radioDIndeterminate);
+ flags.I = GetChecked(radioIDefault, radioIZero, radioIOne, radioIIndeterminate);
+ flags.Z = GetChecked(radioZDefault, radioZZero, radioZOne, radioZIndeterminate);
+ flags.C = GetChecked(radioCDefault, radioCZero, radioCOne, radioCIndeterminate);
+ flags.E = GetChecked(radioEDefault, radioEZero, radioEOne, radioEIndeterminate);
+
+ //// If they're setting emulation mode, also set M/X to 1. This is implicitly
+ //// true, but things are a bit clearer if we make it explicit.
+ //if (flags.E == 1) {
+ // flags.M = flags.X = 1;
+ //}
+
+ FlagValue = flags;
+ }
+
+ ///
+ /// Identifies the checked radio button and returns the appropriate TriState16 value.
+ ///
+ private int GetChecked(RadioButton def, RadioButton zero, RadioButton one,
+ RadioButton indeterminate) {
+ if (zero.IsChecked == true) {
+ return 0;
+ } else if (one.IsChecked == true) {
+ return 1;
+ } else if (indeterminate.IsChecked == true) {
+ return TriState16.INDETERMINATE;
+ } else if (def.IsChecked == true) {
+ return TriState16.UNSPECIFIED;
+ } else {
+ throw new Exception("No radio button selected");
+ }
+ }
+ }
+}
diff --git a/SourceGenWPF/ProjWin/MainWindow.xaml b/SourceGenWPF/ProjWin/MainWindow.xaml
index de7404e..8ad4749 100644
--- a/SourceGenWPF/ProjWin/MainWindow.xaml
+++ b/SourceGenWPF/ProjWin/MainWindow.xaml
@@ -54,6 +54,7 @@ limitations under the License.
+
@@ -100,6 +101,8 @@ limitations under the License.
CanExecute="IsProjectOpen" Executed="CloseCmd_Executed"/>
+
private void Window_MouseDown(object sender, MouseButtonEventArgs e) {
if (e.ChangedButton == MouseButton.XButton1) {
- Debug.WriteLine("TODO: navigate back");
+ if (mMainCtrl.CanNavigateBackward()) {
+ mMainCtrl.NavigateBackward();
+ }
}
}
@@ -673,6 +675,14 @@ namespace SourceGenWPF.ProjWin {
e.CanExecute = mMainCtrl.CanEditAddress();
}
+ private void CanEditStatusFlags(object sender, CanExecuteRoutedEventArgs e) {
+ if (mMainCtrl == null || !mMainCtrl.IsProjectOpen()) {
+ e.CanExecute = false;
+ return;
+ }
+ e.CanExecute = mMainCtrl.CanEditStatusFlags();
+ }
+
private void CanHintAsCodeEntryPoint(object sender, CanExecuteRoutedEventArgs e) {
if (mMainCtrl == null || !mMainCtrl.IsProjectOpen()) {
e.CanExecute = false;
@@ -744,6 +754,10 @@ namespace SourceGenWPF.ProjWin {
mMainCtrl.EditAddress();
}
+ private void EditStatusFlags_Executed(object sender, ExecutedRoutedEventArgs e) {
+ mMainCtrl.EditStatusFlags();
+ }
+
private void HelpCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.ShowHelp();
}
diff --git a/SourceGenWPF/SourceGenWPF.csproj b/SourceGenWPF/SourceGenWPF.csproj
index 3a99e62..96c6aab 100644
--- a/SourceGenWPF/SourceGenWPF.csproj
+++ b/SourceGenWPF/SourceGenWPF.csproj
@@ -84,6 +84,9 @@
EditAddress.xaml
+
+ EditStatusFlags.xaml
+
ProjectLoadIssue.xaml
@@ -168,6 +171,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile