/// ------------------------------------------------------------------------------------ /// <summary> /// Insert a new check result annotation at its correct position in the list. /// </summary> /// <param name="startRef">beginning reference note refers to</param> /// <param name="endRef">ending reference note refers to</param> /// <param name="beginObject">id of beginning object note refers to</param> /// <param name="endObject">id of ending object note refers to</param> /// <param name="checkId">The check id.</param> /// <param name="bldrQuote">Para builder to use for the cited text paragraph</param> /// <param name="bldrDiscussion">Para builder to use to build the Discussion /// paragraph</param> /// <returns>note inserted into annotation list</returns> /// ------------------------------------------------------------------------------------ public IScrScriptureNote InsertErrorAnnotation(BCVRef startRef, BCVRef endRef, ICmObject beginObject, ICmObject endObject, Guid checkId, StTxtParaBldr bldrQuote, StTxtParaBldr bldrDiscussion) { return InsertNote(startRef, endRef, beginObject, endObject, checkId, -1, 0, 0, bldrQuote, bldrDiscussion, null, null, GetInsertIndexForRef(startRef)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Creates an empty paragraph with the given paragraph style and writing system. /// </summary> /// <param name="cache"></param> /// <param name="ownerHvo"></param> /// <param name="paraStyle"></param> /// <param name="ws"></param> /// ------------------------------------------------------------------------------------ public static void CreateEmptyPara(FdoCache cache, int ownerHvo, string paraStyle, int ws) { using (StTxtParaBldr bldr = new StTxtParaBldr(cache)) { bldr.ParaProps = StyleUtils.ParaStyleTextProps(paraStyle); bldr.AppendRun(String.Empty, StyleUtils.CharStyleTextProps(null, ws)); bldr.CreateParagraph(ownerHvo); } // Dispose() frees ICU resources. }
/// ------------------------------------------------------------------------------------ /// <summary> /// Use this method to move the adjacent part of one StText to the adjacent position /// in another. /// </summary> /// <param name="fromText">StText from which the contents is moved</param> /// <param name="toText">StText to which the contents is moved</param> /// <param name="divIndex">Index of last partial paragraph to be moved or the first /// whole paragraph not moved</param> /// <param name="ichDiv">character offset of last character to be moved or zero if /// none are to be moved</param> /// <param name="toIsPreceding">Should equal true if the toText preceeds the fromText. /// If true, the moved text will be appended to the toText. /// If false, they will be placed at the beginning of the toText.</param> /// ------------------------------------------------------------------------------------ public static void MovePartialContents(IStText fromText, IStText toText, int divIndex, int ichDiv, bool toIsPreceding) { int iLastFromPara = fromText.ParagraphsOS.Count - 1; Debug.Assert((divIndex >= 0) && (divIndex <= iLastFromPara)); // Set up parameters for whole paragraph movement based on direction of movement int iStartAt, iEndAt, iInsertAt, iReferenceEdge; if (toIsPreceding) { //From beginning to para preceding IP, appended iStartAt = 0; iEndAt = divIndex - 1; iInsertAt = toText.ParagraphsOS.Count; iReferenceEdge = 0; } else { //From para following IP to the end, pre-pended iStartAt = (ichDiv > 0) ? divIndex + 1 : divIndex; iEndAt = iLastFromPara; iInsertAt = 0; iReferenceEdge = iLastFromPara; } // Move the whole paragraphs of fromText to empty toText if (divIndex != iReferenceEdge || (ichDiv == 0 && !toIsPreceding)) { MoveWholeParas(fromText, iStartAt, iEndAt, toText, iInsertAt); } // Move partial paragraph (now in the edge paragraph of the fromText) // to a new paragraph in the toText if (ichDiv > 0 || toIsPreceding) { DivideParaContents(fromText, ichDiv, toText, toIsPreceding); } if (fromText.ParagraphsOS.Count == 0) { // We moved all of the paragraphs out of the existing section so we need to // create a new paragraph so the user can enter text StTxtPara newSectionFirstPara = (StTxtPara)toText.ParagraphsOS[0]; using (StTxtParaBldr bldr = new StTxtParaBldr(fromText.Cache)) { bldr.ParaProps = newSectionFirstPara.StyleRules; bldr.AppendRun(string.Empty, StyleUtils.CharStyleTextProps(null, fromText.Cache.DefaultVernWs)); bldr.CreateParagraph(fromText.Hvo); } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Use this method to move part of one StText to an adjacent one when the fromText /// must be left with at least one empty paragraph. /// </summary> /// <param name="fromText">StText from which the contents is moved</param> /// <param name="toText">StText to which the contents is moved. This StText should be /// empty.</param> /// <param name="divIndex">Index of last whole paragraph to be moved</param> /// <param name="toIsPreceding">Should equal true if the toText preceeds the fromText. /// If true, the moved paragraphs will be appended to the toText. /// If false, they will be placed at the beginning of the toText.</param> /// ------------------------------------------------------------------------------------ public static void MoveTextParagraphsAndFixEmpty(IStText fromText, IStText toText, int divIndex, bool toIsPreceding) { // Save the paragraph props. We might need it to create an empty paragraph. ITsTextProps paraPropsSave = ((StTxtPara)fromText.ParagraphsOS[divIndex]).StyleRules; MoveTextParagraphs(fromText, toText, divIndex, toIsPreceding); // If fromText is now empty, create a new empty paragraph. if (fromText.ParagraphsOS.Count == 0) { string styleName = paraPropsSave.GetStrPropValue((int)FwTextPropType.ktptNamedStyle); StTxtParaBldr.CreateEmptyPara(fromText.Cache, fromText.Hvo, styleName, fromText.Cache.DefaultVernWs); } }
public void ContentAllParasOfLastSectionToSectionHead() { CheckDisposed(); ITsTextProps textRunProps = StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs); ITsTextProps chapterRunProps = StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs); // create a book IScrBook book = CreateGenesis(); // Create section one IScrSection section1 = CreateSection(book, "My aching head!"); // create paragraph one holding chapter 1 StTxtParaBldr paraBldr = new StTxtParaBldr(Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("1", chapterRunProps); paraBldr.AppendRun("In the beginning", textRunProps); paraBldr.CreateParagraph(section1.ContentOAHvo); // create paragraph two holding text that really belongs in the section head paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("Ouch!", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(section1.ContentOAHvo); Assert.AreEqual(2, section1.ContentOA.ParagraphsOS.Count); // finish the section info section1.AdjustReferences(); // Create section two IScrSection section2 = CreateSection(book, "My other aching head!"); // create paragraph three holding chapter 2 paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("Thus the heavens", textRunProps); paraBldr.CreateParagraph(section2.ContentOAHvo); paraBldr.AppendRun("were completed", textRunProps); paraBldr.CreateParagraph(section2.ContentOAHvo); Assert.AreEqual(2, section2.ContentOA.ParagraphsOS.Count); // finish the section info section2.AdjustReferences(); m_draftView.RefreshDisplay(); // Set the IP at the beginning of the 2nd paragraph in the 1st section. int iBook = 0; // assume that iBook 0 is Genesis int iSectionIP = 1; //section with 2:1 to 2:1 int iParaIP = 0; int ichIP = 0; // Put the IP in place m_draftView.SetInsertionPoint(iBook, iSectionIP, iParaIP, ichIP, true); IVwSelection sel0 = m_draftView.RootBox.Selection; Assert.IsNotNull(sel0); m_draftView.SetInsertionPoint(iBook, iSectionIP, iParaIP + 1, ichIP, true); IVwSelection sel1 = m_draftView.RootBox.Selection; Assert.IsNotNull(sel1); IVwSelection sel = m_draftView.RootBox.MakeRangeSelection(sel0, sel1, true); Assert.IsNotNull(sel); // ApplyStyle should not create a new section, but should move paragraph // from content of section one to heading of section two m_draftView.ApplyStyle(ScrStyleNames.SectionHead); Assert.AreEqual(2, book.SectionsOS.Count, "Should not be combined sections"); // Verify verse start and end refs Assert.AreEqual(1001001, section2.VerseRefMin, "Remaining section should have same verse start ref"); Assert.AreEqual(1001001, section2.VerseRefMax, "Remaining section should have correct verse end ref"); // Verify paragraph counts of section 1 Assert.AreEqual(1, section1.HeadingOA.ParagraphsOS.Count); Assert.AreEqual(2, section1.ContentOA.ParagraphsOS.Count); // Verify section head of section 2 Assert.AreEqual(3, section2.HeadingOA.ParagraphsOS.Count); Assert.AreEqual("My other aching head!", ((StTxtPara)section2.HeadingOA.ParagraphsOS[0]).Contents.Text); ITsTextProps ttp = ((StTxtPara)section2.HeadingOA.ParagraphsOS[0]).StyleRules; Assert.AreEqual(ScrStyleNames.SectionHead, ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); Assert.AreEqual("Thus the heavens", ((StTxtPara)section2.HeadingOA.ParagraphsOS[1]).Contents.Text); ttp = ((StTxtPara)section2.HeadingOA.ParagraphsOS[1]).StyleRules; Assert.AreEqual(ScrStyleNames.SectionHead, ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); Assert.AreEqual("were completed", ((StTxtPara)section2.HeadingOA.ParagraphsOS[2]).Contents.Text); Assert.AreEqual(1, section2.ContentOA.ParagraphsOS.Count); StTxtPara para = (StTxtPara)section2.ContentOA.ParagraphsOS[0]; Assert.AreEqual(0, para.Contents.Length); // Verify that selection is in second paragraph of remaining section Assert.IsTrue(m_draftView.TeEditingHelper.InSectionHead, "Should be in section heading"); Assert.AreEqual(0, m_draftView.TeEditingHelper.BookIndex); Assert.AreEqual(1, m_draftView.TeEditingHelper.SectionIndex); Assert.AreEqual(1, m_draftView.ParagraphIndex); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Inserts a note referencing the currently selected paragraph. /// </summary> /// <param name="noteType">Type of note</param> /// <param name="startRef">reference at beginning of selection</param> /// <param name="endRef">reference at end of selection</param> /// <param name="topObj">The object where quoted text begins.</param> /// <param name="bottomObj">The object where quoted text ends.</param> /// <param name="wsSelector">The writing system selector.</param> /// <param name="startOffset">The starting character offset.</param> /// <param name="endOffset">The ending character offset.</param> /// <param name="tssQuote">The text of the quote.</param> /// <returns>The inserted note</returns> /// ------------------------------------------------------------------------------------ public virtual IScrScriptureNote InsertNote(ICmAnnotationDefn noteType, BCVRef startRef, BCVRef endRef, CmObject topObj, CmObject bottomObj, int wsSelector, int startOffset, int endOffset, ITsString tssQuote) { CheckDisposed(); TeNotesVc notesVc = CurrentNotesVc; IScrScriptureNote annotation; string sUndo, sRedo; int iPos; ScrBookAnnotations annotations = (ScrBookAnnotations)m_scr.BookAnnotationsOS[startRef.Book - 1]; TeResourceHelper.MakeUndoRedoLabels("kstidInsertAnnotation", out sUndo, out sRedo); string sType = noteType.Name.UserDefaultWritingSystem; sUndo = string.Format(sUndo, sType); sRedo = string.Format(sRedo, sType); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(m_cache.MainCacheAccessor, Control as IVwRootSite, sUndo, sRedo, false)) { try { StTxtParaBldr quoteParaBldr = new StTxtParaBldr(m_cache); quoteParaBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.Remark); quoteParaBldr.StringBuilder.ReplaceTsString(0, 0, tssQuote); annotation = annotations.InsertNote(startRef, endRef, topObj, bottomObj, noteType.Guid, wsSelector, startOffset, endOffset, quoteParaBldr, null, null, null, out iPos); if (notesVc != null) { // tell the VC that the newly inserted item should be expanded. That will cause // the view to be updated to show the new note. notesVc.ExpandItem(annotation.Hvo); notesVc.ExpandItem(annotation.DiscussionOAHvo); } } catch { undoTaskHelper.EndUndoTask = false; FwApp.App.RefreshAllViews(m_cache); throw; } } if (Control != null) Control.Focus(); // Make a selection in the discussion so the user can start to type if (notesVc != null && notesVc.NotesSequenceHandler != null) { // Get the corresponding index in the virtual property. iPos = notesVc.NotesSequenceHandler.GetVirtualIndex(annotations.Hvo, iPos); } IVwRootSite rootSite = Control as IVwRootSite; MakeSelectionInNote(notesVc, startRef.Book - 1, iPos, rootSite, true); // REVIEW: Do we need to create a synch record? return annotation; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Finalizes the title. If is empty, a single blank paragraph is written for /// whatever is missing. /// </summary> /// ------------------------------------------------------------------------------------ protected void FinalizePrevTitle() { if (m_cache == null || m_hvoTitle == 0) return; StText title = new StText(m_cache, m_hvoTitle); // First, check if there is content. If not, add a blank paragraph. if (title.ParagraphsOS.Count == 0) { StTxtParaBldr titleParaBldr = new StTxtParaBldr(m_cache); titleParaBldr.ParaStylePropsProxy = m_BookTitleParaProxy; titleParaBldr.CreateParagraph(m_hvoTitle); } m_fInBookTitle = false; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Finalizes section references and checks if the current section has any heading text /// and content. If not, a single blank paragraph is written for whatever is missing. /// </summary> /// ------------------------------------------------------------------------------------ protected void FinalizePrevSection() { if (m_currSection == null || !m_currSection.IsValidObject()) return; m_currSection.AdjustReferences(!m_fInScriptureText); int bcvRef = (m_firstImportedRef.IsEmpty) ? m_currSection.VerseRefMin : Math.Min(m_firstImportedRef, m_currSection.VerseRefMin); m_firstImportedRef = new ScrReference(bcvRef, m_scr.Versification); if (InMainImportDomain) return; // First, check if there is heading content. If not, add a blank paragraph. if (m_currSection.HeadingOA.ParagraphsOS.Count == 0) { StTxtParaBldr paraBldr = new StTxtParaBldr(m_cache); paraBldr.ParaStylePropsProxy = (m_fInScriptureText ? m_ScrSectionHeadParaProxy : m_DefaultIntroSectionHeadParaProxy); paraBldr.StringBuilder.SetIntPropValues(0, 0, (int)FwTextPropType.ktptWs, (int)FwTextPropVar.ktpvDefault, m_wsVern); paraBldr.CreateParagraph(m_hvoSectionHeading); } // Now, check if there is content. If not, add a blank paragraph. if (m_currSection.ContentOA.ParagraphsOS.Count == 0) { StTxtParaBldr paraBldr = new StTxtParaBldr(m_cache); paraBldr.ParaStylePropsProxy = (m_fInScriptureText ? m_DefaultScrParaProxy : m_DefaultIntroParaProxy); paraBldr.StringBuilder.SetIntPropValues(0, 0, (int)FwTextPropType.ktptWs, (int)FwTextPropVar.ktpvDefault, m_wsVern); paraBldr.CreateParagraph(m_hvoSectionContent); } m_fInScriptureText = !m_fCurrentSectionIsIntro; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Inserts one or more paragraphs at the end of a section. New sections for the book /// may also be created. /// </summary> /// <param name="book"></param> /// <param name="section"></param> /// <param name="ttpSrcArray">Array of props of each para to be inserted</param> /// <param name="tssParas">Array of TsStrings for each para to be inserted</param> /// <param name="sectionIndex"></param> /// <param name="cAddedSections"></param> /// <returns></returns> /// ------------------------------------------------------------------------------------ private bool InsertParagraphsAtSectionEnd(ScrBook book, IScrSection section, ITsTextProps[] ttpSrcArray, ITsString[] tssParas, int sectionIndex, out int cAddedSections) { cAddedSections = 0; bool isIntro = false; for (int i = 0; i < ttpSrcArray.Length; i++) { IStStyle style = m_scr.FindStyle(ttpSrcArray[i]); if (style.Structure == StructureValues.Heading) { // If content has been added to section, create a new section. Otherwise, // add the new paragraph to the end of the current section heading. if (section.ContentOA.ParagraphsOS.Count > 0) { isIntro = (style.Context == ContextValues.Intro); // Create a new section and add the current paragraph to the heading section = ScrSection.CreateEmptySection(book, sectionIndex + cAddedSections); CreateParagraph(section.HeadingOA, -1, ttpSrcArray[i], tssParas[i]); // Need additional prop changed event to get screen to refresh properly m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, book.Hvo, (int)ScrBook.ScrBookTags.kflidSections, sectionIndex + cAddedSections, 1, 0); cAddedSections++; } else { // Create heading paragraph at end of section heading CreateParagraph(section.HeadingOA, -1, ttpSrcArray[i], tssParas[i]); } } else { // Create content paragraph for the current section CreateParagraph(section.ContentOA, -1, ttpSrcArray[i], tssParas[i]); } } // create an empty paragraph if section content is empty if (section.ContentOA.ParagraphsOS.Count == 0) { string styleName = isIntro ? ScrStyleNames.IntroParagraph : ScrStyleNames.NormalParagraph; StTxtParaBldr bldr = new StTxtParaBldr(m_cache); bldr.ParaProps = StyleUtils.ParaStyleTextProps(styleName); ITsTextProps charProps = StyleUtils.CharStyleTextProps(styleName, m_cache.DefaultVernWs); bldr.AppendRun(string.Empty, charProps); bldr.CreateParagraph(section.ContentOAHvo); } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initialize the scripture importer /// </summary> /// ------------------------------------------------------------------------------------ protected void Initialize() { m_wsAnal = m_cache.DefaultAnalWs; m_wsVern = m_cache.DefaultVernWs; m_wsPara = m_cache.DefaultVernWs; m_scr = m_cache.LangProject.TranslatedScriptureOA; InitInterpretFootnoteSettings(); ScrImportSet importSettings = (m_settings as ScrImportSet); // ENHANCE (TomB): Might want to make it possible to end importing in the middle // of a book someday. ScrReference endRef = new ScrReference(importSettings.EndRef, m_scr.Versification); ScrReference startRef = new ScrReference(importSettings.StartRef, m_scr.Versification); m_nBookNumber = importSettings.StartRef.Book; importSettings.EndRef = endRef = endRef.LastReferenceForBook; // Initialize scripture object InitScriptureObject(); // Load the scripture text project & enum LoadScriptureProject(); // Display progress if one was supplied if (m_importCallbacks.IsDisplayingUi) { int cChapters = ScrReference.GetNumberOfChaptersInRange(SOWrapper.BooksPresent, startRef, endRef); int nMax = m_settings.ImportTranslation ? cChapters : 0; if (SOWrapper.HasNonInterleavedBT && m_settings.ImportBackTranslation) nMax += cChapters; if (SOWrapper.HasNonInterleavedNotes && m_settings.ImportAnnotations) nMax += cChapters; m_importCallbacks.Maximum = nMax; } // Init our set of style proxies LoadImportMappingProxies(); // Init member vars special paragraph style proxies, used as fallbacks in case // import data lacks a paragraph style. // For now we always use the default vernacular writing system. This may change // when we are able to import paratext project proxies with multiple // domains (vern, back transl, notes) m_BookTitleParaProxy = new ImportStyleProxy(ScrStyleNames.MainBookTitle, StyleType.kstParagraph, m_wsVern, ContextValues.Title, m_styleSheet); Debug.Assert(m_BookTitleParaProxy.Context == ContextValues.Title); m_ScrSectionHeadParaProxy = new ImportStyleProxy(ScrStyleNames.SectionHead, StyleType.kstParagraph, m_wsVern, ContextValues.Text, m_styleSheet); m_DefaultIntroSectionHeadParaProxy = new ImportStyleProxy(ScrStyleNames.IntroSectionHead, StyleType.kstParagraph, m_wsVern, ContextValues.Intro, m_styleSheet); m_DefaultScrParaProxy = new ImportStyleProxy(ScrStyleNames.NormalParagraph, StyleType.kstParagraph, m_wsVern, ContextValues.Text, m_styleSheet); m_DefaultIntroParaProxy = new ImportStyleProxy(ScrStyleNames.IntroParagraph, StyleType.kstParagraph, m_wsVern, ContextValues.Intro, m_styleSheet); m_DefaultFootnoteParaProxy = new ImportStyleProxy(ScrStyleNames.NormalFootnoteParagraph, StyleType.kstParagraph, m_wsVern, ContextValues.Note, m_styleSheet); m_DefaultAnnotationStyleProxy = new ImportStyleProxy(ScrStyleNames.Remark, StyleType.kstParagraph, m_wsAnal, ContextValues.Annotation, m_styleSheet); // Make a paragraph builder. We will keep re-using this every time we build a paragraph. m_ParaBldr = new StTxtParaBldr(m_cache); // Handle the case where the very first marker (after the \id line) is a // character style. m_ParaBldr.ParaStylePropsProxy = m_DefaultIntroParaProxy; // Build generic character props for use with different runs of text and analysis // character properties ITsPropsBldr tsPropsBldr = TsPropsBldrClass.Create(); // analysis character properties tsPropsBldr.SetIntPropValues((int)FwTextPropType.ktptWs, 0, m_wsAnal); m_analTextProps = tsPropsBldr.GetTextProps(); // vernacular character properties tsPropsBldr.SetIntPropValues((int)FwTextPropType.ktptWs, 0, m_wsVern); m_vernTextProps = tsPropsBldr.GetTextProps(); // Get a reference to the annotation definition of translator notes (to use as default note type) m_scrTranslatorAnnotationDef = new CmAnnotationDefn(m_cache, LangProject.kguidAnnTranslatorNote); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Use this method to move the adjacent part of one StText to the adjacent position /// in another. /// </summary> /// <param name="fromText">StText from which the contents is moved</param> /// <param name="toText">StText to which the contents is moved</param> /// <param name="divIndex">Index of last partial paragraph to be moved or the first /// whole paragraph not moved</param> /// <param name="ichDiv">character offset of last character to be moved or zero if /// none are to be moved</param> /// <param name="toIsPreceding">Should equal true if the toText preceeds the fromText. /// If true, the moved text will be appended to the toText. /// If false, they will be placed at the beginning of the toText.</param> /// ------------------------------------------------------------------------------------ public static void MovePartialContents(IStText fromText, IStText toText, int divIndex, int ichDiv, bool toIsPreceding) { int iLastFromPara = fromText.ParagraphsOS.Count - 1; Debug.Assert((divIndex >= 0) && (divIndex <= iLastFromPara)); // Set up parameters for whole paragraph movement based on direction of movement int iStartAt, iEndAt, iInsertAt, iReferenceEdge; if (toIsPreceding) { //From beginning to para preceding IP, appended iStartAt = 0; iEndAt = divIndex - 1; iInsertAt = toText.ParagraphsOS.Count; iReferenceEdge = 0; } else { //From para following IP to the end, pre-pended iStartAt = (ichDiv > 0) ? divIndex + 1 : divIndex; iEndAt = iLastFromPara; iInsertAt = 0; iReferenceEdge = iLastFromPara; } // Move the whole paragraphs of fromText to empty toText if (divIndex != iReferenceEdge || (ichDiv == 0 && !toIsPreceding)) MoveWholeParas(fromText, iStartAt, iEndAt, toText, iInsertAt); // Move partial paragraph (now in the edge paragraph of the fromText) // to a new paragraph in the toText if (ichDiv > 0 || toIsPreceding) DivideParaContents(fromText, ichDiv, toText, toIsPreceding); if (fromText.ParagraphsOS.Count == 0) { // We moved all of the paragraphs out of the existing section so we need to // create a new paragraph so the user can enter text StTxtPara newSectionFirstPara = (StTxtPara)toText.ParagraphsOS[0]; using (StTxtParaBldr bldr = new StTxtParaBldr(fromText.Cache)) { bldr.ParaProps = newSectionFirstPara.StyleRules; bldr.AppendRun(string.Empty, StyleUtils.CharStyleTextProps(null, fromText.Cache.DefaultVernWs)); bldr.CreateParagraph(fromText.Hvo); } } }
/// <summary> /// attach an annotation describing this failure to the object. *Does Not* remove previous annotations! /// </summary> /// <remarks> I say it does not remove previous annotations because I haven't thought about how much smarts /// it would take to only remove once associated with this particular failure. So I am stipulating for now that /// the caller should first remove all of the kinds of indications which it might create.</remarks> /// <returns></returns> protected ICmBaseAnnotation MakeAnnotation() { // callar should do something like this:CmBaseAnnotation.RemoveAnnotationsForObject(m_object.Cache, m_object.Hvo); ICmBaseAnnotation annotation = (ICmBaseAnnotation)m_cache.LangProject.AnnotationsOC.Add(new CmBaseAnnotation()); annotation.CompDetails = m_xmlDescription; annotation.TextOA = new StText(); using (StTxtParaBldr paraBldr = new StTxtParaBldr(m_cache)) { //review: I have no idea what this is as to be paraBldr.ParaProps = StyleUtils.ParaStyleTextProps("Paragraph"); //todo: this pretends that the default analysis writing system is also the user // interface 1. but I don't really know what's the right thing to do. paraBldr.AppendRun(m_explanation, StyleUtils.CharStyleTextProps(null, m_cache.DefaultAnalWs)); paraBldr.CreateParagraph(annotation.TextOAHvo); } // Dispose() frees ICU resources. annotation.BeginObjectRA = m_object; annotation.Flid = m_flid; annotation.CompDetails = m_xmlDescription; annotation.SourceRA = m_cache.LangProject.ConstraintCheckerAgent; // Although we generated a PropChanged when we actually created the annotation, we need another // one now that all its properties have been set, as there may be a filter that excludes it // until those properties. Simulate removing and re-adding the new annotation (presumed to be // at the end of the collection). int chvo = m_cache.LangProject.AnnotationsOC.Count; m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, m_cache.LangProject.Hvo, (int) LangProject.LangProjectTags.kflidAnnotations, chvo - 1, 1, 1); return annotation; }
public void SectionHeadFirstParaToParagraph() { CheckDisposed(); // create a book IScrBook book = CreateGenesis(); // Create section 1 IScrSection sectionCur = CreateSection(book, "My aching head!"); // create paragraph one holding chapter 1 StTxtParaBldr paraBldr = new StTxtParaBldr(Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("1", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("In the beginning, God created the heavens and the earth. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); sectionCur.AdjustReferences(); // create section 2 sectionCur = CreateSection(book, "My other aching head!", "Second paragraph of heading"); // create paragraph holding chapter 2 paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("2", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("Thus the heavens and the earth were completed in all their vast array. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); // finish the section info sectionCur.AdjustReferences(); m_draftView.RefreshDisplay(); // Set the IP in the 2nd section. int iBook = 0; // assume that iBook 0 is Genesis int iSectionIP = 1; //section with 2:1 // Make a range selection that covers both paragraphs of section heading m_draftView.SetInsertionPoint((int)ScrSection.ScrSectionTags.kflidHeading, iBook, iSectionIP); // ApplyStyle should move paragraph from heading, but not change number // of sections. Assert.AreEqual(2, book.SectionsOS.Count, "Two sections before ApplyStyle"); m_draftView.ApplyStyle(ScrStyleNames.NormalParagraph); Assert.AreEqual(2, book.SectionsOS.Count, "Two sections after ApplyStyle"); // setup variables for testing IScrSection section1 = book.SectionsOS[0]; IScrSection section2 = book.SectionsOS[1]; // Verify section paragraphs Assert.AreEqual(1, section1.HeadingOA.ParagraphsOS.Count); Assert.AreEqual(2, section1.ContentOA.ParagraphsOS.Count); StTxtPara para = (StTxtPara)section1.ContentOA.ParagraphsOS[1]; Assert.AreEqual("My other aching head!", para.Contents.Text); Assert.AreEqual(ScrStyleNames.NormalParagraph, para.StyleRules.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); para = (StTxtPara)section2.HeadingOA.ParagraphsOS[0]; Assert.AreEqual("Second paragraph of heading", para.Contents.Text); Assert.AreEqual(ScrStyleNames.SectionHead, para.StyleRules.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); Assert.AreEqual(1, section2.HeadingOA.ParagraphsOS.Count); Assert.AreEqual(1, section2.ContentOA.ParagraphsOS.Count); // Verify that selection is in paragraph that was the heading of the // second section Assert.AreEqual(0, m_draftView.TeEditingHelper.BookIndex); Assert.AreEqual(0, m_draftView.TeEditingHelper.SectionIndex); Assert.AreEqual(1, m_draftView.ParagraphIndex); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Create a new section, to be owned by the given book. The section will be an intro /// section if the isIntro flag is set to <code>true</code> /// The contents of the first content paragraph are filled with a single run as /// requested. The start and end references for the section are set based on where it's /// being inserted in the book. /// </summary> /// <param name="book">The book where the new section will be created</param> /// <param name="iSection">The zero-based index of the new section</param> /// <param name="contentText">The text to be used as the first para in the new section /// content</param> /// <param name="contentTextProps">The character properties to be applied to the first /// para in the new section content</param> /// <param name="isIntro">True to create an intro section, false to create a /// normal scripture section</param> /// <returns>Created section</returns> /// ------------------------------------------------------------------------------------ public static IScrSection CreateScrSection(IScrBook book, int iSection, string contentText, ITsTextProps contentTextProps, bool isIntro) { Debug.Assert(book != null); IScrSection section = CreateSectionWithHeadingPara(book, iSection, isIntro); // Insert the section contents. using (StTxtParaBldr bldr = new StTxtParaBldr(book.Cache)) { bldr.ParaProps = StyleUtils.ParaStyleTextProps( isIntro ? ScrStyleNames.IntroParagraph : ScrStyleNames.NormalParagraph); bldr.AppendRun(contentText, contentTextProps); bldr.CreateParagraph(section.ContentOAHvo); } // Dispose() frees ICU resources. return section; }
public void SectionHeadAllParasToParagraph() { CheckDisposed(); // create a book IScrBook book = CreateGenesis(); // Create section 1 IScrSection sectionCur = CreateSection(book, "My aching head!"); // create paragraph one holding chapter 1 StTxtParaBldr paraBldr = new StTxtParaBldr(Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("1", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("In the beginning, God created the heavens and the earth. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); sectionCur.AdjustReferences(); // create section 2 sectionCur = CreateSection(book, "My other aching head!", "Second paragraph of heading"); // create paragraph holding chapter 2 paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("2", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("Thus the heavens and the earth were completed in all their vast array. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); // finish the section info sectionCur.AdjustReferences(); m_draftView.RefreshDisplay(); // Set the IP in the 2nd section. int iBook = 0; // assume that iBook 0 is Genesis int iSectionIP = 1; //section with 2:1 // Make a range selection that covers both paragraphs of section heading m_draftView.SetInsertionPoint((int)ScrSection.ScrSectionTags.kflidHeading, iBook, iSectionIP); SelectionHelper helper = SelectionHelper.Create(m_draftView); // adjust end point level info to point to second paragraph SelLevInfo[] levInfo = helper.GetLevelInfo(SelectionHelper.SelLimitType.End); levInfo[0].ihvo = 1; helper.SetLevelInfo(SelectionHelper.SelLimitType.End, levInfo); helper.IchEnd = 0; // needed to make selection a range selection helper.SetSelection(true); // InsertSection should add a scripture section Assert.AreEqual(2, book.SectionsOS.Count, "Two sections before ApplyStyle"); m_draftView.ApplyStyle(ScrStyleNames.NormalParagraph); Assert.AreEqual(1, book.SectionsOS.Count, "Should remove a section"); // setup variables for testing IScrSection section = book.SectionsOS[0]; // Verify verse start and end refs Assert.AreEqual(1001001, section.VerseRefMin, "Existing section should have same verse start ref"); Assert.AreEqual(1002001, section.VerseRefMax, "New section should have correct verse end ref"); // Verify section paragraphs Assert.AreEqual(1, section.HeadingOA.ParagraphsOS.Count); Assert.AreEqual(4, section.ContentOA.ParagraphsOS.Count); StTxtPara para = (StTxtPara)section.ContentOA.ParagraphsOS[1]; Assert.AreEqual("My other aching head!", para.Contents.Text); Assert.AreEqual(ScrStyleNames.NormalParagraph, para.StyleRules.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); para = (StTxtPara)section.ContentOA.ParagraphsOS[2]; Assert.AreEqual("Second paragraph of heading", para.Contents.Text); Assert.AreEqual(ScrStyleNames.NormalParagraph, para.StyleRules.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); // Verify that selection is in paragraph that was the heading of the // removed section Assert.AreEqual(0, m_draftView.TeEditingHelper.BookIndex); Assert.AreEqual(0, m_draftView.TeEditingHelper.SectionIndex); Assert.AreEqual(1, m_draftView.ParagraphIndex); }
public void ContentMultipleParasToSectionHead() { CheckDisposed(); // create a book IScrBook book = CreateGenesis(); // Create a section IScrSection sectionCur = CreateSection(book, "My aching head!"); // create paragraph one holding chapter 1 StTxtParaBldr paraBldr = new StTxtParaBldr(Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("1", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("In the beginning, God created the heavens and the earth. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); // create paragraph that will be changed to a section heading paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("My other aching head!", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); // create paragraph that will be changed to a section heading paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("My third aching head!", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); // create paragraph three holding chapter 2 paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("2", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("Thus the heavens and the earth were completed in all their vast array. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); Assert.AreEqual(4, sectionCur.ContentOA.ParagraphsOS.Count); // finish the section info sectionCur.AdjustReferences(); m_draftView.RefreshDisplay(); // Create a range selection from paragraph 1 to paragraph 2. int iBook = 0; // assume that iBook 0 is Genesis int iSectionIP = 0; //section with 1:1 to 2:1 int iParaIP = 1; int ichIP = 0; m_draftView.SetInsertionPoint(iBook, iSectionIP, iParaIP, ichIP, true); IVwSelection sel0 = m_draftView.RootBox.Selection; Assert.IsNotNull(sel0); m_draftView.SetInsertionPoint(iBook, iSectionIP, iParaIP + 1, ichIP, true); IVwSelection sel1 = m_draftView.RootBox.Selection; Assert.IsNotNull(sel1); IVwSelection sel = m_draftView.RootBox.MakeRangeSelection(sel0, sel1, true); Assert.IsNotNull(sel); // InsertSection should add a scripture section m_draftView.ApplyStyle(ScrStyleNames.SectionHead); Assert.AreEqual(2, book.SectionsOS.Count, "Should add a section"); // setup variables for testing IScrSection existingSection = book.SectionsOS[iSectionIP]; int iSectionIns = iSectionIP + 1; IScrSection createdSection = book.SectionsOS[iSectionIns]; // Verify verse start and end refs Assert.AreEqual(1001001, existingSection.VerseRefMin, "Existing section should have same verse start ref"); Assert.AreEqual(1001001, existingSection.VerseRefMax, "Existing section should have new verse end ref"); Assert.AreEqual(1002001, createdSection.VerseRefMin, "New section should have correct verse start ref"); Assert.AreEqual(1002001, createdSection.VerseRefMax, "New section should have correct verse end ref"); // Verify section head Assert.AreEqual(2, createdSection.HeadingOA.ParagraphsOS.Count); Assert.AreEqual("My other aching head!", ((StTxtPara)createdSection.HeadingOA.ParagraphsOS[0]).Contents.Text); Assert.AreEqual("My third aching head!", ((StTxtPara)createdSection.HeadingOA.ParagraphsOS[1]).Contents.Text); Assert.AreEqual(1, createdSection.ContentOA.ParagraphsOS.Count); // Verify that selection is in heading of the new section Assert.IsTrue(m_draftView.TeEditingHelper.InSectionHead, "Should be in section heading"); Assert.AreEqual(0, m_draftView.TeEditingHelper.BookIndex); Assert.AreEqual(iSectionIns, m_draftView.TeEditingHelper.SectionIndex); Assert.AreEqual(0, m_draftView.ParagraphIndex); // Check that end is in second paragraph of heading SelectionHelper helper = SelectionHelper.Create(m_draftView); SelLevInfo[] endInfo = helper.GetLevelInfo(SelectionHelper.SelLimitType.End); Assert.AreEqual(4, endInfo.Length); Assert.AreEqual(iSectionIns, endInfo[2].ihvo); Assert.AreEqual((int)ScrSection.ScrSectionTags.kflidHeading, endInfo[1].tag); Assert.AreEqual(1, endInfo[0].ihvo); }
public void ContentMidParaToSectionHead() { CheckDisposed(); // create a book IScrBook book = CreateGenesis(); // Create a section IScrSection sectionCur = CreateSection(book, "My aching head!"); // create paragraph one holding chapter 1 StTxtParaBldr paraBldr = new StTxtParaBldr(Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("1", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("In the beginning, God created the heavens and the earth. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); // create paragraph that will be changed to a section heading paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("My other aching head!", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); // create paragraph three holding chapter 2 paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("2", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("Thus the heavens and the earth were completed in all their vast array. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); Assert.AreEqual(3, sectionCur.ContentOA.ParagraphsOS.Count); // finish the section info sectionCur.AdjustReferences(); m_draftView.RefreshDisplay(); // Set the IP at the beginning of the 2nd paragraph in the 1st section. int iBook = 0; // assume that iBook 0 is Genesis int iSectionIP = 0; //section with 1:1 to 2:1 int iParaIP = 1; int ichIP = 0; // Put the IP in place m_draftView.SetInsertionPoint(iBook, iSectionIP, iParaIP, ichIP, true); // InsertSection should add a scripture section m_draftView.ApplyStyle(ScrStyleNames.SectionHead); Assert.AreEqual(2, book.SectionsOS.Count, "Should add a section"); // setup variables for testing IScrSection existingSection = book.SectionsOS[iSectionIP]; int iSectionIns = iSectionIP + 1; IScrSection createdSection = book.SectionsOS[iSectionIns]; // Verify verse start and end refs Assert.AreEqual(1001001, existingSection.VerseRefMin, "Existing section should have same verse start ref"); Assert.AreEqual(1001001, existingSection.VerseRefMax, "Existing section should have new verse end ref"); Assert.AreEqual(1002001, createdSection.VerseRefMin, "New section should have correct verse start ref"); Assert.AreEqual(1002001, createdSection.VerseRefMax, "New section should have correct verse end ref"); // Verify section head Assert.AreEqual("My other aching head!", ((StTxtPara)createdSection.HeadingOA.ParagraphsOS.FirstItem).Contents.Text); Assert.AreEqual(1, createdSection.HeadingOA.ParagraphsOS.Count); Assert.AreEqual(1, createdSection.ContentOA.ParagraphsOS.Count); // Verify that selection is in heading of the new section Assert.IsTrue(m_draftView.TeEditingHelper.InSectionHead, "Should be in section heading"); Assert.AreEqual(0, m_draftView.TeEditingHelper.BookIndex); Assert.AreEqual(iSectionIns, m_draftView.TeEditingHelper.SectionIndex); Assert.AreEqual(0, m_draftView.ParagraphIndex); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Insert a new note at its correct position in the list. /// </summary> /// <param name="startRef">beginning reference note refers to</param> /// <param name="endRef">ending reference note refers to</param> /// <param name="beginObject">id of beginning object note refers to</param> /// <param name="endObject">id of ending object note refers to</param> /// <param name="guidNoteType">The GUID representing the CmAnnotationDefn to use for /// the type</param> /// <param name="bldrDiscussion">Para builder to use to build the Discussion /// paragraph</param> /// <returns>note inserted into annotation list</returns> /// ------------------------------------------------------------------------------------ public IScrScriptureNote InsertImportedNote(BCVRef startRef, BCVRef endRef, ICmObject beginObject, ICmObject endObject, Guid guidNoteType, StTxtParaBldr bldrDiscussion) { return InsertNote(startRef, endRef, beginObject, endObject, guidNoteType, -1, 0, 0, null, bldrDiscussion, null, null, GetInsertIndexForRef(startRef)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Insert a new note at its correct position in the list. /// </summary> /// <param name="startRef">beginning reference note refers to</param> /// <param name="endRef">ending reference note refers to</param> /// <param name="beginObject">id of beginning object note refers to</param> /// <param name="endObject">id of ending object note refers to</param> /// <param name="guidNoteType">The GUID representing the CmAnnotationDefn to use for /// the type</param> /// <param name="bldrQuote">Para builder to use to build the Quote paragraph</param> /// <param name="bldrDiscussion">Para builder to use to build the Discussion /// paragraph</param> /// <param name="bldrRecommendation">Para builder to use to build the /// Recommendation paragraph</param> /// <param name="bldrResolution">Para builder to use to build the Resolution /// paragraph</param> /// <returns>note inserted into annotation list</returns> /// ------------------------------------------------------------------------------------ public IScrScriptureNote InsertNote(BCVRef startRef, BCVRef endRef, ICmObject beginObject, ICmObject endObject, Guid guidNoteType, StTxtParaBldr bldrQuote, StTxtParaBldr bldrDiscussion, StTxtParaBldr bldrRecommendation, StTxtParaBldr bldrResolution) { int insertIndex; return InsertNote(startRef, endRef, beginObject, endObject, guidNoteType, -1, -1, 0, bldrQuote, bldrDiscussion, bldrRecommendation, bldrResolution, out insertIndex); }
/// ----------------------------------------------------------------------------------- /// <summary> /// If user presses Enter and a new style is applied to the following paragraph, we /// need to mark that style as being in use. If in a section Head, we might need to fix /// the structure. /// </summary> /// <param name="fCalledFromKeyDown">True if this method gets called from OnKeyDown</param> /// <param name="stuInput">input string</param> /// <param name="cchBackspace">number of backspace characters in stuInput</param> /// <param name="cchDelForward">number of delete characters in stuInput</param> /// <param name="ss">Status of Shift/Control/Alt key</param> /// <param name="graphics">graphics for processing input</param> /// <param name="modifiers">key modifiers - shift status, etc.</param> /// <remarks>I (EberhardB) added the parameter <paramref name="fCalledFromKeyDown"/> /// to be able to distinguish between Ctrl-Delete and Ctrl-Backspace.</remarks> /// ----------------------------------------------------------------------------------- protected void HandleEnterKey(bool fCalledFromKeyDown, string stuInput, int cchBackspace, int cchDelForward, VwShiftStatus ss, IVwGraphics graphics, Keys modifiers) { if (IsPictureSelected) // Enter should do nothing if a picture or caption is selected. return; SelLevInfo[] levInfo; // If we are at the end of a heading paragraph, we need to check the "next" style to // see if it is a body type. If it is not, then allow processing to proceed as normal. // If it is a body type, then don't create a new paragraph, just move down to the start // of the first body paragraph in the section. if (InSectionHead) { // if the selection is a range selection then try to delete the selected text first. if (CurrentSelection.Selection.IsRange) { ITsStrFactory factory = TsStrFactoryClass.Create(); CurrentSelection.Selection.ReplaceWithTsString( factory.MakeString("", m_cache.DefaultVernWs)); // If selection is still a range selection, the deletion failed and we don't // need to do anything else. if (CurrentSelection.Selection.IsRange || !InSectionHead) return; } // If the heading style has a following style that is a body style and we are at the // end of the paragraph then move the IP to the beginning of the body paragraph. levInfo = CurrentSelection.GetLevelInfo(SelectionHelper.SelLimitType.Anchor); // This is the paragraph that was originally selected ScrTxtPara headPara = new ScrTxtPara(m_cache, levInfo[0].hvo); IStStyle headParaStyle = m_scr.FindStyle(headPara.StyleName); IStStyle followStyle = headParaStyle != null ? headParaStyle.NextRA : null; if (followStyle != null && followStyle.Structure == StructureValues.Body && SelectionAtEndParagraph()) { // if there is another section head paragraph, then the section needs to be split ScrSection section = new ScrSection(m_cache, ((ITeView)Control).LocationTracker.GetSectionHvo(CurrentSelection, SelectionHelper.SelLimitType.Anchor)); if (CurrentSelection.LevelInfo[0].ihvo < section.HeadingOA.ParagraphsOS.Count - 1) { // Setting the style rules destroys the selection, so we have to remember // the current location before we change the style rules. int iBook = BookIndex; int iSection = SectionIndex; // break the section // create a new empty paragraph in the first section // set the IP to the start of the new paragraph CreateSection(BCVRef.GetVerseFromBcv(section.VerseRefMin) == 0); Debug.Assert(CurrentSelection != null && CurrentSelection.IsValid, "Creating the section didn't set a selection"); StTxtPara contentPara = new StTxtPara(m_cache, CurrentSelection.LevelInfo[0].hvo); contentPara.StyleRules = StyleUtils.ParaStyleTextProps(followStyle.Name); SetInsertionPoint(iBook, iSection, 0, 0, false); } else { SetInsertionPoint(BookIndex, SectionIndex, 0, 0, false); // If the first paragraph is not empty, then insert a new paragraph with the // follow-on style of the section head. StTxtPara contentPara = new StTxtPara(m_cache, CurrentSelection.LevelInfo[0].hvo); if (contentPara.Contents.Length > 0) { StTxtParaBldr bldr = new StTxtParaBldr(m_cache); bldr.ParaProps = StyleUtils.ParaStyleTextProps(followStyle.Name); bldr.AppendRun(String.Empty, StyleUtils.CharStyleTextProps(null, m_cache.DefaultVernWs)); bldr.CreateParagraph(contentPara.OwnerHVO, 0); SetInsertionPoint(BookIndex, SectionIndex, 0, 0, false); } } return; } } // Call the base to handle the key base.OnCharAux('\r', fCalledFromKeyDown, stuInput, cchBackspace, cchDelForward, ss, graphics, modifiers); try { levInfo = CurrentSelection.GetLevelInfo(SelectionHelper.SelLimitType.Anchor); ScrTxtPara para = new ScrTxtPara(m_cache, levInfo[0].hvo); IStStyle style = m_scr.FindStyle(para.StyleName); if (style != null) style.InUse = true; } catch { // Oh, well. We tried. } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Insert a new note at its correct position in the list. /// </summary> /// <param name="startRef">beginning reference note refers to</param> /// <param name="endRef">ending reference note refers to</param> /// <param name="beginObject">id of beginning object to which annotation refers</param> /// <param name="endObject">id of ending object to which annotation refers</param> /// <param name="guidNoteType">The GUID representing the CmAnnotationDefn to use for /// the type</param> /// <param name="wsSelector">The writing system selector, indicating which /// writing system the annotation refers to.</param> /// <param name="startOffset">The starting character offset.</param> /// <param name="endOffset">The ending character offset.</param> /// <param name="bldrQuote">Para builder to use to build the Quote paragraph</param> /// <param name="bldrDiscussion">Para builder to use to build the Discussion /// paragraph</param> /// <param name="bldrRecommendation">Para builder to use to build the /// Recommendation paragraph</param> /// <param name="bldrResolution">Para builder to use to build the Resolution /// paragraph</param> /// <param name="insertIndex">out: index where annotation was inserted into /// annotation list</param> /// <returns>note inserted into annotation list</returns> /// ------------------------------------------------------------------------------------ public IScrScriptureNote InsertNote(BCVRef startRef, BCVRef endRef, ICmObject beginObject, ICmObject endObject, Guid guidNoteType, int wsSelector, int startOffset, int endOffset, StTxtParaBldr bldrQuote, StTxtParaBldr bldrDiscussion, StTxtParaBldr bldrRecommendation, StTxtParaBldr bldrResolution, out int insertIndex) { // Determine where to insert the new annotation. insertIndex = (startOffset < 0 ? GetInsertIndexForRef(startRef) : GetNewNotesInsertIndex(startRef, beginObject, startOffset)); if (startOffset < 0) startOffset = 0; return InsertNote(startRef, endRef, beginObject, endObject, guidNoteType, wsSelector, startOffset, endOffset, bldrQuote, bldrDiscussion, bldrRecommendation, bldrResolution, insertIndex); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Insert a new note at its correct position in the list. /// </summary> /// <param name="startRef">beginning reference note refers to</param> /// <param name="endRef">ending reference note refers to</param> /// <param name="beginObject">id of beginning object to which annotation refers</param> /// <param name="endObject">id of ending object to which annotation refers</param> /// <param name="guidNoteType">The GUID representing the CmAnnotationDefn to use for /// the type</param> /// <param name="wsSelector">The writing system selector, indicating which /// writing system the annotation refers to.</param> /// <param name="startOffset">The starting character offset.</param> /// <param name="endOffset">The ending character offset.</param> /// <param name="bldrQuote">Para builder to use to build the Quote paragraph</param> /// <param name="bldrDiscussion">Para builder to use to build the Discussion /// paragraph</param> /// <param name="bldrRecommendation">Para builder to use to build the /// Recommendation paragraph</param> /// <param name="bldrResolution">Para builder to use to build the Resolution /// paragraph</param> /// <param name="insertIndex">index where annotation is to be inserted into /// annotation list</param> /// <returns>note inserted into annotation list</returns> /// ------------------------------------------------------------------------------------ public IScrScriptureNote InsertNote(BCVRef startRef, BCVRef endRef, ICmObject beginObject, ICmObject endObject, Guid guidNoteType, int wsSelector, int startOffset, int endOffset, StTxtParaBldr bldrQuote, StTxtParaBldr bldrDiscussion, StTxtParaBldr bldrRecommendation, StTxtParaBldr bldrResolution, int insertIndex) { IScrScriptureNote annotation = new ScrScriptureNote(); NotesOS.InsertAt(annotation, insertIndex); // Initialize the annotation. ((ScrScriptureNote)annotation).InitializeNote(guidNoteType, startRef, endRef, beginObject, endObject, wsSelector, startOffset, endOffset, bldrQuote, bldrDiscussion, bldrRecommendation, bldrResolution); annotation.SourceRA = annotation.AnnotationType == NoteType.CheckingError ? m_cache.LangProject.DefaultComputerAgent : m_cache.LangProject.DefaultUserAgent; // Notify all windows that the new annotation exists m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, Hvo, (int)ScrBookAnnotationsTags.kflidNotes, insertIndex, 1, 0); return annotation; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Add a new annotation to the pending list /// </summary> /// ------------------------------------------------------------------------------------ private void AddNewAnnotation(ImportStyleProxy paraProxy, ITsTextProps runProps) { StTxtParaBldr paraBldr = new StTxtParaBldr(m_cache); paraBldr.ParaStylePropsProxy = paraProxy; paraBldr.AppendRun(m_sSegmentText, runProps); Guid guidAnnotationType = Guid.Empty; try { if (paraProxy.NoteType != null) guidAnnotationType = paraProxy.NoteType.Guid; else if (m_SOWrapper.CurrentAnnotationType > 0) guidAnnotationType = m_cache.GetGuidFromId(m_SOWrapper.CurrentAnnotationType); } catch { } finally { if (guidAnnotationType == Guid.Empty) guidAnnotationType = m_scrTranslatorAnnotationDef.Guid; } BCVRef lastRef = SOWrapper.SegmentLastRef; // If we haven't come across any scripture text (still in title or intro), then make // sure that the chapter number is set right. if (lastRef.Chapter == 0) lastRef.Chapter = 1; m_PendingAnnotations.Add(new ScrAnnotationInfo(guidAnnotationType, paraBldr, (m_ParaBldr.Length > 0 ? m_ParaBldr.Length - 1 : 0), m_currentRef.BBCCCVVV, lastRef.BBCCCVVV)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initialize a new note. /// </summary> /// <param name="guidAnnotationType">GUID representing the type of annotation.</param> /// <param name="startRef">beginning reference note refers to</param> /// <param name="endRef">ending reference note refers to</param> /// <param name="beginObj">beginning object note refers to</param> /// <param name="endObj">ending object note refers to</param> /// <param name="wsSelector">The writing system selector.</param> /// <param name="startOffset">The starting character offset.</param> /// <param name="endOffset">The ending character offset.</param> /// <param name="bldrQuote">Para builder to use to build the Quote paragraph</param> /// <param name="bldrDiscussion">Para builder to use to build the Discussion /// paragraph</param> /// <param name="bldrRecommendation">Para builder to use to build the /// Recommendation paragraph</param> /// <param name="bldrResolution">Para builder to use to build the Resolution /// paragraph</param> /// ------------------------------------------------------------------------------------ public void InitializeNote(Guid guidAnnotationType, BCVRef startRef, BCVRef endRef, ICmObject beginObj, ICmObject endObj, int wsSelector, int startOffset, int endOffset, StTxtParaBldr bldrQuote, StTxtParaBldr bldrDiscussion, StTxtParaBldr bldrRecommendation, StTxtParaBldr bldrResolution) { AnnotationTypeRA = new CmAnnotationDefn(Cache, guidAnnotationType); BeginObjectRA = beginObj; EndObjectRA = endObj; BeginRef = startRef; EndRef = endRef; WsSelector = wsSelector; BeginOffset = startOffset; EndOffset = endOffset; // Now, initialize all the texts QuoteOA = new StJournalText(); InitializeText(bldrQuote, QuoteOA); DiscussionOA = new StJournalText(); InitializeText(bldrDiscussion, DiscussionOA); RecommendationOA = new StJournalText(); InitializeText(bldrRecommendation, RecommendationOA); ResolutionOA = new StJournalText(); InitializeText(bldrResolution, ResolutionOA); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Begin a footnote: insert the footnote into the ScrBook and insert the footnote /// marker into the paragraph. Subsequent footnote segments will be added to the /// footnote paragraph until <see cref="EndFootnote"/> is called. /// </summary> /// ------------------------------------------------------------------------------------ protected void BeginFootnote() { Debug.Assert(!m_fInFootnote); // Check to see if this footnote is a USFM style footnote or otherwise begins with a // single character that is likely to be a footnote marker. If so, strip the marker // from the data. CheckDataForFootnoteMarker(); // If the footnote marker is the auto marker, then generate a marker for it ImportStyleProxy proxy = (m_styleProxy.StyleType == StyleType.kstParagraph) ? m_styleProxy : m_DefaultFootnoteParaProxy; string sFootnoteMarker = m_scr.GetFootnoteMarker(proxy.StyleId); // If the last character in the paragraph is a separator, then insert the footnote // marker before it. (TE-2431) ITsStrBldr strbldr = m_ParaBldr.StringBuilder; int ichMarker = m_ParaBldr.Length; bool fInsertSpaceAfterCaller = false; if (UnicodeCharProps.get_IsSeparator(m_ParaBldr.FinalCharInPara)) ichMarker--; else if (m_settings.ImportTypeEnum == TypeOfImport.Other) { // Check to see if we are inserting this right after a verse. ITsTextProps propsOfLastRun = strbldr.get_Properties(strbldr.RunCount - 1); string sStyleOfLastRun = propsOfLastRun.GetStrPropValue((int)FwTextPropType.ktptNamedStyle); if (sStyleOfLastRun == ScrStyleNames.VerseNumber) fInsertSpaceAfterCaller = true; } // When importing a whole book, we can call this version of InsertFootnoteAt and save // the time of trying to look for the previous footnote each time and checking to see // if we need to resequence following footnotes. // TODO (TE-920 and/or TE-431): m_CurrFootnote = ScrFootnote.InsertFootnoteAt(m_scrBook, m_iCurrFootnote, strbldr, ichMarker, sFootnoteMarker); if (fInsertSpaceAfterCaller) strbldr.Replace(strbldr.Length, strbldr.Length, " ", m_vernTextProps); // Set up the paragraph builder m_SavedParaBldr = m_ParaBldr; m_ParaBldr = new StTxtParaBldr(m_cache); m_ParaBldr.ParaStylePropsProxy = proxy; m_CurrParaFootnotes.Add(new FootnoteInfo(m_CurrFootnote, proxy.StyleId)); // remember that we are now processing a footnote SetInFootnote(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Append a new section to the given book, having the specified text as the section /// head. The new section will have an empty content text created also. /// </summary> /// <param name="styleName">Style name for section</param> /// <param name="book">The book to which the section is to be appended</param> /// <param name="sSectionHead">The text of the new section head</param> /// <returns>The newly created section</returns> /// ------------------------------------------------------------------------------------ private IScrSection CreateSection(string styleName, IScrBook book, params string[] sSectionHead) { // Create a section IScrSection section = new ScrSection(); book.SectionsOS.Append(section); // Create a section head for this section section.HeadingOA = new StText(); StTxtParaBldr paraBldr = new StTxtParaBldr(Cache); for (int i = 0; i < sSectionHead.Length; i++) { paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(styleName); paraBldr.AppendRun(sSectionHead[i], StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(section.HeadingOAHvo); } int verse = (styleName == ScrStyleNames.SectionHead) ? 1 : 0; section.ContentOA = new StText(); section.VerseRefEnd = section.VerseRefStart = new ScrReference(book.CanonicalNum, 1, verse, m_scr.Versification); return section; }
/// <summary> /// Executes in two distinct scenarios. /// /// 1. If disposing is true, the method has been called directly /// or indirectly by a user's code via the Dispose method. /// Both managed and unmanaged resources can be disposed. /// /// 2. If disposing is false, the method has been called by the /// runtime from inside the finalizer and you should not reference (access) /// other managed objects, as they already have been garbage collected. /// Only unmanaged resources can be disposed. /// </summary> /// <param name="disposing"></param> /// <remarks> /// If any exceptions are thrown, that is fine. /// If the method is being done in a finalizer, it will be ignored. /// If it is thrown by client code calling Dispose, /// it needs to be handled by fixing the bug. /// /// If subclasses override this method, they should call the base implementation. /// </remarks> protected virtual void Dispose(bool disposing) { //Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************"); // Must not be run more than once. if (m_isDisposed) return; if (disposing) { // Dispose managed resources here. if (m_ParaBldr != null) m_ParaBldr.Dispose(); } // Dispose unmanaged resources here, whether disposing is true or false. m_ParaBldr = null; m_cache = null; m_styleSheet = null; m_scr = null; m_undoManager = null; m_importCallbacks = null; m_ScrSectionHeadParaProxy = null; m_DefaultIntroSectionHeadParaProxy = null; m_DefaultScrParaProxy = null; m_DefaultIntroParaProxy = null; m_BTStrBldrs = null; m_SavedParaBldr = null; m_CurrFootnote = null; m_ttpChapterNumber = null; m_sPrevBook = null; m_scrBook = null; m_currSection = null; m_isDisposed = true; }
public void ContentOnlyParaToSectionHead() { CheckDisposed(); // create a book IScrBook book = CreateGenesis(); // Create a section IScrSection sectionCur = CreateSection(book, "My aching head!"); // create paragraph one holding text that really belongs in the section head StTxtParaBldr paraBldr = new StTxtParaBldr(Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("Ouch!", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.ContentOAHvo); Assert.AreEqual(1, sectionCur.ContentOA.ParagraphsOS.Count); m_draftView.RefreshDisplay(); // Set the IP at the beginning of the paragraph in the section. int iBook = 0; // assume that iBook 0 is Genesis int iSectionIP = 0; //section with content to become section head int iParaIP = 0; int ichIP = 0; // Put the IP in place m_draftView.SetInsertionPoint(iBook, iSectionIP, iParaIP, ichIP, true); // ApplyStyle should not add a scripture section m_draftView.ApplyStyle(ScrStyleNames.SectionHead); Assert.AreEqual(1, book.SectionsOS.Count, "Should not add a section"); // setup variables for testing IScrSection section = book.SectionsOS[iSectionIP]; // Verify verse start and end refs Assert.AreEqual(1001001, section.VerseRefMin, "Existing section should have same verse start ref"); Assert.AreEqual(1001001, section.VerseRefMax, "New section should have correct verse end ref"); // Verify section head Assert.AreEqual(2, section.HeadingOA.ParagraphsOS.Count, "Should have 2 heading paragraphs"); Assert.AreEqual("My aching head!", ((StTxtPara)section.HeadingOA.ParagraphsOS.FirstItem).Contents.Text); Assert.AreEqual("Ouch!", ((StTxtPara)section.HeadingOA.ParagraphsOS[1]).Contents.Text); ITsTextProps ttp = ((StTxtPara)section.HeadingOA.ParagraphsOS[1]).StyleRules; Assert.AreEqual(ScrStyleNames.SectionHead, ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); // Verify Contents - should now be an empty paragraph Assert.AreEqual(1, section.ContentOA.ParagraphsOS.Count, "Should have one content paragraph"); StTxtPara para = (StTxtPara) section.ContentOA.ParagraphsOS.FirstItem; Assert.AreEqual(0, para.Contents.Length); Assert.AreEqual(ScrStyleNames.NormalParagraph, para.StyleRules.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); // Verify that selection is in second para of the section head Assert.IsTrue(m_draftView.TeEditingHelper.InSectionHead, "Should be in section heading"); Assert.AreEqual(0, m_draftView.TeEditingHelper.BookIndex); Assert.AreEqual(0, m_draftView.TeEditingHelper.SectionIndex); Assert.AreEqual(1, m_draftView.ParagraphIndex); }
public void AdjustAnnotationReferences_WithQuote() { IScrBook genesis = m_scrInMemoryCache.AddBookToMockedScripture(1, "Genesis"); m_scrInMemoryCache.AddTitleToMockedBook(genesis.Hvo, "Genesis"); // Introduction section IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(genesis.Hvo); m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Introduction head", ScrStyleNames.IntroSectionHead); StTxtPara para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.IntroParagraph); m_scrInMemoryCache.AddRunToMockedPara(para, "An intro to Genesis", null); para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.IntroParagraph); m_scrInMemoryCache.AddRunToMockedPara(para, "Contains quoted text - the quote", null); section.AdjustReferences(true); ScrBookAnnotations annotations = (ScrBookAnnotations)m_scr.BookAnnotationsOS[0]; BCVRef ref1 = new BCVRef(1, 1, 0); int iPos; StTxtParaBldr quoteBldr = new StTxtParaBldr(m_scrInMemoryCache.Cache); quoteBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.Remark); quoteBldr.AppendRun("the quote", StyleUtils.CharStyleTextProps(null, m_scrInMemoryCache.Cache.DefaultVernWs)); IScrScriptureNote note = annotations.InsertNote(ref1, ref1, null, null, LangProject.kguidAnnConsultantNote, -1, 0, 0, quoteBldr, null, null, null, out iPos); Assert.IsNotNull(note); m_scr.AdjustAnnotationReferences(); Assert.AreEqual(para.Hvo, note.BeginObjectRA.Hvo); Assert.AreEqual(23, note.BeginOffset); Assert.AreEqual(32, note.EndOffset); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="T:ScrAnnotationInfo"/> class. /// </summary> /// <param name="guidAnnotationType">GUID representing the annotation type.</param> /// <param name="bldrDiscussion">A single Tsstring builder for a one-paragraph /// discussion.</param> /// <param name="ichOffset">character offset where this annotation belongs in the /// "owning" para.</param> /// <param name="startReference">The starting Scripture reference of the annotation.</param> /// <param name="endReference">The ending Scripture reference of the annotation.</param> /// ------------------------------------------------------------------------------------ public ScrAnnotationInfo(Guid guidAnnotationType, StTxtParaBldr bldrDiscussion, int ichOffset, int startReference, int endReference) : this(guidAnnotationType, new List<StTxtParaBldr>(new StTxtParaBldr[] { bldrDiscussion }), null, null, null, ichOffset, startReference, endReference, DateTime.MinValue) { }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initialize the text for the paragraph with the specified builder, or create an /// empty paragraph if the builder is null. /// </summary> /// <param name="bldr">paragraph builder</param> /// <param name="text">StText</param> /// ------------------------------------------------------------------------------------ private void InitializeText(StTxtParaBldr bldr, IStText text) { if (bldr == null) { IStTxtPara para = (StTxtPara)text.ParagraphsOS.Append(new StTxtPara()); para.Contents.UnderlyingTsString = StringUtils.MakeTss(String.Empty, Cache.DefaultAnalWs); para.StyleRules = StyleUtils.ParaStyleTextProps(ScrStyleNames.Remark); } else { bldr.CreateParagraph(text.Hvo); } }
public void ContentLastIntroParaToIntroSectionHead() { CheckDisposed(); // create a book IScrBook book = CreateGenesis(); // Create section one - an introduction section IScrSection section1 = CreateSection(ScrStyleNames.IntroSectionHead, book, "My aching head!"); // create paragraph one holding chapter 1 StTxtParaBldr paraBldr = new StTxtParaBldr(Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.IntroParagraph); paraBldr.AppendRun("This is the first book of the Bible", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(section1.ContentOAHvo); // create paragraph two holding text that really belongs in the section head paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.IntroParagraph); paraBldr.AppendRun("Ouch!", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(section1.ContentOAHvo); Assert.AreEqual(2, section1.ContentOA.ParagraphsOS.Count); // finish the section info section1.AdjustReferences(); // Create section two IScrSection section2 = CreateSection(book, "My other aching head!"); // create paragraph three holding chapter 2 paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("2", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("Thus the heavens and the earth were completed in all their vast array. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(section2.ContentOAHvo); Assert.AreEqual(1, section2.ContentOA.ParagraphsOS.Count); // finish the section info section2.AdjustReferences(); m_draftView.RefreshDisplay(); // Set the IP at the beginning of the 2nd paragraph in the 1st section. int iBook = 0; // assume that iBook 0 is Genesis int iSectionIP = 0; //intro section int iParaIP = 1; // last intro para int ichIP = 0; // Put the IP in place m_draftView.SetInsertionPoint(iBook, iSectionIP, iParaIP, ichIP, true); // ApplyStyle should create a new section with the intro paragraph as the // section head and an empty body. m_draftView.ApplyStyle(ScrStyleNames.IntroSectionHead); Assert.AreEqual(3, book.SectionsOS.Count, "Should add a section"); // Verify verse start and end refs Assert.AreEqual(1001000, section1.VerseRefMin, "Existing section should have same verse start ref"); Assert.AreEqual(1001000, section1.VerseRefMax, "New section should have correct verse end ref"); section2 = (ScrSection) book.SectionsOS[1]; Assert.AreEqual(1001000, section2.VerseRefMin, "Existing section should have same verse start ref"); Assert.AreEqual(1001000, section2.VerseRefMax, "New section should have correct verse end ref"); // Verify Contents of section 1 Assert.AreEqual(1, section1.ContentOA.ParagraphsOS.Count); // Verify section head of section 2 Assert.AreEqual(1, section2.HeadingOA.ParagraphsOS.Count); Assert.AreEqual("Ouch!", ((StTxtPara)section2.HeadingOA.ParagraphsOS.FirstItem).Contents.Text); ITsTextProps ttp = ((StTxtPara)section2.HeadingOA.ParagraphsOS.FirstItem).StyleRules; Assert.AreEqual(ScrStyleNames.IntroSectionHead, ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); Assert.AreEqual(1, section2.ContentOA.ParagraphsOS.Count); Assert.IsNull(((StTxtPara)section2.ContentOA.ParagraphsOS.FirstItem).Contents.Text); ttp = ((StTxtPara)section2.ContentOA.ParagraphsOS.FirstItem).StyleRules; Assert.AreEqual(ScrStyleNames.IntroParagraph, ttp.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)); // Verify that selection is in first paragraph of section two heading Assert.IsTrue(m_draftView.TeEditingHelper.InSectionHead, "Should be in section heading"); Assert.AreEqual(0, m_draftView.TeEditingHelper.BookIndex); Assert.AreEqual(1, m_draftView.TeEditingHelper.SectionIndex); Assert.AreEqual(0, m_draftView.ParagraphIndex); }