Exemple #1
0
        /// <summary>
        /// Handles text input event.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        ///   This object is already disposed.
        /// </exception>
        /// <exception cref="ArgumentNullException">Parameter 'text' is null.</exception>
        internal void HandleTextInput(string text)
        {
            if (_IsDisposed)
            {
                throw new InvalidOperationException("This object is already disposed.");
            }
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }

            var       doc   = Document;
            var       input = new StringBuilder(Math.Max(64, text.Length));
            IGraphics g     = null;

            // if in read only mode, just notify and return
            if (doc.IsReadOnly)
            {
                Plat.Inst.MessageBeep();
                return;
            }

            // ignore if input is an empty text
            if (text.Length == 0)
            {
                return;
            }

            try
            {
                int newCaretIndex;
                int selBegin, selEnd;

                g = _UI.GetIGraphics();

                // begin grouping UNDO action
                doc.BeginUndo();

                // clear rectangle selection
                if (doc.RectSelectRanges != null)
                {
                    doc.DeleteRectSelectText();
                }

                // handle input characters
                foreach (char ch in text)
                {
                    // try to use hook delegate
                    if (AutoIndentHook != null &&
                        AutoIndentHook(_UI, ch) == true)
                    {
                        // Do nothing if this was handled by the hook
                        continue;
                    }

                    // execute built-in hook logic
                    if (TextUtil.IsEolChar(ch))
                    {
                        // if an EOL code was found, stop consuming and discard
                        // following inputs
                        if (IsSingleLineMode)
                        {
                            break;
                        }

                        // change all EOL code in the text
                        input.Append(doc.EolCode);
                    }
                    else if (ch == '\t' && _UsesTabForIndent == false)
                    {
                        string spaces = GetTabEquivalentSpaces(_UI,
                                                               doc.CaretIndex);
                        if (spaces == "")
                        {
                            // When the caret position is close to next tab
                            // stop, an empty string will be the equivalent to
                            // a tab. In this case we should think as if the
                            // caret is just on the next tab stop.
                            for (int i = 0; i < View.TabWidth; i++)
                            {
                                spaces += ' ';
                            }
                        }
                        input.Append(spaces);
                    }
                    else if (ch == '\x3000' && ConvertsFullWidthSpaceToSpace)
                    {
                        input.Append('\x0020');
                    }
                    else
                    {
                        // remember this character
                        input.Append(ch);
                    }
                }

                // calculate new caret position
                doc.GetSelection(out selBegin, out selEnd);
                newCaretIndex = selBegin + input.Length;

                // calc replacement target range
                if (IsOverwriteMode &&
                    selBegin == selEnd && selEnd + 1 < doc.Length &&
                    TextUtil.IsEolChar(doc[selBegin]) != true)
                {
                    selEnd++;
                }

                // replace selection to input char
                doc.Replace(input.ToString(), selBegin, selEnd);
                doc.SetSelection(newCaretIndex, newCaretIndex);

                // set desired column
                if (UsesStickyCaret == false)
                {
                    _View.SetDesiredColumn(g);
                }

                // update graphic
                _View.ScrollToCaret(g);
                //NO_NEED//_View.Invalidate( xxx ); // Doc_ContentChanged will do invalidation well.
            }
            finally
            {
                doc.EndUndo();
                input.Length = 0;
                if (g != null)
                {
                    g.Dispose();
                }
            }
        }