/// <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; } }
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); } }
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 }
/// <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); }
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 }
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); }
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); } }
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); } }
/// <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); }
/// <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); }