public override void Initialize()
		{
			CheckDisposed();
			base.Initialize();
			m_inMemoryCache.InitializeAnnotationDefs();
			InstallVirtuals(@"Language Explorer\Configuration\Words\AreaConfiguration.xml",
				new string[] { "SIL.FieldWorks.IText.ParagraphSegmentsVirtualHandler", "SIL.FieldWorks.IText.OccurrencesInTextsVirtualHandler" });
			m_text = new Text();
			Cache.LangProject.TextsOC.Add(m_text);
			m_para = new ScrTxtPara();
			m_stText = new StText();
			m_text.ContentsOA = m_stText;
			m_stText.ParagraphsOS.Append(m_para);
			ktagParaSegments = InterlinVc.ParaSegmentTag(Cache);
			m_wsVern = Cache.DefaultVernWs;
		}
Пример #2
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Creates a Back Translation for the stuff in Exodus with the following layout:
		///
		///			()
		///		   BT Heading 1
		///	BT Intro text
		///		   BT Heading 2
		///	(1)1BT Verse one.
		///
		///	(1) = chapter number 1
		/// </summary>
		/// ------------------------------------------------------------------------------------
		protected void CreatePartialExodusBT(int wsAnal)
		{
			IScrBook book = ScrBook.FindBookByID(m_scr, 2);
			IScrSection section = book.SectionsOS[0];
			ScrTxtPara para = new ScrTxtPara(Cache, section.HeadingOA.ParagraphsOS.HvoArray[0]);
			CmTranslation trans = (CmTranslation)para.GetOrCreateBT();
			m_scrInMemoryCache.AddRunToMockedTrans(trans, wsAnal, "BT Heading 1", null);

			para = new ScrTxtPara(Cache, section.ContentOA.ParagraphsOS.HvoArray[0]);
			trans = (CmTranslation)para.GetOrCreateBT();
			m_scrInMemoryCache.AddRunToMockedTrans(trans, wsAnal, "BT Intro text", null);

			section = book.SectionsOS[1];
			para = new ScrTxtPara(Cache, section.HeadingOA.ParagraphsOS.HvoArray[0]);
			trans = (CmTranslation)para.GetOrCreateBT();
			m_scrInMemoryCache.AddRunToMockedTrans(trans, wsAnal, "BT Heading 2", null);

			para = new ScrTxtPara(Cache, section.ContentOA.ParagraphsOS.HvoArray[0]);
			trans = (CmTranslation)para.GetOrCreateBT();
			m_scrInMemoryCache.AddRunToMockedTrans(trans, wsAnal, "1", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedTrans(trans, wsAnal, "1", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedTrans(trans, wsAnal, "BT Verse one", null);
		}
Пример #3
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Common utility for the CurrentRef* properties
		/// </summary>
		/// <param name="selection"></param>
		/// <param name="selLimit">The limit of the selection (anchor, end, etc.) to get the
		/// reference of</param>
		/// <returns>the start and end reference of the given selection, as an array of two
		/// ScrReference objects</returns>
		/// ------------------------------------------------------------------------------------
		protected virtual ScrReference[] GetCurrentRefRange(SelectionHelper selection,
			SelectionHelper.SelLimitType selLimit)
		{
			if (m_cache == null || selection == null || BookFilter == null)
				return new ScrReference[] {ScrReference.Empty, ScrReference.Empty};

			ILocationTracker tracker = ((ITeView)Control).LocationTracker;

			// If there is a current book...
			BCVRef start = new BCVRef();
			BCVRef end = new BCVRef();

			int iBook = tracker.GetBookIndex(selection, selLimit);
			if (iBook >= 0 && BookFilter.BookCount > 0)
			{
				try
				{
					ScrBook book = BookFilter.GetBook(iBook);

					// if there is not a current section, then use the book and chapter/verse of 0.
					int hvoSection = tracker.GetSectionHvo(CurrentSelection, selLimit);
					if (hvoSection >= 0)
					{
						// If there is a section...
						ScrSection section = new ScrSection(m_cache, hvoSection);
						int paraHvo = selection.GetLevelInfoForTag(
							(int)StText.StTextTags.kflidParagraphs, selLimit).hvo;
						ScrTxtPara scrPara = new ScrTxtPara(m_cache, paraHvo);
						// Get the ich at either the beginning or the end of the selection,
						// as specified with limit. (NB that this is relative to the property, not the whole paragraph.)
						int ich;
						// Get the TsString, whether in vern or BT
						ITsString tss;
						SelLevInfo segInfo;
						int refWs;
						if (selection.GetLevelInfoForTag(StTxtPara.SegmentsFlid(Cache), selLimit, out segInfo))
						{
							// selection is in a segmented BT segment. Figure the reference based on where the segment is
							// in the underlying paragraph.
							tss = scrPara.Contents.UnderlyingTsString; // for check below on range of ich.
							CmBaseAnnotation seg = new CmBaseAnnotation(Cache, segInfo.hvo);
							ich = seg.BeginOffset;
							Debug.Assert(seg.BeginObjectRAHvo == scrPara.Hvo);
							refWs = -1; // ich is in the paragraph itself, not some CmTranslation
						}
						else
						{
							ich = selection.GetIch(selLimit);
							// Get the TsString, whether in vern or BT
							tss = selection.GetTss(selLimit);
							refWs = GetCurrentBtWs(selLimit); // figures out whether it's in a CmTranslation or the para itself.
						}
						Debug.Assert(tss == null || ich <= tss.Length);
						if (tss != null && ich <= tss.Length)
						{
							scrPara.GetBCVRefAtPosition(refWs, ich, true, out start, out end);

							// If the chapter number is 0, then use the chapter from the section reference
							if (end.Chapter == 0)
								end.Chapter = BCVRef.GetChapterFromBcv(section.VerseRefMin);
							if (start.Chapter == 0)
								start.Chapter = BCVRef.GetChapterFromBcv(section.VerseRefMin);
						}
					}
					else
					{
						// either it didn't find a level or it didn't find an index. Either way,
						// it couldn't find a section.
						start.Book = end.Book = book.CanonicalNum;
					}
				}
				catch
				{
					// Bummer man, something went wrong... don't sweat it though, it happens...
					// This can occur if you are in the introduction or other location that lacks
					// relevant information or other necessary stuff.
				}
			}
			return new ScrReference[] {new ScrReference(start, m_scr.Versification),
				new ScrReference(end, m_scr.Versification)}; ;
		}
Пример #4
0
		/// ------------------------------------------------------------------------------------------
		/// <summary>
		/// Given a position in a back translation string, try to locate the corresponding
		/// verse in the vernacular, and insert the verse number in the BT.
		/// </summary>
		/// <param name="hvoObj">The id of the translation being modified</param>
		/// <param name="propTag">The flid (i.e. Translation)</param>
		/// <param name="selHelper">The selection helper</param>
		/// <param name="wsAlt">The writing system of the back trans multiString alt</param>
		/// <param name="ich">The character position at which to insert verse number</param>
		/// <param name="tssBt">The given BT string, in which we will insert the verse number</param>
		/// <param name="sVerseNumIns">output: String containing the inserted verse number,
		/// or null if no verse number inserted</param>
		/// <param name="sChapterNumIns">output: String containing the inserted chapter number,
		/// or null if no chapter number inserted</param>
		/// <param name="ichLimIns">output: Gets set to the end of the new BT chapter/verse numbers
		/// inserted</param>
		/// <returns>
		/// 	<c>true</c> if we inserted a verse number/bridge; <c>false</c> if not
		/// </returns>
		/// ------------------------------------------------------------------------------------------
		private bool InsertNextVerseNumberInBt(int hvoObj, int propTag,
			SelectionHelper selHelper, int wsAlt, int ich,
			ref ITsString tssBt, out string sVerseNumIns, out string sChapterNumIns, out int ichLimIns)
		{
			// Get the corresponding verse number from the vernacular
			sVerseNumIns = GetBtVerseNumberFromVern(selHelper, tssBt, ich, wsAlt, true,
				out sChapterNumIns);

			ReplaceRangeInBt(hvoObj, propTag, wsAlt, ich, ich, ref sChapterNumIns, ref sVerseNumIns,
					ref tssBt, out ichLimIns);

			// Remove any chapter numbers not in the chapter range of the vernacular para that owns this BT
			ScrTxtPara vernPara = new ScrTxtPara(m_cache, selHelper.LevelInfo[1].hvo);
			BCVRef startRef;
			BCVRef endRef;
			FindParaRefRange(vernPara, out startRef, out endRef);
			CleanChapterInBtPara(hvoObj, wsAlt, ref tssBt, startRef, endRef);
			return true;
		}
Пример #5
0
		///// ------------------------------------------------------------------------------------
		///// <summary>
		///// Goes to the closest match in the given section or following section starting at the
		///// given paragraph and character offsets and ending at the given paragraph and character
		///// offsets
		///// </summary>
		///// <param name="targetRef">ScrReference to find</param>
		///// <param name="bookIndex">index of book to look in</param>
		///// <param name="section">section to search</param>
		///// <param name="startingParaIndex">starting paragraph to look in</param>
		///// <param name="startingCharIndex">starting character index to look at</param>
		///// <param name="endingParaIndex">last paragraph to look in (-1 for end)</param>
		///// <param name="endingCharIndex">ending character index to look at (-1 for end)</param>
		///// <returns><c>false</c> if we can't go to the closest match </returns>
		///// ------------------------------------------------------------------------------------
		//protected virtual bool GotoClosestMatch(ScrReference targetRef,
		//    int bookIndex, ScrSection section, int startingParaIndex, int startingCharIndex,
		//    int endingParaIndex, int endingCharIndex)
		//{
		//    int paraCount = section.ContentParagraphCount;

		//    if (startingParaIndex >= paraCount)
		//        return false;

		//    if (endingParaIndex == -1)
		//        endingParaIndex = paraCount - 1;

		//    if (endingCharIndex == -1)
		//        endingCharIndex = section.LastContentParagraph.Contents.Length;

		//    // only process this section if we have content to check
		//    if (startingParaIndex == endingParaIndex && startingCharIndex == endingCharIndex)
		//        return false;

		//    // Indicator to look for the min of a section.
		//    bool findMin = false;

		//    // If the section does not contain this reference, then look to see if we want to
		//    // put the selection between this section and the next one.
		//    if (!section.ContainsReference(targetRef))
		//    {
		//        // If there is no previous section and the reference is less than the
		//        // min of this section, then place the IP at the start of this section
		//        if (section.VerseRefMin > targetRef && section.PreviousSection == null)
		//        {
		//            SetInsertionPoint((int)ScrSection.ScrSectionTags.kflidContent,
		//                bookIndex, section.IndexInBook, 0, 0, true, VwScrollSelOpts.kssoNearTop);
		//            return true;
		//        }
		//        ScrSection nextSection = section.NextSection;
		//        if (nextSection == null)
		//        {
		//            // If there is no following section and the reference is larger then the
		//            // max of this section, then place it at the end of this section
		//            if (section.VerseRefMax <= targetRef)
		//            {
		//                SetIpAtEndOfSection(bookIndex, section);
		//                return true;
		//            }
		//            else
		//                return false;
		//        }
		//        // If the reference falls between the max of this section and the max of the next
		//        // section, then the IP will either be at the end of this section or in the next section.
		//        if (section.VerseRefMax <= targetRef && targetRef <= nextSection.VerseRefMax)
		//        {
		//            // If the reference falls between the two sections, then place it at the edge of the section
		//            // that has a reference closest to the target reference.
		//            if (targetRef <= nextSection.VerseRefMin || section.VerseRefEnd > nextSection.VerseRefStart)
		//            {
		//                if (targetRef.ClosestTo(section.VerseRefMax, nextSection.VerseRefMin) == 0)
		//                {
		//                    // set selection to the end of this section
		//                    SetInsertionPoint((int)ScrSection.ScrSectionTags.kflidContent,
		//                        bookIndex, section.IndexInBook, paraCount - 1,
		//                        section.LastContentParagraph.Contents.Length, true,
		//                        VwScrollSelOpts.kssoNearTop);
		//                    return true;
		//                }
		//                else
		//                {
		//                    // Place the selection at the min reference of the next section, so
		//                    // set the target reference to the min reference so it will be
		//                    // found below.
		//                    targetRef.BBCCCVVV = nextSection.VerseRefMin;
		//                    findMin = true;
		//                }
		//            }
		//            section = nextSection;
		//            // reset index limits for changed section
		//            paraCount = section.ContentParagraphCount;
		//            startingParaIndex = 0;
		//            endingParaIndex = paraCount - 1;
		//            endingCharIndex = startingCharIndex = -1; // ADDED 8-7-2008 TLB
		//        }
		//        else
		//            return false;
		//    }

		//    ScrVerse prevVerse = null; // REVIEW: This might need to go outside this for loop
		//    // The reference goes somewhere in this section, so look for the spot to put it
		//    for (int paraIndex = startingParaIndex; paraIndex <= endingParaIndex; ++paraIndex)
		//    {
		//        ScrTxtPara para = new ScrTxtPara(m_cache, section[paraIndex].Hvo);
		//        ScrVerseSet verseSet = new ScrVerseSet(para);
		//        int currentEndingCharIndex = (paraIndex == endingParaIndex && endingCharIndex != -1)? endingCharIndex: para.Contents.Length - 1;
		//        foreach (ScrVerse verse in verseSet)
		//        {
		//            if (verse.VerseStartIndex >= currentEndingCharIndex) // past the end
		//                break;
		//            // If we haven't gotten to the beginning position where we want to start
		//            // looking or we're looking for the minimum reference in the section, and
		//            // this is not it, then continue looking.
		//            if (verse.VerseStartIndex >= startingCharIndex ||
		//                (findMin && verse.StartRef == section.VerseRefMin))
		//            {
		//                // When the target reference is found, set the IP
		//                if (verse.StartRef >= targetRef)
		//                {
		//                    // REVIEW: what to do when prevVerse is null
		//                    int ich = verse.VerseStartIndex;
		//                    if (verse.StartRef > targetRef && prevVerse != null)
		//                    {
		//                        ich = prevVerse.TextStartIndex;
		//                        if (prevVerse.HvoPara != para.Hvo)
		//                            paraIndex--;

		//                    }
		//                    // set the IP here now
		//                    GoToPosition(targetRef, bookIndex, section, paraIndex, ich);
		//                    return true;
		//                }
		//            }
		//            prevVerse = verse;
		//        }

		//        // after the first paragraph, start looking at 0
		//        startingCharIndex = 0;
		//    }
		//    return false;
		//}

		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Goes to the closest match in the given book.
		/// </summary>
		/// <param name="targetRef">ScrReference to find</param>
		/// <param name="book">index of book to look in</param>
		/// <returns><c>false</c> if we can't go to the closest match </returns>
		/// ------------------------------------------------------------------------------------
		protected virtual void GotoClosestPrecedingRef(ScrReference targetRef, ScrBook book)
		{
			Debug.Assert(book != null);
			Debug.Assert(book.SectionsOS.Count > 0);
			ScrSection section = null;

			// Move backward through the sections in the book to find the one
			// whose start reference is less than the one we're looking for.
			for (int iSection = book.SectionsOS.Count - 1; iSection >= 0; iSection--)
			{
				section = book[iSection];

				// If the reference we're looking for is greater than the current
				// section's start reference, then get out of the loop because we've
				// found the section in which we need to place the IP.
				if (targetRef >= section.VerseRefStart)
					break;
			}

			// At this point, we know we have the section in which we think the
			// IP should be located.
			int iBook = BookFilter.GetBookIndex(book.Hvo);

			// If the reference we're looking for is before the section's start reference,
			// then we need to put the IP at the beginning of the book's first section,
			// but after a chapter number if the sections begins with one.
			if (targetRef < section.VerseRefStart)
			{
				GoToFirstChapterInSection(iBook, section);
				return;
			}

			int paraCount = section.ContentParagraphCount;

			// If there are no paragraphs in the section, then we're out of luck.
			Debug.Assert(paraCount > 0);

			// Go through the paragraphs and find the one in which we
			// think the IP should be located.
			for (int iPara = paraCount - 1; iPara >= 0; iPara--)
			{
				ScrTxtPara para = new ScrTxtPara(m_cache, section[iPara].Hvo);
				ScrVerseList verses = new ScrVerseList(para);

				// Go backward through the verses in the paragrah, looking for the
				// first one that is less than the reference we're looking for.
				for (int iVerse = verses.Count - 1; iVerse >= 0; iVerse--)
				{
					// If the current reference is before (i.e. less) the one we're looking
					// for,	then put the IP right after the it's verse number.
					if (verses[iVerse].StartRef <= targetRef)
					{
						GoToPosition(targetRef, iBook, section,
							iPara, verses[iVerse].TextStartIndex);

						return;
					}
				}
			}

			// At this point, we have failed to find a good location for the IP.
			// Therefore, just place it at the beginning of the section.
			GoToSectionStart(iBook, section.IndexInBook);
		}
Пример #6
0
		/// <summary>
		/// Go to the indicated verse in the BT. We've already determined the index of the book, the section,
		/// the paragraph, and the character index in the vernacular. We want to figure the corresponding
		/// position in the BT, which should be the non-label segment closest to (hopefully containing) the
		/// vernacular position, and select it.
		/// </summary>
		/// <param name="targetRef"></param>
		/// <param name="bookIndex"></param>
		/// <param name="section"></param>
		/// <param name="paraIndex"></param>
		/// <param name="para"></param>
		/// <param name="ichMainPosition">The position where this verse occurs in the main paragraph.</param>
		protected virtual void GotoVerseBtSeg(ScrReference targetRef, int bookIndex,
			ScrSection section, int paraIndex, ScrTxtPara para, int ichMainPosition)
		{
			int isegTarget = GetBtSegIndexForVernChar(para, ichMainPosition, ViewConstructorWS);
			// Select the appropriate segment (or if nothing matched, the last place we can edit).
			if (isegTarget < 0)
				return; // pathological.
			SelectRangeOfChars(bookIndex, section.IndexInBook, (int)ScrSection.ScrSectionTags.kflidContent, paraIndex, isegTarget,
							   0, 0, true, true, false, VwScrollSelOpts.kssoDefault);
		}
Пример #7
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Look for the given picture's ORC in the given verse.
		/// </summary>
		/// <param name="targetRef">The verse reference to look for</param>
		/// <param name="hvoPict">The hvo of the picture to look for.</param>
		/// <param name="iSection">The index of the section where the ORC was found.</param>
		/// <param name="iPara">The index of the para where the ORC was found.</param>
		/// <param name="ichOrcPos">The character position of the ORC in the paragraph.</param>
		/// <returns>
		/// 	<c>true</c> if the given picture is found in the given verse.
		/// </returns>
		/// ------------------------------------------------------------------------------------
		public bool FindPictureInVerse(ScrReference targetRef, int hvoPict, out int iSection,
			out int iPara, out int ichOrcPos)
		{
			CheckDisposed();

			iSection = iPara = ichOrcPos = -1;

			// Find the book that the reference is in
			IScrBook book = ScrBook.FindBookByID(m_scr, targetRef.Book);
			if (book == null)
				return false;

			iSection = 0;
			// Look through the sections for the target reference
			foreach (ScrSection section in book.SectionsOS)
			{
				if (section.ContainsReference(targetRef))
				{
					iPara = 0;
					// Look through each paragraph in the section
					foreach (StTxtPara para in section.ContentOA.ParagraphsOS)
					{
						// Search for target reference in the verses in the paragraph
						ScrTxtPara scrPara = new ScrTxtPara(m_cache, para.Hvo);
						ScrVerseSet verseSet = new ScrVerseSet(scrPara);
						foreach (ScrVerse verse in verseSet)
						{
							if (verse.StartRef <= targetRef && targetRef <= verse.EndRef)
							{
								// If the paragraph has a chapter number, the verse iterator
								// returns this as a separate string with the same reference
								// as the following verse.
								// We want to return the verse string, not the chapter number
								// run, so we skip a string that has only numeric characters.
								ITsString tssVerse = verse.Text;
								for (int iRun = 0; iRun < tssVerse.RunCount; iRun++)
								{
									string sRun = tssVerse.get_RunText(iRun);
									if (sRun.Length == 1 && sRun[0] == StringUtils.kchObject)
									{
										string str = tssVerse.get_Properties(iRun).GetStrPropValue(
											(int)FwTextPropType.ktptObjData);

										if (!String.IsNullOrEmpty(str) && str[0] == (char)(int)FwObjDataTypes.kodtGuidMoveableObjDisp)
										{
											Guid guid = MiscUtils.GetGuidFromObjData(str.Substring(1));
											if (m_cache.GetIdFromGuid(guid) == hvoPict)
											{
												ichOrcPos = tssVerse.get_MinOfRun(iRun) + verse.VerseStartIndex;
												return true;
											}
										}
									}
								}
							}
						}
						iPara++;
					}
				}
				iSection++;
			}
			return false;
		}
Пример #8
0
		/// -----------------------------------------------------------------------------------
		/// <summary>
		/// Handles the Reset Paragraph Style menu/toolbar command.
		///
		/// Resets the style of the paragraph to be the default style for the current context.
		/// </summary>
		/// -----------------------------------------------------------------------------------
		public void ResetParagraphStyle()
		{
			CheckDisposed();

			if (ParagraphHvo == 0)
				return;
			// Reset paragraph style only active when selection is in a single
			// paragraph, so can just get selected paragraph from anchor
			ScrTxtPara para = new ScrTxtPara(m_cache, ParagraphHvo);
			ApplyStyle(para.DefaultStyleName);
		}
Пример #9
0
		/// -----------------------------------------------------------------------------------
		/// <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.
			}
		}
Пример #10
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Calls ParseStTxtPara to carry out the desired side effects: re-parsing the paragraph
		/// for wordforms, ???.
		/// </summary>
		/// <param name="hvoPara">The Paragraph that was changed</param>
		/// <param name="ivMin">the starting character index where the change occurred</param>
		/// <param name="cvIns">the number of characters inserted</param>
		/// <param name="cvDel">the number of characters deleted</param>
		/// ------------------------------------------------------------------------------------
		protected override void DoEffectsOfPropChange(int hvoPara, int ivMin, int cvIns, int cvDel)
		{
			// If nothing really changed, don't do anything.
			if (cvIns == 0 && cvDel == 0)
				return;

			// Check that the paragraph is truly Scripture, and not a footnote or some other kind
			// of non-Scripture paragraph
			int hvoOfStTextThatOwnsPara = m_cache.GetOwnerOfObject(hvoPara);

			switch (m_cache.GetOwningFlidOfObject(hvoOfStTextThatOwnsPara))
			{
				case (int)ScrSection.ScrSectionTags.kflidContent:
				{
					ScrTxtPara para = new ScrTxtPara(m_cache, hvoPara, false, false);
					// get para props to determine para style - Intro?
					para.ProcessChapterVerseNums(ivMin, cvIns, cvDel);

					// Mark any back translations as unfinished
					para.MarkBackTranslationsAsUnfinished();
					break;
				}
				case (int)ScrBook.ScrBookTags.kflidFootnotes:
				case (int)ScrSection.ScrSectionTags.kflidHeading:
				{
					ScrTxtPara para = new ScrTxtPara(m_cache, hvoPara, false, false);
					// Mark any back translations as stale
					para.MarkBackTranslationsAsUnfinished();
					break;
				}
				default:
					// REVIEW TETeam(TomB): Is any checking needed for anything else?
					break;
			}
		}
Пример #11
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Adjusts the references of the section and creates any needed BT's
		/// </summary>
		/// <param name="hvoText">The StText that was changed</param>
		/// <param name="ivMin">the starting index where the change occurred</param>
		/// <param name="cvIns">the number of paragraphs inserted</param>
		/// <param name="cvDel">the number of paragraphs deleted</param>
		/// ------------------------------------------------------------------------------------
		protected override void DoEffectsOfPropChange(int hvoText, int ivMin, int cvIns, int cvDel)
		{
			if (cvIns == 0 && cvDel == 0)
				return; // Nothing actually changed

			int flid = m_cache.GetOwningFlidOfObject(hvoText);
			StText text = new StText(m_cache, hvoText, false, false);
			FdoOwningSequence<IStPara> paras = text.ParagraphsOS;

			// Create back translations for any new paragraphs
			if (flid == (int)ScrSection.ScrSectionTags.kflidContent ||
				flid == (int)ScrSection.ScrSectionTags.kflidHeading ||
				flid == (int)ScrBook.ScrBookTags.kflidTitle)
			{
				for (int iPara = ivMin; iPara < ivMin + cvIns; iPara++)
				{
					ScrTxtPara para = new ScrTxtPara(m_cache, paras.HvoArray[iPara]);
					para.GetOrCreateBT();
				}
			}

			// Adjust section references for section contents if we have some paragraphs left
			if (flid == (int)ScrSection.ScrSectionTags.kflidContent && paras.Count > 0)
				ScrTxtPara.AdjustSectionRefsForStTextParaChg(text, ivMin);

			// If we show boundary markers and we insert or delete a paragraph, we have to
			// update the marker of the previous paragraph as well, as that might
			// now be no longer the last paragraph (and thus needs to show the paragraph
			// marker instead of the section marker).
			if (((cvIns > 0 && cvDel == 0) || (cvIns == 0 && cvDel > 0)) && ivMin > 0
				&& Options.ShowFormatMarksSetting)
			{
				text.Cache.PropChanged(null, PropChangeType.kpctNotifyAll, hvoText,
					(int)StText.StTextTags.kflidParagraphs, ivMin - 1, 1, 1);
			}
		}
Пример #12
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());
		}
Пример #13
0
		/// -----------------------------------------------------------------------------------
		///<summary>
		/// Verify the specified ScrVerse
		///</summary>
		///<param name="verse">specified ScrVerse</param>
		///<param name="cache">database</param>
		///<param name="verseText">expected text within the ScrVerse</param>
		///<param name="styleName">expected stylename for the ScrVerse paragraph</param>
		///<param name="startRef">expected starting reference</param>
		///<param name="endRef">expected ending reference</param>
		/// -----------------------------------------------------------------------------------
		public static void VerifyScrVerse(ScrVerse verse, FdoCache cache, string verseText,
						string styleName, BCVRef startRef, BCVRef endRef)
		{
			ScrTxtPara versePara = new ScrTxtPara(cache, verse.HvoPara);
			if (string.IsNullOrEmpty(verseText))
				Assert.IsTrue(verse.Text == null || string.IsNullOrEmpty(verse.Text.Text));
			else
				Assert.AreEqual(verseText, verse.Text.Text);
			Assert.AreEqual(styleName, ScrStyleNames.GetStyleName(versePara.Hvo, cache));
			Assert.AreEqual(startRef, verse.StartRef);
			Assert.AreEqual(endRef, verse.EndRef);
		}
Пример #14
0
		public void MoveNext_EmptyPara()
		{
			CheckDisposed();
			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(m_genesis.Hvo);
			StTxtPara emptyPara = AddEmptyPara(section, ScrStyleNames.SpeechLine1);
			section.AdjustReferences();

			// Create and iterate through the verses in the StText.
			ScrTxtPara emptyScrPara = new ScrTxtPara(m_inMemoryCache.Cache, emptyPara.Hvo);
			ScrVerseSet verseSet = new ScrVerseSet(emptyScrPara);

			Assert.IsFalse(verseSet.MoveNext(),
				"The iterator provided a ScrVerse for an empty para that wasn't a Stanza Break.");
		}
Пример #15
0
		public void MoveNext_StanzaBreak()
		{
			CheckDisposed();
			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(m_genesis.Hvo);
			StTxtPara emptyPara = AddEmptyPara(section, ScrStyleNames.StanzaBreak);
			section.AdjustReferences();

			// Create and iterate through the verses in the StText.
			ScrTxtPara emptyScrPara = new ScrTxtPara(m_inMemoryCache.Cache, emptyPara.Hvo);
			ScrVerseSet verseSet = new ScrVerseSet(emptyScrPara);

			Assert.IsTrue(verseSet.MoveNext());
			VerifyScrVerse((ScrVerse)verseSet.Current, m_inMemoryCache.Cache, null,
				ScrStyleNames.StanzaBreak, 01001001, 01001001);
			Assert.IsFalse(verseSet.MoveNext());
		}
Пример #16
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Override ApplyParagraphStyle so that changes in text structure can be handled
		/// correctly.
		/// </summary>
		/// <param name="newParagraphStyle"></param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		public override bool ApplyParagraphStyle(string newParagraphStyle)
		{
			CheckDisposed();

			// Paragraph style changes are not permitted in a back translation view.
			if (IsBackTranslation)
			{
				MiscUtils.ErrorBeep();
				return false;
			}

			// Paragraph style changes are restricted to paragraphs in a single StText
			if (!IsSingleTextSelection())
				return false;

			// Check contexts of new and existing paragraph style
			SelLevInfo[] levInfo =
				CurrentSelection.GetLevelInfo(SelectionHelper.SelLimitType.Anchor);

			// only apply a paragraph style to a paragraph....
			if (m_cache.GetClassOfObject(levInfo[0].hvo) != StTxtPara.kClassId)
				return false;

			ScrTxtPara para = new ScrTxtPara(m_cache, levInfo[0].hvo);
			string curStyleName = para.StyleName;

			IStStyle curStyle = m_scr.FindStyle(curStyleName);
			IStStyle newStyle = m_scr.FindStyle(newParagraphStyle);
			if (curStyle == null)
				curStyle = ((FwStyleSheet)Callbacks.EditedRootBox.Stylesheet).FindStyle(para.DefaultStyleName);
			if (curStyle == null || newStyle == null)
			{
				// This should no longer be possible, but to be safe...
				Debug.Assert(curStyle != null);
				Debug.Assert(newStyle != null);
				return true;
			}

			//REVIEW: If you apply IntroPara style to a section head, what behavior??
			//TODO (MarkB):  If Contexts are not equal, do not apply the change. This should
			//	only happen in case of a program error so some kind of debug message
			//	might be appropriate. Maybe do this in the AdjustTextStructure function.
			//REVIEW (MarkB): AdjustTextStructure only if (Context = "Intro" OR "Text") AND
			//	Structures are not equal. Maybe do this in the AdjustTextStructure function.
			bool applyStyleChange = true;
			if ((curStyle.Context != newStyle.Context &&
				newStyle.Context != ContextValues.General) ||
				curStyle.Structure != newStyle.Structure)
			{
				applyStyleChange = AdjustTextStructure(CurrentSelection, curStyle, newStyle);
			}

			if (applyStyleChange)
				return base.ApplyParagraphStyle(newStyle.Name);
			else
				return true;
		}
Пример #17
0
		public void DiffEditAsPartOfImport()
		{
			CheckDisposed();

			m_settings.ImportTranslation = true;
			MockScrObjWrapper.s_fSimulateCancel = false;

			int origActCount = m_cache.ActionHandlerAccessor.UndoableActionCount;

			IScrBook jude = m_scr.FindBook(65);
			Assert.IsNotNull(jude, "This test is invalid if Jude isn't in the test DB.");
			int cBooksOrig = m_scr.ScriptureBooksOS.Count;

			List<SegmentInfo> al = new List<SegmentInfo>(3);
			// process a \id segment to import an existing a book
			al.Add(new SegmentInfo(@"\id", "JUD", ImportDomain.Main, new BCVRef(65, 0, 0)));
			al.Add(new SegmentInfo(@"\s", "Section head", ImportDomain.Main, new BCVRef(65, 1, 1)));
			al.Add(new SegmentInfo(@"\p", "Contents", ImportDomain.Main, new BCVRef(65, 1, 1)));

			m_importMgr.CallImportWithUndoTask(m_settings, al);

			Assert.AreEqual(1, m_importMgr.NewSavedVersions.Count, "We should have an imported version but not a backup saved version.");
			Assert.AreEqual(origActCount + 4, m_cache.ActionHandlerAccessor.UndoableActionCount,
				"Should have 4 extra undo actions (create backup, create imported version & first book, create second book, delete {empty} backup).");
			// Call ProcessChapterVerseNums to simulate an edit in the diff dialog.
			jude = m_scr.FindBook(65);
			ScrTxtPara sc1Para = new ScrTxtPara(m_cache, jude.SectionsOS[0].ContentOA.ParagraphsOS.HvoArray[0]);
			sc1Para.ProcessChapterVerseNums(0, 1, 0);
			Assert.AreEqual("&Undo Import", m_cache.UndoText);
			Assert.AreEqual(1, m_importMgr.m_cDisplayImportedBooksDlgCalled);
		}
Пример #18
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;
		}
Пример #19
0
		public void FindPrevBackTrans_SecondBookTitleToFirstBook_LastParaFinished()
		{
			CheckDisposed();

			// add new book with a BT
			IScrBook book = m_scrInMemoryCache.AddBookToMockedScripture(3, "Leviticus");
			StText text = m_scrInMemoryCache.AddTitleToMockedBook(book.Hvo, "Title for Leviticus");
			m_scrInMemoryCache.AddBtToMockedParagraph((StTxtPara)text.ParagraphsOS[0],
				Cache.DefaultAnalWs);

			// add BT for the last section heading of the first book
			ScrTxtPara para = new ScrTxtPara(Cache, m_book.SectionsOS[2].HeadingOA.ParagraphsOS.HvoArray[0]);
			m_inMemoryCache.AddBtToMockedParagraph(para, Cache.DefaultAnalWs);
			// add BT for last para of first book
			para = new ScrTxtPara(Cache, m_book.SectionsOS[2].ContentOA.ParagraphsOS.HvoArray[0]);
			ICmTranslation trans = m_inMemoryCache.AddBtToMockedParagraph(para,
				Cache.DefaultAnalWs);
			m_btDraftView.SetTransStatus(trans, BackTranslationStatus.Finished);
			m_btDraftView.RefreshDisplay();

			m_btDraftView.SetInsertionPoint((int)ScrBook.ScrBookTags.kflidTitle, 1, 0);

			m_btDraftView.CallPrevUnfinishedBackTrans();
			SelectionHelper helper = m_btDraftView.EditingHelper.CurrentSelection;

			Assert.AreEqual(0, helper.IchAnchor);
			Assert.AreEqual(0, m_btDraftView.TeEditingHelper.BookIndex);
			Assert.AreEqual(2, m_btDraftView.TeEditingHelper.SectionIndex);
			Assert.AreEqual(0, m_btDraftView.ParagraphIndex);
			Assert.AreEqual((int)ScrSection.ScrSectionTags.kflidHeading,
				m_btDraftView.EditingHelper.CurrentSelection.LevelInfo[2].tag);
			Assert.IsFalse(m_btDraftView.TeEditingHelper.InBookTitle);
		}
Пример #20
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Find a verse and return the text of the verse in one or more
		/// <see cref="VerseTextSubstring"/> objects.
		/// </summary>
		/// <param name="scr">The scripture.</param>
		/// <param name="targetRef">The verse reference to look for</param>
		/// <param name="ichStart">The starting character where the (first part of the) verse
		/// text is located within the (first) containing paragraph</param>
		/// <returns>
		/// A list of <see cref="VerseTextSubstring"/> objects, each representing
		/// one paragraph worth of verse text (e.g., to deal with poetry)
		/// </returns>
		/// <remarks>Verses would not normally be split across sections, but there are a few
		/// places, such as the end of I Cor. 12, where it can happen.
		/// </remarks>
		/// ------------------------------------------------------------------------------------
		public static List<VerseTextSubstring> GetVerseText(IScripture scr, ScrReference targetRef,
			out int ichStart)
		{
			ichStart = -1;

			if (scr.Versification != targetRef.Versification)
				targetRef = new ScrReference(targetRef, scr.Versification);

			List<VerseTextSubstring> verseText = new List<VerseTextSubstring>();

			// Find the book that the reference is in
			IScrBook book = ScrBook.FindBookByID(scr, targetRef.Book);
			if (book == null)
				return verseText;

			if (targetRef.IsBookTitle)
			{
				foreach (StTxtPara para in book.TitleOA.ParagraphsOS)
				{
					verseText.Add(new VerseTextSubstring(para.Contents.UnderlyingTsString, -1,
						para.IndexInOwner, (int)ScrBook.ScrBookTags.kflidTitle));
					ichStart = 0;
				}
				return verseText;
			}

			int iSection = 0;
			// Look through the sections for the target reference
			foreach (ScrSection section in book.SectionsOS)
			{
				if (!section.ContainsReference(targetRef))
				{
					if (verseText.Count > 0)
						return verseText;
				}
				else
				{
					int iPara = 0;
					// Look through each paragraph in the section
					foreach (StTxtPara para in section.ContentOA.ParagraphsOS)
					{
						// Search for target reference in the verses in the paragraph
						ScrTxtPara scrPara = new ScrTxtPara(scr.Cache, para.Hvo);
						ScrVerseSet verseSet = new ScrVerseSet(scrPara);
						foreach (ScrVerse verse in verseSet)
						{
							if (verse.StartRef <= targetRef && targetRef <= verse.EndRef)
							{
								// If the paragraph has a chapter number, the verse iterator
								// returns this as a separate string with the same reference
								// as the following verse.
								// We want to return the verse string, not the chapter number
								// run, so we skip a string that has only numeric characters.
								ITsString verseTextInPara = verse.Text;
								if (verse.Text.RunCount > 0)
								{
									string styleName = verse.Text.get_PropertiesAt(0).GetStrPropValue(
										(int)FwTextPropType.ktptNamedStyle);
									if (styleName == ScrStyleNames.VerseNumber)
										verseTextInPara = StringUtils.Substring(verseTextInPara, verse.Text.get_LimOfRun(0));
								}
								if (!IsNumber(verseTextInPara.Text)) // skip chapter number strings
								{
									if (verseText.Count == 0)
										ichStart = verse.TextStartIndex;
									verseText.Add(new VerseTextSubstring(verseTextInPara, iSection,
										iPara, (int)ScrSection.ScrSectionTags.kflidContent));
									break;
								}
							}
							else if (verseText.Count > 0)
								return verseText;
						}
						iPara++;
					}
				}
				iSection++;
			}
			return verseText;
		}
Пример #21
0
		public void FindNextBackTrans_SectionContentToTitle()
		{
			CheckDisposed();

			// add new book
			IScrBook book = m_scrInMemoryCache.AddBookToMockedScripture(3, "Leviticus");
			StText text = m_scrInMemoryCache.AddTitleToMockedBook(book.Hvo, "Title for Leviticus");
			// add BT for last para of first book
			ScrTxtPara para = new ScrTxtPara(Cache, m_book.SectionsOS[2].ContentOA.ParagraphsOS.HvoArray[0]);
			m_inMemoryCache.AddBtToMockedParagraph(para, Cache.DefaultAnalWs);

			// add BT for title para of the last book
			para = new ScrTxtPara(Cache, text.ParagraphsOS.HvoArray[0]);
			m_inMemoryCache.AddBtToMockedParagraph(para, Cache.DefaultAnalWs);
			m_btDraftView.RefreshDisplay();

			int iLastSectionInExodus = m_book.SectionsOS.Count - 1;
			m_btDraftView.SetInsertionPoint((int)ScrSection.ScrSectionTags.kflidContent,
				0, iLastSectionInExodus,
				m_book.SectionsOS[iLastSectionInExodus].ContentOA.ParagraphsOS.Count -1);

			m_btDraftView.CallNextUnfinishedBackTrans();
			SelectionHelper helper = m_btDraftView.EditingHelper.CurrentSelection;

			Assert.AreEqual(0, helper.IchAnchor);
			Assert.AreEqual(1, m_btDraftView.TeEditingHelper.BookIndex);
			Assert.AreEqual(-1, m_btDraftView.TeEditingHelper.SectionIndex);
			Assert.AreEqual(0, m_btDraftView.ParagraphIndex);
			Assert.IsTrue(m_btDraftView.TeEditingHelper.InBookTitle);
		}
Пример #22
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Goes to the verse reference in the back translation paragraph or the closest
		/// location to where it would occur
		/// </summary>
		/// ------------------------------------------------------------------------------------
		protected virtual void GotoVerseBT(ScrReference targetRef, int bookIndex,
			ScrSection section, int paraIndex, ScrTxtPara para)
		{
			ScrVerseSet verseSet = new ScrVerseSetBT(para, ViewConstructorWS);

			// Look for an exact match of the target verse number in the BT para
			foreach (ScrVerse verse in verseSet)
			{
				if (!verse.VerseNumberRun)
					continue;

				if (verse.StartRef <= targetRef && targetRef <= verse.EndRef)
				{
					// set the IP here now
					SetInsertionPoint(bookIndex, section.IndexInBook, paraIndex,
						verse.TextStartIndex, false);
					return;
				}
			}

			// An exact match was not found, so look for a best guess spot for it
			foreach (ScrVerse verse in verseSet)
			{
				if (!verse.VerseNumberRun)
					continue;

				if (verse.StartRef >= targetRef)
				{
					// set the IP here now
					SetInsertionPoint(bookIndex, section.IndexInBook, paraIndex, verse.VerseStartIndex, false);
					return;
				}
			}

			// A best guess spot was not found so put the selection at the end of the paragraph
			SetIpAtEndOfPara(bookIndex, section.IndexInBook, paraIndex, para);
		}
Пример #23
0
		public void FindNextBackTrans_SectionContentToNextBook_TitleFinished()
		{
			CheckDisposed();

			// add new book
			IScrBook book = m_scrInMemoryCache.AddBookToMockedScripture(3, "Leviticus");
			StText text = m_scrInMemoryCache.AddTitleToMockedBook(book.Hvo, "Title for Leviticus");
			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(book.Hvo);
			m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Heading",
				ScrStyleNames.SectionHead);
			// add BT for last para of first book
			ScrTxtPara para = new ScrTxtPara(Cache, m_book.SectionsOS[2].ContentOA.ParagraphsOS.HvoArray[0]);
			m_inMemoryCache.AddBtToMockedParagraph(para, Cache.DefaultAnalWs);

			// add BT for title para of the last book
			para = new ScrTxtPara(Cache, text.ParagraphsOS.HvoArray[0]);
			ICmTranslation trans = m_inMemoryCache.AddBtToMockedParagraph(para,
				Cache.DefaultAnalWs);
			m_btDraftView.SetTransStatus(trans, BackTranslationStatus.Finished);

			// add BT for the first section head of the last book
			para = new ScrTxtPara(Cache, book.SectionsOS[0].HeadingOA.ParagraphsOS.HvoArray[0]);
			m_inMemoryCache.AddBtToMockedParagraph(para, Cache.DefaultAnalWs);
			m_btDraftView.RefreshDisplay();

			int iLastSectionInExodus = m_book.SectionsOS.Count - 1;
			m_btDraftView.SetInsertionPoint((int)ScrSection.ScrSectionTags.kflidContent,
				0, iLastSectionInExodus,
				m_book.SectionsOS[iLastSectionInExodus].ContentOA.ParagraphsOS.Count -1);

			m_btDraftView.CallNextUnfinishedBackTrans();
			SelectionHelper helper = m_btDraftView.EditingHelper.CurrentSelection;

			Assert.AreEqual(0, helper.IchAnchor);
			Assert.AreEqual(1, m_btDraftView.TeEditingHelper.BookIndex);
			Assert.AreEqual(0, m_btDraftView.TeEditingHelper.SectionIndex);
			Assert.AreEqual(0, m_btDraftView.ParagraphIndex);
			Assert.AreEqual((int)ScrSection.ScrSectionTags.kflidHeading,
				m_btDraftView.EditingHelper.CurrentSelection.LevelInfo[2].tag);
			Assert.IsFalse(m_btDraftView.TeEditingHelper.InBookTitle);
		}
Пример #24
0
		/// <summary>
		/// Given a character position in the contents of an ScrTxtPara, return the index of the corresponding segment
		/// (or the closest editable one).
		/// </summary>
		static public int GetBtSegIndexForVernChar(ScrTxtPara para, int ichMainPosition, int btWs)
		{
			StTxtPara.LoadSegmentFreeTranslations(new int[] { para.Hvo }, para.Cache, btWs);
			int ktagParaSegments = StTxtPara.SegmentsFlid(para.Cache);
			int cseg = para.Cache.GetVectorSize(para.Hvo, ktagParaSegments);
			int kflidFT = StTxtPara.SegmentFreeTranslationFlid(para.Cache);
			ISilDataAccess sda = para.Cache.MainCacheAccessor;
			int isegTarget = -1;
			for (int iseg = 0; iseg < cseg; iseg++)
			{
				int hvoSeg = sda.get_VecItem(para.Hvo, ktagParaSegments, iseg);
				CmBaseAnnotation seg = CmObject.CreateFromDBObject(para.Cache, hvoSeg) as CmBaseAnnotation;
				// If it's a 'label' segment, it's not where we want to put the IP.
				ITsString tssSeg = seg.TextAnnotated;
				if (SegmentBreaker.HasLabelText(tssSeg, 0, tssSeg.Length))
					continue;
				isegTarget = iseg;
				if (ichMainPosition <= seg.EndOffset)
					break; // don't consider any later segment
			}
			return isegTarget;
		}
		public void CreateBtsWhenContentParagraphIsReplacedByMultipleOtherParagraphs()
		{
			CheckDisposed();

			// add scripture section and paragraph
			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(m_book.Hvo);
			StTxtPara para1 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo,
				ScrStyleNames.IntroParagraph);
			StTxtPara para2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo,
				ScrStyleNames.IntroParagraph);
			StTxtPara para3 = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo,
				ScrStyleNames.IntroParagraph);

			// set up the Scripture paragraph ChangeWatcher
			ScriptureChangeWatcher.Create(Cache);

			// Issue a PropChanged that should create a back translation paragraph.
			Cache.MainCacheAccessor.PropChanged(null,
				(int)PropChangeType.kpctNotifyAll,
				section.ContentOA.Hvo,
				(int)StText.StTextTags.kflidParagraphs,
				0, 3, 1);

			// make sure the back translations got created.
			ScrTxtPara scrPara = new ScrTxtPara(Cache, para1.Hvo);
			ICmTranslation bt = scrPara.GetBT();
			Assert.IsNotNull(bt);
			Assert.IsNull(bt.Status.AnalysisDefaultWritingSystem);

			scrPara = new ScrTxtPara(Cache, para2.Hvo);
			bt = scrPara.GetBT();
			Assert.IsNotNull(bt);
			Assert.IsNull(bt.Status.AnalysisDefaultWritingSystem);

			scrPara = new ScrTxtPara(Cache, para3.Hvo);
			bt = scrPara.GetBT();
			Assert.IsNotNull(bt);
			Assert.IsNull(bt.Status.AnalysisDefaultWritingSystem);
		}
Пример #26
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Find the beginning and ending reference for a given paragraph.
		/// </summary>
		/// <param name="para">given paragraph</param>
		/// <param name="startRef">out: reference at start of paragraph</param>
		/// <param name="endRef">out: reference at end of paragraph</param>
		/// ------------------------------------------------------------------------------------
		private void FindParaRefRange(ScrTxtPara para, out BCVRef startRef, out BCVRef endRef)
		{
			BCVRef notUsed;
			para.GetBCVRefAtPosition(0, false, out startRef, out notUsed);
			para.GetBCVRefAtPosition(para.Contents.Length,
				out notUsed, out endRef);
		}
		public void CreateBtWhenHeadingParagraphIsAdded()
		{
			CheckDisposed();

			// add scripture section and paragraph
			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(m_book.Hvo);
			StTxtPara para = m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo,
				"Intro to Genesis or whatever", ScrStyleNames.IntroSectionHead);

			// set up the Scripture paragraph ChangeWatcher
			ScriptureChangeWatcher.Create(Cache);

			// Issue a PropChanged that should create a back translation paragraph.
			Cache.MainCacheAccessor.PropChanged(null,
				(int)PropChangeType.kpctNotifyAll,
				section.HeadingOA.Hvo,
				(int)StText.StTextTags.kflidParagraphs,
				0, 1, 0);

			// make sure the back translation is created.
			ScrTxtPara scrPara = new ScrTxtPara(Cache, para.Hvo);
			ICmTranslation bt = scrPara.GetBT();
			Assert.IsNotNull(bt);
			Assert.IsNull(bt.Status.AnalysisDefaultWritingSystem);
		}
Пример #28
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Remove any duplicate verse numbers following the new verse number in the following
		/// text in the current as well as the following section, if any.
		/// </summary>
		/// <param name="hvoObj">The id of the para or translation being modified</param>
		/// <param name="propTag">The flid (Contents or Translation)</param>
		/// <param name="tss">The structured string or the para or trans with the new verse
		/// number</param>
		/// <param name="wsAlt">The writing system, if a back trans multiString alt</param>
		/// <param name="chapterToRemove">A string representation of the duplicate chapter number
		/// to remove.</param>
		/// <param name="verseRangeToRemove">A string representation of the duplicate verse number to
		/// remove. This may also be a verse bridge, in which case we will remove all verse
		/// numbers up to the end value of the bridge</param>
		/// <param name="ich">The character offset after which we start looking for dups</param>
		/// ------------------------------------------------------------------------------------
		private void RemoveDuplicateVerseNumbers(int hvoObj, int propTag, ITsString tss, int wsAlt,
			string chapterToRemove, string verseRangeToRemove, int ich)
		{
			// Determine the verse number we will remove up to
			int removeUpToVerse = ScrReference.VerseToIntEnd(verseRangeToRemove);

			bool inBackTrans = (m_cache.GetClassOfObject(hvoObj) == CmTranslation.kClassId);

			// Get my current StText, ScrSection and ScrBook
			int hvoCurrPara = inBackTrans ? (new CmTranslation(m_cache, hvoObj)).OwnerHVO : hvoObj;
			ScrTxtPara currentPara = new ScrTxtPara(m_cache, hvoCurrPara);

			// Determine the last chapter reference to remove.
			int removeChapter = (chapterToRemove != null && chapterToRemove.Length > 0) ?
				ScrReference.ChapterToInt(chapterToRemove) : 0;

			// First look in the paragraph where the verse was inserted.
			if (RemoveDuplicateVerseNumbersInPara(hvoObj, propTag, tss, wsAlt, removeChapter,
				removeUpToVerse, ich))
			{
				return;
			}

			// Search through current and subsequent section (if any) for duplicate verse numbers.
			StText text = new StText(m_cache, currentPara.OwnerHVO);
			ScrSection currentSection = new ScrSection(m_cache, text.OwnerHVO);
			IScrBook currentBook = currentSection.OwningBook;

			// First look through successive paragraphs for duplicate verse numbers, and then
			// try the next section if necessary.
			if (!RemoveDuplicateVerseNumbersInText(text, currentPara.IndexInOwner + 1, inBackTrans,
				propTag, wsAlt, removeChapter, removeUpToVerse))
			{
				ScrSection nextSection = currentSection.NextSection;
				if (nextSection != null)
				{
					RemoveDuplicateVerseNumbersInText(nextSection.ContentOA, 0,
						inBackTrans, propTag, wsAlt, removeChapter, removeUpToVerse);
				}
			}
		}
		public void CreateBtWhenBookTitleParagraphIsAdded()
		{
			CheckDisposed();

			// add title paragraphs
			StText title = m_scrInMemoryCache.AddTitleToMockedBook(m_book.Hvo,
				"Genesis or whatever");
			StTxtPara para2 = m_scrInMemoryCache.AddParaToMockedText(title.Hvo, "An anthology");
			StTxtPara para3 = m_scrInMemoryCache.AddParaToMockedText(title.Hvo, "Written by God");
			m_scrInMemoryCache.AddParaToMockedText(title.Hvo, "For Israel and everyone else");

			// set up the Scripture paragraph ChangeWatcher
			ScriptureChangeWatcher.Create(Cache);

			// Issue a PropChanged that should create a back translation paragraph.
			Cache.MainCacheAccessor.PropChanged(null,
				(int)PropChangeType.kpctNotifyAll,
				title.Hvo,
				(int)StText.StTextTags.kflidParagraphs,
				1, 2, 0);

			// Make sure the back translations got created.
			ScrTxtPara scrPara = new ScrTxtPara(Cache, para2.Hvo);
			ICmTranslation bt = scrPara.GetBT();
			Assert.IsNotNull(bt);
			Assert.IsNull(bt.Status.AnalysisDefaultWritingSystem);

			scrPara = new ScrTxtPara(Cache, para3.Hvo);
			bt = scrPara.GetBT();
			Assert.IsNotNull(bt);
			Assert.IsNull(bt.Status.AnalysisDefaultWritingSystem);
		}
Пример #30
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Get the start and end reference of the specified position <paramref name="ivPos"/>
        /// in the paragraph. Section reference could be used, if available, to fill in missing
        /// information, but (at least for now) we will not search back into previous sections.
        /// </summary>
        /// <param name="wsBT">HVO of the writing system of the BT to search, or -1 to search
        /// the vernacular.</param>
        /// <param name="ivPos">Character offset in the paragraph.</param>
        /// <param name="fAssocPrev">Consider this position to be associated with any preceding
        /// text in the paragraph (in the case where ichPos is at a chapter boundary).</param>
        /// <param name="refStart">[out] Start reference</param>
        /// <param name="refEnd">[out] End reference</param>
        /// <remarks><p><paramref name="refStart"/> and <paramref name="refEnd"/> are only
        /// different if we have bridged verse numbers.</p>
        /// <p>May return incomplete or invalid reference if, for example, the section
        /// object does not have a valid start reference.</p>
        /// <p>If ivPos LT zero, we will not search this para, but look only in previous
        /// paragraphs</p></remarks>
        /// ------------------------------------------------------------------------------------
        public void GetBCVRefAtPosition(int wsBT, int ivPos, bool fAssocPrev,
                                        out BCVRef refStart, out BCVRef refEnd)
        {
            refStart = new BCVRef();
            refEnd   = new BCVRef();

            // Might be trying to get the BCVRef in a footnote
            int ownerOwnFlid = m_cache.GetOwningFlidOfObject(OwnerHVO);

            if (ownerOwnFlid == (int)ScrBook.ScrBookTags.kflidFootnotes)
            {
                ScrFootnote footnote = new ScrFootnote(m_cache, OwnerHVO);
                refStart = footnote.StartRef;
                refEnd   = footnote.StartRef;
                return;
            }

            BCVRef            refStartT = new BCVRef();
            BCVRef            refEndT   = new BCVRef();
            ChapterVerseFound found     = ChapterVerseFound.None;
            bool       fGotVerse        = false;
            ScrTxtPara para             = this; // curent paragraph being examined for reference
            int        chvoParas        = 0;    // count of paragraphs in the section
            int        ihvoPara         = 0;    // index of the paragraph within the section

            BCVRef sectRefStart;
            BCVRef sectRefEnd;

            GetSectionStartAndEndRefs(out sectRefStart, out sectRefEnd);

            while (true)
            {
                if (para == this)
                {
                    found = para.GetBCVRefAtPosWithinPara(wsBT, ivPos, fAssocPrev, out refStartT,
                                                          out refEndT);
                }
                else
                {
                    found = para.GetBCVRefAtEndOfPara(out refStartT, out refEndT);
                }

                // if we found a verse, remember it
                if (!fGotVerse && ((found & ChapterVerseFound.Verse) != 0))
                {
                    refStart.Verse = refStartT.Verse;
                    refEnd.Verse   = refEndT.Verse;
                    fGotVerse      = true;
                }

                // if we found a chapter, process it
                if ((found & ChapterVerseFound.Chapter) != 0)
                {
                    if (sectRefStart != null && !sectRefStart.IsEmpty)
                    {
                        refStart.Book = refEnd.Book = sectRefStart.Book;                         //may not exist
                    }
                    refStart.Chapter = refEnd.Chapter = refStartT.Chapter;

                    // GetBCVwithinPara always returns a verse if it finds a chapter number
                    // so we have already built the full reference
                    Debug.Assert(fGotVerse);
                    return;
                }

                // We got to the beginning of the paragraph being edited and still haven't
                // found a decent reference for our edited text, so keep looking back to
                // get it from a previous paragraph.

                // First time thru, figure out which paragraph we are in
                if (chvoParas == 0)
                {
                    // REVIEW (EberhardB): does this work if not all paragraphs are
                    // loaded in the cache?
                    chvoParas = m_cache.GetVectorSize(OwnerHVO,
                                                      (int)StText.StTextTags.kflidParagraphs);
                    // Go forward through vector of paragraphs to find the one being parsed
                    for (ihvoPara = 0; ihvoPara < chvoParas; ihvoPara++)
                    {
                        int hvoPara = m_cache.GetVectorItem(OwnerHVO,
                                                            (int)StText.StTextTags.kflidParagraphs, ihvoPara);
                        if (hvoPara == Hvo)
                        {
                            break;                             // found our current para
                        }
                    }
                }

                // Move to the previous paragraph
                ihvoPara--;

                if (ihvoPara < 0)
                {
                    // We are at the beginning of the section. We can't look back any further.
                    // ENHANCE TomB: If we search all the way through to the beginning of the
                    // section and never get a valid reference, this section begins in the
                    // middle of a verse or chapter (unlikely in the case of a verse, but
                    // quite likely in the case of a chapter). OR (most likely) this edit
                    // happened at the very beginning of the section, and when we start
                    // parsing, the first thing we'll get is a decent reference.
                    // REVIEW: we're using the section reference, but since they don't get
                    // updated, a change (like removing a chapter) in a previous section
                    // could mess up this section.
                    if (fGotVerse)
                    {
                        // Use the verse we got previously (already set), along with the
                        // first chapter for the section and the book, if available.
                        if (sectRefStart != 0)
                        {
                            refStart.Chapter = refEnd.Chapter = sectRefStart.Chapter;
                            refStart.Book    = refEnd.Book = sectRefStart.Book;
                        }
                    }
                    else
                    {
                        // REVIEW:
                        // For now, we're just using the first verse for the section, but this
                        // could be wrong if the section begins in the middle of a verse bridge
                        // or misleading if the section just doesn't yet have verse numbers
                        // marked.
                        if (sectRefStart != 0)
                        {
                            refStart = new BCVRef(sectRefStart);
                            refEnd   = new BCVRef(sectRefStart);
                        }

                        // If we are looking for a negative position in the first para of a section
                        // the needed result is not precisely defined yet,
                        // but this is where you could set it
//						if (para == this && ivPos < 0)
//							refStart.Verse = refEnd.Verse = ????;
                    }
                    return;
                }

                // Set up for the previous paragraph in this section, and we'll try again
                int hvoNewPara = m_cache.GetVectorItem(OwnerHVO,
                                                       (int)StText.StTextTags.kflidParagraphs, ihvoPara);
                // use a special constructor since we already know the section refs
                para = new ScrTxtPara(m_cache, hvoNewPara, false, false);
            }
        }
Пример #31
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Gets Scripture reference for a selection
		/// </summary>
		/// <param name="helper">The selection helper that represents the selection</param>
		/// <param name="fInclusive"><c>true</c> if the reference returned should include the
		/// reference of the text of the verse where the selection is, even if that selection
		/// is not at the start of the verse; <c>false</c> if the reference should be that of
		/// the first full verse at or following the selection</param>
		/// <param name="scriptureRef">returns the scripture reference found</param>
		/// <returns>A TsString representing the reference of the selection, or null if the
		/// selection represents a book title or something weird.</returns>
		/// ------------------------------------------------------------------------------------
		private ITsString GetSelectionReference(SelectionHelper helper, bool fInclusive,
			out BCVRef scriptureRef)
		{
			scriptureRef = new BCVRef();
			if (helper != null && m_page.Publication != null && m_page.Publication is ScripturePublication)
			{
				ScripturePublication scrPub = m_page.Publication as ScripturePublication;
				int iParaLevel = helper.GetLevelForTag((int)StText.StTextTags.kflidParagraphs);
				if (iParaLevel >= 0)
				{
					ScrTxtPara para = new ScrTxtPara(m_cache, helper.LevelInfo[iParaLevel].hvo);
					// Look through the verses of the paragraph until we pass the location
					// where the page break occurs. This verse reference will then be the
					// first one on the page.
					ScrVerse firstVerseOnPage = null;
					int ichPageBreak = helper.IchAnchor;
					foreach (ScrVerse verse in para)
					{
						if (!fInclusive)
							firstVerseOnPage = verse;
						if (verse.VerseStartIndex > ichPageBreak ||
							(verse.VerseStartIndex == ichPageBreak && !fInclusive))
							break;
						if (fInclusive)
							firstVerseOnPage = verse;
					}

					ITsString tssBookName = GetBookName(helper);
					if (tssBookName != null)
					{
						ITsStrBldr bldr = tssBookName.GetBldr();
						int cch = bldr.Length;
						if (firstVerseOnPage != null)
						{
							if (firstVerseOnPage.StartRef.Verse != 0)
							{
								bldr.Replace(cch, cch, " " +
									((Scripture)m_scr).ChapterVerseRefAsString(firstVerseOnPage.StartRef, m_wsDefault), null);
							}
							scriptureRef = firstVerseOnPage.StartRef;
						}
						return bldr.GetString();
					}
					//else
					//{
					//    // Probably no verses were found in the paragraph
					//    IVwSelection sel = FindNextPara(helper);
					//    helper = SelectionHelper.Create(sel, helper.RootSite);

					//    return GetSelectionReference(helper, fInclusive, out scriptureRef);
					//}
				}
			}
			return null;
		}