Repository navigation
LT-22691: Answer the Notebook menus natively - #1240
Conversation
The Avalonia detail view answers every Notebook Edit menu itself. Until now a right-click on a subrecord or the Subrecords section, and the main menu's text and Demote Record commands, needed the hidden DataTree. Structured-text rows get the text menu WinForms shows: Cut, Copy, Paste, Find in Dictionary and Add to Dictionary (LT-22861). Promote, Demote and the word rules are shared with WinForms in DetailRules. Promote publishes JumpToRecord through Pub/Sub in both views, at once and window-scoped, in place of SummarySlice's queued mediator broadcast. Menus and commands now answered natively: * mnuDataTree-SubRecords, mnuDataTree-SubRecords-Hotlinks, mnuDataTree-Subrecord-Hotlinks, mnuDataTree-SubRecordSummary * mnuStTextChoices * CmdLexiconLookup, CmdAddToLexicon, CmdDemoteRecord (Notebook Edit) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NUnit Tests 1 files ± 0 1 suites ±0 14m 28s ⏱️ + 3m 15s Results for commit 51570de. ± Comparison against base commit 36f0082. This pull request removes 1 and adds 44 tests. Note that renamed tests count towards both. |
|
A question about copy/paste behavior and a few small things to consider. Question: Paste drops everything after the first line break, without telling the user. See PastedText at RecordEditView.NotebookMenus.cs:393.
Nits
|
thejambi
left a comment
There was a problem hiding this comment.
@thejambi reviewed 30 files and all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on mark-sil).
|
Thanks, Zach. Paste: yes, it's deliberate for now. Legacy doesn't drop the text: each pasted line becomes its own paragraph, and where a field can't take new paragraphs the line breaks become spaces. The New UI paragraph editor's own paste also keeps only the first line (Avalonia's text box does that when it doesn't accept line breaks), so this is a gap in every New UI structured-text field rather than in this menu. I've added it to the PR's decisions and to LT-22896, where the fix belongs: split pasted lines into paragraphs. I left out the log entry, since users never see the log, so it wouldn't tell them anything. Nits: agreed on both. I'm leaving them out of this PR so it stays as tested. |
The Avalonia detail view answers every Notebook Edit menu itself. Until
now a right-click on a subrecord or the Subrecords section, and the main
menu's text and Demote Record commands, needed the hidden DataTree.
Structured-text rows get the text menu WinForms shows: Cut, Copy, Paste,
Find in Dictionary and Add to Dictionary (LT-22861). Promote, Demote and
the word rules are shared with WinForms in DetailRules.
Promote publishes JumpToRecord through Pub/Sub in both views, at once and
window-scoped, in place of SummarySlice's queued mediator broadcast.
Reviewer notes
Start here:
Src/xWorks/Avalonia/Hosting/RecordEditView.NotebookMenus.cs, every Notebook answer: the subrecord commands, the text menu, and Demote Record. ThenSrc/FdoUi/DetailRules/RecordNesting.cs, the Promote/Demote rule both views now call.The question to bring: does a text command act on the text the user right-clicked? The menu is built from what the editor held at the right-click; the command runs on the saved paragraph after pending edits settle. It runs only if that paragraph still holds the same text, compared in NFD because LCM stores text decomposed, with the selection's offsets mapped into the saved text. Otherwise it does nothing and logs.
Where to look
NotebookMenuTests.EveryRowMenu_OfARecordWithSubrecordsAndText_IsAnsweredNatively; the owned-id pin inLexiconMenuAuthorityTestsshows the four new menus.SummarySlice,DataTreeandStTextSlicecallRecordNestingandTextWordCommands, pinned byRecordNestingTestsandTextWordCommandsTests.TextWordBoundariesTests.SummarySlice.OnPromoteSubitemInVector,RecordEditView.NestRecord.HotlinkItemsFor_AMenuNoAuthorityOwns_ShowsItsCommandsDisabled. Only Words > Analyses has such menus, and that tool is not on in the New UI.Deliberately not here
Verification: build, comment and token hygiene clean; 131 targeted tests passed after #1232 was pulled in, and 34 after the review fixes; 17 manual steps on Sena 3 in both UIs passed. Not covered by tests: running Insert Subrecord, which opens the modal Insert Record dialog. Full suite not run. Main's two newer commits merge cleanly; the merged tree was not built.
Next: approve, or name a Notebook menu that still behaves differently from Legacy.
Decisions, and why
RecordClerk.OnInsertItemInVector), as the reference jumps callCmObjectUi. Rejected: passing the command to the mediator without the hidden tree, which keeps mediator routing in a path the plan is moving off; and copying the record list's rules into a shared rule.SummarySlice's queuedBroadcastMessageUntilHandledbecame an immediate, window-scoped publish; the record list is the only subscriber. The change was checked against the per-site concerns of the JumpToRecord Phase 2 plan.VwTextSelection::FindWordBoundaries), used only by the New UI, because the Avalonia editor is not a Views control. Legacy keeps calling GrowToWord. Rejected: movingStTextSliceonto the C# rule, which changes working code with no visible gain.mnuStTextChoices, replacing the theme's own Cut/Copy/Paste menu, so it gains Find in Dictionary and Add to Dictionary.Found in passing
Both also happen on main and are kept out of this PR.
FwXWindow.OnEditPaste's own. Commented on LT-22896.Preflight review details
Code Review Summary
Branch: claude/lt-22691-notebook-6bbe5a
Base: main (merge base fbf02e6; main has 2 newer commits, #1236 and #1237, which touch
6 of these files and merge cleanly; the merged tree was not built)
Date: 2026-11-10
Review model: Claude Opus 5.5
Files changed: 30 (1 commit, 51570de)
Overview
LT-22691 stage 4, Notebook (with main-menu item 3d). In the New UI, every Notebook Edit
menu is answered by the detail view: the Subrecords section and subrecord menus, their
section buttons, a structured-text row's text menu, and the main menu's and toolbar's Find
in Dictionary and Add to Dictionary and the pane bar's Demote Record. Until now these needed
the hidden DataTree. The text menu is the one WinForms shows (Cut, Copy, Paste, Find in
Dictionary, Add to Dictionary), which also fixes LT-22861. Promote, Demote and the
word-command rules move to
Src/FdoUi/DetailRulesand both views call them. Promote nowpublishes JumpToRecord through Pub/Sub, window-scoped, at once, in both views.
The four analysis passes found no Critical or Important issue. The earlier
/code-review highfindings were resolved or decided with the author (below).Contract/API Changes
FdoUi): newRecordNesting,TextWordBoundaries,TextWordCommands.WinForms
SummarySlice,DataTree(Demote Record) andStTextSlicecall them; theirbehaviour is unchanged.
DemotedRecordOwnerChooser(the WinForms chooser both views show);DataTree.ChooseNewOwnerremoved.DetailTextSelectionSnapshot,IDetailTextSnapshotSource,DetailMenuRequest.TextSnapshot,DataTree.TextSelectionChanged,DetailHostControl.CurrentTextSelection;FwStructuredTextFieldandSliceFactoryContexttake optional menu and selection callbacks;FwReferenceVectorField.PlaceCaretAtPointeris now internal.mnuStTextChoices.StructuredTextMenuAuthority; Notebook answers added to the Lexicon clusterauthority and to the Notebook Edit command authority.
HotlinkItemsForno longer runs anunowned section button through the hidden tree: it shows its commands disabled and logs.
SummarySlice'sBroadcastMessageUntilHandled("JumpToRecord")is replaced by awindow-scoped
Publisher.Publish(EventConstants.JumpToRecord).ksUndoPromote,ksRedoPromote,ksUndoDemote,ksRedoDemotefromDetailControlsStrings (identical FdoUiStrings ones are used now) and
ksHotlinkCommandUnavailable,ksHotlinkCommandDisabledfrom xWorksStrings. No new strings.Findings
Critical - Must address before merge
None.
Important - Should address before merge
None.
Minor - Consider
decomposed text, the editor keeps what was typed) (fixed: the saved-text check and the
selection offsets compare in NFD; test added)
selection; test that it still follows a new selection)
A paragraph using a deleted style could throw in the style lookup(checked:LcmStyleSheet.GetStyleRgchreturns null for an unknown style, and the word rule treatsnull as no properties)
Cut and Paste act on the saved paragraph rather than the editor, so the caret(author: holding the save while a menu is open changes save behaviourposition is lost
for every row; not in this PR)
New UI Undo for a subrecord's Move Up/Down reads "Undo Move Item", not "Undo Move(author: not taken; matching it needs two new xWorks strings)Up/Down"
A read-only, mixed-font paragraph looks up its first word wherever you click(author: left; these paragraphs hold an embedded object and are rare)
Selection clamping is written three times; the text menu has no test through the(author: not taken)real right-click path
Required Validation / Evidence
.\build.ps1 -CommentHygiene -TokenHygiene: clean..\test.ps1 -CommentHygiene -TokenHygiene -TestFilter ...: 131/131 over NotebookMenuTests,LexiconMenuExecutionTests, LexiconMenuAuthorityTests, DetailHotlinkTests and
DetailFocusMemoryTests after main's LT-22693: Show a button per hotlink command on the active section #1232 was pulled in; 34/34 over the new rule and
request tests (RecordNestingTests, TextWordBoundariesTests, TextWordCommandsTests,
StructuredTextMenuRequestTests, NotebookMenuTests) after the review fixes.
Record dialog) and the Demote choosers (the tests supply the pick).
not built.
Positive Observations
removed.
NotebookMenuTestscomposes a record with subrecords and text and checks that every rowmenu is answered natively; the owned-id pin in
LexiconMenuAuthorityTestsshows the fournewly owned menus.
Interview Notes
Decisions settled with the author during the session (not re-asked here):
RecordClerk) directly,as the reference jumps call
CmObjectUi; no mediator routing, no copy of its rules.checked against the JumpToRecord Phase 2 concerns.
an Avalonia text box collapses its selection when it loses focus; the right-click menu
reads it at request time.
keeps calling GrowToWord.
PanelMenu_Clickrefuses every pane-bar menu in a pop-up window, in both UIs.
edit needs F5 to redraw (handed to LT-22692); Ctrl+V while typing in a New UI field
crashes with "Nested tasks are not supported" (commented on LT-22896).
the evidence fields), LT-22895 (no spell checking), LT-22896 (Edit menu Cut/Copy/Paste).
Suggested Review Focus
RecordEditView.NotebookMenus.cs: the saved-paragraph check and NFD offset mappingbefore Cut, Paste and the dictionary commands.
FwStructuredTextField.WireParagraphMenu/WireSelectionReports: the theme's textmenu replaced, and the selection reported only while the paragraph has focus.
RecordNestingagainst the removedSummarySlice/DataTreecode: same enablerules, same choosers, same moves.
🤖 Generated with Claude Code
This change is