@@ -20,7 +20,7 @@ namespace SIL.FieldWorks.Common.FwAvalonia.Region
2020 /// replacement for the legacy <c>StTextSlice</c> RootSite rich editor. A vertical stack of one
2121 /// bordered, dense editor row per paragraph; each row carries a run-aware text editor (the SAME
2222 /// staging the single-WS <see cref="FwMultiWsTextField"/> uses — TextChanged replays the untouched
23- /// runs around the edit and stages through <see cref="IRegionEditContext .TrySetParagraphText"/>),
23+ /// runs around the edit and stages through <see cref="IStructuredTextEditing .TrySetParagraphText"/>),
2424 /// a per-paragraph named-style picker (the shared <see cref="FwOptionPicker"/>), and add/delete
2525 /// paragraph affordances. Enter at a paragraph's end inserts a paragraph after it; Backspace in an
2626 /// empty paragraph (when more than one remains) deletes it.
@@ -53,11 +53,15 @@ public FwStructuredTextField(
5353 AutomationProperties . SetAutomationId ( this , automationId ) ;
5454 AutomationProperties . SetName ( this , field . Label ?? field . Field ?? automationId ) ;
5555
56+ // Paragraph CRUD is the optional IStructuredTextEditing capability; a context without it leaves
57+ // the rows displayed but inert (each gesture below no-ops), the same rejection the former core
58+ // IRegionEditContext paragraph methods returned on a context with no StText rows.
59+ var structuredText = editContext as IStructuredTextEditing ;
5660 var editable = editContext != null && field . IsEditable ;
5761 var paragraphs = field . Paragraphs ;
5862 for ( var i = 0 ; i < paragraphs . Count ; i ++ )
5963 {
60- Children . Add ( BuildParagraphRow ( field , automationId , editContext , writingSystemFocused ,
64+ Children . Add ( BuildParagraphRow ( field , automationId , structuredText , writingSystemFocused ,
6165 gestureCompleted , clipboard , paragraphs [ i ] , i , paragraphs . Count , editable ) ) ;
6266 }
6367
@@ -66,13 +70,13 @@ public FwStructuredTextField(
6670 // — the first keystroke materializes the StText through the edit-context setter (index 0).
6771 if ( paragraphs . Count == 0 )
6872 {
69- Children . Add ( BuildParagraphRow ( field , automationId , editContext , writingSystemFocused ,
73+ Children . Add ( BuildParagraphRow ( field , automationId , structuredText , writingSystemFocused ,
7074 gestureCompleted , clipboard , new RegionParagraph ( null ) , 0 , 1 , editable ) ) ;
7175 }
7276 }
7377
7478 private Control BuildParagraphRow (
75- LexicalEditRegionField field , string automationId , IRegionEditContext editContext ,
79+ LexicalEditRegionField field , string automationId , IStructuredTextEditing editContext ,
7680 Action < string > writingSystemFocused , Action gestureCompleted , IFwClipboard clipboard ,
7781 RegionParagraph paragraph , int index , int paragraphCount , bool fieldEditable )
7882 {
@@ -129,7 +133,7 @@ private Control BuildParagraphRow(
129133 {
130134 if ( e . Key == Key . Enter )
131135 {
132- if ( editContext . TryInsertParagraph ( field , index ) )
136+ if ( editContext != null && editContext . TryInsertParagraph ( field , index ) )
133137 {
134138 gestureCompleted ? . Invoke ( ) ;
135139 e . Handled = true ;
@@ -142,7 +146,7 @@ private Control BuildParagraphRow(
142146 && box . CaretIndex == 0
143147 && paragraphCount > 1 )
144148 {
145- if ( editContext . TryDeleteParagraph ( field , index ) )
149+ if ( editContext != null && editContext . TryDeleteParagraph ( field , index ) )
146150 {
147151 gestureCompleted ? . Invoke ( ) ;
148152 e . Handled = true ;
@@ -158,7 +162,7 @@ private Control BuildParagraphRow(
158162 addAffordance = BuildIconButton ( automationId + ".Para." + index + ".Add" , "+" ,
159163 FwAvaloniaStrings . AddParagraph , ( ) =>
160164 {
161- if ( editContext . TryInsertParagraph ( field , index ) )
165+ if ( editContext != null && editContext . TryInsertParagraph ( field , index ) )
162166 gestureCompleted ? . Invoke ( ) ;
163167 } ) ;
164168
@@ -169,7 +173,7 @@ private Control BuildParagraphRow(
169173 deleteAffordance = BuildIconButton ( automationId + ".Para." + index + ".Delete" , "×" ,
170174 FwAvaloniaStrings . DeleteParagraph , ( ) =>
171175 {
172- if ( editContext . TryDeleteParagraph ( field , index ) )
176+ if ( editContext != null && editContext . TryDeleteParagraph ( field , index ) )
173177 gestureCompleted ? . Invoke ( ) ;
174178 } ) ;
175179 }
@@ -241,7 +245,7 @@ private Control BuildParagraphRow(
241245 // a TextChanged stages a plain-text-over-preserved-runs edit through the paragraph seam. A
242246 // last-staged guard keeps the template's initial set and no-op events from staging; the guard
243247 // advances only on a successful stage so a failed write re-attempts.
244- private void WireParagraphTextEditing ( LexicalEditRegionField field , IRegionEditContext editContext ,
248+ private void WireParagraphTextEditing ( LexicalEditRegionField field , IStructuredTextEditing editContext ,
245249 TextBox box , RegionRichTextValue currentRich , int index , Action < RegionRichTextValue > onStaged )
246250 {
247251 var lastStaged = currentRich ? . PlainText ?? string . Empty ;
@@ -253,7 +257,7 @@ private void WireParagraphTextEditing(LexicalEditRegionField field, IRegionEditC
253257 var updatedRich = RegionRichTextEditAlgorithms . ApplyPlainTextEdit (
254258 currentRich ?? RegionRichTextEditAlgorithms . FromRuns ( string . Empty , Array . Empty < RegionTextRun > ( ) ) ,
255259 text ) ;
256- if ( editContext . TrySetParagraphText ( field , index , updatedRich ) )
260+ if ( editContext != null && editContext . TrySetParagraphText ( field , index , updatedRich ) )
257261 {
258262 lastStaged = text ;
259263 currentRich = updatedRich ;
@@ -270,7 +274,7 @@ private void WireParagraphTextEditing(LexicalEditRegionField field, IRegionEditC
270274 // seam and completes the gesture (structural: commit immediately + re-show). Built only when the
271275 // field carries available paragraph styles.
272276 private Control BuildStyleAffordance ( LexicalEditRegionField field , string automationId ,
273- IRegionEditContext editContext , Action gestureCompleted , RegionParagraph paragraph , int index )
277+ IStructuredTextEditing editContext , Action gestureCompleted , RegionParagraph paragraph , int index )
274278 {
275279 if ( field . AvailableParagraphStyles == null || field . AvailableParagraphStyles . Count == 0 )
276280 return null ;
@@ -312,7 +316,7 @@ private Control BuildStyleAffordance(LexicalEditRegionField field, string automa
312316 {
313317 styleFlyout . Hide ( ) ;
314318 var styleName = string . IsNullOrEmpty ( option ? . Key ) ? null : option . Key ;
315- if ( editContext . TrySetParagraphStyle ( field , index , styleName ) )
319+ if ( editContext != null && editContext . TrySetParagraphStyle ( field , index , styleName ) )
316320 gestureCompleted ? . Invoke ( ) ;
317321 } ;
318322 stylePicker . OptionCommitted += styleCommitted ;
@@ -401,7 +405,7 @@ private Control BuildValueContentWithFontSwap(LexicalEditRegionField field, stri
401405 // clear entry plus the project's character styles, acting on the box's current selection and
402406 // staging ApplySpanNamedStyle through the paragraph-text seam. Null when no character styles.
403407 private Control BuildCharStyleAffordance ( LexicalEditRegionField field , string automationId ,
404- IRegionEditContext editContext , Action gestureCompleted , TextBox box , int index ,
408+ IStructuredTextEditing editContext , Action gestureCompleted , TextBox box , int index ,
405409 Func < RegionRichTextValue > getRich , Action < RegionRichTextValue > setRich )
406410 {
407411 if ( field . AvailableNamedStyles == null || field . AvailableNamedStyles . Count == 0 )
@@ -449,7 +453,7 @@ private Control BuildCharStyleAffordance(LexicalEditRegionField field, string au
449453 var styleName = string . IsNullOrEmpty ( option ? . Key ) ? null : option . Key ;
450454 var restyled = RegionRichTextEditAlgorithms . ApplySpanNamedStyle ( rich , lo , hi , styleName ) ;
451455 if ( ! ReferenceEquals ( restyled , rich )
452- && editContext . TrySetParagraphText ( field , index , restyled ) )
456+ && editContext != null && editContext . TrySetParagraphText ( field , index , restyled ) )
453457 {
454458 setRich ( restyled ) ;
455459 gestureCompleted ? . Invoke ( ) ;
@@ -463,7 +467,7 @@ private Control BuildCharStyleAffordance(LexicalEditRegionField field, string au
463467 // writing systems (no clear entry), acting on the box's current selection and staging
464468 // RetagSpanWritingSystem through the paragraph-text seam. Null when no writing systems.
465469 private Control BuildWsRetagAffordance ( LexicalEditRegionField field , string automationId ,
466- IRegionEditContext editContext , Action gestureCompleted , TextBox box , int index ,
470+ IStructuredTextEditing editContext , Action gestureCompleted , TextBox box , int index ,
467471 Func < RegionRichTextValue > getRich , Action < RegionRichTextValue > setRich )
468472 {
469473 if ( field . AvailableWritingSystems == null || field . AvailableWritingSystems . Count == 0 )
@@ -510,7 +514,7 @@ private Control BuildWsRetagAffordance(LexicalEditRegionField field, string auto
510514 new [ ] { new RegionTextRun ( box . Text ?? string . Empty ) } ) ;
511515 var retagged = RegionRichTextEditAlgorithms . RetagSpanWritingSystem ( rich , lo , hi , option . Key ) ;
512516 if ( ! ReferenceEquals ( retagged , rich )
513- && editContext . TrySetParagraphText ( field , index , retagged ) )
517+ && editContext != null && editContext . TrySetParagraphText ( field , index , retagged ) )
514518 {
515519 setRich ( retagged ) ;
516520 gestureCompleted ? . Invoke ( ) ;
0 commit comments