/// ------------------------------------------------------------------------------------ /// <summary> /// Go to the previous footnote in the footnote view /// </summary> /// <returns></returns> /// ------------------------------------------------------------------------------------ public override ScrFootnote GoToPreviousFootnote() { CheckDisposed(); // In case no footnote is selected - can happen when footnote pane is first opened. if (CurrentSelection == null) { return(null); } // Get the information needed from the current selection int iBook = CurrentSelection.GetLevelInfoForTag(BookFilter.Tag).ihvo; int iFootnote = CurrentSelection.GetLevelInfoForTag((int)ScrBook.ScrBookTags.kflidFootnotes).ihvo; ScrBook book = BookFilter.GetBook(iBook); // Get the previous footnote if it exists if (--iFootnote < 0) { return(null); } ScrFootnote footnote = new ScrFootnote(m_cache, book.FootnotesOS.HvoArray[iFootnote]); ScrollToFootnote(iBook, iFootnote, 0); return(footnote); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Write the first paragraph in the given footnote. (TE allows only 1 paragraph in /// footnotes!) /// </summary> /// ------------------------------------------------------------------------------------ private void ExportFootnote(ScrFootnote foot) { IStTxtPara para = foot.ParagraphsOS[0] as IStTxtPara; string sStyle = para.StyleName; if (String.IsNullOrEmpty(sStyle)) { sStyle = "scrFootnote"; } else { sStyle = m_xhtml.GetValidCssClassName(sStyle); } ITsStrBldr bldr = foot.MakeFootnoteMarker(m_cache.DefaultVernWs); string sFootnoteMarker = bldr.Text; ITsString tssPara = para.Contents.UnderlyingTsString; m_writer.WriteLine("<span class=\"{0}\" id=\"{1}\" title=\"{2}\">", sStyle, "F" + foot.Guid.ToString().ToUpperInvariant(), sFootnoteMarker); m_xhtml.MapCssToLang(sStyle, LanguageCode(StringUtils.GetWsAtOffset(tssPara, 0))); WriteTsStringAsXml(tssPara, 4); m_writer.WriteLine("</span>"); // The following class is inserted by the XSLT processing. m_xhtml.MapCssToLang("scrFootnoteMarker", LanguageCode(m_cache.DefaultVernWs)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Creates a blank dummy footnote. Used when a footnote object is missing. /// Note: This does not insert an ORC into the paragraph. The caller is fixing the ORC /// with a missing object. /// </summary> /// <param name="owner">The owner to which we will add a footnote.</param> /// <param name="iFootnote">The 0-based index where the footnote will be inserted in the /// owner.</param> /// <param name="paraContents">The paragraph string where the ORC is being fixed.</param> /// <param name="iRun">The 0-based index of the run from which we will get the writing /// system used in the footnote.</param> /// <returns>a blank general footnote</returns> /// ------------------------------------------------------------------------------------ protected override StFootnote CreateBlankDummyFootnoteNoRecursion(ICmObject owner, int iFootnote, ITsString paraContents, int iRun) { if (!(owner is IScrBook)) { return(base.CreateBlankDummyFootnoteNoRecursion(owner, iFootnote, paraContents, iRun)); } // get the writing system of the existing ORC run int nDummy; int ws = paraContents.get_Properties(iRun).GetIntPropValues( (int)FwTextPropType.ktptWs, out nDummy); // Make a dummy blank footnote IScripture scr = m_cache.LangProject.TranslatedScriptureOA; string sMarker = scr.GeneralFootnoteMarker; StFootnote newFootnote = ScrFootnote.CreateFootnoteInScrBook((IScrBook)owner, iFootnote, ref sMarker, m_cache, ws); // Create an empty footnote paragraph with properties with default style and writing system. StTxtPara footnotePara = new StTxtPara(); newFootnote.ParagraphsOS.Append(footnotePara); footnotePara.StyleRules = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalFootnoteParagraph); // Insert an empty run into the footnote paragraph in order to set the // default writing system. ITsStrFactory strFactory = TsStrFactoryClass.Create(); footnotePara.Contents.UnderlyingTsString = strFactory.MakeString(string.Empty, m_cache.DefaultVernWs); return(newFootnote); }
/// ------------------------------------------------------------------------------------ /// <summary> /// /// </summary> /// ------------------------------------------------------------------------------------ protected override void CreateTestData() { ITsStrFactory strfact = TsStrFactoryClass.Create(); //Jude IScrBook jude = m_scrInMemoryCache.AddBookToMockedScripture(65, "Jude"); m_scrInMemoryCache.AddTitleToMockedBook(jude.Hvo, "Jude"); // Jude Scripture section IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(jude.Hvo); m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "First section", "Section Head"); StTxtPara judePara = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, "Paragraph"); m_scrInMemoryCache.AddRunToMockedPara(judePara, "1", ScrStyleNames.ChapterNumber); m_scrInMemoryCache.AddRunToMockedPara(judePara, "1", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(judePara, "This is the first verse", null); // Insert footnote into para 1 of Jude ITsStrBldr bldr = judePara.Contents.UnderlyingTsString.GetBldr(); StFootnote foot = ScrFootnote.InsertFootnoteAt(jude, 0, bldr, 10, "#"); StTxtPara footPara = new StTxtPara(); foot.ParagraphsOS.Append(footPara); footPara.StyleRules = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalFootnoteParagraph); footPara.Contents.UnderlyingTsString = strfact.MakeString("This is text for the footnote.", Cache.DefaultVernWs); judePara.Contents.UnderlyingTsString = bldr.GetString(); section.AdjustReferences(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Loads the footnotes. /// </summary> /// <param name="footnoteHvo">The footnote hvo.</param> /// ------------------------------------------------------------------------------------ private void LoadFootnotes(int footnoteHvo) { Debug.Assert(m_cache.GetClassOfObject(footnoteHvo) == StFootnote.kClassId); StFootnote foot = new StFootnote(m_cache, footnoteHvo); IScrBook book = new ScrBook(m_cache, foot.OwnerHVO); int footnoteCount = GetBookFootnoteCount(book.Hvo); FdoOwningSequence <IStFootnote> footnotes = book.FootnotesOS; // If the information we want is already in the cache, then do nothing if (footnotes.Count == footnoteCount && m_htFootnoteIndex.ContainsKey(footnoteHvo)) { return; } ScrFootnote footnote = null; int index = 0; for (int i = 0; i < footnotes.Count; i++) { footnote = new ScrFootnote(m_cache, footnotes.HvoArray[i]); if (footnote.FootnoteType == FootnoteMarkerTypes.AutoFootnoteMarker) { int oldIndex = GetFootnoteIndex(footnote.Hvo); if (oldIndex != index) { m_htFootnoteIndex[footnote.Hvo] = new FootnoteIndexCacheInfo(index, true); } index++; } } m_htBookFootnoteCount[book.Hvo] = footnotes.Count; }
public void DeleteFootnoteFromContextMenuRangeSelection() { CheckDisposed(); SelectionHelper selHelper = new SelectionHelper(); selHelper.AssocPrev = true; selHelper.NumberOfLevels = 3; SelLevInfo[] anchorLevInfo = new SelLevInfo[3]; anchorLevInfo[2].tag = m_footnoteView.BookFilter.Tag; anchorLevInfo[2].ihvo = 1; anchorLevInfo[1].tag = (int)ScrBook.ScrBookTags.kflidFootnotes; anchorLevInfo[1].ihvo = 2; anchorLevInfo[0].tag = (int)StText.StTextTags.kflidParagraphs; anchorLevInfo[0].ihvo = 0; selHelper.SetLevelInfo(SelectionHelper.SelLimitType.Anchor, anchorLevInfo); selHelper.IchAnchor = 1; SelLevInfo[] endLevInfo = new SelLevInfo[3]; endLevInfo[2].tag = m_footnoteView.BookFilter.Tag; endLevInfo[2].ihvo = 1; endLevInfo[1].tag = (int)ScrBook.ScrBookTags.kflidFootnotes; endLevInfo[1].ihvo = 6; endLevInfo[0].tag = (int)StText.StTextTags.kflidParagraphs; endLevInfo[0].ihvo = 0; selHelper.SetLevelInfo(SelectionHelper.SelLimitType.End, endLevInfo); selHelper.IchEnd = 7; // Now that all the preparation to set the selection is done, set it. selHelper.SetSelection(m_footnoteView, true, true); Application.DoEvents(); // First get the footnotes we're deleting. ScrFootnote[] footnotes = new ScrFootnote[5]; Guid[] guidFootnotes = new Guid[5]; int[] hvoParas = new int[5]; for (int i = 0; i < 5; i++) { footnotes[i] = new ScrFootnote(Cache, m_Jude.FootnotesOS.HvoArray[i + 2]); guidFootnotes[i] = Cache.GetGuidFromId(footnotes[i].Hvo); hvoParas[i] = footnotes[i].ContainingParagraphHvo; } m_footnoteView.DeleteFootnote(); foreach (ScrFootnote footnote in footnotes) { Assert.IsFalse(Cache.IsRealObject(footnote.Hvo, StFootnote.kClassId)); } // now make sure that we don't find the footnote markers for (int i = 0; i < 5; i++) { VerifyRemovedFootnoteMarker(hvoParas[i], guidFootnotes[i]); VerifyRemovedFootnoteMarker(hvoParas[i], guidFootnotes[i], InMemoryFdoCache.s_wsHvos.En); VerifyRemovedFootnoteMarker(hvoParas[i], guidFootnotes[i], InMemoryFdoCache.s_wsHvos.De); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Deletes a footnote /// </summary> /// <param name="args"></param> /// <returns><c>true</c> if we handle this</returns> /// ------------------------------------------------------------------------------------ protected bool OnDeleteFootnote(object args) { if (DataUpdateMonitor.IsUpdateInProgress(DataAccess)) { return(true); //discard this event } if (!ValidFootnoteSelection) { return(true); } string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidUndoDelFootnote", out undo, out redo); using (new UndoTaskHelper(this, undo, redo, false)) using (new DataUpdateMonitor(this, RootBox.DataAccess, this, "DeleteFootnote")) { SelectionHelper helper = SelectionHelper.Create(this); int fnLevel = helper.GetLevelForTag((int)ScrBook.ScrBookTags.kflidFootnotes); if (helper.Selection.IsRange) { DeleteFootnoteRange(helper); } else { // There's no range selection, so delete only one footnote ScrFootnote footnote = new ScrFootnote(m_fdoCache, helper.LevelInfo[fnLevel].hvo); ScrFootnote.DeleteFootnoteAndMarker(footnote); } if (RootBox.Height <= 0) { DraftView.Focus(); } else { int iBook = helper.LevelInfo[fnLevel + 1].ihvo; ScrBook book = m_bookFilter.GetBook(iBook); int iFootnote = helper.LevelInfo[fnLevel].ihvo; // If the last footnote in the book was deleted find a footnote to move to if (iFootnote >= book.FootnotesOS.Count) { FindNearestFootnote(ref iBook, ref iFootnote); } FootnoteEditingHelper.ScrollToFootnote(iBook, iFootnote, 0); } } return(true); }
public void GoToNextFootnote_AtLastFootnote() { CheckDisposed(); IScrBook philemon; StFootnote footnote1, footnote2; CreateBookWithTwoFootnotes(out philemon, out footnote1, out footnote2); m_editingHelper.SetupSelectionInFootnote(footnote2, philemon, 0, 0, 0); ScrFootnote nextfootnote = m_editingHelper.GoToNextFootnote(); Assert.IsNull(nextfootnote, "Footnote was found when it should not have been"); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Display the footnote marker. /// </summary> /// <param name="vwenv">View environment</param> /// <param name="footnote">The footnote.</param> /// ------------------------------------------------------------------------------------ private void DisplayFootnoteMarker(IVwEnv vwenv, ScrFootnote footnote) { vwenv.NoteDependency(new int[] { footnote.Hvo }, new int[] { (int)StFootnote.StFootnoteTags.kflidFootnoteMarker }, 1); // The footnote marker is not editable. vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); ITsStrBldr strBldr = footnote.MakeFootnoteMarker(DefaultWs); strBldr.Replace(strBldr.Length, strBldr.Length, " ", null); vwenv.AddString(strBldr.GetString()); }
public void GoToNextFootnote_FirstFootnote() { CheckDisposed(); IScrBook philemon; StFootnote footnote1, footnote2; CreateBookWithTwoFootnotes(out philemon, out footnote1, out footnote2); m_editingHelper.SetupSelectionInFootnote(footnote1, philemon, 0, 0, 0); ScrFootnote nextfootnote = m_editingHelper.GoToNextFootnote(); Assert.IsNotNull(nextfootnote, "Couldn't find footnote"); Assert.AreEqual(philemon.FootnotesOS.HvoArray[1], nextfootnote.Hvo); }
public void GoToPreviousFootnote_AtFirstFootnote() { CheckDisposed(); IScrBook philemon; StFootnote footnote1, footnote2; CreateBookWithTwoFootnotes(out philemon, out footnote1, out footnote2); // set the selection to the first footnote and go to previous. There are // none so it should return null m_editingHelper.SetupSelectionInFootnote(footnote1, philemon, 0, 0, 0); ScrFootnote prevfootnote = m_editingHelper.GoToPreviousFootnote(); Assert.IsNull(prevfootnote); }
public void GoToPreviousFootnote_LastFootnote() { CheckDisposed(); IScrBook philemon; StFootnote footnote1, footnote2; CreateBookWithTwoFootnotes(out philemon, out footnote1, out footnote2); // set the selection to the second footnote and go to previous. The footnote // should be the first footnote. m_editingHelper.SetupSelectionInFootnote(footnote2, philemon, 0, 0, 0); ScrFootnote prevfootnote = m_editingHelper.GoToPreviousFootnote(); Assert.AreEqual(footnote1.Hvo, prevfootnote.Hvo); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Deletes footnotes when there is a range selection. /// </summary> /// <param name="helper"></param> /// ------------------------------------------------------------------------------------ private void DeleteFootnoteRange(SelectionHelper helper) { int nTopLevels = helper.GetNumberOfLevels(SelectionHelper.SelLimitType.Top); int nBottomLevels = helper.GetNumberOfLevels(SelectionHelper.SelLimitType.Bottom); // Get the index of the book containing the first footnote in the selection. // Then get the index of the footnote within that book. int iFirstBook = helper.GetLevelInfo(SelectionHelper.SelLimitType.Top)[nTopLevels - 1].ihvo; int iFirstFootnote = helper.GetLevelInfo(SelectionHelper.SelLimitType.Top)[nTopLevels - 2].ihvo; // Get the index of the book containing the last footnote in the selection. // Then get the index of the footnote within that book. int iLastBook = helper.GetLevelInfo(SelectionHelper.SelLimitType.Bottom)[nBottomLevels - 1].ihvo; int iLastFootnote = helper.GetLevelInfo(SelectionHelper.SelLimitType.Bottom)[nBottomLevels - 2].ihvo; // Loop through the books containing footnotes in the selection. for (int iBook = iFirstBook; iBook <= iLastBook; iBook++) { ScrBook book = BookFilter.GetBook(iBook); int iBeg = iFirstFootnote; if (iFirstBook != iLastBook && iBook > iFirstBook) { iBeg = 0; } int iEnd = iLastFootnote; if (iFirstBook != iLastBook && iBook < iLastBook) { iEnd = book.FootnotesOS.Count - 1; } // Loop through the footnotes from the selection that are in the // current book. Go in reverse order through the collection. for (int i = iEnd; i >= iBeg; i--) { // TODO: check filter for each HVO ScrFootnote footnote = new ScrFootnote(m_fdoCache, book.FootnotesOS[i].Hvo); ScrFootnote.DeleteFootnoteAndMarker(footnote); } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// /// </summary> /// <param name="hvoBook">The hvo of the book containing the footnotes</param> /// <param name="ivMin">The index in the vector of the change</param> /// <param name="cvIns">the number of footnotes inserted</param> /// <param name="cvDel">the number of footnotes deleted</param> /// ------------------------------------------------------------------------------------ protected override void DoEffectsOfPropChange(int hvoBook, int ivMin, int cvIns, int cvDel) { bool fNeedToRecalculate = true; ScrBook book = new ScrBook(m_cache, hvoBook); if (cvIns > 0) { // if we inserted, we only need to recalculate the markers if the inserted footnote // offset the auto-lettering. Debug.Assert(ivMin < book.FootnotesOS.Count); ScrFootnote footnoteIns = new ScrFootnote(m_cache, book.FootnotesOS.HvoArray[ivMin]); fNeedToRecalculate = (footnoteIns.FootnoteType == FootnoteMarkerTypes.AutoFootnoteMarker); } if (fNeedToRecalculate) { ScrFootnote.RecalculateFootnoteMarkers(book, ivMin); } }
public void DeleteFootnoteInRangeSelectionAcrossMultipleBooks() { SetupSelectionForRangeAcrossBooks(); IScripture scr = m_cache.LangProject.TranslatedScriptureOA; ScrFootnote[] footnotes = new ScrFootnote[4]; Guid[] guidFootnotes = new Guid[4]; int[] hvoParas = new int[4]; // First get the footnotes we're deleting from JAMES. IScrBook book = (IScrBook)scr.ScriptureBooksOS[1]; footnotes[0] = new ScrFootnote(m_cache, book.FootnotesOS.HvoArray[31]); footnotes[1] = new ScrFootnote(m_cache, book.FootnotesOS.HvoArray[32]); // First get the footnotes we're deleting from JUDE. book = (IScrBook)scr.ScriptureBooksOS[2]; footnotes[2] = new ScrFootnote(m_cache, book.FootnotesOS.HvoArray[0]); footnotes[3] = new ScrFootnote(m_cache, book.FootnotesOS.HvoArray[1]); for (int i = 0; i < 4; i++) { guidFootnotes[i] = m_cache.GetGuidFromId(footnotes[i].Hvo); hvoParas[i] = footnotes[i].ContainingParagraphHvo; } m_footnoteView.DeleteFootnote(); foreach (IStFootnote footnote in footnotes) { Assert.IsFalse(m_cache.IsRealObject(footnote.Hvo, StFootnote.kClassId)); } // now make sure that we don't find the footnote markers for (int i = 0; i < 4; i++) { Assert.IsFalse(IsFootnoteMarkerInText(hvoParas[i], guidFootnotes[i]), "Footnote marker didn't get deleted from text"); } }
public void DeleteFootnoteFromContextMenuIPSelection() { CheckDisposed(); MakeFootnoteSelection(1, 1, 1); // First get the footnote we're deleting. ScrFootnote footnote = new ScrFootnote(Cache, m_Jude.FootnotesOS.HvoArray[1]); Guid guidFootnote = Cache.GetGuidFromId(footnote.Hvo); // Find the paragraph that this footnote is in int hvoPara = footnote.ContainingParagraphHvo; m_footnoteView.DeleteFootnote(); Assert.IsFalse(Cache.IsRealObject(footnote.Hvo, StFootnote.kClassId)); // Now make sure that we don't find the footnote marker in the vern or either BT of // the para that used to contain it. VerifyRemovedFootnoteMarker(hvoPara, guidFootnote); VerifyRemovedFootnoteMarker(hvoPara, guidFootnote, InMemoryFdoCache.s_wsHvos.En); VerifyRemovedFootnoteMarker(hvoPara, guidFootnote, InMemoryFdoCache.s_wsHvos.De); }
/// ------------------------------------------------------------------------------------ /// <summary> /// This is the main interesting method of displaying objects and fragments of them. /// Scripture Footnotes are displayed by displaying each footnote's reference and text. /// The text is displayed using the standard view constructor for StText. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="frag"></param> /// ------------------------------------------------------------------------------------ public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); switch (frag) { case (int)FootnoteFrags.kfrScripture: { vwenv.NoteDependency(new int[] { m_cache.LangProject.TranslatedScriptureOAHvo }, new int[] { (int)Scripture.ScriptureTags.kflidScriptureBooks }, 1); vwenv.AddLazyVecItems(BooksTag, this, (int)FootnoteFrags.kfrBook); break; } case (int)FootnoteFrags.kfrRootInPageSeq: { int tag = DummyVirtualHandler.InstallDummyHandler(m_cache.VwCacheDaAccessor, "Scripture", "FootnotesOnPage", (int)CellarModuleDefns.kcptReferenceSequence).Tag; // Get the list of footnotes to display int[] hvos = m_cache.GetVectorProperty(hvo, tag, true); if (hvos.Length > 0) { int ownerHvo = m_cache.GetOwnerOfObject(hvos[0]); // The ownerHvo should be the HVO of the book vwenv.NoteDependency(new int[] { ownerHvo }, new int[] { (int)ScrBook.ScrBookTags.kflidFootnotes }, 1); } vwenv.AddObjVec(tag, this, (int)FootnoteFrags.kfrAllFootnotesWithinPagePara); break; } case (int)FootnoteFrags.kfrFootnoteWithinPagePara: { // Note a dependency on the footnote options so that the footnote will // be refreshed when these are changed. int[] depHvos = { hvo }; int[] depTags = { StFootnote.ktagFootnoteOptions }; vwenv.NoteDependency(depHvos, depTags, 1); // Insert the marker and reference vwenv.AddObj(hvo, this, (int)StTextFrags.kfrFootnoteMarker); vwenv.AddObj(hvo, this, (int)StTextFrags.kfrFootnoteReference); // Insert (we hope only one) paragraph contents. vwenv.AddObjVecItems((int)StText.StTextTags.kflidParagraphs, this, (int)FootnoteFrags.kfrFootnoteParaWithinPagePara); break; } case (int)FootnoteFrags.kfrFootnoteParaWithinPagePara: { if (!InsertParaContentsUserPrompt(vwenv, hvo)) { // Display the text paragraph contents, or its user prompt. vwenv.AddStringProp((int)StTxtPara.StTxtParaTags.kflidContents, null); } break; } case (int)FootnoteFrags.kfrBook: { vwenv.OpenDiv(); vwenv.AddObjVecItems((int)ScrBook.ScrBookTags.kflidFootnotes, this, (int)StTextFrags.kfrFootnote); vwenv.CloseDiv(); break; } case (int)StTextFrags.kfrFootnoteMarker: { ScrFootnote footnote = new ScrFootnote(Cache, hvo); if (footnote.DisplayFootnoteMarker) { DisplayFootnoteMarker(vwenv, footnote); } break; } case (int)StTextFrags.kfrFootnoteReference: { ITsStrFactory tsStrFactory = TsStrFactoryClass.Create(); ITsPropsFactory tpf = TsPropsFactoryClass.Create(); ITsTextProps ttp = tpf.MakeProps(ScrStyleNames.FootnoteTargetRef, m_wsDefault, 0); ScrFootnote footnote = new ScrFootnote(m_cache, hvo); string footnoteRef = footnote.GetReference(m_wsDefault); ITsString tssRef = tsStrFactory.MakeStringWithPropsRgch(footnoteRef, footnoteRef.Length, ttp); vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); vwenv.AddString(tssRef); break; } default: base.Display(vwenv, hvo, frag); break; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Get the start and end reference of the specified position <paramref name="ivPos"/> /// in the paragraph. Section reference could be used, if available, to fill in missing /// information, but (at least for now) we will not search back into previous sections. /// </summary> /// <param name="wsBT">HVO of the writing system of the BT to search, or -1 to search /// the vernacular.</param> /// <param name="ivPos">Character offset in the paragraph.</param> /// <param name="fAssocPrev">Consider this position to be associated with any preceding /// text in the paragraph (in the case where ichPos is at a chapter boundary).</param> /// <param name="refStart">[out] Start reference</param> /// <param name="refEnd">[out] End reference</param> /// <remarks><p><paramref name="refStart"/> and <paramref name="refEnd"/> are only /// different if we have bridged verse numbers.</p> /// <p>May return incomplete or invalid reference if, for example, the section /// object does not have a valid start reference.</p> /// <p>If ivPos LT zero, we will not search this para, but look only in previous /// paragraphs</p></remarks> /// ------------------------------------------------------------------------------------ public void GetBCVRefAtPosition(int wsBT, int ivPos, bool fAssocPrev, out BCVRef refStart, out BCVRef refEnd) { refStart = new BCVRef(); refEnd = new BCVRef(); // Might be trying to get the BCVRef in a footnote int ownerOwnFlid = m_cache.GetOwningFlidOfObject(OwnerHVO); if (ownerOwnFlid == (int)ScrBook.ScrBookTags.kflidFootnotes) { ScrFootnote footnote = new ScrFootnote(m_cache, OwnerHVO); refStart = footnote.StartRef; refEnd = footnote.StartRef; return; } BCVRef refStartT = new BCVRef(); BCVRef refEndT = new BCVRef(); ChapterVerseFound found = ChapterVerseFound.None; bool fGotVerse = false; ScrTxtPara para = this; // curent paragraph being examined for reference int chvoParas = 0; // count of paragraphs in the section int ihvoPara = 0; // index of the paragraph within the section BCVRef sectRefStart; BCVRef sectRefEnd; GetSectionStartAndEndRefs(out sectRefStart, out sectRefEnd); while (true) { if (para == this) { found = para.GetBCVRefAtPosWithinPara(wsBT, ivPos, fAssocPrev, out refStartT, out refEndT); } else { found = para.GetBCVRefAtEndOfPara(out refStartT, out refEndT); } // if we found a verse, remember it if (!fGotVerse && ((found & ChapterVerseFound.Verse) != 0)) { refStart.Verse = refStartT.Verse; refEnd.Verse = refEndT.Verse; fGotVerse = true; } // if we found a chapter, process it if ((found & ChapterVerseFound.Chapter) != 0) { if (sectRefStart != null && !sectRefStart.IsEmpty) { refStart.Book = refEnd.Book = sectRefStart.Book; //may not exist } refStart.Chapter = refEnd.Chapter = refStartT.Chapter; // GetBCVwithinPara always returns a verse if it finds a chapter number // so we have already built the full reference Debug.Assert(fGotVerse); return; } // We got to the beginning of the paragraph being edited and still haven't // found a decent reference for our edited text, so keep looking back to // get it from a previous paragraph. // First time thru, figure out which paragraph we are in if (chvoParas == 0) { // REVIEW (EberhardB): does this work if not all paragraphs are // loaded in the cache? chvoParas = m_cache.GetVectorSize(OwnerHVO, (int)StText.StTextTags.kflidParagraphs); // Go forward through vector of paragraphs to find the one being parsed for (ihvoPara = 0; ihvoPara < chvoParas; ihvoPara++) { int hvoPara = m_cache.GetVectorItem(OwnerHVO, (int)StText.StTextTags.kflidParagraphs, ihvoPara); if (hvoPara == Hvo) { break; // found our current para } } } // Move to the previous paragraph ihvoPara--; if (ihvoPara < 0) { // We are at the beginning of the section. We can't look back any further. // ENHANCE TomB: If we search all the way through to the beginning of the // section and never get a valid reference, this section begins in the // middle of a verse or chapter (unlikely in the case of a verse, but // quite likely in the case of a chapter). OR (most likely) this edit // happened at the very beginning of the section, and when we start // parsing, the first thing we'll get is a decent reference. // REVIEW: we're using the section reference, but since they don't get // updated, a change (like removing a chapter) in a previous section // could mess up this section. if (fGotVerse) { // Use the verse we got previously (already set), along with the // first chapter for the section and the book, if available. if (sectRefStart != 0) { refStart.Chapter = refEnd.Chapter = sectRefStart.Chapter; refStart.Book = refEnd.Book = sectRefStart.Book; } } else { // REVIEW: // For now, we're just using the first verse for the section, but this // could be wrong if the section begins in the middle of a verse bridge // or misleading if the section just doesn't yet have verse numbers // marked. if (sectRefStart != 0) { refStart = new BCVRef(sectRefStart); refEnd = new BCVRef(sectRefStart); } // If we are looking for a negative position in the first para of a section // the needed result is not precisely defined yet, // but this is where you could set it // if (para == this && ivPos < 0) // refStart.Verse = refEnd.Verse = ????; } return; } // Set up for the previous paragraph in this section, and we'll try again int hvoNewPara = m_cache.GetVectorItem(OwnerHVO, (int)StText.StTextTags.kflidParagraphs, ihvoPara); // use a special constructor since we already know the section refs para = new ScrTxtPara(m_cache, hvoNewPara, false, false); } }
/// <summary> /// Load sections into the books of a scripture tree view optionally including the /// heading as well as the content of each section. /// </summary> /// <param name="cache"></param> /// <param name="fIncludeHeadings"></param> public void LoadSections(FdoCache cache, bool fIncludeHeadings) { try { cache.EnableBulkLoadingIfPossible(true); // first load the book ids. this.Nodes.Clear(); this.LoadBooks(cache); TreeNode bibleNode; if (this.Nodes.Count == 1) { bibleNode = this.Nodes[0]; } else if (this.Nodes.Count > 0) { throw new ArgumentException("We should only have 1 Bible node, not " + this.Nodes.Count); } else { return; } if (cache.LangProject.TranslatedScriptureOA == null) { return; } Scripture scripture = cache.LangProject.TranslatedScriptureOA as Scripture; foreach (TreeNode testament in bibleNode.Nodes) { foreach (TreeNode bookNode in testament.Nodes) { IScrBook book = ScrBook.CreateFromDBObject(cache, (int)bookNode.Tag) as IScrBook; // Add Title node. if (book.TitleOAHvo != 0) { TreeNode titleNode = new TreeNode(ResourceHelper.GetResourceString("kstidScriptureTitle")); titleNode.Name = book.TitleOAHvo.ToString(); titleNode.Tag = book.TitleOAHvo; bookNode.Nodes.Add(titleNode); } // Add Sections. foreach (IScrSection section in book.SectionsOS) { string chapterVerseBridge = scripture.ChapterVerseBridgeAsString(section); if (fIncludeHeadings && section.HeadingOAHvo != 0) { // Include the heading text if it's not empty. See LT-8764. int cTotal = 0; foreach (IStTxtPara para in section.HeadingOA.ParagraphsOS) { cTotal += para.Contents.Length; } if (cTotal > 0) { string sFmt = ResourceHelper.GetResourceString("kstidSectionHeading"); TreeNode node = new TreeNode(String.Format(sFmt, chapterVerseBridge)); node.Name = String.Format(sFmt, section.Hvo.ToString()); node.Tag = section.HeadingOAHvo; // expect an StText bookNode.Nodes.Add(node); } } TreeNode sectionNode = new TreeNode(chapterVerseBridge); sectionNode.Name = section.Hvo.ToString(); sectionNode.Tag = section.ContentOAHvo; // expect an StText bookNode.Nodes.Add(sectionNode); } // Add Footnotes in reverse order, so we can insert them in the proper order. List <IStFootnote> footnotes = new List <IStFootnote>(book.FootnotesOS); footnotes.Reverse(); foreach (IStFootnote footnote in footnotes) { ScrFootnote scrFootnote = footnote as ScrFootnote; if (scrFootnote == null) { scrFootnote = new ScrFootnote(cache, footnote.Hvo); } // insert under the relevant section, if any (LTB-408) int hvoContainingObj; if (scrFootnote.TryGetContainingSectionHvo(out hvoContainingObj) || scrFootnote.TryGetContainingTitle(out hvoContainingObj)) { string nodeName = scripture.ContainingRefAsString(scrFootnote); TreeNode footnoteNode = new TreeNode(nodeName); footnoteNode.Tag = footnote.Hvo; footnoteNode.Name = "Footnote"; // see if we can lookup the node of this section. int nodeIndex = bookNode.Nodes.IndexOfKey(hvoContainingObj.ToString()); //TreeNode[] sectionNodes = bookNode.Nodes.Find(hvoSection.ToString(), false); //if (sectionNodes != null && sectionNodes.Length > 0) if (nodeIndex >= 0) { bookNode.Nodes.Insert(nodeIndex + 1, footnoteNode); } else { bookNode.Nodes.Add(footnoteNode); // insert at end. } } } } } } finally { cache.EnableBulkLoadingIfPossible(false); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Call the ExportFootnote method /// </summary> /// <param name="footnote">The footnote.</param> /// <param name="wsBt">The writing system of the back translation to export.</param> /// ------------------------------------------------------------------------------------ public void CallExportFootnote(ScrFootnote footnote, int wsBt) { m_rtfStyleTable.ConnectStyles(); base.ExportFootnote(footnote, wsBt); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adds the overrides to highlight a footnote diff. /// </summary> /// <param name="hvo">The hvo of the footnote paragraph.</param> /// ------------------------------------------------------------------------------------ private void AddOverridesToHighlightFootnoteDiff(int hvo) { Difference diff = FindSubDiffForFootnote(hvo); if (diff == null) { return; } StTxtPara para = new StTxtPara(Cache, hvo); // Get the footnote which contains the paragraph. int ownerHvo = para.OwnerHVO; Debug.Assert(m_cache.GetClassOfObject(ownerHvo) == StFootnote.kClassId); if (m_cache.GetClassOfObject(ownerHvo) != StFootnote.kClassId) { return; //don't override the props for this para; continue on gracefully } ScrFootnote footnote = new ScrFootnote(Cache, ownerHvo); // Only add offset to first paragraph in footnote (should only be one para) int offset = 0; if (footnote.ParagraphsOS[0].Hvo == hvo) { int refLength = footnote.GetReference(m_wsDefault).Length; int markerLength = footnote.FootnoteMarker.Length; //add one for the space in between (added in StVc) offset = refLength + markerLength + 1; } const uint knNinch = 0x80000000; // Now add appropriate properties. // Need to add override properties for each run in the // range to be highlighted. int ichOverrideMin = diff.GetIchMin(m_fRev); ITsString tss = para.Contents.UnderlyingTsString; TsRunInfo runInfo; int ichOverrideLim; int prevLim = 0; do { tss.FetchRunInfoAt(ichOverrideMin, out runInfo); ichOverrideLim = Math.Min(diff.GetIchLim(m_fRev), runInfo.ichLim); // Prevent infinite loop in case of bad data in difference if (ichOverrideLim == prevLim) { break; } prevLim = ichOverrideLim; DispPropOverride prop = new DispPropOverride(); prop.chrp.clrBack = DiffViewVc.kHighlightColor; prop.chrp.clrFore = knNinch; prop.chrp.clrUnder = knNinch; prop.chrp.dympOffset = -1; prop.chrp.ssv = -1; prop.chrp.unt = -1; prop.chrp.ttvBold = -1; prop.chrp.ttvItalic = -1; prop.chrp.dympHeight = -1; prop.chrp.szFaceName = null; prop.chrp.szFontVar = null; prop.ichMin = ichOverrideMin + offset; prop.ichLim = ichOverrideLim + offset; m_DispPropOverrides.Add(prop); ichOverrideMin = ichOverrideLim; }while (ichOverrideLim < diff.GetIchLim(m_fRev)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// This is the main interesting method of displaying objects and fragments of them. /// A Scripture is displayed by displaying its Books; /// and a Book is displayed by displaying its Title and Sections; /// and a Section is diplayed by displaying its Heading and Content; /// which are displayed by using the standard view constructor for StText. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="frag"></param> /// <returns><c>true</c> if we dealt with the display, otherwise <c>false</c></returns> /// ------------------------------------------------------------------------------------ public bool Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case (int)FootnoteFrags.kfrScripture: case (int)ScrFrags.kfrScripture: { // This fragment should only be used on full refresh - clear the user prompt // flags so they will be shown again. m_RealVc.ClearUserPromptUpdates(); // We add this lazy - we will expand some of it immediately, but the non- // visible parts will remain lazy! vwenv.NoteDependency(new int[] { m_cache.LangProject.TranslatedScriptureOAHvo }, new int[] { (int)Scripture.ScriptureTags.kflidScriptureBooks }, 1); vwenv.AddLazyVecItems(m_bookTag, m_RealVc, frag == (int)ScrFrags.kfrScripture ? (int)ScrFrags.kfrBook : (int)FootnoteFrags.kfrBook); break; } case (int)ScrFrags.kfrBook: { vwenv.OpenDiv(); vwenv.AddObjProp((int)ScrBook.ScrBookTags.kflidTitle, m_RealVc, (int)StTextFrags.kfrText); vwenv.NoteDependency(new int[] { hvo }, new int[] { (int)ScrBook.ScrBookTags.kflidSections }, 1); vwenv.AddLazyVecItems((int)ScrBook.ScrBookTags.kflidSections, m_RealVc, (int)ScrFrags.kfrSection); vwenv.CloseDiv(); break; } case (int)FootnoteFrags.kfrBook: { vwenv.OpenDiv(); vwenv.AddObjVecItems((int)ScrBook.ScrBookTags.kflidFootnotes, m_RealVc, (int)StTextFrags.kfrFootnote); vwenv.CloseDiv(); break; } case (int)ScrFrags.kfrSection: { vwenv.OpenDiv(); vwenv.AddObjProp((int)ScrSection.ScrSectionTags.kflidHeading, m_RealVc, (int)StTextFrags.kfrText); vwenv.AddObjProp((int)ScrSection.ScrSectionTags.kflidContent, m_RealVc, (int)StTextFrags.kfrText); vwenv.CloseDiv(); break; } case (int)StTextFrags.kfrPara: case (int)StTextFrags.kfrFootnotePara: { // Open a table to display the vern para in column 1, and the BT para in column 2. VwLength vlTable; vlTable.nVal = 10000; vlTable.unit = VwUnit.kunPercent100; VwLength vlColumn; vlColumn.nVal = 5000; vlColumn.unit = VwUnit.kunPercent100; int nColumns = 2; vwenv.OpenTable(nColumns, // One or two columns. vlTable, // Table uses 100% of available width. 0, // Border thickness. VwAlignment.kvaLeft, // Default alignment. VwFramePosition.kvfpVoid, // No border. VwRule.kvrlNone, 0, //No space between cells. 0, //No padding inside cells. true); // Specify column widths. The first argument is the number of columns, // not a column index. vwenv.MakeColumns(nColumns, vlColumn); vwenv.OpenTableBody(); vwenv.OpenTableRow(); if (m_RealVc.RightToLeft) { AddBtParagraph(vwenv, hvo, frag, false); AddVernParagraph(vwenv, hvo, frag, true); } else { AddVernParagraph(vwenv, hvo, frag, false); AddBtParagraph(vwenv, hvo, frag, true); } // Close table vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); break; } case (int)StTextFrags.kfrFootnoteReference: { ITsStrFactory tsStrFactory = TsStrFactoryClass.Create(); ScrFootnote footnote = new ScrFootnote(m_cache, hvo); ITsString tssRef = tsStrFactory.MakeString(footnote.GetReference(m_RealVc.DefaultWs), m_RealVc.DefaultWs); vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); vwenv.AddString(tssRef); break; } default: return(false); } return(true); }
/// ------------------------------------------------------------------------------------ /// <summary> /// /// </summary> /// ------------------------------------------------------------------------------------ protected override void CreateTestData() { ITsStrFactory strfact = TsStrFactoryClass.Create(); //James IScrBook book = m_scrInMemoryCache.AddBookToMockedScripture(59, "James"); m_scrInMemoryCache.AddTitleToMockedBook(book.Hvo, "James"); // James first section IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(book.Hvo); m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Paul tells people", "Section Head"); StTxtPara para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, "Paragraph"); m_scrInMemoryCache.AddRunToMockedPara(para, "1", "Chapter Number"); m_scrInMemoryCache.AddRunToMockedPara(para, "1", "Verse Number"); m_scrInMemoryCache.AddRunToMockedPara(para, "and the earth was without form and void and darkness covered the face of the deep", null); section.AdjustReferences(); // James section2 IScrSection section2 = m_scrInMemoryCache.AddSectionToMockedBook(book.Hvo); m_scrInMemoryCache.AddSectionHeadParaToSection(section2.Hvo, "Paul tells people more", "Section Head"); StTxtPara para2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section2.Hvo, "Paragraph"); m_scrInMemoryCache.AddRunToMockedPara(para2, "2", "Chapter Number"); m_scrInMemoryCache.AddRunToMockedPara(para2, "1", "Verse Number"); m_scrInMemoryCache.AddRunToMockedPara(para2, "paul expounds on the nature of reality", null); StTxtPara para3 = m_scrInMemoryCache.AddParaToMockedSectionContent(section2.Hvo, "Paragraph"); m_scrInMemoryCache.AddRunToMockedPara(para3, "2", "Verse Number"); m_scrInMemoryCache.AddRunToMockedPara(para3, "the existentialists are all wrong", null); // insert footnotes into para 2 of James ITsTextProps normalFootnoteParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalFootnoteParagraph); ITsStrBldr jamesBldr = para2.Contents.UnderlyingTsString.GetBldr(); int iFootIch = 10; for (int i = 0; i < 2; i++) { StFootnote foot = ScrFootnote.InsertFootnoteAt(book, i, jamesBldr, iFootIch, "a"); StTxtPara footPara = new StTxtPara(); foot.ParagraphsOS.Append(footPara); footPara.StyleRules = normalFootnoteParaProps; footPara.Contents.UnderlyingTsString = strfact.MakeString("This is footnote text for footnote " + i.ToString(), Cache.DefaultVernWs); iFootIch += 20; } para2.Contents.UnderlyingTsString = jamesBldr.GetString(); section2.AdjustReferences(); //Jude m_Jude = m_scrInMemoryCache.AddBookToMockedScripture(65, "Jude"); m_scrInMemoryCache.AddTitleToMockedBook(m_Jude.Hvo, "Jude"); //Jude intro section IScrSection judeSection = m_scrInMemoryCache.AddSectionToMockedBook(m_Jude.Hvo); m_scrInMemoryCache.AddSectionHeadParaToSection(judeSection.Hvo, "Introduction", "Intro Section Head"); StTxtPara judePara = m_scrInMemoryCache.AddParaToMockedSectionContent(judeSection.Hvo, "Intro Paragraph"); m_scrInMemoryCache.AddRunToMockedPara(judePara, "The Letter from Jude was written to warn against" + " false teachers who claimed to be believers. In this brief letter, which is similar in" + " content to 2 Peter the writer encourages his readers “to fight on for the faith which" + " once and for all God has given to his people.", null); judeSection.AdjustReferences(); // Insert BT (in two different writing systems) of intro paragraph ICmTranslation transEn = m_inMemoryCache.AddBtToMockedParagraph(judePara, InMemoryFdoCache.s_wsHvos.En); ICmTranslation transDe = m_inMemoryCache.AddBtToMockedParagraph(judePara, InMemoryFdoCache.s_wsHvos.De); // Jude Scripture section IScrSection judeSection2 = m_scrInMemoryCache.AddSectionToMockedBook(m_Jude.Hvo); m_scrInMemoryCache.AddSectionHeadParaToSection(judeSection2.Hvo, "First section", "Section Head"); StTxtPara judePara2 = m_scrInMemoryCache.AddParaToMockedSectionContent(judeSection2.Hvo, "Paragraph"); m_scrInMemoryCache.AddRunToMockedPara(judePara2, "1", ScrStyleNames.ChapterNumber); m_scrInMemoryCache.AddRunToMockedPara(judePara2, "1", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(judePara2, "This is the first verse", null); m_scrInMemoryCache.AddRunToMockedPara(judePara2, "2", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(judePara2, "This is the second verse", null); m_scrInMemoryCache.AddRunToMockedPara(judePara2, "3", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(judePara2, "This is the third verse", null); m_scrInMemoryCache.AddRunToMockedPara(judePara2, "4", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(judePara2, "This is the fourth verse", null); // Insert footnotes into para 1 of Jude ITsStrBldr bldr = judePara.Contents.UnderlyingTsString.GetBldr(); iFootIch = 10; for (int i = 0; i < 4; i++) { StFootnote foot = ScrFootnote.InsertFootnoteAt(m_Jude, i, bldr, iFootIch, "a"); StTxtPara footPara = new StTxtPara(); foot.ParagraphsOS.Append(footPara); footPara.StyleRules = normalFootnoteParaProps; footPara.Contents.UnderlyingTsString = strfact.MakeString("This is text for footnote " + i.ToString(), Cache.DefaultVernWs); iFootIch += 30; // Insert ORC for footnote into BT (in both writing systems) m_scrInMemoryCache.AddFootnoteORCtoTrans(transEn, i, InMemoryFdoCache.s_wsHvos.En, foot); m_scrInMemoryCache.AddFootnoteORCtoTrans(transDe, i, InMemoryFdoCache.s_wsHvos.De, foot); } judePara.Contents.UnderlyingTsString = bldr.GetString(); // Insert footnotes into para 2 of Jude bldr = judePara2.Contents.UnderlyingTsString.GetBldr(); iFootIch = 10; for (int i = 0; i < 4; i++) { StFootnote foot = ScrFootnote.InsertFootnoteAt(m_Jude, i + 4, bldr, iFootIch, "a"); StTxtPara footPara = new StTxtPara(); foot.ParagraphsOS.Append(footPara); footPara.StyleRules = normalFootnoteParaProps; footPara.Contents.UnderlyingTsString = strfact.MakeString("This is text for footnote " + (i + 4).ToString(), Cache.DefaultVernWs); iFootIch += 20; } judePara2.Contents.UnderlyingTsString = bldr.GetString(); judeSection2.AdjustReferences(); }