private void EnsureSyncText() { if (m_selHelper != null && m_selHelper.Selection != null && m_selHelper.Selection.RootBox != null) { TextSelInfo tsi = new TextSelInfo(m_selHelper.Selection); m_selHelper.RootSite.RootBox.PropChanged(tsi.HvoAnchor, tsi.TagAnchor, 0, 0, 0); if (tsi.Hvo(false) != tsi.Hvo(true)) { m_selHelper.RootSite.RootBox.PropChanged(tsi.Hvo(true), tsi.Tag(true), 0, 0, 0); } } }
private void EnsureSyncText() { if (m_selHelper != null && m_selHelper.Selection != null && m_selHelper.Selection.RootBox != null) { TextSelInfo tsi = new TextSelInfo(m_selHelper.Selection); m_selHelper.RootSite.RootBox.PropChanged(tsi.HvoAnchor, tsi.TagAnchor, 0, 0, 0); if (tsi.Hvo(false) != tsi.Hvo(true)) m_selHelper.RootSite.RootBox.PropChanged(tsi.Hvo(true), tsi.Tag(true), 0, 0, 0); } }
/// <summary> /// If the key is Enter, and the selection is in the contents of an StTxtPara, save information we will need /// to adjust things after the keypress executes. /// </summary> public void StartKeyPressed(KeyPressEventArgs e, Keys modifiers) { if (m_segDefn_note == 0) //|| !m_parentEditingHelper.Editable return; // in-memory testing or we can't edit the view anyways m_tsiOrig = new TextSelInfo(m_parentEditingHelper.EditedRootBox); // Enhance JohnT: maybe there is something useful we could do if the other end of the selection isn't in the // same text, but it's not enough to just get the objects after the end; that produces a crash. // A temporary patch is to not attempt this adjustment at all in this case. See TE-8416. // This means segmented BT is lost on the trailing part of the paragraph when Enter is used // to replace a range, also some precision is lost on scripture notes on that segment. See TE-8419. // It should be fixed in the re-architecture, where the delete is handled as a separate UOW. if (e.KeyChar == '\r' && (modifiers & Keys.Shift) == 0 && m_tsiOrig.Selection != null && m_tsiOrig.Tag(true) == kflidContents && m_tsiOrig.Tag(false) == kflidContents && m_cache.GetOwnerOfObject(m_tsiOrig.Hvo(false)) == m_cache.GetOwnerOfObject(m_tsiOrig.Hvo(true))) { // collect annotations that come after the selection, so we can move those into the new paragraph. if (m_tsiOrig.Selection.EndBeforeAnchor) { // The 'end' of the selection (the boundary after which stuff will be moved) // is really the anchor. m_hvoParaSelEnd = m_tsiOrig.Hvo(false); m_ichSelEnd = m_tsiOrig.IchAnchor; m_hvoStText = m_tsiOrig.ContainingObject(1, false); } else { m_hvoParaSelEnd = m_tsiOrig.Hvo(true); m_ichSelEnd = m_tsiOrig.IchEnd; m_hvoStText = m_tsiOrig.ContainingObject(1, true); } m_ihvoParaPrev = m_cache.GetObjIndex(m_hvoStText, kflidParagraphs, m_hvoParaSelEnd); string sql = String.Format("select cba.BeginObject, cba.Id, cba.AnnotationType, cba.BeginOffset, cba.EndOffset from CmBaseAnnotation_ cba " + "where cba.BeginObject = {0} and " + "cba.BeginOffset >= {1} " + "order by cba.BeginOffset, cba.EndOffset", new object[] { m_hvoParaSelEnd, m_ichSelEnd }); m_cbaHvosAffectedByEdit = GetCbasPotentiallyAffectedByTextEdit(m_cache, m_hvoParaSelEnd, sql); // we will need to subtract the difference from the selection's end. m_cchAdjust = -m_ichSelEnd; m_parasWeHaveAdjusted.Add(m_hvoParaSelEnd); } else { m_hvoStText = 0; // this functionality does not apply. } if (m_cbaHvosAffectedByEdit != null) m_movedAnnsFromAfterInsertBreak.AddRange(m_cbaHvosAffectedByEdit); }
/// <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; }
internal string BuildCurrentMorphsString(IVwSelection sel) { CheckDisposed(); int ichSel = -1; int hvoObj = 0; int tag = 0; m_needDelayedSelection = false; if (sel != null) { TextSelInfo selInfo = new TextSelInfo(sel); // Receiving data from TSF on Windows creates a range covering the inserted character instead // of an insertion point following the inserted character. Anchor marks the beginning of that // range and End marks the end of the range. We want an insertion point at the end. ichSel = selInfo.IchEnd; hvoObj = selInfo.Hvo(true); tag = selInfo.Tag(true); if (Environment.OSVersion.Platform == PlatformID.Win32NT && ichSel != selInfo.IchAnchor) { // TSF also replaces our carefully created selection, adjusted carefully to follow the // inserted character, with one of its own choosing after we return, so flag that we'll // need to recreate the desired selection at idle time when TSF has quit interfering. m_needDelayedSelection = true; } } // for now, we'll just configure getting the string for the primary morpheme line. int ws = this.VernWsForPrimaryMorphemeLine; m_ichSel = -1; ITsStrBldr builder = TsStrBldrClass.Create(); ITsString space = TsStringUtils.MakeTss(" ", ws); ISilDataAccess sda = m_sandbox.Caches.DataAccess; ITsString tssWordform = m_sandbox.SbWordForm(ws); // we're dealing with a phrase if there are spaces in the word. bool fBaseWordIsPhrase = SandboxBase.IsPhrase(tssWordform.Text); int cmorphs = m_sda.get_VecSize(m_hvoSbWord, SandboxBase.ktagSbWordMorphs); for (int imorph = 0; imorph < cmorphs; ++imorph) { int hvoMorph = m_sda.get_VecItem(m_hvoSbWord, SandboxBase.ktagSbWordMorphs, imorph); if (imorph != 0) { builder.ReplaceTsString(builder.Length, builder.Length, space); // add a second space to separate morphs in a phrase. if (fBaseWordIsPhrase) builder.ReplaceTsString(builder.Length, builder.Length, space); } int hvoMorphForm = sda.get_ObjectProp(hvoMorph, SandboxBase.ktagSbMorphForm); if (hvoMorph == hvoObj && tag == SandboxBase.ktagSbMorphPrefix) m_ichSel = builder.Length + ichSel; builder.ReplaceTsString(builder.Length, builder.Length, sda.get_StringProp(hvoMorph, SandboxBase.ktagSbMorphPrefix)); if (hvoMorphForm == hvoObj && tag == SandboxBase.ktagSbNamedObjName) m_ichSel = builder.Length + ichSel; builder.ReplaceTsString(builder.Length, builder.Length, sda.get_MultiStringAlt(hvoMorphForm, SandboxBase.ktagSbNamedObjName, ws)); if (hvoMorph == hvoObj && tag == SandboxBase.ktagSbMorphPostfix) m_ichSel = builder.Length + ichSel; builder.ReplaceTsString(builder.Length, builder.Length, sda.get_StringProp(hvoMorph, SandboxBase.ktagSbMorphPostfix)); } if (cmorphs == 0) { if (m_hvoSbWord == hvoObj && tag == SandboxBase.ktagMissingMorphs) m_ichSel = ichSel; m_morphString = SandboxBase.InterlinComboHandler.StrFromTss(tssWordform); } else { m_morphString = SandboxBase.InterlinComboHandler.StrFromTss(builder.GetString()); } return m_morphString; }