// Return true if a spelling error occurs in the word that is the specified substring of m_text.
        bool CheckWord(int ichMinWord, int ichLimWord)
        {
            string       word = TsStringUtils.NormalizeToNFC(m_text.Substring(ichMinWord, ichLimWord - ichMinWord));
            TsRunInfo    tri;
            ITsTextProps props = m_tss.FetchRunInfoAt(ichMinWord, out tri);
            int          var;
            int          ws            = props.GetIntPropValues((int)FwTextPropType.ktptWs, out var);
            bool         fFoundOurWs   = (ws == m_ws);
            bool         fFoundOtherWs = (ws != m_ws);

            while (tri.ichLim < ichLimWord)
            {
                props          = m_tss.FetchRunInfoAt(tri.ichLim, out tri);
                ws             = props.GetIntPropValues((int)FwTextPropType.ktptWs, out var);
                fFoundOurWs   |= (ws == m_ws);
                fFoundOtherWs |= (ws != m_ws);
            }
            if (!fFoundOurWs)
            {
                return(false);                // don't check words with nothing in interesting WS.
            }
            if (fFoundOtherWs)
            {
                return(true);                // mixed writing system in a 'word' always counts as a 'spelling' error.
            }
            return(!m_dict.Check(word));     // succeed if check fails!
        }
Example #2
0
		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;
		}
Example #3
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Get a list of suggested corrections if the selection is a spelling or similar error.
        /// Returns null if there is no problem at the selection location.
        /// Note that it may also return an empty list; this has a distinct meaning, namely,
        /// that there IS a problem, but we have no useful suggestions for what to change it to.
        /// nonSpellingError is set true when the error is not simply a mis-spelled word in a
        /// single writing system; currently this should disable or hide the commands to add
        /// the word to the dictionary or change multiple occurrences.
        /// The input arguments indicate where the user clicked and allow us to find the
        /// text he might be trying to correct. The other output arguments indicate which WS
        /// (wasAlt -- 0 for simple string) of which property (tag) of which object (hvoObj)
        /// is affected by the change, the ws of the mis-spelled word, and the corresponding
        /// spelling engine. Much of this information is already known to the
        /// SpellCorrectMenuItems returned, but some clients use it in creating other menu options.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        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, false, ichMin, 0) + 1;             // further expanded start of word.
            int ichLimAdjust = AdjustWordBoundary(wsf, tss, true, ichLim - 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;

            // 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 = TsStringUtils.MakeString(suggest, 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);
        }