Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Src/LexText/LexTextControls/PatternVcBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,25 @@ protected void AddExtraLines(int numLines, int tag, IVwEnv vwenv)
}
}

/// <summary>
/// Keeps the zero-width-space boundary spans editable even inside a pattern that has
/// been marked not editable as a whole.
/// </summary>
/// <remarks>
/// Clicking an item, and every insert and delete, place the cursor through
/// MakeTextSelInObj with fEditable true, so a cell has to offer at least one editable
/// position or those commands stop working with no error. These boundary spans are the
/// position. They are safe to leave editable because ktagLeftBoundary and
/// ktagRightBoundary are fake tags rather than model properties, and
/// RuleFormulaVcBase.UpdateProp returns the value unchanged, so an edit landing here
/// reaches nothing real.
/// </remarks>
protected static void MarkBoundaryEditable(IVwEnv vwenv)
{
vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum,
(int)TptEditable.ktptIsEditable);
}

protected void OpenSingleLinePile(IVwEnv vwenv, int maxNumLines)
{
OpenSingleLinePile(vwenv, maxNumLines, true);
Expand All @@ -227,6 +246,7 @@ protected void OpenSingleLinePile(IVwEnv vwenv, int maxNumLines, bool addBoundar
if (addBoundary)
{
vwenv.Props = m_bracketProps;
MarkBoundaryEditable(vwenv);
vwenv.AddProp(ktagLeftBoundary, this, kfragZeroWidthSpace);
}
}
Expand All @@ -241,6 +261,7 @@ protected void CloseSingleLinePile(IVwEnv vwenv, bool addBoundary)
if (addBoundary)
{
vwenv.Props = m_bracketProps;
MarkBoundaryEditable(vwenv);
vwenv.AddProp(ktagRightBoundary, this, kfragZeroWidthSpace);
}
vwenv.CloseParagraph();
Expand Down
19 changes: 14 additions & 5 deletions Src/LexText/LexTextControls/PatternView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ public PatternEditingHelper(LcmCache cache, IEditingCallbacks callbacks)
{
}

public override bool CanCopy()
{
return false;
}

/// <summary>
/// Cut and paste stay refused because they would change the rule. Copy is not
/// overridden: a read-only view still has to let the formula be copied out, and the
/// base implementation already requires a real range selection.
/// </summary>
public override bool CanCut()
{
return false;
Expand All @@ -69,6 +69,15 @@ protected override EditingHelper CreateEditingHelper()
return new PatternEditingHelper(Cache, this);
}

/// <summary>
/// Activate() is disabled by default in ReadOnlyViews, but a pattern editor does want to
/// show selections so the user can see what a chooser insert/delete will act on.
/// </summary>
protected override bool AllowDisplaySelection
{
get { return true; }
}

public void Init(Mediator mediator, PropertyTable propertyTable, int hvo, IPatternControl patternControl, PatternVcBase vc, int rootFrag, ISilDataAccess sda)
{
CheckDisposed();
Expand Down
1 change: 1 addition & 0 deletions Src/LexText/Morphology/AffixRuleFormulaVc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ public override void Display(IVwEnv vwenv, int hvo, int frag)
VwLength tableLen;
tableLen.nVal = 10000;
tableLen.unit = VwUnit.kunPercent100;
MarkFormulaNotEditable(vwenv);
vwenv.OpenTable(3, tableLen, 0, VwAlignment.kvaLeft, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 0, false);

VwLength inputLen;
Expand Down
1 change: 1 addition & 0 deletions Src/LexText/Morphology/MetaRuleFormulaVc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public override void Display(IVwEnv vwenv, int hvo, int frag)
VwLength tableLen;
tableLen.nVal = 10000;
tableLen.unit = VwUnit.kunPercent100;
MarkFormulaNotEditable(vwenv);
vwenv.OpenTable(5, tableLen, 0, VwAlignment.kvaCenter, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 4000, false);

VwLength ctxtLen;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2026 SIL International
// This software is licensed under the LGPL, version 2.1 or later
// (http://www.gnu.org/licenses/lgpl-2.1.html)

using NUnit.Framework;

namespace SIL.FieldWorks.XWorks.MorphologyEditor
{
/// <summary>
/// Constructing each real rule formula control must produce a read-only rootsite, since a
/// rule cell is modifiable only by chooser-insert and delete.
/// </summary>
[TestFixture]
public class RuleFormulaControlWiringTests
{
[Test]
public void RegRuleFormulaControl_RootSiteIsReadOnly()
{
using (var control = new RegRuleFormulaControl(null))
{
Assert.That(control.RootSite.ReadOnlyView, Is.True,
"RegRuleFormulaControl must wire up a read-only rootsite");
}
}

[Test]
public void MetaRuleFormulaControl_RootSiteIsReadOnly()
{
using (var control = new MetaRuleFormulaControl(null))
{
Assert.That(control.RootSite.ReadOnlyView, Is.True,
"MetaRuleFormulaControl must wire up a read-only rootsite");
}
}

[Test]
public void AffixRuleFormulaControl_RootSiteIsReadOnly()
{
using (var control = new AffixRuleFormulaControl(null))
{
Assert.That(control.RootSite.ReadOnlyView, Is.True,
"AffixRuleFormulaControl must wire up a read-only rootsite");
}
}
}
}
Loading
Loading