From 99b484df4cda2e7f1ecfd03a35ee31fd4b0033a1 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Sun, 7 Jul 2019 16:18:46 -0700 Subject: [PATCH] Implement long-comment editing We can now Edit Long Comment and Edit Header Comment. Changing the number of lines in a long comment exposed a bug in the display list update. Fixed. Running the WinForms version trashed the column widths, which exposed the fact that the default column widths were set too narrow. Fixed. On an unrelated note, hitting undo/redo quickly will sometimes leave you scrolled to the bottom of the code list. Some sort of command- handling race in the WPF framework? (Not fixed.) --- SourceGenWPF/AsmGen/WpfGui/GenAndAsm.xaml | 3 +- SourceGenWPF/DisplayList.cs | 11 +- SourceGenWPF/LineListGen.cs | 65 +++---- SourceGenWPF/MainController.cs | 51 +++++- SourceGenWPF/SourceGenWPF.csproj | 7 + SourceGenWPF/WpfGui/EditLongComment.xaml | 78 +++++++++ SourceGenWPF/WpfGui/EditLongComment.xaml.cs | 177 ++++++++++++++++++++ SourceGenWPF/WpfGui/MainWindow.xaml | 32 ++-- SourceGenWPF/WpfGui/MainWindow.xaml.cs | 56 ++++--- 9 files changed, 408 insertions(+), 72 deletions(-) create mode 100644 SourceGenWPF/WpfGui/EditLongComment.xaml create mode 100644 SourceGenWPF/WpfGui/EditLongComment.xaml.cs diff --git a/SourceGenWPF/AsmGen/WpfGui/GenAndAsm.xaml b/SourceGenWPF/AsmGen/WpfGui/GenAndAsm.xaml index a9ea5c1..7d3ed4a 100644 --- a/SourceGenWPF/AsmGen/WpfGui/GenAndAsm.xaml +++ b/SourceGenWPF/AsmGen/WpfGui/GenAndAsm.xaml @@ -23,7 +23,8 @@ limitations under the License. mc:Ignorable="d" Title="Generate and Assemble" Width="800" Height="700" MinWidth="600" MinHeight="600" ResizeMode="CanResizeWithGrip" - ShowInTaskbar="False" WindowStartupLocation="CenterOwner" Loaded="Window_Loaded"> + ShowInTaskbar="False" WindowStartupLocation="CenterOwner" + Loaded="Window_Loaded"> diff --git a/SourceGenWPF/DisplayList.cs b/SourceGenWPF/DisplayList.cs index f0289fa..360c797 100644 --- a/SourceGenWPF/DisplayList.cs +++ b/SourceGenWPF/DisplayList.cs @@ -277,12 +277,12 @@ namespace SourceGenWPF { mList.Add(null); } + SelectedIndices = new DisplayListSelection(size); + // send one big notification at the end; "reset" means "forget everything you knew" OnPropertyChanged(CountString); OnPropertyChanged(IndexerName); OnCollectionReset(); - - SelectedIndices = new DisplayListSelection(size); } /// @@ -294,7 +294,7 @@ namespace SourceGenWPF { /// Number of new lines. May be zero. public void ClearListSegment(int startIndex, int oldCount, int newCount) { Debug.WriteLine("ClearListSegment start=" + startIndex + " old=" + oldCount + - " new=" + newCount); + " new=" + newCount + " (mList.Count=" + mList.Count + ")"); Debug.Assert(startIndex >= 0 && startIndex < mList.Count); Debug.Assert(oldCount > 0 && startIndex + oldCount < mList.Count); @@ -307,6 +307,11 @@ namespace SourceGenWPF { mList.Insert(startIndex, null); } // TODO: can we null out existing entries, and just insert/remove when counts differ? + + if (oldCount != newCount) { + SelectedIndices = new DisplayListSelection(mList.Count); + } + OnPropertyChanged(CountString); OnPropertyChanged(IndexerName); OnCollectionReset(); diff --git a/SourceGenWPF/LineListGen.cs b/SourceGenWPF/LineListGen.cs index ee5665b..aaaae5a 100644 --- a/SourceGenWPF/LineListGen.cs +++ b/SourceGenWPF/LineListGen.cs @@ -576,7 +576,9 @@ namespace SourceGenWPF { /// public void GenerateAll() { mLineList.Clear(); - GenerateHeaderLines(mProject, mFormatter, mPseudoOpNames, mLineList); + List headerLines = GenerateHeaderLines(mProject, mFormatter, mPseudoOpNames); + mLineList.InsertRange(0, headerLines); + GenerateLineList(mProject, mFormatter, mPseudoOpNames, 0, mProject.FileData.Length - 1, mLineList); @@ -594,10 +596,22 @@ namespace SourceGenWPF { /// End offset (inclusive). public void GenerateRange(int startOffset, int endOffset) { if (startOffset < 0) { - ClearHeaderLines(); - GenerateHeaderLines(mProject, mFormatter, mPseudoOpNames, mLineList); + // Clear existing header lines. Find the first non-header item. + int headerEndIndex = FindLineByOffset(mLineList, 0); + if (headerEndIndex == 0) { + // no header lines present + Debug.WriteLine("No header lines found"); + } else { + Debug.WriteLine("Removing " + headerEndIndex + " header lines"); + mLineList.RemoveRange(0, headerEndIndex); + } + + List headerLines = GenerateHeaderLines(mProject, mFormatter, mPseudoOpNames); + mLineList.InsertRange(0, headerLines); + mDisplayList.ClearListSegment(0, headerEndIndex, headerLines.Count); + if (endOffset < 0) { - // nothing else to do + // nothing else to do -- header-only change return; } // do the rest @@ -708,21 +722,20 @@ namespace SourceGenWPF { return true; } - /// - /// Removes all header lines from the display list. - /// - private void ClearHeaderLines() { - // Find the first non-header item. - int endIndex = FindLineByOffset(mLineList, 0); - if (endIndex == 0) { - // no header lines present - Debug.WriteLine("No header lines found"); - return; - } - Debug.WriteLine("Removing " + endIndex + " header lines"); - mLineList.RemoveRange(0, endIndex); - mDisplayList.ClearListSegment(0, endIndex, 0); - } + ///// + ///// Removes all header lines from the line list. + ///// + //private void ClearHeaderLines() { + // // Find the first non-header item. + // int endIndex = FindLineByOffset(mLineList, 0); + // if (endIndex == 0) { + // // no header lines present + // Debug.WriteLine("No header lines found"); + // return; + // } + // Debug.WriteLine("Removing " + endIndex + " header lines"); + // mLineList.RemoveRange(0, endIndex); + //} /// /// Generates a synthetic offset for the FileOffset field from an index value. The @@ -745,18 +758,14 @@ namespace SourceGenWPF { } /// - /// Generates the header lines (header comment, EQU directives), and inserts them at - /// the top of the list. - /// - /// This does not currently do incremental generation. Call ClearHeaderLines() before - /// calling here if you're not starting with an empty list. + /// Generates the header lines (header comment, EQU directives). /// /// Project reference. /// Output formatter. /// Pseudo-op names. - /// List to add output lines to. - private static void GenerateHeaderLines(DisasmProject proj, Formatter formatter, - PseudoOp.PseudoOpNames opNames, List fullLines) { + /// List with header lines. + private static List GenerateHeaderLines(DisasmProject proj, Formatter formatter, + PseudoOp.PseudoOpNames opNames) { List tmpLines = new List(); Line line; FormattedParts parts; @@ -793,7 +802,7 @@ namespace SourceGenWPF { tmpLines.Add(line); } - fullLines.InsertRange(0, tmpLines); + return tmpLines; } /// diff --git a/SourceGenWPF/MainController.cs b/SourceGenWPF/MainController.cs index d59accd..61e354e 100644 --- a/SourceGenWPF/MainController.cs +++ b/SourceGenWPF/MainController.cs @@ -212,6 +212,9 @@ namespace SourceGenWPF { mMainWin.UpdateRecentLinks(); ProcessCommandLine(); + + // Create an initial value. + SelectionAnalysis = UpdateSelectionState(); } private void ProcessCommandLine() { @@ -1210,11 +1213,9 @@ namespace SourceGenWPF { } break; case LineListGen.Line.Type.LongComment: -#if false - if (editLongCommentToolStripMenuItem.Enabled) { - EditLongComment_Click(sender, e); + if (CanEditLongComment()) { + EditLongComment(); } -#endif break; case LineListGen.Line.Type.Note: #if false @@ -1355,6 +1356,10 @@ namespace SourceGenWPF { } } + public void EditHeaderComment() { + EditLongComment(LineListGen.Line.HEADER_COMMENT_OFFSET); + } + public bool CanEditLabel() { if (SelectionAnalysis.mNumItemsSelected != 1) { return false; @@ -1395,12 +1400,48 @@ namespace SourceGenWPF { } } + public bool CanEditLongComment() { + if (SelectionAnalysis.mNumItemsSelected != 1) { + return false; + } + EntityCounts counts = SelectionAnalysis.mEntityCounts; + // Single line, code or data, or a long comment. + return (counts.mDataLines > 0 || counts.mCodeLines > 0 || + SelectionAnalysis.mLineType == LineListGen.Line.Type.LongComment); + } + + public void EditLongComment() { + int selIndex = mMainWin.CodeListView_GetFirstSelectedIndex(); + int offset = CodeLineList[selIndex].FileOffset; + EditLongComment(offset); + } + + private void EditLongComment(int offset) { + EditLongComment dlg = new EditLongComment(mMainWin, mOutputFormatter); + if (mProject.LongComments.TryGetValue(offset, out MultiLineComment oldComment)) { + dlg.LongComment = oldComment; + } + dlg.ShowDialog(); + + if (dlg.DialogResult == true) { + MultiLineComment newComment = dlg.LongComment; + if (oldComment != newComment) { + Debug.WriteLine("Changing long comment at +" + offset.ToString("x6")); + + UndoableChange uc = UndoableChange.CreateLongCommentChange(offset, + oldComment, newComment); + ChangeSet cs = new ChangeSet(uc); + ApplyUndoableChanges(cs); + } + } + } + public bool CanEditStatusFlags() { if (SelectionAnalysis.mNumItemsSelected != 1) { return false; } EntityCounts counts = SelectionAnalysis.mEntityCounts; - // Line must be code, or a RegWidth directive. + // Single line, must be code or a RegWidth directive. return (SelectionAnalysis.mLineType == LineListGen.Line.Type.Code || SelectionAnalysis.mLineType == LineListGen.Line.Type.RegWidthDirective); } diff --git a/SourceGenWPF/SourceGenWPF.csproj b/SourceGenWPF/SourceGenWPF.csproj index d85b673..840416d 100644 --- a/SourceGenWPF/SourceGenWPF.csproj +++ b/SourceGenWPF/SourceGenWPF.csproj @@ -90,6 +90,9 @@ EditLabel.xaml + + EditLongComment.xaml + EditProjectProperties.xaml @@ -213,6 +216,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/SourceGenWPF/WpfGui/EditLongComment.xaml b/SourceGenWPF/WpfGui/EditLongComment.xaml new file mode 100644 index 0000000..da07ba4 --- /dev/null +++ b/SourceGenWPF/WpfGui/EditLongComment.xaml @@ -0,0 +1,78 @@ + + + + + + + + Ctrl+Enter + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +