/// ------------------------------------------------------------------------------------ /// <summary> /// Makes changes in text structure when the context of the new paragraph style does not /// match the context of the current paragraph style. /// </summary> /// <remarks>This method properly adjusts the text structure for newStyle; the style is /// not applied here - the caller should do that.</remarks> /// <param name="selHelper">the selection to which the new style is being applied</param> /// <param name="curStyle">current style at the selection anchor</param> /// <param name="newStyle">new style to be applied (has a new style context)</param> /// <returns>Returns true if the style change can now be applied.</returns> /// ------------------------------------------------------------------------------------ protected virtual bool AdjustTextStructure(SelectionHelper selHelper, IStStyle curStyle, IStStyle newStyle) { SelLevInfo[] top = selHelper.GetLevelInfo(SelectionHelper.SelLimitType.Top); SelLevInfo[] bottom = selHelper.GetLevelInfo(SelectionHelper.SelLimitType.Bottom); ILocationTracker tracker = ((ITeView)Control).LocationTracker; int scrLevelCount = tracker.GetLevelCount((int)ScrSection.ScrSectionTags.kflidContent); // Adjustments will only be done in section level selections. if (top.Length != scrLevelCount || bottom.Length != scrLevelCount) return true; // CASE 1: Change a section head to a content paragraph // If style of paragraphs of the section heading are changed to something // that is not a section head style, restructure heading paragraphs if (top[1].tag == (int)ScrSection.ScrSectionTags.kflidHeading && newStyle.Structure == StructureValues.Body) { // these will be adjusted to the new indices after the structure is changed int iSection = tracker.GetSectionIndexInBook(selHelper, SelectionHelper.SelLimitType.Top); int iPara; bool firstSectionInContext = (iSection == 0); int iBook = tracker.GetBookIndex(selHelper, SelectionHelper.SelLimitType.Top); ScrBook book = BookFilter.GetBook(iBook); ScrSection section = (ScrSection)book.SectionsOS[iSection]; // for an interior section, need to check context of next section if (!firstSectionInContext) { IScrSection prevSection = book.SectionsOS[iSection - 1]; firstSectionInContext = !SectionsHaveSameContext(section, prevSection); } // If all paragraphs of heading are selected, merge selected section // with previous section if (AreAllParagraphsSelected(top, bottom, section.HeadingOA)) { if (!firstSectionInContext) { iPara = ScrSection.MergeIntoPreviousSectionContent(m_cache, book, iSection); iSection--; } else { // Just need to move all heading paragraphs to the content. The move // method will create a new empty heading paragraph. iPara = 0; section.MoveHeadingParasToContent(0); } } // If selection starts at first paragraph of the heading, move heading paragraphs to // content of previous section. else if (top[0].ihvo == 0) { if (!firstSectionInContext) { iPara = ScrSection.MoveHeadingToPreviousSectionContent(m_cache, book, iSection, bottom[0].ihvo); iSection--; } else { // In this case, we want the selected paragraphs to become the content // of a new section, and the preceding paragraph(s) to become the // heading of the new section. section.ChangeParagraphToSectionContent(top[0].ihvo, bottom[0].ihvo - top[0].ihvo + 1); // update insertion point to first paragraph(s) of new section content iPara = 0; } } else { // If selection bottoms at the last paragraph of the heading, move heading // paragraphs to content of this section if (section.HeadingOA.ParagraphsOS.Count - 1 == bottom[0].ihvo) { section.MoveHeadingParasToContent(top[0].ihvo); iPara = 0; } else // The selection must be only inner paragraphs in the section head, // not including the first or last paragraphs. // In this case, we want the selected paragraph(s) to become content for // the heading paragraph(s) above it, and the following section head // paragraph(s) become the heading of a new section object. { int iParaStart = top[0].ihvo; int iParabottom = bottom[0].ihvo; section.SplitSectionHeading(iSection, iParaStart, iParabottom); iPara = 0; } } // Select all paragraphs in content that were part of section heading (and have // now been moved to iSection, iPara) SetInsertionPoint(iBook, iSection, iPara, 0, false); // Get bottom point of selection and update it to point to beginning of // last paragraph of old heading. Use offsets of current selection. SelectionHelper newHelper = SelectionHelper.Create(Callbacks.EditedRootBox.Site); SelLevInfo[] levInfo = newHelper.GetLevelInfo(SelectionHelper.SelLimitType.End); levInfo[0].ihvo += bottom[0].ihvo - top[0].ihvo; newHelper.SetLevelInfo(SelectionHelper.SelLimitType.End, levInfo); newHelper.IchAnchor = selHelper.GetIch(SelectionHelper.SelLimitType.Top); newHelper.IchEnd = selHelper.GetIch(SelectionHelper.SelLimitType.Bottom); newHelper.SetSelection(true); } //bottom of CASE 1 "Change a section head to a scripture paragraph" // CASE 2: Change scripture paragraph to a section head // - only if the new style has "section head" structure, the selection is in // one paragraph, and that paragraph is part of the section content else if (top[1].tag == (int)ScrSection.ScrSectionTags.kflidContent && newStyle.Structure == StructureValues.Heading) { // Check selected paragraphs for chapter or verse numbers - style will not be // changed if any are found. ScrSection section = new ScrSection(m_cache, tracker.GetSectionHvo(selHelper, SelectionHelper.SelLimitType.Top)); for (int i = top[0].ihvo; i <= bottom[0].ihvo; i++) { ScrTxtPara para = new ScrTxtPara(m_cache, section.ContentOA.ParagraphsOS.HvoArray[i]); if (para.HasChapterOrVerseNumbers()) { // Cancel the request if chapter or verse numbers are present. // display message box if not running in a test if (!InTestMode) { MessageBox.Show(Control, TeResourceHelper.GetResourceString("kstidParaHasNumbers"), TeResourceHelper.GetResourceString("kstidApplicationName"), MessageBoxButtons.OK); } return false; } } int iBook = tracker.GetBookIndex(selHelper, SelectionHelper.SelLimitType.Top); int iSection = tracker.GetSectionIndexInBook(selHelper, SelectionHelper.SelLimitType.Top); int iPara; ScrBook book = section.OwningBook; // End of book is end of context type bool lastSectionInContext = (iSection == book.SectionsOS.Count - 1); // for an interior section, need to check context of next section if (!lastSectionInContext) { IScrSection nextSection = book.SectionsOS[iSection + 1]; lastSectionInContext = !SectionsHaveSameContext(section, nextSection); } if (AreAllParagraphsSelected(top, bottom, section.ContentOA)) { if (!lastSectionInContext) { // Need to combine this section with the following section. // Heading of combined section will be section1.Heading + // section1.Content + section2.Heading iPara = section.HeadingOA.ParagraphsOS.Count; IScrSection nextSection = book.SectionsOS[iSection + 1]; StText.MoveTextContents(section.ContentOA, nextSection.HeadingOA, false); StText.MoveTextContents(section.HeadingOA, nextSection.HeadingOA, false); nextSection.AdjustReferences(); book.SectionsOS.RemoveAt(iSection); } else { // Just need to move all content paragraphs to the heading. The move // method will create a new empty content paragraph. iPara = section.HeadingOA.ParagraphsOS.Count; section.MoveContentParasToHeading(section.ContentOA.ParagraphsOS.Count - 1); } } else if (top[0].ihvo == 0) { // Move the first content paragraphs to become the last para of the // section head section.MoveContentParasToHeading(bottom[0].ihvo); iPara = section.HeadingOA.ParagraphsOS.Count - (bottom[0].ihvo - top[0].ihvo + 1); } else if (bottom[0].ihvo == section.ContentOA.ParagraphsOS.Count - 1 && !lastSectionInContext) { // Move the last content paragraphs to become the first para of the next // section in the book. ScrSection.MoveContentParasToNextSectionHeading(m_cache, book, iSection, top[0].ihvo); // update insertion point to first paragraph(s) of next section head iSection++; iPara = 0; } else { // In this case, we want the selected paragraph to become the heading // of a new section, and the following paragraph(s) to become the // content of the new section object. section.ChangeParagraphToSectionHead(top[0].ihvo, bottom[0].ihvo - top[0].ihvo + 1); // update insertion point to first paragraph(s) of next section head iSection++; iPara = 0; } // Select all paragraphs in content that were part of section heading (and have // now been moved to iSection, iPara) SetInsertionPoint((int)ScrSection.ScrSectionTags.kflidHeading, iBook, iSection, iPara); // Get bottom point of selection and update it to point to beginning of // last paragraph of old heading. Use offsets of current selection. SelectionHelper newHelper = SelectionHelper.Create(Callbacks.EditedRootBox.Site); SelLevInfo[] levInfo = newHelper.GetLevelInfo(SelectionHelper.SelLimitType.End); levInfo[0].ihvo += bottom[0].ihvo - top[0].ihvo; newHelper.SetLevelInfo(SelectionHelper.SelLimitType.End, levInfo); newHelper.IchAnchor = selHelper.GetIch(SelectionHelper.SelLimitType.Top); newHelper.IchEnd = selHelper.GetIch(SelectionHelper.SelLimitType.Bottom); newHelper.SetSelection(true); } return true; }
public void HasChapterOrVerseNumbers_InScripture() { CheckDisposed(); // add section and paragraph IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(m_book.Hvo); StTxtPara para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.NormalParagraph); m_scrInMemoryCache.AddRunToMockedPara(para, "1", ScrStyleNames.ChapterNumber); m_scrInMemoryCache.AddRunToMockedPara(para, "some text", null); section.AdjustReferences(); ScrTxtPara scrPara = new ScrTxtPara(Cache, para.Hvo); Assert.IsTrue(scrPara.HasChapterOrVerseNumbers()); }