/// <summary> /// triggered in Disposing DataUpdateMonitor, or called directly by anything that calls OnAboutToModify /// or OnAboutToEdit directly when not using a DUM. /// </summary> public void OnFinishedEdit() { if (m_segDefn_note == 0) return; // in-memory testing. // in case these get called out of the preferred order, make sure we move annotations to a new // paragraph before we reparse the text here. EndKeyPressed(); if (m_cbasToDel.Count > 0) { // delete annotations that will no longer be used. DeleteCalculatedAnnotations(m_cbasToDel); m_cbasToDel.Clear(); } m_annsToMoveFromDeletedParagraph.Clear(); m_movedAnnsFromAfterInsertBreak.Clear(); m_annotationsToDelete.Clear(); bool fDidTextChange = false; if (m_anchorTextInfo != null && m_BtWs != 0) { fDidTextChange = m_anchorTextInfo.HandleMajorTextChange(m_BtWs); if (m_endpointTextInfo != null) fDidTextChange |= m_endpointTextInfo.HandleMajorTextChange(m_BtWs); if (!fDidTextChange && m_fSegSeqChanged) m_anchorTextInfo.HandleMajorParaChange(m_BtWs); } // If things changed this drastically we'd better refresh (see e.g. TE-7884, TE-7904) if (m_cache.ActionHandlerAccessor != null && m_parseOnUndoAction != null && m_parseOnUndoAction.RecordDoneState()) m_cache.ActionHandlerAccessor.AddAction(RestoreSegmentsUndoAction.CreateForRedo(m_parseOnUndoAction)); m_anchorTextInfo = null; // disable monitoring changes until we record a new relevant start state. }
/// <summary> /// Create an empty one to be stuck at the beginning of the task for Undo. Passed zero, one, or two /// TextStateInfo objects with the information about the endpoints. Info2 is always null if info1 is. /// </summary> public static RestoreSegmentsUndoAction CreateForUndo(FdoCache cache, TextStateInfo info1, TextStateInfo info2) { RestoreSegmentsUndoAction result = new RestoreSegmentsUndoAction(); result.m_cache = cache; result.m_fForRedo = false; if (info2 != null) result.m_textStateInfo = new TextStateInfo[] {info1, info2}; else if (info1 != null) result.m_textStateInfo = new TextStateInfo[] {info1}; else result.m_textStateInfo = new TextStateInfo[0]; return result; }
/// <summary> /// Set up TextStateInfo as we would for a selection entirely in the specified object, /// if it is a paragraph. Make sure to call OnFinishedEdit. /// </summary> public void OnAboutToModify(FdoCache cache, int hvoObj) { if (m_segDefn_note == 0) return; // in-memory testing. m_endpointTextInfo = null; m_anchorTextInfo = TextStateInfo.Create(cache, hvoObj); CommonInit(); }
/// <summary> /// Create one (or return null) pertaining to a single paragraph. /// Returns null if it is not an StTxtPara. /// This should be used only for edits that will definitely NOT change the sequence of paragraphs. /// </summary> static public TextStateInfo Create(FdoCache cache, int hvoObj) { CmObject obj = CmObject.CreateFromDBObject(cache, hvoObj) as CmObject; if (!(obj is StTxtPara)) return null; StText text = obj.Owner as StText; if (!(text is StText)) return null; // paranoia! TextStateInfo result = new TextStateInfo(); result.m_stText = text; result.m_hvoPara = hvoObj; result.m_paras.Add(new ParaStateInfo(obj as StTxtPara)); result.m_tssAnchorText = (obj as StTxtPara).Contents.UnderlyingTsString; result.m_fCheckOtherParasOfText = false; return result; }
/// <summary> /// Create one from the specified end of the selection. If that end is not in a /// relevant property return null. Also return null if in the same StText as /// hvoOther. /// </summary> /// <param name="info"></param> /// <param name="fEndPoint"></param> static public TextStateInfo Create(TextSelInfo info, bool fEndPoint, FdoCache cache, int hvoOther) { int offset = 0; // in the SelInfoStack if (info.Tag(fEndPoint) == kflidContents) { if (info.Levels(fEndPoint) < 2) return null; } else { // One other case we need to handle is an embedded picture, because deleting it will modify the string. if (!info.IsPicture || info.Levels(false) < 3 || info.ContainingObjectTag(1) != kflidContents) return null; offset = 1; // one more level for the picture. } int hvoStText = info.ContainingObject(1 + offset, fEndPoint); if (hvoStText == hvoOther) return null; TextStateInfo result = new TextStateInfo(); result.m_stText = CmObject.CreateFromDBObject(cache, hvoStText) as StText;; result.m_hvoPara = info.ContainingObject(offset, fEndPoint); foreach (StTxtPara para in result.m_stText.ParagraphsOS) result.m_paras.Add(new ParaStateInfo(para)); result.m_tssAnchorText = cache.GetTsStringProperty(result.m_hvoPara, kflidContents); result.m_fCheckOtherParasOfText = true; return result; }
private bool m_fSegSeqChanged; // Set true if something changes the sequence of segment objects on a paragraph. /// <summary> /// Saves some extra information for use in OnFinishedEdit. Make sure to call that, unless setting up /// a DataUpdateMonitor which will do so. /// </summary> public void OnAboutToEdit() { m_fSegSeqChanged = false; if (m_segDefn_note == 0) return; // in-memory testing. TextSelInfo info = m_parentEditingHelper.TextSelInfoBeforeEdit; m_anchorTextInfo = TextStateInfo.Create(info, false, m_cache, 0); if (m_anchorTextInfo != null) m_endpointTextInfo = TextStateInfo.Create(info, true, m_cache, m_anchorTextInfo.HvoText); else m_endpointTextInfo = null; CommonInit(); }