// // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // License: GNU Lesser General Public License (LGPLv3) // // Email: pavel_torgashov@ukr.net. // // Copyright (C) Pavel Torgashov, 2011-2015. // #define debug // ------------------------------------------------------------------------------- // By default the FastColoredTextbox supports no more 16 styles at the same time. // This restriction saves memory. // However, you can to compile FCTB with 32 styles supporting. // Uncomment following definition if you need 32 styles instead of 16: // // #define Styles32 using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Design; using System.Drawing.Drawing2D; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; using System.Windows.Forms.Design; using Microsoft.Win32; using Timer = System.Windows.Forms.Timer; namespace FastColoredTextBoxNS { /// /// Fast colored textbox /// public partial class FastColoredTextBox : UserControl, ISupportInitialize { internal const int minLeftIndent = 8; private const int maxBracketSearchIterations = 1000; private const int maxLinesForFolding = 3000; private const int minLinesForAccuracy = 100000; private const int WM_IME_SETCONTEXT = 0x0281; private const int WM_HSCROLL = 0x114; private const int WM_VSCROLL = 0x115; private const int SB_ENDSCROLL = 0x8; public readonly List LineInfos = new List(); private readonly Range selection; private readonly Timer timer = new Timer(); private readonly Timer timer2 = new Timer(); private readonly Timer timer3 = new Timer(); private readonly List visibleMarkers = new List(); public int TextHeight; public bool AllowInsertRemoveLines = true; private Brush backBrush; private BaseBookmarks bookmarks; private bool caretVisible; private Color changedLineColor; private int charHeight; private Color currentLineColor; private Cursor defaultCursor; private Range delayedTextChangedRange; private string descriptionFile; private int endFoldingLine = -1; private Color foldingIndicatorColor; protected Dictionary foldingPairs = new Dictionary(); private bool handledChar; private bool highlightFoldingIndicator; private Hints hints; private Color indentBackColor; private bool isChanged; private bool isLineSelect; private bool isReplaceMode; private Language language; private Keys lastModifiers; private Point lastMouseCoord; private DateTime lastNavigatedDateTime; private Range leftBracketPosition; private Range leftBracketPosition2; private int leftPadding; private int lineInterval; private Color lineNumberColor; private uint lineNumberStartValue; private int lineSelectFrom; private TextSource lines; private IntPtr m_hImc; private int maxLineLength; private bool mouseIsDrag; private bool mouseIsDragDrop; private bool multiline; protected bool needRecalc; protected bool needRecalcWordWrap; private Point needRecalcWordWrapInterval; private bool needRecalcFoldingLines; private bool needRiseSelectionChangedDelayed; private bool needRiseTextChangedDelayed; private bool needRiseVisibleRangeChangedDelayed; private Color paddingBackColor; private int preferredLineWidth; private Range rightBracketPosition; private Range rightBracketPosition2; private bool scrollBars; private Color selectionColor; private Color serviceLinesColor; private bool showFoldingLines; private bool showLineNumbers; private FastColoredTextBox sourceTextBox; private int startFoldingLine = -1; private int updating; private Range updatingRange; private Range visibleRange; private bool wordWrap; private WordWrapMode wordWrapMode = WordWrapMode.WordWrapControlWidth; private int reservedCountOfLineNumberChars = 1; private int zoom = 100; private Size localAutoScrollMinSize; /// /// Constructor /// public FastColoredTextBox() { //register type provider TypeDescriptionProvider prov = TypeDescriptor.GetProvider(GetType()); object theProvider = prov.GetType().GetField("Provider", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(prov); if (theProvider.GetType() != typeof (FCTBDescriptionProvider)) TypeDescriptor.AddProvider(new FCTBDescriptionProvider(GetType()), GetType()); //drawing optimization SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.ResizeRedraw, true); //append monospace font //Font = new Font("Consolas", 9.75f, FontStyle.Regular, GraphicsUnit.Point); Font = new Font(FontFamily.GenericMonospace, 9.75f); //create one line InitTextSource(CreateTextSource()); if (lines.Count == 0) lines.InsertLine(0, lines.CreateLine()); selection = new Range(this) {Start = new Place(0, 0)}; //default settings Cursor = Cursors.IBeam; BackColor = Color.White; LineNumberColor = Color.Teal; IndentBackColor = Color.WhiteSmoke; ServiceLinesColor = Color.Silver; FoldingIndicatorColor = Color.Green; CurrentLineColor = Color.Transparent; ChangedLineColor = Color.Transparent; HighlightFoldingIndicator = true; ShowLineNumbers = true; TabLength = 4; FoldedBlockStyle = new FoldedBlockStyle(Brushes.Gray, null, FontStyle.Regular); SelectionColor = Color.Blue; BracketsStyle = new MarkerStyle(new SolidBrush(Color.FromArgb(80, Color.Lime))); BracketsStyle2 = new MarkerStyle(new SolidBrush(Color.FromArgb(60, Color.Red))); DelayedEventsInterval = 100; DelayedTextChangedInterval = 100; AllowSeveralTextStyleDrawing = false; LeftBracket = '\x0'; RightBracket = '\x0'; LeftBracket2 = '\x0'; RightBracket2 = '\x0'; SyntaxHighlighter = new SyntaxHighlighter(); language = Language.Custom; PreferredLineWidth = 0; needRecalc = true; lastNavigatedDateTime = DateTime.Now; AutoIndent = true; AutoIndentExistingLines = true; CommentPrefix = "//"; lineNumberStartValue = 1; multiline = true; scrollBars = true; AcceptsTab = true; AcceptsReturn = true; caretVisible = true; CaretColor = Color.Black; WideCaret = false; Paddings = new Padding(0, 0, 0, 0); PaddingBackColor = Color.Transparent; DisabledColor = Color.FromArgb(100, 180, 180, 180); needRecalcFoldingLines = true; AllowDrop = true; FindEndOfFoldingBlockStrategy = FindEndOfFoldingBlockStrategy.Strategy1; VirtualSpace = false; bookmarks = new Bookmarks(this); BookmarkColor = Color.PowderBlue; ToolTip = new ToolTip(); timer3.Interval = 500; hints = new Hints(this); SelectionHighlightingForLineBreaksEnabled = true; textAreaBorder = TextAreaBorderType.None; textAreaBorderColor = Color.Black; macrosManager = new MacrosManager(this); HotkeysMapping = new HotkeysMapping(); HotkeysMapping.InitDefault(); WordWrapAutoIndent = true; FoldedBlocks = new Dictionary(); AutoCompleteBrackets = false; AutoIndentCharsPatterns = @"^\s*[\w\.]+\s*(?=)\s*(?[^;]+);"; AutoIndentChars = true; CaretBlinking = true; ServiceColors = new ServiceColors(); // base.AutoScroll = true; timer.Tick += timer_Tick; timer2.Tick += timer2_Tick; timer3.Tick += timer3_Tick; middleClickScrollingTimer.Tick += middleClickScrollingTimer_Tick; } private char[] autoCompleteBracketsList = { '(', ')', '{', '}', '[', ']', '"', '"', '\'', '\'' }; public char[] AutoCompleteBracketsList { get { return autoCompleteBracketsList; } set { autoCompleteBracketsList = value; } } /// /// AutoComplete brackets /// [DefaultValue(false)] [Description("AutoComplete brackets.")] public bool AutoCompleteBrackets { get; set; } /// /// Colors of some service visual markers /// [Browsable(true)] [Description("Colors of some service visual markers.")] [TypeConverter(typeof(ExpandableObjectConverter))] public ServiceColors ServiceColors { get; set; } /// /// Contains UniqueId of start lines of folded blocks /// /// This dictionary remembers folding state of blocks. /// It is needed to restore child folding after user collapsed/expanded top-level folding block. [Browsable(false)] public Dictionary FoldedBlocks { get; private set; } /// /// Strategy of search of brackets to highlighting /// [DefaultValue(typeof(BracketsHighlightStrategy), "Strategy1")] [Description("Strategy of search of brackets to highlighting.")] public BracketsHighlightStrategy BracketsHighlightStrategy { get; set; } /// /// Automatically shifts secondary wordwrap lines on the shift amount of the first line /// [DefaultValue(true)] [Description("Automatically shifts secondary wordwrap lines on the shift amount of the first line.")] public bool WordWrapAutoIndent { get; set; } /// /// Indent of secondary wordwrap lines (in chars) /// [DefaultValue(0)] [Description("Indent of secondary wordwrap lines (in chars).")] public int WordWrapIndent { get; set; } MacrosManager macrosManager; /// /// MacrosManager records, stores and executes the macroses /// [Browsable(false)] public MacrosManager MacrosManager { get { return macrosManager; } } /// /// Allows drag and drop /// [DefaultValue(true)] [Description("Allows drag and drop")] public override bool AllowDrop { get { return base.AllowDrop; } set { base.AllowDrop = value; } } /// /// Collection of Hints. /// This is temporary buffer for currently displayed hints. /// /// You can asynchronously add, remove and clear hints. Appropriate hints will be shown or hidden from the screen. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] public Hints Hints { get { return hints; } set { hints = value; } } /// /// Delay (ms) of ToolTip /// [Browsable(true)] [DefaultValue(500)] [Description("Delay(ms) of ToolTip.")] public int ToolTipDelay { get { return timer3.Interval; } set { timer3.Interval = value; } } /// /// ToolTip component /// [Browsable(true)] [Description("ToolTip component.")] public ToolTip ToolTip { get; set; } /// /// Color of bookmarks /// [Browsable(true)] [DefaultValue(typeof (Color), "PowderBlue")] [Description("Color of bookmarks.")] public Color BookmarkColor { get; set; } /// /// Bookmarks /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] public BaseBookmarks Bookmarks { get { return bookmarks; } set { bookmarks = value; } } /// /// Enables virtual spaces /// [DefaultValue(false)] [Description("Enables virtual spaces.")] public bool VirtualSpace { get; set; } /// /// Strategy of search of end of folding block /// [DefaultValue(FindEndOfFoldingBlockStrategy.Strategy1)] [Description("Strategy of search of end of folding block.")] public FindEndOfFoldingBlockStrategy FindEndOfFoldingBlockStrategy { get; set; } /// /// Indicates if tab characters are accepted as input /// [DefaultValue(true)] [Description("Indicates if tab characters are accepted as input.")] public bool AcceptsTab { get; set; } /// /// Indicates if return characters are accepted as input /// [DefaultValue(true)] [Description("Indicates if return characters are accepted as input.")] public bool AcceptsReturn { get; set; } /// /// Shows or hides the caret /// [DefaultValue(true)] [Description("Shows or hides the caret")] public bool CaretVisible { get { return caretVisible; } set { caretVisible = value; Invalidate(); } } /// /// Enables caret blinking /// [DefaultValue(true)] [Description("Enables caret blinking")] public bool CaretBlinking { get; set; } Color textAreaBorderColor; /// /// Color of border of text area /// [DefaultValue(typeof(Color), "Black")] [Description("Color of border of text area")] public Color TextAreaBorderColor { get { return textAreaBorderColor; } set { textAreaBorderColor = value; Invalidate(); } } TextAreaBorderType textAreaBorder; /// /// Type of border of text area /// [DefaultValue(typeof(TextAreaBorderType), "None")] [Description("Type of border of text area")] public TextAreaBorderType TextAreaBorder { get { return textAreaBorder; } set { textAreaBorder = value; Invalidate(); } } /// /// Background color for current line /// [DefaultValue(typeof (Color), "Transparent")] [Description("Background color for current line. Set to Color.Transparent to hide current line highlighting")] public Color CurrentLineColor { get { return currentLineColor; } set { currentLineColor = value; Invalidate(); } } /// /// Background color for highlighting of changed lines /// [DefaultValue(typeof (Color), "Transparent")] [Description("Background color for highlighting of changed lines. Set to Color.Transparent to hide changed line highlighting")] public Color ChangedLineColor { get { return changedLineColor; } set { changedLineColor = value; Invalidate(); } } /// /// Fore color (default style color) /// public override Color ForeColor { get { return base.ForeColor; } set { base.ForeColor = value; lines.InitDefaultStyle(); Invalidate(); } } /// /// Height of char in pixels (includes LineInterval) /// [Browsable(false)] public int CharHeight { get { return charHeight; } set { charHeight = value; NeedRecalc(); OnCharSizeChanged(); } } /// /// Interval between lines (in pixels) /// [Description("Interval between lines in pixels")] [DefaultValue(0)] public int LineInterval { get { return lineInterval; } set { lineInterval = value; SetFont(Font); Invalidate(); } } /// /// Width of char in pixels /// [Browsable(false)] public int CharWidth { get; set; } /// /// Spaces count for tab /// [DefaultValue(4)] [Description("Spaces count for tab")] public int TabLength { get; set; } /// /// Text was changed /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsChanged { get { return isChanged; } set { if (!value) //clear line's IsChanged property lines.ClearIsChanged(); isChanged = value; } } /// /// Text version /// /// This counter is incremented each time changes the text [Browsable(false)] public int TextVersion { get; private set; } /// /// Read only /// [DefaultValue(false)] public bool ReadOnly { get; set; } /// /// Shows line numbers. /// [DefaultValue(true)] [Description("Shows line numbers.")] public bool ShowLineNumbers { get { return showLineNumbers; } set { showLineNumbers = value; NeedRecalc(); Invalidate(); } } /// /// Shows vertical lines between folding start line and folding end line. /// [DefaultValue(false)] [Description("Shows vertical lines between folding start line and folding end line.")] public bool ShowFoldingLines { get { return showFoldingLines; } set { showFoldingLines = value; Invalidate(); } } /// /// Rectangle where located text /// [Browsable(false)] public Rectangle TextAreaRect { get { int rightPaddingStartX = LeftIndent + maxLineLength * CharWidth + Paddings.Left + 1; rightPaddingStartX = Math.Max(ClientSize.Width - Paddings.Right, rightPaddingStartX); int bottomPaddingStartY = TextHeight + Paddings.Top; bottomPaddingStartY = Math.Max(ClientSize.Height - Paddings.Bottom, bottomPaddingStartY); var top = Math.Max(0, Paddings.Top - 1) - VerticalScroll.Value; var left = LeftIndent - HorizontalScroll.Value - 2 + Math.Max(0, Paddings.Left - 1); var rect = Rectangle.FromLTRB(left, top, rightPaddingStartX - HorizontalScroll.Value, bottomPaddingStartY - VerticalScroll.Value); return rect; } } /// /// Color of line numbers. /// [DefaultValue(typeof (Color), "Teal")] [Description("Color of line numbers.")] public Color LineNumberColor { get { return lineNumberColor; } set { lineNumberColor = value; Invalidate(); } } /// /// Start value of first line number. /// [DefaultValue(typeof (uint), "1")] [Description("Start value of first line number.")] public uint LineNumberStartValue { get { return lineNumberStartValue; } set { lineNumberStartValue = value; needRecalc = true; Invalidate(); } } /// /// Background color of indent area /// [DefaultValue(typeof(Color), "WhiteSmoke")] [Description("Background color of indent area")] public Color IndentBackColor { get { return indentBackColor; } set { indentBackColor = value; Invalidate(); } } /// /// Background color of padding area /// [DefaultValue(typeof (Color), "Transparent")] [Description("Background color of padding area")] public Color PaddingBackColor { get { return paddingBackColor; } set { paddingBackColor = value; Invalidate(); } } /// /// Color of disabled component /// [DefaultValue(typeof (Color), "100;180;180;180")] [Description("Color of disabled component")] public Color DisabledColor { get; set; } /// /// Color of caret /// [DefaultValue(typeof (Color), "Black")] [Description("Color of caret.")] public Color CaretColor { get; set; } /// /// Wide caret /// [DefaultValue(false)] [Description("Wide caret.")] public bool WideCaret { get; set; } /// /// Color of service lines (folding lines, borders of blocks etc.) /// [DefaultValue(typeof (Color), "Silver")] [Description("Color of service lines (folding lines, borders of blocks etc.)")] public Color ServiceLinesColor { get { return serviceLinesColor; } set { serviceLinesColor = value; Invalidate(); } } /// /// Padings of text area /// [Browsable(true)] [Description("Paddings of text area.")] public Padding Paddings { get; set; } /// /// --Do not use this property-- /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] public new Padding Padding { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } //hide RTL [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)] public new bool RightToLeft { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } /// /// Color of folding area indicator /// [DefaultValue(typeof (Color), "Green")] [Description("Color of folding area indicator.")] public Color FoldingIndicatorColor { get { return foldingIndicatorColor; } set { foldingIndicatorColor = value; Invalidate(); } } /// /// Enables folding indicator (left vertical line between folding bounds) /// [DefaultValue(true)] [Description("Enables folding indicator (left vertical line between folding bounds)")] public bool HighlightFoldingIndicator { get { return highlightFoldingIndicator; } set { highlightFoldingIndicator = value; Invalidate(); } } /// /// Left distance to text beginning /// [Browsable(false)] [Description("Left distance to text beginning.")] public int LeftIndent { get; private set; } /// /// Left padding in pixels /// [DefaultValue(0)] [Description("Width of left service area (in pixels)")] public int LeftPadding { get { return leftPadding; } set { leftPadding = value; Invalidate(); } } /// /// This property draws vertical line after defined char position. /// Set to 0 for disable drawing of vertical line. /// [DefaultValue(0)] [Description("This property draws vertical line after defined char position. Set to 0 for disable drawing of vertical line.")] public int PreferredLineWidth { get { return preferredLineWidth; } set { preferredLineWidth = value; Invalidate(); } } /// /// Styles /// [Browsable(false)] public Style[] Styles { get { return lines.Styles; } } /// /// Hotkeys. Do not use this property in your code, use HotkeysMapping property. /// [Description("Here you can change hotkeys for FastColoredTextBox.")] [Editor(typeof(HotkeysEditor), typeof(UITypeEditor))] [DefaultValue("Tab=IndentIncrease, Escape=ClearHints, PgUp=GoPageUp, PgDn=GoPageDown, End=GoEnd, Home=GoHome, Left=GoLeft, Up=GoUp, Right=GoRight, Down=GoDown, Ins=ReplaceMode, Del=DeleteCharRight, F3=FindNext, Shift+Tab=IndentDecrease, Shift+PgUp=GoPageUpWithSelection, Shift+PgDn=GoPageDownWithSelection, Shift+End=GoEndWithSelection, Shift+Home=GoHomeWithSelection, Shift+Left=GoLeftWithSelection, Shift+Up=GoUpWithSelection, Shift+Right=GoRightWithSelection, Shift+Down=GoDownWithSelection, Shift+Ins=Paste, Shift+Del=Cut, Ctrl+Back=ClearWordLeft, Ctrl+Space=AutocompleteMenu, Ctrl+End=GoLastLine, Ctrl+Home=GoFirstLine, Ctrl+Left=GoWordLeft, Ctrl+Up=ScrollUp, Ctrl+Right=GoWordRight, Ctrl+Down=ScrollDown, Ctrl+Ins=Copy, Ctrl+Del=ClearWordRight, Ctrl+0=ZoomNormal, Ctrl+A=SelectAll, Ctrl+B=BookmarkLine, Ctrl+C=Copy, Ctrl+E=MacroExecute, Ctrl+F=FindDialog, Ctrl+G=GoToDialog, Ctrl+H=ReplaceDialog, Ctrl+I=AutoIndentChars, Ctrl+M=MacroRecord, Ctrl+N=GoNextBookmark, Ctrl+R=Redo, Ctrl+U=UpperCase, Ctrl+V=Paste, Ctrl+X=Cut, Ctrl+Z=Undo, Ctrl+Add=ZoomIn, Ctrl+Subtract=ZoomOut, Ctrl+OemMinus=NavigateBackward, Ctrl+Shift+End=GoLastLineWithSelection, Ctrl+Shift+Home=GoFirstLineWithSelection, Ctrl+Shift+Left=GoWordLeftWithSelection, Ctrl+Shift+Right=GoWordRightWithSelection, Ctrl+Shift+B=UnbookmarkLine, Ctrl+Shift+C=CommentSelected, Ctrl+Shift+N=GoPrevBookmark, Ctrl+Shift+U=LowerCase, Ctrl+Shift+OemMinus=NavigateForward, Alt+Back=Undo, Alt+Up=MoveSelectedLinesUp, Alt+Down=MoveSelectedLinesDown, Alt+F=FindChar, Alt+Shift+Left=GoLeft_ColumnSelectionMode, Alt+Shift+Up=GoUp_ColumnSelectionMode, Alt+Shift+Right=GoRight_ColumnSelectionMode, Alt+Shift+Down=GoDown_ColumnSelectionMode")] public string Hotkeys { get { return HotkeysMapping.ToString(); } set { HotkeysMapping = HotkeysMapping.Parse(value); } } /// /// Hotkeys mapping /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public HotkeysMapping HotkeysMapping{ get; set;} /// /// Default text style /// This style is using when no one other TextStyle is not defined in Char.style /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public TextStyle DefaultStyle { get { return lines.DefaultStyle; } set { lines.DefaultStyle = value; } } /// /// Style for rendering Selection area /// [Browsable(false)] public SelectionStyle SelectionStyle { get; set; } /// /// Style for folded block rendering /// [Browsable(false)] public TextStyle FoldedBlockStyle { get; set; } /// /// Style for brackets highlighting /// [Browsable(false)] public MarkerStyle BracketsStyle { get; set; } /// /// Style for alternative brackets highlighting /// [Browsable(false)] public MarkerStyle BracketsStyle2 { get; set; } /// /// Opening bracket for brackets highlighting. /// Set to '\x0' for disable brackets highlighting. /// [DefaultValue('\x0')] [Description("Opening bracket for brackets highlighting. Set to '\\x0' for disable brackets highlighting.")] public char LeftBracket { get; set; } /// /// Closing bracket for brackets highlighting. /// Set to '\x0' for disable brackets highlighting. /// [DefaultValue('\x0')] [Description("Closing bracket for brackets highlighting. Set to '\\x0' for disable brackets highlighting.")] public char RightBracket { get; set; } /// /// Alternative opening bracket for brackets highlighting. /// Set to '\x0' for disable brackets highlighting. /// [DefaultValue('\x0')] [Description("Alternative opening bracket for brackets highlighting. Set to '\\x0' for disable brackets highlighting.")] public char LeftBracket2 { get; set; } /// /// Alternative closing bracket for brackets highlighting. /// Set to '\x0' for disable brackets highlighting. /// [DefaultValue('\x0')] [Description("Alternative closing bracket for brackets highlighting. Set to '\\x0' for disable brackets highlighting.")] public char RightBracket2 { get; set; } /// /// Comment line prefix. /// [DefaultValue("//")] [Description("Comment line prefix.")] public string CommentPrefix { get; set; } /// /// This property specifies which part of the text will be highlighted as you type (by built-in highlighter). /// /// When a user enters text, a component refreshes highlighting (because the text was changed). /// This property specifies exactly which section of the text will be re-highlighted. /// This can be useful to highlight multi-line comments, for example. [DefaultValue(typeof (HighlightingRangeType), "ChangedRange")] [Description("This property specifies which part of the text will be highlighted as you type.")] public HighlightingRangeType HighlightingRangeType { get; set; } /// /// Is keyboard in replace mode (wide caret) ? /// [Browsable(false)] public bool IsReplaceMode { get { return isReplaceMode && Selection.IsEmpty && (!Selection.ColumnSelectionMode) && Selection.Start.iChar < lines[Selection.Start.iLine].Count; } set { isReplaceMode = value; } } /// /// Allows text rendering several styles same time. /// [Browsable(true)] [DefaultValue(false)] [Description("Allows text rendering several styles same time.")] public bool AllowSeveralTextStyleDrawing { get; set; } /// /// Allows to record macros. /// [Browsable(true)] [DefaultValue(true)] [Description("Allows to record macros.")] public bool AllowMacroRecording { get { return macrosManager.AllowMacroRecordingByUser; } set { macrosManager.AllowMacroRecordingByUser = value; } } /// /// Allows AutoIndent. Inserts spaces before new line. /// [DefaultValue(true)] [Description("Allows auto indent. Inserts spaces before line chars.")] public bool AutoIndent { get; set; } /// /// Does autoindenting in existing lines. It works only if AutoIndent is True. /// [DefaultValue(true)] [Description("Does autoindenting in existing lines. It works only if AutoIndent is True.")] public bool AutoIndentExistingLines { get; set; } /// /// Minimal delay(ms) for delayed events (except TextChangedDelayed). /// [Browsable(true)] [DefaultValue(100)] [Description("Minimal delay(ms) for delayed events (except TextChangedDelayed).")] public int DelayedEventsInterval { get { return timer.Interval; } set { timer.Interval = value; } } /// /// Minimal delay(ms) for TextChangedDelayed event. /// [Browsable(true)] [DefaultValue(100)] [Description("Minimal delay(ms) for TextChangedDelayed event.")] public int DelayedTextChangedInterval { get { return timer2.Interval; } set { timer2.Interval = value; } } /// /// Language for highlighting by built-in highlighter. /// [Browsable(true)] [DefaultValue(typeof (Language), "Custom")] [Description("Language for highlighting by built-in highlighter.")] public Language Language { get { return language; } set { language = value; if (SyntaxHighlighter != null) SyntaxHighlighter.InitStyleSchema(language); Invalidate(); } } /// /// Syntax Highlighter /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public SyntaxHighlighter SyntaxHighlighter { get; set; } /// /// XML file with description of syntax highlighting. /// This property works only with Language == Language.Custom. /// [Browsable(true)] [DefaultValue(null)] [Editor(typeof (FileNameEditor), typeof (UITypeEditor))] [Description( "XML file with description of syntax highlighting. This property works only with Language == Language.Custom." )] public string DescriptionFile { get { return descriptionFile; } set { descriptionFile = value; Invalidate(); } } /// /// Position of left highlighted bracket. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Range LeftBracketPosition { get { return leftBracketPosition; } } /// /// Position of right highlighted bracket. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Range RightBracketPosition { get { return rightBracketPosition; } } /// /// Position of left highlighted alternative bracket. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Range LeftBracketPosition2 { get { return leftBracketPosition2; } } /// /// Position of right highlighted alternative bracket. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Range RightBracketPosition2 { get { return rightBracketPosition2; } } /// /// Start line index of current highlighted folding area. Return -1 if start of area is not found. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int StartFoldingLine { get { return startFoldingLine; } } /// /// End line index of current highlighted folding area. Return -1 if end of area is not found. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int EndFoldingLine { get { return endFoldingLine; } } /// /// TextSource /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public TextSource TextSource { get { return lines; } set { InitTextSource(value); } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool HasSourceTextBox { get { return SourceTextBox != null; } } /// /// The source of the text. /// Allows to get text from other FastColoredTextBox. /// [Browsable(true)] [DefaultValue(null)] [Description("Allows to get text from other FastColoredTextBox.")] //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public FastColoredTextBox SourceTextBox { get { return sourceTextBox; } set { if (value == sourceTextBox) return; sourceTextBox = value; if (sourceTextBox == null) { InitTextSource(CreateTextSource()); lines.InsertLine(0, TextSource.CreateLine()); IsChanged = false; } else { InitTextSource(SourceTextBox.TextSource); isChanged = false; } Invalidate(); } } /// /// Returns current visible range of text /// [Browsable(false)] public Range VisibleRange { get { if (visibleRange != null) return visibleRange; return GetRange( PointToPlace(new Point(LeftIndent, 0)), PointToPlace(new Point(ClientSize.Width, ClientSize.Height)) ); } } /// /// Current selection range /// [Browsable(false)] public Range Selection { get { return selection; } set { if (value == selection) return; selection.BeginUpdate(); selection.Start = value.Start; selection.End = value.End; selection.EndUpdate(); Invalidate(); } } /// /// Background color. /// It is used if BackBrush is null. /// [DefaultValue(typeof (Color), "White")] [Description("Background color.")] public override Color BackColor { get { return base.BackColor; } set { base.BackColor = value; } } /// /// Background brush. /// If Null then BackColor is used. /// [Browsable(false)] public Brush BackBrush { get { return backBrush; } set { backBrush = value; Invalidate(); } } [Browsable(true)] [DefaultValue(true)] [Description("Scollbars visibility.")] public bool ShowScrollBars { get { return scrollBars; } set { if (value == scrollBars) return; scrollBars = value; needRecalc = true; Invalidate(); } } /// /// Multiline /// [Browsable(true)] [DefaultValue(true)] [Description("Multiline mode.")] public bool Multiline { get { return multiline; } set { if (multiline == value) return; multiline = value; needRecalc = true; if (multiline) { base.AutoScroll = true; ShowScrollBars = true; } else { base.AutoScroll = false; ShowScrollBars = false; if (lines.Count > 1) lines.RemoveLine(1, lines.Count - 1); lines.Manager.ClearHistory(); } Invalidate(); } } /// /// WordWrap. /// [Browsable(true)] [DefaultValue(false)] [Description("WordWrap.")] public bool WordWrap { get { return wordWrap; } set { if (wordWrap == value) return; wordWrap = value; if (wordWrap) Selection.ColumnSelectionMode = false; NeedRecalc(false, true); //RecalcWordWrap(0, LinesCount - 1); Invalidate(); } } /// /// WordWrap mode. /// [Browsable(true)] [DefaultValue(typeof (WordWrapMode), "WordWrapControlWidth")] [Description("WordWrap mode.")] public WordWrapMode WordWrapMode { get { return wordWrapMode; } set { if (wordWrapMode == value) return; wordWrapMode = value; NeedRecalc(false, true); //RecalcWordWrap(0, LinesCount - 1); Invalidate(); } } private bool selectionHighlightingForLineBreaksEnabled; /// /// If true then line breaks included into the selection will be selected too. /// Then line breaks will be shown as selected blank character. /// [DefaultValue(true)] [Description("If enabled then line ends included into the selection will be selected too. " + "Then line ends will be shown as selected blank character.")] public bool SelectionHighlightingForLineBreaksEnabled { get { return selectionHighlightingForLineBreaksEnabled; } set { selectionHighlightingForLineBreaksEnabled = value; Invalidate(); } } [Browsable(false)] public FindForm findForm { get; private set; } [Browsable(false)] public ReplaceForm replaceForm { get; private set; } /// /// Do not change this property /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override bool AutoScroll { get { return base.AutoScroll; } set { ; } } /// /// Count of lines /// [Browsable(false)] public int LinesCount { get { return lines.Count; } } /// /// Gets or sets char and styleId for given place /// This property does not fire OnTextChanged event /// public Char this[Place place] { get { return lines[place.iLine][place.iChar]; } set { lines[place.iLine][place.iChar] = value; } } /// /// Gets Line /// public Line this[int iLine] { get { return lines[iLine]; } } /// /// Text of control /// [Browsable(true)] [Localizable(true)] [Editor( "System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" , typeof (UITypeEditor))] [SettingsBindable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [Description("Text of the control.")] [Bindable(true)] public override string Text { get { if (LinesCount == 0) return ""; var sel = new Range(this); sel.SelectAll(); return sel.Text; } set { if (value == Text && value != "") return; SetAsCurrentTB(); Selection.ColumnSelectionMode = false; Selection.BeginUpdate(); try { Selection.SelectAll(); InsertText(value); GoHome(); } finally { Selection.EndUpdate(); } } } /// /// Text lines /// [Browsable(false)] public IList Lines { get { return lines.GetLines(); } } /// /// Gets colored text as HTML /// /// For more flexibility you can use ExportToHTML class also [Browsable(false)] public string Html { get { var exporter = new ExportToHTML(); exporter.UseNbsp = false; exporter.UseStyleTag = false; exporter.UseBr = false; return "
" + exporter.GetHtml(this) + "
"; } } /// /// Gets colored text as RTF /// /// For more flexibility you can use ExportToRTF class also [Browsable(false)] public string Rtf { get { var exporter = new ExportToRTF(); return exporter.GetRtf(this); } } /// /// Text of current selection /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string SelectedText { get { return Selection.Text; } set { InsertText(value); } } /// /// Start position of selection /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int SelectionStart { get { return Math.Min(PlaceToPosition(Selection.Start), PlaceToPosition(Selection.End)); } set { Selection.Start = PositionToPlace(value); } } /// /// Length of selected text /// [Browsable(false)] [DefaultValue(0)] public int SelectionLength { get { return Math.Abs(PlaceToPosition(Selection.Start) - PlaceToPosition(Selection.End)); } set { if (value > 0) Selection.End = PositionToPlace(SelectionStart + value); } } /// /// Font /// /// Use only monospaced font [DefaultValue(typeof (Font), "Courier New, 9.75")] public override Font Font { get { return BaseFont; } set { originalFont = (Font)value.Clone(); SetFont(value); } } Font baseFont; /// /// Font /// /// Use only monospaced font [DefaultValue(typeof(Font), "Courier New, 9.75")] private Font BaseFont { get { return baseFont; } set { baseFont = value; } } private void SetFont(Font newFont) { BaseFont = newFont; //check monospace font SizeF sizeM = GetCharSize(BaseFont, 'M'); SizeF sizeDot = GetCharSize(BaseFont, '.'); if (sizeM != sizeDot) BaseFont = new Font("Courier New", BaseFont.SizeInPoints, FontStyle.Regular, GraphicsUnit.Point); //clac size SizeF size = GetCharSize(BaseFont, 'M'); CharWidth = (int) Math.Round(size.Width*1f /*0.85*/) - 1 /*0*/; CharHeight = lineInterval + (int) Math.Round(size.Height*1f /*0.9*/) - 1 /*0*/; // //if (wordWrap) // RecalcWordWrap(0, Lines.Count - 1); NeedRecalc(false, wordWrap); // Invalidate(); } public new Size AutoScrollMinSize { set { if (scrollBars) { if (!base.AutoScroll) base.AutoScroll = true; Size newSize = value; if (WordWrap && WordWrapMode != FastColoredTextBoxNS.WordWrapMode.Custom) { int maxWidth = GetMaxLineWordWrapedWidth(); newSize = new Size(Math.Min(newSize.Width, maxWidth), newSize.Height); } base.AutoScrollMinSize = newSize; } else { if (base.AutoScroll) base.AutoScroll = false; base.AutoScrollMinSize = new Size(0, 0); VerticalScroll.Visible = false; HorizontalScroll.Visible = false; VerticalScroll.Maximum = Math.Max(0, value.Height - ClientSize.Height); HorizontalScroll.Maximum = Math.Max(0, value.Width - ClientSize.Width); localAutoScrollMinSize = value; } } get { if (scrollBars) return base.AutoScrollMinSize; else //return new Size(HorizontalScroll.Maximum, VerticalScroll.Maximum); return localAutoScrollMinSize; } } /// /// Indicates that IME is allowed (for CJK language entering) /// [Browsable(false)] public bool ImeAllowed { get { return ImeMode != ImeMode.Disable && ImeMode != ImeMode.Off && ImeMode != ImeMode.NoControl; } } /// /// Is undo enabled? /// [Browsable(false)] public bool UndoEnabled { get { return lines.Manager.UndoEnabled; } } /// /// Is redo enabled? /// [Browsable(false)] public bool RedoEnabled { get { return lines.Manager.RedoEnabled; } } private int LeftIndentLine { get { return LeftIndent - minLeftIndent/2 - 3; } } /// /// Range of all text /// [Browsable(false)] public Range Range { get { return new Range(this, new Place(0, 0), new Place(lines[lines.Count - 1].Count, lines.Count - 1)); } } /// /// Color of selected area /// [DefaultValue(typeof (Color), "Blue")] [Description("Color of selected area.")] public virtual Color SelectionColor { get { return selectionColor; } set { selectionColor = value; if (selectionColor.A == 255) selectionColor = Color.FromArgb(60, selectionColor); SelectionStyle = new SelectionStyle(new SolidBrush(selectionColor)); Invalidate(); } } public override Cursor Cursor { get { return base.Cursor; } set { defaultCursor = value; base.Cursor = value; } } /// /// Reserved space for line number characters. /// If smaller than needed (e. g. line count >= 10 and this value set to 1) this value will have no impact. /// If you want to reserve space, e. g. for line numbers >= 10 or >= 100 than you can set this value to 2 or 3 or higher. /// [DefaultValue(1)] [Description( "Reserved space for line number characters. If smaller than needed (e. g. line count >= 10 and " + "this value set to 1) this value will have no impact. If you want to reserve space, e. g. for line " + "numbers >= 10 or >= 100, than you can set this value to 2 or 3 or higher.")] public int ReservedCountOfLineNumberChars { get { return reservedCountOfLineNumberChars; } set { reservedCountOfLineNumberChars = value; NeedRecalc(); Invalidate(); } } /// /// Occurs when mouse is moving over text and tooltip is needed /// [Browsable(true)] [Description("Occurs when mouse is moving over text and tooltip is needed.")] public event EventHandler ToolTipNeeded; /// /// Removes all hints /// public void ClearHints() { if (Hints != null) Hints.Clear(); } /// /// Add and shows the hint /// /// Linked range /// Inner control /// Scrolls textbox to the hint /// Inlining. If True then hint will moves apart text /// Docking. If True then hint will fill whole line public virtual Hint AddHint(Range range, Control innerControl, bool scrollToHint, bool inline, bool dock) { var hint = new Hint(range, innerControl, inline, dock); Hints.Add(hint); if (scrollToHint) hint.DoVisible(); return hint; } /// /// Add and shows the hint /// /// Linked range /// Inner control public Hint AddHint(Range range, Control innerControl) { return AddHint(range, innerControl, true, true, true); } /// /// Add and shows simple text hint /// /// Linked range /// Text of simple hint /// Scrolls textbox to the hint /// Inlining. If True then hint will moves apart text /// Docking. If True then hint will fill whole line public virtual Hint AddHint(Range range, string text, bool scrollToHint, bool inline, bool dock) { var hint = new Hint(range, text, inline, dock); Hints.Add(hint); if (scrollToHint) hint.DoVisible(); return hint; } /// /// Add and shows simple text hint /// /// Linked range /// Text of simple hint public Hint AddHint(Range range, string text) { return AddHint(range, text, true, true, true); } /// /// Occurs when user click on the hint /// /// public virtual void OnHintClick(Hint hint) { if (HintClick != null) HintClick(this, new HintClickEventArgs(hint)); } private void timer3_Tick(object sender, EventArgs e) { timer3.Stop(); OnToolTip(); } protected virtual void OnToolTip() { if (ToolTip == null) return; if (ToolTipNeeded == null) return; //get place under mouse Place place = PointToPlace(lastMouseCoord); //check distance Point p = PlaceToPoint(place); if (Math.Abs(p.X - lastMouseCoord.X) > CharWidth*2 || Math.Abs(p.Y - lastMouseCoord.Y) > CharHeight*2) return; //get word under mouse var r = new Range(this, place, place); string hoveredWord = r.GetFragment("[a-zA-Z]").Text; //event handler var ea = new ToolTipNeededEventArgs(place, hoveredWord); ToolTipNeeded(this, ea); if (ea.ToolTipText != null) { //show tooltip ToolTip.ToolTipTitle = ea.ToolTipTitle; ToolTip.ToolTipIcon = ea.ToolTipIcon; //ToolTip.SetToolTip(this, ea.ToolTipText); ToolTip.Show(ea.ToolTipText, this, new Point(lastMouseCoord.X, lastMouseCoord.Y + CharHeight)); } } /// /// Occurs when VisibleRange is changed /// public virtual void OnVisibleRangeChanged() { needRecalcFoldingLines = true; needRiseVisibleRangeChangedDelayed = true; ResetTimer(timer); if (VisibleRangeChanged != null) VisibleRangeChanged(this, new EventArgs()); } /// /// Invalidates the entire surface of the control and causes the control to be redrawn. /// This method is thread safe and does not require Invoke. /// public new void Invalidate() { if (InvokeRequired) BeginInvoke(new MethodInvoker(Invalidate)); else base.Invalidate(); } protected virtual void OnCharSizeChanged() { VerticalScroll.SmallChange = charHeight; VerticalScroll.LargeChange = 10*charHeight; HorizontalScroll.SmallChange = CharWidth; } /// /// HintClick event. /// It occurs if user click on the hint. /// [Browsable(true)] [Description("It occurs if user click on the hint.")] public event EventHandler HintClick; /// /// TextChanged event. /// It occurs after insert, delete, clear, undo and redo operations. /// [Browsable(true)] [Description("It occurs after insert, delete, clear, undo and redo operations.")] public new event EventHandler TextChanged; /// /// Fake event for correct data binding /// [Browsable(false)] internal event EventHandler BindingTextChanged; /// /// Occurs when user paste text from clipboard /// [Description("Occurs when user paste text from clipboard")] public event EventHandler Pasting; /// /// TextChanging event. /// It occurs before insert, delete, clear, undo and redo operations. /// [Browsable(true)] [Description("It occurs before insert, delete, clear, undo and redo operations.")] public event EventHandler TextChanging; /// /// SelectionChanged event. /// It occurs after changing of selection. /// [Browsable(true)] [Description("It occurs after changing of selection.")] public event EventHandler SelectionChanged; /// /// VisibleRangeChanged event. /// It occurs after changing of visible range. /// [Browsable(true)] [Description("It occurs after changing of visible range.")] public event EventHandler VisibleRangeChanged; /// /// TextChangedDelayed event. /// It occurs after insert, delete, clear, undo and redo operations. /// This event occurs with a delay relative to TextChanged, and fires only once. /// [Browsable(true)] [Description( "It occurs after insert, delete, clear, undo and redo operations. This event occurs with a delay relative to TextChanged, and fires only once." )] public event EventHandler TextChangedDelayed; /// /// SelectionChangedDelayed event. /// It occurs after changing of selection. /// This event occurs with a delay relative to SelectionChanged, and fires only once. /// [Browsable(true)] [Description( "It occurs after changing of selection. This event occurs with a delay relative to SelectionChanged, and fires only once." )] public event EventHandler SelectionChangedDelayed; /// /// VisibleRangeChangedDelayed event. /// It occurs after changing of visible range. /// This event occurs with a delay relative to VisibleRangeChanged, and fires only once. /// [Browsable(true)] [Description( "It occurs after changing of visible range. This event occurs with a delay relative to VisibleRangeChanged, and fires only once." )] public event EventHandler VisibleRangeChangedDelayed; /// /// It occurs when user click on VisualMarker. /// [Browsable(true)] [Description("It occurs when user click on VisualMarker.")] public event EventHandler VisualMarkerClick; /// /// It occurs when visible char is enetering (alphabetic, digit, punctuation, DEL, BACKSPACE) /// /// Set Handle to True for cancel key [Browsable(true)] [Description("It occurs when visible char is enetering (alphabetic, digit, punctuation, DEL, BACKSPACE).")] public event KeyPressEventHandler KeyPressing; /// /// It occurs when visible char is enetered (alphabetic, digit, punctuation, DEL, BACKSPACE) /// [Browsable(true)] [Description("It occurs when visible char is enetered (alphabetic, digit, punctuation, DEL, BACKSPACE).")] public event KeyPressEventHandler KeyPressed; /// /// It occurs when calculates AutoIndent for new line /// [Browsable(true)] [Description("It occurs when calculates AutoIndent for new line.")] public event EventHandler AutoIndentNeeded; /// /// It occurs when line background is painting /// [Browsable(true)] [Description("It occurs when line background is painting.")] public event EventHandler PaintLine; /// /// Occurs when line was inserted/added /// [Browsable(true)] [Description("Occurs when line was inserted/added.")] public event EventHandler LineInserted; /// /// Occurs when line was removed /// [Browsable(true)] [Description("Occurs when line was removed.")] public event EventHandler LineRemoved; /// /// Occurs when current highlighted folding area is changed. /// Current folding area see in StartFoldingLine and EndFoldingLine. /// /// [Browsable(true)] [Description("Occurs when current highlighted folding area is changed.")] public event EventHandler FoldingHighlightChanged; /// /// Occurs when undo/redo stack is changed /// /// [Browsable(true)] [Description("Occurs when undo/redo stack is changed.")] public event EventHandler UndoRedoStateChanged; /// /// Occurs when component was zoomed /// [Browsable(true)] [Description("Occurs when component was zoomed.")] public event EventHandler ZoomChanged; /// /// Occurs when user pressed key, that specified as CustomAction /// [Browsable(true)] [Description("Occurs when user pressed key, that specified as CustomAction.")] public event EventHandler CustomAction; /// /// Occurs when scroolbars are updated /// [Browsable(true)] [Description("Occurs when scroolbars are updated.")] public event EventHandler ScrollbarsUpdated; /// /// Occurs when custom wordwrap is needed /// [Browsable(true)] [Description("Occurs when custom wordwrap is needed.")] public event EventHandler WordWrapNeeded; /// /// Returns list of styles of given place /// public List