/ScintillaNET/Scintilla.cs
C# | 3754 lines | 2491 code | 616 blank | 647 comment | 543 complexity | a1b3521f073405e8be9ce6667178001a MD5 | raw file
Possible License(s): MIT, CC-BY-SA-3.0
Large files files are truncated, but you can click here to view the full file
- #region Using Directives
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.Drawing;
- using System.Drawing.Design;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Security.Permissions;
- using System.Text;
- using System.Windows.Forms;
- using ScintillaNET.Configuration;
- using ScintillaNET.Design;
- using ScintillaNET.Properties;
- #endregion Using Directives
- namespace ScintillaNET
- {
- /// <summary>
- /// Represents a Scintilla text editor control.
- /// </summary>
- [Designer(typeof(ScintillaDesigner))]
- [Docking(DockingBehavior.Ask)]
- [DefaultBindingProperty("Text")]
- [DefaultProperty("Text")]
- [DefaultEvent("DocumentChanged")]
- public partial class Scintilla : Control, INativeScintilla, ISupportInitialize
- {
- #region Fields
- private static IntPtr _moduleHandle;
- private static string _moduleName = (IntPtr.Size == 4 ? Resources.ModuleName : Resources.ModuleName64);
- private static NativeMethods.Scintilla_DirectFunction _directFunction;
- private IntPtr _directPointer;
- private static readonly object _annotationChangedEventKey = new object();
- private static readonly object _autoCompleteAcceptedEventKey = new object();
- private static readonly object _beforeTextDeleteEventKey = new object();
- private static readonly object _beforeTextInsertEventKey = new object();
- private static readonly object _borderStyleChangedEventKey = new object();
- private static readonly object _callTipClickEventKey = new object();
- private static readonly object _charAddedEventKey = new object();
- private static readonly object _documentChangeEventKey = new object();
- private static readonly object _dropMarkerCollectEventKey = new object();
- private static readonly object _dwellEndEventKey = new object();
- private static readonly object _dwellStartEventKey = new object();
- private static readonly object _fileDropEventKey = new object();
- private static readonly object _foldChangedEventKey = new object();
- private static readonly object _hotspotClickedEventKey = new object();
- private static readonly object _hotspotDoubleClickedEventKey = new object();
- private static readonly object _hotspotReleaseClickEventKey = new object();
- private static readonly object _indicatorClickEventKey = new object();
- private static readonly object _linesNeedShownEventKey = new object();
- private static readonly object _loadEventKey = new object();
- private static readonly object _macroRecordEventKey = new object();
- private static readonly object _marginClickEventKey = new object();
- private static readonly object _markerChangedEventKey = new object();
- private static readonly object _modifiedChangedEventKey = new object();
- private static readonly object _readOnlyModifyAttemptEventKey = new object();
- private static readonly object _scrollEventKey = new object();
- private static readonly object _selectionChangedEventKey = new object();
- private static readonly object _styleNeededEventKey = new object();
- private static readonly object _textDeletedEventKey = new object();
- private static readonly object _textInsertedEventKey = new object();
- private static readonly object _uriDroppedEventKey = new object();
- private static readonly object _userListEventKey = new object();
- private static readonly object _zoomChangedEventKey = new object();
- private static readonly int _modifiedState = BitVector32.CreateMask();
- private static readonly int _acceptsReturnState = BitVector32.CreateMask(_modifiedState);
- private static readonly int _acceptsTabState = BitVector32.CreateMask(_acceptsReturnState);
- private BitVector32 _state;
- private AnnotationCollection _annotations;
- private LineWrapping _lineWrapping;
- private List<TopLevelHelper> _helpers = new List<TopLevelHelper>();
- private AutoComplete _autoComplete;
- private CallTip _callTip;
- private CaretInfo _caret;
- private Clipboard _clipboard;
- private Commands _commands;
- private Configuration.ConfigurationManager _configurationManager;
- private DocumentHandler _documentHandler;
- private DocumentNavigation _documentNavigation;
- private DropMarkers _dropMarkers;
- private Encoding _encoding;
- private EndOfLine _endOfLine;
- private FindReplace _findReplace;
- private Folding _folding;
- private GoTo _goto;
- private HotspotStyle _hotspotStyle;
- private Indentation _indentation;
- private IndicatorCollection _indicators;
- private Lexing _lexing;
- private LineCollection _lines;
- private LongLines _longLines;
- private MarginCollection _margins;
- private MarkerCollection _markers;
- private Printing _printing;
- private Scrolling _scrolling;
- private Selection _selection;
- private SnippetManager _snippets;
- private StyleCollection _styles;
- private UndoRedo _undoRedo;
- private Whitespace _whitespace;
- private bool _allowDrop;
- private string _caption;
- private Dictionary<string, Color> _colorBag = new Dictionary<string, Color>();
- /// <summary>
- /// Enables the brace matching from current position.
- /// </summary>
- private bool _isBraceMatching = false;
- private bool _isCustomPaintingEnabled = true;
- private bool _isInitializing = false;
- private List<ManagedRange> _managedRanges = new List<ManagedRange>();
- private bool _matchBraces = true;
- private INativeScintilla _ns;
- private Hashtable _propertyBag = new Hashtable();
- private SearchFlags _searchFlags = SearchFlags.Empty;
- private bool _supressControlCharacters = true;
- // List of Scintilla Supported encodings
- internal static readonly IList<Encoding> ValidCodePages = new Encoding[]
- {
- Encoding.ASCII,
- Encoding.UTF8,
- Encoding.Unicode, // UTF-16
- Encoding.GetEncoding(932), // shift_jis - Japanese (Shift-JIS)
- Encoding.GetEncoding(936), // gb2312 - Chinese Simplified (GB2312)
- Encoding.GetEncoding(949), // ks_c_5601-1987 - Korean
- Encoding.GetEncoding(950), // big5 - Chinese Traditional (Big5)
- Encoding.GetEncoding(1361) // Johab - Korean (Johab)
- };
- // This has to be set *early* because CreateParams is called before our constructor
- private BorderStyle _borderStyle = BorderStyle.Fixed3D;
- #endregion Fields
- #region Methods
- /// <summary>
- /// Adds a line _end marker to the _end of the document
- /// </summary>
- public void AddLastLineEnd()
- {
- EndOfLineMode eolMode = _endOfLine.Mode;
- string eolMarker = "\r\n";
- if (eolMode == EndOfLineMode.CR)
- eolMarker = "\r";
- else if (eolMode == EndOfLineMode.LF)
- eolMarker = "\n";
- int tl = TextLength;
- int start = tl - eolMarker.Length;
- if (start < 0 || GetRange(start, start + eolMarker.Length).Text != eolMarker)
- AppendText(eolMarker);
- }
- /// <summary>
- /// Appends a copy of the specified string to the _end of this instance.
- /// </summary>
- /// <param name="text">The <see cref="String"/> to append.</param>
- /// <returns>A <see cref="Range"/> representing the appended text.</returns>
- public Range AppendText(string text)
- {
- int oldLength = TextLength;
- NativeInterface.AppendText(Encoding.GetByteCount(text), text);
- return GetRange(oldLength, TextLength);
- }
- public void BeginInit()
- {
- _isInitializing = true;
- }
- public char CharAt(int position)
- {
- return _ns.GetCharAt(position);
- }
- /// <summary>
- /// Creates and returns a new <see cref="AnnotationCollection" /> object.
- /// </summary>
- /// <returns>A new <see cref="AnnotationCollection" /> object.</returns>
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- protected virtual AnnotationCollection CreateAnnotationsInstance()
- {
- return new AnnotationCollection(this);
- }
- /// <summary>
- /// Creates and returns a new <see cref="LineWrapping" /> object.
- /// </summary>
- /// <returns>A new <see cref="LineWrapping" /> object.</returns>
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- protected virtual LineWrapping CreateLineWrappingInstance()
- {
- return new LineWrapping(this);
- }
- /// <summary>
- /// Sends the specified message directly to the native Scintilla window,
- /// bypassing any managed APIs.
- /// </summary>
- /// <param name="msg">The message ID.</param>
- /// <param name="wParam">The message <c>wparam</c> field.</param>
- /// <param name="lParam">The message <c>lparam</c> field.</param>
- /// <returns>An <see cref="IntPtr"/> representing the result of the message request.</returns>
- /// <remarks>
- /// Warning: The Surgeon General Has Determined that Calling the Underlying Scintilla
- /// Window Directly May Result in Unexpected Behavior!
- /// </remarks>
- /// <exception cref="InvalidOperationException">
- /// The method was called from a thread other than the thread it was created on.
- /// </exception>
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- public IntPtr DirectMessage(int msg, IntPtr wParam, IntPtr lParam)
- {
- // Enforce illegal cross-thread calls
- if (Form.CheckForIllegalCrossThreadCalls && InvokeRequired)
- {
- string message = string.Format(Resources.Culture, Resources.Exception_IllegalCrossThreadCall, Name);
- throw new InvalidOperationException(message);
- }
- // Call the direct function delegate
- return _directFunction(_directPointer, msg, wParam, lParam);
- }
- /// <summary>
- /// Overridden. Releases the unmanaged resources used by the <see cref="Control" /> and
- /// its child controls and optionally releases the managed resources.
- /// </summary>
- /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool disposing)
- {
- foreach (ScintillaHelperBase heler in _helpers)
- {
- heler.Dispose();
- }
- if (disposing && IsHandleCreated)
- {
- // wi11811 2008-07-28 Chris Rickard
- // Since we eat the destroy message in WndProc
- // we have to manually let Scintilla know to
- // clean up its resources.
- Message destroyMessage = new Message();
- destroyMessage.Msg = NativeMethods.WM_DESTROY;
- destroyMessage.HWnd = Handle;
- base.DefWndProc(ref destroyMessage);
- }
- base.Dispose(disposing);
- }
- public void EndInit()
- {
- _isInitializing = false;
- foreach (ScintillaHelperBase helper in _helpers)
- {
- helper.Initialize();
- }
- }
- /// <summary>
- /// Exports a HTML representation of the current document.
- /// </summary>
- /// <returns>A <see cref="String"/> containing the contents of the document formatted as HTML.</returns>
- /// <remarks>Only ASCII documents are supported. Other encoding types have undefined behavior.</remarks>
- public string ExportHtml()
- {
- StringBuilder sb = new StringBuilder();
- using (StringWriter sw = new StringWriter(sb))
- ExportHtml(sw, "Untitled", false);
- return sb.ToString();
- }
- /// <summary>
- /// Exports a HTML representation of the current document.
- /// </summary>
- /// <param name="writer">The <see cref="TextWriter"/>with which to write. </param>
- /// <param name="title">The title of the HTML document.</param>
- /// <param name="allStyles">
- /// <c>true</c> to output all styles including those not
- /// used in the document; otherwise, <c>false</c>.
- /// </param>
- /// <remarks>Only ASCII documents are supported. Other encoding types have undefined behavior.</remarks>
- public void ExportHtml(TextWriter writer, string title, bool allStyles)
- {
- // Make sure the document is current
- // Lexing.Colorize();
- // Get the styles used
- int length = NativeInterface.GetLength();
- bool[] stylesUsed = new bool[(int)StylesCommon.Max + 1];
- if (allStyles)
- {
- for (int i = 0; i < stylesUsed.Length; i++)
- stylesUsed[i] = true;
- }
- else
- {
- // Record all the styles used
- for (int i = 0; i < length; i++)
- stylesUsed[Styles.GetStyleAt(i) & (int)StylesCommon.Max] = true;
- }
- // The tab width
- int tabWidth = Indentation.TabWidth;
- // Start writing
- writer.WriteLine(@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01 Transitional//EN"" ""http://www.w3.org/TR/html4/loose.dtd"">");
- writer.WriteLine("<html>");
- writer.WriteLine("<head>");
- writer.WriteLine("<title>{0}</title>", title);
- writer.WriteLine(@"<style type=""text/css"">");
- writer.WriteLine();
- // Write the body style
- writer.WriteLine("body {");
- writer.WriteLine("background-color: {0};", Utilities.ColorToHtml(Styles.Default.BackColor));
- if (LineWrapping.Mode == LineWrappingMode.None)
- writer.WriteLine("white-space: nowrap;");
- writer.WriteLine("}");
- writer.WriteLine();
- // Write the styles
- for (int i = 0; i < stylesUsed.Length; i++)
- {
- if (!stylesUsed[i])
- continue;
- Style s = Styles[i];
- writer.WriteLine("span.s{0} {{", i);
- writer.WriteLine("font-family: \"" + s.FontName + "\";");
- writer.WriteLine("font-size: {0}pt;", s.Size);
- if (s.Italic)
- writer.WriteLine("font-style: italic;");
- if (s.Bold)
- writer.WriteLine("font-weight: bold;");
- if (!s.ForeColor.IsEmpty && s.ForeColor != Color.Transparent)
- writer.WriteLine("color: {0};", Utilities.ColorToHtml(s.ForeColor));
- if (!s.BackColor.IsEmpty && s.BackColor != Color.Transparent)
- writer.WriteLine("background-color: {0};", Utilities.ColorToHtml(s.BackColor));
- writer.WriteLine("}");
- writer.WriteLine();
- }
- writer.WriteLine("</style>");
- writer.WriteLine("</head>");
- writer.WriteLine("<body>");
- // Write the document
- // TODO There's more to be done here to support codepages/UTF-8
- char lc;
- char c = '\0';
- int lastStyle = -1;
- for (int i = 0; i < length; i++)
- {
- lc = c;
- c = NativeInterface.GetCharAt(i);
- int style = Styles.GetStyleAt(i);
- if(style != lastStyle)
- {
- if(lastStyle != -1)
- writer.Write("</span>");
- writer.Write(@"<span class=""s{0}"">", style);
- lastStyle = style;
- }
- switch (c)
- {
- case '\0':
- continue;
- case ' ':
- if (lc == ' ')
- writer.Write(" ");
- else
- writer.Write(c);
- continue;
- case '\t':
- for (int t = 0; t < tabWidth; t++)
- writer.Write(" ");
- continue;
- case '\r':
- case '\n':
- if (c == '\r' && i < length - 1 && NativeInterface.GetCharAt(i + 1) == '\n')
- i++;
- if (lastStyle != -1)
- writer.Write("</span>");
- writer.WriteLine("<br />");
- lastStyle = -1;
- continue;
- case '<':
- writer.Write("<");
- continue;
- case '>':
- writer.Write(">");
- continue;
- case '&':
- writer.Write("&");
- continue;
- default:
- writer.Write(c);
- continue;
- }
- }
- if (lastStyle != -1)
- writer.Write("</span>");
- writer.WriteLine();
- writer.WriteLine("</body>");
- writer.WriteLine("</html>");
- }
- public int FindColumn(int line, int column)
- {
- return _ns.FindColumn(line, column);
- }
- internal void FireCallTipClick(int arrow)
- {
- CallTipArrow a = (CallTipArrow)arrow;
- OverloadList ol = CallTip.OverloadList;
- CallTipClickEventArgs e;
- if (ol == null)
- {
- e = new CallTipClickEventArgs(a, -1, -1, null, CallTip.HighlightStart, CallTip.HighlightEnd);
- }
- else
- {
- int newIndex = ol.CurrentIndex;
- if (a == CallTipArrow.Down)
- {
- if (ol.CurrentIndex == ol.Count - 1)
- newIndex = 0;
- else
- newIndex++;
- }
- else if (a == CallTipArrow.Up)
- {
- if (ol.CurrentIndex == 0)
- newIndex = ol.Count - 1;
- else
- newIndex--;
- }
- e = new CallTipClickEventArgs(a, ol.CurrentIndex, newIndex, ol, CallTip.HighlightStart, CallTip.HighlightEnd);
- }
- OnCallTipClick(e);
- if (e.Cancel)
- {
- CallTip.Cancel();
- }
- else
- {
- if (ol != null)
- {
- // We allow them to alse replace the list entirely or just
- // manipulate the New Index
- CallTip.OverloadList = e.OverloadList;
- CallTip.OverloadList.CurrentIndex = e.NewIndex;
- CallTip.ShowOverloadInternal();
- }
- CallTip.HighlightStart = e.HighlightStart;
- CallTip.HighlightEnd = e.HighlightEnd;
- }
- }
- internal void FireKeyDown(KeyEventArgs e)
- {
- OnKeyDown(e);
- }
- internal void FireMarginClick(SCNotification n)
- {
- Margin m = Margins[n.margin];
- Keys k = Keys.None;
- if ((n.modifiers & (int)KeyMod.Alt) == (int)KeyMod.Alt)
- k |= Keys.Alt;
- if ((n.modifiers & (int)KeyMod.Ctrl) == (int)KeyMod.Ctrl)
- k |= Keys.Control;
- if ((n.modifiers & (int)KeyMod.Shift) == (int)KeyMod.Shift)
- k |= Keys.Shift;
- OnMarginClick(new MarginClickEventArgs(k, n.position, Lines.FromPosition(n.position), m, m.AutoToggleMarkerNumber, m.IsFoldMargin));
- }
- public int GetColumn(int position)
- {
- return _ns.GetColumn(position);
- }
- /// <summary>
- /// Gets the text of the line containing the caret.
- /// </summary>
- /// <returns>A <see cref="String" /> representing the text of the line containing the caret.</returns>
- public unsafe string GetCurrentLine()
- {
- int tmp;
- return GetCurrentLine(out tmp);
- }
- /// <summary>
- /// Gets the text of the line containing the caret and the current caret position within that line.
- /// </summary>
- /// <param name="caretPosition">When this method returns, contains the byte offset of the current caret position with the line.</param>
- /// <returns>A <see cref="String" /> representing the text of the line containing the caret.</returns>
- public unsafe string GetCurrentLine(out int caretPosition)
- {
- int length = DirectMessage(NativeMethods.SCI_GETCURLINE, IntPtr.Zero, IntPtr.Zero).ToInt32();
- byte[] buffer = new byte[length];
- fixed (byte* bp = buffer)
- caretPosition = DirectMessage(NativeMethods.SCI_GETCURLINE, new IntPtr(buffer.Length), new IntPtr(bp)).ToInt32();
- return Encoding.GetString(buffer, 0, length - 1);
- }
- public Range GetRange()
- {
- return new Range(0, _ns.GetTextLength(), this);
- }
- public Range GetRange(int position)
- {
- return new Range(position, position + 1, this);
- }
- public Range GetRange(int startPosition, int endPosition)
- {
- return new Range(startPosition, endPosition, this);
- }
- /// <summary>
- /// Gets a word from the specified position
- /// </summary>
- public string GetWordFromPosition(int position)
- {
- // Chris Rickard 2008-07-28
- // Fixing implementation to actually return the word at the position...
- // Credit goes to Stumpii for the code.
- // As a side note: I think the previous code was implemented based off
- // some funky code I made for the snippet keyword detection, but since
- // it doesn't reference this method there's no reason to keep the buggy
- // behavior. I also removed the try..catch because in theory this
- // shouldn't throw and we REALLY shouldn't be eating exceptions at the
- // System.Exception level. If some _start popping up I can add some
- // conditionals or catch more specific Exceptions.
- int startPosition = NativeInterface.WordStartPosition(position, true);
- int endPosition = NativeInterface.WordEndPosition(position, true);
- return GetRange(startPosition, endPosition).Text;
- }
- private void HandleFileDrop(IntPtr hDrop)
- {
- StringBuilder buffer = null;
- uint nfiles = NativeMethods.DragQueryFile(hDrop, 0xffffffff, buffer, 0);
- List<string> files = new List<string>();
- for (uint i = 0; i < nfiles; i++)
- {
- buffer = new StringBuilder(512);
- NativeMethods.DragQueryFile(hDrop, i, buffer, 512);
- files.Add(buffer.ToString());
- }
- NativeMethods.DragFinish(hDrop);
- OnFileDrop(new FileDropEventArgs(files.ToArray()));
- }
- /// <summary>
- /// Inserts text at the current cursor position
- /// </summary>
- /// <param name="text">Text to insert</param>
- /// <returns>The range inserted</returns>
- public Range InsertText(string text)
- {
- NativeInterface.AddText(Encoding.GetByteCount(text), text);
- return GetRange(_caret.Position, Encoding.GetByteCount(text));
- }
- /// <summary>
- /// Inserts text at the given position
- /// </summary>
- /// <param name="position">The position to insert text in</param>
- /// <param name="text">Text to insert</param>
- /// <returns>The text range inserted</returns>
- public Range InsertText(int position, string text)
- {
- NativeInterface.InsertText(position, text);
- return GetRange(position, Encoding.GetByteCount(text));
- }
- /// <summary>
- /// Overridden. See <see cref="Control.IsInputKey"/>.
- /// </summary>
- protected override bool IsInputKey(Keys keyData)
- {
- if ((keyData & Keys.Shift) != Keys.None)
- keyData ^= Keys.Shift;
- switch (keyData)
- {
- case Keys.Tab:
- return _state[_acceptsTabState];
- case Keys.Enter:
- return _state[_acceptsReturnState];
- case Keys.Up:
- case Keys.Down:
- case Keys.Left:
- case Keys.Right:
- case Keys.F:
- return true;
- }
- return base.IsInputKey(keyData);
- }
- private static void LoadModule()
- {
- if (_moduleHandle == IntPtr.Zero)
- {
- // Load the Scintilla module into memory
- if ((_moduleHandle = NativeMethods.LoadLibrary(_moduleName)) == IntPtr.Zero)
- {
- string message = string.Format(Resources.Culture, Resources.Exception_CannotLoadModule, _moduleName);
- throw new Win32Exception(message, new Win32Exception(Marshal.GetLastWin32Error()));
- }
- // Get the direct function. We use GetProcAddress instead of DllImport
- // because we don't know the name of the module ahead of time.
- _directFunction = Marshal.GetDelegateForFunctionPointer(
- NativeMethods.GetProcAddress(_moduleHandle, "Scintilla_DirectFunction"),
- typeof(NativeMethods.Scintilla_DirectFunction)) as NativeMethods.Scintilla_DirectFunction;
- if (_directFunction == null)
- {
- string message = string.Format(Resources.Culture, Resources.Exception_InvalidModule, _moduleName);
- throw new Win32Exception(message, new Win32Exception(Marshal.GetLastWin32Error()));
- }
- }
- }
- private List<ManagedRange> ManagedRangesInRange(int firstPos, int lastPos)
- {
- // TODO: look into optimizing this so that it isn't a linear
- // search. This is fine for a few markers per document but
- // can be greatly improved if there are a large # of markers
- List<ManagedRange> ret = new List<ManagedRange>();
- foreach (ManagedRange mr in _managedRanges)
- if (mr.Start >= firstPos && mr.Start <= lastPos)
- ret.Add(mr);
- return ret;
- }
- /// <summary>
- /// Raises the <see cref="AnnotationChanged" /> event.
- /// </summary>
- /// <param name="e">An <see cref="AnnotationChangedEventArgs" /> that contains the event data.</param>
- protected virtual void OnAnnotationChanged(AnnotationChangedEventArgs e)
- {
- EventHandler<AnnotationChangedEventArgs> handler = Events[_annotationChangedEventKey] as EventHandler<AnnotationChangedEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="AutoCompleteAccepted"/> event.
- /// </summary>
- /// <param name="e">An <see cref="AutoCompleteAcceptedEventArgs"/> that contains the event data.</param>
- protected virtual void OnAutoCompleteAccepted(AutoCompleteAcceptedEventArgs e)
- {
- EventHandler<AutoCompleteAcceptedEventArgs> handler = Events[_autoCompleteAcceptedEventKey] as EventHandler<AutoCompleteAcceptedEventArgs>;
- if (handler != null)
- handler(this, e);
- if (e.Cancel)
- AutoComplete.Cancel();
- }
- /// <summary>
- /// Raises the <see cref="BackColorChanged"/> event.
- /// </summary>
- /// <param name="e">An <see cref="EventArgs"/> that contains the event data. </param>
- protected override void OnBackColorChanged(EventArgs e)
- {
- ResetStyles();
- base.OnBackColorChanged(e);
- }
- /// <summary>
- /// Raises the <see cref="BeforeTextDelete"/> event.
- /// </summary>
- /// <param name="e">An <see cref="TextModifiedEventArgs"/> that contains the event data.</param>
- protected virtual void OnBeforeTextDelete(TextModifiedEventArgs e)
- {
- int firstPos = e.Position;
- int lastPos = firstPos + e.Length;
- List<ManagedRange> deletedRanges = new List<ManagedRange>();
- foreach (ManagedRange mr in _managedRanges)
- {
- // These ranges lie within the deleted range so
- // the ranges themselves need to be deleted
- if (mr.Start >= firstPos && mr.End <= lastPos)
- {
- // If the entire range is being delete and NOT a superset of the range,
- // don't delete it, only collapse it.
- if (!mr.IsPoint && e.Position == mr.Start && (e.Position + e.Length == mr.End))
- {
- mr.Change(mr.Start, mr.Start);
- }
- else
- {
- // Notify the virtual Range that it needs to cleanup
- mr.Change(-1, -1);
- // Mark for deletion after this foreach:
- deletedRanges.Add(mr);
- }
- }
- else if (mr.Start >= lastPos)
- {
- // These ranges are merely offset by the deleted range
- mr.Change(mr.Start - e.Length, mr.End - e.Length);
- }
- else if (mr.Start >= firstPos && mr.Start <= lastPos)
- {
- // The left side of the managed range is getting
- // cut off
- mr.Change(firstPos, mr.End - e.Length);
- }
- else if (mr.Start < firstPos && mr.End >= firstPos && mr.End >= lastPos)
- {
- mr.Change(mr.Start, mr.End - e.Length);
- }
- else if (mr.Start < firstPos && mr.End >= firstPos && mr.End < lastPos)
- {
- mr.Change(mr.Start, firstPos);
- }
- }
- foreach (ManagedRange mr in deletedRanges)
- mr.Dispose();
- EventHandler<TextModifiedEventArgs> handler = Events[_beforeTextDeleteEventKey] as EventHandler<TextModifiedEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="BeforeTextInsert"/> event.
- /// </summary>
- /// <param name="e">An <see cref="TextModifiedEventArgs"/> that contains the event data.</param>
- protected virtual void OnBeforeTextInsert(TextModifiedEventArgs e)
- {
- List<ManagedRange> offsetRanges = new List<ManagedRange>();
- foreach (ManagedRange mr in _managedRanges)
- {
- if (mr.Start == e.Position && mr.PendingDeletion)
- {
- mr.PendingDeletion = false;
- ManagedRange lmr = mr;
- BeginInvoke(new MethodInvoker(delegate() { lmr.Change(e.Position, e.Position + e.Length); }));
- }
- // If the Range is a single point we treat it slightly
- // differently than a spanned range
- if (mr.IsPoint)
- {
- // Unlike a spanned range, if the insertion point of
- // the new text == the _start of the range (and thus
- // the _end as well) we offset the entire point.
- if (mr.Start >= e.Position)
- mr.Change(mr.Start + e.Length, mr.End + e.Length);
- else if (mr.End >= e.Position)
- mr.Change(mr.Start, mr.End + e.Length);
- }
- else
- {
- // We offset a spanned range entirely only if the
- // _start occurs after the insertion point of the new
- // text.
- if (mr.Start > e.Position)
- mr.Change(mr.Start + e.Length, mr.End + e.Length);
- else if (mr.End >= e.Position)
- {
- // However it the _start of the range == the insertion
- // point of the new text instead of offestting the
- // range we expand it.
- mr.Change(mr.Start, mr.End + e.Length);
- }
- }
- }
- EventHandler<TextModifiedEventArgs> handler = Events[_beforeTextInsertEventKey] as EventHandler<TextModifiedEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="BorderStyleChanged" /> event.
- /// </summary>
- /// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
- protected virtual void OnBorderStyleChanged(EventArgs e)
- {
- EventHandler handler = Events[_borderStyleChangedEventKey] as EventHandler;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="CallTipClick"/> event.
- /// </summary>
- /// <param name="e">An <see cref="CallTipClickEventArgs"/> that contains the event data.</param>
- protected virtual void OnCallTipClick(CallTipClickEventArgs e)
- {
- EventHandler<CallTipClickEventArgs> handler = Events[_callTipClickEventKey] as EventHandler<CallTipClickEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="CharAdded"/> event.
- /// </summary>
- /// <param name="e">An <see cref="CharAddedEventArgs"/> that contains the event data.</param>
- protected virtual void OnCharAdded(CharAddedEventArgs e)
- {
- EventHandler<CharAddedEventArgs> handler = Events[_charAddedEventKey] as EventHandler<CharAddedEventArgs>;
- if (handler != null)
- handler(this, e);
- if (_indentation.SmartIndentType != SmartIndent.None)
- _indentation.CheckSmartIndent(e.Ch);
- }
- /// <summary>
- /// Overridden. See <see cref="Control.OnCreateControl"/>.
- /// </summary>
- protected override void OnCreateControl()
- {
- base.OnCreateControl();
- OnLoad(EventArgs.Empty);
- }
- /// <summary>
- /// Raises the <see cref="DocumentChange"/> event.
- /// </summary>
- /// <param name="e">An <see cref="NativeScintillaEventArgs"/> that contains the event data.</param>
- protected virtual void OnDocumentChange(NativeScintillaEventArgs e)
- {
- EventHandler<NativeScintillaEventArgs> handler = Events[_documentChangeEventKey] as EventHandler<NativeScintillaEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Provides the support for code block selection
- /// </summary>
- protected override void OnDoubleClick(EventArgs e)
- {
- base.OnDoubleClick(e);
- if (_isBraceMatching)
- {
- int position = CurrentPos - 1,
- bracePosStart = -1,
- bracePosEnd = -1;
- char character = (char)CharAt(position);
- switch (character)
- {
- case '{':
- case '(':
- case '[':
- if (!this.PositionIsOnComment(position))
- {
- bracePosStart = position;
- bracePosEnd = _ns.BraceMatch(position, 0) + 1;
- _selection.Start = bracePosStart;
- _selection.End = bracePosEnd;
- }
- break;
- }
- }
- }
- /// <summary>
- /// Raises the <see cref="DropMarkerCollect"/> event.
- /// </summary>
- /// <param name="e">An <see cref="DropMarkerCollectEventArgs"/> that contains the event data.</param>
- protected internal virtual void OnDropMarkerCollect(DropMarkerCollectEventArgs e)
- {
- EventHandler<DropMarkerCollectEventArgs> handler = Events[_dropMarkerCollectEventKey] as EventHandler<DropMarkerCollectEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="DwellEnd"/> event.
- /// </summary>
- /// <param name="e">An <see cref="ScintillaMouseEventArgs"/> that contains the event data.</param>
- protected virtual void OnDwellEnd(ScintillaMouseEventArgs e)
- {
- EventHandler<ScintillaMouseEventArgs> handler = Events[_dwellEndEventKey] as EventHandler<ScintillaMouseEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="DwellStart"/> event.
- /// </summary>
- /// <param name="e">An <see cref="ScintillaMouseEventArgs"/> that contains the event data.</param>
- protected virtual void OnDwellStart(ScintillaMouseEventArgs e)
- {
- EventHandler<ScintillaMouseEventArgs> handler = Events[_dwellStartEventKey] as EventHandler<ScintillaMouseEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="FileDrop"/> event.
- /// </summary>
- /// <param name="e">An <see cref="FileDropEventArgs"/> that contains the event data.</param>
- protected virtual void OnFileDrop(FileDropEventArgs e)
- {
- EventHandler<FileDropEventArgs> handler = Events[_fileDropEventKey] as EventHandler<FileDropEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="FoldChanged"/> event.
- /// </summary>
- /// <param name="e">An <see cref="FoldChangedEventArgs"/> that contains the event data.</param>
- protected virtual void OnFoldChanged(FoldChangedEventArgs e)
- {
- EventHandler<FoldChangedEventArgs> handler = Events[_foldChangedEventKey] as EventHandler<FoldChangedEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="FontChanged"/> event.
- /// </summary>
- /// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
- protected override void OnFontChanged(EventArgs e)
- {
- ResetStyles();
- base.OnFontChanged(e);
- }
- /// <summary>
- /// Raises the <see cref="ForeColorChanged"/> event.
- /// </summary>
- /// <param name="e">An <see cref="EventArgs"/> that contains the event data. </param>
- protected override void OnForeColorChanged(EventArgs e)
- {
- ResetStyles();
- base.OnForeColorChanged(e);
- }
- /// <summary>
- /// Overridden. See <see cref="Control.OnGotFocus"/>.
- /// </summary>
- protected override void OnGotFocus(EventArgs e)
- {
- if (!Selection.Hidden)
- _ns.HideSelection(false);
- _ns.SetSelBack(Selection.BackColor != Color.Transparent, Utilities.ColorToRgb(Selection.BackColor));
- _ns.SetSelFore(Selection.ForeColor != Color.Transparent, Utilities.ColorToRgb(Selection.ForeColor));
- base.OnGotFocus(e);
- }
- /// <summary>
- /// Overridden. Raises the <see cref="Control.HandleCreated"/> event.
- /// </summary>
- /// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
- protected override void OnHandleCreated(EventArgs e)
- {
- // TODO Recreating handle?
- // Get the Scintilla direct pointer
- _directPointer = NativeMethods.SendMessage(Handle, NativeMethods.SCI_GETDIRECTPOINTER, IntPtr.Zero, IntPtr.Zero);
- if (_directPointer == IntPtr.Zero)
- throw new Win32Exception(Resources.Exception_CannotCreateDirectFunction);
- base.OnHandleCreated(e);
- }
- /// <summary>
- /// Raises the <see cref="HotspotClick"/> event.
- /// </summary>
- /// <param name="e">A <see cref="HotspotClickEventArgs"/> that contains the event data.</param>
- protected virtual void OnHotspotClick(HotspotClickEventArgs e)
- {
- EventHandler<HotspotClickEventArgs> handler = Events[_hotspotClickEventKey] as EventHandler<HotspotClickEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="HotspotDoubleClick"/> event.
- /// </summary>
- /// <param name="e">A <see cref="HotspotClickEventArgs"/> that contains the event data.</param>
- protected virtual void OnHotspotDoubleClick(HotspotClickEventArgs e)
- {
- EventHandler<HotspotClickEventArgs> handler = Events[_hotspotDoubleClickEventKey] as EventHandler<HotspotClickEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="HotspotReleaseClick"/> event.
- /// </summary>
- /// <param name="e">A <see cref="HotspotClickEventArgs"/> that contains the event data.</param>
- protected virtual void OnHotspotReleaseClick(HotspotClickEventArgs e)
- {
- EventHandler<HotspotClickEventArgs> handler = Events[_hotspotReleaseClickEventKey] as EventHandler<HotspotClickEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="IndicatorClick"/> event.
- /// </summary>
- /// <param name="e">An <see cref="ScintillaMouseEventArgs"/> that contains the event data.</param>
- protected virtual void OnIndicatorClick(ScintillaMouseEventArgs e)
- {
- EventHandler<ScintillaMouseEventArgs> handler = Events[_indicatorClickEventKey] as EventHandler<ScintillaMouseEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Overridden. See <see cref="Control.OnKeyDown"/>.
- /// </summary>
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (!e.Handled)
- e.SuppressKeyPress = _commands.ProcessKey(e);
- }
- /// <summary>
- /// Overridden. See <see cref="Control.OnKeyPress"/>.
- /// </summary>
- protected override void OnKeyPress(KeyPressEventArgs e)
- {
- if (_supressControlCharacters && (int)e.KeyChar < 32)
- e.Handled = true;
- if (_snippets.IsEnabled && _snippets.IsOneKeySelectionEmbedEnabled && _selection.Length > 0)
- {
- Snippet s;
- if (_snippets.List.TryGetValue(e.KeyChar.ToString(), out s))
- {
- if (s.IsSurroundsWith)
- {
- _snippets.InsertSnippet(s);
- e.Handled = true;
- }
- }
- }
- base.OnKeyPress(e);
- }
- /// <summary>
- /// Raises the <see cref="LinesNeedShown"/> event.
- /// </summary>
- /// <param name="e">An <see cref="LinesNeedShownEventArgs"/> that contains the event data.</param>
- protected virtual void OnLinesNeedShown(LinesNeedShownEventArgs e)
- {
- EventHandler<LinesNeedShownEventArgs> handler = Events[_linesNeedShownEventKey] as EventHandler<LinesNeedShownEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="Load"/> event.
- /// </summary>
- /// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
- protected virtual void OnLoad(EventArgs e)
- {
- EventHandler handler = Events[_loadEventKey] as EventHandler;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Overridden. See <see cref="Control.OnLostFocus"/>.
- /// </summary>
- protected override void OnLostFocus(EventArgs e)
- {
- if (Selection.HideSelection)
- _ns.HideSelection(true);
- _ns.SetSelBack(Selection.BackColorUnfocused != Color.Transparent, Utilities.ColorToRgb(Selection.BackColorUnfocused));
- _ns.SetSelFore(Selection.ForeColorUnfocused != Color.Transparent, Utilities.ColorToRgb(Selection.ForeColorUnfocused));
- base.OnLostFocus(e);
- }
- /// <summary>
- /// Raises the <see cref="MacroRecord"/> event.
- /// </summary>
- /// <param name="e">An <see cref="MacroRecordEventArgs"/> that contains the event data.</param>
- protected virtual void OnMacroRecord(MacroRecordEventArgs e)
- {
- EventHandler<MacroRecordEventArgs> handler = Events[_macroRecordEventKey] as EventHandler<MacroRecordEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="MarginClick"/> event.
- /// </summary>
- /// <param name="e">An <see cref="MarginClickEventArgs"/> that contains the event data.</param>
- protected virtual void OnMarginClick(MarginClickEventArgs e)
- {
- EventHandler<MarginClickEventArgs> handler = Events[_marginClickEventKey] as EventHandler<MarginClickEventArgs>;
- if (handler != null)
- handler(this, e);
- if (e.ToggleMarkerNumber >= 0)
- {
- int mask = (int)Math.Pow(2, e.ToggleMarkerNumber);
- if ((e.Line.GetMarkerMask() & mask) == mask)
- e.Line.DeleteMarker(e.ToggleMarkerNumber);
- else
- e.Line.AddMarker(e.ToggleMarkerNumber);
- }
- if (e.ToggleFold)
- e.Line.ToggleFoldExpanded();
- }
- /// <summary>
- /// Raises the <see cref="MarkerChanged"/> event.
- /// </summary>
- /// <param name="e">An <see cref="MarkerChangedEventArgs"/> that contains the event data.</param>
- protected virtual void OnMarkerChanged(MarkerChangedEventArgs e)
- {
- EventHandler<MarkerChangedEventArgs> handler = Events[_markerChangedEventKey] as EventHandler<MarkerChangedEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="ModifiedChanged"/> event.
- /// </summary>
- /// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
- protected virtual void OnModifiedChanged(EventArgs e)
- {
- EventHandler handler = Events[_modifiedChangedEventKey] as EventHandler;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Overridden. See <see cref="Control.OnPaint"/>.
- /// </summary>
- protected override void OnPaint(PaintEventArgs e)
- {
- base.OnPaint(e);
- paintRanges(e.Graphics);
- }
- /// <summary>
- /// Raises the <see cref="ReadOnlyModifyAttempt"/> event.
- /// </summary>
- /// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
- protected virtual void OnReadOnlyModifyAttempt(EventArgs e)
- {
- EventHandler handler = Events[_readOnlyModifyAttemptEventKey] as EventHandler;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="Scroll"/> event.
- /// </summary>
- /// <param name="e">An <see cref="ScrollEventArgs"/> that contains the event data.</param>
- protected virtual void OnScroll(ScrollEventArgs e)
- {
- EventHandler<ScrollEventArgs> handler = Events[_scrollEventKey] as EventHandler<ScrollEventArgs>;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>
- /// Raises the <see cref="SelectionChang…
Large files files are truncated, but you can click here to view the full file