/// <summary>
		/// If the paragraph sequence for the text has changed, reparse it completely
		/// and issue PropChanges for any changed segment sequences. Return true if it
		/// was dealt with (including if it has been deleted).
		/// </summary>
		/// <returns></returns>
		public bool HandleMajorTextChange(int btWs)
		{
			if (!m_stText.IsValidObject())
				return true;
			if (ParaSequenceChanged())
			{
				bool fDidParse;
				ParagraphParserOptions options = new ParagraphParserOptions();
				options.SuppressSubTasks = false; // this is part of an edit, for it to be undoable the side effects need to be
				options.CreateRealSegments = true; // we will attach free translations, which requires them to be real.
				ParagraphParser.ParseText(m_stText, options, new NullProgressState(), out fDidParse);
				StTxtPara.LoadSegmentFreeTranslations(m_stText.ParagraphsOS.HvoArray, m_stText.Cache, btWs);
				Set<int> oldParas = new Set<int>(m_paras.Count);
				foreach (ParaStateInfo info in m_paras)
				{
					info.HandleSegPropChanged(m_stText.Cache);
					oldParas.Add(info.HvoPara);
				}
				int kflidSegments = StTxtPara.SegmentsFlid(m_stText.Cache);
				if (m_fCheckOtherParasOfText)
				{
					foreach (int hvoPara in m_stText.ParagraphsOS.HvoArray)
					{
						if (!oldParas.Contains(hvoPara))
						{
							// A new paragraph. Possibly some segments got created for it after it was
							// displayed.
							int cseg = m_stText.Cache.GetVectorSize(hvoPara, kflidSegments);
							if (cseg > 0)
								m_stText.Cache.PropChanged(hvoPara, kflidSegments, 0, cseg, 0);
						}
					}
				}
				return true;
			}
			return false;
		}
		/// <summary>
		/// We suspect there has been a significant change to the segments of the selected paragraph.
		/// Reparse it and issue a PropChanged if needed.
		/// </summary>
		/// <param name="btWs"></param>
		public void HandleMajorParaChange(int btWs)
		{
			ParagraphParserOptions options = new ParagraphParserOptions();
			options.SuppressSubTasks = false; // this is part of some undoable task, the side effects need to be undoable, too.
			// This is surprisingly important. If LoadSegmentFreeTranslations has to convert dummy segments to real,
			// it issues PropChanged calls; but when new segments are being added, this method gets called before the Views
			// code has been informed of the extra ones. We may end up replacing ones it doesn't know are there, resulting
			// in fall-back behavior that produces strange results when we later send the PropChanged from the old segment
			// list to the new one. It's also more efficient, since we're going to want real segments, to make them right away.
			options.CreateRealSegments = true;
			ParagraphParser.ParseParagraph(CmObject.CreateFromDBObject(m_stText.Cache, m_hvoPara, false) as StTxtPara, options);
			StTxtPara.LoadSegmentFreeTranslations(new int[] {m_hvoPara}, m_stText.Cache, btWs);
			foreach (ParaStateInfo info in m_paras)
				if (info.HvoPara == m_hvoPara)
				{
					info.HandleSegPropChanged(m_stText.Cache);
					return;
				}
		}
Beispiel #3
0
		private static void ParseTextCore(IStText text, ParagraphParserOptions options, ProgressState progress)
		{
			using (ParagraphParser pp = new ParagraphParser(text.Cache))
			{
				pp.SetOptions(options);
				if (options.ResetConcordance)
					(text.Cache.LangProject.WordformInventoryOA as WordformInventory).ResetAllWordformOccurrences();
				if (text.LastParsedTimestamp != 0)
				{
					// We actually have parsed before...yet we have to again. Possibly another program changed
					// the data. Reload it as efficiently as possible.
					string sql = "select Id, UpdStmp, Contents, Contents_Fmt from StTxtPara_ where Owner$ = " + text.Hvo + " order by OwnOrd$";
					IDbColSpec dcs = DbColSpecClass.Create();
					dcs.Push((int)DbColType.koctObjVecOwn, 0, (int)StText.StTextTags.kflidParagraphs, 0);
					dcs.Push((int)DbColType.koctTimeStamp, 1, 0, 0);
					dcs.Push((int)DbColType.koctString, 1, (int)StTxtPara.StTxtParaTags.kflidContents, 0);
					dcs.Push((int)DbColType.koctFmt, 1, (int)StTxtPara.StTxtParaTags.kflidContents, 0);
					text.Cache.VwOleDbDaAccessor.Load(sql, dcs, text.Hvo, 0, null, false);
				}
				pp.SalvageDummyAnnotations(text);
				pp.Parse(text, progress);
				text.RecordParseTimestamp();
				pp.AddEntryGuesses(progress);
				pp.CleanupLeftoverAnnotations(progress);
			}
		}
Beispiel #4
0
		private void SetOptions(ParagraphParserOptions options)
		{
			CollectWordformOccurrencesInTexts = options.CollectWordformOccurrencesInTexts;
			m_fCreateRealSegments = options.CreateRealSegments;
			CreateDummyWordforms = !options.CreateRealWordforms;
			m_fSuppressSubTasks = options.SuppressSubTasks;
			// Enhance: figure how to obey options.UseRealData;
			// options.ResetConcordance is used in the calling method to decide whether to ResetAllWordformOccurrences on the Wfi
		}
Beispiel #5
0
		/// <summary>
		/// Parse a text. Return true if successful. May fail because (a) no contents; (b) too long.
		/// Determining that the text doesn't need parsing counts as success.
		/// Todo: arrange to be able to Undo this, restoring the previous annotations.
		/// </summary>
		/// <param name="text"></param>
		/// <param name="fSuppressSubTasks">true if we don't want to be able to Undo.</param>
		/// <param name="fDidParse">True if an actual parse occurred and we need to reload.</param>
		/// <returns>True if successful</returns>
		public static bool ParseText(IStText text, bool fSuppressSubTasks, ProgressState progress, out bool fDidParse)
		{
			ParagraphParserOptions options = new ParagraphParserOptions();
			options.SuppressSubTasks = fSuppressSubTasks;
			return ParseText(text, options, progress, out fDidParse);
		}
Beispiel #6
0
		public static bool ParseText(IStText text, ParagraphParserOptions options, ProgressState progress, out bool fDidParse)
		{
			fDidParse = false;
			if (text == null || !text.IsValidObject())
				return false;
			if (text.ParagraphsOS.Count == 0)
				return false;
#if DEBUG
			//TimeRecorder.Begin("deciding whether to parse para");
#endif
			if (text.IsUpToDate())
				return true;
#if DEBUG
			//TimeRecorder.End("deciding whether to parse para");
#endif
			fDidParse = true; // we're going to parse!
#if DEBUG
			//TimeRecorder.Begin("parse text");
#endif
			if (progress is MilestoneProgressState)
			{
				MilestoneProgressState mp = progress as SIL.FieldWorks.Common.Controls.MilestoneProgressState;
				AddParseTextMilestones(mp);
			}

			// Reparsing a whole text, words may have moved from one paragraph to another.
			// Do the whole with a single ParagraphParser.
#if DEBUG
			//TimeRecorder.Begin("setup");
#endif
			ParagraphParser.ResetParseSessionDependentStaticData();
			WordformInventory wfi = (text.Cache.LangProject.WordformInventoryOA as WordformInventory);

			if (options.SuppressSubTasks)
			{
				using (SuppressSubTasks suppressor = new SuppressSubTasks(text.Cache, true))
				{
					ParseTextCore(text, options, progress);
				}
			}
			else
			{
				ParseTextCore(text, options, progress);
			}
			return true; // succeeded.
#if DEBUG
			//TimeRecorder.End("note parse times");
			//TimeRecorder.Report();
#endif
		}
Beispiel #7
0
		private void ParseWithOptionsCore(IStTxtPara para, ParagraphParserOptions options)
		{
			ParagraphParser.ResetParseSessionDependentStaticData();
			if (options.ResetConcordance)
				(Cache.LangProject.WordformInventoryOA as WordformInventory).ResetAllWordformOccurrences();
			CollectWordformOccurrencesInTexts = options.CollectWordformOccurrencesInTexts;
			CreateDummyWordforms = !options.CreateRealWordforms;
			Parse(para, options.UseRealData);
		}
Beispiel #8
0
		private void ParseWithOptions(IStTxtPara para, ParagraphParserOptions options)
		{
			m_fSuppressSubTasks = options.SuppressSubTasks;
			m_fCreateRealSegments = options.CreateRealSegments;
			if (options.SuppressSubTasks)
			{
				using (SuppressSubTasks suppressor = new SuppressSubTasks(Cache, true))
				{
					ParseWithOptionsCore(para, options);
				}
			}
			else
			{
				ParseWithOptionsCore(para, options);
			}
		}
Beispiel #9
0
		private static void ParseParagraph(IStTxtPara para, int tagSegments, int tagSegForms, ParagraphParserOptions options)
		{
			using (ParagraphParser pp = new ParagraphParser(para.Cache, tagSegments, tagSegForms))
			{
				pp.ParseWithOptions(para, options);
			}
		}
Beispiel #10
0
		/// <summary>
		/// Parse a single paragraph with the specified options.
		/// </summary>
		public static void ParseParagraph(IStTxtPara para, ParagraphParserOptions options)
		{
			ParseParagraph(para, InterlinVc.ParaSegmentTag(para.Cache), InterlinVc.SegmentFormsTag(para.Cache), options);
		}
Beispiel #11
0
		/// <summary>
		/// We override this to check that segments are properly loaded. Normally this is done by LoadDataForStText
		/// when the containing section (the smallest lazy element) is loaded, but that doesn't run when we insert a paragraph.
		/// </summary>
		protected override void InsertBtSegments(StVc vc, IVwEnv vwenv, int hvo)
		{
			int kflidSegments = StTxtPara.SegmentsFlid(Cache);
			if (!Cache.MainCacheAccessor.get_IsPropInCache(hvo, kflidSegments, (int)CellarModuleDefns.kcptReferenceSequence, 0))
			{
				StTxtPara para = CmObject.CreateFromDBObject(Cache, hvo) as StTxtPara;
				ParagraphParserOptions options = new ParagraphParserOptions();
				options.CreateRealSegments = true;
				ParagraphParser.ParseParagraph(para, options);
				StTxtPara.LoadSegmentFreeTranslations(new int[] {hvo}, Cache, BackTranslationWS);
				// This is probably redundant, AFAIK this can only happen for newly created paragraphs,
				// but it's safe and (for the same reason) rare.
				if (para.HasNoSegmentBt(BackTranslationWS))
					ConvertOldBtToNew(para);
			}
			base.InsertBtSegments(vc, vwenv, hvo);
		}