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; + } } }