Example #1
0
		/// ------------------------------------------------------------------------------------
		/// <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;
		}