public GetSelectionAtPoint ( Point position, bool fInstall ) : IVwSelection | ||
position | Point | |
fInstall | bool | |
Résultat | IVwSelection |
public ICollection<SpellCorrectMenuItem> GetSuggestions(Point mousePos, SimpleRootSite rootsite, out int hvoObj, out int tag, out int wsAlt, out int wsText, out string word, out ISpellEngine dict, out bool nonSpellingError) { hvoObj = tag = wsAlt = wsText = 0; // make compiler happy for early returns word = null; dict = null; nonSpellingError = true; IVwRootBox rootb = rootsite != null ? rootsite.RootBox : null; if (rootb == null) return null; // Get a selection at the indicated point. IVwSelection sel = rootsite.GetSelectionAtPoint(mousePos, false); // Get the selected word and verify that it is a single run within a single // editable string. if (sel != null) sel = sel.GrowToWord(); if (sel == null || !sel.IsRange || sel.SelType != VwSelType.kstText || !SelectionHelper.IsEditable(sel)) return null; ITsString tss; bool fAssocPrev; int ichAnchor; sel.TextSelInfo(false, out tss, out ichAnchor, out fAssocPrev, out hvoObj, out tag, out wsAlt); int ichEnd, hvoObjE, tagE, wsE; sel.TextSelInfo(true, out tss, out ichEnd, out fAssocPrev, out hvoObjE, out tagE, out wsE); if (hvoObj != hvoObjE || tag != tagE || wsAlt != wsE) return null; int ichMin = Math.Min(ichEnd, ichAnchor); int ichLim = Math.Max(ichEnd, ichAnchor); ILgWritingSystemFactory wsf = rootsite.RootBox.DataAccess.WritingSystemFactory; // May need to enlarge the word beyond what GrowToWord does, if there is adjacent wordforming material. int ichMinAdjust = AdjustWordBoundary(wsf, tss, ichMin, -1, 0) + 1; // further expanded start of word. int ichLimAdjust = AdjustWordBoundary(wsf, tss, ichLim - 1, 1, tss.Length); // further expanded lim of word. // From the ends we can strip stuff with different spell-checking properties. IVwStylesheet styles = rootsite.RootBox.Stylesheet; int spellProps = SpellCheckProps(tss, ichMin, styles); while (ichMinAdjust < ichMin && SpellCheckProps(tss, ichMinAdjust, styles) != spellProps) ichMinAdjust++; while (ichLimAdjust > ichLim && SpellCheckProps(tss, ichLimAdjust - 1, styles) != spellProps) ichLimAdjust--; ichMin = ichMinAdjust; ichLim = ichLimAdjust; ITsStrFactory tsf = TsStrFactoryClass.Create(); // Now we have the specific range we will check. Get the actual string. ITsStrBldr bldr = tss.GetBldr(); if (ichLim < bldr.Length) bldr.ReplaceTsString(ichLim, bldr.Length, null); if (ichMin > 0) bldr.ReplaceTsString(0, ichMin, null); ITsString tssWord = bldr.GetString(); // See whether we need the special blue underline, which is used mainly for adjacent words in different writing systems. List<int> wss = TsStringUtils.GetWritingSystems(tssWord); if (wss.Count > 1) return MakeWssSuggestions(tssWord, wss, rootb, hvoObj, tag, wsAlt, ichMin, ichLim); ITsString keepOrcs; // holds any ORCs we found in the original word that we need to keep rather than reporting. IList<SpellCorrectMenuItem> result = MakeEmbeddedNscSuggestion(ref tssWord, styles, rootb, hvoObj, tag, wsAlt, ichMin, ichLim, out keepOrcs); if (result.Count > 0) return result; // Determine whether it is a spelling problem. wsText = TsStringUtils.GetWsOfRun(tssWord, 0); dict = SpellingHelper.GetSpellChecker(wsText, wsf); if (dict == null) return null; word = tssWord.get_NormalizedForm(FwNormalizationMode.knmNFC).Text; if (word == null) return null; // don't think this can happen, but... if (dict.Check(word)) return null; // not mis-spelled. // Get suggestions. Make sure to return an empty collection rather than null, even if no suggestions, // to indicate an error. ICollection<string> suggestions = dict.Suggest(word); foreach (string suggest in suggestions) { ITsString replacement = tsf.MakeStringRgch(suggest, suggest.Length, wsText); if (keepOrcs != null) { ITsStrBldr bldrRep = keepOrcs.GetBldr(); bldrRep.ReplaceTsString(0, 0, replacement); replacement = bldrRep.GetString(); } result.Add(new SpellCorrectMenuItem(rootb, hvoObj, tag, wsAlt, ichMin, ichLim, suggest, replacement)); } nonSpellingError = false; // it IS a spelling problem. return result; }
/// <summary> /// Return an item of the specified class that is indicated by a click at the specified position, /// but only if it is part of a different object also of that class. /// </summary> internal static ICmObject SubitemClicked(Point where, int clsid, SimpleRootSite view, FdoCache cache, ISortItemProvider sortItemProvider, IPreferedTargetAdjuster adjuster) { var sel = view.GetSelectionAtPoint(where, false); if (sel == null) return null; Rect rcPrimary = view.GetPrimarySelRect(sel); Rectangle selRect = new Rectangle(rcPrimary.left, rcPrimary.top, rcPrimary.right - rcPrimary.left, rcPrimary.bottom - rcPrimary.top); selRect.Inflate(8,2); if (!selRect.Contains(where)) return null; // off somewhere in white space, tooltip is confusing var helper = SelectionHelper.Create(sel, view); var levels = helper.GetLevelInfo(SelectionHelper.SelLimitType.Anchor); ICmObject firstMatch = null; ICmObject lastMatch = null; foreach (var info in levels) { int hvo = info.hvo; if (!cache.ServiceLocator.IsValidObjectId(hvo)) continue; // may be some invalid numbers in there var obj = cache.ServiceLocator.GetObject(hvo); var target = GetTarget(obj, clsid); if (target == null) continue; // nothing interesting at this level. lastMatch = target; // last one we've seen. if (firstMatch == null) firstMatch = target; // first one we've seen } firstMatch = adjuster.AdjustTarget(firstMatch); if (firstMatch == lastMatch) return null; // the only object we can find to jump to is the top-level one we clicked inside. A jump would go nowhere. if (sortItemProvider.IndexOf(firstMatch.Hvo) != -1) return firstMatch; // it's a link to a top-level item in the list, we can jump // Enhance JohnT: we'd like to be able to jump to the parent entry, if target is a subentry. // That's tricky, because this is generic code, and finding the right object requires domain knowledge. // For now I'm putting a special case in. At some point we could move this into a helper that could be configured by XML. if(firstMatch is ILexSense) { firstMatch = ((ILexSense) firstMatch).Entry; if (sortItemProvider.IndexOf(firstMatch.Hvo) != -1) return firstMatch; // it's a link to a top-level item in the list, we can jump } return null; }