/// ------------------------------------------------------------------------------------ /// <summary> /// Creates a section with optional heading/content paragraphs. /// </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="isIntro">True to create an intro section, false to create a /// normal scripture section</param> /// <param name="createHeadingPara">if true, heading paragraph will be created</param> /// <param name="createContentPara">if true, content paragraph will be created</param> /// <returns>The newly created <see cref="ScrSection"/></returns> /// ------------------------------------------------------------------------------------ private static ScrSection CreateSection(IScrBook book, int iSection, bool isIntro, bool createHeadingPara, bool createContentPara) { Debug.Assert(book != null); // Create an empty section. The end reference needs to be set to indicate to // AdjustReferences if the section is an intro section ScrSection section = (ScrSection)CreateEmptySection(book, iSection); section.VerseRefEnd = new ScrReference(book.CanonicalNum, 1, isIntro ? 0 : 1, book.Cache.LangProject.TranslatedScriptureOA.Versification); section.AdjustReferences(); // Add an empty paragraph to the section head. if (createHeadingPara) { string paraStyle = isIntro ? ScrStyleNames.IntroSectionHead : ScrStyleNames.SectionHead; StTxtParaBldr.CreateEmptyPara(book.Cache, section.HeadingOAHvo, paraStyle, book.Cache.DefaultVernWs); } // Add an empty paragraph to the section content. if (createContentPara) { string paraStyle = isIntro ? ScrStyleNames.IntroParagraph : ScrStyleNames.NormalParagraph; StTxtParaBldr.CreateEmptyPara(book.Cache, section.ContentOAHvo, paraStyle, book.Cache.DefaultVernWs); } return(section); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Creates a new section using the contents of the given paragraph as it's heading /// and the remaining paragraphs of this section as it's content. /// </summary> /// <param name="iPara">Index of paragraph to be changed to section head.</param> /// <param name="cParagraphs">Number of paragraphs changed.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ public IScrSection ChangeParagraphToSectionHead(int iPara, int cParagraphs) { ScrBook book = OwningBook; int iSection = 0; while (book.SectionsOS.HvoArray[iSection] != Hvo) { iSection++; Debug.Assert(iSection < book.SectionsOS.Count, "Couldn't find index of section " + Hvo); } //Set up parameters depending on the type of change iSection++; //New section follows original one. ScrSection newSection = (ScrSection)ScrSection.CreateEmptySection(book, iSection); // move paragraphs following the changed paragraphs, if any if (iPara + cParagraphs < ContentOA.ParagraphsOS.Count) { StText.MoveTextParagraphs(ContentOA, newSection.ContentOA, iPara + cParagraphs, false); } else { // if the paragraph was at the end of a section then we need to create a // blank content paragraph in the new section. string styleName = IsIntro ? ScrStyleNames.IntroParagraph : ScrStyleNames.NormalParagraph; StTxtParaBldr.CreateEmptyPara(book.Cache, newSection.ContentOAHvo, styleName, Cache.DefaultVernWs); } // move paragraphs to section head StText.MoveTextParagraphs(ContentOA, newSection.HeadingOA, iPara, false); // Make sure the references are correct for both the sections. AdjustReferences(); newSection.AdjustReferences(); // notify views that new section exists m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, book.Hvo, (int)ScrBook.ScrBookTags.kflidSections, iSection, 1, 0); return(newSection as IScrSection); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Creates a new section using the contents of the given section heading as it's content /// and the remaining paragraphs above the selection will become the heading of the new /// section /// </summary> /// <param name="iPara">index of paragraph to be changed to section content</param> /// <param name="cParagraphs">number of paragraphs to move</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ public IScrSection ChangeParagraphToSectionContent(int iPara, int cParagraphs) { ScrBook book = OwningBook; int iSection = 0; while (book.SectionsOS.HvoArray[iSection] != Hvo) { iSection++; Debug.Assert(iSection < book.SectionsOS.Count, "Couldn't find index of section " + Hvo); } ScrSection newSection = (ScrSection)ScrSection.CreateEmptySection(book, iSection); // move paragraphs preceding the changed paragraphs, if any if (iPara > 0) { StText.MoveTextParagraphs(HeadingOA, newSection.HeadingOA, iPara - 1, true); } else { // if the paragraph was at the beginning of a section then we need to create a // blank heading paragraph in the new section. string styleName = IsIntro ? ScrStyleNames.IntroSectionHead : ScrStyleNames.SectionHead; StTxtParaBldr.CreateEmptyPara(book.Cache, newSection.HeadingOAHvo, styleName, Cache.DefaultVernWs); } // move paragraphs to section head StText.MoveTextParagraphs(HeadingOA, newSection.ContentOA, cParagraphs - 1, true); // Make sure the sections have correct references AdjustReferences(); newSection.AdjustReferences(); // notify views that new section exists m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, book.Hvo, (int)ScrBook.ScrBookTags.kflidSections, iSection, 1, 0); return(newSection as IScrSection); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Divides the current section into two sections with section index iSection and /// iSection + 1. Moves the selected paragraphs from the heading of /// the current section into the content of the current section. /// </summary> /// <param name="iSection">index of the current section</param> /// <param name="iParaStart">index of the first heading paragraph to be moved into /// content</param> /// <param name="iParaEnd">index of the last heading paragraph to be moved into /// content</param> /// ------------------------------------------------------------------------------------ public void SplitSectionHeading(int iSection, int iParaStart, int iParaEnd) { // Create empty section after the current section ScrSection newSection = (ScrSection)ScrSection.CreateEmptySection(OwningBook, iSection + 1); // Move Heading and Content to new section: // the heading paras after selection, StText.MoveTextParagraphs(this.HeadingOA, newSection.HeadingOA, iParaEnd + 1, false); // all content paras StText.MoveTextParagraphs(this.ContentOA, newSection.ContentOA, 0, false); // Move current selection in heading to content // note: because we already moved the "heading paras after selection" // we will now move all paras from start of selection MoveHeadingParasToContent(iParaStart); // Adjust references for the two sections AdjustReferences(); newSection.AdjustReferences(); Cache.PropChanged(OwnerHVO, (int)ScrBook.ScrBookTags.kflidSections, iSection + 1, 1, 0); }
public void MoveNext_SpacesInVerses() { CheckDisposed(); ScrSection sectionCur = new ScrSection(); m_genesis.SectionsOS.Append(sectionCur); // Create a section head for this section sectionCur.HeadingOA = new StText(); StTxtParaBldr paraBldr = new StTxtParaBldr(Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.SectionHead); paraBldr.AppendRun("My aching head!", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.CreateParagraph(sectionCur.HeadingOAHvo); sectionCur.ContentOA = new StText(); paraBldr = new StTxtParaBldr(Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalParagraph); paraBldr.AppendRun("1", StyleUtils.CharStyleTextProps(ScrStyleNames.ChapterNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("Verse One. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.AppendRun("2", StyleUtils.CharStyleTextProps(ScrStyleNames.VerseNumber, Cache.DefaultVernWs)); paraBldr.AppendRun(" Verse Two. ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.AppendRun("3", StyleUtils.CharStyleTextProps(ScrStyleNames.VerseNumber, Cache.DefaultVernWs)); paraBldr.AppendRun("Verse Three.", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); paraBldr.AppendRun("4", StyleUtils.CharStyleTextProps(ScrStyleNames.VerseNumber, Cache.DefaultVernWs)); paraBldr.AppendRun(" ", StyleUtils.CharStyleTextProps(null, Cache.DefaultVernWs)); StTxtPara para = paraBldr.CreateParagraph(sectionCur.ContentOA.Hvo); sectionCur.AdjustReferences(); ScrTxtPara stPara = new ScrTxtPara(Cache, para.Hvo); ScrVerseSet verseSet = new ScrVerseSet(stPara); // Iterate through the verses in the paragraph ScrVerse verse; Assert.IsTrue(verseSet.MoveNext()); verse = (ScrVerse)verseSet.Current; Assert.AreEqual("1", verse.Text.Text); Assert.AreEqual(01001001, verse.StartRef); Assert.AreEqual(01001001, verse.EndRef); Assert.IsTrue(verseSet.MoveNext()); verse = (ScrVerse)verseSet.Current; Assert.AreEqual("Verse One. ", verse.Text.Text); Assert.AreEqual(01001001, verse.StartRef); Assert.AreEqual(01001001, verse.EndRef); Assert.IsTrue(verseSet.MoveNext()); verse = (ScrVerse)verseSet.Current; Assert.AreEqual("2 Verse Two. ", verse.Text.Text); Assert.AreEqual(01001002, verse.StartRef); Assert.AreEqual(01001002, verse.EndRef); Assert.IsTrue(verseSet.MoveNext()); verse = (ScrVerse)verseSet.Current; Assert.AreEqual("3Verse Three.", verse.Text.Text); Assert.AreEqual(01001003, verse.StartRef); Assert.AreEqual(01001003, verse.EndRef); Assert.IsTrue(verseSet.MoveNext()); verse = (ScrVerse)verseSet.Current; Assert.AreEqual("4 ", verse.Text.Text); Assert.AreEqual(01001004, verse.StartRef); Assert.AreEqual(01001004, verse.EndRef); Assert.IsFalse(verseSet.MoveNext()); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Called to make the test data for the tests /// </summary> /// ------------------------------------------------------------------------------------ protected override void CreateTestData() { base.CreateTestData(); m_scrInMemoryCache.InitializeScrPublications(); m_genesis = m_scrInMemoryCache.AddBookWithTwoSections(1, "Genesis"); // Set up an introduction for the book IScrSection intro = new ScrSection(); m_genesis.SectionsOS.InsertAt(intro, 0); intro.ContentOA = new StText(); intro.HeadingOA = new StText(); IStTxtPara introPara = new StTxtPara(); intro.ContentOA.ParagraphsOS.Append(introPara); introPara.Contents.Text = "This is my introduction"; intro.HeadingOA.ParagraphsOS.Append(new StTxtPara()); intro.VerseRefEnd = 01001000; intro.AdjustReferences(); IScrSection section1 = m_genesis.SectionsOS[1]; StTxtPara para1 = (StTxtPara)section1.ContentOA.ParagraphsOS[0]; m_scrInMemoryCache.AddRunToMockedPara(para1, "2", ScrStyleNames.VerseNumber); section1.AdjustReferences(); IScrSection section2 = m_genesis.SectionsOS[2]; StTxtPara para2 = (StTxtPara)section2.ContentOA.ParagraphsOS[0]; m_scrInMemoryCache.AddRunToMockedPara(para2, "3", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(para2, "some verse text", null); m_scrInMemoryCache.AddRunToMockedPara(para2, "4", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(para2, "some more verse text", null); section2.AdjustReferences(); IScrSection section3 = m_scrInMemoryCache.AddSectionToMockedBook(m_genesis.Hvo); StTxtPara para3_1 = m_scrInMemoryCache.AddParaToMockedSectionContent(section3.Hvo, ScrStyleNames.NormalParagraph); m_scrInMemoryCache.AddRunToMockedPara(para3_1, "2", ScrStyleNames.ChapterNumber); m_scrInMemoryCache.AddRunToMockedPara(para3_1, "1", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(para3_1, "text of verse 1.", null); StTxtPara para3_2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section3.Hvo, ScrStyleNames.NormalParagraph); m_scrInMemoryCache.AddRunToMockedPara(para3_2, "2", ScrStyleNames.VerseNumber); m_scrInMemoryCache.AddRunToMockedPara(para3_2, "text of verse 2.", null); section3.AdjustReferences(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adjust section refs if needed. /// Called by a ChangeWatcher if any paras in StText.ParagraphsOS are added, deleted, /// or moved. /// </summary> /// <param name="text">the StText whose Paragraphs collection was changed</param> /// <param name="ivMin">index of the first para inserted or deleted in the StText</param> /// ------------------------------------------------------------------------------------ public static void AdjustSectionRefsForStTextParaChg(IStText text, int ivMin) { // We expect that this StText is part of ScrSection.Content Debug.Assert(text.Cache.GetOwningFlidOfObject(text.Hvo) == (int)ScrSection.ScrSectionTags.kflidContent); ScrSection section = new ScrSection(text.Cache, text.Cache.GetOwnerOfObject(text.Hvo)); section.AdjustReferences(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adjust section refs for the edited paragraph. /// Called by a ChangeWatcher if any StTxtPara.Contents is modified. /// </summary> /// <param name="ivMin">Character index where text was added and/or deleted</param> /// <param name="cvIns">Count of characters inserted</param> /// <param name="cvDel">Count of characters deleted</param> /// ------------------------------------------------------------------------------------ public void ProcessChapterVerseNums(int ivMin, int cvIns, int cvDel) { // We expect that our para is part of a ScrSection.Content Debug.Assert(m_cache.GetOwningFlidOfObject(OwnerHVO) == (int)ScrSection.ScrSectionTags.kflidContent); // If we join a paragraph with an empty paragraph, there's nothing for us to do. if (cvIns == 0 && cvDel == 0) return; // Now adjust our section refs if necessary ScrSection section = new ScrSection(m_cache, m_cache.GetOwnerOfObject(OwnerHVO)); section.AdjustReferences(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adjust the start and end section references to reflect the content of the section. /// </summary> /// <param name="fIsIntro">if set to <c>true</c> this is an intro section.</param> /// ------------------------------------------------------------------------------------ public void AdjustReferences(bool fIsIntro) { // If this is not the first section then get the previous section's end reference // as a starting point for this section ScrSection prevSection = PreviousSection; ScrReference currentRefStart = new ScrReference(OwningBook.CanonicalNum, 1, 0, Cache.LangProject.TranslatedScriptureOA.Versification); if (prevSection != null) { currentRefStart.BBCCCVVV = prevSection.VerseRefEnd; } // If this is not an intro section then start the verse at 1 so it will not // be an intro section. if (currentRefStart.Verse == 0 && !fIsIntro) { currentRefStart.Verse = 1; } // Default the starting reference for the case that there is no content. int newSectionStart = currentRefStart; // Scan the paragraphs of the section to get the min and max references ScrReference refMin = new ScrReference(currentRefStart); ScrReference refMax = new ScrReference(currentRefStart); ScrReference currentRefEnd = new ScrReference(currentRefStart); bool isFirstTextRun = true; if (ContentOA != null) { foreach (StTxtPara para in ContentOA.ParagraphsOS) { ITsString paraContents = para.Contents.UnderlyingTsString; int iLim = paraContents.RunCount; RefRunType runType = RefRunType.None; for (int iRun = 0; iRun < iLim;) { // for very first run in StText we want to set VerseRefStart int iLimTmp = (iRun == 0 && isFirstTextRun) ? iRun + 1 : iLim; runType = Scripture.GetNextRef(iRun, iLimTmp, paraContents, true, ref currentRefStart, ref currentRefEnd, out iRun); // If a verse or chapter was found, adjust the max and min if the current // verse refs are less than min or greater than max if (runType != RefRunType.None) { // If a chapter or verse is found at the start of the section, then use that // reference instead of the one from the previous section as the min and max. if (isFirstTextRun || currentRefStart < refMin) { refMin.BBCCCVVV = currentRefStart.BBCCCVVV; } if (isFirstTextRun || currentRefEnd > refMax) { refMax.BBCCCVVV = currentRefEnd.BBCCCVVV; } } // after the first run, store the starting reference if (isFirstTextRun) { newSectionStart = currentRefStart; isFirstTextRun = false; } } } } // Store the min and max as the reference range for the section VerseRefStart = newSectionStart; VerseRefMin = refMin; VerseRefMax = refMax; // Store the last reference for the section. bool verseRefEndHasChanged = (VerseRefEnd != currentRefEnd.BBCCCVVV); bool verseRefEndChapterHasChanged = (BCVRef.GetChapterFromBcv(VerseRefEnd) != currentRefEnd.Chapter); VerseRefEnd = currentRefEnd; // If the last reference changes then the next section's references have potentially been invalidated ScrSection nextSection = NextSection; if (nextSection != null) { if ((verseRefEndChapterHasChanged && !nextSection.StartsWithChapterNumber) || (verseRefEndHasChanged && !nextSection.StartsWithVerseOrChapterNumber)) { nextSection.AdjustReferences(); } } }
/// ------------------------------------------------------------------------------------ /// <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="scrInMemoryCache">in-memory cache to use for testing</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. Can be a simple string /// or a format string. (See CreateText for the definition of the format string)</param> /// <param name="paraStyleName">paragraph style to apply to the section head</param> /// <returns>The newly created section</returns> /// ------------------------------------------------------------------------------------ internal static ScrSection CreateSection(ScrInMemoryFdoCache scrInMemoryCache, IScrBook book, string sSectionHead, string paraStyleName) { // Create a section ScrSection section = new ScrSection(); book.SectionsOS.Append(section); // Create a section head for this section section.HeadingOA = new StText(); if (sSectionHead.Length == 0 || sSectionHead[0] != '\\') { // create a simple section head with no character style StTxtParaBldr paraBldr = new StTxtParaBldr(scrInMemoryCache.Cache); paraBldr.ParaProps = StyleUtils.ParaStyleTextProps(paraStyleName); paraBldr.AppendRun(sSectionHead, StyleUtils.CharStyleTextProps(null, scrInMemoryCache.Cache.DefaultVernWs)); paraBldr.CreateParagraph(section.HeadingOAHvo); } else { // Create a more complex section head from the given format string // insert a new para in the title StTxtPara para = new StTxtPara(); section.HeadingOA.ParagraphsOS.Append(para); // set the para's fields scrInMemoryCache.AddFormatTextToMockedPara(book, para, sSectionHead, scrInMemoryCache.Cache.DefaultVernWs); para.StyleRules = StyleUtils.ParaStyleTextProps(paraStyleName); } section.ContentOA = new StText(); section.AdjustReferences(); return section; }