public void TemplateCreatedForCurLang() { CheckDisposed(); int germanBtWs = InMemoryFdoCache.s_wsHvos.De; CreatePartialExodusBT(InMemoryFdoCache.s_wsHvos.De); m_btDraftView.ViewConstructorWS = germanBtWs; m_btDraftView.RefreshDisplay(); m_btDraftView.SetInsertionPoint(0, 1, 0, 0, true); // Generate the section template m_btDraftView.TeEditingHelper.GenerateTranslationCVNumsForSection(); StTxtPara para = (StTxtPara)m_book.SectionsOS[1].ContentOA.ParagraphsOS[0]; CmTranslation transPara1 = (CmTranslation)para.GetBT(); para = (StTxtPara)m_book.SectionsOS[1].ContentOA.ParagraphsOS[1]; CmTranslation transPara2 = (CmTranslation)para.GetBT(); para = (StTxtPara)m_book.SectionsOS[1].ContentOA.ParagraphsOS[2]; CmTranslation transPara3 = (CmTranslation)para.GetBT(); Assert.AreEqual("11BT Verse one", transPara1.Translation.GetAlternative(germanBtWs).Text); Assert.AreEqual("3", transPara2.Translation.GetAlternative(germanBtWs).Text); Assert.AreEqual("4 5", transPara3.Translation.GetAlternative(germanBtWs).Text); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the text representation of the back translations for a footnote paragraph. /// </summary> /// <param name="footnotePara">The footnote paragraph.</param> /// <returns> /// text representation of all of the back translations for the footnote paragraph /// </returns> /// ------------------------------------------------------------------------------------ private string GetTextRepresentationOfTrans(StTxtPara footnotePara) { string transRepresentation = string.Empty; CmTranslation trans = (CmTranslation)footnotePara.GetBT(); if (trans == null) { return(transRepresentation); } List <int> transWs = m_cache.GetUsedScriptureTransWsForPara(footnotePara.Hvo); foreach (int ws in transWs) { ITsString tss = trans.Translation.GetAlternativeTss(ws); if (tss != null && tss.Length > 0) { LgWritingSystem lgws = new LgWritingSystem(m_cache, ws); transRepresentation += "<TRANS WS='" + lgws.ICULocale + "'>"; transRepresentation += GetTextRepresentationOfTsString(tss); transRepresentation += "</TRANS>"; } } return(transRepresentation); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Compares the given footnote with the values in m_footnote. /// </summary> /// <param name="footnote">The footnote to compare</param> /// ------------------------------------------------------------------------------------ private void CompareFootnote(StFootnote footnote) { Assert.AreEqual(m_footnote.DisplayFootnoteMarker, footnote.DisplayFootnoteMarker, "Display footnote marker values did not match"); Assert.AreEqual(m_footnote.DisplayFootnoteReference, footnote.DisplayFootnoteReference, "Display footnote reference values did not match"); Assert.AreEqual(m_footnote.FootnoteMarker.Text, footnote.FootnoteMarker.Text); Assert.AreEqual(m_footnote.ParagraphsOS.Count, footnote.ParagraphsOS.Count, "Footnote paragraph count did not match"); string diff = string.Empty; for (int i = 0; i < m_footnote.ParagraphsOS.Count; i++) { StTxtPara expectedPara = (StTxtPara)m_footnote.ParagraphsOS[i]; StTxtPara actualPara = (StTxtPara)footnote.ParagraphsOS[i]; bool result = TsTextPropsHelper.PropsAreEqual(expectedPara.StyleRules, actualPara.StyleRules, out diff); Assert.IsTrue(result, "paragraph " + i + " stylerules differed in: " + diff); result = TsStringHelper.TsStringsAreEqual(expectedPara.Contents.UnderlyingTsString, actualPara.Contents.UnderlyingTsString, out diff); Assert.IsTrue(result, "paragraph " + i + " differed in: " + diff); CompareFootnoteTrans((CmTranslation)expectedPara.GetBT(), (CmTranslation)actualPara.GetBT(), actualPara.Hvo); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Helper method verifies that the copy was sufficiently "deep": /// copied paragraphs are different objects, and that owner and owned objects /// are different. /// </summary> /// <param name="srcPara">The para rev.</param> /// <param name="newPara">The new para.</param> /// ------------------------------------------------------------------------------------ private static void VerifyParagraphsAreDifferentObjects(StTxtPara srcPara, StTxtPara newPara) { Assert.AreNotEqual(srcPara.Hvo, newPara.Hvo); // owned by different StTexts Assert.AreNotEqual(srcPara.OwnerHVO, newPara.OwnerHVO); // owning different back translations Assert.AreNotEqual(srcPara.GetBT().Hvo, newPara.GetBT().Hvo); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Verifies that the footnote marker was deleted from the specified back translation /// </summary> /// <param name="hvoPara">HVO of the paragraph that contains the footnote marker</param> /// <param name="guidFootnote">GUID of the deleted footnote</param> /// <param name="ws">The HVO of the back trans writing system to check</param> /// ------------------------------------------------------------------------------------ private void VerifyRemovedFootnoteMarker(int hvoPara, Guid guidFootnote, int ws) { StTxtPara para = new StTxtPara(Cache, hvoPara); ICmTranslation trans = para.GetBT(); if (trans == null) { return; // no back translation exists to check } ITsString tssBt = trans.Translation.GetAlternativeTss(ws); VerifyRemovedFootnoteMarker(guidFootnote, tssBt); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Tests that a footnote has been created in the DB with a single default run having /// the specified text and the given translation. /// </summary> /// <param name="iFootnoteIndex">zero-based footnote index</param> /// <param name="sFootnoteSegment">Expected footnote contents</param> /// <param name="sFootnoteTransSegment">Expected footnote translation contents</param> /// <param name="sMarker">One of: <c>"a"</c>, for automatic alpha sequence; <c>"*"</c>, /// for a literal marker (we always use "*" in these tests); or <c>string.Empty</c>, /// for no marker</param> /// <param name="sParaStyleName">Name of the paragraph style</param> /// ------------------------------------------------------------------------------------ public void VerifyFootnoteWithTranslation(int iFootnoteIndex, string sFootnoteSegment, string sFootnoteTransSegment, string sMarker, string sParaStyleName) { // Force reload of book IStFootnote footnote = m_importer.GetFootnote(iFootnoteIndex); if (sMarker == "a") { sMarker = new string((char)((int)'a' + (iFootnoteIndex % 26)), 1); } if (sMarker != null) { AssertEx.RunIsCorrect(footnote.FootnoteMarker.UnderlyingTsString, 0, sMarker, ScrStyleNames.FootnoteMarker, m_wsVern); } else { Assert.IsNull(footnote.FootnoteMarker.Text); } FdoOwningSequence <IStPara> footnoteParas = footnote.ParagraphsOS; Assert.AreEqual(1, footnoteParas.Count); StTxtPara para = (StTxtPara)footnoteParas[0]; Assert.AreEqual(StyleUtils.ParaStyleTextProps(sParaStyleName), para.StyleRules); ITsString tss = para.Contents.UnderlyingTsString; Assert.AreEqual(1, tss.RunCount); AssertEx.RunIsCorrect(tss, 0, sFootnoteSegment, null, m_wsVern); // Check Translation if (sFootnoteTransSegment != null) { Assert.AreEqual(1, para.TranslationsOC.Count); ICmTranslation trans = para.GetBT(); tss = trans.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString; Assert.AreEqual(1, tss.RunCount); AssertEx.RunIsCorrect(tss, 0, sFootnoteTransSegment, null, m_wsAnal); } else { Assert.AreEqual(0, para.TranslationsOC.Count); } }
public void RemoveOwnedObjectsForString_FootnotesWithBT() { CheckDisposed(); StTxtPara para = (StTxtPara)m_currentText.ParagraphsOS[0]; // Add footnotes to existing paragraph. StFootnote footnote1 = m_inMemoryCache.AddFootnote(m_currentFootnotesOS, para, 6, "Footnote1"); StFootnote footnote2 = m_inMemoryCache.AddFootnote(m_currentFootnotesOS, para, 10, "Footnote2"); Assert.AreEqual(2, m_currentFootnotesOS.Count); // add two back translations of the para and footnotes ICmTranslation trans; int[] wsBt = new int[] { InMemoryFdoCache.s_wsHvos.En, InMemoryFdoCache.s_wsHvos.De }; foreach (int ws in wsBt) { // add back translation of the para trans = m_inMemoryCache.AddBtToMockedParagraph(para, ws); m_inMemoryCache.AddRunToMockedTrans(trans, ws, "BT of test paragraph", null); // add BT footnotes m_inMemoryCache.AddFootnoteORCtoTrans(trans, 2, ws, footnote1, "BT of footnote1"); m_inMemoryCache.AddFootnoteORCtoTrans(trans, 6, ws, footnote2, "BT of footnote2"); Assert.AreEqual("BT" + StringUtils.kchObject + " of" + StringUtils.kchObject + " test paragraph", trans.Translation.GetAlternative(ws).Text); // confirm that ORCs were inserted in BTs } para.RemoveOwnedObjectsForString(5, 12); Assert.AreEqual(0, m_currentFootnotesOS.Count); // We expect that the ORCs would have also been removed from both back translations. trans = para.GetBT() as CmTranslation; Assert.IsNotNull(trans); foreach (int ws in wsBt) { Assert.AreEqual("BT of test paragraph", trans.Translation.GetAlternative(ws).Text); } }
public void ReplaceAll_InBackTranslation() { CheckDisposed(); InitializeForReplaceAll(); // Replace "BT" with "back translation" int wsBt = Cache.DefaultAnalWs; m_pattern.Pattern = m_strFactory.MakeString("BT", wsBt); m_pattern.ReplaceWith = m_strFactory.MakeString("Back Translation", Cache.DefaultAnalWs); int hvoRoot; IVwViewConstructor vc; int frag; IVwStylesheet styleSheet; m_btDraftView.RootBox.GetRootObject(out hvoRoot, out vc, out frag, out styleSheet); ReplaceAllCollectorEnv collectorEnv = new ReplaceAllCollectorEnv(vc, Cache.MainCacheAccessor, hvoRoot, frag, m_pattern, null); int nReplaces = collectorEnv.ReplaceAll(); // Get back translation from Exodus after Replace All. StTxtPara headingPara1 = (StTxtPara)m_exodus.SectionsOS[0].HeadingOA.ParagraphsOS[0]; ITsString btHeading1 = headingPara1.GetBT().Translation.GetAlternative(wsBt).UnderlyingTsString; StTxtPara contentPara1 = (StTxtPara)m_exodus.SectionsOS[0].ContentOA.ParagraphsOS[0]; ITsString btContent1 = contentPara1.GetBT().Translation.GetAlternative(wsBt).UnderlyingTsString; StTxtPara headingPara2 = (StTxtPara)m_exodus.SectionsOS[1].HeadingOA.ParagraphsOS[0]; ITsString btHeading2 = headingPara2.GetBT().Translation.GetAlternative(wsBt).UnderlyingTsString; StTxtPara contentPara2 = (StTxtPara)m_exodus.SectionsOS[1].ContentOA.ParagraphsOS[0]; ITsString btContent2 = contentPara2.GetBT().Translation.GetAlternative(wsBt).UnderlyingTsString; // Confirm that "BT" was replaced with "Back Translation" Assert.AreEqual(4, nReplaces); Assert.AreEqual("Back Translation Heading 1", btHeading1.Text); Assert.AreEqual("Back Translation Intro text", btContent1.Text); Assert.AreEqual("Back Translation Heading 2", btHeading2.Text); Assert.AreEqual("11Back Translation Verse one", btContent2.Text); }
public void BtOnlyFootnotes() { m_scrInMemoryCache.InitializeScrPublications(); // Set up Scripture to correspond with the back translation to be imported. IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(2, "Exodus"); IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo); StTxtPara para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph); m_scrInMemoryCache.AddRunToMockedPara(para, "1", ScrStyleNames.ChapterNumber); m_scrInMemoryCache.AddRunToMockedPara(para, "1", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(para, "verse one text", null); m_scrInMemoryCache.AddRunToMockedPara(para, "2", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(para, "verse two text", null); StFootnote noteOne = m_scrInMemoryCache.AddFootnote(exodus, para, 11, "vernacular text for footnote one"); // footnote after "one" in verse 1 StFootnote noteTwo = m_scrInMemoryCache.AddFootnote(exodus, para, 27, "vernacular text for footnote two"); // footnote after "two" in verse 2 ICmTranslation noteOneTrans = ((StTxtPara)noteOne.ParagraphsOS[0]).GetOrCreateBT(); ICmTranslation noteTwoTrans = ((StTxtPara)noteTwo.ParagraphsOS[0]).GetOrCreateBT(); section.AdjustReferences(); m_importer.Settings.ImportTranslation = false; m_importer.Settings.ImportBackTranslation = true; m_importer.CurrentImportDomain = ImportDomain.BackTrans; // ************** process a \id segment, test MakeBook() method ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("", @"\id"); // no text provided in segment, just the refs Assert.AreEqual(2, m_importer.BookNumber); // verify that a new book was added to the DB IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo); Assert.AreEqual("EXO", book.BookId); // ************** process a main title ********************* m_importer.ProcessSegment(string.Empty, @"\mt"); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 0); m_importer.ProcessSegment("", @"\c"); // ****** process a new BT paragraph with footnotes ********** m_importer.ProcessSegment("", @"\p"); m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\v"); m_importer.ProcessSegment("verse one BT text", @"\vt"); m_importer.ProcessSegment("+", @"\f"); m_importer.ProcessSegment("BT text for footnote one.", @"\ft"); m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 2); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 2); m_importer.ProcessSegment("", @"\v"); m_importer.ProcessSegment("verse two BT text", @"\vt"); m_importer.ProcessSegment("+", @"\f"); m_importer.ProcessSegment("BT text for footnote two.", @"\ft"); // ************** finalize ************** m_importer.FinalizeImport(); // Check the BT of these two paragraphs Assert.AreEqual(1, para.TranslationsOC.Count); ICmTranslation trans1 = para.GetBT(); Assert.IsNotNull(trans1); ITsString tss1 = trans1.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString; //Assert.AreEqual(7, tss1.RunCount); AssertEx.RunIsCorrect(tss1, 0, "1", ScrStyleNames.ChapterNumber, m_wsAnal); AssertEx.RunIsCorrect(tss1, 1, "1", ScrStyleNames.VerseNumber, m_wsAnal); AssertEx.RunIsCorrect(tss1, 2, "verse one BT text", null, m_wsAnal); Guid guid1 = StringUtils.GetGuidFromRun(tss1, 3); int hvoFootnote = Cache.GetIdFromGuid(guid1); Assert.AreEqual(noteOneTrans.OwnerHVO, new StFootnote(Cache, hvoFootnote).ParagraphsOS[0].Hvo, "The first imported BT footnote should be owned by paragraph in the first footnote but isn't"); VerifyFootnoteWithTranslation(0, "vernacular text for footnote one", "BT text for footnote one.", null, ScrStyleNames.NormalFootnoteParagraph); AssertEx.RunIsCorrect(tss1, 4, "2", ScrStyleNames.VerseNumber, m_wsAnal); AssertEx.RunIsCorrect(tss1, 5, "verse two BT text", null, m_wsAnal); VerifyFootnoteWithTranslation(1, "vernacular text for footnote two", "BT text for footnote two.", null, ScrStyleNames.NormalFootnoteParagraph); }
public void SkipInitialStanzaBreak() { CheckDisposed(); m_scrInMemoryCache.InitializeScrPublications(); // Set up Scripture to correspond with the back translation to be imported. IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(2, "Exodus"); IScrSection section1 = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo); StTxtPara paraH1 = m_scrInMemoryCache.AddSectionHeadParaToSection(section1.Hvo, "Seccion Uno", ScrStyleNames.SectionHead); StTxtPara paraC1 = m_scrInMemoryCache.AddParaToMockedSectionContent(section1.Hvo, ScrStyleNames.NormalParagraph); m_scrInMemoryCache.AddRunToMockedPara(paraC1, "1", ScrStyleNames.ChapterNumber); m_scrInMemoryCache.AddRunToMockedPara(paraC1, "1", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(paraC1, "verse one text", null); section1.AdjustReferences(); IScrSection section2 = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo); StTxtPara paraH2 = m_scrInMemoryCache.AddSectionHeadParaToSection(section2.Hvo, "Seccion Dos", ScrStyleNames.SectionHead); StTxtPara paraC2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section2.Hvo, ScrStyleNames.NormalParagraph); m_scrInMemoryCache.AddRunToMockedPara(paraC2, "2", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(paraC2, "verse two text", null); section2.AdjustReferences(); m_importer.Settings.ImportBackTranslation = true; m_importer.CurrentImportDomain = ImportDomain.BackTrans; // ************** process a \id segment, test MakeBook() method ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("", @"\id"); // no text provided in segment, just the refs // ************** process a main title ********************* m_importer.ProcessSegment(string.Empty, @"\mt"); // ************** process a bogus stanza break ********************* m_importer.ProcessSegment(string.Empty, @"\b"); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 0); m_importer.ProcessSegment("", @"\c"); // ************** process first section head ********************* m_importer.ProcessSegment("Section One", @"\s"); // ************** process section contents ********************* m_importer.ProcessSegment("", @"\p"); m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("BT text for verse one", @"\v"); // ************** process second section head ********************* m_importer.ProcessSegment("Section Two", @"\s"); // ************** process section contents ********************* m_importer.ProcessSegment("", @"\p"); m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 2); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 2); m_importer.ProcessSegment("BT for text at start of verse 2", @"\v"); // ************** finalize ************** m_importer.FinalizeImport(); // Check the BT Assert.AreEqual(1, paraH1.TranslationsOC.Count); Assert.AreEqual(1, paraC1.TranslationsOC.Count); Assert.AreEqual(1, paraH2.TranslationsOC.Count); Assert.AreEqual(1, paraC2.TranslationsOC.Count); ICmTranslation transH1 = paraH1.GetBT(); ITsString tssH1 = transH1.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString; Assert.AreEqual(1, tssH1.RunCount); AssertEx.RunIsCorrect(tssH1, 0, "Section One", null, m_wsAnal); ICmTranslation transC1 = paraC1.GetBT(); ITsString tssC1 = transC1.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString; Assert.AreEqual(3, tssC1.RunCount); AssertEx.RunIsCorrect(tssC1, 0, "1", ScrStyleNames.ChapterNumber, m_wsAnal); AssertEx.RunIsCorrect(tssC1, 1, "1", ScrStyleNames.VerseNumber, m_wsAnal); AssertEx.RunIsCorrect(tssC1, 2, "BT text for verse one", null, m_wsAnal); ICmTranslation transH2 = paraH2.GetBT(); ITsString tssH2 = transH2.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString; Assert.AreEqual(1, tssH2.RunCount); AssertEx.RunIsCorrect(tssH2, 0, "Section Two", null, m_wsAnal); ICmTranslation transC2 = paraC2.GetBT(); ITsString tssC2 = transC2.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString; Assert.AreEqual(2, tssC2.RunCount); AssertEx.RunIsCorrect(tssC2, 0, "2", ScrStyleNames.VerseNumber, m_wsAnal); AssertEx.RunIsCorrect(tssC2, 1, "BT for text at start of verse 2", null, m_wsAnal); }
public void TwoBts() { CheckDisposed(); m_importer.Settings.ImportBackTranslation = true; // initialize - process a \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("EXO Vernacular ID Text", @"\id"); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\c"); Assert.AreEqual(1, m_importer.Chapter); // ************** process v1 verse 1 ********************* m_importer.ProcessSegment("verse text", @"\v"); // verify state of NormalParaStrBldr Assert.AreEqual(3, m_importer.NormalParaStrBldr.RunCount); VerifyBldrRun(0, "1", ScrStyleNames.ChapterNumber); VerifyBldrRun(1, "1", ScrStyleNames.VerseNumber); VerifyBldrRun(2, "verse text", null); // ************** End of Scripture file ********************* // ******* Back translation in default Analysis WS ********** m_importer.CurrentImportDomain = ImportDomain.BackTrans; m_importer.DummySoWrapper.m_CurrentWs = m_wsAnal; // process an \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("EXO Ignore this", @"\id"); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\c"); Assert.AreEqual(1, m_importer.Chapter); // ************** process v1 verse 1 ********************* m_importer.ProcessSegment("back trans", @"\v"); // ******* Back translation in Spanish WS ********** int wsSpanish = Cache.LanguageWritingSystemFactoryAccessor.GetWsFromStr("es"); m_importer.DummySoWrapper.m_CurrentWs = wsSpanish; // process an \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("EXO Ignora esto tambien", @"\id"); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\c"); Assert.AreEqual(1, m_importer.Chapter); // ************** process v1 verse 1 ********************* m_importer.ProcessSegment("retrotraduccion", @"\v"); // ************** finalize ************** m_importer.FinalizeImport(); IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo); Assert.AreEqual("Vernacular ID Text", book.IdText); Assert.AreEqual(1, book.SectionsOS.Count); IScrSection section = book.SectionsOS[0]; Assert.AreEqual(1, section.ContentOA.ParagraphsOS.Count); Assert.AreEqual(02001001, section.VerseRefMin); Assert.AreEqual(02001001, section.VerseRefMax); StTxtPara para = (StTxtPara)section.ContentOA.ParagraphsOS[0]; Assert.AreEqual("11verse text", para.Contents.Text); Assert.AreEqual(1, para.TranslationsOC.Count); ICmTranslation trans = para.GetBT(); // Check default analysis BT TsStringAccessor bt = trans.Translation.AnalysisDefaultWritingSystem; Assert.AreEqual("11back trans", bt.Text); Assert.AreEqual(3, bt.UnderlyingTsString.RunCount); Assert.AreEqual("back trans", bt.UnderlyingTsString.get_RunText(2)); ITsTextProps ttpRun3 = bt.UnderlyingTsString.get_Properties(2); Assert.AreEqual(null, ttpRun3.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); int nVar; Assert.AreEqual(m_wsAnal, ttpRun3.GetIntPropValues((int)FwTextPropType.ktptWs, out nVar)); // Check Spanish BT bt = trans.Translation.GetAlternative(wsSpanish); Assert.AreEqual("11retrotraduccion", bt.Text); Assert.AreEqual(3, bt.UnderlyingTsString.RunCount); Assert.AreEqual("retrotraduccion", bt.UnderlyingTsString.get_RunText(2)); ttpRun3 = bt.UnderlyingTsString.get_Properties(2); Assert.AreEqual(null, ttpRun3.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); Assert.AreEqual(wsSpanish, ttpRun3.GetIntPropValues((int)FwTextPropType.ktptWs, out nVar)); }
public void ImplicitParaStart() { CheckDisposed(); m_scrInMemoryCache.InitializeScrPublications(); // Set up Scripture to correspond with the back translation to be imported. IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(2, "Exodus"); IScrSection section1 = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo); StTxtPara para1 = m_scrInMemoryCache.AddParaToMockedSectionContent(section1.Hvo, ScrStyleNames.NormalParagraph); m_scrInMemoryCache.AddRunToMockedPara(para1, "1", ScrStyleNames.ChapterNumber); m_scrInMemoryCache.AddRunToMockedPara(para1, "1", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(para1, "verse one text", null); m_scrInMemoryCache.AddRunToMockedPara(para1, "2", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(para1, "verse two text", null); StTxtPara para2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section1.Hvo, "List Item1"); m_scrInMemoryCache.AddRunToMockedPara(para2, "more verse two text", null); section1.AdjustReferences(); m_importer.Settings.ImportBackTranslation = true; m_importer.CurrentImportDomain = ImportDomain.BackTrans; // ************** process a \id segment, test MakeBook() method ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("", @"\id"); // no text provided in segment, just the refs Assert.AreEqual(2, m_importer.BookNumber); IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo); Assert.AreEqual("EXO", book.BookId); // ************** process a main title ********************* m_importer.ProcessSegment(string.Empty, @"\mt"); //Assert.AreEqual(string.Empty, m_importer.ScrBook.Name.GetAlternative( // m_wsAnal)); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 0); m_importer.ProcessSegment("", @"\c"); // ************** process two new paragraphs ********************* m_importer.ProcessSegment("", @"\p"); m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\v"); m_importer.ProcessSegment("BT text for verse one", @"\vt"); m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 2); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 2); m_importer.ProcessSegment("", @"\v"); m_importer.ProcessSegment("BT for text at start of verse 2", @"\vt"); m_importer.ProcessSegment("", @"\li1"); m_importer.ProcessSegment("BT of continued text", @"\vt"); // ************** finalize ************** m_importer.FinalizeImport(); // Check the BT of these two paragraphs Assert.AreEqual(1, para1.TranslationsOC.Count); ICmTranslation trans1 = para1.GetBT(); ITsString tss1 = trans1.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString; Assert.AreEqual(5, tss1.RunCount); AssertEx.RunIsCorrect(tss1, 0, "1", ScrStyleNames.ChapterNumber, m_wsAnal); AssertEx.RunIsCorrect(tss1, 1, "1", ScrStyleNames.VerseNumber, m_wsAnal); AssertEx.RunIsCorrect(tss1, 2, "BT text for verse one", null, m_wsAnal); AssertEx.RunIsCorrect(tss1, 3, "2", ScrStyleNames.VerseNumber, m_wsAnal); AssertEx.RunIsCorrect(tss1, 4, "BT for text at start of verse 2", null, m_wsAnal); Assert.AreEqual(1, para2.TranslationsOC.Count); ICmTranslation trans2 = para2.GetBT(); ITsString tss2 = trans2.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString; Assert.AreEqual(1, tss2.RunCount); }
public void VerseBeyondVersificationMax() { CheckDisposed(); m_importer.Settings.ImportBackTranslation = true; // initialize - process a \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(45, 7, 25); m_importer.TextSegment.LastReference = new BCVRef(45, 7, 25); m_importer.ProcessSegment("", @"\id"); m_importer.ProcessSegment("", @"\c"); // ************** process two new paragraphs ********************* m_importer.ProcessSegment("", @"\p"); m_importer.ProcessSegment("", @"\v"); m_importer.ProcessSegment("Front text for verse25", @"\vt"); m_importer.TextSegment.FirstReference = new BCVRef(45, 7, 26); m_importer.TextSegment.LastReference = new BCVRef(45, 7, 26); m_importer.ProcessSegment("", @"\v"); m_importer.ProcessSegment("Front text for verse26", @"\vt"); //// verify state of NormalParaStrBldr Assert.AreEqual(5, m_importer.NormalParaStrBldr.RunCount); VerifyBldrRun(0, "7", ScrStyleNames.ChapterNumber); VerifyBldrRun(1, "25", ScrStyleNames.VerseNumber); VerifyBldrRun(2, "Front text for verse25", null); VerifyBldrRun(3, "26", ScrStyleNames.VerseNumber); VerifyBldrRun(4, "Front text for verse26", null); // ************** End of Scripture file ********************* // ******* Back translation in default Analysis WS ********** m_importer.CurrentImportDomain = ImportDomain.BackTrans; m_importer.DummySoWrapper.m_CurrentWs = m_wsAnal; // process an \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(45, 7, 26); m_importer.TextSegment.LastReference = new BCVRef(45, 7, 26); m_importer.ProcessSegment("", @"\id"); m_importer.ProcessSegment("", @"\c"); // ************** process two new paragraphs ********************* m_importer.ProcessSegment("", @"\p"); m_importer.ProcessSegment("", @"\v"); m_importer.ProcessSegment("Back text for verse", @"\vt"); // ************** finalize ************** m_importer.FinalizeImport(); IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo); // Check section 1 StTxtPara para = (StTxtPara)book.SectionsOS[0].ContentOA.ParagraphsOS[0]; Assert.AreEqual("725Front text for verse2526Front text for verse26", para.Contents.Text); Assert.AreEqual(1, para.TranslationsOC.Count); ICmTranslation trans = para.GetBT(); // Check default analysis BT TsStringAccessor bt = trans.Translation.AnalysisDefaultWritingSystem; Assert.AreEqual("726Back text for verse", bt.Text); Assert.AreEqual(3, bt.UnderlyingTsString.RunCount); AssertEx.RunIsCorrect(bt.UnderlyingTsString, 0, "7", ScrStyleNames.ChapterNumber, m_scr.Cache.DefaultAnalWs); AssertEx.RunIsCorrect(bt.UnderlyingTsString, 1, "26", ScrStyleNames.VerseNumber, m_scr.Cache.DefaultAnalWs); AssertEx.RunIsCorrect(bt.UnderlyingTsString, 2, "Back text for verse", null, m_scr.Cache.DefaultAnalWs); }
public void DoubleSectionHeadMarker() { CheckDisposed(); m_importer.Settings.ImportBackTranslation = true; // initialize - process a \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("", @"\id"); // ************** process the two-line section head *************** m_importer.ProcessSegment("Front Section head 1.1", @"\s"); m_importer.ProcessSegment("Front Section head 1.2", @"\s"); //// verify state of NormalParaStrBldr Assert.AreEqual(1, m_importer.NormalParaStrBldr.RunCount); VerifyBldrRun(0, "Front Section head 1.1\u2028Front Section head 1.2", null); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\c"); Assert.AreEqual(1, m_importer.Chapter); // ************** process v1 verse 1 ********************* m_importer.ProcessSegment("Some verse", @"\v"); // ************** process another two-line section head ************** m_importer.ProcessSegment("Front Section head 2.1", @"\s"); m_importer.ProcessSegment("Front Section head 2.2", @"\s"); //// verify state of NormalParaStrBldr Assert.AreEqual(1, m_importer.NormalParaStrBldr.RunCount); VerifyBldrRun(0, "Front Section head 2.1\u2028Front Section head 2.2", null); // ************** End of Scripture file ********************* // ******* Back translation in default Analysis WS ********** m_importer.CurrentImportDomain = ImportDomain.BackTrans; m_importer.DummySoWrapper.m_CurrentWs = m_wsAnal; // process an \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("", @"\id"); // ************** process the BT of section head 1 ************** m_importer.ProcessSegment("Back Section head 1.1", @"\s"); m_importer.ProcessSegment("Back Section head 1.2", @"\s"); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\c"); Assert.AreEqual(1, m_importer.Chapter); // ************** process v1 verse 1 ********************* m_importer.ProcessSegment("Algun versiculo", @"\v"); // ************** process the BT of section head 2 ************** m_importer.ProcessSegment("Back Section head 2.1", @"\s"); m_importer.ProcessSegment("Back Section head 2.2", @"\s"); // ************** finalize ************** m_importer.FinalizeImport(); IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo); // Check section 1 StTxtPara para = (StTxtPara)book.SectionsOS[0].HeadingOA.ParagraphsOS[0]; Assert.AreEqual("Front Section head 1.1\u2028Front Section head 1.2", para.Contents.Text); Assert.AreEqual(1, para.TranslationsOC.Count); ICmTranslation trans = para.GetBT(); // Check default analysis BT TsStringAccessor bt = trans.Translation.AnalysisDefaultWritingSystem; Assert.AreEqual("Back Section head 1.1\u2028Back Section head 1.2", bt.Text); Assert.AreEqual(1, bt.UnderlyingTsString.RunCount); AssertEx.RunIsCorrect(bt.UnderlyingTsString, 0, "Back Section head 1.1\u2028Back Section head 1.2", null, m_scr.Cache.DefaultAnalWs); // Check section 2 para = (StTxtPara)book.SectionsOS[1].HeadingOA.ParagraphsOS[0]; Assert.AreEqual("Front Section head 2.1\u2028Front Section head 2.2", para.Contents.Text); Assert.AreEqual(1, para.TranslationsOC.Count); trans = para.GetBT(); // Check default analysis BT bt = trans.Translation.AnalysisDefaultWritingSystem; Assert.AreEqual("Back Section head 2.1\u2028Back Section head 2.2", bt.Text); Assert.AreEqual(1, bt.UnderlyingTsString.RunCount); AssertEx.RunIsCorrect(bt.UnderlyingTsString, 0, "Back Section head 2.1\u2028Back Section head 2.2", null, m_scr.Cache.DefaultAnalWs); }
public void TitleSecondary() { CheckDisposed(); m_importer.Settings.ImportBackTranslation = true; // initialize - process a \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("", @"\id"); // ************** process the title secondary style ********************* m_importer.ProcessSegment("Title secondary", @"\st"); m_importer.ProcessSegment("main title", @"\mt"); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\c"); Assert.AreEqual(1, m_importer.Chapter); // ************** process v1 verse 1 ********************* m_importer.ProcessSegment("verse text", @"\v"); // verify state of NormalParaStrBldr Assert.AreEqual(3, m_importer.NormalParaStrBldr.RunCount); VerifyBldrRun(0, "1", ScrStyleNames.ChapterNumber); VerifyBldrRun(1, "1", ScrStyleNames.VerseNumber); VerifyBldrRun(2, "verse text", null); // ************** End of Scripture file ********************* // ******* Back translation in default Analysis WS ********** m_importer.CurrentImportDomain = ImportDomain.BackTrans; m_importer.DummySoWrapper.m_CurrentWs = m_wsAnal; // process an \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("", @"\id"); // ************** process the title secondary style ********************* m_importer.ProcessSegment("Title secondary BT", @"\st"); m_importer.ProcessSegment("main title BT", @"\mt"); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\c"); Assert.AreEqual(1, m_importer.Chapter); // ************** process v1 verse 1 ********************* m_importer.ProcessSegment("back trans", @"\v"); // ******* Back translation in Spanish WS ********** int wsSpanish = Cache.LanguageWritingSystemFactoryAccessor.GetWsFromStr("es"); m_importer.DummySoWrapper.m_CurrentWs = wsSpanish; // process an \id segment to establish a book m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0); m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0); m_importer.ProcessSegment("", @"\id"); // ************** process a chapter ********************* m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1); m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1); m_importer.ProcessSegment("", @"\c"); Assert.AreEqual(1, m_importer.Chapter); // ************** process v1 verse 1 ********************* m_importer.ProcessSegment("retrotraduccion", @"\v"); // ************** finalize ************** m_importer.FinalizeImport(); IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo); StTxtPara para = (StTxtPara)book.TitleOA.ParagraphsOS[0]; Assert.AreEqual("Title secondary\u2028main title", para.Contents.Text); Assert.AreEqual(1, para.TranslationsOC.Count); ICmTranslation trans = para.GetBT(); // Check default analysis BT TsStringAccessor bt = trans.Translation.AnalysisDefaultWritingSystem; Assert.AreEqual("Title secondary BT\u2028main title BT", bt.Text); Assert.AreEqual(2, bt.UnderlyingTsString.RunCount); AssertEx.RunIsCorrect(bt.UnderlyingTsString, 0, "Title secondary BT", "Title Secondary", m_scr.Cache.DefaultAnalWs); AssertEx.RunIsCorrect(bt.UnderlyingTsString, 1, "\u2028main title BT", null, m_scr.Cache.DefaultAnalWs); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Helper method: /// Verify the given copied paragraph, including footnotes and back translation, /// plus any other fields deemed necessary. /// </summary> /// ------------------------------------------------------------------------------------ private void VerifyCopiedPara(StTxtPara newPara) { // Verify the para StyleRules Assert.AreEqual("Line 1", newPara.StyleRules.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); // Verify the para Contents Assert.AreEqual("11This" + StringUtils.kchObject + " is" + StringUtils.kchObject + " the previous version of the text.", newPara.Contents.Text); ITsString tssNewParaContents = newPara.Contents.UnderlyingTsString; Assert.AreEqual(7, tssNewParaContents.RunCount); AssertEx.RunIsCorrect(tssNewParaContents, 0, "1", "CharacterStyle1", Cache.DefaultVernWs, true); AssertEx.RunIsCorrect(tssNewParaContents, 1, "1", "CharacterStyle2", Cache.DefaultVernWs, true); AssertEx.RunIsCorrect(tssNewParaContents, 2, "This", null, Cache.DefaultVernWs, true); // Run #3 is ORC for footnote, checked below... AssertEx.RunIsCorrect(tssNewParaContents, 4, " is", null, Cache.DefaultVernWs, true); // Run #5 is ORC for footnote, checked below... AssertEx.RunIsCorrect(tssNewParaContents, 6, " the previous version of the text.", null, Cache.DefaultVernWs, true); // note: At this point, having done the Copyxx() but not CreateOwnedObjects(), // the ORCs still refer to footnote objects owned by m_archivedText... StFootnote footnote1 = (StFootnote)m_archivedFootnotesOS.FirstItem; VerifyFootnote(footnote1, newPara, 6); Assert.AreEqual("Footnote1", ((StTxtPara)footnote1.ParagraphsOS[0]).Contents.Text); StFootnote footnote2 = (StFootnote)m_archivedFootnotesOS[1]; VerifyFootnote(footnote2, newPara, 10); Assert.AreEqual("Footnote2", ((StTxtPara)footnote2.ParagraphsOS[0]).Contents.Text); // ...thus the footnotes are not yet in m_currentFootnotesOS. Assert.AreEqual(0, m_currentFootnotesOS.Count); // Verify the para translations Assert.AreEqual(1, newPara.TranslationsOC.Count); //only 1 translation, the BT ICmTranslation paraTrans = newPara.GetBT(); // verify each alternate translation int[] wsBt = new int[] { InMemoryFdoCache.s_wsHvos.En, InMemoryFdoCache.s_wsHvos.De }; foreach (int ws in wsBt) { ITsString tssBtParaContents = paraTrans.Translation.GetAlternativeTss(ws); Assert.AreEqual("BT" + StringUtils.kchObject + " of" + StringUtils.kchObject + " test paragraph" + ws.ToString(), tssBtParaContents.Text); Assert.AreEqual(5, tssBtParaContents.RunCount); // could check every run too, but we'll skip that Assert.AreEqual(BackTranslationStatus.Finished.ToString(), paraTrans.Status.GetAlternative(ws)); } // Verify the footnote translations, their ORCs, and their status foreach (int ws in wsBt) { VerifyBtFootnote(footnote1, newPara, ws, 2); ICmTranslation footnoteTrans = ((StTxtPara)footnote1.ParagraphsOS[0]).GetBT(); Assert.AreEqual("BT of footnote1 " + ws.ToString(), footnoteTrans.Translation.GetAlternativeTss(ws).Text); Assert.AreEqual(BackTranslationStatus.Checked.ToString(), footnoteTrans.Status.GetAlternative(ws)); VerifyBtFootnote(footnote2, newPara, ws, 6); footnoteTrans = ((StTxtPara)footnote2.ParagraphsOS[0]).GetBT(); Assert.AreEqual("BT of footnote2 " + ws.ToString(), footnoteTrans.Translation.GetAlternativeTss(ws).Text); Assert.AreEqual(BackTranslationStatus.Finished.ToString(), footnoteTrans.Status.GetAlternative(ws)); } }
public static void UpdateMainTransFromSegmented(StTxtPara para, int[] wss) { if (!para.IsValidObject()) { return; // in merge, paragraph may be modified then deleted. } FdoCache cache = para.Cache; BtConverter.EnsureMainParaSegments(para, wss[0]); ISilDataAccess sda = cache.MainCacheAccessor; List <int> segments = para.Segments; int kflidFT = StTxtPara.SegmentFreeTranslationFlid(cache); ITsString tssContents = para.Contents.UnderlyingTsString; IScripture scr = para.Cache.LangProject.TranslatedScriptureOA; ICmTranslation originalBT = para.GetBT(); // Can be null string sUnfinished = BackTranslationStatus.Unfinished.ToString(); foreach (int ws in wss) { ITsStrBldr bldr = TsStrBldrClass.Create(); bool wantNextSpace = false; // suppresses space before the first thing we add. bool haveBtText = false; // Text that isn't segment label text foreach (int hvoSeg in segments) { // If it's a label, insert it directly. Suppress following space. int beginOffset = sda.get_IntProp(hvoSeg, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginOffset); int endOffset = sda.get_IntProp(hvoSeg, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidEndOffset); ITsString tssFt; // Whether we want to insert a space before the current segment is determined by the previous one. // Save that value so we can set wantSpace appropriately for the following one. bool wantSpace = wantNextSpace; if (SegmentBreaker.HasLabelText(tssContents, beginOffset, endOffset)) { tssFt = (new CmBaseAnnotation(cache, hvoSeg)).TextAnnotated; tssFt = scr.ConvertCVNumbersInStringForBT(CorrectFootnotes(tssFt), ws); wantNextSpace = false; } else { int hvoFt = sda.get_ObjectProp(hvoSeg, kflidFT); tssFt = sda.get_MultiStringAlt(hvoFt, (int)CmAnnotation.CmAnnotationTags.kflidComment, ws); haveBtText |= (tssFt.Length > 0); wantNextSpace = EndsWithNonSpace(tssFt); } if (tssFt.Length > 0) { if (wantSpace) { // The preceding segment should typically be followed by a space. if (!StartsWithSpaceOrOrc(tssFt)) { bldr.Replace(bldr.Length, bldr.Length, " ", null); } } bldr.ReplaceTsString(bldr.Length, bldr.Length, tssFt); } } // If the back translation doesn't have text, we don't want to create verse // segment labels. This prevents the problem where the book thinks it has a // back translation because of automatically generated verse labels (TE-8283). if (!haveBtText) { // This check might not be needed, but it shouldn't hurt anything. if (originalBT != null) { if (originalBT.Translation.GetAlternative(ws).Length > 0) { string origStatus = originalBT.Status.GetAlternative(ws); if (!String.IsNullOrEmpty(origStatus) && origStatus != sUnfinished) { originalBT.Status.SetAlternative(sUnfinished, ws); } } } continue; } ITsString newFt = bldr.GetString(); ICmTranslation trans; if (newFt.Length == 0) { trans = para.GetBT(); if (trans == null) { return; // don't bother creating one to store an empty translation! } } else { trans = para.GetOrCreateBT(); } // Don't write unless it changed...PropChanged can be expensive. if (!trans.Translation.GetAlternative(ws).UnderlyingTsString.Equals(newFt)) { trans.Translation.SetAlternative(newFt, ws); trans.Status.SetAlternative(sUnfinished, ws); } } }