Repository navigation
Conversation
In the Avalonia detail view, Insert Subsense, Insert Sense, Insert Example, Insert Extended Note and Insert Etymology now run from the row itself: the Lexicon menu authority answers every DataTreeInsert leaf that creates a concrete class in an owning field, so mnuDataTree-Subsenses, mnuDataTree-ExtendedNotes, mnuDataTree-Sense-Hotlinks, mnuDataTree-ExtendedNote-Hotlinks and mnuDataTree-Etymology-Hotlinks no longer build the hidden DataTree. The same predicate completes the posEdit section menus mnuDataTree-POS-AffixTemplates, mnuDataTree-POS-AffixSlots, mnuDataTree-POS-InflectionClasses, mnuDataTree-POS-InflectionClass-Subclasses and mnuDataTree-POS-StemNames. The new object goes after the row's object in its owner's sequence, or at the end of the row's own, and the re-show puts the keyboard in the new object's first editor. An insert is enabled when its command resolves an owning target from the row's object, so Insert Extended Note under an existing note now inserts a sibling note where it was shown disabled. The allomorph inserts, SubPossibilities inserts and inserts into a reference field keep their ids with the adapter until their rules are answered. Both detail views share the rule: the WinForms Slice and DTMenuHandler call the same code, so the two views cannot drift. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # Src/Common/FwAvalonia/Detail/DataTree.cs # Src/Common/FwAvalonia/Detail/DetailFocusMemory.cs # Src/Common/FwAvalonia/FwAvaloniaTests/DetailFocusMemoryTests.cs # Src/xWorks/Avalonia/Hosting/RecordEditView.LexiconMenus.cs # Src/xWorks/xWorksTests/Avalonia/Hosting/LexiconMenuAuthorityTests.cs # Src/xWorks/xWorksTests/Avalonia/Hosting/LexiconMenuExecutionTests.cs
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1190 +/- ##
==========================================
+ Coverage 39.70% 39.74% +0.04%
==========================================
Files 1543 1544 +1
Lines 355006 355085 +79
Branches 41205 41247 +42
==========================================
+ Hits 140958 141140 +182
+ Misses 184684 184585 -99
+ Partials 29364 29360 -4
🚀 New features to boost your workflow:
|
|
Should fix:
|
The shared insert rule returned a target for an owning atomic field that already held an object. The Avalonia detail view enables an Insert item whenever the rule finds a target, so such an item would have been enabled, and running it would have replaced the existing object. The WinForms display rule already refused that case. The rule now refuses a filled owning atomic field, so the item is disabled in both detail views. No owned menu reaches the case today; the allomorph inserts that target Lexeme Form and Linker are still answered by the hidden DataTree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@thejambi Fixed in ba00aae: |
thejambi
left a comment
There was a problem hiding this comment.
@thejambi reviewed 11 files and all commit messages, made 1 comment, and resolved 1 discussion.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on mark-sil).
Start here:
Src/FdoUi/DetailRules/DetailObjectInsertion.cs. It is the insert rule both detail views now share, and every other change in this PR calls it.In the Avalonia detail view, Insert Subsense, Insert Sense, Insert Example, Insert Extended Note and Insert Etymology now run from the row itself. The Lexicon menu authority answers every
DataTreeInsertleaf that creates a concrete class in an owning field, so 20 more menu ids stop building the hidden DataTree. Five of them are Lexicon menus (-Subsenses,-ExtendedNotes,-Sense-Hotlinks,-ExtendedNote-Hotlinks,-Etymology-Hotlinks) and five are posEdit section menus (Affix Templates, Affix Slots, Inflection Classes, Subclasses, Stem Allomorph Labels). After an insert, the keyboard lands in the new object's first editor.The question a reviewer starts with is whether the WinForms insert path still puts new objects where it did.
Slice.InsertObjectandDTMenuHandler.CanInsertFieldIntoObjnow call the rule's pieces (field resolution, owner hop, concrete class, position after the current slice) instead of their own copies; a manual WinForms insert pass confirmed the same placement. The review worth your time is the rule itself and the focus change.Where to look
DetailObjectInsertion.ResolveTarget: the owner climb,slice="owner", and the position after the clicked object. Pinned byDetailObjectInsertionTests.InsertLeaves_OutsideTheScope_LeaveTheirIdsWithTheAdapter.DetailFocusMemory.RestoreAfterLayout: a requested object now wins over a surviving editor. This also moves focus after Convert to Affix Process. Pinned by threeDetailFocusMemoryTests.Not here: the allomorph inserts, the Insert Variant dialog and pictures/media (stage 2 PR C2); SubPossibilities and
DataTreeCopy(stage 4).Verification: off main.
build.ps1 -CommentHygiene -TokenHygieneis clean; 148 targeted tests pass. Fourteen manual tests on Sena 3 passed, covering Lexicon, posEdit, WinForms and Convert. The full suite was not run.Next: approve.
Reading this a year from now -- start here
This PR is stage 2 PR C1 of LT-22691, which retires the hidden WinForms DataTree from the Avalonia detail view one context-menu id at a time. The plan of record and the per-id cycle live in the
hidden-datatree-menu-idsskill. The decisions below are the ones the code cannot explain on its own.Decisions, and why
LexiconMenuAuthority.Answertakes an optional leaf predicate. A leaf outside it leaves its whole id with the adapter, because an id is answered natively in full or not at all. The scope admits a concrete class created in an owning field; everything with a rule of its own (allomorph visibility, SubPossibilities, the Insert Variant dialog) stays out until the PR that answers it.ResolveTargetfinds an owning field from the row's object up its owners. That is why Insert Extended Note under a note is enabled: the sense owning the note takes it. WinForms asks only the shown entry and the row's own object, so that hotlink is dead there.recomputeVirtualis not read. The WinForms handler splits the attribute and does nothing with it; the Avalonia re-show recomposes every row anyway.DataTree.FocusFirstRowOftries the object's editor rows first, matching WinForms, which focuses the first focusable slice of the new object.Surprising findings
mnuDataTree-Subsensesreaches only the Subsenses prompt row of a sense without subsenses: nested sense sequences suppress their banner, and their items takemnuDataTree-Sense.mnuDataTree-ExtendedNotesisvisibility="ifdata", so without Show Hidden Fields there is no prompt row for the first note.DataTree.RefreshListAndFocus) and not addressed here.Deferred, and what would unblock it
-AlternateForms,-AlternateForms-Hotlinks): need the morph-type and first-allomorph visibility rules and theActiveClerk.ListSizecheck. Stage 2 PR C2.-VariantForms,-VariantForms-Hotlinks): needs the Insert Variant dialog path. Stage 2 PR C2.DataTreeCopy: Grammar only (Duplicate Affix Slot/Template). Stage 4.Evidence
Targeted run on the tree merged with main, 148 of 148 passed:
Manual tests on Sena 3, all passed:
Preflight review details
Code Review Summary
Branch: claude/lt-22691p-cbd94e
Base: main
Date: 2026-10-15
Review model: Claude Opus 5.5
Files changed: 11
Overview
Stage 2 PR C1 of LT-22691: the E5 insert engine, core half. The Lexicon menu authority answers
every DataTreeInsert leaf that creates a concrete class in an owning field, so
mnuDataTree-Subsenses,mnuDataTree-ExtendedNotes,mnuDataTree-Sense-Hotlinks,mnuDataTree-ExtendedNote-HotlinksandmnuDataTree-Etymology-Hotlinksno longer build thehidden DataTree. The same predicate completes five posEdit section menus
(
mnuDataTree-POS-AffixTemplates,-POS-AffixSlots,-POS-InflectionClasses,-POS-InflectionClass-Subclasses,-POS-StemNames). The shared rule lives inSrc/FdoUi/DetailRules/DetailObjectInsertion.cs, and the WinFormsSliceandDTMenuHandlerinsert path calls it.
The analysis found no contract, native or localization issues. Two validation gaps (the posEdit
menus, and the focus change's effect on PR B's Convert) were closed by manual tests during the
interview. Five minor items from the agent code review were kept as is by the author.
Contract/API Changes
SIL.FieldWorks.Common.DetailRules.DetailObjectInsertionand publicsealed
DetailInsertTargetin FdoUi (additions).DTMenuHandler.CanInsertFieldIntoObj(protected) keeps its signature; its body calls the rule.The private
GetFlidIfPossiblehelper is removed.LexiconMenuAuthority.Answer(internal) gains an optional leaf scope.DetailFocusMemory.RestoreAfterLayout(public): a requested object now wins over a survivingremembered editor, and a requested row wins over a remembered menu button. A requested row
still yields to a surviving editor.
DataTree.FocusFirstRowOf(internal): the object's editor rows first, its header only when noeditor can take focus.
LexiconMenuAuthorityTestslists every owned id by area.Findings
Critical - Must address before merge
None.
Important - Should address before merge
Minor - Consider
The owner hop in(kept as is: no current layout reaches the difference)Slice.InsertObjectaccepts a subclass of the field's class where the old code required the exact classWith(kept as is: matches the WinForms label; no owned command uses it)displayNumber, the Insert label shows the vector end plus one while the insert lands after the clicked itemThe insert scope keys on field names across all classes, not on the command's target class(kept as is: no current DataTreeInsert command collides)No headless test asserts the focus request an insert makes from the host(kept as is)(kept as is)IsOwningFieldNamescans the metadata field list once per insert leaf per menu buildTicket: user-visible, carries LT-22691; no new ticket needed.
Required Validation / Evidence
.\build.ps1 -CommentHygiene -TokenHygiene: clean, on the merged tree (C1 plus main with PR B)..\test.ps1 -CommentHygiene -TokenHygiene -TestFilterover DetailObjectInsertionTests,DetailRulesBoundaryTests, DetailJumpTargetsTests, LexemeFormConversionTests,
LexiconMenuAuthorityTests, LexiconMenuExecutionTests, DetailFocusMemoryTests and
DetailObjectCommandExecutionTests: Total tests 148, passed 148, on the merged tree.
passed after two focus fixes), and the four posEdit section menus plus PR B's Convert after
the merge (all passed).
Positive Observations
DetailRules boundary test, with its own test file.
adapter in full instead of answering them partially.
pinned in the equivalence test rather than hidden.
Interview Notes
field in a new item when an item is inserted. We wanted this consistent in all cases. After an
insert, the new object takes focus even from an editor that is still on screen. After a delete,
a surviving editor keeps focus."
Note: the answer states the two rules but not what selects between them (an insert asks the
re-show to focus an object; a delete asks it to focus rows).
pre-existing (
DataTree.RefreshListAndFocus); the author chose not to track it.Suggested Review Focus
DetailObjectInsertion.ResolveTarget: owner climb,slice="owner", and the position after the clicked object.DetailFocusMemory.RestoreAfterLayout: the new precedence between object requests, row requests and a surviving editor.🤖 Generated with Claude Code
This change is