diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd13189c..2c85fc8f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added
+- [SIL.LCModel] Add GetCaptionOrHeadword() to CmPicture
- [SIL.LCModel] `LCModelStrings.NotSure` to allow clients to know if a grammatical category is the placeholder
- [SIL.LCModel.Utils] `DateTime` extension method `ToLCMTimeFormatWithMillisString()` (replaces `ReadWriteServices.FormatDateTime`)
diff --git a/src/SIL.LCModel/DomainImpl/CmPicture.cs b/src/SIL.LCModel/DomainImpl/CmPicture.cs
index 95c2ca4a..ba01d342 100644
--- a/src/SIL.LCModel/DomainImpl/CmPicture.cs
+++ b/src/SIL.LCModel/DomainImpl/CmPicture.cs
@@ -211,6 +211,53 @@ public string GetTextRepOfPicture(bool fFileNameOnly, string sReference,
// TODO (TE-7759) Include LocationRangeType and ScaleFactor
return sResult;
}
+
+ ///
+ /// First try to get the Caption property of this CmPicture,for the given writing system name. If
+ /// there isn't one then try to get the Headword property, for the given writing system name.
+ ///
+ /// The name of the writing system, which could be "magic".
+ /// Output the id of the writing system to which the TsString belongs.
+ /// The TsString of the Caption or Headword property.
+ public ITsString GetCaptionOrHeadword(string wsName, out int wsActual)
+ {
+ ITsString bestString;
+ var wsId = WritingSystemServices.GetMagicWsIdFromName(wsName);
+ // Non-magic ws.
+ if (wsId == 0)
+ {
+ wsId = Cache.WritingSystemFactory.GetWsFromStr(wsName);
+ // The config is bad or stale, so just return null
+ if (wsId == 0)
+ {
+ Debug.WriteLine("Writing system requested that is not known in the local store: {0}", wsName);
+ wsActual = 0;
+ return null;
+ }
+ // First try to get the caption.
+ bestString = Caption.get_String(wsId);
+ if (String.IsNullOrEmpty(bestString.Text))
+ {
+ // Second try to get the headword.
+ bestString = this.OwningSense.Entry.HeadWordForWs(wsId);
+ }
+ wsActual = wsId;
+ }
+ // Magic ws. (i.e. default analysis)
+ else
+ {
+ // First try to get the caption (and actual ws).
+ bestString = Caption.GetAlternativeOrBestTss(wsId, out wsActual);
+ if (String.IsNullOrEmpty(bestString.Text))
+ {
+ // Second try to get the headword (and actual ws).
+ wsActual = WritingSystemServices.ActualWs(Cache, wsId, Hvo, 0);
+ bestString = this.OwningSense.Entry.HeadWordForWs(wsActual);
+ }
+ }
+
+ return bestString;
+ }
#endregion
#region Public properties
diff --git a/src/SIL.LCModel/InterfaceAdditions.cs b/src/SIL.LCModel/InterfaceAdditions.cs
index cdedf74e..e81c3f19 100644
--- a/src/SIL.LCModel/InterfaceAdditions.cs
+++ b/src/SIL.LCModel/InterfaceAdditions.cs
@@ -4614,6 +4614,15 @@ string GetTextRepOfPicture(bool fFileNameOnly, string sReference,
/// Get the sense number of the owning LexSense.
///
ITsString SenseNumberTSS { get; }
+
+ ///
+ /// First try to get the Caption property of this CmPicture,for the given writing system name. If
+ /// there isn't one then try to get the Headword property, for the given writing system name.
+ ///
+ /// The name of the writing system, which could be "magic".
+ /// Output the id of the writing system to which the TsString belongs.
+ /// The TsString of the Caption or Headword property.
+ ITsString GetCaptionOrHeadword(string wsName, out int wsActual);
}
/// ----------------------------------------------------------------------------------------
diff --git a/tests/SIL.LCModel.Tests/DomainImpl/CmPictureTests.cs b/tests/SIL.LCModel.Tests/DomainImpl/CmPictureTests.cs
index db7d41a2..6320aac3 100644
--- a/tests/SIL.LCModel.Tests/DomainImpl/CmPictureTests.cs
+++ b/tests/SIL.LCModel.Tests/DomainImpl/CmPictureTests.cs
@@ -603,5 +603,89 @@ public void ParseScale_PercentSign()
typeof(CmPictureFactory),
"ParseScaleFactor", "43%"));
}
+
+ /// ------------------------------------------------------------------------------------
+ ///
+ /// Get the Caption for the writing system.
+ ///
+ /// ------------------------------------------------------------------------------------
+ [Test]
+ public void CaptionOrHeadword_CaptionBeatsHeadword()
+ {
+ var wsId = Cache.LangProject.DefaultVernacularWritingSystem.Id;
+ int wsHandle = Cache.LangProject.DefaultVernacularWritingSystem.Handle;
+ var entry = Cache.ServiceLocator.GetInstance().Create();
+ var sense = Cache.ServiceLocator.GetInstance().Create();
+ entry.SensesOS.Add(sense);
+ var lexform = Cache.ServiceLocator.GetInstance().Create();
+ entry.LexemeFormOA = lexform;
+ lexform.Form.VernacularDefaultWritingSystem = TsStringUtils.MakeString("Headword", wsHandle);
+ var picture = MakePicture(sense.Hvo, TsStringUtils.MakeString("Caption", wsHandle));
+
+ // SUT
+ var outStr = picture.GetCaptionOrHeadword(wsId, out _);
+ Assert.That(outStr.Text, Contains.Substring("Caption"));
+ }
+
+ /// ------------------------------------------------------------------------------------
+ ///
+ /// If the Caption is null or empty then get the Headword for the writing system.
+ ///
+ /// ------------------------------------------------------------------------------------
+ [Test]
+ public void CaptionOrHeadword_CaptionNullOrEmptyGivesHeadword()
+ {
+ var wsId = Cache.LangProject.DefaultVernacularWritingSystem.Id;
+ int wsHandle = Cache.LangProject.DefaultVernacularWritingSystem.Handle;
+ var entry = Cache.ServiceLocator.GetInstance().Create();
+ var sense = Cache.ServiceLocator.GetInstance().Create();
+ entry.SensesOS.Add(sense);
+ var lexform = Cache.ServiceLocator.GetInstance().Create();
+ entry.LexemeFormOA = lexform;
+ lexform.Form.VernacularDefaultWritingSystem = TsStringUtils.MakeString("Headword", wsHandle);
+ var pictureNull = MakePicture(sense.Hvo, null);
+ var pictureEmpty = MakePicture(sense.Hvo, TsStringUtils.EmptyString(wsHandle));
+
+ // SUT
+ var outStr1 = pictureNull.GetCaptionOrHeadword(wsId, out _);
+ var outStr2 = pictureEmpty.GetCaptionOrHeadword(wsId, out _);
+ Assert.That(outStr1.Text, Contains.Substring("Headword"));
+ Assert.That(outStr2.Text, Contains.Substring("Headword"));
+ }
+
+ /// ------------------------------------------------------------------------------------
+ ///
+ /// Confirm that we get the correct result when a magic ws is passed in.
+ ///
+ /// ------------------------------------------------------------------------------------
+ [Test]
+ public void CaptionOrHeadword_MagicWS()
+ {
+ var magicDefaultVernacular = "vernacular";
+ int wsHandle = Cache.LangProject.DefaultVernacularWritingSystem.Handle;
+ var entry = Cache.ServiceLocator.GetInstance().Create();
+ var sense = Cache.ServiceLocator.GetInstance().Create();
+ entry.SensesOS.Add(sense);
+ var lexform = Cache.ServiceLocator.GetInstance().Create();
+ entry.LexemeFormOA = lexform;
+ lexform.Form.VernacularDefaultWritingSystem = TsStringUtils.MakeString("Headword", wsHandle);
+ var pictureNullCaption = MakePicture(sense.Hvo, null);
+
+ // SUT
+ int wsActual = 0;
+ var outStr = pictureNullCaption.GetCaptionOrHeadword(magicDefaultVernacular, out wsActual);
+
+ Assert.That(outStr.Text, Contains.Substring("Headword"));
+ Assert.AreEqual(wsActual, wsHandle);
+ }
+
+ private ICmPicture MakePicture(int hvoOwner, ITsString captionTss)
+ {
+ var sda = Cache.DomainDataByFlid;
+ var hvoPicture = sda.MakeNewObject(CmPictureTags.kClassId, hvoOwner, LexSenseTags.kflidPictures, 0);
+ var picture = Cache.ServiceLocator.GetInstance().GetObject(hvoPicture);
+ picture.UpdatePicture(m_internalPath, captionTss, CmFolderTags.LocalPictures, Cache.DefaultVernWs);
+ return picture;
+ }
}
}