Beispiel #1
0
		int m_wsUr; // Urdu writing system (used for Foreign style)
		#endregion

		#region Test setup
		/// ------------------------------------------------------------------------------------
		/// <summary>
		///
		/// </summary>
		/// ------------------------------------------------------------------------------------
		protected override void CreateTestData()
		{
			m_inMemoryCache.InitializeWritingSystemEncodings();

			// create footnote
			m_footnote = new StFootnote();
			m_book = (ScrBook)m_scrInMemoryCache.AddBookToMockedScripture(1, "Genesis");
			m_book.FootnotesOS.Append(m_footnote);
			m_footnote.FootnoteMarker.Text = "o";
			m_footnote.DisplayFootnoteMarker = true;
			m_footnote.DisplayFootnoteReference = false;

			// create one empty footnote para
			StTxtPara para = new StTxtPara();
			m_footnote.ParagraphsOS.Append(para);
			para.StyleRules = StyleUtils.ParaStyleTextProps(ScrStyleNames.NormalFootnoteParagraph);

			m_strFact = TsStrFactoryClass.Create();
			m_vernWs = Cache.LangProject.DefaultVernacularWritingSystem;
			para.Contents.UnderlyingTsString = m_strFact.MakeString(string.Empty, m_vernWs);
			m_footnotePara = (StTxtPara)m_footnote.ParagraphsOS[0];

			m_wsUr = InMemoryFdoCache.s_wsHvos.Ur; // used with 'foreign' character style
			m_wsDe = InMemoryFdoCache.s_wsHvos.De; // used for back translations
			m_wsEs = InMemoryFdoCache.s_wsHvos.Es;
		}
		public void TitleSecondary()
		{
			CheckDisposed();

			m_importer.Settings.ImportBackTranslation = true;

			// initialize - process a \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("", @"\id");

			// ************** process the title secondary style *********************
			m_importer.ProcessSegment("Title secondary", @"\st");
			m_importer.ProcessSegment("main title", @"\mt");

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\c");
			Assert.AreEqual(1, m_importer.Chapter);

			// ************** process v1 verse 1 *********************
			m_importer.ProcessSegment("verse text", @"\v");

			// verify state of NormalParaStrBldr
			Assert.AreEqual(3, m_importer.NormalParaStrBldr.RunCount);
			VerifyBldrRun(0, "1", ScrStyleNames.ChapterNumber);
			VerifyBldrRun(1, "1", ScrStyleNames.VerseNumber);
			VerifyBldrRun(2, "verse text", null);

			// ************** End of Scripture file *********************

			// ******* Back translation in default Analysis WS **********
			m_importer.CurrentImportDomain = ImportDomain.BackTrans;
			m_importer.DummySoWrapper.m_CurrentWs = m_wsAnal;

			// process an \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("", @"\id");

			// ************** process the title secondary style *********************
			m_importer.ProcessSegment("Title secondary BT", @"\st");
			m_importer.ProcessSegment("main title BT", @"\mt");

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\c");
			Assert.AreEqual(1, m_importer.Chapter);

			// ************** process v1 verse 1 *********************
			m_importer.ProcessSegment("back trans", @"\v");

			// ******* Back translation in Spanish WS **********
			int wsSpanish = Cache.LanguageWritingSystemFactoryAccessor.GetWsFromStr("es");
			m_importer.DummySoWrapper.m_CurrentWs = wsSpanish;

			// process an \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("", @"\id");

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\c");
			Assert.AreEqual(1, m_importer.Chapter);

			// ************** process v1 verse 1 *********************
			m_importer.ProcessSegment("retrotraduccion", @"\v");


			// ************** finalize **************
			m_importer.FinalizeImport();

			IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo);
			StTxtPara para = (StTxtPara)book.TitleOA.ParagraphsOS[0];
			Assert.AreEqual("Title secondary\u2028main title", para.Contents.Text);
			Assert.AreEqual(1, para.TranslationsOC.Count);
			ICmTranslation trans = para.GetBT();
			// Check default analysis BT
			TsStringAccessor bt = trans.Translation.AnalysisDefaultWritingSystem;
			Assert.AreEqual("Title secondary BT\u2028main title BT", bt.Text);
			Assert.AreEqual(2, bt.UnderlyingTsString.RunCount);
			AssertEx.RunIsCorrect(bt.UnderlyingTsString, 0, "Title secondary BT",
				"Title Secondary", m_scr.Cache.DefaultAnalWs);
			AssertEx.RunIsCorrect(bt.UnderlyingTsString, 1, "\u2028main title BT",
				null, m_scr.Cache.DefaultAnalWs);
		}
Beispiel #3
0
		/// <summary>
		/// Executes in two distinct scenarios.
		///
		/// 1. If disposing is true, the method has been called directly
		/// or indirectly by a user's code via the Dispose method.
		/// Both managed and unmanaged resources can be disposed.
		///
		/// 2. If disposing is false, the method has been called by the
		/// runtime from inside the finalizer and you should not reference (access)
		/// other managed objects, as they already have been garbage collected.
		/// Only unmanaged resources can be disposed.
		/// </summary>
		/// <param name="disposing"></param>
		/// <remarks>
		/// If any exceptions are thrown, that is fine.
		/// If the method is being done in a finalizer, it will be ignored.
		/// If it is thrown by client code calling Dispose,
		/// it needs to be handled by fixing the bug.
		///
		/// If subclasses override this method, they should call the base implementation.
		/// </remarks>
		protected override void Dispose(bool disposing)
		{
			//Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************");
			// Must not be run more than once.
			if (IsDisposed)
				return;

			if (disposing)
			{
				// Dispose managed resources here.
			}

			// Dispose unmanaged resources here, whether disposing is true or false.
			m_footnote = null;;
			m_book = null;
			if (m_strFact != null)
				Marshal.ReleaseComObject(m_strFact);
			m_strFact = null;;

			base.Dispose(disposing);
		}
Beispiel #4
0
		public void MergeBTsWhenParasMerge_FromMiddleOfPara1ToMiddleOfPara2_aKey()
		{
			CheckDisposed();

			ShowForm(Lng.English, DummyBasicViewVc.DisplayType.kNormal);

			IVwRootBox rootBox = m_basicView.RootBox;

			// Add a second paragraph to the first text and create some Back Translations on
			// both paragraphs
			ScrBook book = new ScrBook(Cache, m_hvoRoot);
			StText text1 = (StText)book.FootnotesOS[0];
			StTxtPara para1 = (StTxtPara)text1.ParagraphsOS[0];
			StTxtPara para2 = m_scrInMemoryCache.AddParaToMockedText(text1.Hvo, string.Empty);
			m_scrInMemoryCache.AddRunToMockedPara(para2, DummyBasicView.kSecondParaEng, m_wsEng);
			// We'll just re-use our "vernacular" WS for the back translation, for testing purposes.
			ICmTranslation trans1 = m_inMemoryCache.AddBtToMockedParagraph(para1, m_wsEng);
			m_inMemoryCache.AddRunToMockedTrans(trans1, m_wsEng, "BT1", null);
			ICmTranslation trans2 = m_inMemoryCache.AddBtToMockedParagraph(para2, m_wsEng);
			m_inMemoryCache.AddRunToMockedTrans(trans2, m_wsEng, "BT2", null);

			Cache.PropChanged(null, PropChangeType.kpctNotifyAll, text1.Hvo,
				(int)StText.StTextTags.kflidParagraphs, 1, 1, 0);

			// Make a selection from the end of first paragraph to the beginning of the second.
			SelLevInfo[] levelInfo = new SelLevInfo[2];
			levelInfo[1].tag = m_flidContainingTexts;
			levelInfo[1].cpropPrevious = 0;
			levelInfo[1].ihvo = 0;
			levelInfo[0].tag = (int)StText.StTextTags.kflidParagraphs;
			levelInfo[0].cpropPrevious = 0;
			levelInfo[0].ihvo = 0;
			int ichAnchor = DummyBasicView.kFirstParaEng.Length - 2;
			int ichEnd = 2;
			rootBox.MakeTextSelection(0, 2, levelInfo,
				(int)StTxtPara.StTxtParaTags.kflidContents, 0, ichAnchor, ichEnd, 0, true, 1, null,
				true);
			TypeChar('a');

			Assert.AreEqual(DummyBasicView.kFirstParaEng.Substring(0, ichAnchor) + "a" +
				DummyBasicView.kSecondParaEng.Substring(ichEnd), para1.Contents.Text);
			Assert.AreEqual("BT1 BT2", trans1.Translation.GetAlternative(m_wsEng).Text);
		}
Beispiel #5
0
		public void MergeTranslationsWhenParasMerge_FirstParaHasNoTranslations()
		{
			CheckDisposed();

			ShowForm(Lng.English, DummyBasicViewVc.DisplayType.kNormal);

			IVwRootBox rootBox = m_basicView.RootBox;

			// Add a second paragraph to the first text and create some translations on
			// both paragraphs
			ScrBook book = new ScrBook(Cache, m_hvoRoot);
			StText text1 = (StText)book.FootnotesOS[0];
			StTxtPara para1 = (StTxtPara)text1.ParagraphsOS[0];
			StTxtPara para2 = m_inMemoryCache.AddParaToMockedText(text1.Hvo, string.Empty);
			m_inMemoryCache.AddRunToMockedPara(para2, DummyBasicView.kSecondParaEng, m_wsEng);

			// We'll just re-use our "vernacular" WS for the translations, for testing purposes.
			ICmTranslation bt2 = m_inMemoryCache.AddBtToMockedParagraph(para2, m_wsEng);
			m_inMemoryCache.AddRunToMockedTrans(bt2, m_wsEng, "BT2", null);

			ICmTranslation free2 = m_inMemoryCache.AddTransToMockedParagraph(para2,
				LangProject.kguidTranFreeTranslation, m_wsEng);
			m_inMemoryCache.AddRunToMockedTrans(free2, m_wsEng, "Free2", null);

			ICmTranslation lit2 = m_inMemoryCache.AddTransToMockedParagraph(para2,
				LangProject.kguidTranLiteralTranslation, m_wsEng);
			m_inMemoryCache.AddRunToMockedTrans(lit2, m_wsEng, "Lit2", null);

			Cache.PropChanged(null, PropChangeType.kpctNotifyAll, text1.Hvo,
				(int)StText.StTextTags.kflidParagraphs, 1, 1, 0);

			// Make a selection from the end of first paragraph to the beginning of the second.
			SelLevInfo[] levelInfo = new SelLevInfo[2];
			levelInfo[1].tag = m_flidContainingTexts;
			levelInfo[1].cpropPrevious = 0;
			levelInfo[1].ihvo = 0;
			levelInfo[0].tag = (int)StText.StTextTags.kflidParagraphs;
			levelInfo[0].cpropPrevious = 0;
			levelInfo[0].ihvo = 0;
			int ich = DummyBasicView.kFirstParaEng.Length;
			rootBox.MakeTextSelection(0, 2, levelInfo,
				(int)StTxtPara.StTxtParaTags.kflidContents, 0, ich, 0, 0, true, 1, null,
				true);
			TypeBackspace();

			Assert.AreEqual(DummyBasicView.kFirstParaEng + DummyBasicView.kSecondParaEng,
				para1.Contents.Text);
			ICmTranslation bt1 = para1.GetBT();
			Assert.AreEqual("BT2", bt1.Translation.GetAlternative(m_wsEng).Text);
			ICmTranslation free1 = para1.GetTrans(LangProject.kguidTranFreeTranslation);
			Assert.AreEqual("Free2", free1.Translation.GetAlternative(m_wsEng).Text);
			ICmTranslation lit1 = para1.GetTrans(LangProject.kguidTranLiteralTranslation);
			Assert.AreEqual("Lit2", lit1.Translation.GetAlternative(m_wsEng).Text);
		}
Beispiel #6
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Merges content of given section into the content of the previous section and then
		/// deletes the given section.
		/// </summary>
		/// <param name="helper"> </param>
		/// <param name="book"></param>
		/// <param name="section"></param>
		/// <param name="ihvoSection"></param>
		/// <param name="fPositionAtEnd">If true position of Selection is placed at end of
		/// paragraph, else at the beginning.</param>
		/// ------------------------------------------------------------------------------------
		private void MergeContentWithPreviousSection(SelectionHelper helper, ScrBook book,
			IScrSection section, int ihvoSection, bool fPositionAtEnd)
		{
			//REVIEW: Can the methods that call this be refactored
			//to use (a refactored?) ScrSection.MergeWithPreviousSection?
			//
			// Get the previous section and move the paragraphs.
			IScrSection sectionPrev = book.SectionsOS[ihvoSection - 1];
			IStText textPrev = sectionPrev.ContentOA;
			ILocationTracker tracker = ((ITeView)Control).LocationTracker;
			int iBook = tracker.GetBookIndex(helper, SelectionHelper.SelLimitType.Top);
			int cparaPrev = 0;
			if (textPrev == null)
			{
				// Prevent crash when dealing with corrupt database (TE-4869)
				// Since the previous section doesn't have a text, we simply move the entire text
				// object from the current section to the previous section.
				m_cache.ChangeOwner(section.ContentOAHvo, sectionPrev.Hvo,
					(int)ScrSection.ScrSectionTags.kflidContent);
			}
			else
			{
				cparaPrev = textPrev.ParagraphsOS.Count;
				IStText textOldContents = section.ContentOA;
				m_cache.MoveOwningSequence(textOldContents.Hvo, (int)StText.StTextTags.kflidParagraphs,
					0, textOldContents.ParagraphsOS.Count - 1,
					textPrev.Hvo, (int)StText.StTextTags.kflidParagraphs, cparaPrev);
			}
			// protected for some reason...textPrev.ParagraphsOS.Append(text.ParagraphsOS.HvoArray);
			book.SectionsOS.RemoveAt(ihvoSection);
			// Now we have to re-establish a selection. Whatever happens, it will be in the
			// same book as before, and the previous section, and in the body.
			if (InSectionHead || !fPositionAtEnd)
			{
				tracker.SetBookAndSection(helper, SelectionHelper.SelLimitType.Top, iBook,
					ihvoSection - 1);
				helper.GetLevelInfo(SelectionHelper.SelLimitType.Top)[1].tag =
					(int)ScrSection.ScrSectionTags.kflidContent;
			}
			Debug.Assert(helper.GetLevelInfo(SelectionHelper.SelLimitType.Top)[1].tag ==
				(int)ScrSection.ScrSectionTags.kflidContent);

			if (fPositionAtEnd)
			{
				// we want selection at end of last paragraph of old previous section.
				// (That is, at the end of paragraph cparaPrev - 1.)
				Debug.Assert(cparaPrev > 0);
				helper.GetLevelInfo(SelectionHelper.SelLimitType.Top)[0].ihvo = cparaPrev - 1;
				StTxtPara paraPrev = (StTxtPara)(textPrev.ParagraphsOS[cparaPrev - 1]);

				int cchParaPrev = paraPrev.Contents.Length;
				helper.IchAnchor = cchParaPrev;
				helper.IchEnd = cchParaPrev;
				helper.AssocPrev = true;
			}
			else
			{
				// want selection at start of old first paragraph of deleted section.
				// (That is, at the start of paragraph cparaPrev.)
				helper.GetLevelInfo(SelectionHelper.SelLimitType.Top)[0].ihvo = cparaPrev;
				helper.IchAnchor = 0;
				helper.IchEnd = 0;
				helper.AssocPrev = false;
			}
			helper.SetLevelInfo(SelectionHelper.SelLimitType.Bottom,
				helper.GetLevelInfo(SelectionHelper.SelLimitType.Top));
			helper.SetSelection(true);
		}
Beispiel #7
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Handles deletion of empty section content paragraph on backspace key being pressed
		/// at text boundary.
		/// </summary>
		/// <param name="helper">The selection helper.</param>
		/// <returns><c>true</c> if we merged the sections, otherwise <c>false</c>.</returns>
		/// ------------------------------------------------------------------------------------
		private bool HandleBackspaceAfterEmptyContentParagraph(SelectionHelper helper)
		{
			SelLevInfo[] levInfo = helper.GetLevelInfo(SelectionHelper.SelLimitType.Top);
			ILocationTracker tracker = ((ITeView)Control).LocationTracker;
			ScrBook book = new ScrBook(m_cache, tracker.GetBookHvo(helper, SelectionHelper.SelLimitType.Top));
			int iSection = tracker.GetSectionIndexInBook(helper, SelectionHelper.SelLimitType.Top);
			if (iSection == 0)
				return false;
			IScrSection prevSection = book.SectionsOS[iSection - 1];
			int cParas = prevSection.ContentOA != null ? prevSection.ContentOA.ParagraphsOS.Count : 0;
			if (cParas > 0)
			{
				// If we are the beginning of heading before a multi-paragraph content
				// and the last paragraph is empty, we delete the last paragraph of
				// the content.
				if (cParas > 1)
				{
					StTxtPara para = (StTxtPara)prevSection.ContentOA.ParagraphsOS[cParas - 1];
					if (para.Contents.Length == 0)
					{
						prevSection.ContentOA.ParagraphsOS.RemoveAt(cParas - 1);
						return true;
					}
				}
				// If we are at beginning of heading before an empty section content and
				// not in the first section, we should merge sections.
				else
				{
					StTxtPara para = (StTxtPara)prevSection.ContentOA.ParagraphsOS[cParas - 1];
					if (para.Contents.Length == 0)
					{
						return MergeWithFollowingSectionIfInSameContext(helper, book,
							iSection - 1, prevSection, false);
					}
				}
			}
			else
			{
				return MergeWithFollowingSectionIfInSameContext(helper, book, iSection - 1,
					prevSection, false);
			}
			return false;
		}
Beispiel #8
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Handles deletion of empty section content paragraph on delete key being pressed at
		/// text boundary.
		/// </summary>
		/// <param name="helper">The selection helper.</param>
		/// <returns><c>true</c> if we merged the sections, otherwise <c>false</c>.</returns>
		/// ------------------------------------------------------------------------------------
		private bool HandleDeleteBeforeEmptySectionContentParagraph(SelectionHelper helper)
		{
			// delete problem deletion will occur at end of section heading
			SelLevInfo[] levInfo = helper.GetLevelInfo(SelectionHelper.SelLimitType.Top);
			ILocationTracker tracker = ((ITeView)Control).LocationTracker;
			ScrBook book = new ScrBook(m_cache, tracker.GetBookHvo(helper,
				SelectionHelper.SelLimitType.Top));
			int iSection = tracker.GetSectionIndexInBook(helper, SelectionHelper.SelLimitType.Top);
			IScrSection section = book.SectionsOS[iSection];
			int cParas = section.ContentOA != null ? section.ContentOA.ParagraphsOS.Count : 0;
			if (cParas > 0)
			{
				// If we are the end of heading before a multi-paragraph content
				// and the first paragraph is empty, we delete the first paragraph of
				// the content.
				if (cParas > 1)
				{
					StTxtPara para = (StTxtPara)section.ContentOA.ParagraphsOS[0];
					if (para.Contents.Length == 0)
					{
						section.ContentOA.ParagraphsOS.RemoveAt(0);
						return true;
					}
				}
				// If we are at end of section heading or beginning of section content
				// and not in the last section, we should merge sections.
				else
				{
					if (iSection == book.SectionsOS.Count - 1)
						return false;
					StTxtPara para = (StTxtPara)section.ContentOA.ParagraphsOS[0];
					if (para.Contents.Length == 0)
					{
						return MergeWithFollowingSectionIfInSameContext(helper, book, iSection,
							section, true);
					}
				}
			}
			else
			{
				return MergeWithFollowingSectionIfInSameContext(helper, book, iSection,
					section, true);
			}
			return false;
		}
Beispiel #9
0
		/// -----------------------------------------------------------------------------------
		/// <summary>
		/// Get a string that describes the Scripture passage based on the selection.
		/// </summary>
		/// <param name="tag">The flid of the selected element</param>
		/// <param name="hvoSel">The hvo of the selected element, either a ScrSection (usually)
		/// or ScrBook (if in a title)</param>
		/// <param name="fSimpleFormat">Gets a simple, standardized reference (uses SIL 3-letter
		/// codes and no verse bridges)</param>
		/// <returns>String that describes the Scripture passage or null if the selection
		/// can't be interpreted as a book and/or section reference.</returns>
		/// -----------------------------------------------------------------------------------
		public virtual string GetPassageAsString(int tag, int hvoSel, bool fSimpleFormat)
		{
			CheckDisposed();

			if (m_cache == null)
				return null;

			string sEditRef = null; // Title/reference/etc of text being edited in the draft pane
			switch (tag)
			{
				case (int)ScrSection.ScrSectionTags.kflidHeading:
				case (int)ScrSection.ScrSectionTags.kflidContent:
				{
					// ENHANCE TomB: might want to use low-level methods to get
					// cached values directly instead of creating the FDO objects
					// and having them reread the info from the DB. Also, may want
					// to cache the hvoSel in a method static variable so that when
					// the selection hasn't really changed to a new section or book,
					// we stop here.
					ScrSection section = new ScrSection(m_cache, hvoSel, false, false);
					BCVRef startRef;
					BCVRef endRef;
					section.GetDisplayRefs(out startRef, out endRef);
					if (fSimpleFormat)
						sEditRef = startRef.AsString;
					else
					{
						sEditRef = ScrReference.MakeReferenceString(section.OwningBook.BestUIName,
							startRef, endRef, m_scr.ChapterVerseSepr, m_scr.Bridge);
					}
					break;
				}
				case (int)ScrBook.ScrBookTags.kflidTitle:
				{
					ScrBook book = new ScrBook(m_cache, hvoSel, false, false);
					sEditRef = (fSimpleFormat ? (book.BookId + " 0:0") : book.BestUIName);
					break;
				}
				default:
					return null;
			}

			// Add the back translation writing system info to the output string, if needed
			if (IsBackTranslation)
			{
				LgWritingSystem ws = new LgWritingSystem(m_cache, ViewConstructorWS);
				sEditRef = string.Format(
					TeResourceHelper.GetResourceString("kstidCaptionInBackTrans"),
					sEditRef, ws.Name.UserDefaultWritingSystem);
			}

			return (sEditRef != null && sEditRef.Length != 0) ? sEditRef : null;
		}
Beispiel #10
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Scrolls the requested footnote to the top of the view
		/// </summary>
		/// <param name="footnote">The target footnote</param>
		/// <param name="fPutInsertionPtAtEnd">if set to <c>true</c> and showing the view,
		/// the insertion point will be put at the end of the footnote text instead of at the
		/// beginning, as would be appropriate in the case of a newly inserted footnote that has
		/// Reference Text. This parameter is ignored if footnote is null.</param>
		/// ------------------------------------------------------------------------------------
		public void ScrollToFootnote(StFootnote footnote, bool fPutInsertionPtAtEnd)
		{
			CheckDisposed();

			// find book owning this footnote
			int iBook = m_bookFilter.GetBookIndex(footnote.OwnerHVO);
			ScrBook book = new ScrBook(Cache, footnote.OwnerHVO);

			// find index of this footnote
			int iFootnote = footnote.IndexInOwner;

			// create selection pointing to this footnote
			FootnoteEditingHelper.ScrollToFootnote(iBook, iFootnote, (fPutInsertionPtAtEnd ?
				((StTxtPara)footnote.ParagraphsOS[0]).Contents.Length: 0));
		}
		public void BtOnlyFootnotes()
		{
			m_scrInMemoryCache.InitializeScrPublications();

			// Set up Scripture to correspond with the back translation to be imported.
			IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(2, "Exodus");
			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			StTxtPara para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo,
				ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(para, "1", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para, "1", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para, "verse one text", null);
			m_scrInMemoryCache.AddRunToMockedPara(para, "2", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para, "verse two text", null);
			StFootnote noteOne = m_scrInMemoryCache.AddFootnote(exodus, para, 11,
				"vernacular text for footnote one"); // footnote after "one" in verse 1
			StFootnote noteTwo = m_scrInMemoryCache.AddFootnote(exodus, para, 27,
				"vernacular text for footnote two"); // footnote after "two" in verse 2
			ICmTranslation noteOneTrans = ((StTxtPara)noteOne.ParagraphsOS[0]).GetOrCreateBT();
			ICmTranslation noteTwoTrans = ((StTxtPara)noteTwo.ParagraphsOS[0]).GetOrCreateBT();
			section.AdjustReferences();

			m_importer.Settings.ImportTranslation = false;
			m_importer.Settings.ImportBackTranslation = true;
			m_importer.CurrentImportDomain = ImportDomain.BackTrans;

			// ************** process a \id segment, test MakeBook() method *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("", @"\id"); // no text provided in segment, just the refs
			Assert.AreEqual(2, m_importer.BookNumber);
			// verify that a new book was added to the DB
			IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo);
			Assert.AreEqual("EXO", book.BookId);

			// ************** process a main title *********************
			m_importer.ProcessSegment(string.Empty, @"\mt");

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 0);
			m_importer.ProcessSegment("", @"\c");

			// ****** process a new BT paragraph with footnotes **********
			m_importer.ProcessSegment("", @"\p");
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\v");
			m_importer.ProcessSegment("verse one BT text", @"\vt");
			m_importer.ProcessSegment("+", @"\f");
			m_importer.ProcessSegment("BT text for footnote one.", @"\ft");
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 2);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 2);
			m_importer.ProcessSegment("", @"\v");
			m_importer.ProcessSegment("verse two BT text", @"\vt");
			m_importer.ProcessSegment("+", @"\f");
			m_importer.ProcessSegment("BT text for footnote two.", @"\ft");

			// ************** finalize **************
			m_importer.FinalizeImport();

			// Check the BT of these two paragraphs
			Assert.AreEqual(1, para.TranslationsOC.Count);
			ICmTranslation trans1 = para.GetBT();
			Assert.IsNotNull(trans1);
			ITsString tss1 = trans1.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString;
			//Assert.AreEqual(7, tss1.RunCount);
			AssertEx.RunIsCorrect(tss1, 0, "1", ScrStyleNames.ChapterNumber, m_wsAnal);
			AssertEx.RunIsCorrect(tss1, 1, "1", ScrStyleNames.VerseNumber, m_wsAnal);
			AssertEx.RunIsCorrect(tss1, 2, "verse one BT text", null, m_wsAnal);

			Guid guid1 = StringUtils.GetGuidFromRun(tss1, 3);
			int hvoFootnote = Cache.GetIdFromGuid(guid1);
			Assert.AreEqual(noteOneTrans.OwnerHVO,
				new StFootnote(Cache, hvoFootnote).ParagraphsOS[0].Hvo,
				"The first imported BT footnote should be owned by paragraph in the first footnote but isn't");

			VerifyFootnoteWithTranslation(0, "vernacular text for footnote one",
				"BT text for footnote one.", null, ScrStyleNames.NormalFootnoteParagraph);
			AssertEx.RunIsCorrect(tss1, 4, "2", ScrStyleNames.VerseNumber, m_wsAnal);
			AssertEx.RunIsCorrect(tss1, 5, "verse two BT text", null, m_wsAnal);
			VerifyFootnoteWithTranslation(1, "vernacular text for footnote two",
				"BT text for footnote two.", null, ScrStyleNames.NormalFootnoteParagraph);
		}
		public void TwoBts()
		{
			CheckDisposed();

			m_importer.Settings.ImportBackTranslation = true;

			// initialize - process a \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("EXO Vernacular ID Text", @"\id");

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\c");
			Assert.AreEqual(1, m_importer.Chapter);

			// ************** process v1 verse 1 *********************
			m_importer.ProcessSegment("verse text", @"\v");

			// verify state of NormalParaStrBldr
			Assert.AreEqual(3, m_importer.NormalParaStrBldr.RunCount);
			VerifyBldrRun(0, "1", ScrStyleNames.ChapterNumber);
			VerifyBldrRun(1, "1", ScrStyleNames.VerseNumber);
			VerifyBldrRun(2, "verse text", null);

			// ************** End of Scripture file *********************

			// ******* Back translation in default Analysis WS **********
			m_importer.CurrentImportDomain = ImportDomain.BackTrans;
			m_importer.DummySoWrapper.m_CurrentWs = m_wsAnal;

			// process an \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("EXO Ignore this", @"\id");

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\c");
			Assert.AreEqual(1, m_importer.Chapter);

			// ************** process v1 verse 1 *********************
			m_importer.ProcessSegment("back trans", @"\v");

			// ******* Back translation in Spanish WS **********
			int wsSpanish = Cache.LanguageWritingSystemFactoryAccessor.GetWsFromStr("es");
			m_importer.DummySoWrapper.m_CurrentWs = wsSpanish;

			// process an \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("EXO Ignora esto tambien", @"\id");

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\c");
			Assert.AreEqual(1, m_importer.Chapter);

			// ************** process v1 verse 1 *********************
			m_importer.ProcessSegment("retrotraduccion", @"\v");

			// ************** finalize **************
			m_importer.FinalizeImport();

			IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo);
			Assert.AreEqual("Vernacular ID Text", book.IdText);
			Assert.AreEqual(1, book.SectionsOS.Count);
			IScrSection section = book.SectionsOS[0];
			Assert.AreEqual(1, section.ContentOA.ParagraphsOS.Count);
			Assert.AreEqual(02001001, section.VerseRefMin);
			Assert.AreEqual(02001001, section.VerseRefMax);
			StTxtPara para = (StTxtPara)section.ContentOA.ParagraphsOS[0];
			Assert.AreEqual("11verse text", para.Contents.Text);
			Assert.AreEqual(1, para.TranslationsOC.Count);
			ICmTranslation trans = para.GetBT();
			// Check default analysis BT
			TsStringAccessor bt = trans.Translation.AnalysisDefaultWritingSystem;
			Assert.AreEqual("11back trans", bt.Text);
			Assert.AreEqual(3, bt.UnderlyingTsString.RunCount);
			Assert.AreEqual("back trans", bt.UnderlyingTsString.get_RunText(2));
			ITsTextProps ttpRun3 = bt.UnderlyingTsString.get_Properties(2);
			Assert.AreEqual(null,
				ttpRun3.GetStrPropValue((int)FwTextPropType.ktptNamedStyle));
			int nVar;
			Assert.AreEqual(m_wsAnal,
				ttpRun3.GetIntPropValues((int)FwTextPropType.ktptWs, out nVar));

			// Check Spanish BT
			bt = trans.Translation.GetAlternative(wsSpanish);
			Assert.AreEqual("11retrotraduccion", bt.Text);
			Assert.AreEqual(3, bt.UnderlyingTsString.RunCount);
			Assert.AreEqual("retrotraduccion", bt.UnderlyingTsString.get_RunText(2));
			ttpRun3 = bt.UnderlyingTsString.get_Properties(2);
			Assert.AreEqual(null,
				ttpRun3.GetStrPropValue((int)FwTextPropType.ktptNamedStyle));
			Assert.AreEqual(wsSpanish,
				ttpRun3.GetIntPropValues((int)FwTextPropType.ktptWs, out nVar));
		}
		public void ImplicitParaStart()
		{
			CheckDisposed();
			m_scrInMemoryCache.InitializeScrPublications();

			// Set up Scripture to correspond with the back translation to be imported.
			IScrBook exodus = m_scrInMemoryCache.AddBookToMockedScripture(2, "Exodus");
			IScrSection section1 = m_scrInMemoryCache.AddSectionToMockedBook(exodus.Hvo);
			StTxtPara para1 = m_scrInMemoryCache.AddParaToMockedSectionContent(section1.Hvo,
				ScrStyleNames.NormalParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(para1, "1", ScrStyleNames.ChapterNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para1, "1", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para1, "verse one text", null);
			m_scrInMemoryCache.AddRunToMockedPara(para1, "2", ScrStyleNames.VerseNumber);
			m_scrInMemoryCache.AddRunToMockedPara(para1, "verse two text", null);
			StTxtPara para2 = m_scrInMemoryCache.AddParaToMockedSectionContent(section1.Hvo, "List Item1");
			m_scrInMemoryCache.AddRunToMockedPara(para2, "more verse two text", null);
			section1.AdjustReferences();

			m_importer.Settings.ImportBackTranslation = true;
			m_importer.CurrentImportDomain = ImportDomain.BackTrans;

			// ************** process a \id segment, test MakeBook() method *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("", @"\id"); // no text provided in segment, just the refs
			Assert.AreEqual(2, m_importer.BookNumber);
			IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo);
			Assert.AreEqual("EXO", book.BookId);

			// ************** process a main title *********************
			m_importer.ProcessSegment(string.Empty, @"\mt");
			//Assert.AreEqual(string.Empty, m_importer.ScrBook.Name.GetAlternative(
			//    m_wsAnal));

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 0);
			m_importer.ProcessSegment("", @"\c");

			// ************** process two new paragraphs *********************
			m_importer.ProcessSegment("", @"\p");
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\v");
			m_importer.ProcessSegment("BT text for verse one", @"\vt");
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 2);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 2);
			m_importer.ProcessSegment("", @"\v");
			m_importer.ProcessSegment("BT for text at start of verse 2", @"\vt");
			m_importer.ProcessSegment("", @"\li1");
			m_importer.ProcessSegment("BT of continued text", @"\vt");

			// ************** finalize **************
			m_importer.FinalizeImport();

			// Check the BT of these two paragraphs
			Assert.AreEqual(1, para1.TranslationsOC.Count);
			ICmTranslation trans1 = para1.GetBT();
			ITsString tss1 = trans1.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString;
			Assert.AreEqual(5, tss1.RunCount);
			AssertEx.RunIsCorrect(tss1, 0, "1", ScrStyleNames.ChapterNumber, m_wsAnal);
			AssertEx.RunIsCorrect(tss1, 1, "1", ScrStyleNames.VerseNumber, m_wsAnal);
			AssertEx.RunIsCorrect(tss1, 2, "BT text for verse one", null, m_wsAnal);
			AssertEx.RunIsCorrect(tss1, 3, "2", ScrStyleNames.VerseNumber, m_wsAnal);
			AssertEx.RunIsCorrect(tss1, 4, "BT for text at start of verse 2", null, m_wsAnal);

			Assert.AreEqual(1, para2.TranslationsOC.Count);
			ICmTranslation trans2 = para2.GetBT();
			ITsString tss2 = trans2.Translation.AnalysisDefaultWritingSystem.UnderlyingTsString;
			Assert.AreEqual(1, tss2.RunCount);
		}
		public void VerseBeyondVersificationMax()
		{
			CheckDisposed();

			m_importer.Settings.ImportBackTranslation = true;

			// initialize - process a \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(45, 7, 25);
			m_importer.TextSegment.LastReference = new BCVRef(45, 7, 25);
			m_importer.ProcessSegment("", @"\id");

			m_importer.ProcessSegment("", @"\c");

			// ************** process two new paragraphs *********************
			m_importer.ProcessSegment("", @"\p");
			m_importer.ProcessSegment("", @"\v");
			m_importer.ProcessSegment("Front text for verse25", @"\vt");
			m_importer.TextSegment.FirstReference = new BCVRef(45, 7, 26);
			m_importer.TextSegment.LastReference = new BCVRef(45, 7, 26);
			m_importer.ProcessSegment("", @"\v");
			m_importer.ProcessSegment("Front text for verse26", @"\vt");

			//// verify state of NormalParaStrBldr
			Assert.AreEqual(5, m_importer.NormalParaStrBldr.RunCount);
			VerifyBldrRun(0, "7", ScrStyleNames.ChapterNumber);
			VerifyBldrRun(1, "25", ScrStyleNames.VerseNumber);
			VerifyBldrRun(2, "Front text for verse25", null);
			VerifyBldrRun(3, "26", ScrStyleNames.VerseNumber);
			VerifyBldrRun(4, "Front text for verse26", null);


			// ************** End of Scripture file *********************

			// ******* Back translation in default Analysis WS **********
			m_importer.CurrentImportDomain = ImportDomain.BackTrans;
			m_importer.DummySoWrapper.m_CurrentWs = m_wsAnal;

			// process an \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(45, 7, 26);
			m_importer.TextSegment.LastReference = new BCVRef(45, 7, 26);
			m_importer.ProcessSegment("", @"\id");
			m_importer.ProcessSegment("", @"\c");

			// ************** process two new paragraphs *********************
			m_importer.ProcessSegment("", @"\p");
			m_importer.ProcessSegment("", @"\v");
			m_importer.ProcessSegment("Back text for verse", @"\vt");

			// ************** finalize **************
			m_importer.FinalizeImport();

			IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo);
			// Check section 1
			StTxtPara para = (StTxtPara)book.SectionsOS[0].ContentOA.ParagraphsOS[0];
			Assert.AreEqual("725Front text for verse2526Front text for verse26", para.Contents.Text);
			Assert.AreEqual(1, para.TranslationsOC.Count);
			ICmTranslation trans = para.GetBT();
			// Check default analysis BT
			TsStringAccessor bt = trans.Translation.AnalysisDefaultWritingSystem;
			Assert.AreEqual("726Back text for verse", bt.Text);
			Assert.AreEqual(3, bt.UnderlyingTsString.RunCount);
			AssertEx.RunIsCorrect(bt.UnderlyingTsString, 0,
				"7", ScrStyleNames.ChapterNumber, m_scr.Cache.DefaultAnalWs);
			AssertEx.RunIsCorrect(bt.UnderlyingTsString, 1,
				"26", ScrStyleNames.VerseNumber, m_scr.Cache.DefaultAnalWs);
			AssertEx.RunIsCorrect(bt.UnderlyingTsString, 2,
				"Back text for verse", null, m_scr.Cache.DefaultAnalWs);
		}
		public void DoubleSectionHeadMarker()
		{
			CheckDisposed();

			m_importer.Settings.ImportBackTranslation = true;

			// initialize - process a \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("", @"\id");

			// ************** process the two-line section head ***************
			m_importer.ProcessSegment("Front Section head 1.1", @"\s");
			m_importer.ProcessSegment("Front Section head 1.2", @"\s");

			//// verify state of NormalParaStrBldr
			Assert.AreEqual(1, m_importer.NormalParaStrBldr.RunCount);
			VerifyBldrRun(0, "Front Section head 1.1\u2028Front Section head 1.2", null);

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\c");
			Assert.AreEqual(1, m_importer.Chapter);

			// ************** process v1 verse 1 *********************
			m_importer.ProcessSegment("Some verse", @"\v");

			// ************** process another two-line section head **************
			m_importer.ProcessSegment("Front Section head 2.1", @"\s");
			m_importer.ProcessSegment("Front Section head 2.2", @"\s");

			//// verify state of NormalParaStrBldr
			Assert.AreEqual(1, m_importer.NormalParaStrBldr.RunCount);
			VerifyBldrRun(0, "Front Section head 2.1\u2028Front Section head 2.2", null);

			// ************** End of Scripture file *********************

			// ******* Back translation in default Analysis WS **********
			m_importer.CurrentImportDomain = ImportDomain.BackTrans;
			m_importer.DummySoWrapper.m_CurrentWs = m_wsAnal;

			// process an \id segment to establish a book
			m_importer.TextSegment.FirstReference = new BCVRef(2, 0, 0);
			m_importer.TextSegment.LastReference = new BCVRef(2, 0, 0);
			m_importer.ProcessSegment("", @"\id");

			// ************** process the BT of section head 1 **************
			m_importer.ProcessSegment("Back Section head 1.1", @"\s");
			m_importer.ProcessSegment("Back Section head 1.2", @"\s");

			// ************** process a chapter *********************
			m_importer.TextSegment.FirstReference = new BCVRef(2, 1, 1);
			m_importer.TextSegment.LastReference = new BCVRef(2, 1, 1);
			m_importer.ProcessSegment("", @"\c");
			Assert.AreEqual(1, m_importer.Chapter);

			// ************** process v1 verse 1 *********************
			m_importer.ProcessSegment("Algun versiculo", @"\v");

			// ************** process the BT of section head 2 **************
			m_importer.ProcessSegment("Back Section head 2.1", @"\s");
			m_importer.ProcessSegment("Back Section head 2.2", @"\s");

			// ************** finalize **************
			m_importer.FinalizeImport();

			IScrBook book = new ScrBook(Cache, m_importer.ScrBook.Hvo);
			// Check section 1
			StTxtPara para = (StTxtPara)book.SectionsOS[0].HeadingOA.ParagraphsOS[0];
			Assert.AreEqual("Front Section head 1.1\u2028Front Section head 1.2", para.Contents.Text);
			Assert.AreEqual(1, para.TranslationsOC.Count);
			ICmTranslation trans = para.GetBT();
			// Check default analysis BT
			TsStringAccessor bt = trans.Translation.AnalysisDefaultWritingSystem;
			Assert.AreEqual("Back Section head 1.1\u2028Back Section head 1.2", bt.Text);
			Assert.AreEqual(1, bt.UnderlyingTsString.RunCount);
			AssertEx.RunIsCorrect(bt.UnderlyingTsString, 0,
				"Back Section head 1.1\u2028Back Section head 1.2", null, m_scr.Cache.DefaultAnalWs);

			// Check section 2
			para = (StTxtPara)book.SectionsOS[1].HeadingOA.ParagraphsOS[0];
			Assert.AreEqual("Front Section head 2.1\u2028Front Section head 2.2", para.Contents.Text);
			Assert.AreEqual(1, para.TranslationsOC.Count);
			trans = para.GetBT();
			// Check default analysis BT
			bt = trans.Translation.AnalysisDefaultWritingSystem;
			Assert.AreEqual("Back Section head 2.1\u2028Back Section head 2.2", bt.Text);
			Assert.AreEqual(1, bt.UnderlyingTsString.RunCount);
			AssertEx.RunIsCorrect(bt.UnderlyingTsString, 0,
				"Back Section head 2.1\u2028Back Section head 2.2", null, m_scr.Cache.DefaultAnalWs);
		}
Beispiel #16
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Handles deletion of empty section heading paragraph on backspace key being pressed
		/// at text boundary.
		/// </summary>
		/// <param name="helper">The selection helper.</param>
		/// <returns><c>true</c> if we handled the deletion, otherwise <c>false</c></returns>
		/// ------------------------------------------------------------------------------------
		private bool HandleBackspaceAfterEmptySectionHeadParagraph(SelectionHelper helper)
		{
			ILocationTracker tracker = ((ITeView)Control).LocationTracker;
			SelLevInfo[] levInfo = helper.GetLevelInfo(SelectionHelper.SelLimitType.Top);
			ScrBook book = new ScrBook(m_cache, tracker.GetBookHvo(helper,
				SelectionHelper.SelLimitType.Top));
			ScrSection section = new ScrSection(m_cache, tracker.GetSectionHvo(helper,
				SelectionHelper.SelLimitType.Top));
			int iSection = tracker.GetSectionIndexInBook(helper, SelectionHelper.SelLimitType.Top);
			int cParas = section.HeadingOA != null ? section.HeadingOA.ParagraphsOS.Count : 0;
			if (cParas > 0)
			{
				// If we are the beginning of content before a multi-paragraph heading
				// and the last paragraph is empty, we delete the last paragraph of
				// the heading.
				if (cParas > 1)
				{
					StTxtPara para = (StTxtPara)section.HeadingOA.ParagraphsOS[cParas - 1];
					if (para.Contents.Length == 0)
					{
						section.HeadingOA.ParagraphsOS.RemoveAt(cParas - 1);
						return true;
					}
				}
				// If we are at beginning of content before an empty section head and
				// not in the first section, we should merge sections.
				else if (iSection > 0)
				{
					StTxtPara para = (StTxtPara)section.HeadingOA.ParagraphsOS[cParas - 1];
					if (para.Contents.Length == 0)
					{
						return MergeWithPreviousSectionIfInSameContext(helper, book, section,
							iSection, false);
					}
				}
				return false;	// heading is not empty
			}

			// don't crash if database is corrupt - allow user to merge with
			// previous section (TE-4869)
			if (iSection > 0)
			{
				return MergeWithPreviousSectionIfInSameContext(helper, book,
					section, iSection, false);
			}
			return false;
		}
Beispiel #17
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Merges the content of the current section with the previous section if in the
		/// sections have the same context.
		/// </summary>
		/// <param name="helper">The selection helper.</param>
		/// <param name="book">The current book.</param>
		/// <param name="section">The current section.</param>
		/// <param name="iSection">The index of the current section.</param>
		/// <param name="fPositionAtEnd">If true position of Selection is placed at end of
		/// paragraph, else at the beginning.</param>
		/// <returns><c>true</c> if we merged the sections, otherwise <c>false</c>.</returns>
		/// ------------------------------------------------------------------------------------
		private bool MergeWithPreviousSectionIfInSameContext(SelectionHelper helper, ScrBook book,
			IScrSection section, int iSection, bool fPositionAtEnd)
		{
			IScrSection prevSection = book.SectionsOS[iSection - 1];
			if (SectionsHaveSameContext(prevSection, section))
			{
				MergeContentWithPreviousSection(helper, book, section, iSection,
					fPositionAtEnd);
				return true;
			}
			return false;
		}
Beispiel #18
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Apply style to selection
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public override void ApplyStyle(string sStyleToApply)
		{
			CheckDisposed();

			// Make sure that the Chapter Number style is not applied to non-numeric data
			if (sStyleToApply == ScrStyleNames.ChapterNumber && CurrentSelection != null)
			{
				ITsString tssSelected;
				CurrentSelection.Selection.GetSelectionString(out tssSelected, string.Empty);
				if (tssSelected.Text != null)
				{
					foreach (char ch in tssSelected.Text)
					{
						if (!Char.IsDigit(ch))
						{
							MiscUtils.ErrorBeep();
							return;
						}
					}
				}
			}
			base.ApplyStyle(sStyleToApply);

			// Update the footnote markers if we changed the style of a footnote
			if ((sStyleToApply == ScrStyleNames.CrossRefFootnoteParagraph ||
				sStyleToApply == ScrStyleNames.NormalFootnoteParagraph) &&
				ParagraphHvo > 0)
			{
				// Save the selection
				SelectionHelper prevSelection = CurrentSelection;

				if (m_cache.MarkerIndexCache != null)
					m_cache.MarkerIndexCache.ClearCache();
				StTxtPara para = new StTxtPara(m_cache, ParagraphHvo);
				Debug.Assert(m_cache.GetClassOfObject(para.OwnerHVO) == StFootnote.kClassId);

				StFootnote footnote = new StFootnote(m_cache, para.OwnerHVO);
				ScrBook book = new ScrBook(m_cache, footnote.OwnerHVO);

				m_cache.PropChanged(null, PropChangeType.kpctNotifyAll,
					book.Hvo, (int)ScrBook.ScrBookTags.kflidFootnotes, 0,
					book.FootnotesOS.Count, book.FootnotesOS.Count);

				// restore the selection
				prevSelection.SetSelection(true);
			}
		}
Beispiel #19
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Merges the section the with following section if they are in the same context.
		/// </summary>
		/// <param name="helper">The selection helper.</param>
		/// <param name="book">The book.</param>
		/// <param name="iSection">The index of the current section.</param>
		/// <param name="section">The current section.</param>
		/// <param name="fDeleteForward">if set to <c>true</c> the user pressed the delete key,
		/// otherwise the backspace key.</param>
		/// <returns><c>true</c> if we merged the sections, otherwise <c>false</c>.</returns>
		/// ------------------------------------------------------------------------------------
		private bool MergeWithFollowingSectionIfInSameContext(SelectionHelper helper, ScrBook book,
			int iSection, IScrSection section, bool fDeleteForward)
		{
			IScrSection nextSection = book.SectionsOS[iSection + 1];
			// Merge the sections if they have the same context.
			if (SectionsHaveSameContext(nextSection, section))
			{
				bool wasInHeading = InSectionHead;
				int lastParaIndex = section.HeadingOA.ParagraphsOS.Count - 1;
				MergeHeadingWithFollowingSection(helper, book, section, iSection);
				// Now we have to re-establish a selection
				if (wasInHeading && fDeleteForward)
				{
					// delete key was pressed at end of section head, place IP at
					// end of what was the original heading
					section = book.SectionsOS[iSection];
					StTxtPara lastPara =
						(StTxtPara)section.HeadingOA.ParagraphsOS[lastParaIndex];
					SetInsertionPoint((int)ScrSection.ScrSectionTags.kflidHeading,
						BookFilter.GetBookIndex(book.Hvo), iSection, lastParaIndex);
					CurrentSelection.IchAnchor = lastPara.Contents.Length;
					CurrentSelection.SetSelection(true);
				}
				else
				{
					// delete key was pressed in empty section content, place IP
					// at beginning of what was following section heading
					SetInsertionPoint((int)ScrSection.ScrSectionTags.kflidHeading,
						BookFilter.GetBookIndex(book.Hvo), iSection, lastParaIndex + 1);
				}
				return true;
			}
			return false;
		}
Beispiel #20
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);
		}
Beispiel #21
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Deletes a section heading.
		/// </summary>
		/// <param name="helper">Selection information</param>
		/// <param name="allowHeadingText">if <code>true</code> section head will be deleted
		/// even if heading contains text</param>
		/// <param name="positionAtEnd">if <code>true</code> IP will be at end of paragraph
		/// before top point of current selection</param>
		/// <returns><code>true</code> if deletion was done</returns>
		/// ------------------------------------------------------------------------------------
		private bool DeleteSectionHead(SelectionHelper helper, bool allowHeadingText,
			bool positionAtEnd)
		{
			ILocationTracker tracker = ((ITeView)Control).LocationTracker;
			if (helper.GetNumberOfLevels(SelectionHelper.SelLimitType.Top) !=
				tracker.GetLevelCount((int)ScrSection.ScrSectionTags.kflidContent))
				return false;
			int tag = helper.GetTextPropId(SelectionHelper.SelLimitType.Top);
			if (tag != (int)StTxtPara.StTxtParaTags.kflidContents &&
				tag != SimpleRootSite.kTagUserPrompt)
			{
				// Currently this is the only possible leaf property in draft view;
				// if this changes somehow, we'll probably need to enhance this code.
				Debug.Assert(false);
				return false;
			}
			int hvoBook = tracker.GetBookHvo(helper, SelectionHelper.SelLimitType.Top);
			if (hvoBook < 0)
			{
				Debug.Assert(false);
				return false;
			}
			ScrBook book = new ScrBook(m_cache, hvoBook);

			int iSection = tracker.GetSectionIndexInBook(helper, SelectionHelper.SelLimitType.Top);
			if (iSection < 0)
			{
				// Something changed catastrophically. Book has something in it other than sections.
				Debug.Assert(false);
				return false;
			}
			IScrSection section = book.SectionsOS[iSection];

			if (helper.GetLevelInfo(SelectionHelper.SelLimitType.Top)[0].tag !=
				(int)StText.StTextTags.kflidParagraphs)
			{
				// Something changed catastrophically. StText has something in it other than paragraphs!
				Debug.Assert(false);
				return false;
			}
			// For now we just handle the heading.
			if (helper.GetLevelInfo(SelectionHelper.SelLimitType.Top)[1].tag !=
				(int)ScrSection.ScrSectionTags.kflidHeading)
			{
				// Add code here if desired to handle bsp/del at boundary of body.
				return false;
			}

			// OK, we're dealing with a change at the boundary of a section heading
			// (in a paragraph of an StText that is the heading of an ScrSection in an ScrBook).
			IStText text = section.HeadingOA;
			int ihvoPara = helper.GetLevelInfo(SelectionHelper.SelLimitType.Top)[0].ihvo;
			IStTxtPara para = (IStTxtPara)(text.ParagraphsOS[ihvoPara]);

			if (!allowHeadingText && para.Contents.Length > 0)
			{
				// The current heading paragraph has something in it!
				// For now we won't try to handle this.
				// (The problem is knowing what to do with the undeleted header text...
				// make it part of the previous section? The previous header? Delete it?)
				return false;
			}
			if (text.ParagraphsOS.Count != 1)
			{
				// Backspace at start or delete at end of non-empty section, and the paragraph is
				// empty. Do nothing.
				return false;

				// Other options:
				// - delete the section? But what do we do with the rest of its heading?
				// - delete the empty paragraph? That's easy...just
				//		text.ParagraphsOS.RemoveAt(ihvoPara);
				// But where do we put the IP afterwards? At the end of the previous body,
				// for bsp, or the start of our own body, for del? Or keep it in the heading?
			}
			// OK, we're in a completely empty section heading.
			// If it's the very first section of the book, we can't join it to the previous
			// section, so do nothing. (May eventually enhance to join the two books...
			// perhaps after asking for confirmation!)
			if (iSection == 0)
				return false;
			// Finally...we know we're going to merge the two sections.
			MergeContentWithPreviousSection(helper, book, section, iSection, positionAtEnd);
			return true;
		}
Beispiel #22
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Inserts one or more paragraphs at the end of a section.  New sections for the book
		/// may also be created.
		/// </summary>
		/// <param name="book"></param>
		/// <param name="section"></param>
		/// <param name="ttpSrcArray">Array of props of each para to be inserted</param>
		/// <param name="tssParas">Array of TsStrings for each para to be inserted</param>
		/// <param name="sectionIndex"></param>
		/// <param name="cAddedSections"></param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		private bool InsertParagraphsAtSectionEnd(ScrBook book, IScrSection section,
			ITsTextProps[] ttpSrcArray, ITsString[] tssParas, int sectionIndex, out int cAddedSections)
		{
			cAddedSections = 0;
			bool isIntro = false;

			for (int i = 0; i < ttpSrcArray.Length; i++)
			{
				IStStyle style = m_scr.FindStyle(ttpSrcArray[i]);
				if (style.Structure == StructureValues.Heading)
				{
					// If content has been added to section, create a new section.  Otherwise,
					// add the new paragraph to the end of the current section heading.
					if (section.ContentOA.ParagraphsOS.Count > 0)
					{
						isIntro = (style.Context == ContextValues.Intro);
						// Create a new section and add the current paragraph to the heading
						section = ScrSection.CreateEmptySection(book,
							sectionIndex + cAddedSections);
						CreateParagraph(section.HeadingOA, -1, ttpSrcArray[i], tssParas[i]);
						// Need additional prop changed event to get screen to refresh properly
						m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, book.Hvo,
							(int)ScrBook.ScrBookTags.kflidSections,
							sectionIndex + cAddedSections, 1, 0);
						cAddedSections++;
					}
					else
					{
						// Create heading paragraph at end of section heading
						CreateParagraph(section.HeadingOA, -1, ttpSrcArray[i], tssParas[i]);
					}
				}
				else
				{
					// Create content paragraph for the current section
					CreateParagraph(section.ContentOA, -1, ttpSrcArray[i], tssParas[i]);
				}
			}

			// create an empty paragraph if section content is empty
			if (section.ContentOA.ParagraphsOS.Count == 0)
			{
				string styleName =
					isIntro ? ScrStyleNames.IntroParagraph : ScrStyleNames.NormalParagraph;
				StTxtParaBldr bldr = new StTxtParaBldr(m_cache);
				bldr.ParaProps = StyleUtils.ParaStyleTextProps(styleName);
				ITsTextProps charProps = StyleUtils.CharStyleTextProps(styleName,
					m_cache.DefaultVernWs);
				bldr.AppendRun(string.Empty, charProps);
				bldr.CreateParagraph(section.ContentOAHvo);
			}

			return true;
		}
Beispiel #23
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Merges heading of given section into the heading of the follwing section and then
		/// deletes the given section. We assume that the content of the current section is
		/// empty.
		/// </summary>
		/// <param name="helper"> </param>
		/// <param name="book"></param>
		/// <param name="section"></param>
		/// <param name="ihvoSection"></param>
		/// ------------------------------------------------------------------------------------
		private void MergeHeadingWithFollowingSection(SelectionHelper helper, ScrBook book,
			IScrSection section, int ihvoSection)
		{
			// Get the following section and move the paragraphs.
			IScrSection sectionNext = book.SectionsOS[ihvoSection + 1];
			IStText textNext = sectionNext.HeadingOA;
			if (textNext == null)
			{
				// Prevent crash when dealing with corrupt database (TE-4869)
				// Since the next section doesn't have a heading text, we simply move the entire
				// text object from the current section head to the next section.
				m_cache.ChangeOwner(section.HeadingOAHvo, sectionNext.Hvo,
					(int)ScrSection.ScrSectionTags.kflidHeading);
			}
			else
			{
				IStText textOldHeading = section.HeadingOA;
				int cOldHeadingParas = textOldHeading.ParagraphsOS.Count;
				m_cache.MoveOwningSequence(textOldHeading.Hvo, (int)StText.StTextTags.kflidParagraphs,
					0, cOldHeadingParas - 1,
					textNext.Hvo, (int)StText.StTextTags.kflidParagraphs, 0);
			}
			// protected for some reason...textNext.ParagraphsOS.Append(text.ParagraphsOS.HvoArray);
			book.SectionsOS.RemoveAt(ihvoSection);
		}
Beispiel #24
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Insert a new section at the given position. The new section will include an empty
		/// paragraph.
		/// </summary>
		/// <param name="book"></param>
		/// <param name="iSection"></param>
		/// <param name="isIntroSection"></param>
		/// ------------------------------------------------------------------------------------
		protected internal IScrSection InsertSectionAtIndex(ScrBook book, int iSection,
			bool isIntroSection)
		{
			if (m_cache == null)
				return null;

			return ScrSection.CreateSectionWithEmptyParas(book, iSection, isIntroSection);
		}
Beispiel #25
0
		public void MergeBTsWhenParasMerge_FirstParaHasNoBt_DelKey()
		{
			CheckDisposed();

			ShowForm(Lng.English, DummyBasicViewVc.DisplayType.kNormal);

			IVwRootBox rootBox = m_basicView.RootBox;

			// Add a second paragraph to the first text and create a Back Translations on
			// only the second paragraph
			ScrBook book = new ScrBook(Cache, m_hvoRoot);
			StText text1 = (StText)book.FootnotesOS[0];
			StTxtPara para1 = (StTxtPara)text1.ParagraphsOS[0];
			StTxtPara para2 = m_scrInMemoryCache.AddParaToMockedText(text1.Hvo, string.Empty);
			m_scrInMemoryCache.AddRunToMockedPara(para2, DummyBasicView.kSecondParaEng, m_wsEng);
			// We'll just re-use our "vernacular" WS for the back translation, for testing purposes.
			ICmTranslation trans2 = m_inMemoryCache.AddBtToMockedParagraph(para2, m_wsEng);
			m_inMemoryCache.AddRunToMockedTrans(trans2, m_wsEng, "BT2", null);

			Cache.PropChanged(null, PropChangeType.kpctNotifyAll, text1.Hvo,
				(int)StText.StTextTags.kflidParagraphs, 1, 1, 0);

			// Make a selection from the end of first paragraph to the beginning of the second.
			SelLevInfo[] levelInfo = new SelLevInfo[2];
			levelInfo[1].tag = m_flidContainingTexts;
			levelInfo[1].cpropPrevious = 0;
			levelInfo[1].ihvo = 0;
			levelInfo[0].tag = (int)StText.StTextTags.kflidParagraphs;
			levelInfo[0].cpropPrevious = 0;
			levelInfo[0].ihvo = 0;
			int ich = DummyBasicView.kFirstParaEng.Length;
			rootBox.MakeTextSelection(0, 2, levelInfo,
				(int)StTxtPara.StTxtParaTags.kflidContents, 0, ich, 0, 0, true, 1, null,
				true);
			TypeDelete();

			Assert.AreEqual(DummyBasicView.kFirstParaEng + DummyBasicView.kSecondParaEng,
				para1.Contents.Text);
			IEnumerator<ICmTranslation> translations = para1.TranslationsOC.GetEnumerator();
			translations.MoveNext();
			ICmTranslation transl = translations.Current;
			Assert.AreEqual("BT2", transl.Translation.GetAlternative(m_wsEng).Text);
		}
Beispiel #26
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Merges the paras in table.
		/// </summary>
		/// <param name="helper">The helper.</param>
		/// <param name="dpt">The problem deletion type.</param>
		/// <returns><c>true</c> if we merged the paras, otherwise <c>false</c>.</returns>
		/// ------------------------------------------------------------------------------------
		internal protected bool MergeParasInTable(SelectionHelper helper, VwDelProbType dpt)
		{
			SelLevInfo[] levInfo = helper.GetLevelInfo(SelectionHelper.SelLimitType.Top);
			if (levInfo[0].tag != (int)StText.StTextTags.kflidParagraphs)
				return false;

			ILocationTracker tracker = ((ITeView)Control).LocationTracker;
			IScrBook book = new ScrBook(m_cache, tracker.GetBookHvo(
				helper, SelectionHelper.SelLimitType.Anchor));

			SelLevInfo tmpInfo;
			IStText text;
			if (helper.GetLevelInfoForTag((int)ScrBook.ScrBookTags.kflidTitle, out tmpInfo))
				text = book.TitleOA;
			else
			{
				IScrSection section = book.SectionsOS[tracker.GetSectionIndexInBook(
					helper,	SelectionHelper.SelLimitType.Anchor)];

				text = (levInfo[1].tag == (int)ScrSection.ScrSectionTags.kflidHeading ?
					section.HeadingOA :	text = section.ContentOA);
			}

			int iPara = helper.GetLevelInfoForTag((int)StText.StTextTags.kflidParagraphs).ihvo;
			StTxtPara currPara = (StTxtPara)text.ParagraphsOS[iPara];
			ITsStrBldr bldr;

			// Backspace at beginning of paragraph
			if (dpt == VwDelProbType.kdptBsAtStartPara)
			{
				if (iPara <= 0)
				{
					MiscUtils.ErrorBeep();
					return false;
				}

				StTxtPara prevPara = (StTxtPara)text.ParagraphsOS[iPara - 1];
				int prevParaLen = prevPara.Contents.Length;

				// Need to make sure we move the back translations
				AboutToDelete(helper, currPara.Hvo, text.Hvo,
					(int)StText.StTextTags.kflidParagraphs, iPara, false);

				bldr = prevPara.Contents.UnderlyingTsString.GetBldr();
				bldr.ReplaceTsString(prevPara.Contents.Length, prevPara.Contents.Length,
					currPara.Contents.UnderlyingTsString);
				prevPara.Contents.UnderlyingTsString = bldr.GetString();
				text.ParagraphsOS.RemoveAt(iPara);
				helper.SetIch(SelectionHelper.SelLimitType.Top, prevParaLen);
				helper.SetIch(SelectionHelper.SelLimitType.Bottom, prevParaLen);
				levInfo[0].ihvo = iPara - 1;
				helper.SetLevelInfo(SelectionHelper.SelLimitType.Top, levInfo);
				helper.SetLevelInfo(SelectionHelper.SelLimitType.Bottom, levInfo);
				helper.SetSelection(true);
				return true;
			}
			// delete at end of a paragraph
			int cParas = text.ParagraphsOS.Count;
			if (iPara + 1 >= cParas)
				return false; // We don't handle merging across StTexts

			StTxtPara nextPara = (StTxtPara)text.ParagraphsOS[iPara + 1];

			// Need to make sure we move the back translations
			AboutToDelete(helper, nextPara.Hvo, text.Hvo,
				(int)StText.StTextTags.kflidParagraphs, iPara + 1, false);

			bldr = currPara.Contents.UnderlyingTsString.GetBldr();
			bldr.ReplaceTsString(currPara.Contents.Length, currPara.Contents.Length,
				nextPara.Contents.UnderlyingTsString);
			currPara.Contents.UnderlyingTsString = bldr.GetString();
			text.ParagraphsOS.RemoveAt(iPara + 1);
			helper.SetSelection(true);
			return true;
		}
Beispiel #27
0
		public void AdjustAnnotationReferences_ParaInArchive()
		{
			IScrBook genesis = m_scrInMemoryCache.AddBookToMockedScripture(1, "Genesis");
			StText titleText = m_scrInMemoryCache.AddTitleToMockedBook(genesis.Hvo, "Genesis");
			IStPara titlePara = titleText.ParagraphsOS[0];

			// Introduction section
			IScrSection section = m_scrInMemoryCache.AddSectionToMockedBook(genesis.Hvo);
			m_scrInMemoryCache.AddSectionHeadParaToSection(section.Hvo, "Introduction head", ScrStyleNames.IntroSectionHead);
			StTxtPara para = m_scrInMemoryCache.AddParaToMockedSectionContent(section.Hvo, ScrStyleNames.IntroParagraph);
			m_scrInMemoryCache.AddRunToMockedPara(para, "An intro to Genesis", null);
			section.AdjustReferences(true);

			IScrDraft version = new ScrDraft();
			m_scr.ArchivedDraftsOC.Add(version);
			int hvoSavedVersion = m_scr.AddBookToSavedVersion(version, genesis.Hvo);
			IScrBook genesisSaved = new ScrBook(m_scrInMemoryCache.Cache, hvoSavedVersion);
			IStPara paraSaved = genesisSaved.SectionsOS[0].ContentOA.ParagraphsOS[0];

			ScrBookAnnotations annotations = (ScrBookAnnotations)m_scr.BookAnnotationsOS[0];
			BCVRef ref1 = new BCVRef(1, 1, 0);
			IScrScriptureNote note = annotations.InsertNote(ref1, ref1, paraSaved, paraSaved, LangProject.kguidAnnConsultantNote);
			Assert.IsNotNull(note);

			m_scr.AdjustAnnotationReferences();

			Assert.AreEqual(para.Hvo, note.BeginObjectRA.Hvo);
		}
Beispiel #28
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Determines if the selection is an entire book
		/// </summary>
		/// <param name="helper"></param>
		/// <param name="topInfo"></param>
		/// <param name="bottomInfo"></param>
		/// <returns></returns>
		/// ------------------------------------------------------------------------------------
		private bool IsBookSelection (SelectionHelper helper, SelLevInfo[] topInfo,
			SelLevInfo[] bottomInfo)
		{
			ILocationTracker tracker = ((ITeView)Control).LocationTracker;
			int bookTitleLevelCount = tracker.GetLevelCount((int)ScrBook.ScrBookTags.kflidTitle);
			if (topInfo.Length == bookTitleLevelCount && bottomInfo.Length == bookTitleLevelCount)
			{
				// Verify that selection goes from beginning of book title to
				// beginning of title in next book.
				return (tracker.GetBookIndex(helper, SelectionHelper.SelLimitType.Top) ==
					tracker.GetBookIndex(helper, SelectionHelper.SelLimitType.Bottom) - 1 &&
					topInfo[1].tag == (int)ScrBook.ScrBookTags.kflidTitle &&
					topInfo[1].ihvo == 0 &&
					topInfo[0].tag == (int)StText.StTextTags.kflidParagraphs &&
					topInfo[0].ihvo == 0 &&
					bottomInfo[1].tag == (int)ScrBook.ScrBookTags.kflidTitle &&
					bottomInfo[1].ihvo == 0 &&
					bottomInfo[0].tag == (int)StText.StTextTags.kflidParagraphs &&
					bottomInfo[0].ihvo == 0 &&
					helper.IchAnchor == 0 &&
					helper.IchEnd == 0);
			}
			else if (topInfo.Length == bookTitleLevelCount && bottomInfo.Length ==
				tracker.GetLevelCount((int)ScrSection.ScrSectionTags.kflidContent))
			{
				// Check that selection is at start of title
				bool bookSel = (tracker.GetBookIndex(helper, SelectionHelper.SelLimitType.Top) ==
					tracker.GetBookIndex(helper, SelectionHelper.SelLimitType.Bottom) &&
					topInfo[1].tag == (int)ScrBook.ScrBookTags.kflidTitle &&
					topInfo[1].ihvo == 0 &&
					topInfo[0].tag == (int)StText.StTextTags.kflidParagraphs &&
					topInfo[0].ihvo == 0 &&
					helper.GetIch(SelectionHelper.SelLimitType.Top) == 0);

				if (bookSel)
				{
					// Get information about last paragraph of the book
					ScrBook book = new ScrBook(m_cache,
						tracker.GetBookHvo(helper, SelectionHelper.SelLimitType.Top));
					int iSection = book.SectionsOS.Count - 1;
					IScrSection section = book.SectionsOS[iSection];
					int iPara = section.ContentOA.ParagraphsOS.Count - 1;
					StTxtPara para = (StTxtPara) section.ContentOA.ParagraphsOS[iPara];
					int ichEnd = para.Contents.Length;

					// Check that selection is at end of last paragraph of book
					bookSel = (tracker.GetSectionIndexInBook(helper,
						SelectionHelper.SelLimitType.Bottom) == iSection &&
						bottomInfo[1].tag == (int)ScrSection.ScrSectionTags.kflidContent &&
						bottomInfo[0].ihvo == iPara &&
						bottomInfo[0].tag == (int)StText.StTextTags.kflidParagraphs &&
						helper.GetIch(SelectionHelper.SelLimitType.Bottom) == ichEnd);
				}

				return bookSel;
			}
			return false;
		}
Beispiel #29
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Handles deletion of empty section heading paragraph on delete key being pressed at
		/// text boundary.
		/// </summary>
		/// <param name="helper"></param>
		/// <returns><c>true</c> if we handled the deletion, otherwise <c>false</c></returns>
		/// ------------------------------------------------------------------------------------
		private bool HandleDeleteBeforeEmptySectionHeadParagraph(SelectionHelper helper)
		{
			SelLevInfo[] levInfo = helper.GetLevelInfo(SelectionHelper.SelLimitType.Top);
			ScrBook book = new ScrBook(m_cache, ((ITeView)Control).LocationTracker.GetBookHvo(
				helper, SelectionHelper.SelLimitType.Top));

			// Delete problem deletion will be at end of last paragraph of content,
			// need to check following section head (if available)

			// Get next section of book.
			int iSection = ((ITeView)Control).LocationTracker.GetSectionIndexInBook(
				helper, SelectionHelper.SelLimitType.Top);

			bool positionAtEnd = false;
			if (!InSectionHead)
			{
				iSection++;
				if (iSection > book.SectionsOS.Count - 1)
					return false;
				positionAtEnd = true;
			}
			else if (iSection == 0)
				return false;

			IScrSection section = book.SectionsOS[iSection];

			if (section.HeadingOA == null || section.HeadingOA.ParagraphsOS.Count == 0)
			{
				// don't crash if database is corrupt - allow user to merge the two
				// sections (TE-4869)
				return MergeWithPreviousSectionIfInSameContext(helper, book,
					section, iSection, positionAtEnd);
			}
			else
			{
				// if there are more than one paragraph in heading, check to see if first
				// paragraph can be deleted.
				if (section.HeadingOA.ParagraphsOS.Count > 1)
				{
					StTxtPara para = (StTxtPara)section.HeadingOA.ParagraphsOS[0];
					if (para.Contents.Length == 0)
					{
						section.HeadingOA.ParagraphsOS.RemoveAt(0);
						return true;
					}
				}
				// If we are at end of content before an empty section head,
				// we should merge sections.
				else
				{
					StTxtPara para = (StTxtPara)section.HeadingOA.ParagraphsOS[0];
					if (para.Contents.Length == 0)
					{
						return MergeWithPreviousSectionIfInSameContext(helper, book,
							section, iSection, positionAtEnd);
					}
				}
			}

			return false;
		}
Beispiel #30
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Finds the previous footnote and returns it.
		/// </summary>
		/// <param name="para">Paragraph to start search</param>
		/// <param name="ich">Character index to start search, or -1 to start at the end of
		/// the paragraph.</param>
		/// <returns>Previous footnote, or <c>null</c> if there isn't a previous footnote in the
		/// current book.</returns>
		/// ------------------------------------------------------------------------------------
		public static ScrFootnote FindPreviousFootnote(IStTxtPara para, int ich)
		{
			FdoCache cache = para.Cache;
			IScrBook book;
			IStText text = new StText(cache, para.OwnerHVO);
			int iPara = Array.IndexOf(text.ParagraphsOS.HvoArray, para.Hvo);
			int flid = text.OwningFlid;
			if (flid == (int)ScrSection.ScrSectionTags.kflidHeading ||
				flid == (int)ScrSection.ScrSectionTags.kflidContent)
			{
				ScrSection section = new ScrSection(cache, text.OwnerHVO);
				int iSection = section.IndexInBook;
				return ScrFootnote.FindPreviousFootnote(cache, section.OwningBook,
					ref iSection, ref iPara, ref ich, ref flid);
			}
			else if (flid == (int)ScrBook.ScrBookTags.kflidTitle)
			{
				book = new ScrBook(cache, text.OwnerHVO);
				return ScrFootnote.FindPreviousFootnoteInText(text, ref iPara,
					ref ich, false);
			}
			else
				throw new Exception("Can only create footnotes in Scripture Book titles, section heads, and contents");
		}