Добавьте файлы проекта.

This commit is contained in:
gituser
2026-04-11 19:34:51 +03:00
parent 698a2088a5
commit 744331b4bb
312 changed files with 57691 additions and 0 deletions

25
MenuGenerator.sln Normal file
View File

@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36119.2 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MenuGenerator", "MenuGenerator\MenuGenerator.csproj", "{1E315396-8A27-49D6-A452-45D47A40CABC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1E315396-8A27-49D6-A452-45D47A40CABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E315396-8A27-49D6-A452-45D47A40CABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E315396-8A27-49D6-A452-45D47A40CABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E315396-8A27-49D6-A452-45D47A40CABC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3FA41CD-B1C2-4105-8ADD-CCDDD2DB3AD1}
EndGlobalSection
EndGlobal

6
MenuGenerator/App.config Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />
</startup>
</configuration>

View File

@@ -0,0 +1,108 @@
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
[Bb]in/
[Oo]bj/
# mstest test results
TestResults
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.log
*.vspscc
*.vssscc
.builds
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
packages
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
[Bb]in
[Oo]bj
sql
TestResults
[Tt]est[Rr]esult*
*.Cache
ClientBin
[Ss]tyle[Cc]op.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
<doc>
<brackets left="&lt;" right="&gt;" />
<style name="Maroon" color="Maroon" fontStyle="Bold,Italic" />
<style name="Blue" color="Blue"/>
<style name="Red" color="Red" backColor="#f5f5e5" />
<style name="Green" color="Green" />
<rule style="Green" options="Singleline">(&lt;!--.*?--&gt;)|(&lt;!--.*)</rule>
<rule style="Green" options="Singleline,RightToLeft">(&lt;!--.*?--&gt;)|(.*--&gt;)</rule>
<rule style="Blue">&lt;|/&gt;|&lt;/|&gt;</rule>
<rule style="Blue">&lt;|/&gt;|&lt;/|&gt;</rule>
<rule style="Maroon">&lt;(?&lt;range&gt;[!\w\d]+)</rule>
<rule style="Maroon">&lt;/(?&lt;range&gt;[\w\d]+)&gt;</rule>
<rule style="Red" options="Multiline">(?&lt;range&gt;\S+?)='[^']*'|(?&lt;range&gt;\S+)="[^"]*"|(?&lt;range&gt;\S+)=\S+</rule>
<folding start="&lt;div" finish="&lt;/div&gt;" options="IgnoreCase"/>
</doc>

View File

@@ -0,0 +1,54 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tester", "Tester\Tester.csproj", "{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastColoredTextBox", "FastColoredTextBox\FastColoredTextBox.csproj", "{6DD14A85-CCFC-4774-BD26-0F5772512319}"
EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "TesterVB", "TesterVB\TesterVB.vbproj", "{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|Any CPU.ActiveCfg = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|Mixed Platforms.Build.0 = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|x86.ActiveCfg = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|x86.Build.0 = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|Any CPU.ActiveCfg = Release|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|Mixed Platforms.ActiveCfg = Release|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|Mixed Platforms.Build.0 = Release|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|x86.ActiveCfg = Release|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|x86.Build.0 = Release|x86
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|x86.ActiveCfg = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|Any CPU.Build.0 = Release|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|x86.ActiveCfg = Release|Any CPU
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Debug|Any CPU.ActiveCfg = Debug|x86
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Debug|Mixed Platforms.Build.0 = Debug|x86
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Debug|x86.ActiveCfg = Debug|x86
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Debug|x86.Build.0 = Debug|x86
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Release|Any CPU.ActiveCfg = Release|x86
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Release|Mixed Platforms.ActiveCfg = Release|x86
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Release|Mixed Platforms.Build.0 = Release|x86
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Release|x86.ActiveCfg = Release|x86
{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,266 @@
using System;
using System.Drawing;
using System.Drawing.Printing;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Item of autocomplete menu
/// </summary>
public class AutocompleteItem
{
public string Text;
public int ImageIndex = -1;
public object Tag;
string toolTipTitle;
string toolTipText;
string menuText;
public AutocompleteMenu Parent { get; internal set; }
public AutocompleteItem()
{
}
public AutocompleteItem(string text)
{
Text = text;
}
public AutocompleteItem(string text, int imageIndex)
: this(text)
{
this.ImageIndex = imageIndex;
}
public AutocompleteItem(string text, int imageIndex, string menuText)
: this(text, imageIndex)
{
this.menuText = menuText;
}
public AutocompleteItem(string text, int imageIndex, string menuText, string toolTipTitle, string toolTipText)
: this(text, imageIndex, menuText)
{
this.toolTipTitle = toolTipTitle;
this.toolTipText = toolTipText;
}
/// <summary>
/// Returns text for inserting into Textbox
/// </summary>
public virtual string GetTextForReplace()
{
return Text;
}
/// <summary>
/// Compares fragment text with this item
/// </summary>
public virtual CompareResult Compare(string fragmentText)
{
if (Text.StartsWith(fragmentText, StringComparison.InvariantCultureIgnoreCase) &&
Text != fragmentText)
return CompareResult.VisibleAndSelected;
return CompareResult.Hidden;
}
/// <summary>
/// Returns text for display into popup menu
/// </summary>
public override string ToString()
{
return menuText ?? Text;
}
/// <summary>
/// This method is called after item inserted into text
/// </summary>
public virtual void OnSelected(AutocompleteMenu popupMenu, SelectedEventArgs e)
{
;
}
/// <summary>
/// Title for tooltip.
/// </summary>
/// <remarks>Return null for disable tooltip for this item</remarks>
public virtual string ToolTipTitle
{
get { return toolTipTitle; }
set { toolTipTitle = value; }
}
/// <summary>
/// Tooltip text.
/// </summary>
/// <remarks>For display tooltip text, ToolTipTitle must be not null</remarks>
public virtual string ToolTipText
{
get{ return toolTipText; }
set { toolTipText = value; }
}
/// <summary>
/// Menu text. This text is displayed in the drop-down menu.
/// </summary>
public virtual string MenuText
{
get { return menuText; }
set { menuText = value; }
}
/// <summary>
/// Fore color of text of item
/// </summary>
public virtual Color ForeColor
{
get { return Color.Transparent; }
set { throw new NotImplementedException("Override this property to change color"); }
}
/// <summary>
/// Back color of item
/// </summary>
public virtual Color BackColor
{
get { return Color.Transparent; }
set { throw new NotImplementedException("Override this property to change color"); }
}
}
public enum CompareResult
{
/// <summary>
/// Item do not appears
/// </summary>
Hidden,
/// <summary>
/// Item appears
/// </summary>
Visible,
/// <summary>
/// Item appears and will selected
/// </summary>
VisibleAndSelected
}
/// <summary>
/// Autocomplete item for code snippets
/// </summary>
/// <remarks>Snippet can contain special char ^ for caret position.</remarks>
public class SnippetAutocompleteItem : AutocompleteItem
{
public SnippetAutocompleteItem(string snippet)
{
Text = snippet.Replace("\r", "");
ToolTipTitle = "Code snippet:";
ToolTipText = Text;
}
public override string ToString()
{
return MenuText ?? Text.Replace("\n", " ").Replace("^", "");
}
public override string GetTextForReplace()
{
return Text;
}
public override void OnSelected(AutocompleteMenu popupMenu, SelectedEventArgs e)
{
e.Tb.BeginUpdate();
e.Tb.Selection.BeginUpdate();
//remember places
var p1 = popupMenu.Fragment.Start;
var p2 = e.Tb.Selection.Start;
//do auto indent
if (e.Tb.AutoIndent)
{
for (int iLine = p1.iLine + 1; iLine <= p2.iLine; iLine++)
{
e.Tb.Selection.Start = new Place(0, iLine);
e.Tb.DoAutoIndent(iLine);
}
}
e.Tb.Selection.Start = p1;
//move caret position right and find char ^
while (e.Tb.Selection.CharBeforeStart != '^')
if (!e.Tb.Selection.GoRightThroughFolded())
break;
//remove char ^
e.Tb.Selection.GoLeft(true);
e.Tb.InsertText("");
//
e.Tb.Selection.EndUpdate();
e.Tb.EndUpdate();
}
/// <summary>
/// Compares fragment text with this item
/// </summary>
public override CompareResult Compare(string fragmentText)
{
if (Text.StartsWith(fragmentText, StringComparison.InvariantCultureIgnoreCase) &&
Text != fragmentText)
return CompareResult.Visible;
return CompareResult.Hidden;
}
}
/// <summary>
/// This autocomplete item appears after dot
/// </summary>
public class MethodAutocompleteItem : AutocompleteItem
{
string firstPart;
string lowercaseText;
public MethodAutocompleteItem(string text)
: base(text)
{
lowercaseText = Text.ToLower();
}
public override CompareResult Compare(string fragmentText)
{
int i = fragmentText.LastIndexOf('.');
if (i < 0)
return CompareResult.Hidden;
string lastPart = fragmentText.Substring(i + 1);
firstPart = fragmentText.Substring(0, i);
if(lastPart=="") return CompareResult.Visible;
if(Text.StartsWith(lastPart, StringComparison.InvariantCultureIgnoreCase))
return CompareResult.VisibleAndSelected;
if(lowercaseText.Contains(lastPart.ToLower()))
return CompareResult.Visible;
return CompareResult.Hidden;
}
public override string GetTextForReplace()
{
return firstPart + "." + Text;
}
}
/// <summary>
/// This Item does not check correspondence to current text fragment.
/// SuggestItem is intended for dynamic menus.
/// </summary>
public class SuggestItem : AutocompleteItem
{
public SuggestItem(string text, int imageIndex):base(text, imageIndex)
{
}
public override CompareResult Compare(string fragmentText)
{
return CompareResult.Visible;
}
}
}

View File

@@ -0,0 +1,792 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using System.Text.RegularExpressions;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Popup menu for autocomplete
/// </summary>
[Browsable(false)]
public class AutocompleteMenu : ToolStripDropDown, IDisposable
{
AutocompleteListView listView;
public ToolStripControlHost host;
public Range Fragment { get; internal set; }
/// <summary>
/// Regex pattern for serach fragment around caret
/// </summary>
public string SearchPattern { get; set; }
/// <summary>
/// Minimum fragment length for popup
/// </summary>
public int MinFragmentLength { get; set; }
/// <summary>
/// User selects item
/// </summary>
public event EventHandler<SelectingEventArgs> Selecting;
/// <summary>
/// It fires after item inserting
/// </summary>
public event EventHandler<SelectedEventArgs> Selected;
/// <summary>
/// Occurs when popup menu is opening
/// </summary>
public new event EventHandler<CancelEventArgs> Opening;
/// <summary>
/// Allow TAB for select menu item
/// </summary>
public bool AllowTabKey { get { return listView.AllowTabKey; } set { listView.AllowTabKey = value; } }
/// <summary>
/// Interval of menu appear (ms)
/// </summary>
public int AppearInterval { get { return listView.AppearInterval; } set { listView.AppearInterval = value; } }
/// <summary>
/// Sets the max tooltip window size
/// </summary>
public Size MaxTooltipSize { get { return listView.MaxToolTipSize; } set { listView.MaxToolTipSize = value; } }
/// <summary>
/// Tooltip will perm show and duration will be ignored
/// </summary>
public bool AlwaysShowTooltip { get { return listView.AlwaysShowTooltip; } set { listView.AlwaysShowTooltip = value; } }
/// <summary>
/// Back color of selected item
/// </summary>
[DefaultValue(typeof(Color), "Orange")]
public Color SelectedColor
{
get { return listView.SelectedColor; }
set { listView.SelectedColor = value; }
}
/// <summary>
/// Border color of hovered item
/// </summary>
[DefaultValue(typeof(Color), "Red")]
public Color HoveredColor
{
get { return listView.HoveredColor; }
set { listView.HoveredColor = value; }
}
public AutocompleteMenu(FastColoredTextBox tb)
{
// create a new popup and add the list view to it
AutoClose = false;
AutoSize = false;
Margin = Padding.Empty;
Padding = Padding.Empty;
BackColor = Color.White;
listView = new AutocompleteListView(tb);
host = new ToolStripControlHost(listView);
host.Margin = new Padding(2, 2, 2, 2);
host.Padding = Padding.Empty;
host.AutoSize = false;
host.AutoToolTip = false;
CalcSize();
base.Items.Add(host);
listView.Parent = this;
SearchPattern = @"[\w\.]";
MinFragmentLength = 2;
}
public new Font Font
{
get { return listView.Font; }
set { listView.Font = value; }
}
new internal void OnOpening(CancelEventArgs args)
{
if (Opening != null)
Opening(this, args);
}
public new void Close()
{
listView.toolTip.Hide(listView);
base.Close();
}
internal void CalcSize()
{
host.Size = listView.Size;
Size = new System.Drawing.Size(listView.Size.Width + 4, listView.Size.Height + 4);
}
public virtual void OnSelecting()
{
listView.OnSelecting();
}
public void SelectNext(int shift)
{
listView.SelectNext(shift);
}
internal void OnSelecting(SelectingEventArgs args)
{
if (Selecting != null)
Selecting(this, args);
}
public void OnSelected(SelectedEventArgs args)
{
if (Selected != null)
Selected(this, args);
}
public new AutocompleteListView Items
{
get { return listView; }
}
/// <summary>
/// Shows popup menu immediately
/// </summary>
/// <param name="forced">If True - MinFragmentLength will be ignored</param>
public void Show(bool forced)
{
Items.DoAutocomplete(forced);
}
/// <summary>
/// Minimal size of menu
/// </summary>
public new Size MinimumSize
{
get { return Items.MinimumSize; }
set { Items.MinimumSize = value; }
}
/// <summary>
/// Image list of menu
/// </summary>
public new ImageList ImageList
{
get { return Items.ImageList; }
set { Items.ImageList = value; }
}
/// <summary>
/// Tooltip duration (ms)
/// </summary>
public int ToolTipDuration
{
get { return Items.ToolTipDuration; }
set { Items.ToolTipDuration = value; }
}
/// <summary>
/// Tooltip
/// </summary>
public ToolTip ToolTip
{
get { return Items.toolTip; }
set { Items.toolTip = value; }
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (listView != null && !listView.IsDisposed)
listView.Dispose();
}
}
[System.ComponentModel.ToolboxItem(false)]
public class AutocompleteListView : UserControl, IDisposable
{
public event EventHandler FocussedItemIndexChanged;
internal List<AutocompleteItem> visibleItems;
IEnumerable<AutocompleteItem> sourceItems = new List<AutocompleteItem>();
int focussedItemIndex = 0;
int hoveredItemIndex = -1;
private int ItemHeight
{
get { return Font.Height + 2; }
}
AutocompleteMenu Menu { get { return Parent as AutocompleteMenu; } }
int oldItemCount = 0;
FastColoredTextBox tb;
internal ToolTip toolTip = new ToolTip();
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
internal bool AllowTabKey { get; set; }
public ImageList ImageList { get; set; }
internal int AppearInterval { get { return timer.Interval; } set { timer.Interval = value; } }
internal int ToolTipDuration { get; set; }
internal Size MaxToolTipSize { get; set; }
internal bool AlwaysShowTooltip
{
get { return toolTip.ShowAlways; }
set { toolTip.ShowAlways = value; }
}
public Color SelectedColor { get; set; }
public Color HoveredColor { get; set; }
public int FocussedItemIndex
{
get { return focussedItemIndex; }
set
{
if (focussedItemIndex != value)
{
focussedItemIndex = value;
if (FocussedItemIndexChanged != null)
FocussedItemIndexChanged(this, EventArgs.Empty);
}
}
}
public AutocompleteItem FocussedItem
{
get
{
if (FocussedItemIndex >= 0 && focussedItemIndex < visibleItems.Count)
return visibleItems[focussedItemIndex];
return null;
}
set
{
FocussedItemIndex = visibleItems.IndexOf(value);
}
}
internal AutocompleteListView(FastColoredTextBox tb)
{
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
base.Font = new Font(FontFamily.GenericSansSerif, 9);
visibleItems = new List<AutocompleteItem>();
VerticalScroll.SmallChange = ItemHeight;
MaximumSize = new Size(Size.Width, 180);
toolTip.ShowAlways = false;
AppearInterval = 500;
timer.Tick += new EventHandler(timer_Tick);
SelectedColor = Color.Orange;
HoveredColor = Color.Red;
ToolTipDuration = 3000;
toolTip.Popup += ToolTip_Popup;
this.tb = tb;
tb.KeyDown += new KeyEventHandler(tb_KeyDown);
tb.SelectionChanged += new EventHandler(tb_SelectionChanged);
tb.KeyPressed += new KeyPressEventHandler(tb_KeyPressed);
Form form = tb.FindForm();
if (form != null)
{
form.LocationChanged += delegate { SafetyClose(); };
form.ResizeBegin += delegate { SafetyClose(); };
form.FormClosing += delegate { SafetyClose(); };
form.LostFocus += delegate { SafetyClose(); };
}
tb.LostFocus += (o, e) =>
{
if (Menu != null && !Menu.IsDisposed)
if (!Menu.Focused)
SafetyClose();
};
tb.Scroll += delegate { SafetyClose(); };
this.VisibleChanged += (o, e) =>
{
if (this.Visible)
DoSelectedVisible();
};
}
private void ToolTip_Popup(object sender, PopupEventArgs e)
{
if (MaxToolTipSize.Height > 0 && MaxToolTipSize.Width > 0)
e.ToolTipSize = MaxToolTipSize;
}
protected override void Dispose(bool disposing)
{
if (toolTip != null)
{
toolTip.Popup -= ToolTip_Popup;
toolTip.Dispose();
}
if (tb != null)
{
tb.KeyDown -= tb_KeyDown;
tb.KeyPressed -= tb_KeyPressed;
tb.SelectionChanged -= tb_SelectionChanged;
}
if (timer != null)
{
timer.Stop();
timer.Tick -= timer_Tick;
timer.Dispose();
}
base.Dispose(disposing);
}
void SafetyClose()
{
if (Menu != null && !Menu.IsDisposed)
Menu.Close();
}
void tb_KeyPressed(object sender, KeyPressEventArgs e)
{
bool backspaceORdel = e.KeyChar == '\b' || e.KeyChar == 0xff;
/*
if (backspaceORdel)
prevSelection = tb.Selection.Start;*/
if (Menu.Visible && !backspaceORdel)
DoAutocomplete(false);
else
ResetTimer(timer);
}
void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
DoAutocomplete(false);
}
void ResetTimer(System.Windows.Forms.Timer timer)
{
timer.Stop();
timer.Start();
}
internal void DoAutocomplete()
{
DoAutocomplete(false);
}
internal void DoAutocomplete(bool forced)
{
if (!Menu.Enabled)
{
Menu.Close();
return;
}
visibleItems.Clear();
FocussedItemIndex = 0;
VerticalScroll.Value = 0;
//some magic for update scrolls
AutoScrollMinSize -= new Size(1, 0);
AutoScrollMinSize += new Size(1, 0);
//get fragment around caret
Range fragment = tb.Selection.GetFragment(Menu.SearchPattern);
string text = fragment.Text;
//calc screen point for popup menu
Point point = tb.PlaceToPoint(fragment.End);
point.Offset(2, tb.CharHeight);
//
if (forced || (text.Length >= Menu.MinFragmentLength
&& tb.Selection.IsEmpty /*pops up only if selected range is empty*/
&& (tb.Selection.Start > fragment.Start || text.Length == 0/*pops up only if caret is after first letter*/)))
{
Menu.Fragment = fragment;
bool foundSelected = false;
//build popup menu
foreach (var item in sourceItems)
{
item.Parent = Menu;
CompareResult res = item.Compare(text);
if(res != CompareResult.Hidden)
visibleItems.Add(item);
if (res == CompareResult.VisibleAndSelected && !foundSelected)
{
foundSelected = true;
FocussedItemIndex = visibleItems.Count - 1;
}
}
if (foundSelected)
{
AdjustScroll();
DoSelectedVisible();
}
}
//show popup menu
if (Count > 0)
{
if (!Menu.Visible)
{
CancelEventArgs args = new CancelEventArgs();
Menu.OnOpening(args);
if(!args.Cancel)
Menu.Show(tb, point);
}
DoSelectedVisible();
Invalidate();
}
else
Menu.Close();
}
void tb_SelectionChanged(object sender, EventArgs e)
{
/*
FastColoredTextBox tb = sender as FastColoredTextBox;
if (Math.Abs(prevSelection.iChar - tb.Selection.Start.iChar) > 1 ||
prevSelection.iLine != tb.Selection.Start.iLine)
Menu.Close();
prevSelection = tb.Selection.Start;*/
if (Menu.Visible)
{
bool needClose = false;
if (!tb.Selection.IsEmpty)
needClose = true;
else
if (!Menu.Fragment.Contains(tb.Selection.Start))
{
if (tb.Selection.Start.iLine == Menu.Fragment.End.iLine && tb.Selection.Start.iChar == Menu.Fragment.End.iChar + 1)
{
//user press key at end of fragment
char c = tb.Selection.CharBeforeStart;
if (!Regex.IsMatch(c.ToString(), Menu.SearchPattern))//check char
needClose = true;
}
else
needClose = true;
}
if (needClose)
Menu.Close();
}
}
void tb_KeyDown(object sender, KeyEventArgs e)
{
var tb = sender as FastColoredTextBox;
if (Menu.Visible)
if (ProcessKey(e.KeyCode, e.Modifiers))
e.Handled = true;
if (!Menu.Visible)
{
if (tb.HotkeysMapping.ContainsKey(e.KeyData) && tb.HotkeysMapping[e.KeyData] == FCTBAction.AutocompleteMenu)
{
DoAutocomplete();
e.Handled = true;
}
else
{
if (e.KeyCode == Keys.Escape && timer.Enabled)
timer.Stop();
}
}
}
void AdjustScroll()
{
if (oldItemCount == visibleItems.Count)
return;
int needHeight = ItemHeight * visibleItems.Count + 1;
Height = Math.Min(needHeight, MaximumSize.Height);
Menu.CalcSize();
AutoScrollMinSize = new Size(0, needHeight);
oldItemCount = visibleItems.Count;
}
protected override void OnPaint(PaintEventArgs e)
{
AdjustScroll();
var itemHeight = ItemHeight;
int startI = VerticalScroll.Value / itemHeight - 1;
int finishI = (VerticalScroll.Value + ClientSize.Height) / itemHeight + 1;
startI = Math.Max(startI, 0);
finishI = Math.Min(finishI, visibleItems.Count);
int y = 0;
int leftPadding = 18;
for (int i = startI; i < finishI; i++)
{
y = i * itemHeight - VerticalScroll.Value;
var item = visibleItems[i];
if(item.BackColor != Color.Transparent)
using (var brush = new SolidBrush(item.BackColor))
e.Graphics.FillRectangle(brush, 1, y, ClientSize.Width - 1 - 1, itemHeight - 1);
if (ImageList != null && visibleItems[i].ImageIndex >= 0)
e.Graphics.DrawImage(ImageList.Images[item.ImageIndex], 1, y);
if (i == FocussedItemIndex)
using (var selectedBrush = new LinearGradientBrush(new Point(0, y - 3), new Point(0, y + itemHeight), Color.Transparent, SelectedColor))
using (var pen = new Pen(SelectedColor))
{
e.Graphics.FillRectangle(selectedBrush, leftPadding, y, ClientSize.Width - 1 - leftPadding, itemHeight - 1);
e.Graphics.DrawRectangle(pen, leftPadding, y, ClientSize.Width - 1 - leftPadding, itemHeight - 1);
}
if (i == hoveredItemIndex)
using(var pen = new Pen(HoveredColor))
e.Graphics.DrawRectangle(pen, leftPadding, y, ClientSize.Width - 1 - leftPadding, itemHeight - 1);
using (var brush = new SolidBrush(item.ForeColor != Color.Transparent ? item.ForeColor : ForeColor))
e.Graphics.DrawString(item.ToString(), Font, brush, leftPadding, y);
}
}
protected override void OnScroll(ScrollEventArgs se)
{
base.OnScroll(se);
Invalidate();
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
FocussedItemIndex = PointToItemIndex(e.Location);
DoSelectedVisible();
Invalidate();
}
}
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
base.OnMouseDoubleClick(e);
FocussedItemIndex = PointToItemIndex(e.Location);
Invalidate();
OnSelecting();
}
internal virtual void OnSelecting()
{
if (FocussedItemIndex < 0 || FocussedItemIndex >= visibleItems.Count)
return;
tb.TextSource.Manager.BeginAutoUndoCommands();
try
{
AutocompleteItem item = FocussedItem;
SelectingEventArgs args = new SelectingEventArgs()
{
Item = item,
SelectedIndex = FocussedItemIndex
};
Menu.OnSelecting(args);
if (args.Cancel)
{
FocussedItemIndex = args.SelectedIndex;
Invalidate();
return;
}
if (!args.Handled)
{
var fragment = Menu.Fragment;
DoAutocomplete(item, fragment);
}
Menu.Close();
//
SelectedEventArgs args2 = new SelectedEventArgs()
{
Item = item,
Tb = Menu.Fragment.tb
};
item.OnSelected(Menu, args2);
Menu.OnSelected(args2);
}
finally
{
tb.TextSource.Manager.EndAutoUndoCommands();
}
}
private void DoAutocomplete(AutocompleteItem item, Range fragment)
{
string newText = item.GetTextForReplace();
//replace text of fragment
var tb = fragment.tb;
tb.BeginAutoUndo();
tb.TextSource.Manager.ExecuteCommand(new SelectCommand(tb.TextSource));
if (tb.Selection.ColumnSelectionMode)
{
var start = tb.Selection.Start;
var end = tb.Selection.End;
start.iChar = fragment.Start.iChar;
end.iChar = fragment.End.iChar;
tb.Selection.Start = start;
tb.Selection.End = end;
}
else
{
tb.Selection.Start = fragment.Start;
tb.Selection.End = fragment.End;
}
tb.InsertText(newText);
tb.TextSource.Manager.ExecuteCommand(new SelectCommand(tb.TextSource));
tb.EndAutoUndo();
tb.Focus();
}
int PointToItemIndex(Point p)
{
return (p.Y + VerticalScroll.Value) / ItemHeight;
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
ProcessKey(keyData, Keys.None);
return base.ProcessCmdKey(ref msg, keyData);
}
private bool ProcessKey(Keys keyData, Keys keyModifiers)
{
if (keyModifiers == Keys.None)
switch (keyData)
{
case Keys.Down:
SelectNext(+1);
return true;
case Keys.PageDown:
SelectNext(+10);
return true;
case Keys.Up:
SelectNext(-1);
return true;
case Keys.PageUp:
SelectNext(-10);
return true;
case Keys.Enter:
OnSelecting();
return true;
case Keys.Tab:
if (!AllowTabKey)
break;
OnSelecting();
return true;
case Keys.Escape:
Menu.Close();
return true;
}
return false;
}
public void SelectNext(int shift)
{
FocussedItemIndex = Math.Max(0, Math.Min(FocussedItemIndex + shift, visibleItems.Count - 1));
DoSelectedVisible();
//
Invalidate();
}
private void DoSelectedVisible()
{
if (FocussedItem != null)
SetToolTip(FocussedItem);
var y = FocussedItemIndex * ItemHeight - VerticalScroll.Value;
if (y < 0)
VerticalScroll.Value = FocussedItemIndex * ItemHeight;
if (y > ClientSize.Height - ItemHeight)
VerticalScroll.Value = Math.Min(VerticalScroll.Maximum, FocussedItemIndex * ItemHeight - ClientSize.Height + ItemHeight);
//some magic for update scrolls
AutoScrollMinSize -= new Size(1, 0);
AutoScrollMinSize += new Size(1, 0);
}
private void SetToolTip(AutocompleteItem autocompleteItem)
{
var title = autocompleteItem.ToolTipTitle;
var text = autocompleteItem.ToolTipText;
if (string.IsNullOrEmpty(title))
{
toolTip.ToolTipTitle = null;
toolTip.SetToolTip(this, null);
return;
}
if (this.Parent != null)
{
IWin32Window window = this.Parent ?? this;
Point location;
if ((this.PointToScreen(this.Location).X + MaxToolTipSize.Width + 105) < Screen.FromControl(this.Parent).WorkingArea.Right)
location = new Point(Right + 5, 0);
else
location = new Point(Left - 105 - MaximumSize.Width, 0);
if (string.IsNullOrEmpty(text))
{
toolTip.ToolTipTitle = null;
toolTip.Show(title, window, location.X, location.Y, ToolTipDuration);
}
else
{
toolTip.ToolTipTitle = title;
toolTip.Show(text, window, location.X, location.Y, ToolTipDuration);
}
}
}
public int Count
{
get { return visibleItems.Count; }
}
public void SetAutocompleteItems(ICollection<string> items)
{
List<AutocompleteItem> list = new List<AutocompleteItem>(items.Count);
foreach (var item in items)
list.Add(new AutocompleteItem(item));
SetAutocompleteItems(list);
}
public void SetAutocompleteItems(IEnumerable<AutocompleteItem> items)
{
sourceItems = items;
}
}
public class SelectingEventArgs : EventArgs
{
public AutocompleteItem Item { get; internal set; }
public bool Cancel {get;set;}
public int SelectedIndex{get;set;}
public bool Handled { get; set; }
}
public class SelectedEventArgs : EventArgs
{
public AutocompleteItem Item { get; internal set; }
public FastColoredTextBox Tb { get; set; }
}
}

View File

@@ -0,0 +1,256 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Base class for bookmark collection
/// </summary>
public abstract class BaseBookmarks : ICollection<Bookmark>, IDisposable
{
#region ICollection
public abstract void Add(Bookmark item);
public abstract void Clear();
public abstract bool Contains(Bookmark item);
public abstract void CopyTo(Bookmark[] array, int arrayIndex);
public abstract int Count { get; }
public abstract bool IsReadOnly { get; }
public abstract bool Remove(Bookmark item);
public abstract IEnumerator<Bookmark> GetEnumerator();
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region IDisposable
public abstract void Dispose();
#endregion
#region Additional properties
public abstract void Add(int lineIndex, string bookmarkName);
public abstract void Add(int lineIndex);
public abstract bool Contains(int lineIndex);
public abstract bool Remove(int lineIndex);
public abstract Bookmark GetBookmark(int i);
#endregion
}
/// <summary>
/// Collection of bookmarks
/// </summary>
public class Bookmarks : BaseBookmarks
{
protected FastColoredTextBox tb;
protected List<Bookmark> items = new List<Bookmark>();
protected int counter;
public Bookmarks(FastColoredTextBox tb)
{
this.tb = tb;
tb.LineInserted += tb_LineInserted;
tb.LineRemoved += tb_LineRemoved;
}
protected virtual void tb_LineRemoved(object sender, LineRemovedEventArgs e)
{
for(int i=0; i<Count; i++)
if (items[i].LineIndex >= e.Index)
{
if (items[i].LineIndex >= e.Index + e.Count)
{
items[i].LineIndex = items[i].LineIndex - e.Count;
continue;
}
var was = e.Index <= 0;
foreach (var b in items)
if (b.LineIndex == e.Index - 1)
was = true;
if(was)
{
items.RemoveAt(i);
i--;
}else
items[i].LineIndex = e.Index - 1;
//if (items[i].LineIndex == e.Index + e.Count - 1)
//{
// items[i].LineIndex = items[i].LineIndex - e.Count;
// continue;
//}
//
//items.RemoveAt(i);
//i--;
}
}
protected virtual void tb_LineInserted(object sender, LineInsertedEventArgs e)
{
for (int i = 0; i < Count; i++)
if (items[i].LineIndex >= e.Index)
{
items[i].LineIndex = items[i].LineIndex + e.Count;
}else
if (items[i].LineIndex == e.Index - 1 && e.Count == 1)
{
if(tb[e.Index - 1].StartSpacesCount == tb[e.Index - 1].Count)
items[i].LineIndex = items[i].LineIndex + e.Count;
}
}
public override void Dispose()
{
tb.LineInserted -= tb_LineInserted;
tb.LineRemoved -= tb_LineRemoved;
}
public override IEnumerator<Bookmark> GetEnumerator()
{
foreach (var item in items)
yield return item;
}
public override void Add(int lineIndex, string bookmarkName)
{
Add(new Bookmark(tb, bookmarkName ?? "Bookmark " + counter, lineIndex));
}
public override void Add(int lineIndex)
{
Add(new Bookmark(tb, "Bookmark " + counter, lineIndex));
}
public override void Clear()
{
items.Clear();
counter = 0;
}
public override void Add(Bookmark bookmark)
{
foreach (var bm in items)
if (bm.LineIndex == bookmark.LineIndex)
return;
items.Add(bookmark);
counter++;
tb.Invalidate();
}
public override bool Contains(Bookmark item)
{
return items.Contains(item);
}
public override bool Contains(int lineIndex)
{
foreach (var item in items)
if (item.LineIndex == lineIndex)
return true;
return false;
}
public override void CopyTo(Bookmark[] array, int arrayIndex)
{
items.CopyTo(array, arrayIndex);
}
public override int Count
{
get { return items.Count; }
}
public override bool IsReadOnly
{
get { return false; }
}
public override bool Remove(Bookmark item)
{
tb.Invalidate();
return items.Remove(item);
}
/// <summary>
/// Removes bookmark by line index
/// </summary>
public override bool Remove(int lineIndex)
{
bool was = false;
for (int i = 0; i < Count; i++)
if (items[i].LineIndex == lineIndex)
{
items.RemoveAt(i);
i--;
was = true;
}
tb.Invalidate();
return was;
}
/// <summary>
/// Returns Bookmark by index.
/// </summary>
public override Bookmark GetBookmark(int i)
{
return items[i];
}
}
/// <summary>
/// Bookmark of FastColoredTextbox
/// </summary>
public class Bookmark
{
public FastColoredTextBox TB { get; private set; }
/// <summary>
/// Name of bookmark
/// </summary>
public string Name { get; set; }
/// <summary>
/// Line index
/// </summary>
public int LineIndex {get; set; }
/// <summary>
/// Color of bookmark sign
/// </summary>
public Color Color { get; set; }
/// <summary>
/// Scroll textbox to the bookmark
/// </summary>
public virtual void DoVisible()
{
TB.Selection.Start = new Place(0, LineIndex);
TB.DoRangeVisible(TB.Selection, true);
TB.Invalidate();
}
public Bookmark(FastColoredTextBox tb, string name, int lineIndex)
{
this.TB = tb;
this.Name = name;
this.LineIndex = lineIndex;
Color = tb.BookmarkColor;
}
public virtual void Paint(Graphics gr, Rectangle lineRect)
{
var size = TB.CharHeight - 1;
using (var brush = new LinearGradientBrush(new Rectangle(0, lineRect.Top, size, size), Color.White, Color, 45))
gr.FillEllipse(brush, 0, lineRect.Top, size, size);
using (var pen = new Pen(Color))
gr.DrawEllipse(pen, 0, lineRect.Top, size, size);
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Char and style
/// </summary>
public struct Char
{
/// <summary>
/// Unicode character
/// </summary>
public char c;
/// <summary>
/// Style bit mask
/// </summary>
/// <remarks>Bit 1 in position n means that this char will rendering by FastColoredTextBox.Styles[n]</remarks>
public StyleIndex style;
public Char(char c)
{
this.c = c;
style = StyleIndex.None;
}
}
}

View File

@@ -0,0 +1,245 @@
using System.Collections.Generic;
using System;
namespace FastColoredTextBoxNS
{
public class CommandManager
{
public static int MaxHistoryLength = 200;
LimitedStack<UndoableCommand> history;
Stack<UndoableCommand> redoStack = new Stack<UndoableCommand>();
public TextSource TextSource{ get; private set; }
public bool UndoRedoStackIsEnabled { get; set; }
public event EventHandler RedoCompleted = delegate { };
public CommandManager(TextSource ts)
{
history = new LimitedStack<UndoableCommand>(MaxHistoryLength);
TextSource = ts;
UndoRedoStackIsEnabled = true;
}
public virtual void ExecuteCommand(Command cmd)
{
if (disabledCommands > 0)
return;
//multirange ?
if (cmd.ts.CurrentTB.Selection.ColumnSelectionMode)
if (cmd is UndoableCommand)
//make wrapper
cmd = new MultiRangeCommand((UndoableCommand)cmd);
if (cmd is UndoableCommand)
{
//if range is ColumnRange, then create wrapper
(cmd as UndoableCommand).autoUndo = autoUndoCommands > 0;
history.Push(cmd as UndoableCommand);
}
try
{
cmd.Execute();
}
catch (ArgumentOutOfRangeException)
{
//OnTextChanging cancels enter of the text
if (cmd is UndoableCommand)
history.Pop();
}
//
if (!UndoRedoStackIsEnabled)
ClearHistory();
//
redoStack.Clear();
//
TextSource.CurrentTB.OnUndoRedoStateChanged();
}
public void Undo()
{
if (history.Count > 0)
{
var cmd = history.Pop();
//
BeginDisableCommands();//prevent text changing into handlers
try
{
cmd.Undo();
}
finally
{
EndDisableCommands();
}
//
redoStack.Push(cmd);
}
//undo next autoUndo command
if (history.Count > 0)
{
if (history.Peek().autoUndo)
Undo();
}
TextSource.CurrentTB.OnUndoRedoStateChanged();
}
protected int disabledCommands = 0;
private void EndDisableCommands()
{
disabledCommands--;
}
private void BeginDisableCommands()
{
disabledCommands++;
}
int autoUndoCommands = 0;
public void EndAutoUndoCommands()
{
autoUndoCommands--;
if (autoUndoCommands == 0)
if (history.Count > 0)
history.Peek().autoUndo = false;
}
public void BeginAutoUndoCommands()
{
autoUndoCommands++;
}
internal void ClearHistory()
{
history.Clear();
redoStack.Clear();
TextSource.CurrentTB.OnUndoRedoStateChanged();
}
internal void Redo()
{
if (redoStack.Count == 0)
return;
UndoableCommand cmd;
BeginDisableCommands();//prevent text changing into handlers
try
{
cmd = redoStack.Pop();
if (TextSource.CurrentTB.Selection.ColumnSelectionMode)
TextSource.CurrentTB.Selection.ColumnSelectionMode = false;
TextSource.CurrentTB.Selection.Start = cmd.sel.Start;
TextSource.CurrentTB.Selection.End = cmd.sel.End;
cmd.Execute();
history.Push(cmd);
}
finally
{
EndDisableCommands();
}
//call event
RedoCompleted(this, EventArgs.Empty);
//redo command after autoUndoable command
if (cmd.autoUndo)
Redo();
TextSource.CurrentTB.OnUndoRedoStateChanged();
}
public bool UndoEnabled
{
get
{
return history.Count > 0;
}
}
public bool RedoEnabled
{
get
{
return redoStack.Count > 0;
}
}
}
public abstract class Command
{
public TextSource ts;
public abstract void Execute();
}
internal class RangeInfo
{
public Place Start { get; set; }
public Place End { get; set; }
public RangeInfo(Range r)
{
Start = r.Start;
End = r.End;
}
internal int FromX
{
get
{
if (End.iLine < Start.iLine) return End.iChar;
if (End.iLine > Start.iLine) return Start.iChar;
return Math.Min(End.iChar, Start.iChar);
}
}
}
public abstract class UndoableCommand : Command
{
internal RangeInfo sel;
internal RangeInfo lastSel;
internal bool autoUndo;
public UndoableCommand(TextSource ts)
{
this.ts = ts;
sel = new RangeInfo(ts.CurrentTB.Selection);
}
public virtual void Undo()
{
OnTextChanged(true);
}
public override void Execute()
{
lastSel = new RangeInfo(ts.CurrentTB.Selection);
OnTextChanged(false);
}
protected virtual void OnTextChanged(bool invert)
{
bool b = sel.Start.iLine < lastSel.Start.iLine;
if (invert)
{
if (b)
ts.OnTextChanged(sel.Start.iLine, sel.Start.iLine);
else
ts.OnTextChanged(sel.Start.iLine, lastSel.Start.iLine);
}
else
{
if (b)
ts.OnTextChanged(sel.Start.iLine, lastSel.Start.iLine);
else
ts.OnTextChanged(lastSel.Start.iLine, lastSel.Start.iLine);
}
}
public abstract UndoableCommand Clone();
}
}

View File

@@ -0,0 +1,809 @@
using System;
using System.Collections.Generic;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Insert single char
/// </summary>
/// <remarks>This operation includes also insertion of new line and removing char by backspace</remarks>
public class InsertCharCommand : UndoableCommand
{
public char c;
char deletedChar = '\x0';
/// <summary>
/// Constructor
/// </summary>
/// <param name="tb">Underlaying textbox</param>
/// <param name="c">Inserting char</param>
public InsertCharCommand(TextSource ts, char c): base(ts)
{
this.c = c;
}
/// <summary>
/// Undo operation
/// </summary>
public override void Undo()
{
ts.OnTextChanging();
switch (c)
{
case '\n': MergeLines(sel.Start.iLine, ts); break;
case '\r': break;
case '\b':
ts.CurrentTB.Selection.Start = lastSel.Start;
char cc = '\x0';
if (deletedChar != '\x0')
{
ts.CurrentTB.ExpandBlock(ts.CurrentTB.Selection.Start.iLine);
InsertChar(deletedChar, ref cc, ts);
}
break;
case '\t':
ts.CurrentTB.ExpandBlock(sel.Start.iLine);
for (int i = sel.FromX; i < lastSel.FromX; i++)
ts[sel.Start.iLine].RemoveAt(sel.Start.iChar);
ts.CurrentTB.Selection.Start = sel.Start;
break;
default:
ts.CurrentTB.ExpandBlock(sel.Start.iLine);
ts[sel.Start.iLine].RemoveAt(sel.Start.iChar);
ts.CurrentTB.Selection.Start = sel.Start;
break;
}
ts.NeedRecalc(new TextSource.TextChangedEventArgs(sel.Start.iLine, sel.Start.iLine));
base.Undo();
}
/// <summary>
/// Execute operation
/// </summary>
public override void Execute()
{
ts.CurrentTB.ExpandBlock(ts.CurrentTB.Selection.Start.iLine);
string s = c.ToString();
ts.OnTextChanging(ref s);
if (s.Length == 1)
c = s[0];
if (String.IsNullOrEmpty(s))
throw new ArgumentOutOfRangeException();
if (ts.Count == 0)
InsertLine(ts);
InsertChar(c, ref deletedChar, ts);
ts.NeedRecalc(new TextSource.TextChangedEventArgs(ts.CurrentTB.Selection.Start.iLine, ts.CurrentTB.Selection.Start.iLine));
base.Execute();
}
internal static void InsertChar(char c, ref char deletedChar, TextSource ts)
{
var tb = ts.CurrentTB;
switch (c)
{
case '\n':
if (!ts.CurrentTB.AllowInsertRemoveLines)
throw new ArgumentOutOfRangeException("Cant insert this char in ColumnRange mode");
if (ts.Count == 0)
InsertLine(ts);
InsertLine(ts);
break;
case '\r': break;
case '\b'://backspace
if (tb.Selection.Start.iChar == 0 && tb.Selection.Start.iLine == 0)
return;
if (tb.Selection.Start.iChar == 0)
{
if (!ts.CurrentTB.AllowInsertRemoveLines)
throw new ArgumentOutOfRangeException("Cant insert this char in ColumnRange mode");
if (tb.LineInfos[tb.Selection.Start.iLine - 1].VisibleState != VisibleState.Visible)
tb.ExpandBlock(tb.Selection.Start.iLine - 1);
deletedChar = '\n';
MergeLines(tb.Selection.Start.iLine - 1, ts);
}
else
{
deletedChar = ts[tb.Selection.Start.iLine][tb.Selection.Start.iChar - 1].c;
ts[tb.Selection.Start.iLine].RemoveAt(tb.Selection.Start.iChar - 1);
tb.Selection.Start = new Place(tb.Selection.Start.iChar - 1, tb.Selection.Start.iLine);
}
break;
case '\t':
int spaceCountNextTabStop = tb.TabLength - (tb.Selection.Start.iChar % tb.TabLength);
if (spaceCountNextTabStop == 0)
spaceCountNextTabStop = tb.TabLength;
for (int i = 0; i < spaceCountNextTabStop; i++)
ts[tb.Selection.Start.iLine].Insert(tb.Selection.Start.iChar, new Char(' '));
tb.Selection.Start = new Place(tb.Selection.Start.iChar + spaceCountNextTabStop, tb.Selection.Start.iLine);
break;
default:
ts[tb.Selection.Start.iLine].Insert(tb.Selection.Start.iChar, new Char(c));
tb.Selection.Start = new Place(tb.Selection.Start.iChar + 1, tb.Selection.Start.iLine);
break;
}
}
internal static void InsertLine(TextSource ts)
{
var tb = ts.CurrentTB;
if (!tb.Multiline && tb.LinesCount > 0)
return;
if (ts.Count == 0)
ts.InsertLine(0, ts.CreateLine());
else
BreakLines(tb.Selection.Start.iLine, tb.Selection.Start.iChar, ts);
tb.Selection.Start = new Place(0, tb.Selection.Start.iLine + 1);
ts.NeedRecalc(new TextSource.TextChangedEventArgs(0, 1));
}
/// <summary>
/// Merge lines i and i+1
/// </summary>
internal static void MergeLines(int i, TextSource ts)
{
var tb = ts.CurrentTB;
if (i + 1 >= ts.Count)
return;
tb.ExpandBlock(i);
tb.ExpandBlock(i + 1);
int pos = ts[i].Count;
//
/*
if(ts[i].Count == 0)
ts.RemoveLine(i);
else*/
if (ts[i + 1].Count == 0)
ts.RemoveLine(i + 1);
else
{
ts[i].AddRange(ts[i + 1]);
ts.RemoveLine(i + 1);
}
tb.Selection.Start = new Place(pos, i);
ts.NeedRecalc(new TextSource.TextChangedEventArgs(0, 1));
}
internal static void BreakLines(int iLine, int pos, TextSource ts)
{
Line newLine = ts.CreateLine();
for(int i=pos;i<ts[iLine].Count;i++)
newLine.Add(ts[iLine][i]);
ts[iLine].RemoveRange(pos, ts[iLine].Count - pos);
//
ts.InsertLine(iLine+1, newLine);
}
public override UndoableCommand Clone()
{
return new InsertCharCommand(ts, c);
}
}
/// <summary>
/// Insert text
/// </summary>
public class InsertTextCommand : UndoableCommand
{
public string InsertedText;
/// <summary>
/// Constructor
/// </summary>
/// <param name="tb">Underlaying textbox</param>
/// <param name="insertedText">Text for inserting</param>
public InsertTextCommand(TextSource ts, string insertedText): base(ts)
{
this.InsertedText = insertedText;
}
/// <summary>
/// Undo operation
/// </summary>
public override void Undo()
{
ts.CurrentTB.Selection.Start = sel.Start;
ts.CurrentTB.Selection.End = lastSel.Start;
ts.OnTextChanging();
ClearSelectedCommand.ClearSelected(ts);
base.Undo();
}
/// <summary>
/// Execute operation
/// </summary>
public override void Execute()
{
ts.OnTextChanging(ref InsertedText);
InsertText(InsertedText, ts);
base.Execute();
}
internal static void InsertText(string insertedText, TextSource ts)
{
var tb = ts.CurrentTB;
try
{
tb.Selection.BeginUpdate();
char cc = '\x0';
if (ts.Count == 0)
{
InsertCharCommand.InsertLine(ts);
tb.Selection.Start = Place.Empty;
}
tb.ExpandBlock(tb.Selection.Start.iLine);
var len = insertedText.Length;
for (int i = 0; i < len; i++)
{
var c = insertedText[i];
if(c == '\r' && (i >= len - 1 || insertedText[i + 1] != '\n'))
InsertCharCommand.InsertChar('\n', ref cc, ts);
else
InsertCharCommand.InsertChar(c, ref cc, ts);
}
ts.NeedRecalc(new TextSource.TextChangedEventArgs(0, 1));
}
finally {
tb.Selection.EndUpdate();
}
}
public override UndoableCommand Clone()
{
return new InsertTextCommand(ts, InsertedText);
}
}
/// <summary>
/// Insert text into given ranges
/// </summary>
public class ReplaceTextCommand : UndoableCommand
{
string insertedText;
List<Range> ranges;
List<string> prevText = new List<string>();
/// <summary>
/// Constructor
/// </summary>
/// <param name="tb">Underlaying textbox</param>
/// <param name="ranges">List of ranges for replace</param>
/// <param name="insertedText">Text for inserting</param>
public ReplaceTextCommand(TextSource ts, List<Range> ranges, string insertedText)
: base(ts)
{
//sort ranges by place
ranges.Sort((r1, r2)=>
{
if (r1.Start.iLine == r2.Start.iLine)
return r1.Start.iChar.CompareTo(r2.Start.iChar);
return r1.Start.iLine.CompareTo(r2.Start.iLine);
});
//
this.ranges = ranges;
this.insertedText = insertedText;
lastSel = sel = new RangeInfo(ts.CurrentTB.Selection);
}
/// <summary>
/// Undo operation
/// </summary>
public override void Undo()
{
var tb = ts.CurrentTB;
ts.OnTextChanging();
tb.BeginUpdate();
tb.Selection.BeginUpdate();
for (int i = 0; i<ranges.Count; i++)
{
tb.Selection.Start = ranges[i].Start;
for (int j = 0; j < insertedText.Length; j++)
tb.Selection.GoRight(true);
ClearSelected(ts);
InsertTextCommand.InsertText(prevText[prevText.Count - i - 1], ts);
}
tb.Selection.EndUpdate();
tb.EndUpdate();
if (ranges.Count > 0)
ts.OnTextChanged(ranges[0].Start.iLine, ranges[ranges.Count - 1].End.iLine);
ts.NeedRecalc(new TextSource.TextChangedEventArgs(0, 1));
}
/// <summary>
/// Execute operation
/// </summary>
public override void Execute()
{
var tb = ts.CurrentTB;
prevText.Clear();
ts.OnTextChanging(ref insertedText);
tb.Selection.BeginUpdate();
tb.BeginUpdate();
for (int i = ranges.Count - 1; i >= 0; i--)
{
tb.Selection.Start = ranges[i].Start;
tb.Selection.End = ranges[i].End;
prevText.Add(tb.Selection.Text);
ClearSelected(ts);
if (insertedText != "")
InsertTextCommand.InsertText(insertedText, ts);
}
if(ranges.Count > 0)
ts.OnTextChanged(ranges[0].Start.iLine, ranges[ranges.Count - 1].End.iLine);
tb.EndUpdate();
tb.Selection.EndUpdate();
ts.NeedRecalc(new TextSource.TextChangedEventArgs(0, 1));
lastSel = new RangeInfo(tb.Selection);
}
public override UndoableCommand Clone()
{
return new ReplaceTextCommand(ts, new List<Range>(ranges), insertedText);
}
internal static void ClearSelected(TextSource ts)
{
var tb = ts.CurrentTB;
tb.Selection.Normalize();
Place start = tb.Selection.Start;
Place end = tb.Selection.End;
int fromLine = Math.Min(end.iLine, start.iLine);
int toLine = Math.Max(end.iLine, start.iLine);
int fromChar = tb.Selection.FromX;
int toChar = tb.Selection.ToX;
if (fromLine < 0) return;
//
if (fromLine == toLine)
ts[fromLine].RemoveRange(fromChar, toChar - fromChar);
else
{
ts[fromLine].RemoveRange(fromChar, ts[fromLine].Count - fromChar);
ts[toLine].RemoveRange(0, toChar);
ts.RemoveLine(fromLine + 1, toLine - fromLine - 1);
InsertCharCommand.MergeLines(fromLine, ts);
}
}
}
/// <summary>
/// Clear selected text
/// </summary>
public class ClearSelectedCommand : UndoableCommand
{
string deletedText;
/// <summary>
/// Construstor
/// </summary>
/// <param name="tb">Underlaying textbox</param>
public ClearSelectedCommand(TextSource ts): base(ts)
{
}
/// <summary>
/// Undo operation
/// </summary>
public override void Undo()
{
ts.CurrentTB.Selection.Start = new Place(sel.FromX, Math.Min(sel.Start.iLine, sel.End.iLine));
ts.OnTextChanging();
InsertTextCommand.InsertText(deletedText, ts);
ts.OnTextChanged(sel.Start.iLine, sel.End.iLine);
ts.CurrentTB.Selection.Start = sel.Start;
ts.CurrentTB.Selection.End = sel.End;
}
/// <summary>
/// Execute operation
/// </summary>
public override void Execute()
{
var tb = ts.CurrentTB;
string temp = null;
ts.OnTextChanging(ref temp);
if (temp == "")
throw new ArgumentOutOfRangeException();
deletedText = tb.Selection.Text;
ClearSelected(ts);
lastSel = new RangeInfo(tb.Selection);
ts.OnTextChanged(lastSel.Start.iLine, lastSel.Start.iLine);
}
internal static void ClearSelected(TextSource ts)
{
var tb = ts.CurrentTB;
Place start = tb.Selection.Start;
Place end = tb.Selection.End;
int fromLine = Math.Min(end.iLine, start.iLine);
int toLine = Math.Max(end.iLine, start.iLine);
int fromChar = tb.Selection.FromX;
int toChar = tb.Selection.ToX;
if (fromLine < 0) return;
//
if (fromLine == toLine)
ts[fromLine].RemoveRange(fromChar, toChar - fromChar);
else
{
ts[fromLine].RemoveRange(fromChar, ts[fromLine].Count - fromChar);
ts[toLine].RemoveRange(0, toChar);
ts.RemoveLine(fromLine + 1, toLine - fromLine - 1);
InsertCharCommand.MergeLines(fromLine, ts);
}
//
tb.Selection.Start = new Place(fromChar, fromLine);
//
ts.NeedRecalc(new TextSource.TextChangedEventArgs(fromLine, toLine));
}
public override UndoableCommand Clone()
{
return new ClearSelectedCommand(ts);
}
}
/// <summary>
/// Replaces text
/// </summary>
public class ReplaceMultipleTextCommand : UndoableCommand
{
List<ReplaceRange> ranges;
List<string> prevText = new List<string>();
public class ReplaceRange
{
public Range ReplacedRange { get; set; }
public String ReplaceText { get; set; }
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="ts">Underlaying textsource</param>
/// <param name="ranges">List of ranges for replace</param>
public ReplaceMultipleTextCommand(TextSource ts, List<ReplaceRange> ranges)
: base(ts)
{
//sort ranges by place
ranges.Sort((r1, r2) =>
{
if (r1.ReplacedRange.Start.iLine == r2.ReplacedRange.Start.iLine)
return r1.ReplacedRange.Start.iChar.CompareTo(r2.ReplacedRange.Start.iChar);
return r1.ReplacedRange.Start.iLine.CompareTo(r2.ReplacedRange.Start.iLine);
});
//
this.ranges = ranges;
lastSel = sel = new RangeInfo(ts.CurrentTB.Selection);
}
/// <summary>
/// Undo operation
/// </summary>
public override void Undo()
{
var tb = ts.CurrentTB;
ts.OnTextChanging();
tb.Selection.BeginUpdate();
for (int i = 0; i < ranges.Count; i++)
{
tb.Selection.Start = ranges[i].ReplacedRange.Start;
for (int j = 0; j < ranges[i].ReplaceText.Length; j++)
tb.Selection.GoRight(true);
ClearSelectedCommand.ClearSelected(ts);
var prevTextIndex = ranges.Count - 1 - i;
InsertTextCommand.InsertText(prevText[prevTextIndex], ts);
ts.OnTextChanged(ranges[i].ReplacedRange.Start.iLine, ranges[i].ReplacedRange.Start.iLine);
}
tb.Selection.EndUpdate();
ts.NeedRecalc(new TextSource.TextChangedEventArgs(0, 1));
}
/// <summary>
/// Execute operation
/// </summary>
public override void Execute()
{
var tb = ts.CurrentTB;
prevText.Clear();
ts.OnTextChanging();
tb.Selection.BeginUpdate();
for (int i = ranges.Count - 1; i >= 0; i--)
{
tb.Selection.Start = ranges[i].ReplacedRange.Start;
tb.Selection.End = ranges[i].ReplacedRange.End;
prevText.Add(tb.Selection.Text);
ClearSelectedCommand.ClearSelected(ts);
InsertTextCommand.InsertText(ranges[i].ReplaceText, ts);
ts.OnTextChanged(ranges[i].ReplacedRange.Start.iLine, ranges[i].ReplacedRange.End.iLine);
}
tb.Selection.EndUpdate();
ts.NeedRecalc(new TextSource.TextChangedEventArgs(0, 1));
lastSel = new RangeInfo(tb.Selection);
}
public override UndoableCommand Clone()
{
return new ReplaceMultipleTextCommand(ts, new List<ReplaceRange>(ranges));
}
}
/// <summary>
/// Removes lines
/// </summary>
public class RemoveLinesCommand : UndoableCommand
{
List<int> iLines;
List<string> prevText = new List<string>();
/// <summary>
/// Constructor
/// </summary>
/// <param name="tb">Underlaying textbox</param>
/// <param name="ranges">List of ranges for replace</param>
/// <param name="insertedText">Text for inserting</param>
public RemoveLinesCommand(TextSource ts, List<int> iLines)
: base(ts)
{
//sort iLines
iLines.Sort();
//
this.iLines = iLines;
lastSel = sel = new RangeInfo(ts.CurrentTB.Selection);
}
/// <summary>
/// Undo operation
/// </summary>
public override void Undo()
{
var tb = ts.CurrentTB;
ts.OnTextChanging();
tb.Selection.BeginUpdate();
//tb.BeginUpdate();
for (int i = 0; i < iLines.Count; i++)
{
var iLine = iLines[i];
if(iLine < ts.Count)
tb.Selection.Start = new Place(0, iLine);
else
tb.Selection.Start = new Place(ts[ts.Count - 1].Count, ts.Count - 1);
InsertCharCommand.InsertLine(ts);
tb.Selection.Start = new Place(0, iLine);
var text = prevText[prevText.Count - i - 1];
InsertTextCommand.InsertText(text, ts);
ts[iLine].IsChanged = true;
if (iLine < ts.Count - 1)
ts[iLine + 1].IsChanged = true;
else
ts[iLine - 1].IsChanged = true;
if(text.Trim() != string.Empty)
ts.OnTextChanged(iLine, iLine);
}
//tb.EndUpdate();
tb.Selection.EndUpdate();
ts.NeedRecalc(new TextSource.TextChangedEventArgs(0, 1));
}
/// <summary>
/// Execute operation
/// </summary>
public override void Execute()
{
var tb = ts.CurrentTB;
prevText.Clear();
ts.OnTextChanging();
tb.Selection.BeginUpdate();
for(int i = iLines.Count - 1; i >= 0; i--)
{
var iLine = iLines[i];
prevText.Add(ts[iLine].Text);//backward
ts.RemoveLine(iLine);
//ts.OnTextChanged(ranges[i].Start.iLine, ranges[i].End.iLine);
}
tb.Selection.Start = new Place(0, 0);
tb.Selection.EndUpdate();
ts.NeedRecalc(new TextSource.TextChangedEventArgs(0, 1));
lastSel = new RangeInfo(tb.Selection);
}
public override UndoableCommand Clone()
{
return new RemoveLinesCommand(ts, new List<int>(iLines));
}
}
/// <summary>
/// Wrapper for multirange commands
/// </summary>
public class MultiRangeCommand : UndoableCommand
{
private UndoableCommand cmd;
private Range range;
private List<UndoableCommand> commandsByRanges = new List<UndoableCommand>();
public MultiRangeCommand(UndoableCommand command):base(command.ts)
{
this.cmd = command;
range = ts.CurrentTB.Selection.Clone();
}
public override void Execute()
{
commandsByRanges.Clear();
var prevSelection = range.Clone();
var iChar = -1;
var iStartLine = prevSelection.Start.iLine;
var iEndLine = prevSelection.End.iLine;
ts.CurrentTB.Selection.ColumnSelectionMode = false;
ts.CurrentTB.Selection.BeginUpdate();
ts.CurrentTB.BeginUpdate();
ts.CurrentTB.AllowInsertRemoveLines = false;
try
{
if (cmd is InsertTextCommand)
ExecuteInsertTextCommand(ref iChar, (cmd as InsertTextCommand).InsertedText);
else
if (cmd is InsertCharCommand && (cmd as InsertCharCommand).c != '\x0' && (cmd as InsertCharCommand).c != '\b')//if not DEL or BACKSPACE
ExecuteInsertTextCommand(ref iChar, (cmd as InsertCharCommand).c.ToString());
else
ExecuteCommand(ref iChar);
}
catch (ArgumentOutOfRangeException)
{
}
finally
{
ts.CurrentTB.AllowInsertRemoveLines = true;
ts.CurrentTB.EndUpdate();
ts.CurrentTB.Selection = range;
if (iChar >= 0)
{
ts.CurrentTB.Selection.Start = new Place(iChar, iStartLine);
ts.CurrentTB.Selection.End = new Place(iChar, iEndLine);
}
ts.CurrentTB.Selection.ColumnSelectionMode = true;
ts.CurrentTB.Selection.EndUpdate();
}
}
private void ExecuteInsertTextCommand(ref int iChar, string text)
{
var lines = text.Split('\n');
var iLine = 0;
foreach (var r in range.GetSubRanges(true))
{
var line = ts.CurrentTB[r.Start.iLine];
var lineIsEmpty = r.End < r.Start && line.StartSpacesCount == line.Count;
if (!lineIsEmpty)
{
var insertedText = lines[iLine%lines.Length];
if (r.End < r.Start && insertedText!="")
{
//add forwarding spaces
insertedText = new string(' ', r.Start.iChar - r.End.iChar) + insertedText;
r.Start = r.End;
}
ts.CurrentTB.Selection = r;
var c = new InsertTextCommand(ts, insertedText);
c.Execute();
if (ts.CurrentTB.Selection.End.iChar > iChar)
iChar = ts.CurrentTB.Selection.End.iChar;
commandsByRanges.Add(c);
}
iLine++;
}
}
private void ExecuteCommand(ref int iChar)
{
foreach (var r in range.GetSubRanges(false))
{
ts.CurrentTB.Selection = r;
var c = cmd.Clone();
c.Execute();
if (ts.CurrentTB.Selection.End.iChar > iChar)
iChar = ts.CurrentTB.Selection.End.iChar;
commandsByRanges.Add(c);
}
}
public override void Undo()
{
ts.CurrentTB.BeginUpdate();
ts.CurrentTB.Selection.BeginUpdate();
try
{
for (int i = commandsByRanges.Count - 1; i >= 0; i--)
commandsByRanges[i].Undo();
}
finally
{
ts.CurrentTB.Selection.EndUpdate();
ts.CurrentTB.EndUpdate();
}
ts.CurrentTB.Selection = range.Clone();
ts.CurrentTB.OnTextChanged(range);
ts.CurrentTB.OnSelectionChanged();
ts.CurrentTB.Selection.ColumnSelectionMode = true;
}
public override UndoableCommand Clone()
{
throw new NotImplementedException();
}
}
/// <summary>
/// Remembers current selection and restore it after Undo
/// </summary>
public class SelectCommand : UndoableCommand
{
public SelectCommand(TextSource ts):base(ts)
{
}
public override void Execute()
{
//remember selection
lastSel = new RangeInfo(ts.CurrentTB.Selection);
}
protected override void OnTextChanged(bool invert)
{
}
public override void Undo()
{
//restore selection
ts.CurrentTB.Selection = new Range(ts.CurrentTB, lastSel.Start, lastSel.End);
}
public override UndoableCommand Clone()
{
var result = new SelectCommand(ts);
if(lastSel!=null)
result.lastSel = new RangeInfo(new Range(ts.CurrentTB, lastSel.Start, lastSel.End));
return result;
}
}
}

View File

@@ -0,0 +1,250 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Shows document map of FCTB
/// </summary>
public class DocumentMap : Control
{
public EventHandler TargetChanged;
FastColoredTextBox target;
private float scale = 0.3f;
private bool needRepaint = true;
private Place startPlace = Place.Empty;
private bool scrollbarVisible = true;
[Description("Target FastColoredTextBox")]
public FastColoredTextBox Target
{
get { return target; }
set
{
if (target != null)
UnSubscribe(target);
target = value;
if (value != null)
{
Subscribe(target);
}
OnTargetChanged();
}
}
/// <summary>
/// Scale
/// </summary>
[Description("Scale")]
[DefaultValue(0.3f)]
public float Scale
{
get { return scale; }
set
{
scale = value;
NeedRepaint();
}
}
/// <summary>
/// Scrollbar visibility
/// </summary>
[Description("Scrollbar visibility")]
[DefaultValue(true)]
public bool ScrollbarVisible
{
get { return scrollbarVisible; }
set
{
scrollbarVisible = value;
NeedRepaint();
}
}
public DocumentMap()
{
ForeColor = Color.Maroon;
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true);
Application.Idle += Application_Idle;
}
void Application_Idle(object sender, EventArgs e)
{
if(needRepaint)
Invalidate();
}
protected virtual void OnTargetChanged()
{
NeedRepaint();
if (TargetChanged != null)
TargetChanged(this, EventArgs.Empty);
}
protected virtual void UnSubscribe(FastColoredTextBox target)
{
target.Scroll -= new ScrollEventHandler(Target_Scroll);
target.SelectionChangedDelayed -= new EventHandler(Target_SelectionChanged);
target.VisibleRangeChanged -= new EventHandler(Target_VisibleRangeChanged);
}
protected virtual void Subscribe(FastColoredTextBox target)
{
target.Scroll += new ScrollEventHandler(Target_Scroll);
target.SelectionChangedDelayed += new EventHandler(Target_SelectionChanged);
target.VisibleRangeChanged += new EventHandler(Target_VisibleRangeChanged);
}
protected virtual void Target_VisibleRangeChanged(object sender, EventArgs e)
{
NeedRepaint();
}
protected virtual void Target_SelectionChanged(object sender, EventArgs e)
{
NeedRepaint();
}
protected virtual void Target_Scroll(object sender, ScrollEventArgs e)
{
NeedRepaint();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
NeedRepaint();
}
public void NeedRepaint()
{
needRepaint = true;
}
protected override void OnPaint(PaintEventArgs e)
{
if (target == null)
return;
var zoom = this.Scale * 100 / target.Zoom;
if (zoom <= float.Epsilon)
return;
//calc startPlace
var r = target.VisibleRange;
if (startPlace.iLine > r.Start.iLine)
startPlace.iLine = r.Start.iLine;
else
{
var endP = target.PlaceToPoint(r.End);
endP.Offset(0, -(int)(ClientSize.Height / zoom) + target.CharHeight);
var pp = target.PointToPlace(endP);
if (pp.iLine > startPlace.iLine)
startPlace.iLine = pp.iLine;
}
startPlace.iChar = 0;
//calc scroll pos
var linesCount = target.Lines.Count;
var sp1 = (float)r.Start.iLine / linesCount;
var sp2 = (float)r.End.iLine / linesCount;
//scale graphics
e.Graphics.ScaleTransform(zoom, zoom);
//draw text
var size = new SizeF(ClientSize.Width / zoom, ClientSize.Height / zoom);
target.DrawText(e.Graphics, startPlace, size.ToSize());
//draw visible rect
var p0 = target.PlaceToPoint(startPlace);
var p1 = target.PlaceToPoint(r.Start);
var p2 = target.PlaceToPoint(r.End);
var y1 = p1.Y - p0.Y;
var y2 = p2.Y + target.CharHeight - p0.Y;
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
using (var brush = new SolidBrush(Color.FromArgb(50, ForeColor)))
using (var pen = new Pen(brush, 1 / zoom))
{
var rect = new Rectangle(0, y1, (int)((ClientSize.Width - 1) / zoom), y2 - y1);
e.Graphics.FillRectangle(brush, rect);
e.Graphics.DrawRectangle(pen, rect);
}
//draw scrollbar
if (scrollbarVisible)
{
e.Graphics.ResetTransform();
e.Graphics.SmoothingMode = SmoothingMode.None;
using (var brush = new SolidBrush(Color.FromArgb(200, ForeColor)))
{
var rect = new RectangleF(ClientSize.Width - 3, ClientSize.Height*sp1, 2,
ClientSize.Height*(sp2 - sp1));
e.Graphics.FillRectangle(brush, rect);
}
}
needRepaint = false;
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
Scroll(e.Location);
base.OnMouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
Scroll(e.Location);
base.OnMouseMove(e);
}
private void Scroll(Point point)
{
if (target == null)
return;
var zoom = this.Scale*100/target.Zoom;
if (zoom <= float.Epsilon)
return;
var p0 = target.PlaceToPoint(startPlace);
p0 = new Point(0, p0.Y + (int) (point.Y/zoom));
var pp = target.PointToPlace(p0);
target.DoRangeVisible(new Range(target, pp, pp), true);
BeginInvoke((MethodInvoker)OnScroll);
}
private void OnScroll()
{
Refresh();
target.Refresh();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
Application.Idle -= Application_Idle;
if (target != null)
UnSubscribe(target);
}
base.Dispose(disposing);
}
}
}

View File

@@ -0,0 +1,363 @@
// Copyright Tao Klerks, 2010-2012, tao@klerks.biz
// Licensed under the modified BSD license.
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace FastColoredTextBoxNS
{
public static class EncodingDetector
{
const long _defaultHeuristicSampleSize = 0x10000; //completely arbitrary - inappropriate for high numbers of files / high speed requirements
public static Encoding DetectTextFileEncoding(string InputFilename)
{
using (FileStream textfileStream = File.OpenRead(InputFilename))
{
return DetectTextFileEncoding(textfileStream, _defaultHeuristicSampleSize);
}
}
public static Encoding DetectTextFileEncoding(FileStream InputFileStream, long HeuristicSampleSize)
{
bool uselessBool = false;
return DetectTextFileEncoding(InputFileStream, _defaultHeuristicSampleSize, out uselessBool);
}
public static Encoding DetectTextFileEncoding(FileStream InputFileStream, long HeuristicSampleSize, out bool HasBOM)
{
Encoding encodingFound = null;
long originalPos = InputFileStream.Position;
InputFileStream.Position = 0;
//First read only what we need for BOM detection
byte[] bomBytes = new byte[InputFileStream.Length > 4 ? 4 : InputFileStream.Length];
InputFileStream.Read(bomBytes, 0, bomBytes.Length);
encodingFound = DetectBOMBytes(bomBytes);
if (encodingFound != null)
{
InputFileStream.Position = originalPos;
HasBOM = true;
return encodingFound;
}
//BOM Detection failed, going for heuristics now.
// create sample byte array and populate it
byte[] sampleBytes = new byte[HeuristicSampleSize > InputFileStream.Length ? InputFileStream.Length : HeuristicSampleSize];
Array.Copy(bomBytes, sampleBytes, bomBytes.Length);
if (InputFileStream.Length > bomBytes.Length)
InputFileStream.Read(sampleBytes, bomBytes.Length, sampleBytes.Length - bomBytes.Length);
InputFileStream.Position = originalPos;
//test byte array content
encodingFound = DetectUnicodeInByteSampleByHeuristics(sampleBytes);
HasBOM = false;
return encodingFound;
}
public static Encoding DetectBOMBytes(byte[] BOMBytes)
{
if (BOMBytes.Length < 2)
return null;
if (BOMBytes[0] == 0xff
&& BOMBytes[1] == 0xfe
&& (BOMBytes.Length < 4
|| BOMBytes[2] != 0
|| BOMBytes[3] != 0
)
)
return Encoding.Unicode;
if (BOMBytes[0] == 0xfe
&& BOMBytes[1] == 0xff
)
return Encoding.BigEndianUnicode;
if (BOMBytes.Length < 3)
return null;
if (BOMBytes[0] == 0xef && BOMBytes[1] == 0xbb && BOMBytes[2] == 0xbf)
return Encoding.UTF8;
if (BOMBytes[0] == 0x2b && BOMBytes[1] == 0x2f && BOMBytes[2] == 0x76)
return Encoding.UTF7;
if (BOMBytes.Length < 4)
return null;
if (BOMBytes[0] == 0xff && BOMBytes[1] == 0xfe && BOMBytes[2] == 0 && BOMBytes[3] == 0)
return Encoding.UTF32;
if (BOMBytes[0] == 0 && BOMBytes[1] == 0 && BOMBytes[2] == 0xfe && BOMBytes[3] == 0xff)
return Encoding.GetEncoding(12001);
return null;
}
public static Encoding DetectUnicodeInByteSampleByHeuristics(byte[] SampleBytes)
{
long oddBinaryNullsInSample = 0;
long evenBinaryNullsInSample = 0;
long suspiciousUTF8SequenceCount = 0;
long suspiciousUTF8BytesTotal = 0;
long likelyUSASCIIBytesInSample = 0;
//Cycle through, keeping count of binary null positions, possible UTF-8
// sequences from upper ranges of Windows-1252, and probable US-ASCII
// character counts.
long currentPos = 0;
int skipUTF8Bytes = 0;
while (currentPos < SampleBytes.Length)
{
//binary null distribution
if (SampleBytes[currentPos] == 0)
{
if (currentPos % 2 == 0)
evenBinaryNullsInSample++;
else
oddBinaryNullsInSample++;
}
//likely US-ASCII characters
if (IsCommonUSASCIIByte(SampleBytes[currentPos]))
likelyUSASCIIBytesInSample++;
//suspicious sequences (look like UTF-8)
if (skipUTF8Bytes == 0)
{
int lengthFound = DetectSuspiciousUTF8SequenceLength(SampleBytes, currentPos);
if (lengthFound > 0)
{
suspiciousUTF8SequenceCount++;
suspiciousUTF8BytesTotal += lengthFound;
skipUTF8Bytes = lengthFound - 1;
}
}
else
{
skipUTF8Bytes--;
}
currentPos++;
}
//1: UTF-16 LE - in english / european environments, this is usually characterized by a
// high proportion of odd binary nulls (starting at 0), with (as this is text) a low
// proportion of even binary nulls.
// The thresholds here used (less than 20% nulls where you expect non-nulls, and more than
// 60% nulls where you do expect nulls) are completely arbitrary.
if (((evenBinaryNullsInSample * 2.0) / SampleBytes.Length) < 0.2
&& ((oddBinaryNullsInSample * 2.0) / SampleBytes.Length) > 0.6
)
return Encoding.Unicode;
//2: UTF-16 BE - in english / european environments, this is usually characterized by a
// high proportion of even binary nulls (starting at 0), with (as this is text) a low
// proportion of odd binary nulls.
// The thresholds here used (less than 20% nulls where you expect non-nulls, and more than
// 60% nulls where you do expect nulls) are completely arbitrary.
if (((oddBinaryNullsInSample * 2.0) / SampleBytes.Length) < 0.2
&& ((evenBinaryNullsInSample * 2.0) / SampleBytes.Length) > 0.6
)
return Encoding.BigEndianUnicode;
//3: UTF-8 - Martin Dürst outlines a method for detecting whether something CAN be UTF-8 content
// using regexp, in his w3c.org unicode FAQ entry:
// http://www.w3.org/International/questions/qa-forms-utf-8
// adapted here for C#.
string potentiallyMangledString = Encoding.ASCII.GetString(SampleBytes);
Regex UTF8Validator = new Regex(@"\A("
+ @"[\x09\x0A\x0D\x20-\x7E]"
+ @"|[\xC2-\xDF][\x80-\xBF]"
+ @"|\xE0[\xA0-\xBF][\x80-\xBF]"
+ @"|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}"
+ @"|\xED[\x80-\x9F][\x80-\xBF]"
+ @"|\xF0[\x90-\xBF][\x80-\xBF]{2}"
+ @"|[\xF1-\xF3][\x80-\xBF]{3}"
+ @"|\xF4[\x80-\x8F][\x80-\xBF]{2}"
+ @")*\z");
if (UTF8Validator.IsMatch(potentiallyMangledString))
{
//Unfortunately, just the fact that it CAN be UTF-8 doesn't tell you much about probabilities.
//If all the characters are in the 0-127 range, no harm done, most western charsets are same as UTF-8 in these ranges.
//If some of the characters were in the upper range (western accented characters), however, they would likely be mangled to 2-byte by the UTF-8 encoding process.
// So, we need to play stats.
// The "Random" likelihood of any pair of randomly generated characters being one
// of these "suspicious" character sequences is:
// 128 / (256 * 256) = 0.2%.
//
// In western text data, that is SIGNIFICANTLY reduced - most text data stays in the <127
// character range, so we assume that more than 1 in 500,000 of these character
// sequences indicates UTF-8. The number 500,000 is completely arbitrary - so sue me.
//
// We can only assume these character sequences will be rare if we ALSO assume that this
// IS in fact western text - in which case the bulk of the UTF-8 encoded data (that is
// not already suspicious sequences) should be plain US-ASCII bytes. This, I
// arbitrarily decided, should be 80% (a random distribution, eg binary data, would yield
// approx 40%, so the chances of hitting this threshold by accident in random data are
// VERY low).
if ((suspiciousUTF8SequenceCount * 500000.0 / SampleBytes.Length >= 1) //suspicious sequences
&& (
//all suspicious, so cannot evaluate proportion of US-Ascii
SampleBytes.Length - suspiciousUTF8BytesTotal == 0
||
likelyUSASCIIBytesInSample * 1.0 / (SampleBytes.Length - suspiciousUTF8BytesTotal) >= 0.8
)
)
return Encoding.UTF8;
}
return null;
}
private static bool IsCommonUSASCIIByte(byte testByte)
{
if (testByte == 0x0A //lf
|| testByte == 0x0D //cr
|| testByte == 0x09 //tab
|| (testByte >= 0x20 && testByte <= 0x2F) //common punctuation
|| (testByte >= 0x30 && testByte <= 0x39) //digits
|| (testByte >= 0x3A && testByte <= 0x40) //common punctuation
|| (testByte >= 0x41 && testByte <= 0x5A) //capital letters
|| (testByte >= 0x5B && testByte <= 0x60) //common punctuation
|| (testByte >= 0x61 && testByte <= 0x7A) //lowercase letters
|| (testByte >= 0x7B && testByte <= 0x7E) //common punctuation
)
return true;
else
return false;
}
private static int DetectSuspiciousUTF8SequenceLength(byte[] SampleBytes, long currentPos)
{
int lengthFound = 0;
if (SampleBytes.Length >= currentPos + 1
&& SampleBytes[currentPos] == 0xC2
)
{
if (SampleBytes[currentPos + 1] == 0x81
|| SampleBytes[currentPos + 1] == 0x8D
|| SampleBytes[currentPos + 1] == 0x8F
)
lengthFound = 2;
else if (SampleBytes[currentPos + 1] == 0x90
|| SampleBytes[currentPos + 1] == 0x9D
)
lengthFound = 2;
else if (SampleBytes[currentPos + 1] >= 0xA0
&& SampleBytes[currentPos + 1] <= 0xBF
)
lengthFound = 2;
}
else if (SampleBytes.Length >= currentPos + 1
&& SampleBytes[currentPos] == 0xC3
)
{
if (SampleBytes[currentPos + 1] >= 0x80
&& SampleBytes[currentPos + 1] <= 0xBF
)
lengthFound = 2;
}
else if (SampleBytes.Length >= currentPos + 1
&& SampleBytes[currentPos] == 0xC5
)
{
if (SampleBytes[currentPos + 1] == 0x92
|| SampleBytes[currentPos + 1] == 0x93
)
lengthFound = 2;
else if (SampleBytes[currentPos + 1] == 0xA0
|| SampleBytes[currentPos + 1] == 0xA1
)
lengthFound = 2;
else if (SampleBytes[currentPos + 1] == 0xB8
|| SampleBytes[currentPos + 1] == 0xBD
|| SampleBytes[currentPos + 1] == 0xBE
)
lengthFound = 2;
}
else if (SampleBytes.Length >= currentPos + 1
&& SampleBytes[currentPos] == 0xC6
)
{
if (SampleBytes[currentPos + 1] == 0x92)
lengthFound = 2;
}
else if (SampleBytes.Length >= currentPos + 1
&& SampleBytes[currentPos] == 0xCB
)
{
if (SampleBytes[currentPos + 1] == 0x86
|| SampleBytes[currentPos + 1] == 0x9C
)
lengthFound = 2;
}
else if (SampleBytes.Length >= currentPos + 2
&& SampleBytes[currentPos] == 0xE2
)
{
if (SampleBytes[currentPos + 1] == 0x80)
{
if (SampleBytes[currentPos + 2] == 0x93
|| SampleBytes[currentPos + 2] == 0x94
)
lengthFound = 3;
if (SampleBytes[currentPos + 2] == 0x98
|| SampleBytes[currentPos + 2] == 0x99
|| SampleBytes[currentPos + 2] == 0x9A
)
lengthFound = 3;
if (SampleBytes[currentPos + 2] == 0x9C
|| SampleBytes[currentPos + 2] == 0x9D
|| SampleBytes[currentPos + 2] == 0x9E
)
lengthFound = 3;
if (SampleBytes[currentPos + 2] == 0xA0
|| SampleBytes[currentPos + 2] == 0xA1
|| SampleBytes[currentPos + 2] == 0xA2
)
lengthFound = 3;
if (SampleBytes[currentPos + 2] == 0xA6)
lengthFound = 3;
if (SampleBytes[currentPos + 2] == 0xB0)
lengthFound = 3;
if (SampleBytes[currentPos + 2] == 0xB9
|| SampleBytes[currentPos + 2] == 0xBA
)
lengthFound = 3;
}
else if (SampleBytes[currentPos + 1] == 0x82
&& SampleBytes[currentPos + 2] == 0xAC
)
lengthFound = 3;
else if (SampleBytes[currentPos + 1] == 0x84
&& SampleBytes[currentPos + 2] == 0xA2
)
lengthFound = 3;
}
return lengthFound;
}
}
}

View File

@@ -0,0 +1,222 @@
using System.Text;
using System.Drawing;
using System.Collections.Generic;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Exports colored text as HTML
/// </summary>
/// <remarks>At this time only TextStyle renderer is supported. Other styles is not exported.</remarks>
public class ExportToHTML
{
public string LineNumbersCSS = "<style type=\"text/css\"> .lineNumber{font-family : monospace; font-size : small; font-style : normal; font-weight : normal; color : Teal; background-color : ThreedFace;} </style>";
/// <summary>
/// Use nbsp; instead space
/// </summary>
public bool UseNbsp { get; set; }
/// <summary>
/// Use nbsp; instead space in beginning of line
/// </summary>
public bool UseForwardNbsp { get; set; }
/// <summary>
/// Use original font
/// </summary>
public bool UseOriginalFont { get; set; }
/// <summary>
/// Use style tag instead style attribute
/// </summary>
public bool UseStyleTag { get; set; }
/// <summary>
/// Use 'br' tag instead of '\n'
/// </summary>
public bool UseBr { get; set; }
/// <summary>
/// Includes line numbers
/// </summary>
public bool IncludeLineNumbers { get; set; }
FastColoredTextBox tb;
public ExportToHTML()
{
UseNbsp = true;
UseOriginalFont = true;
UseStyleTag = true;
UseBr = true;
}
public string GetHtml(FastColoredTextBox tb)
{
this.tb = tb;
Range sel = new Range(tb);
sel.SelectAll();
return GetHtml(sel);
}
public string GetHtml(Range r)
{
this.tb = r.tb;
Dictionary<StyleIndex, object> styles = new Dictionary<StyleIndex, object>();
StringBuilder sb = new StringBuilder();
StringBuilder tempSB = new StringBuilder();
StyleIndex currentStyleId = StyleIndex.None;
r.Normalize();
int currentLine = r.Start.iLine;
styles[currentStyleId] = null;
//
if (UseOriginalFont)
sb.AppendFormat("<font style=\"font-family: {0}, monospace; font-size: {1}pt; line-height: {2}px;\">",
r.tb.Font.Name, r.tb.Font.SizeInPoints, r.tb.CharHeight);
//
if (IncludeLineNumbers)
tempSB.AppendFormat("<span class=lineNumber>{0}</span> ", currentLine + 1);
//
bool hasNonSpace = false;
foreach (Place p in r)
{
Char c = r.tb[p.iLine][p.iChar];
if (c.style != currentStyleId)
{
Flush(sb, tempSB, currentStyleId);
currentStyleId = c.style;
styles[currentStyleId] = null;
}
if (p.iLine != currentLine)
{
for (int i = currentLine; i < p.iLine; i++)
{
tempSB.Append(UseBr ? "<br>" : "\r\n");
if (IncludeLineNumbers)
tempSB.AppendFormat("<span class=lineNumber>{0}</span> ", i + 2);
}
currentLine = p.iLine;
hasNonSpace = false;
}
switch (c.c)
{
case ' ':
if ((hasNonSpace || !UseForwardNbsp) && !UseNbsp)
goto default;
tempSB.Append("&nbsp;");
break;
case '<':
tempSB.Append("&lt;");
break;
case '>':
tempSB.Append("&gt;");
break;
case '&':
tempSB.Append("&amp;");
break;
default:
hasNonSpace = true;
tempSB.Append(c.c);
break;
}
}
Flush(sb, tempSB, currentStyleId);
if (UseOriginalFont)
sb.Append("</font>");
//build styles
if (UseStyleTag)
{
tempSB.Length = 0;
tempSB.Append("<style type=\"text/css\">");
foreach (var styleId in styles.Keys)
tempSB.AppendFormat(".fctb{0}{{ {1} }}\r\n", GetStyleName(styleId), GetCss(styleId));
tempSB.Append("</style>");
sb.Insert(0, tempSB.ToString());
}
if (IncludeLineNumbers)
sb.Insert(0, LineNumbersCSS);
return sb.ToString();
}
private string GetCss(StyleIndex styleIndex)
{
List<Style> styles = new List<Style>();
//find text renderer
TextStyle textStyle = null;
int mask = 1;
bool hasTextStyle = false;
for (int i = 0; i < tb.Styles.Length; i++)
{
if (tb.Styles[i] != null && ((int)styleIndex & mask) != 0)
if (tb.Styles[i].IsExportable)
{
var style = tb.Styles[i];
styles.Add(style);
bool isTextStyle = style is TextStyle;
if (isTextStyle)
if (!hasTextStyle || tb.AllowSeveralTextStyleDrawing)
{
hasTextStyle = true;
textStyle = style as TextStyle;
}
}
mask = mask << 1;
}
//add TextStyle css
string result = "";
if (!hasTextStyle)
{
//draw by default renderer
result = tb.DefaultStyle.GetCSS();
}
else
{
result = textStyle.GetCSS();
}
//add no TextStyle css
foreach(var style in styles)
// if (style != textStyle)
if(!(style is TextStyle))
result += style.GetCSS();
return result;
}
public static string GetColorAsString(Color color)
{
if(color==Color.Transparent)
return "";
return string.Format("#{0:x2}{1:x2}{2:x2}", color.R, color.G, color.B);
}
string GetStyleName(StyleIndex styleIndex)
{
return styleIndex.ToString().Replace(" ", "").Replace(",", "");
}
private void Flush(StringBuilder sb, StringBuilder tempSB, StyleIndex currentStyle)
{
//find textRenderer
if (tempSB.Length == 0)
return;
if (UseStyleTag)
sb.AppendFormat("<font class=fctb{0}>{1}</font>", GetStyleName(currentStyle), tempSB.ToString());
else
{
string css = GetCss(currentStyle);
if(css!="")
sb.AppendFormat("<font style=\"{0}\">", css);
sb.Append(tempSB.ToString());
if (css != "")
sb.Append("</font>");
}
tempSB.Length = 0;
}
}
}

View File

@@ -0,0 +1,217 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Exports colored text as RTF
/// </summary>
/// <remarks>At this time only TextStyle renderer is supported. Other styles are not exported.</remarks>
public class ExportToRTF
{
/// <summary>
/// Includes line numbers
/// </summary>
public bool IncludeLineNumbers { get; set; }
/// <summary>
/// Use original font
/// </summary>
public bool UseOriginalFont { get; set; }
FastColoredTextBox tb;
Dictionary<Color, int> colorTable = new Dictionary<Color, int>();
public ExportToRTF()
{
UseOriginalFont = true;
}
public string GetRtf(FastColoredTextBox tb)
{
this.tb = tb;
Range sel = new Range(tb);
sel.SelectAll();
return GetRtf(sel);
}
public string GetRtf(Range r)
{
this.tb = r.tb;
var styles = new Dictionary<StyleIndex, object>();
var sb = new StringBuilder();
var tempSB = new StringBuilder();
var currentStyleId = StyleIndex.None;
r.Normalize();
int currentLine = r.Start.iLine;
styles[currentStyleId] = null;
colorTable.Clear();
//
var lineNumberColor = GetColorTableNumber(r.tb.LineNumberColor);
if (IncludeLineNumbers)
tempSB.AppendFormat(@"{{\cf{1} {0}}}\tab", currentLine + 1, lineNumberColor);
//
foreach (Place p in r)
{
Char c = r.tb[p.iLine][p.iChar];
if (c.style != currentStyleId)
{
Flush(sb, tempSB, currentStyleId);
currentStyleId = c.style;
styles[currentStyleId] = null;
}
if (p.iLine != currentLine)
{
for (int i = currentLine; i < p.iLine; i++)
{
tempSB.AppendLine(@"\line");
if (IncludeLineNumbers)
tempSB.AppendFormat(@"{{\cf{1} {0}}}\tab", i + 2, lineNumberColor);
}
currentLine = p.iLine;
}
switch (c.c)
{
case '\\':
tempSB.Append(@"\\");
break;
case '{':
tempSB.Append(@"\{");
break;
case '}':
tempSB.Append(@"\}");
break;
default:
var ch = c.c;
var code = (int)ch;
if(code < 128)
tempSB.Append(c.c);
else
tempSB.AppendFormat(@"{{\u{0}}}", code);
break;
}
}
Flush(sb, tempSB, currentStyleId);
//build color table
var list = new SortedList<int, Color>();
foreach (var pair in colorTable)
list.Add(pair.Value, pair.Key);
tempSB.Length = 0;
tempSB.AppendFormat(@"{{\colortbl;");
foreach (var pair in list)
tempSB.Append(GetColorAsString(pair.Value)+";");
tempSB.AppendLine("}");
//
if (UseOriginalFont)
{
sb.Insert(0, string.Format(@"{{\fonttbl{{\f0\fmodern {0};}}}}{{\fs{1} ",
tb.Font.Name, (int)(2 * tb.Font.SizeInPoints), tb.CharHeight));
sb.AppendLine(@"}");
}
sb.Insert(0, tempSB.ToString());
sb.Insert(0, @"{\rtf1\ud\deff0");
sb.AppendLine(@"}");
return sb.ToString();
}
private RTFStyleDescriptor GetRtfDescriptor(StyleIndex styleIndex)
{
List<Style> styles = new List<Style>();
//find text renderer
TextStyle textStyle = null;
int mask = 1;
bool hasTextStyle = false;
for (int i = 0; i < tb.Styles.Length; i++)
{
if (tb.Styles[i] != null && ((int)styleIndex & mask) != 0)
if (tb.Styles[i].IsExportable)
{
var style = tb.Styles[i];
styles.Add(style);
bool isTextStyle = style is TextStyle;
if (isTextStyle)
if (!hasTextStyle || tb.AllowSeveralTextStyleDrawing)
{
hasTextStyle = true;
textStyle = style as TextStyle;
}
}
mask = mask << 1;
}
//add TextStyle css
RTFStyleDescriptor result = null;
if (!hasTextStyle)
{
//draw by default renderer
result = tb.DefaultStyle.GetRTF();
}
else
{
result = textStyle.GetRTF();
}
return result;
}
public static string GetColorAsString(Color color)
{
if (color == Color.Transparent)
return "";
return string.Format(@"\red{0}\green{1}\blue{2}", color.R, color.G, color.B);
}
private void Flush(StringBuilder sb, StringBuilder tempSB, StyleIndex currentStyle)
{
//find textRenderer
if (tempSB.Length == 0)
return;
var desc = GetRtfDescriptor(currentStyle);
var cf = GetColorTableNumber(desc.ForeColor);
var cb = GetColorTableNumber(desc.BackColor);
var tags = new StringBuilder();
if (cf >= 0)
tags.AppendFormat(@"\cf{0}", cf);
if (cb >= 0)
tags.AppendFormat(@"\highlight{0}", cb);
if(!string.IsNullOrEmpty(desc.AdditionalTags))
tags.Append(desc.AdditionalTags.Trim());
if(tags.Length > 0)
sb.AppendFormat(@"{{{0} {1}}}", tags, tempSB.ToString());
else
sb.Append(tempSB.ToString());
tempSB.Length = 0;
}
private int GetColorTableNumber(Color color)
{
if (color.A == 0)
return -1;
if (!colorTable.ContainsKey(color))
colorTable[color] = colorTable.Count + 1;
return colorTable[color];
}
}
public class RTFStyleDescriptor
{
public Color ForeColor { get; set; }
public Color BackColor { get; set; }
public string AdditionalTags { get; set; }
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{6DD14A85-CCFC-4774-BD26-0F5772512319}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>FastColoredTextBoxNS</RootNamespace>
<AssemblyName>FastColoredTextBox</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\FastColoredTextBox.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>FCTB_key.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.XML" />
</ItemGroup>
<ItemGroup>
<Compile Include="AutocompleteItem.cs" />
<Compile Include="AutocompleteMenu.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Bookmarks.cs" />
<Compile Include="Char.cs" />
<Compile Include="DocumentMap.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="EncodingDetector.cs" />
<Compile Include="ExportToHTML.cs" />
<Compile Include="ExportToRTF.cs" />
<Compile Include="GoToForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="GoToForm.Designer.cs">
<DependentUpon>GoToForm.cs</DependentUpon>
</Compile>
<Compile Include="Hints.cs" />
<Compile Include="HotkeysEditorForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="HotkeysEditorForm.Designer.cs">
<DependentUpon>HotkeysEditorForm.cs</DependentUpon>
</Compile>
<Compile Include="LineNumberFormatting.cs" />
<Compile Include="LinesAccessor.cs" />
<Compile Include="MacrosManager.cs" />
<Compile Include="PlatformType.cs" />
<Compile Include="Hotkeys.cs" />
<Compile Include="Ruler.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Ruler.Designer.cs">
<DependentUpon>Ruler.cs</DependentUpon>
</Compile>
<Compile Include="SyntaxDescriptor.cs" />
<Compile Include="SyntaxHighlighter.cs" />
<Compile Include="ReplaceForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="ReplaceForm.Designer.cs">
<DependentUpon>ReplaceForm.cs</DependentUpon>
</Compile>
<Compile Include="FastColoredTextBox.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="CommandManager.cs" />
<Compile Include="Commands.cs" />
<Compile Include="FindForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FindForm.Designer.cs">
<DependentUpon>FindForm.cs</DependentUpon>
</Compile>
<Compile Include="LimitedStack.cs" />
<Compile Include="Line.cs" />
<Compile Include="Place.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Range.cs" />
<Compile Include="Style.cs" />
<Compile Include="TextSource.cs" />
<Compile Include="TypeDescriptor.cs" />
<Compile Include="FileTextSource.cs" />
<Compile Include="UnfocusablePanel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="VisualMarker.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="FastColoredTextBox.resx">
<DependentUpon>FastColoredTextBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="FindForm.resx">
<DependentUpon>FindForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="GoToForm.resx">
<DependentUpon>GoToForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="HotkeysEditorForm.resx">
<DependentUpon>HotkeysEditorForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ReplaceForm.resx">
<DependentUpon>ReplaceForm.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="FCTB_key.snk" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,492 @@
//#define debug
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace FastColoredTextBoxNS
{
/// <summary>
/// This class contains the source text (chars and styles).
/// It stores a text lines, the manager of commands, undo/redo stack, styles.
/// </summary>
public class FileTextSource : TextSource, IDisposable
{
List<int> sourceFileLinePositions = new List<int>();
FileStream fs;
Encoding fileEncoding;
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
/// <summary>
/// Occurs when need to display line in the textbox
/// </summary>
public event EventHandler<LineNeededEventArgs> LineNeeded;
/// <summary>
/// Occurs when need to save line in the file
/// </summary>
public event EventHandler<LinePushedEventArgs> LinePushed;
public FileTextSource(FastColoredTextBox currentTB)
: base(currentTB)
{
timer.Interval = 10000;
timer.Tick += new EventHandler(timer_Tick);
timer.Enabled = true;
SaveEOL = Environment.NewLine;
}
void timer_Tick(object sender, EventArgs e)
{
timer.Enabled = false;
try
{
UnloadUnusedLines();
}
finally
{
timer.Enabled = true;
}
}
private void UnloadUnusedLines()
{
const int margin = 2000;
var iStartVisibleLine = CurrentTB.VisibleRange.Start.iLine;
var iFinishVisibleLine = CurrentTB.VisibleRange.End.iLine;
int count = 0;
for (int i = 0; i < Count; i++)
if (base.lines[i] != null && !base.lines[i].IsChanged && Math.Abs(i - iFinishVisibleLine) > margin)
{
base.lines[i] = null;
count++;
}
#if debug
Console.WriteLine("UnloadUnusedLines: " + count);
#endif
}
public void OpenFile(string fileName, Encoding enc)
{
Clear();
if (fs != null)
fs.Dispose();
SaveEOL = Environment.NewLine;
//read lines of file
fs = new FileStream(fileName, FileMode.Open);
var length = fs.Length;
//read signature
enc = DefineEncoding(enc, fs);
int shift = DefineShift(enc);
//first line
sourceFileLinePositions.Add((int)fs.Position);
base.lines.Add(null);
//other lines
sourceFileLinePositions.Capacity = (int)(length/7 + 1000);
//int prev = 0;
//while(fs.Position < length)
//{
// var b = fs.ReadByte();
// if (b == 10)// \n
// {
// sourceFileLinePositions.Add((int)(fs.Position) + shift);
// base.lines.Add(null);
// }else
// if (prev == 13)// \r (Mac format)
// {
// sourceFileLinePositions.Add((int)(fs.Position - 1) + shift);
// base.lines.Add(null);
// SaveEOL = "\r";
// }
// prev = b;
//}
//if (prev == 13)
//{
// sourceFileLinePositions.Add((int)(fs.Position) + shift);
// base.lines.Add(null);
//}
int prev = 0;
int prevPos = 0;
BinaryReader br = new BinaryReader(fs, enc);
while (fs.Position < length)
{
prevPos = (int)fs.Position;
var b = br.ReadChar();
if (b == 10)// \n
{
sourceFileLinePositions.Add((int)fs.Position);
base.lines.Add(null);
}
else
if (prev == 13)// \r (Mac format)
{
sourceFileLinePositions.Add((int)prevPos);
base.lines.Add(null);
SaveEOL = "\r";
}
prev = b;
}
if (prev == 13)
{
sourceFileLinePositions.Add((int)prevPos);
base.lines.Add(null);
}
if(length > 2000000)
GC.Collect();
Line[] temp = new Line[100];
var c = base.lines.Count;
base.lines.AddRange(temp);
base.lines.TrimExcess();
base.lines.RemoveRange(c, temp.Length);
int[] temp2 = new int[100];
c = base.lines.Count;
sourceFileLinePositions.AddRange(temp2);
sourceFileLinePositions.TrimExcess();
sourceFileLinePositions.RemoveRange(c, temp.Length);
fileEncoding = enc;
OnLineInserted(0, Count);
//load first lines for calc width of the text
var linesCount = Math.Min(lines.Count, CurrentTB.ClientRectangle.Height/CurrentTB.CharHeight);
for (int i = 0; i < linesCount; i++)
LoadLineFromSourceFile(i);
//
NeedRecalc(new TextChangedEventArgs(0, linesCount - 1));
if (CurrentTB.WordWrap)
OnRecalcWordWrap(new TextChangedEventArgs(0, linesCount - 1));
}
private int DefineShift(Encoding enc)
{
if (enc.IsSingleByte)
return 0;
if (enc.HeaderName == "unicodeFFFE")
return 0;//UTF16 BE
if (enc.HeaderName == "utf-16")
return 1;//UTF16 LE
if (enc.HeaderName == "utf-32BE")
return 0;//UTF32 BE
if (enc.HeaderName == "utf-32")
return 3;//UTF32 LE
return 0;
}
private static Encoding DefineEncoding(Encoding enc, FileStream fs)
{
int bytesPerSignature = 0;
byte[] signature = new byte[4];
int c = fs.Read(signature, 0, 4);
if (signature[0] == 0xFF && signature[1] == 0xFE && signature[2] == 0x00 && signature[3] == 0x00 && c >= 4)
{
enc = Encoding.UTF32;//UTF32 LE
bytesPerSignature = 4;
}
else
if (signature[0] == 0x00 && signature[1] == 0x00 && signature[2] == 0xFE && signature[3] == 0xFF)
{
enc = new UTF32Encoding(true, true);//UTF32 BE
bytesPerSignature = 4;
}
else
if (signature[0] == 0xEF && signature[1] == 0xBB && signature[2] == 0xBF)
{
enc = Encoding.UTF8;//UTF8
bytesPerSignature = 3;
}
else
if (signature[0] == 0xFE && signature[1] == 0xFF)
{
enc = Encoding.BigEndianUnicode;//UTF16 BE
bytesPerSignature = 2;
}
else
if (signature[0] == 0xFF && signature[1] == 0xFE)
{
enc = Encoding.Unicode;//UTF16 LE
bytesPerSignature = 2;
}
fs.Seek(bytesPerSignature, SeekOrigin.Begin);
return enc;
}
public void CloseFile()
{
if(fs!=null)
try
{
fs.Dispose();
}
catch
{
;
}
fs = null;
}
/// <summary>
/// End Of Line characters used for saving
/// </summary>
public string SaveEOL { get; set; }
public override void SaveToFile(string fileName, Encoding enc)
{
//
var newLinePos = new List<int>(Count);
//create temp file
var dir = Path.GetDirectoryName(fileName);
var tempFileName = Path.Combine(dir, Path.GetFileNameWithoutExtension(fileName) + ".tmp");
StreamReader sr = new StreamReader(fs, fileEncoding);
using (FileStream tempFs = new FileStream(tempFileName, FileMode.Create))
using (StreamWriter sw = new StreamWriter(tempFs, enc))
{
sw.Flush();
for (int i = 0; i < Count; i++)
{
newLinePos.Add((int)tempFs.Length);
var sourceLine = ReadLine(sr, i);//read line from source file
string line;
bool lineIsChanged = lines[i] != null && lines[i].IsChanged;
if (lineIsChanged)
line = lines[i].Text;
else
line = sourceLine;
//call event handler
if (LinePushed != null)
{
var args = new LinePushedEventArgs(sourceLine, i, lineIsChanged ? line : null);
LinePushed(this, args);
if(args.SavedText != null)
line = args.SavedText;
}
//save line to file
sw.Write(line);
if (i < Count - 1)
sw.Write(SaveEOL);
sw.Flush();
}
}
//clear lines buffer
for (int i = 0; i < Count; i++)
lines[i] = null;
//deattach from source file
sr.Dispose();
fs.Dispose();
//delete target file
if (File.Exists(fileName))
File.Delete(fileName);
//rename temp file
File.Move(tempFileName, fileName);
//binding to new file
sourceFileLinePositions = newLinePos;
fs = new FileStream(fileName, FileMode.Open);
this.fileEncoding = enc;
}
private string ReadLine(StreamReader sr, int i)
{
string line;
var filePos = sourceFileLinePositions[i];
if (filePos < 0)
return "";
fs.Seek(filePos, SeekOrigin.Begin);
sr.DiscardBufferedData();
line = sr.ReadLine();
return line;
}
public override void ClearIsChanged()
{
foreach (var line in lines)
if(line!=null)
line.IsChanged = false;
}
public override Line this[int i]
{
get
{
if (base.lines[i] != null)
return lines[i];
else
LoadLineFromSourceFile(i);
return lines[i];
}
set
{
throw new NotImplementedException();
}
}
private void LoadLineFromSourceFile(int i)
{
var line = CreateLine();
fs.Seek(sourceFileLinePositions[i], SeekOrigin.Begin);
StreamReader sr = new StreamReader(fs, fileEncoding);
var s = sr.ReadLine();
if (s == null)
s = "";
//call event handler
if(LineNeeded!=null)
{
var args = new LineNeededEventArgs(s, i);
LineNeeded(this, args);
s = args.DisplayedLineText;
if (s == null)
return;
}
foreach (var c in s)
line.Add(new Char(c));
base.lines[i] = line;
if (CurrentTB.WordWrap)
OnRecalcWordWrap(new TextChangedEventArgs(i, i));
}
public override void InsertLine(int index, Line line)
{
sourceFileLinePositions.Insert(index, -1);
base.InsertLine(index, line);
}
public override void RemoveLine(int index, int count)
{
sourceFileLinePositions.RemoveRange(index, count);
base.RemoveLine(index, count);
}
public override void Clear()
{
base.Clear();
}
public override int GetLineLength(int i)
{
if (base.lines[i] == null)
return 0;
else
return base.lines[i].Count;
}
public override bool LineHasFoldingStartMarker(int iLine)
{
if (lines[iLine] == null)
return false;
else
return !string.IsNullOrEmpty(lines[iLine].FoldingStartMarker);
}
public override bool LineHasFoldingEndMarker(int iLine)
{
if (lines[iLine] == null)
return false;
else
return !string.IsNullOrEmpty(lines[iLine].FoldingEndMarker);
}
public override void Dispose()
{
if (fs != null)
fs.Dispose();
timer.Dispose();
}
internal void UnloadLine(int iLine)
{
if (lines[iLine] != null && !lines[iLine].IsChanged)
lines[iLine] = null;
}
}
public class LineNeededEventArgs : EventArgs
{
public string SourceLineText { get; private set; }
public int DisplayedLineIndex { get; private set; }
/// <summary>
/// This text will be displayed in textbox
/// </summary>
public string DisplayedLineText { get; set; }
public LineNeededEventArgs(string sourceLineText, int displayedLineIndex)
{
this.SourceLineText = sourceLineText;
this.DisplayedLineIndex = displayedLineIndex;
this.DisplayedLineText = sourceLineText;
}
}
public class LinePushedEventArgs : EventArgs
{
public string SourceLineText { get; private set; }
public int DisplayedLineIndex { get; private set; }
/// <summary>
/// This property contains only changed text.
/// If text of line is not changed, this property contains null.
/// </summary>
public string DisplayedLineText { get; private set; }
/// <summary>
/// This text will be saved in the file
/// </summary>
public string SavedText { get; set; }
public LinePushedEventArgs(string sourceLineText, int displayedLineIndex, string displayedLineText)
{
this.SourceLineText = sourceLineText;
this.DisplayedLineIndex = displayedLineIndex;
this.DisplayedLineText = displayedLineText;
this.SavedText = displayedLineText;
}
}
class CharReader : TextReader
{
public override int Read()
{
return base.Read();
}
}
}

View File

@@ -0,0 +1,146 @@
namespace FastColoredTextBoxNS
{
partial class FindForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btClose = new System.Windows.Forms.Button();
this.btFindNext = new System.Windows.Forms.Button();
this.tbFind = new System.Windows.Forms.TextBox();
this.cbRegex = new System.Windows.Forms.CheckBox();
this.cbMatchCase = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.cbWholeWord = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// btClose
//
this.btClose.Location = new System.Drawing.Point(273, 73);
this.btClose.Name = "btClose";
this.btClose.Size = new System.Drawing.Size(75, 23);
this.btClose.TabIndex = 5;
this.btClose.Text = "Close";
this.btClose.UseVisualStyleBackColor = true;
this.btClose.Click += new System.EventHandler(this.btClose_Click);
//
// btFindNext
//
this.btFindNext.Location = new System.Drawing.Point(192, 73);
this.btFindNext.Name = "btFindNext";
this.btFindNext.Size = new System.Drawing.Size(75, 23);
this.btFindNext.TabIndex = 4;
this.btFindNext.Text = "Find next";
this.btFindNext.UseVisualStyleBackColor = true;
this.btFindNext.Click += new System.EventHandler(this.btFindNext_Click);
//
// tbFind
//
this.tbFind.Location = new System.Drawing.Point(42, 12);
this.tbFind.Name = "tbFind";
this.tbFind.Size = new System.Drawing.Size(306, 20);
this.tbFind.TabIndex = 0;
this.tbFind.TextChanged += new System.EventHandler(this.cbMatchCase_CheckedChanged);
this.tbFind.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.tbFind_KeyPress);
//
// cbRegex
//
this.cbRegex.AutoSize = true;
this.cbRegex.Location = new System.Drawing.Point(249, 38);
this.cbRegex.Name = "cbRegex";
this.cbRegex.Size = new System.Drawing.Size(57, 17);
this.cbRegex.TabIndex = 3;
this.cbRegex.Text = "Regex";
this.cbRegex.UseVisualStyleBackColor = true;
this.cbRegex.CheckedChanged += new System.EventHandler(this.cbMatchCase_CheckedChanged);
//
// cbMatchCase
//
this.cbMatchCase.AutoSize = true;
this.cbMatchCase.Location = new System.Drawing.Point(42, 38);
this.cbMatchCase.Name = "cbMatchCase";
this.cbMatchCase.Size = new System.Drawing.Size(82, 17);
this.cbMatchCase.TabIndex = 1;
this.cbMatchCase.Text = "Match case";
this.cbMatchCase.UseVisualStyleBackColor = true;
this.cbMatchCase.CheckedChanged += new System.EventHandler(this.cbMatchCase_CheckedChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(6, 15);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(33, 13);
this.label1.TabIndex = 5;
this.label1.Text = "Find: ";
//
// cbWholeWord
//
this.cbWholeWord.AutoSize = true;
this.cbWholeWord.Location = new System.Drawing.Point(130, 38);
this.cbWholeWord.Name = "cbWholeWord";
this.cbWholeWord.Size = new System.Drawing.Size(113, 17);
this.cbWholeWord.TabIndex = 2;
this.cbWholeWord.Text = "Match whole word";
this.cbWholeWord.UseVisualStyleBackColor = true;
this.cbWholeWord.CheckedChanged += new System.EventHandler(this.cbMatchCase_CheckedChanged);
//
// FindForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(360, 108);
this.Controls.Add(this.cbWholeWord);
this.Controls.Add(this.label1);
this.Controls.Add(this.cbMatchCase);
this.Controls.Add(this.cbRegex);
this.Controls.Add(this.tbFind);
this.Controls.Add(this.btFindNext);
this.Controls.Add(this.btClose);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "FindForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Find";
this.TopMost = true;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FindForm_FormClosing);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btClose;
private System.Windows.Forms.Button btFindNext;
private System.Windows.Forms.CheckBox cbRegex;
private System.Windows.Forms.CheckBox cbMatchCase;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.CheckBox cbWholeWord;
public System.Windows.Forms.TextBox tbFind;
}
}

View File

@@ -0,0 +1,129 @@
using System;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections.Generic;
namespace FastColoredTextBoxNS
{
public partial class FindForm : Form
{
bool firstSearch = true;
Place startPlace;
FastColoredTextBox tb;
public FindForm(FastColoredTextBox tb)
{
InitializeComponent();
this.tb = tb;
}
private void btClose_Click(object sender, EventArgs e)
{
Close();
}
private void btFindNext_Click(object sender, EventArgs e)
{
FindNext(tbFind.Text);
}
public virtual void FindNext(string pattern)
{
try
{
RegexOptions opt = cbMatchCase.Checked ? RegexOptions.None : RegexOptions.IgnoreCase;
if (!cbRegex.Checked)
pattern = Regex.Escape(pattern);
if (cbWholeWord.Checked)
pattern = "\\b" + pattern + "\\b";
//
Range range = tb.Selection.Clone();
range.Normalize();
//
if (firstSearch)
{
startPlace = range.Start;
firstSearch = false;
}
//
range.Start = range.End;
if (range.Start >= startPlace)
range.End = new Place(tb.GetLineLength(tb.LinesCount - 1), tb.LinesCount - 1);
else
range.End = startPlace;
//
foreach (var r in range.GetRangesByLines(pattern, opt))
{
tb.Selection = r;
tb.DoSelectionVisible();
tb.Invalidate();
return;
}
//
if (range.Start >= startPlace && startPlace > Place.Empty)
{
tb.Selection.Start = new Place(0, 0);
FindNext(pattern);
return;
}
MessageBox.Show("Not found");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void tbFind_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\r')
{
btFindNext.PerformClick();
e.Handled = true;
return;
}
if (e.KeyChar == '\x1b')
{
Hide();
e.Handled = true;
return;
}
}
private void FindForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
Hide();
}
this.tb.Focus();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Escape)
{
this.Close();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
protected override void OnActivated(EventArgs e)
{
tbFind.Focus();
ResetSerach();
}
void ResetSerach()
{
firstSearch = true;
}
private void cbMatchCase_CheckedChanged(object sender, EventArgs e)
{
ResetSerach();
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,110 @@
namespace FastColoredTextBoxNS
{
partial class GoToForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label = new System.Windows.Forms.Label();
this.tbLineNumber = new System.Windows.Forms.TextBox();
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label
//
this.label.AutoSize = true;
this.label.Location = new System.Drawing.Point(12, 9);
this.label.Name = "label";
this.label.Size = new System.Drawing.Size(96, 13);
this.label.TabIndex = 0;
this.label.Text = "Line Number (1/1):";
//
// tbLineNumber
//
this.tbLineNumber.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tbLineNumber.Location = new System.Drawing.Point(12, 29);
this.tbLineNumber.Name = "tbLineNumber";
this.tbLineNumber.Size = new System.Drawing.Size(296, 20);
this.tbLineNumber.TabIndex = 1;
//
// btnOk
//
this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOk.Location = new System.Drawing.Point(152, 71);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(75, 23);
this.btnOk.TabIndex = 2;
this.btnOk.Text = "OK";
this.btnOk.UseVisualStyleBackColor = true;
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(233, 71);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 3;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// GoToForm
//
this.AcceptButton = this.btnOk;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(320, 106);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOk);
this.Controls.Add(this.tbLineNumber);
this.Controls.Add(this.label);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "GoToForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Go To Line";
this.TopMost = true;
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label;
private System.Windows.Forms.TextBox tbLineNumber;
private System.Windows.Forms.Button btnOk;
private System.Windows.Forms.Button btnCancel;
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Windows.Forms;
namespace FastColoredTextBoxNS
{
public partial class GoToForm : Form
{
public int SelectedLineNumber { get; set; }
public int TotalLineCount { get; set; }
public GoToForm()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.tbLineNumber.Text = this.SelectedLineNumber.ToString();
this.label.Text = String.Format("Line number (1 - {0}):", this.TotalLineCount);
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
this.tbLineNumber.Focus();
}
private void btnOk_Click(object sender, EventArgs e)
{
int enteredLine;
if (int.TryParse(this.tbLineNumber.Text, out enteredLine))
{
enteredLine = Math.Min(enteredLine, this.TotalLineCount);
enteredLine = Math.Max(1, enteredLine);
this.SelectedLineNumber = enteredLine;
}
this.DialogResult = DialogResult.OK;
this.Close();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,388 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Collection of Hints.
/// This is temporary buffer for currently displayed hints.
/// </summary>
public class Hints : ICollection<Hint>, IDisposable
{
FastColoredTextBox tb;
List<Hint> items = new List<Hint>();
public Hints(FastColoredTextBox tb)
{
this.tb = tb;
tb.TextChanged += OnTextBoxTextChanged;
tb.KeyDown += OnTextBoxKeyDown;
tb.VisibleRangeChanged += OnTextBoxVisibleRangeChanged;
}
protected virtual void OnTextBoxKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == System.Windows.Forms.Keys.Escape && e.Modifiers == System.Windows.Forms.Keys.None)
Clear();
}
protected virtual void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
Clear();
}
public void Dispose()
{
tb.TextChanged -= OnTextBoxTextChanged;
tb.KeyDown -= OnTextBoxKeyDown;
tb.VisibleRangeChanged -= OnTextBoxVisibleRangeChanged;
}
void OnTextBoxVisibleRangeChanged(object sender, EventArgs e)
{
if (items.Count == 0)
return;
tb.NeedRecalc(true);
foreach (var item in items)
{
LayoutHint(item);
item.HostPanel.Invalidate();
}
}
private void LayoutHint(Hint hint)
{
if (hint.Inline)
{
if (hint.Range.Start.iLine < tb.LineInfos.Count - 1)
hint.HostPanel.Top = tb.LineInfos[hint.Range.Start.iLine + 1].startY - hint.TopPadding - hint.HostPanel.Height - tb.VerticalScroll.Value;
else
hint.HostPanel.Top = tb.TextHeight + tb.Paddings.Top - hint.HostPanel.Height - tb.VerticalScroll.Value;
}
else
{
if (hint.Range.Start.iLine > tb.LinesCount - 1) return;
if (hint.Range.Start.iLine == tb.LinesCount - 1)
{
var y = tb.LineInfos[hint.Range.Start.iLine].startY - tb.VerticalScroll.Value + tb.CharHeight;
if (y + hint.HostPanel.Height + 1 > tb.ClientRectangle.Bottom)
{
hint.HostPanel.Top = Math.Max(0, tb.LineInfos[hint.Range.Start.iLine].startY - tb.VerticalScroll.Value - hint.HostPanel.Height);
}
else
hint.HostPanel.Top = y;
}
else
{
hint.HostPanel.Top = tb.LineInfos[hint.Range.Start.iLine + 1].startY - tb.VerticalScroll.Value;
if (hint.HostPanel.Bottom > tb.ClientRectangle.Bottom)
hint.HostPanel.Top = tb.LineInfos[hint.Range.Start.iLine + 1].startY - tb.CharHeight - hint.TopPadding - hint.HostPanel.Height - tb.VerticalScroll.Value;
}
}
if (hint.Dock == DockStyle.Fill)
{
hint.Width = tb.ClientSize.Width - tb.LeftIndent - 2;
hint.HostPanel.Left = tb.LeftIndent;
}
else
{
var p1 = tb.PlaceToPoint(hint.Range.Start);
var p2 = tb.PlaceToPoint(hint.Range.End);
var cx = (p1.X + p2.X) / 2;
var x = cx - hint.HostPanel.Width / 2;
hint.HostPanel.Left = Math.Max( tb.LeftIndent, x);
if(hint.HostPanel.Right > tb.ClientSize.Width)
hint.HostPanel.Left = Math.Max(tb.LeftIndent, x - (hint.HostPanel.Right - tb.ClientSize.Width));
}
}
public IEnumerator<Hint> GetEnumerator()
{
foreach (var item in items)
yield return item;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Clears all displayed hints
/// </summary>
public void Clear()
{
items.Clear();
if (tb.Controls.Count != 0)
{
var toDelete = new List<Control>();
foreach (Control item in tb.Controls)
if (item is UnfocusablePanel)
toDelete.Add(item);
foreach (var item in toDelete)
tb.Controls.Remove(item);
for (int i = 0; i < tb.LineInfos.Count; i++)
{
var li = tb.LineInfos[i];
li.bottomPadding = 0;
tb.LineInfos[i] = li;
}
tb.NeedRecalc();
tb.Invalidate();
tb.Select();
tb.ActiveControl = null;
}
}
/// <summary>
/// Add and shows the hint
/// </summary>
/// <param name="hint"></param>
public void Add(Hint hint)
{
items.Add(hint);
if (hint.Inline/* || hint.Range.Start.iLine >= tb.LinesCount - 1*/)
{
var li = tb.LineInfos[hint.Range.Start.iLine];
hint.TopPadding = li.bottomPadding;
li.bottomPadding += hint.HostPanel.Height;
tb.LineInfos[hint.Range.Start.iLine] = li;
tb.NeedRecalc(true);
}
LayoutHint(hint);
tb.OnVisibleRangeChanged();
hint.HostPanel.Parent = tb;
tb.Select();
tb.ActiveControl = null;
tb.Invalidate();
}
/// <summary>
/// Is collection contains the hint?
/// </summary>
public bool Contains(Hint item)
{
return items.Contains(item);
}
public void CopyTo(Hint[] array, int arrayIndex)
{
items.CopyTo(array, arrayIndex);
}
/// <summary>
/// Count of hints
/// </summary>
public int Count
{
get { return items.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(Hint item)
{
throw new NotImplementedException();
}
}
/// <summary>
/// Hint of FastColoredTextbox
/// </summary>
public class Hint
{
/// <summary>
/// Text of simple hint
/// </summary>
public string Text { get { return HostPanel.Text; } set { HostPanel.Text = value; } }
/// <summary>
/// Linked range
/// </summary>
public Range Range { get; set; }
/// <summary>
/// Backcolor
/// </summary>
public Color BackColor { get { return HostPanel.BackColor; } set { HostPanel.BackColor = value; } }
/// <summary>
/// Second backcolor
/// </summary>
public Color BackColor2 { get { return HostPanel.BackColor2; } set { HostPanel.BackColor2 = value; } }
/// <summary>
/// Border color
/// </summary>
public Color BorderColor { get { return HostPanel.BorderColor; } set { HostPanel.BorderColor = value; } }
/// <summary>
/// Fore color
/// </summary>
public Color ForeColor { get { return HostPanel.ForeColor; } set { HostPanel.ForeColor = value; } }
/// <summary>
/// Text alignment
/// </summary>
public StringAlignment TextAlignment { get { return HostPanel.TextAlignment; } set { HostPanel.TextAlignment = value; } }
/// <summary>
/// Font
/// </summary>
public Font Font { get { return HostPanel.Font; } set { HostPanel.Font = value; } }
/// <summary>
/// Occurs when user click on simple hint
/// </summary>
public event EventHandler Click
{
add { HostPanel.Click += value; }
remove { HostPanel.Click -= value; }
}
/// <summary>
/// Inner control
/// </summary>
public Control InnerControl { get; set; }
/// <summary>
/// Docking (allows None and Fill only)
/// </summary>
public DockStyle Dock { get; set; }
/// <summary>
/// Width of hint (if Dock is None)
/// </summary>
public int Width { get { return HostPanel.Width; } set { HostPanel.Width = value; } }
/// <summary>
/// Height of hint
/// </summary>
public int Height { get { return HostPanel.Height; } set { HostPanel.Height = value; } }
/// <summary>
/// Host panel
/// </summary>
public UnfocusablePanel HostPanel { get; private set; }
internal int TopPadding { get; set; }
/// <summary>
/// Tag
/// </summary>
public object Tag { get; set; }
/// <summary>
/// Cursor
/// </summary>
public Cursor Cursor { get { return HostPanel.Cursor; } set { HostPanel.Cursor = value; } }
/// <summary>
/// Inlining. If True then hint will moves apart text.
/// </summary>
public bool Inline{get; set;}
/// <summary>
/// Scroll textbox to the hint
/// </summary>
public virtual void DoVisible()
{
Range.tb.DoRangeVisible(Range, true);
Range.tb.DoVisibleRectangle(HostPanel.Bounds);
Range.tb.Invalidate();
}
private Hint(Range range, Control innerControl, string text, bool inline, bool dock)
{
this.Range = range;
this.Inline = inline;
this.InnerControl = innerControl;
Init();
Dock = dock ? DockStyle.Fill : DockStyle.None;
Text = text;
}
/// <summary>
/// Creates Hint
/// </summary>
/// <param name="range">Linked range</param>
/// <param name="text">Text for simple hint</param>
/// <param name="inline">Inlining. If True then hint will moves apart text</param>
/// <param name="dock">Docking. If True then hint will fill whole line</param>
public Hint(Range range, string text, bool inline, bool dock)
: this(range, null, text, inline, dock)
{
}
/// <summary>
/// Creates Hint
/// </summary>
/// <param name="range">Linked range</param>
/// <param name="text">Text for simple hint</param>
public Hint(Range range, string text)
: this(range, null, text, true, true)
{
}
/// <summary>
/// Creates Hint
/// </summary>
/// <param name="range">Linked range</param>
/// <param name="innerControl">Inner control</param>
/// <param name="inline">Inlining. If True then hint will moves apart text</param>
/// <param name="dock">Docking. If True then hint will fill whole line</param>
public Hint(Range range, Control innerControl, bool inline, bool dock)
: this(range, innerControl, null, inline, dock)
{
}
/// <summary>
/// Creates Hint
/// </summary>
/// <param name="range">Linked range</param>
/// <param name="innerControl">Inner control</param>
public Hint(Range range, Control innerControl)
: this(range, innerControl, null, true, true)
{
}
protected virtual void Init()
{
HostPanel = new UnfocusablePanel();
HostPanel.Click += OnClick;
Cursor = Cursors.Default;
BorderColor = Color.Silver;
BackColor2 = Color.White;
BackColor = InnerControl == null ? Color.Silver : SystemColors.Control;
ForeColor = Color.Black;
TextAlignment = StringAlignment.Near;
Font = Range.tb.Parent == null ? Range.tb.Font : Range.tb.Parent.Font;
if (InnerControl != null)
{
HostPanel.Controls.Add(InnerControl);
var size = InnerControl.GetPreferredSize(InnerControl.Size);
HostPanel.Width = size.Width + 2;
HostPanel.Height = size.Height + 2;
InnerControl.Dock = DockStyle.Fill;
InnerControl.Visible = true;
BackColor = SystemColors.Control;
}
else
{
HostPanel.Height = Range.tb.CharHeight + 5;
}
}
protected virtual void OnClick(object sender, EventArgs e)
{
Range.tb.OnHintClick(this);
}
}
}

View File

@@ -0,0 +1,251 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Globalization;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using KEYS = System.Windows.Forms.Keys;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Dictionary of shortcuts for FCTB
/// </summary>
public class HotkeysMapping : SortedDictionary<Keys, FCTBAction>
{
public virtual void InitDefault()
{
this[KEYS.Control | KEYS.G] = FCTBAction.GoToDialog;
this[KEYS.Control | KEYS.F] = FCTBAction.FindDialog;
this[KEYS.Alt | KEYS.F] = FCTBAction.FindChar;
this[KEYS.F3] = FCTBAction.FindNext;
this[KEYS.Control | KEYS.H] = FCTBAction.ReplaceDialog;
this[KEYS.Control | KEYS.C] = FCTBAction.Copy;
this[KEYS.Control | KEYS.Shift | KEYS.C] = FCTBAction.CommentSelected;
this[KEYS.Control | KEYS.X] = FCTBAction.Cut;
this[KEYS.Control | KEYS.V] = FCTBAction.Paste;
this[KEYS.Control | KEYS.A] = FCTBAction.SelectAll;
this[KEYS.Control | KEYS.Z] = FCTBAction.Undo;
this[KEYS.Control | KEYS.R] = FCTBAction.Redo;
this[KEYS.Control | KEYS.U] = FCTBAction.UpperCase;
this[KEYS.Shift | KEYS.Control | KEYS.U] = FCTBAction.LowerCase;
this[KEYS.Control | KEYS.OemMinus] = FCTBAction.NavigateBackward;
this[KEYS.Control | KEYS.Shift | KEYS.OemMinus] = FCTBAction.NavigateForward;
this[KEYS.Control | KEYS.B] = FCTBAction.BookmarkLine;
this[KEYS.Control | KEYS.Shift | KEYS.B] = FCTBAction.UnbookmarkLine;
this[KEYS.Control | KEYS.N] = FCTBAction.GoNextBookmark;
this[KEYS.Control | KEYS.Shift | KEYS.N] = FCTBAction.GoPrevBookmark;
this[KEYS.Alt | KEYS.Back] = FCTBAction.Undo;
this[KEYS.Control | KEYS.Back] = FCTBAction.ClearWordLeft;
this[KEYS.Insert] = FCTBAction.ReplaceMode;
this[KEYS.Control | KEYS.Insert] = FCTBAction.Copy;
this[KEYS.Shift | KEYS.Insert] = FCTBAction.Paste;
this[KEYS.Delete] = FCTBAction.DeleteCharRight;
this[KEYS.Control | KEYS.Delete] = FCTBAction.ClearWordRight;
this[KEYS.Shift | KEYS.Delete] = FCTBAction.Cut;
this[KEYS.Left] = FCTBAction.GoLeft;
this[KEYS.Shift | KEYS.Left] = FCTBAction.GoLeftWithSelection;
this[KEYS.Control | KEYS.Left] = FCTBAction.GoWordLeft;
this[KEYS.Control | KEYS.Shift | KEYS.Left] = FCTBAction.GoWordLeftWithSelection;
this[KEYS.Alt | KEYS.Shift | KEYS.Left] = FCTBAction.GoLeft_ColumnSelectionMode;
this[KEYS.Right] = FCTBAction.GoRight;
this[KEYS.Shift | KEYS.Right] = FCTBAction.GoRightWithSelection;
this[KEYS.Control | KEYS.Right] = FCTBAction.GoWordRight;
this[KEYS.Control | KEYS.Shift | KEYS.Right] = FCTBAction.GoWordRightWithSelection;
this[KEYS.Alt | KEYS.Shift | KEYS.Right] = FCTBAction.GoRight_ColumnSelectionMode;
this[KEYS.Up] = FCTBAction.GoUp;
this[KEYS.Shift | KEYS.Up] = FCTBAction.GoUpWithSelection;
this[KEYS.Alt | KEYS.Shift | KEYS.Up] = FCTBAction.GoUp_ColumnSelectionMode;
this[KEYS.Alt | KEYS.Up] = FCTBAction.MoveSelectedLinesUp;
this[KEYS.Control | KEYS.Up] = FCTBAction.ScrollUp;
this[KEYS.Down] = FCTBAction.GoDown;
this[KEYS.Shift | KEYS.Down] = FCTBAction.GoDownWithSelection;
this[KEYS.Alt | KEYS.Shift | KEYS.Down] = FCTBAction.GoDown_ColumnSelectionMode;
this[KEYS.Alt | KEYS.Down] = FCTBAction.MoveSelectedLinesDown;
this[KEYS.Control | KEYS.Down] = FCTBAction.ScrollDown;
this[KEYS.PageUp] = FCTBAction.GoPageUp;
this[KEYS.Shift | KEYS.PageUp] = FCTBAction.GoPageUpWithSelection;
this[KEYS.PageDown] = FCTBAction.GoPageDown;
this[KEYS.Shift | KEYS.PageDown] = FCTBAction.GoPageDownWithSelection;
this[KEYS.Home] = FCTBAction.GoHome;
this[KEYS.Shift | KEYS.Home] = FCTBAction.GoHomeWithSelection;
this[KEYS.Control | KEYS.Home] = FCTBAction.GoFirstLine;
this[KEYS.Control | KEYS.Shift | KEYS.Home] = FCTBAction.GoFirstLineWithSelection;
this[KEYS.End] = FCTBAction.GoEnd;
this[KEYS.Shift | KEYS.End] = FCTBAction.GoEndWithSelection;
this[KEYS.Control | KEYS.End] = FCTBAction.GoLastLine;
this[KEYS.Control | KEYS.Shift | KEYS.End] = FCTBAction.GoLastLineWithSelection;
this[KEYS.Escape] = FCTBAction.ClearHints;
this[KEYS.Control | KEYS.M] = FCTBAction.MacroRecord;
this[KEYS.Control | KEYS.E] = FCTBAction.MacroExecute;
this[KEYS.Control | KEYS.Space] = FCTBAction.AutocompleteMenu;
this[KEYS.Tab] = FCTBAction.IndentIncrease;
this[KEYS.Shift | KEYS.Tab] = FCTBAction.IndentDecrease;
this[KEYS.Control | KEYS.Subtract] = FCTBAction.ZoomOut;
this[KEYS.Control | KEYS.Add] = FCTBAction.ZoomIn;
this[KEYS.Control | KEYS.D0] = FCTBAction.ZoomNormal;
this[KEYS.Control | KEYS.I] = FCTBAction.AutoIndentChars;
}
public override string ToString()
{
var cult = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
StringBuilder sb = new StringBuilder();
var kc = new KeysConverter();
foreach (var pair in this)
{
sb.AppendFormat("{0}={1}, ", kc.ConvertToString(pair.Key), pair.Value);
}
if (sb.Length > 1)
sb.Remove(sb.Length - 2, 2);
Thread.CurrentThread.CurrentUICulture = cult;
return sb.ToString();
}
public static HotkeysMapping Parse(string s)
{
var result = new HotkeysMapping();
result.Clear();
var cult = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
var kc = new KeysConverter();
foreach (var p in s.Split(','))
{
var pp = p.Split('=');
var k = (Keys)kc.ConvertFromString(pp[0].Trim());
var a = (FCTBAction)Enum.Parse(typeof(FCTBAction), pp[1].Trim());
result[k] = a;
}
Thread.CurrentThread.CurrentUICulture = cult;
return result;
}
}
/// <summary>
/// Actions for shortcuts
/// </summary>
public enum FCTBAction
{
None,
AutocompleteMenu,
AutoIndentChars,
BookmarkLine,
ClearHints,
ClearWordLeft,
ClearWordRight,
CommentSelected,
Copy,
Cut,
DeleteCharRight,
FindChar,
FindDialog,
FindNext,
GoDown,
GoDownWithSelection,
GoDown_ColumnSelectionMode,
GoEnd,
GoEndWithSelection,
GoFirstLine,
GoFirstLineWithSelection,
GoHome,
GoHomeWithSelection,
GoLastLine,
GoLastLineWithSelection,
GoLeft,
GoLeftWithSelection,
GoLeft_ColumnSelectionMode,
GoPageDown,
GoPageDownWithSelection,
GoPageUp,
GoPageUpWithSelection,
GoRight,
GoRightWithSelection,
GoRight_ColumnSelectionMode,
GoToDialog,
GoNextBookmark,
GoPrevBookmark,
GoUp,
GoUpWithSelection,
GoUp_ColumnSelectionMode,
GoWordLeft,
GoWordLeftWithSelection,
GoWordRight,
GoWordRightWithSelection,
IndentIncrease,
IndentDecrease,
LowerCase,
MacroExecute,
MacroRecord,
MoveSelectedLinesDown,
MoveSelectedLinesUp,
NavigateBackward,
NavigateForward,
Paste,
Redo,
ReplaceDialog,
ReplaceMode,
ScrollDown,
ScrollUp,
SelectAll,
UnbookmarkLine,
Undo,
UpperCase,
ZoomIn,
ZoomNormal,
ZoomOut,
CustomAction1,
CustomAction2,
CustomAction3,
CustomAction4,
CustomAction5,
CustomAction6,
CustomAction7,
CustomAction8,
CustomAction9,
CustomAction10,
CustomAction11,
CustomAction12,
CustomAction13,
CustomAction14,
CustomAction15,
CustomAction16,
CustomAction17,
CustomAction18,
CustomAction19,
CustomAction20
}
internal class HotkeysEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if ((provider != null) && (((IWindowsFormsEditorService) provider.GetService(typeof(IWindowsFormsEditorService))) != null))
{
var form = new HotkeysEditorForm(HotkeysMapping.Parse(value as string));
if (form.ShowDialog() == DialogResult.OK)
value = form.GetHotkeys().ToString();
}
return value;
}
}
}

View File

@@ -0,0 +1,210 @@
namespace FastColoredTextBoxNS
{
partial class HotkeysEditorForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
this.dgv = new System.Windows.Forms.DataGridView();
this.cbModifiers = new System.Windows.Forms.DataGridViewComboBoxColumn();
this.cbKey = new System.Windows.Forms.DataGridViewComboBoxColumn();
this.cbAction = new System.Windows.Forms.DataGridViewComboBoxColumn();
this.btAdd = new System.Windows.Forms.Button();
this.btRemove = new System.Windows.Forms.Button();
this.btCancel = new System.Windows.Forms.Button();
this.btOk = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.btResore = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dgv)).BeginInit();
this.SuspendLayout();
//
// dgv
//
this.dgv.AllowUserToAddRows = false;
this.dgv.AllowUserToDeleteRows = false;
this.dgv.AllowUserToResizeColumns = false;
this.dgv.AllowUserToResizeRows = false;
this.dgv.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dgv.BackgroundColor = System.Drawing.SystemColors.Control;
this.dgv.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgv.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.cbModifiers,
this.cbKey,
this.cbAction});
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.Color.LightSteelBlue;
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dgv.DefaultCellStyle = dataGridViewCellStyle1;
this.dgv.GridColor = System.Drawing.SystemColors.Control;
this.dgv.Location = new System.Drawing.Point(12, 28);
this.dgv.Name = "dgv";
this.dgv.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None;
this.dgv.RowHeadersVisible = false;
this.dgv.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
this.dgv.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.dgv.Size = new System.Drawing.Size(525, 278);
this.dgv.TabIndex = 0;
this.dgv.RowsAdded += new System.Windows.Forms.DataGridViewRowsAddedEventHandler(this.dgv_RowsAdded);
//
// cbModifiers
//
this.cbModifiers.DataPropertyName = "Modifiers";
this.cbModifiers.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.ComboBox;
this.cbModifiers.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.cbModifiers.HeaderText = "Modifiers";
this.cbModifiers.Name = "cbModifiers";
//
// cbKey
//
this.cbKey.DataPropertyName = "Key";
this.cbKey.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.ComboBox;
this.cbKey.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.cbKey.HeaderText = "Key";
this.cbKey.Name = "cbKey";
this.cbKey.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.cbKey.Width = 120;
//
// cbAction
//
this.cbAction.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.cbAction.DataPropertyName = "Action";
this.cbAction.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.ComboBox;
this.cbAction.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.cbAction.HeaderText = "Action";
this.cbAction.Name = "cbAction";
//
// btAdd
//
this.btAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btAdd.Location = new System.Drawing.Point(13, 322);
this.btAdd.Name = "btAdd";
this.btAdd.Size = new System.Drawing.Size(75, 23);
this.btAdd.TabIndex = 1;
this.btAdd.Text = "Add";
this.btAdd.UseVisualStyleBackColor = true;
this.btAdd.Click += new System.EventHandler(this.btAdd_Click);
//
// btRemove
//
this.btRemove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btRemove.Location = new System.Drawing.Point(103, 322);
this.btRemove.Name = "btRemove";
this.btRemove.Size = new System.Drawing.Size(75, 23);
this.btRemove.TabIndex = 2;
this.btRemove.Text = "Remove";
this.btRemove.UseVisualStyleBackColor = true;
this.btRemove.Click += new System.EventHandler(this.btRemove_Click);
//
// btCancel
//
this.btCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btCancel.Location = new System.Drawing.Point(460, 322);
this.btCancel.Name = "btCancel";
this.btCancel.Size = new System.Drawing.Size(75, 23);
this.btCancel.TabIndex = 4;
this.btCancel.Text = "Cancel";
this.btCancel.UseVisualStyleBackColor = true;
//
// btOk
//
this.btOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btOk.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btOk.Location = new System.Drawing.Point(379, 322);
this.btOk.Name = "btOk";
this.btOk.Size = new System.Drawing.Size(75, 23);
this.btOk.TabIndex = 3;
this.btOk.Text = "OK";
this.btOk.UseVisualStyleBackColor = true;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(114, 16);
this.label1.TabIndex = 5;
this.label1.Text = "Hotkeys mapping";
//
// btResore
//
this.btResore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btResore.Location = new System.Drawing.Point(194, 322);
this.btResore.Name = "btResore";
this.btResore.Size = new System.Drawing.Size(105, 23);
this.btResore.TabIndex = 6;
this.btResore.Text = "Restore default";
this.btResore.UseVisualStyleBackColor = true;
this.btResore.Click += new System.EventHandler(this.btResore_Click);
//
// HotkeysEditorForm
//
this.AcceptButton = this.btOk;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btCancel;
this.ClientSize = new System.Drawing.Size(549, 357);
this.Controls.Add(this.btResore);
this.Controls.Add(this.label1);
this.Controls.Add(this.btCancel);
this.Controls.Add(this.btOk);
this.Controls.Add(this.btRemove);
this.Controls.Add(this.btAdd);
this.Controls.Add(this.dgv);
this.MaximumSize = new System.Drawing.Size(565, 700);
this.MinimumSize = new System.Drawing.Size(565, 395);
this.Name = "HotkeysEditorForm";
this.ShowIcon = false;
this.Text = "Hotkeys Editor";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.HotkeysEditorForm_FormClosing);
((System.ComponentModel.ISupportInitialize)(this.dgv)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridView dgv;
private System.Windows.Forms.Button btAdd;
private System.Windows.Forms.Button btRemove;
private System.Windows.Forms.Button btCancel;
private System.Windows.Forms.Button btOk;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btResore;
private System.Windows.Forms.DataGridViewComboBoxColumn cbModifiers;
private System.Windows.Forms.DataGridViewComboBoxColumn cbKey;
private System.Windows.Forms.DataGridViewComboBoxColumn cbAction;
}
}

View File

@@ -0,0 +1,179 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace FastColoredTextBoxNS
{
public partial class HotkeysEditorForm : Form
{
BindingList<HotkeyWrapper> wrappers = new BindingList<HotkeyWrapper>();
public HotkeysEditorForm(HotkeysMapping hotkeys)
{
InitializeComponent();
BuildWrappers(hotkeys);
dgv.DataSource = wrappers;
}
int CompereKeys(Keys key1, Keys key2)
{
var res = ((int)key1 & 0xff).CompareTo((int)key2 & 0xff);
if (res == 0)
res = key1.CompareTo(key2);
return res;
}
private void BuildWrappers(HotkeysMapping hotkeys)
{
var keys = new List<Keys>(hotkeys.Keys);
keys.Sort(CompereKeys);
wrappers.Clear();
foreach (var k in keys)
wrappers.Add(new HotkeyWrapper(k, hotkeys[k]));
}
/// <summary>
/// Returns edited hotkey map
/// </summary>
/// <returns></returns>
public HotkeysMapping GetHotkeys()
{
var result = new HotkeysMapping();
foreach (var w in wrappers)
result[w.ToKeyData()] = w.Action;
return result;
}
private void btAdd_Click(object sender, EventArgs e)
{
wrappers.Add(new HotkeyWrapper(Keys.None, FCTBAction.None));
}
private void dgv_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
var cell = (dgv[0, e.RowIndex] as DataGridViewComboBoxCell);
if(cell.Items.Count == 0)
foreach(var item in new string[]{"", "Ctrl", "Ctrl + Shift", "Ctrl + Alt", "Shift", "Shift + Alt", "Alt", "Ctrl + Shift + Alt"})
cell.Items.Add(item);
cell = (dgv[1, e.RowIndex] as DataGridViewComboBoxCell);
if (cell.Items.Count == 0)
foreach (var item in Enum.GetValues(typeof(Keys)))
cell.Items.Add(item);
cell = (dgv[2, e.RowIndex] as DataGridViewComboBoxCell);
if (cell.Items.Count == 0)
foreach (var item in Enum.GetValues(typeof(FCTBAction)))
cell.Items.Add(item);
}
private void btResore_Click(object sender, EventArgs e)
{
HotkeysMapping h = new HotkeysMapping();
h.InitDefault();
BuildWrappers(h);
}
private void btRemove_Click(object sender, EventArgs e)
{
for (int i = dgv.RowCount - 1; i >= 0; i--)
if (dgv.Rows[i].Selected) dgv.Rows.RemoveAt(i);
}
private void HotkeysEditorForm_FormClosing(object sender, FormClosingEventArgs e)
{
if(DialogResult == System.Windows.Forms.DialogResult.OK)
{
var actions = GetUnAssignedActions();
if (!string.IsNullOrEmpty(actions))
{
if (MessageBox.Show("Some actions are not assigned!\r\nActions: " + actions + "\r\nPress Yes to save and exit, press No to continue editing", "Some actions is not assigned", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.No)
e.Cancel = true;
}
}
}
private string GetUnAssignedActions()
{
StringBuilder sb = new StringBuilder();
var dic = new Dictionary<FCTBAction, FCTBAction>();
foreach (var w in wrappers)
dic[w.Action] = w.Action;
foreach (var item in Enum.GetValues(typeof(FCTBAction)))
if ((FCTBAction)item != FCTBAction.None)
if(!((FCTBAction)item).ToString().StartsWith("CustomAction"))
{
if(!dic.ContainsKey((FCTBAction)item))
sb.Append(item+", ");
}
return sb.ToString().TrimEnd(' ', ',');
}
}
internal class HotkeyWrapper
{
public HotkeyWrapper(Keys keyData, FCTBAction action)
{
KeyEventArgs a = new KeyEventArgs(keyData);
Ctrl = a.Control;
Shift = a.Shift;
Alt = a.Alt;
Key = a.KeyCode;
Action = action;
}
public Keys ToKeyData()
{
var res = Key;
if (Ctrl) res |= Keys.Control;
if (Alt) res |= Keys.Alt;
if (Shift) res |= Keys.Shift;
return res;
}
bool Ctrl;
bool Shift;
bool Alt;
public string Modifiers
{
get
{
var res = "";
if (Ctrl) res += "Ctrl + ";
if (Shift) res += "Shift + ";
if (Alt) res += "Alt + ";
return res.Trim(' ', '+');
}
set
{
if (value == null)
{
Ctrl = Alt = Shift = false;
}
else
{
Ctrl = value.Contains("Ctrl");
Shift = value.Contains("Shift");
Alt = value.Contains("Alt");
}
}
}
public Keys Key { get; set; }
public FCTBAction Action { get; set; }
}
}

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="cbModifiers.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="cbKey.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="cbAction.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@@ -0,0 +1,105 @@
using System;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Limited stack
/// </summary>
public class LimitedStack<T>
{
T[] items;
int count;
int start;
/// <summary>
/// Max stack length
/// </summary>
public int MaxItemCount
{
get { return items.Length; }
}
/// <summary>
/// Current length of stack
/// </summary>
public int Count
{
get { return count; }
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="maxItemCount">Maximum length of stack</param>
public LimitedStack(int maxItemCount)
{
items = new T[maxItemCount];
count = 0;
start = 0;
}
/// <summary>
/// Pop item
/// </summary>
public T Pop()
{
if (count == 0)
throw new Exception("Stack is empty");
int i = LastIndex;
T item = items[i];
items[i] = default(T);
count--;
return item;
}
int LastIndex
{
get { return (start + count - 1) % items.Length; }
}
/// <summary>
/// Peek item
/// </summary>
public T Peek()
{
if (count == 0)
return default(T);
return items[LastIndex];
}
/// <summary>
/// Push item
/// </summary>
public void Push(T item)
{
if (count == items.Length)
start = (start + 1) % items.Length;
else
count++;
items[LastIndex] = item;
}
/// <summary>
/// Clear stack
/// </summary>
public void Clear()
{
items = new T[items.Length];
count = 0;
start = 0;
}
public T[] ToArray()
{
T[] result = new T[count];
for (int i = 0; i < count; i++)
result[i] = items[(start + i) % items.Length];
return result;
}
}
}

View File

@@ -0,0 +1,289 @@
using System.Collections.Generic;
using System;
using System.Text;
using System.Drawing;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Line of text
/// </summary>
public class Line : IList<Char>
{
protected List<Char> chars;
public string FoldingStartMarker { get; set; }
public string FoldingEndMarker { get; set; }
/// <summary>
/// Text of line was changed
/// </summary>
public bool IsChanged { get; set; }
/// <summary>
/// Time of last visit of caret in this line
/// </summary>
/// <remarks>This property can be used for forward/backward navigating</remarks>
public DateTime LastVisit { get; set; }
/// <summary>
/// Background brush.
/// </summary>
public Brush BackgroundBrush { get; set;}
/// <summary>
/// Unique ID
/// </summary>
public int UniqueId { get; private set; }
/// <summary>
/// Count of needed start spaces for AutoIndent
/// </summary>
public int AutoIndentSpacesNeededCount
{
get;
set;
}
internal Line(int uid)
{
this.UniqueId = uid;
chars = new List<Char>();
}
/// <summary>
/// Clears style of chars, delete folding markers
/// </summary>
public void ClearStyle(StyleIndex styleIndex)
{
FoldingStartMarker = null;
FoldingEndMarker = null;
for (int i = 0; i < Count; i++)
{
Char c = this[i];
c.style &= ~styleIndex;
this[i] = c;
}
}
/// <summary>
/// Text of the line
/// </summary>
public virtual string Text
{
get{
StringBuilder sb = new StringBuilder(Count);
foreach(Char c in this)
sb.Append(c.c);
return sb.ToString();
}
}
/// <summary>
/// Clears folding markers
/// </summary>
public void ClearFoldingMarkers()
{
FoldingStartMarker = null;
FoldingEndMarker = null;
}
/// <summary>
/// Count of start spaces
/// </summary>
public int StartSpacesCount
{
get
{
int spacesCount = 0;
for (int i = 0; i < Count; i++)
if (this[i].c == ' ')
spacesCount++;
else
break;
return spacesCount;
}
}
public int IndexOf(Char item)
{
return chars.IndexOf(item);
}
public void Insert(int index, Char item)
{
chars.Insert(index, item);
}
public void RemoveAt(int index)
{
chars.RemoveAt(index);
}
public Char this[int index]
{
get
{
return chars[index];
}
set
{
chars[index] = value;
}
}
public void Add(Char item)
{
chars.Add(item);
}
public void Clear()
{
chars.Clear();
}
public bool Contains(Char item)
{
return chars.Contains(item);
}
public void CopyTo(Char[] array, int arrayIndex)
{
chars.CopyTo(array, arrayIndex);
}
/// <summary>
/// Chars count
/// </summary>
public int Count
{
get { return chars.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(Char item)
{
return chars.Remove(item);
}
public IEnumerator<Char> GetEnumerator()
{
return chars.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return chars.GetEnumerator() as System.Collections.IEnumerator;
}
public virtual void RemoveRange(int index, int count)
{
if (index >= Count)
return;
chars.RemoveRange(index, Math.Min(Count - index, count));
}
public virtual void TrimExcess()
{
chars.TrimExcess();
}
public virtual void AddRange(IEnumerable<Char> collection)
{
chars.AddRange(collection);
}
}
public struct LineInfo
{
List<int> cutOffPositions;
//Y coordinate of line on screen
internal int startY;
internal int bottomPadding;
//indent of secondary wordwrap strings (in chars)
internal int wordWrapIndent;
/// <summary>
/// Visible state
/// </summary>
public VisibleState VisibleState;
public LineInfo(int startY)
{
cutOffPositions = null;
VisibleState = VisibleState.Visible;
this.startY = startY;
bottomPadding = 0;
wordWrapIndent = 0;
}
/// <summary>
/// Positions for wordwrap cutoffs
/// </summary>
public List<int> CutOffPositions
{
get
{
if (cutOffPositions == null)
cutOffPositions = new List<int>();
return cutOffPositions;
}
}
/// <summary>
/// Count of wordwrap string count for this line
/// </summary>
public int WordWrapStringsCount
{
get
{
switch (VisibleState)
{
case VisibleState.Visible:
if (cutOffPositions == null)
return 1;
else
return cutOffPositions.Count + 1;
case VisibleState.Hidden: return 0;
case VisibleState.StartOfHiddenBlock: return 1;
}
return 0;
}
}
internal int GetWordWrapStringStartPosition(int iWordWrapLine)
{
return iWordWrapLine == 0 ? 0 : CutOffPositions[iWordWrapLine - 1];
}
internal int GetWordWrapStringFinishPosition(int iWordWrapLine, Line line)
{
if (WordWrapStringsCount <= 0)
return 0;
return iWordWrapLine == WordWrapStringsCount - 1 ? line.Count - 1 : CutOffPositions[iWordWrapLine] - 1;
}
/// <summary>
/// Gets index of wordwrap string for given char position
/// </summary>
public int GetWordWrapStringIndex(int iChar)
{
if (cutOffPositions == null || cutOffPositions.Count == 0) return 0;
for (int i = 0; i < cutOffPositions.Count; i++)
if (cutOffPositions[i] >/*>=*/ iChar)
return i;
return cutOffPositions.Count;
}
}
public enum VisibleState: byte
{
Visible, StartOfHiddenBlock, Hidden
}
public enum IndentMarker
{
None,
Increased,
Decreased
}
}

View File

@@ -0,0 +1,23 @@
namespace FastColoredTextBoxNS
{
/// <summary>
/// Customize how we display the line numbers
/// </summary>
public abstract class LineNumberFormatting
{
/// <summary>
/// Defines how line number is displayed
/// </summary>
/// <param name="lineNumber"></param>
/// <returns></returns>
public abstract string FromLineNumberToString(int lineNumber);
/// <summary>
/// Recover the line number from the formatted string
/// </summary>
/// <param name="lineNumber"></param>
/// <param name="parsedLineNumber"></param>
/// <returns></returns>
public abstract bool TryParseStringIntoLineNumber(string lineNumber, out int parsedLineNumber);
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace FastColoredTextBoxNS
{
public class LinesAccessor : IList<string>
{
IList<Line> ts;
public LinesAccessor(IList<Line> ts)
{
this.ts = ts;
}
public int IndexOf(string item)
{
for (int i = 0; i < ts.Count; i++)
if (ts[i].Text == item)
return i;
return -1;
}
public void Insert(int index, string item)
{
throw new NotImplementedException();
}
public void RemoveAt(int index)
{
throw new NotImplementedException();
}
public string this[int index]
{
get
{
return ts[index].Text;
}
set
{
throw new NotImplementedException();
}
}
public void Add(string item)
{
throw new NotImplementedException();
}
public void Clear()
{
throw new NotImplementedException();
}
public bool Contains(string item)
{
for (int i = 0; i < ts.Count; i++)
if (ts[i].Text == item)
return true;
return false;
}
public void CopyTo(string[] array, int arrayIndex)
{
for (int i = 0; i < ts.Count; i++)
array[i + arrayIndex] = ts[i].Text;
}
public int Count
{
get { return ts.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public bool Remove(string item)
{
throw new NotImplementedException();
}
public IEnumerator<string> GetEnumerator()
{
for (int i = 0; i < ts.Count; i++)
yield return ts[i].Text;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@@ -0,0 +1,183 @@
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
namespace FastColoredTextBoxNS
{
/// <summary>
/// This class records, stores and executes the macros.
/// </summary>
public class MacrosManager
{
private readonly List<object> macro = new List<object>();
internal MacrosManager(FastColoredTextBox ctrl)
{
UnderlayingControl = ctrl;
AllowMacroRecordingByUser = true;
}
/// <summary>
/// Allows to user to record macros
/// </summary>
public bool AllowMacroRecordingByUser { get;set; }
private bool isRecording;
/// <summary>
/// Returns current recording state. Set to True/False to start/stop recording programmatically.
/// </summary>
public bool IsRecording
{
get { return isRecording; }
set { isRecording = value; UnderlayingControl.Invalidate(); }
}
/// <summary>
/// FCTB
/// </summary>
public FastColoredTextBox UnderlayingControl { get; private set; }
/// <summary>
/// Executes recorded macro
/// </summary>
/// <returns></returns>
public void ExecuteMacros()
{
IsRecording = false;
UnderlayingControl.BeginUpdate();
UnderlayingControl.Selection.BeginUpdate();
UnderlayingControl.BeginAutoUndo();
foreach (var item in macro)
{
if (item is Keys)
{
UnderlayingControl.ProcessKey((Keys)item);
}
if (item is KeyValuePair<char, Keys>)
{
var p = (KeyValuePair<char, Keys>)item;
UnderlayingControl.ProcessKey(p.Key, p.Value);
}
}
UnderlayingControl.EndAutoUndo();
UnderlayingControl.Selection.EndUpdate();
UnderlayingControl.EndUpdate();
}
/// <summary>
/// Adds the char to current macro
/// </summary>
public void AddCharToMacros(char c, Keys modifiers)
{
macro.Add(new KeyValuePair<char, Keys>(c, modifiers));
}
/// <summary>
/// Adds keyboard key to current macro
/// </summary>
public void AddKeyToMacros(Keys keyData)
{
macro.Add(keyData);
}
/// <summary>
/// Clears last recorded macro
/// </summary>
public void ClearMacros()
{
macro.Clear();
}
internal void ProcessKey(Keys keyData)
{
if (IsRecording)
AddKeyToMacros(keyData);
}
internal void ProcessKey(char c, Keys modifiers)
{
if (IsRecording)
AddCharToMacros(c, modifiers);
}
/// <summary>
/// Returns True if last macro is empty
/// </summary>
public bool MacroIsEmpty { get { return macro.Count == 0; }}
/// <summary>
/// Macros as string.
/// </summary>
public string Macros
{
get
{
var cult = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
var kc = new KeysConverter();
StringBuilder sb = new StringBuilder();
sb.AppendLine("<macros>");
foreach (var item in macro)
{
if (item is Keys)
{
sb.AppendFormat("<item key='{0}' />\r\n", kc.ConvertToString((Keys)item));
}
else if (item is KeyValuePair<char, Keys>)
{
var p = (KeyValuePair<char, Keys>)item;
sb.AppendFormat("<item char='{0}' key='{1}' />\r\n", (int)p.Key, kc.ConvertToString(p.Value));
}
}
sb.AppendLine("</macros>");
Thread.CurrentThread.CurrentUICulture = cult;
return sb.ToString();
}
set
{
isRecording = false;
ClearMacros();
if (string.IsNullOrEmpty(value))
return;
var doc = new XmlDocument();
doc.LoadXml(value);
var list = doc.SelectNodes("./macros/item");
var cult = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
var kc = new KeysConverter();
if(list != null)
foreach (XmlElement node in list)
{
var ca = node.GetAttributeNode("char");
var ka = node.GetAttributeNode("key");
if (ca != null)
{
if(ka!=null)
AddCharToMacros((char)int.Parse(ca.Value), (Keys)kc.ConvertFromString(ka.Value));
else
AddCharToMacros((char)int.Parse(ca.Value), Keys.None);
}else
if(ka!=null)
AddKeyToMacros((Keys)kc.ConvertFromString(ka.Value));
}
Thread.CurrentThread.CurrentUICulture = cult;
}
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Line index and char index
/// </summary>
public struct Place : IEquatable<Place>
{
public int iChar;
public int iLine;
public Place(int iChar, int iLine)
{
this.iChar = iChar;
this.iLine = iLine;
}
public void Offset(int dx, int dy)
{
iChar += dx;
iLine += dy;
}
public bool Equals(Place other)
{
return iChar == other.iChar && iLine == other.iLine;
}
public override bool Equals(object obj)
{
return (obj is Place) && Equals((Place)obj);
}
public override int GetHashCode()
{
return iChar.GetHashCode() ^ iLine.GetHashCode();
}
public static bool operator !=(Place p1, Place p2)
{
return !p1.Equals(p2);
}
public static bool operator ==(Place p1, Place p2)
{
return p1.Equals(p2);
}
public static bool operator <(Place p1, Place p2)
{
if (p1.iLine < p2.iLine) return true;
if (p1.iLine > p2.iLine) return false;
if (p1.iChar < p2.iChar) return true;
return false;
}
public static bool operator <=(Place p1, Place p2)
{
if (p1.Equals(p2)) return true;
if (p1.iLine < p2.iLine) return true;
if (p1.iLine > p2.iLine) return false;
if (p1.iChar < p2.iChar) return true;
return false;
}
public static bool operator >(Place p1, Place p2)
{
if (p1.iLine > p2.iLine) return true;
if (p1.iLine < p2.iLine) return false;
if (p1.iChar > p2.iChar) return true;
return false;
}
public static bool operator >=(Place p1, Place p2)
{
if (p1.Equals(p2)) return true;
if (p1.iLine > p2.iLine) return true;
if (p1.iLine < p2.iLine) return false;
if (p1.iChar > p2.iChar) return true;
return false;
}
public static Place operator +(Place p1, Place p2)
{
return new Place(p1.iChar + p2.iChar, p1.iLine + p2.iLine);
}
public static Place Empty
{
get { return new Place(); }
}
public override string ToString()
{
return "(" + iChar + "," + iLine + ")";
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace FastColoredTextBoxNS
{
public static class PlatformType
{
const ushort PROCESSOR_ARCHITECTURE_INTEL = 0;
const ushort PROCESSOR_ARCHITECTURE_IA64 = 6;
const ushort PROCESSOR_ARCHITECTURE_AMD64 = 9;
const ushort PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF;
[StructLayout(LayoutKind.Sequential)]
struct SYSTEM_INFO
{
public ushort wProcessorArchitecture;
public ushort wReserved;
public uint dwPageSize;
public IntPtr lpMinimumApplicationAddress;
public IntPtr lpMaximumApplicationAddress;
public UIntPtr dwActiveProcessorMask;
public uint dwNumberOfProcessors;
public uint dwProcessorType;
public uint dwAllocationGranularity;
public ushort wProcessorLevel;
public ushort wProcessorRevision;
};
[DllImport("kernel32.dll")]
static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo);
[DllImport("kernel32.dll")]
static extern void GetSystemInfo(ref SYSTEM_INFO lpSystemInfo);
public static Platform GetOperationSystemPlatform()
{
var sysInfo = new SYSTEM_INFO();
// WinXP and older - use GetNativeSystemInfo
if (Environment.OSVersion.Version.Major > 5 ||
(Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1))
{
GetNativeSystemInfo(ref sysInfo);
}
// else use GetSystemInfo
else
{
GetSystemInfo(ref sysInfo);
}
switch (sysInfo.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_IA64:
case PROCESSOR_ARCHITECTURE_AMD64:
return Platform.X64;
case PROCESSOR_ARCHITECTURE_INTEL:
return Platform.X86;
default:
return Platform.Unknown;
}
}
}
public enum Platform
{
X86,
X64,
Unknown
}
}

View File

@@ -0,0 +1,37 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("FastColoredTextBox")]
[assembly: AssemblyDescription("Fast сolored textbox control")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Pavel Torgashov")]
[assembly: AssemblyProduct("FastColoredTextBox")]
[assembly: AssemblyCopyright("© Pavel Torgashov, 2011-2016, pavel_torgashov@ukr.net.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("95be11b3-45bc-4512-be26-a860a78bd1f1")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.16.26.0")]
[assembly: AssemblyFileVersion("2.16.26.0")]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,196 @@
namespace FastColoredTextBoxNS
{
partial class ReplaceForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btClose = new System.Windows.Forms.Button();
this.btFindNext = new System.Windows.Forms.Button();
this.tbFind = new System.Windows.Forms.TextBox();
this.cbRegex = new System.Windows.Forms.CheckBox();
this.cbMatchCase = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.cbWholeWord = new System.Windows.Forms.CheckBox();
this.btReplace = new System.Windows.Forms.Button();
this.btReplaceAll = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.tbReplace = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// btClose
//
this.btClose.Location = new System.Drawing.Point(273, 153);
this.btClose.Name = "btClose";
this.btClose.Size = new System.Drawing.Size(75, 23);
this.btClose.TabIndex = 8;
this.btClose.Text = "Close";
this.btClose.UseVisualStyleBackColor = true;
this.btClose.Click += new System.EventHandler(this.btClose_Click);
//
// btFindNext
//
this.btFindNext.Location = new System.Drawing.Point(111, 124);
this.btFindNext.Name = "btFindNext";
this.btFindNext.Size = new System.Drawing.Size(75, 23);
this.btFindNext.TabIndex = 5;
this.btFindNext.Text = "Find next";
this.btFindNext.UseVisualStyleBackColor = true;
this.btFindNext.Click += new System.EventHandler(this.btFindNext_Click);
//
// tbFind
//
this.tbFind.Location = new System.Drawing.Point(62, 12);
this.tbFind.Name = "tbFind";
this.tbFind.Size = new System.Drawing.Size(286, 20);
this.tbFind.TabIndex = 0;
this.tbFind.TextChanged += new System.EventHandler(this.cbMatchCase_CheckedChanged);
this.tbFind.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.tbFind_KeyPress);
//
// cbRegex
//
this.cbRegex.AutoSize = true;
this.cbRegex.Location = new System.Drawing.Point(273, 38);
this.cbRegex.Name = "cbRegex";
this.cbRegex.Size = new System.Drawing.Size(57, 17);
this.cbRegex.TabIndex = 3;
this.cbRegex.Text = "Regex";
this.cbRegex.UseVisualStyleBackColor = true;
this.cbRegex.CheckedChanged += new System.EventHandler(this.cbMatchCase_CheckedChanged);
//
// cbMatchCase
//
this.cbMatchCase.AutoSize = true;
this.cbMatchCase.Location = new System.Drawing.Point(66, 38);
this.cbMatchCase.Name = "cbMatchCase";
this.cbMatchCase.Size = new System.Drawing.Size(82, 17);
this.cbMatchCase.TabIndex = 1;
this.cbMatchCase.Text = "Match case";
this.cbMatchCase.UseVisualStyleBackColor = true;
this.cbMatchCase.CheckedChanged += new System.EventHandler(this.cbMatchCase_CheckedChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(23, 14);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(33, 13);
this.label1.TabIndex = 5;
this.label1.Text = "Find: ";
//
// cbWholeWord
//
this.cbWholeWord.AutoSize = true;
this.cbWholeWord.Location = new System.Drawing.Point(154, 38);
this.cbWholeWord.Name = "cbWholeWord";
this.cbWholeWord.Size = new System.Drawing.Size(113, 17);
this.cbWholeWord.TabIndex = 2;
this.cbWholeWord.Text = "Match whole word";
this.cbWholeWord.UseVisualStyleBackColor = true;
this.cbWholeWord.CheckedChanged += new System.EventHandler(this.cbMatchCase_CheckedChanged);
//
// btReplace
//
this.btReplace.Location = new System.Drawing.Point(192, 124);
this.btReplace.Name = "btReplace";
this.btReplace.Size = new System.Drawing.Size(75, 23);
this.btReplace.TabIndex = 6;
this.btReplace.Text = "Replace";
this.btReplace.UseVisualStyleBackColor = true;
this.btReplace.Click += new System.EventHandler(this.btReplace_Click);
//
// btReplaceAll
//
this.btReplaceAll.Location = new System.Drawing.Point(273, 124);
this.btReplaceAll.Name = "btReplaceAll";
this.btReplaceAll.Size = new System.Drawing.Size(75, 23);
this.btReplaceAll.TabIndex = 7;
this.btReplaceAll.Text = "Replace all";
this.btReplaceAll.UseVisualStyleBackColor = true;
this.btReplaceAll.Click += new System.EventHandler(this.btReplaceAll_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(6, 81);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(50, 13);
this.label2.TabIndex = 9;
this.label2.Text = "Replace:";
//
// tbReplace
//
this.tbReplace.Location = new System.Drawing.Point(62, 78);
this.tbReplace.Name = "tbReplace";
this.tbReplace.Size = new System.Drawing.Size(286, 20);
this.tbReplace.TabIndex = 0;
this.tbReplace.TextChanged += new System.EventHandler(this.cbMatchCase_CheckedChanged);
this.tbReplace.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.tbFind_KeyPress);
//
// ReplaceForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(360, 191);
this.Controls.Add(this.tbFind);
this.Controls.Add(this.label2);
this.Controls.Add(this.tbReplace);
this.Controls.Add(this.btReplaceAll);
this.Controls.Add(this.btReplace);
this.Controls.Add(this.cbWholeWord);
this.Controls.Add(this.label1);
this.Controls.Add(this.cbMatchCase);
this.Controls.Add(this.cbRegex);
this.Controls.Add(this.btFindNext);
this.Controls.Add(this.btClose);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "ReplaceForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Find and replace";
this.TopMost = true;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ReplaceForm_FormClosing);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btClose;
private System.Windows.Forms.Button btFindNext;
private System.Windows.Forms.CheckBox cbRegex;
private System.Windows.Forms.CheckBox cbMatchCase;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.CheckBox cbWholeWord;
private System.Windows.Forms.Button btReplace;
private System.Windows.Forms.Button btReplaceAll;
private System.Windows.Forms.Label label2;
public System.Windows.Forms.TextBox tbFind;
public System.Windows.Forms.TextBox tbReplace;
}
}

View File

@@ -0,0 +1,187 @@
using System;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections.Generic;
namespace FastColoredTextBoxNS
{
public partial class ReplaceForm : Form
{
FastColoredTextBox tb;
bool firstSearch = true;
Place startPlace;
public ReplaceForm(FastColoredTextBox tb)
{
InitializeComponent();
this.tb = tb;
}
private void btClose_Click(object sender, EventArgs e)
{
Close();
}
private void btFindNext_Click(object sender, EventArgs e)
{
try
{
if (!Find(tbFind.Text))
MessageBox.Show("Not found");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public List<Range> FindAll(string pattern)
{
var opt = cbMatchCase.Checked ? RegexOptions.None : RegexOptions.IgnoreCase;
if (!cbRegex.Checked)
pattern = Regex.Escape(pattern);
if (cbWholeWord.Checked)
pattern = "\\b" + pattern + "\\b";
//
var range = tb.Selection.IsEmpty? tb.Range.Clone() : tb.Selection.Clone();
//
var list = new List<Range>();
foreach (var r in range.GetRangesByLines(pattern, opt))
list.Add(r);
return list;
}
public bool Find(string pattern)
{
RegexOptions opt = cbMatchCase.Checked ? RegexOptions.None : RegexOptions.IgnoreCase;
if (!cbRegex.Checked)
pattern = Regex.Escape(pattern);
if (cbWholeWord.Checked)
pattern = "\\b" + pattern + "\\b";
//
Range range = tb.Selection.Clone();
range.Normalize();
//
if (firstSearch)
{
startPlace = range.Start;
firstSearch = false;
}
//
range.Start = range.End;
if (range.Start >= startPlace)
range.End = new Place(tb.GetLineLength(tb.LinesCount - 1), tb.LinesCount - 1);
else
range.End = startPlace;
//
foreach (var r in range.GetRangesByLines(pattern, opt))
{
tb.Selection.Start = r.Start;
tb.Selection.End = r.End;
tb.DoSelectionVisible();
tb.Invalidate();
return true;
}
if (range.Start >= startPlace && startPlace > Place.Empty)
{
tb.Selection.Start = new Place(0, 0);
return Find(pattern);
}
return false;
}
private void tbFind_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\r')
btFindNext_Click(sender, null);
if (e.KeyChar == '\x1b')
Hide();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) // David
{
if (keyData == Keys.Escape)
{
this.Close();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void ReplaceForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
Hide();
}
this.tb.Focus();
}
private void btReplace_Click(object sender, EventArgs e)
{
try
{
if (tb.SelectionLength != 0)
if (!tb.Selection.ReadOnly)
tb.InsertText(tbReplace.Text);
btFindNext_Click(sender, null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btReplaceAll_Click(object sender, EventArgs e)
{
try
{
tb.Selection.BeginUpdate();
//search
var ranges = FindAll(tbFind.Text);
//check readonly
var ro = false;
foreach (var r in ranges)
if (r.ReadOnly)
{
ro = true;
break;
}
//replace
if (!ro)
if (ranges.Count > 0)
{
tb.TextSource.Manager.ExecuteCommand(new ReplaceTextCommand(tb.TextSource, ranges, tbReplace.Text));
tb.Selection.Start = new Place(0, 0);
}
//
tb.Invalidate();
MessageBox.Show(ranges.Count + " occurrence(s) replaced");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
tb.Selection.EndUpdate();
}
protected override void OnActivated(EventArgs e)
{
tbFind.Focus();
ResetSerach();
}
void ResetSerach()
{
firstSearch = true;
}
private void cbMatchCase_CheckedChanged(object sender, EventArgs e)
{
ResetSerach();
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,37 @@
namespace FastColoredTextBoxNS
{
partial class Ruler
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
}
#endregion
}
}

View File

@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace FastColoredTextBoxNS
{
public partial class Ruler : UserControl
{
public EventHandler TargetChanged;
[DefaultValue(typeof(Color), "ControlLight")]
public Color BackColor2 { get; set; }
[DefaultValue(typeof(Color), "DarkGray")]
public Color TickColor { get; set; }
[DefaultValue(typeof(Color), "Black")]
public Color CaretTickColor { get; set; }
FastColoredTextBox target;
[Description("Target FastColoredTextBox")]
public FastColoredTextBox Target
{
get { return target; }
set
{
if (target != null)
UnSubscribe(target);
target = value;
Subscribe(target);
OnTargetChanged();
}
}
public Ruler()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
MinimumSize = new Size(0, 24);
MaximumSize = new Size(int.MaxValue/2, 24);
BackColor2 = SystemColors.ControlLight;
TickColor = Color.DarkGray;
CaretTickColor = Color.Black;
}
protected virtual void OnTargetChanged()
{
if (TargetChanged != null)
TargetChanged(this, EventArgs.Empty);
}
protected virtual void UnSubscribe(FastColoredTextBox target)
{
target.Scroll -= new ScrollEventHandler(target_Scroll);
target.SelectionChanged -= new EventHandler(target_SelectionChanged);
target.VisibleRangeChanged -= new EventHandler(target_VisibleRangeChanged);
}
protected virtual void Subscribe(FastColoredTextBox target)
{
target.Scroll += new ScrollEventHandler(target_Scroll);
target.SelectionChanged += new EventHandler(target_SelectionChanged);
target.VisibleRangeChanged += new EventHandler(target_VisibleRangeChanged);
}
void target_VisibleRangeChanged(object sender, EventArgs e)
{
Invalidate();
}
void target_SelectionChanged(object sender, EventArgs e)
{
Invalidate();
}
protected virtual void target_Scroll(object sender, ScrollEventArgs e)
{
Invalidate();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
if (target == null)
return;
Point car = PointToClient(target.PointToScreen(target.PlaceToPoint(target.Selection.Start)));
Size fontSize = TextRenderer.MeasureText("W", Font);
int column = 0;
e.Graphics.FillRectangle(new LinearGradientBrush(new Rectangle(0, 0, Width, Height), BackColor, BackColor2, 270), new Rectangle(0, 0, Width, Height));
float columnWidth = target.CharWidth;
var sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Near;
var zeroPoint = target.PositionToPoint(0);
zeroPoint = PointToClient(target.PointToScreen(zeroPoint));
using (var pen = new Pen(TickColor))
using (var textBrush = new SolidBrush(ForeColor))
for (float x = zeroPoint.X; x < Right; x += columnWidth, ++column)
{
if (column % 10 == 0)
e.Graphics.DrawString(column.ToString(), Font, textBrush, x, 0f, sf);
e.Graphics.DrawLine(pen, (int)x, fontSize.Height + (column % 5 == 0 ? 1 : 3), (int)x, Height - 4);
}
using (var pen = new Pen(TickColor))
e.Graphics.DrawLine(pen, new Point(car.X - 3, Height - 3), new Point(car.X + 3, Height - 3));
using (var pen = new Pen(CaretTickColor))
{
e.Graphics.DrawLine(pen, new Point(car.X - 2, fontSize.Height + 3), new Point(car.X - 2, Height - 4));
e.Graphics.DrawLine(pen, new Point(car.X, fontSize.Height + 1), new Point(car.X, Height - 4));
e.Graphics.DrawLine(pen, new Point(car.X + 2, fontSize.Height + 3), new Point(car.X + 2, Height - 4));
}
}
}
}

View File

@@ -0,0 +1,430 @@
using System.Drawing;
using System;
using System.Drawing.Drawing2D;
using System.Collections.Generic;
namespace FastColoredTextBoxNS
{
/// <summary>
/// Style of chars
/// </summary>
/// <remarks>This is base class for all text and design renderers</remarks>
public abstract class Style : IDisposable
{
/// <summary>
/// This style is exported to outer formats (HTML for example)
/// </summary>
public virtual bool IsExportable { get; set; }
/// <summary>
/// Occurs when user click on StyleVisualMarker joined to this style
/// </summary>
public event EventHandler<VisualMarkerEventArgs> VisualMarkerClick;
/// <summary>
/// Constructor
/// </summary>
public Style()
{
IsExportable = true;
}
/// <summary>
/// Renders given range of text
/// </summary>
/// <param name="gr">Graphics object</param>
/// <param name="position">Position of the range in absolute control coordinates</param>
/// <param name="range">Rendering range of text</param>
public abstract void Draw(Graphics gr, Point position, Range range);
/// <summary>
/// Occurs when user click on StyleVisualMarker joined to this style
/// </summary>
public virtual void OnVisualMarkerClick(FastColoredTextBox tb, VisualMarkerEventArgs args)
{
if (VisualMarkerClick != null)
VisualMarkerClick(tb, args);
}
/// <summary>
/// Shows VisualMarker
/// Call this method in Draw method, when you need to show VisualMarker for your style
/// </summary>
protected virtual void AddVisualMarker(FastColoredTextBox tb, StyleVisualMarker marker)
{
tb.AddVisualMarker(marker);
}
public static Size GetSizeOfRange(Range range)
{
return new Size((range.End.iChar - range.Start.iChar) * range.tb.CharWidth, range.tb.CharHeight);
}
public static GraphicsPath GetRoundedRectangle(Rectangle rect, int d)
{
GraphicsPath gp = new GraphicsPath();
gp.AddArc(rect.X, rect.Y, d, d, 180, 90);
gp.AddArc(rect.X + rect.Width - d, rect.Y, d, d, 270, 90);
gp.AddArc(rect.X + rect.Width - d, rect.Y + rect.Height - d, d, d, 0, 90);
gp.AddArc(rect.X, rect.Y + rect.Height - d, d, d, 90, 90);
gp.AddLine(rect.X, rect.Y + rect.Height - d, rect.X, rect.Y + d / 2);
return gp;
}
public virtual void Dispose()
{
;
}
/// <summary>
/// Returns CSS for export to HTML
/// </summary>
/// <returns></returns>
public virtual string GetCSS()
{
return "";
}
/// <summary>
/// Returns RTF descriptor for export to RTF
/// </summary>
/// <returns></returns>
public virtual RTFStyleDescriptor GetRTF()
{
return new RTFStyleDescriptor();
}
}
/// <summary>
/// Style for chars rendering
/// This renderer can draws chars, with defined fore and back colors
/// </summary>
public class TextStyle : Style
{
public Brush ForeBrush { get; set; }
public Brush BackgroundBrush { get; set; }
public FontStyle FontStyle { get; set; }
//public readonly Font Font;
public StringFormat stringFormat;
public TextStyle(Brush foreBrush, Brush backgroundBrush, FontStyle fontStyle)
{
this.ForeBrush = foreBrush;
this.BackgroundBrush = backgroundBrush;
this.FontStyle = fontStyle;
stringFormat = new StringFormat(StringFormatFlags.MeasureTrailingSpaces);
}
public override void Draw(Graphics gr, Point position, Range range)
{
//draw background
if (BackgroundBrush != null)
gr.FillRectangle(BackgroundBrush, position.X, position.Y, (range.End.iChar - range.Start.iChar) * range.tb.CharWidth, range.tb.CharHeight);
//draw chars
using(var f = new Font(range.tb.Font, FontStyle))
{
Line line = range.tb[range.Start.iLine];
float dx = range.tb.CharWidth;
float y = position.Y + range.tb.LineInterval/2;
float x = position.X - range.tb.CharWidth/3;
if (ForeBrush == null)
ForeBrush = new SolidBrush(range.tb.ForeColor);
if (range.tb.ImeAllowed)
{
//IME mode
for (int i = range.Start.iChar; i < range.End.iChar; i++)
{
SizeF size = FastColoredTextBox.GetCharSize(f, line[i].c);
var gs = gr.Save();
float k = size.Width > range.tb.CharWidth + 1 ? range.tb.CharWidth/size.Width : 1;
gr.TranslateTransform(x, y + (1 - k)*range.tb.CharHeight/2);
gr.ScaleTransform(k, (float) Math.Sqrt(k));
gr.DrawString(line[i].c.ToString(), f, ForeBrush, 0, 0, stringFormat);
gr.Restore(gs);
x += dx;
}
}
else
{
//classic mode
for (int i = range.Start.iChar; i < range.End.iChar; i++)
{
//draw char
gr.DrawString(line[i].c.ToString(), f, ForeBrush, x, y, stringFormat);
x += dx;
}
}
}
}
public override string GetCSS()
{
string result = "";
if (BackgroundBrush is SolidBrush)
{
var s = ExportToHTML.GetColorAsString((BackgroundBrush as SolidBrush).Color);
if (s != "")
result += "background-color:" + s + ";";
}
if (ForeBrush is SolidBrush)
{
var s = ExportToHTML.GetColorAsString((ForeBrush as SolidBrush).Color);
if (s != "")
result += "color:" + s + ";";
}
if ((FontStyle & FontStyle.Bold) != 0)
result += "font-weight:bold;";
if ((FontStyle & FontStyle.Italic) != 0)
result += "font-style:oblique;";
if ((FontStyle & FontStyle.Strikeout) != 0)
result += "text-decoration:line-through;";
if ((FontStyle & FontStyle.Underline) != 0)
result += "text-decoration:underline;";
return result;
}
public override RTFStyleDescriptor GetRTF()
{
var result = new RTFStyleDescriptor();
if (BackgroundBrush is SolidBrush)
result.BackColor = (BackgroundBrush as SolidBrush).Color;
if (ForeBrush is SolidBrush)
result.ForeColor = (ForeBrush as SolidBrush).Color;
if ((FontStyle & FontStyle.Bold) != 0)
result.AdditionalTags += @"\b";
if ((FontStyle & FontStyle.Italic) != 0)
result.AdditionalTags += @"\i";
if ((FontStyle & FontStyle.Strikeout) != 0)
result.AdditionalTags += @"\strike";
if ((FontStyle & FontStyle.Underline) != 0)
result.AdditionalTags += @"\ul";
return result;
}
}
/// <summary>
/// Renderer for folded block
/// </summary>
public class FoldedBlockStyle : TextStyle
{
public FoldedBlockStyle(Brush foreBrush, Brush backgroundBrush, FontStyle fontStyle):
base(foreBrush, backgroundBrush, fontStyle)
{
}
public override void Draw(Graphics gr, Point position, Range range)
{
if (range.End.iChar > range.Start.iChar)
{
base.Draw(gr, position, range);
int firstNonSpaceSymbolX = position.X;
//find first non space symbol
for (int i = range.Start.iChar; i < range.End.iChar; i++)
if (range.tb[range.Start.iLine][i].c != ' ')
break;
else
firstNonSpaceSymbolX += range.tb.CharWidth;
//create marker
range.tb.AddVisualMarker(new FoldedAreaMarker(range.Start.iLine, new Rectangle(firstNonSpaceSymbolX, position.Y, position.X + (range.End.iChar - range.Start.iChar) * range.tb.CharWidth - firstNonSpaceSymbolX, range.tb.CharHeight)));
}
else
{
//draw '...'
using(Font f = new Font(range.tb.Font, FontStyle))
gr.DrawString("...", f, ForeBrush, range.tb.LeftIndent, position.Y - 2);
//create marker
range.tb.AddVisualMarker(new FoldedAreaMarker(range.Start.iLine, new Rectangle(range.tb.LeftIndent + 2, position.Y, 2 * range.tb.CharHeight, range.tb.CharHeight)));
}
}
}
/// <summary>
/// Renderer for selected area
/// </summary>
public class SelectionStyle : Style
{
public Brush BackgroundBrush{ get; set;}
public Brush ForegroundBrush { get; private set; }
public override bool IsExportable
{
get{return false;} set{}
}
public SelectionStyle(Brush backgroundBrush, Brush foregroundBrush = null)
{
this.BackgroundBrush = backgroundBrush;
this.ForegroundBrush = foregroundBrush;
}
public override void Draw(Graphics gr, Point position, Range range)
{
//draw background
if (BackgroundBrush != null)
{
gr.SmoothingMode = SmoothingMode.None;
var rect = new Rectangle(position.X, position.Y, (range.End.iChar - range.Start.iChar) * range.tb.CharWidth, range.tb.CharHeight);
if (rect.Width == 0)
return;
gr.FillRectangle(BackgroundBrush, rect);
//
if (ForegroundBrush != null)
{
//draw text
gr.SmoothingMode = SmoothingMode.AntiAlias;
var r = new Range(range.tb, range.Start.iChar, range.Start.iLine,
Math.Min(range.tb[range.End.iLine].Count, range.End.iChar), range.End.iLine);
using (var style = new TextStyle(ForegroundBrush, null, FontStyle.Regular))
style.Draw(gr, new Point(position.X, position.Y - 1), r);
}
}
}
}
/// <summary>
/// Marker style
/// Draws background color for text
/// </summary>
public class MarkerStyle : Style
{
public Brush BackgroundBrush{get;set;}
public MarkerStyle(Brush backgroundBrush)
{
this.BackgroundBrush = backgroundBrush;
IsExportable = true;
}
public override void Draw(Graphics gr, Point position, Range range)
{
//draw background
if (BackgroundBrush != null)
{
Rectangle rect = new Rectangle(position.X, position.Y, (range.End.iChar - range.Start.iChar) * range.tb.CharWidth, range.tb.CharHeight);
if (rect.Width == 0)
return;
gr.FillRectangle(BackgroundBrush, rect);
}
}
public override string GetCSS()
{
string result = "";
if (BackgroundBrush is SolidBrush)
{
var s = ExportToHTML.GetColorAsString((BackgroundBrush as SolidBrush).Color);
if (s != "")
result += "background-color:" + s + ";";
}
return result;
}
}
/// <summary>
/// Draws small rectangle for popup menu
/// </summary>
public class ShortcutStyle : Style
{
public Pen borderPen;
public ShortcutStyle(Pen borderPen)
{
this.borderPen = borderPen;
}
public override void Draw(Graphics gr, Point position, Range range)
{
//get last char coordinates
Point p = range.tb.PlaceToPoint(range.End);
//draw small square under char
Rectangle rect = new Rectangle(p.X - 5, p.Y + range.tb.CharHeight - 2, 4, 3);
gr.FillPath(Brushes.White, GetRoundedRectangle(rect, 1));
gr.DrawPath(borderPen, GetRoundedRectangle(rect, 1));
//add visual marker for handle mouse events
AddVisualMarker(range.tb, new StyleVisualMarker(new Rectangle(p.X-range.tb.CharWidth, p.Y, range.tb.CharWidth, range.tb.CharHeight), this));
}
}
/// <summary>
/// This style draws a wavy line below a given text range.
/// </summary>
/// <remarks>Thanks for Yallie</remarks>
public class WavyLineStyle : Style
{
private Pen Pen { get; set; }
public WavyLineStyle(int alpha, Color color)
{
Pen = new Pen(Color.FromArgb(alpha, color));
}
public override void Draw(Graphics gr, Point pos, Range range)
{
var size = GetSizeOfRange(range);
var start = new Point(pos.X, pos.Y + size.Height - 1);
var end = new Point(pos.X + size.Width, pos.Y + size.Height - 1);
DrawWavyLine(gr, start, end);
}
private void DrawWavyLine(Graphics graphics, Point start, Point end)
{
if (end.X - start.X < 2)
{
graphics.DrawLine(Pen, start, end);
return;
}
var offset = -1;
var points = new List<Point>();
for (int i = start.X; i <= end.X; i += 2)
{
points.Add(new Point(i, start.Y + offset));
offset = -offset;
}
graphics.DrawLines(Pen, points.ToArray());
}
public override void Dispose()
{
base.Dispose();
if (Pen != null)
Pen.Dispose();
}
}
/// <summary>
/// This style is used to mark range of text as ReadOnly block
/// </summary>
/// <remarks>You can inherite this style to add visual effects of readonly text</remarks>
public class ReadOnlyStyle : Style
{
public ReadOnlyStyle()
{
IsExportable = false;
}
public override void Draw(Graphics gr, Point position, Range range)
{
//
}
}
}

View File

@@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System;
namespace FastColoredTextBoxNS
{
public class SyntaxDescriptor: IDisposable
{
public char leftBracket = '(';
public char rightBracket = ')';
public char leftBracket2 = '{';
public char rightBracket2 = '}';
public BracketsHighlightStrategy bracketsHighlightStrategy = BracketsHighlightStrategy.Strategy2;
public readonly List<Style> styles = new List<Style>();
public readonly List<RuleDesc> rules = new List<RuleDesc>();
public readonly List<FoldingDesc> foldings = new List<FoldingDesc>();
public void Dispose()
{
foreach (var style in styles)
style.Dispose();
}
}
public class RuleDesc
{
Regex regex;
public string pattern;
public RegexOptions options = RegexOptions.None;
public Style style;
public Regex Regex
{
get
{
if (regex == null)
{
regex = new Regex(pattern, SyntaxHighlighter.RegexCompiledOption | options);
}
return regex;
}
}
}
public class FoldingDesc
{
public string startMarkerRegex;
public string finishMarkerRegex;
public RegexOptions options = RegexOptions.None;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,509 @@
using System.Drawing;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System;
namespace FastColoredTextBoxNS
{
public class SyntaxHighlighter: IDisposable
{
//styles
public readonly Style BlueStyle = new TextStyle(Brushes.Blue, null, FontStyle.Regular);
public readonly Style BlueBoldStyle = new TextStyle(Brushes.Blue, null, FontStyle.Bold);
public readonly Style BoldStyle = new TextStyle(null, null, FontStyle.Bold | FontStyle.Underline);
public readonly Style GrayStyle = new TextStyle(Brushes.Gray, null, FontStyle.Regular);
public readonly Style MagentaStyle = new TextStyle(Brushes.Magenta, null, FontStyle.Regular);
public readonly Style GreenStyle = new TextStyle(Brushes.Green, null, FontStyle.Italic);
public readonly Style BrownStyle = new TextStyle(Brushes.Brown, null, FontStyle.Italic);
public readonly Style RedStyle = new TextStyle(Brushes.Red, null, FontStyle.Regular);
public readonly Style MaroonStyle = new TextStyle(Brushes.Maroon, null, FontStyle.Regular);
//
Dictionary<string, SyntaxDescriptor> descByXMLfileNames = new Dictionary<string, SyntaxDescriptor>();
/// <summary>
/// Highlights syntax for given language
/// </summary>
public virtual void HighlightSyntax(Language language, Range range)
{
switch (language)
{
case Language.CSharp: CSharpSyntaxHighlight(range); break;
case Language.VB: VBSyntaxHighlight(range); break;
case Language.HTML: HTMLSyntaxHighlight(range); break;
case Language.SQL: SQLSyntaxHighlight(range); break;
case Language.PHP: PHPSyntaxHighlight(range); break;
default:
break;
}
}
/// <summary>
/// Highlights syntax for given XML description file
/// </summary>
public virtual void HighlightSyntax(string XMLdescriptionFile, Range range)
{
SyntaxDescriptor desc = null;
if (!descByXMLfileNames.TryGetValue(XMLdescriptionFile, out desc))
{
var doc = new XmlDocument();
string file = XMLdescriptionFile;
if (!File.Exists(file))
file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.GetFileName(file));
doc.LoadXml(File.ReadAllText(file));
desc = ParseXmlDescription(doc);
descByXMLfileNames[XMLdescriptionFile] = desc;
}
HighlightSyntax(desc, range);
}
public virtual void AutoIndentNeeded(object sender, AutoIndentEventArgs args)
{
FastColoredTextBox tb = (sender as FastColoredTextBox);
Language language = tb.Language;
switch (language)
{
case Language.CSharp: CSharpAutoIndentNeeded(sender, args); break;
case Language.VB: VBAutoIndentNeeded(sender, args); break;
case Language.HTML: HTMLAutoIndentNeeded(sender, args); break;
case Language.SQL: SQLAutoIndentNeeded(sender, args); break;
case Language.PHP: PHPAutoIndentNeeded(sender, args); break;
default:
break;
}
}
private void PHPAutoIndentNeeded(object sender, AutoIndentEventArgs args)
{
FastColoredTextBox tb = sender as FastColoredTextBox;
tb.CalcAutoIndentShiftByCodeFolding(sender, args);
}
private void SQLAutoIndentNeeded(object sender, AutoIndentEventArgs args)
{
FastColoredTextBox tb = sender as FastColoredTextBox;
tb.CalcAutoIndentShiftByCodeFolding(sender, args);
}
private void HTMLAutoIndentNeeded(object sender, AutoIndentEventArgs args)
{
FastColoredTextBox tb = sender as FastColoredTextBox;
tb.CalcAutoIndentShiftByCodeFolding(sender, args);
}
private void VBAutoIndentNeeded(object sender, AutoIndentEventArgs args)
{
//end of block
if (Regex.IsMatch(args.LineText, @"^\s*(End|EndIf|Next|Loop)\b", RegexOptions.IgnoreCase))
{
args.Shift = -args.TabLength;
args.ShiftNextLines = -args.TabLength;
return;
}
//start of declaration
if (Regex.IsMatch(args.LineText, @"\b(Class|Property|Enum|Structure|Sub|Function|Namespace|Interface|Get|Set)\b", RegexOptions.IgnoreCase))
{
args.ShiftNextLines = args.TabLength;
return;
}
// then ...
if (Regex.IsMatch(args.LineText, @"\b(Then)\s*\S+", RegexOptions.IgnoreCase))
return;
//start of operator block
if (Regex.IsMatch(args.LineText, @"^\s*(If|While|For|Do|Try|With|Using|Select)\b", RegexOptions.IgnoreCase))
{
args.ShiftNextLines = args.TabLength;
return;
}
//Statements else, elseif, case etc
if (Regex.IsMatch(args.LineText, @"^\s*(Else|ElseIf|Case|Catch|Finally)\b", RegexOptions.IgnoreCase))
{
args.Shift = -args.TabLength;
return;
}
//Char _
if (args.PrevLineText.TrimEnd().EndsWith("_"))
{
args.Shift = args.TabLength;
return;
}
}
private void CSharpAutoIndentNeeded(object sender, AutoIndentEventArgs args)
{
//block {}
if (Regex.IsMatch(args.LineText, @"^[^""']*\{.*\}[^""']*$"))
return;
//start of block {}
if (Regex.IsMatch(args.LineText, @"^[^""']*\{"))
{
args.ShiftNextLines = args.TabLength;
return;
}
//end of block {}
if (Regex.IsMatch(args.LineText, @"}[^""']*$"))
{
args.Shift = -args.TabLength;
args.ShiftNextLines = -args.TabLength;
return;
}
//label
if (Regex.IsMatch(args.LineText, @"^\s*\w+\s*:\s*($|//)") &&
!Regex.IsMatch(args.LineText, @"^\s*default\s*:"))
{
args.Shift = -args.TabLength;
return;
}
//some statements: case, default
if (Regex.IsMatch(args.LineText, @"^\s*(case|default)\b.*:\s*($|//)"))
{
args.Shift = -args.TabLength/2;
return;
}
//is unclosed operator in previous line ?
if (Regex.IsMatch(args.PrevLineText, @"^\s*(if|for|foreach|while|[\}\s]*else)\b[^{]*$"))
if (!Regex.IsMatch(args.PrevLineText, @"(;\s*$)|(;\s*//)"))//operator is unclosed
{
args.Shift = args.TabLength;
return;
}
}
public static SyntaxDescriptor ParseXmlDescription(XmlDocument doc)
{
SyntaxDescriptor desc = new SyntaxDescriptor();
XmlNode brackets = doc.SelectSingleNode("doc/brackets");
if (brackets != null)
{
if (brackets.Attributes["left"] == null || brackets.Attributes["right"] == null ||
brackets.Attributes["left"].Value == "" || brackets.Attributes["right"].Value == "")
{
desc.leftBracket = '\x0';
desc.rightBracket = '\x0';
}
else
{
desc.leftBracket = brackets.Attributes["left"].Value[0];
desc.rightBracket = brackets.Attributes["right"].Value[0];
}
if (brackets.Attributes["left2"] == null || brackets.Attributes["right2"] == null ||
brackets.Attributes["left2"].Value == "" || brackets.Attributes["right2"].Value == "")
{
desc.leftBracket2 = '\x0';
desc.rightBracket2 = '\x0';
}
else
{
desc.leftBracket2 = brackets.Attributes["left2"].Value[0];
desc.rightBracket2 = brackets.Attributes["right2"].Value[0];
}
}
Dictionary<string, Style> styleByName = new Dictionary<string, Style>();
foreach (XmlNode style in doc.SelectNodes("doc/style"))
{
var s = ParseStyle(style);
styleByName[style.Attributes["name"].Value] = s;
desc.styles.Add(s);
}
foreach (XmlNode rule in doc.SelectNodes("doc/rule"))
desc.rules.Add(ParseRule(rule, styleByName));
foreach (XmlNode folding in doc.SelectNodes("doc/folding"))
desc.foldings.Add(ParseFolding(folding));
return desc;
}
private static FoldingDesc ParseFolding(XmlNode foldingNode)
{
FoldingDesc folding = new FoldingDesc();
//regex
folding.startMarkerRegex = foldingNode.Attributes["start"].Value;
folding.finishMarkerRegex = foldingNode.Attributes["finish"].Value;
//options
var optionsA = foldingNode.Attributes["options"];
if (optionsA != null)
folding.options = (RegexOptions)Enum.Parse(typeof(RegexOptions), optionsA.Value);
return folding;
}
private static RuleDesc ParseRule(XmlNode ruleNode, Dictionary<string, Style> styles)
{
RuleDesc rule = new RuleDesc();
rule.regex = ruleNode.InnerText;
//
var styleA = ruleNode.Attributes["style"];
var optionsA = ruleNode.Attributes["options"];
//Style
if (styleA == null)
throw new Exception("Rule must contain style name.");
if(!styles.ContainsKey(styleA.Value))
throw new Exception("Style '"+styleA.Value+"' is not found.");
rule.style = styles[styleA.Value];
//options
if (optionsA != null)
rule.options = (RegexOptions)Enum.Parse(typeof(RegexOptions), optionsA.Value);
return rule;
}
private static Style ParseStyle(XmlNode styleNode)
{
var typeA = styleNode.Attributes["type"];
var colorA = styleNode.Attributes["color"];
var backColorA = styleNode.Attributes["backColor"];
var fontStyleA = styleNode.Attributes["fontStyle"];
var nameA = styleNode.Attributes["name"];
//colors
SolidBrush foreBrush = null;
if (colorA != null)
foreBrush = new SolidBrush(ParseColor(colorA.Value));
SolidBrush backBrush = null;
if (backColorA != null)
backBrush = new SolidBrush(ParseColor(backColorA.Value));
//fontStyle
FontStyle fontStyle = FontStyle.Regular;
if (fontStyleA != null)
fontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), fontStyleA.Value);
return new TextStyle(foreBrush, backBrush, fontStyle);
}
private static Color ParseColor(string s)
{
if (s.StartsWith("#"))
{
if(s.Length<=7)
return Color.FromArgb(255, Color.FromArgb(Int32.Parse(s.Substring(1), System.Globalization.NumberStyles.AllowHexSpecifier)));
else
return Color.FromArgb(Int32.Parse(s.Substring(1), System.Globalization.NumberStyles.AllowHexSpecifier));
}
else
return Color.FromName(s);
}
public void HighlightSyntax(SyntaxDescriptor desc, Range range)
{
//set style order
range.tb.ClearStylesBuffer();
for(int i=0;i<desc.styles.Count;i++)
range.tb.Styles[i] = desc.styles[i];
//brackets
range.tb.LeftBracket = desc.leftBracket;
range.tb.RightBracket = desc.rightBracket;
range.tb.LeftBracket2 = desc.leftBracket2;
range.tb.RightBracket2 = desc.rightBracket2;
//clear styles of range
range.ClearStyle(desc.styles.ToArray());
//highlight syntax
foreach (var rule in desc.rules)
range.SetStyle(rule.style, rule.regex, rule.options);
//clear folding
range.ClearFoldingMarkers();
//folding markers
foreach (var folding in desc.foldings)
range.SetFoldingMarkers(folding.startMarkerRegex, folding.finishMarkerRegex, folding.options);
}
/// <summary>
/// Highlights C# code
/// </summary>
/// <param name="range"></param>
public virtual void CSharpSyntaxHighlight(Range range)
{
range.tb.CommentPrefix = "//";
range.tb.LeftBracket = '(';
range.tb.RightBracket = ')';
range.tb.LeftBracket2 = '\x0';
range.tb.RightBracket2 = '\x0';
//clear style of changed range
range.ClearStyle(BlueStyle, BoldStyle, GrayStyle, MagentaStyle, GreenStyle, BrownStyle);
//string highlighting
range.SetStyle(BrownStyle, @""".*?""|'.+?'");
//comment highlighting
range.SetStyle(GreenStyle, @"//.*$", RegexOptions.Multiline);
range.SetStyle(GreenStyle, @"(/\*.*?\*/)|(/\*.*)", RegexOptions.Singleline);
range.SetStyle(GreenStyle, @"(/\*.*?\*/)|(.*\*/)", RegexOptions.Singleline | RegexOptions.RightToLeft);
//number highlighting
range.SetStyle(MagentaStyle, @"\b\d+[\.]?\d*([eE]\-?\d+)?[lLdDfF]?\b|\b0x[a-fA-F\d]+\b");
//attribute highlighting
range.SetStyle(GrayStyle, @"^\s*(?<range>\[.+?\])\s*$", RegexOptions.Multiline);
//class name highlighting
range.SetStyle(BoldStyle, @"\b(class|struct|enum|interface)\s+(?<range>\w+?)\b");
//keyword highlighting
range.SetStyle(BlueStyle, @"\b(abstract|as|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b|#region\b|#endregion\b");
//clear folding markers
range.ClearFoldingMarkers();
//set folding markers
range.SetFoldingMarkers("{", "}");//allow to collapse brackets block
range.SetFoldingMarkers(@"#region\b", @"#endregion\b");//allow to collapse #region blocks
range.SetFoldingMarkers(@"/\*", @"\*/");//allow to collapse comment block
}
/// <summary>
/// Highlights VB code
/// </summary>
/// <param name="range"></param>
public virtual void VBSyntaxHighlight(Range range)
{
range.tb.CommentPrefix = "'";
range.tb.LeftBracket = '(';
range.tb.RightBracket = ')';
range.tb.LeftBracket2 = '\x0';
range.tb.RightBracket2 = '\x0';
//clear style of changed range
range.ClearStyle(BrownStyle, GreenStyle, MagentaStyle, BoldStyle, BlueStyle);
//string highlighting
range.SetStyle(BrownStyle, @""".*?""");
//comment highlighting
range.SetStyle(GreenStyle, @"'.*$", RegexOptions.Multiline);
//number highlighting
range.SetStyle(MagentaStyle, @"\b\d+[\.]?\d*([eE]\-?\d+)?\b");
//class name highlighting
range.SetStyle(BoldStyle, @"\b(Class|Structure|Enum|Interface)[ ]+(?<range>\w+?)\b", RegexOptions.IgnoreCase);
//keyword highlighting
range.SetStyle(BlueStyle, @"\b(AddHandler|AddressOf|Alias|And|AndAlso|As|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|Continue|CSByte|CShort|CSng|CStr|CType|CUInt|CULng|CUShort|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|False|Finally|For|Friend|Function|Get|GetType|GetXMLNamespace|Global|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|IsNot|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|Narrowing|New|Next|Not|Nothing|NotInheritable|NotOverridable|Object|Of|On|Operator|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Partial|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|REM|RemoveHandler|Resume|Return|SByte|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|True|Try|TryCast|TypeOf|UInteger|ULong|UShort|Using|Variant|Wend|When|While|Widening|With|WithEvents|WriteOnly|Xor|Region)\b|(#Const|#Else|#ElseIf|#End|#If|#Region)\b", RegexOptions.IgnoreCase);
//clear folding markers
range.ClearFoldingMarkers();
//set folding markers
range.SetFoldingMarkers(@"#Region\b", @"#End\s+Region\b", RegexOptions.IgnoreCase);
range.SetFoldingMarkers(@"\b(Class|Property|Enum|Structure|Interface)[ \t]+\S+", @"\bEnd (Class|Property|Enum|Structure|Interface)\b", RegexOptions.IgnoreCase);
range.SetFoldingMarkers(@"^\s*(?<range>While)[ \t]+\S+", @"^\s*(?<range>End While)\b", RegexOptions.Multiline | RegexOptions.IgnoreCase);
range.SetFoldingMarkers(@"\b(Sub|Function)[ \t]+[^\s']+", @"\bEnd (Sub|Function)\b", RegexOptions.IgnoreCase);//this declared separately because Sub and Function can be unclosed
range.SetFoldingMarkers(@"(\r|\n|^)[ \t]*(?<range>Get|Set)[ \t]*(\r|\n|$)", @"\bEnd (Get|Set)\b", RegexOptions.IgnoreCase);
range.SetFoldingMarkers(@"^\s*(?<range>For|For\s+Each)\b", @"^\s*(?<range>Next)\b", RegexOptions.Multiline | RegexOptions.IgnoreCase);
range.SetFoldingMarkers(@"^\s*(?<range>Do)\b", @"^\s*(?<range>Loop)\b", RegexOptions.Multiline | RegexOptions.IgnoreCase);
}
/// <summary>
/// Highlights HTML code
/// </summary>
/// <param name="range"></param>
public virtual void HTMLSyntaxHighlight(Range range)
{
range.tb.CommentPrefix = null;
range.tb.LeftBracket = '<';
range.tb.RightBracket = '>';
range.tb.LeftBracket2 = '(';
range.tb.RightBracket2 = ')';
//clear style of changed range
range.ClearStyle(BlueStyle, MaroonStyle, RedStyle);
//tag brackets highlighting
range.SetStyle(BlueStyle, @"<|/>|</|>");
//tag name
range.SetStyle(MaroonStyle, @"<(?<range>[!\w]+)");
//end of tag
range.SetStyle(MaroonStyle, @"</(?<range>\w+)>");
//attributes
range.SetStyle(RedStyle, @"(?<range>\S+?)='[^']*'|(?<range>\S+)=""[^""]*""|(?<range>\S+)=\S+");
//attribute values
range.SetStyle(BlueStyle, @"\S+?=(?<range>'[^']*')|\S+=(?<range>""[^""]*"")|\S+=(?<range>\S+)");
//clear folding markers
range.ClearFoldingMarkers();
//set folding markers
range.SetFoldingMarkers("<head", "</head>", RegexOptions.IgnoreCase);
range.SetFoldingMarkers("<body", "</body>", RegexOptions.IgnoreCase);
range.SetFoldingMarkers("<table", "</table>", RegexOptions.IgnoreCase);
range.SetFoldingMarkers("<form", "</form>", RegexOptions.IgnoreCase);
range.SetFoldingMarkers("<div", "</div>", RegexOptions.IgnoreCase);
range.SetFoldingMarkers("<script", "</script>", RegexOptions.IgnoreCase);
range.SetFoldingMarkers("<tr", "</tr>", RegexOptions.IgnoreCase);
}
/// <summary>
/// Highlights SQL code
/// </summary>
/// <param name="range"></param>
public virtual void SQLSyntaxHighlight(Range range)
{
range.tb.CommentPrefix = "--";
range.tb.LeftBracket = '(';
range.tb.RightBracket = ')';
range.tb.LeftBracket2 = '\x0';
range.tb.RightBracket2 = '\x0';
//clear style of changed range
range.ClearStyle(RedStyle, MagentaStyle, GreenStyle, BlueBoldStyle, BlueStyle, MaroonStyle);
//string highlighting
range.SetStyle(RedStyle, @""".*?""|'.+?'");
//number highlighting
range.SetStyle(MagentaStyle, @"\b\d+[\.]?\d*([eE]\-?\d+)?\b");
//comment highlighting
range.SetStyle(GreenStyle, @"--.*$", RegexOptions.Multiline);
range.SetStyle(GreenStyle, @"(/\*.*?\*/)|(/\*.*)", RegexOptions.Singleline);
range.SetStyle(GreenStyle, @"(/\*.*?\*/)|(.*\*/)", RegexOptions.Singleline | RegexOptions.RightToLeft);
//var highlighting
range.SetStyle(MaroonStyle, @"@[a-zA-Z_\d]*\b");
//statements
range.SetStyle(BlueBoldStyle, @"\b(ALTER APPLICATION ROLE|ALTER ASSEMBLY|ALTER ASYMMETRIC KEY|ALTER AUTHORIZATION|ALTER BROKER PRIORITY|ALTER CERTIFICATE|ALTER CREDENTIAL|ALTER CRYPTOGRAPHIC PROVIDER|ALTER DATABASE|ALTER DATABASE AUDIT SPECIFICATION|ALTER DATABASE ENCRYPTION KEY|ALTER ENDPOINT|ALTER EVENT SESSION|ALTER FULLTEXT CATALOG|ALTER FULLTEXT INDEX|ALTER FULLTEXT STOPLIST|ALTER FUNCTION|ALTER INDEX|ALTER LOGIN|ALTER MASTER KEY|ALTER MESSAGE TYPE|ALTER PARTITION FUNCTION|ALTER PARTITION SCHEME|ALTER PROCEDURE|ALTER QUEUE|ALTER REMOTE SERVICE BINDING|ALTER RESOURCE GOVERNOR|ALTER RESOURCE POOL|ALTER ROLE|ALTER ROUTE|ALTER SCHEMA|ALTER SERVER AUDIT|ALTER SERVER AUDIT SPECIFICATION|ALTER SERVICE|ALTER SERVICE MASTER KEY|ALTER SYMMETRIC KEY|ALTER TABLE|ALTER TRIGGER|ALTER USER|ALTER VIEW|ALTER WORKLOAD GROUP|ALTER XML SCHEMA COLLECTION|BULK INSERT|CREATE AGGREGATE|CREATE APPLICATION ROLE|CREATE ASSEMBLY|CREATE ASYMMETRIC KEY|CREATE BROKER PRIORITY|CREATE CERTIFICATE|CREATE CONTRACT|CREATE CREDENTIAL|CREATE CRYPTOGRAPHIC PROVIDER|CREATE DATABASE|CREATE DATABASE AUDIT SPECIFICATION|CREATE DATABASE ENCRYPTION KEY|CREATE DEFAULT|CREATE ENDPOINT|CREATE EVENT NOTIFICATION|CREATE EVENT SESSION|CREATE FULLTEXT CATALOG|CREATE FULLTEXT INDEX|CREATE FULLTEXT STOPLIST|CREATE FUNCTION|CREATE INDEX|CREATE LOGIN|CREATE MASTER KEY|CREATE MESSAGE TYPE|CREATE PARTITION FUNCTION|CREATE PARTITION SCHEME|CREATE PROCEDURE|CREATE QUEUE|CREATE REMOTE SERVICE BINDING|CREATE RESOURCE POOL|CREATE ROLE|CREATE ROUTE|CREATE RULE|CREATE SCHEMA|CREATE SERVER AUDIT|CREATE SERVER AUDIT SPECIFICATION|CREATE SERVICE|CREATE SPATIAL INDEX|CREATE STATISTICS|CREATE SYMMETRIC KEY|CREATE SYNONYM|CREATE TABLE|CREATE TRIGGER|CREATE TYPE|CREATE USER|CREATE VIEW|CREATE WORKLOAD GROUP|CREATE XML INDEX|CREATE XML SCHEMA COLLECTION|DELETE|DISABLE TRIGGER|DROP AGGREGATE|DROP APPLICATION ROLE|DROP ASSEMBLY|DROP ASYMMETRIC KEY|DROP BROKER PRIORITY|DROP CERTIFICATE|DROP CONTRACT|DROP CREDENTIAL|DROP CRYPTOGRAPHIC PROVIDER|DROP DATABASE|DROP DATABASE AUDIT SPECIFICATION|DROP DATABASE ENCRYPTION KEY|DROP DEFAULT|DROP ENDPOINT|DROP EVENT NOTIFICATION|DROP EVENT SESSION|DROP FULLTEXT CATALOG|DROP FULLTEXT INDEX|DROP FULLTEXT STOPLIST|DROP FUNCTION|DROP INDEX|DROP LOGIN|DROP MASTER KEY|DROP MESSAGE TYPE|DROP PARTITION FUNCTION|DROP PARTITION SCHEME|DROP PROCEDURE|DROP QUEUE|DROP REMOTE SERVICE BINDING|DROP RESOURCE POOL|DROP ROLE|DROP ROUTE|DROP RULE|DROP SCHEMA|DROP SERVER AUDIT|DROP SERVER AUDIT SPECIFICATION|DROP SERVICE|DROP SIGNATURE|DROP STATISTICS|DROP SYMMETRIC KEY|DROP SYNONYM|DROP TABLE|DROP TRIGGER|DROP TYPE|DROP USER|DROP VIEW|DROP WORKLOAD GROUP|DROP XML SCHEMA COLLECTION|ENABLE TRIGGER|EXEC|EXECUTE|FROM|INSERT|MERGE|OPTION|OUTPUT|SELECT|TOP|TRUNCATE TABLE|UPDATE|UPDATE STATISTICS|WHERE|WITH)\b", RegexOptions.IgnoreCase);
//key words
range.SetStyle(BlueStyle, @"\b(ADD|ALL|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BY|CASCADE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTINUE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXISTS|EXIT|EXTERNAL|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITY_INSERT|IDENTITYCOL|IF|IN|INDEX|INNER|INTERSECT|INTO|IS|JOIN|KEY|KILL|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|OF|OFF|OFFSETS|ON|OPEN|OR|ORDER|OUTER|OVER|PERCENT|PIVOT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVERT|REVOKE|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SECURITYAUDIT|SET|SHUTDOWN|SOME|STATISTICS|TABLE|TABLESAMPLE|TEXTSIZE|THEN|TO|TRAN|TRANSACTION|TRIGGER|TSEQUAL|UNION|UNIQUE|UNPIVOT|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHILE|WRITETEXT)\b", RegexOptions.IgnoreCase);
//functions
range.SetStyle(MaroonStyle, @"(@@CONNECTIONS|@@CPU_BUSY|@@CURSOR_ROWS|@@DATEFIRST|@@DATEFIRST|@@DBTS|@@ERROR|@@FETCH_STATUS|@@IDENTITY|@@IDLE|@@IO_BUSY|@@LANGID|@@LANGUAGE|@@LOCK_TIMEOUT|@@MAX_CONNECTIONS|@@MAX_PRECISION|@@NESTLEVEL|@@OPTIONS|@@PACKET_ERRORS|@@PROCID|@@REMSERVER|@@ROWCOUNT|@@SERVERNAME|@@SERVICENAME|@@SPID|@@TEXTSIZE|@@TRANCOUNT|@@VERSION)\b|\b(ABS|ACOS|APP_NAME|ASCII|ASIN|ASSEMBLYPROPERTY|AsymKey_ID|ASYMKEY_ID|asymkeyproperty|ASYMKEYPROPERTY|ATAN|ATN2|AVG|CASE|CAST|CEILING|Cert_ID|Cert_ID|CertProperty|CHAR|CHARINDEX|CHECKSUM_AGG|COALESCE|COL_LENGTH|COL_NAME|COLLATIONPROPERTY|COLLATIONPROPERTY|COLUMNPROPERTY|COLUMNS_UPDATED|COLUMNS_UPDATED|CONTAINSTABLE|CONVERT|COS|COT|COUNT|COUNT_BIG|CRYPT_GEN_RANDOM|CURRENT_TIMESTAMP|CURRENT_TIMESTAMP|CURRENT_USER|CURRENT_USER|CURSOR_STATUS|DATABASE_PRINCIPAL_ID|DATABASE_PRINCIPAL_ID|DATABASEPROPERTY|DATABASEPROPERTYEX|DATALENGTH|DATALENGTH|DATEADD|DATEDIFF|DATENAME|DATEPART|DAY|DB_ID|DB_NAME|DECRYPTBYASYMKEY|DECRYPTBYCERT|DECRYPTBYKEY|DECRYPTBYKEYAUTOASYMKEY|DECRYPTBYKEYAUTOCERT|DECRYPTBYPASSPHRASE|DEGREES|DENSE_RANK|DIFFERENCE|ENCRYPTBYASYMKEY|ENCRYPTBYCERT|ENCRYPTBYKEY|ENCRYPTBYPASSPHRASE|ERROR_LINE|ERROR_MESSAGE|ERROR_NUMBER|ERROR_PROCEDURE|ERROR_SEVERITY|ERROR_STATE|EVENTDATA|EXP|FILE_ID|FILE_IDEX|FILE_NAME|FILEGROUP_ID|FILEGROUP_NAME|FILEGROUPPROPERTY|FILEPROPERTY|FLOOR|fn_helpcollations|fn_listextendedproperty|fn_servershareddrives|fn_virtualfilestats|fn_virtualfilestats|FORMATMESSAGE|FREETEXTTABLE|FULLTEXTCATALOGPROPERTY|FULLTEXTSERVICEPROPERTY|GETANSINULL|GETDATE|GETUTCDATE|GROUPING|HAS_PERMS_BY_NAME|HOST_ID|HOST_NAME|IDENT_CURRENT|IDENT_CURRENT|IDENT_INCR|IDENT_INCR|IDENT_SEED|IDENTITY\(|INDEX_COL|INDEXKEY_PROPERTY|INDEXPROPERTY|IS_MEMBER|IS_OBJECTSIGNED|IS_SRVROLEMEMBER|ISDATE|ISDATE|ISNULL|ISNUMERIC|Key_GUID|Key_GUID|Key_ID|Key_ID|KEY_NAME|KEY_NAME|LEFT|LEN|LOG|LOG10|LOWER|LTRIM|MAX|MIN|MONTH|NCHAR|NEWID|NTILE|NULLIF|OBJECT_DEFINITION|OBJECT_ID|OBJECT_NAME|OBJECT_SCHEMA_NAME|OBJECTPROPERTY|OBJECTPROPERTYEX|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|ORIGINAL_LOGIN|ORIGINAL_LOGIN|PARSENAME|PATINDEX|PATINDEX|PERMISSIONS|PI|POWER|PUBLISHINGSERVERNAME|PWDCOMPARE|PWDENCRYPT|QUOTENAME|RADIANS|RAND|RANK|REPLACE|REPLICATE|REVERSE|RIGHT|ROUND|ROW_NUMBER|ROWCOUNT_BIG|RTRIM|SCHEMA_ID|SCHEMA_ID|SCHEMA_NAME|SCHEMA_NAME|SCOPE_IDENTITY|SERVERPROPERTY|SESSION_USER|SESSION_USER|SESSIONPROPERTY|SETUSER|SIGN|SignByAsymKey|SignByCert|SIN|SOUNDEX|SPACE|SQL_VARIANT_PROPERTY|SQRT|SQUARE|STATS_DATE|STDEV|STDEVP|STR|STUFF|SUBSTRING|SUM|SUSER_ID|SUSER_NAME|SUSER_SID|SUSER_SNAME|SWITCHOFFSET|SYMKEYPROPERTY|symkeyproperty|sys\.dm_db_index_physical_stats|sys\.fn_builtin_permissions|sys\.fn_my_permissions|SYSDATETIME|SYSDATETIMEOFFSET|SYSTEM_USER|SYSTEM_USER|SYSUTCDATETIME|TAN|TERTIARY_WEIGHTS|TEXTPTR|TODATETIMEOFFSET|TRIGGER_NESTLEVEL|TYPE_ID|TYPE_NAME|TYPEPROPERTY|UNICODE|UPDATE\(|UPPER|USER_ID|USER_NAME|USER_NAME|VAR|VARP|VerifySignedByAsymKey|VerifySignedByCert|XACT_STATE|YEAR)\b", RegexOptions.IgnoreCase);
//clear folding markers
range.ClearFoldingMarkers();
//set folding markers
range.SetFoldingMarkers(@"\bBEGIN\b", @"\bEND\b", RegexOptions.IgnoreCase);//allow to collapse BEGIN..END blocks
range.SetFoldingMarkers(@"/\*", @"\*/");//allow to collapse comment block
}
/// <summary>
/// Highlights PHP code
/// </summary>
/// <param name="range"></param>
public virtual void PHPSyntaxHighlight(Range range)
{
range.tb.CommentPrefix = "#";
range.tb.LeftBracket = '(';
range.tb.RightBracket = ')';
range.tb.LeftBracket2 = '\x0';
range.tb.RightBracket2 = '\x0';
//clear style of changed range
range.ClearStyle(BlueStyle, GrayStyle, MagentaStyle, GreenStyle, RedStyle, MaroonStyle);
//string highlighting
range.SetStyle(RedStyle, @""".*?""|'.+?'");
//number highlighting
range.SetStyle(RedStyle, @"\b\d+[\.]?\d*\b");
//comment highlighting
range.SetStyle(GreenStyle, @"(//|#).*$", RegexOptions.Multiline);
range.SetStyle(GreenStyle, @"(/\*.*?\*/)|(/\*.*)", RegexOptions.Singleline);
range.SetStyle(GreenStyle, @"(/\*.*?\*/)|(.*\*/)", RegexOptions.Singleline | RegexOptions.RightToLeft);
//var highlighting
range.SetStyle(MaroonStyle, @"\$[a-zA-Z_\d]*\b");
//keyword highlighting
range.SetStyle(MagentaStyle, @"\b(die|echo|empty|exit|eval|include|include_once|isset|list|require|require_once|return|print|unset)\b");
range.SetStyle(BlueStyle, @"\b(abstract|and|array|as|break|case|catch|cfunction|class|clone|const|continue|declare|default|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|final|for|foreach|function|global|goto|if|implements|instanceof|interface|namespace|new|or|private|protected|public|static|switch|throw|try|use|var|while|xor)\b");
range.SetStyle(GrayStyle, @"__CLASS__|__DIR__|__FILE__|__LINE__|__FUNCTION__|__METHOD__|__NAMESPACE__");
//clear folding markers
range.ClearFoldingMarkers();
//set folding markers
range.SetFoldingMarkers("{", "}");//allow to collapse brackets block
range.SetFoldingMarkers(@"/\*", @"\*/");//allow to collapse comment block
}
public void Dispose()
{
foreach (var desc in descByXMLfileNames.Values)
desc.Dispose();
}
}
/// <summary>
/// Language
/// </summary>
public enum Language
{
Custom, CSharp, VB, HTML, SQL, PHP
}
}

View File

@@ -0,0 +1,338 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Drawing;
using System.IO;
namespace FastColoredTextBoxNS
{
/// <summary>
/// This class contains the source text (chars and styles).
/// It stores a text lines, the manager of commands, undo/redo stack, styles.
/// </summary>
public class TextSource: IList<Line>, IDisposable
{
readonly protected List<Line> lines = new List<Line>();
protected LinesAccessor linesAccessor;
int lastLineUniqueId;
public CommandManager Manager { get; set; }
FastColoredTextBox currentTB;
/// <summary>
/// Styles
/// </summary>
public readonly Style[] Styles;
/// <summary>
/// Occurs when line was inserted/added
/// </summary>
public event EventHandler<LineInsertedEventArgs> LineInserted;
/// <summary>
/// Occurs when line was removed
/// </summary>
public event EventHandler<LineRemovedEventArgs> LineRemoved;
/// <summary>
/// Occurs when text was changed
/// </summary>
public event EventHandler<TextChangedEventArgs> TextChanged;
/// <summary>
/// Occurs when recalc is needed
/// </summary>
public event EventHandler<TextChangedEventArgs> RecalcNeeded;
/// <summary>
/// Occurs when recalc wordwrap is needed
/// </summary>
public event EventHandler<TextChangedEventArgs> RecalcWordWrap;
/// <summary>
/// Occurs before text changing
/// </summary>
public event EventHandler<TextChangingEventArgs> TextChanging;
/// <summary>
/// Occurs after CurrentTB was changed
/// </summary>
public event EventHandler CurrentTBChanged;
/// <summary>
/// Current focused FastColoredTextBox
/// </summary>
public FastColoredTextBox CurrentTB {
get { return currentTB; }
set {
if (currentTB == value)
return;
currentTB = value;
OnCurrentTBChanged();
}
}
public virtual void ClearIsChanged()
{
foreach(var line in lines)
line.IsChanged = false;
}
public virtual Line CreateLine()
{
return new Line(GenerateUniqueLineId());
}
private void OnCurrentTBChanged()
{
if (CurrentTBChanged != null)
CurrentTBChanged(this, EventArgs.Empty);
}
/// <summary>
/// Default text style
/// This style is using when no one other TextStyle is not defined in Char.style
/// </summary>
public TextStyle DefaultStyle { get; set; }
public TextSource(FastColoredTextBox currentTB)
{
this.CurrentTB = currentTB;
linesAccessor = new LinesAccessor(this);
Manager = new CommandManager(this);
if (Enum.GetUnderlyingType(typeof(StyleIndex)) == typeof(UInt32))
Styles = new Style[32];
else
Styles = new Style[16];
InitDefaultStyle();
}
public virtual void InitDefaultStyle()
{
DefaultStyle = new TextStyle(null, null, FontStyle.Regular);
}
public virtual Line this[int i]
{
get{
return lines[i];
}
set {
throw new NotImplementedException();
}
}
public virtual bool IsLineLoaded(int iLine)
{
return lines[iLine] != null;
}
/// <summary>
/// Text lines
/// </summary>
public virtual IList<string> GetLines()
{
return linesAccessor;
}
public IEnumerator<Line> GetEnumerator()
{
return lines.GetEnumerator();
}
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return (lines as IEnumerator);
}
public virtual int BinarySearch(Line item, IComparer<Line> comparer)
{
return lines.BinarySearch(item, comparer);
}
public virtual int GenerateUniqueLineId()
{
return lastLineUniqueId++;
}
public virtual void InsertLine(int index, Line line)
{
lines.Insert(index, line);
OnLineInserted(index);
}
public virtual void OnLineInserted(int index)
{
OnLineInserted(index, 1);
}
public virtual void OnLineInserted(int index, int count)
{
if (LineInserted != null)
LineInserted(this, new LineInsertedEventArgs(index, count));
}
public virtual void RemoveLine(int index)
{
RemoveLine(index, 1);
}
public virtual bool IsNeedBuildRemovedLineIds
{
get { return LineRemoved != null; }
}
public virtual void RemoveLine(int index, int count)
{
List<int> removedLineIds = new List<int>();
//
if (count > 0)
if (IsNeedBuildRemovedLineIds)
for (int i = 0; i < count; i++)
removedLineIds.Add(this[index + i].UniqueId);
//
lines.RemoveRange(index, count);
OnLineRemoved(index, count, removedLineIds);
}
public virtual void OnLineRemoved(int index, int count, List<int> removedLineIds)
{
if (count > 0)
if (LineRemoved != null)
LineRemoved(this, new LineRemovedEventArgs(index, count, removedLineIds));
}
public virtual void OnTextChanged(int fromLine, int toLine)
{
if (TextChanged != null)
TextChanged(this, new TextChangedEventArgs(Math.Min(fromLine, toLine), Math.Max(fromLine, toLine) ));
}
public class TextChangedEventArgs : EventArgs
{
public int iFromLine;
public int iToLine;
public TextChangedEventArgs(int iFromLine, int iToLine)
{
this.iFromLine = iFromLine;
this.iToLine = iToLine;
}
}
public virtual int IndexOf(Line item)
{
return lines.IndexOf(item);
}
public virtual void Insert(int index, Line item)
{
InsertLine(index, item);
}
public virtual void RemoveAt(int index)
{
RemoveLine(index);
}
public virtual void Add(Line item)
{
InsertLine(Count, item);
}
public virtual void Clear()
{
RemoveLine(0, Count);
}
public virtual bool Contains(Line item)
{
return lines.Contains(item);
}
public virtual void CopyTo(Line[] array, int arrayIndex)
{
lines.CopyTo(array, arrayIndex);
}
/// <summary>
/// Lines count
/// </summary>
public virtual int Count
{
get { return lines.Count; }
}
public virtual bool IsReadOnly
{
get { return false; }
}
public virtual bool Remove(Line item)
{
int i = IndexOf(item);
if (i >= 0)
{
RemoveLine(i);
return true;
}
else
return false;
}
public virtual void NeedRecalc(TextChangedEventArgs args)
{
if (RecalcNeeded != null)
RecalcNeeded(this, args);
}
public virtual void OnRecalcWordWrap(TextChangedEventArgs args)
{
if (RecalcWordWrap != null)
RecalcWordWrap(this, args);
}
public virtual void OnTextChanging()
{
string temp = null;
OnTextChanging(ref temp);
}
public virtual void OnTextChanging(ref string text)
{
if (TextChanging != null)
{
var args = new TextChangingEventArgs() { InsertingText = text };
TextChanging(this, args);
text = args.InsertingText;
if (args.Cancel)
text = string.Empty;
};
}
public virtual int GetLineLength(int i)
{
return lines[i].Count;
}
public virtual bool LineHasFoldingStartMarker(int iLine)
{
return !string.IsNullOrEmpty(lines[iLine].FoldingStartMarker);
}
public virtual bool LineHasFoldingEndMarker(int iLine)
{
return !string.IsNullOrEmpty(lines[iLine].FoldingEndMarker);
}
public virtual void Dispose()
{
;
}
public virtual void SaveToFile(string fileName, Encoding enc)
{
using (StreamWriter sw = new StreamWriter(fileName, false, enc))
{
for (int i = 0; i < Count - 1;i++ )
sw.WriteLine(lines[i].Text);
sw.Write(lines[Count-1].Text);
}
}
}
}

View File

@@ -0,0 +1,96 @@
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace FastColoredTextBoxNS
{
///
/// These classes are required for correct data binding to Text property of FastColoredTextbox
///
class FCTBDescriptionProvider : TypeDescriptionProvider
{
public FCTBDescriptionProvider(Type type)
: base(GetDefaultTypeProvider(type))
{
}
private static TypeDescriptionProvider GetDefaultTypeProvider(Type type)
{
return TypeDescriptor.GetProvider(type);
}
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance);
return new FCTBTypeDescriptor(defaultDescriptor, instance);
}
}
class FCTBTypeDescriptor : CustomTypeDescriptor
{
ICustomTypeDescriptor parent;
object instance;
public FCTBTypeDescriptor(ICustomTypeDescriptor parent, object instance)
: base(parent)
{
this.parent = parent;
this.instance = instance;
}
public override string GetComponentName()
{
var ctrl = (instance as Control);
return ctrl == null ? null : ctrl.Name;
}
public override EventDescriptorCollection GetEvents()
{
var coll = base.GetEvents();
var list = new EventDescriptor[coll.Count];
for (int i = 0; i < coll.Count; i++)
if (coll[i].Name == "TextChanged")//instead of TextChanged slip BindingTextChanged for binding
list[i] = new FooTextChangedDescriptor(coll[i]);
else
list[i] = coll[i];
return new EventDescriptorCollection(list);
}
}
class FooTextChangedDescriptor : EventDescriptor
{
public FooTextChangedDescriptor(MemberDescriptor desc)
: base(desc)
{
}
public override void AddEventHandler(object component, Delegate value)
{
(component as FastColoredTextBox).BindingTextChanged += value as EventHandler;
}
public override Type ComponentType
{
get { return typeof(FastColoredTextBox); }
}
public override Type EventType
{
get { return typeof(EventHandler); }
}
public override bool IsMulticast
{
get { return true; }
}
public override void RemoveEventHandler(object component, Delegate value)
{
(component as FastColoredTextBox).BindingTextChanged -= value as EventHandler;
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace FastColoredTextBoxNS
{
[System.ComponentModel.ToolboxItem(false)]
public class UnfocusablePanel : UserControl
{
public Color BackColor2 { get; set; }
public Color BorderColor { get; set; }
public new string Text { get; set; }
public StringAlignment TextAlignment { get; set; }
public UnfocusablePanel()
{
SetStyle(ControlStyles.Selectable, false);
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
using (var brush = new LinearGradientBrush(ClientRectangle, BackColor2, BackColor, 90))
e.Graphics.FillRectangle(brush, 0, 0, ClientSize.Width - 1, ClientSize.Height - 1);
using(var pen = new Pen(BorderColor))
e.Graphics.DrawRectangle(pen, 0, 0, ClientSize.Width - 1, ClientSize.Height - 1);
if (!string.IsNullOrEmpty(Text))
{
StringFormat sf = new StringFormat();
sf.Alignment = TextAlignment;
sf.LineAlignment = StringAlignment.Center;
using(var brush = new SolidBrush(ForeColor))
e.Graphics.DrawString(Text, Font, brush, new RectangleF(1, 1, ClientSize.Width - 2, ClientSize.Height - 2), sf);
}
}
}
}

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
namespace FastColoredTextBoxNS
{
public class VisualMarker
{
public readonly Rectangle rectangle;
public VisualMarker(Rectangle rectangle)
{
this.rectangle = rectangle;
}
public virtual void Draw(Graphics gr, Pen pen)
{
}
public virtual Cursor Cursor
{
get { return Cursors.Hand; }
}
}
public class CollapseFoldingMarker: VisualMarker
{
public readonly int iLine;
public CollapseFoldingMarker(int iLine, Rectangle rectangle)
: base(rectangle)
{
this.iLine = iLine;
}
public void Draw(Graphics gr, Pen pen, Brush backgroundBrush, Pen forePen)
{
//draw minus
gr.FillRectangle(backgroundBrush, rectangle);
gr.DrawRectangle(pen, rectangle);
gr.DrawLine(forePen, rectangle.Left + 2, rectangle.Top + rectangle.Height / 2, rectangle.Right - 2, rectangle.Top + rectangle.Height / 2);
}
}
public class ExpandFoldingMarker : VisualMarker
{
public readonly int iLine;
public ExpandFoldingMarker(int iLine, Rectangle rectangle)
: base(rectangle)
{
this.iLine = iLine;
}
public void Draw(Graphics gr, Pen pen, Brush backgroundBrush, Pen forePen)
{
//draw plus
gr.FillRectangle(backgroundBrush, rectangle);
gr.DrawRectangle(pen, rectangle);
gr.DrawLine(forePen, rectangle.Left + 2, rectangle.Top + rectangle.Height / 2, rectangle.Right - 2, rectangle.Top + rectangle.Height / 2);
gr.DrawLine(forePen, rectangle.Left + rectangle.Width / 2, rectangle.Top + 2, rectangle.Left + rectangle.Width / 2, rectangle.Bottom - 2);
}
}
public class FoldedAreaMarker : VisualMarker
{
public readonly int iLine;
public FoldedAreaMarker(int iLine, Rectangle rectangle)
: base(rectangle)
{
this.iLine = iLine;
}
public override void Draw(Graphics gr, Pen pen)
{
gr.DrawRectangle(pen, rectangle);
}
}
public class StyleVisualMarker : VisualMarker
{
public Style Style{get;private set;}
public StyleVisualMarker(Rectangle rectangle, Style style)
: base(rectangle)
{
this.Style = style;
}
}
public class VisualMarkerEventArgs : MouseEventArgs
{
public Style Style { get; private set; }
public StyleVisualMarker Marker { get; private set; }
public VisualMarkerEventArgs(Style style, StyleVisualMarker marker, MouseEventArgs args)
: base(args.Button, args.Clicks, args.X, args.Y, args.Delta)
{
this.Style = style;
this.Marker = marker;
}
}
}

View File

@@ -0,0 +1,42 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastColoredTextBox", "FastColoredTextBox\FastColoredTextBox.csproj", "{6DD14A85-CCFC-4774-BD26-0F5772512319}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tester", "Tester\Tester.csproj", "{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Debug|x86.ActiveCfg = Debug|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|Any CPU.Build.0 = Release|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{6DD14A85-CCFC-4774-BD26-0F5772512319}.Release|x86.ActiveCfg = Release|Any CPU
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|Any CPU.ActiveCfg = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|Mixed Platforms.Build.0 = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|x86.ActiveCfg = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Debug|x86.Build.0 = Debug|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|Any CPU.ActiveCfg = Release|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|Mixed Platforms.ActiveCfg = Release|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|Mixed Platforms.Build.0 = Release|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|x86.ActiveCfg = Release|x86
{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,14 @@
FastColoredTextBox
==================
Fast Colored TextBox is text editor component for .NET.
Allows you to create custom text editor with syntax highlighting.
It works well with small, medium, large and very-very large files.
It has such settings as foreground color, font style, background color which can be adjusted for arbitrarily selected text symbols. One can easily gain access to a text with the use of regular expressions. WordWrap, Find/Replace, Code folding and multilevel Undo/Redo are supported as well.
![Fast Colored TextBox](http://www.codeproject.com/KB/edit/FastColoredTextBox_/fastcoloredtextbox2.png)
More details http://www.codeproject.com/Articles/161871/Fast-Colored-TextBox-for-syntax-highlighting
Nuget package https://www.nuget.org/packages/FCTB/

View File

@@ -0,0 +1,108 @@
namespace Tester
{
partial class AutoIndentCharsSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.label1 = new System.Windows.Forms.Label();
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(490, 42);
this.label1.TabIndex = 2;
this.label1.Text = "This example demonstrates AutoIndentChars functionality.\r\nPress Ctrl-I or type ne" +
"w command.";
//
// fctb
//
this.fctb.AutoCompleteBracketsList = new char[] {
'(',
')',
'{',
'}',
'[',
']',
'\"',
'\"',
'\'',
'\''};
this.fctb.AutoIndentCharsPatterns = "^\\s*[\\w\\.]+(\\s\\w+)?\\s*(?<range>=)\\s*(?<range>[^;=]+);\r\n^\\s*(case|default)\\s*[^:]*(?<range>:)\\s*(?<range>[^;]+);";
this.fctb.AutoScrollMinSize = new System.Drawing.Size(137, 180);
this.fctb.BackBrush = null;
this.fctb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fctb.BracketsHighlightStrategy = FastColoredTextBoxNS.BracketsHighlightStrategy.Strategy2;
this.fctb.CharHeight = 15;
this.fctb.CharWidth = 7;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DelayedEventsInterval = 500;
this.fctb.DelayedTextChangedInterval = 500;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F);
this.fctb.IsReplaceMode = false;
this.fctb.LeftBracket = '(';
this.fctb.LeftBracket2 = '{';
this.fctb.Location = new System.Drawing.Point(0, 42);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(0);
this.fctb.RightBracket = ')';
this.fctb.RightBracket2 = '}';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.Size = new System.Drawing.Size(490, 311);
this.fctb.TabIndex = 3;
this.fctb.Text = "POP DX\r\nXOR DL,40H\r\nMOV AH,36H\r\nINT 21H\r\nCMP AX, 0FFFFH\r\nJE EXITSPC\r\nXOR DX,DX\r\n" +
"MUL CX\r\nXCHG BX,CX\r\nMUL CX\r\nPUSH AX\r\nPUSH DX";
this.fctb.Zoom = 100;
//
// AutoIndentCharsSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(490, 353);
this.Controls.Add(this.fctb);
this.Controls.Add(this.label1);
this.Name = "AutoIndentCharsSample";
this.Text = "AutoIndentChars Sample";
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private FastColoredTextBoxNS.FastColoredTextBox fctb;
}
}

View File

@@ -0,0 +1,14 @@
using System.Windows.Forms;
namespace Tester
{
public partial class AutoIndentCharsSample : Form
{
public AutoIndentCharsSample()
{
InitializeComponent();
fctb.AutoIndentChars = true;
fctb.AutoIndentCharsPatterns = @"^\s*\w+\s+(?<range>[^,]+)\s*,?\s*(?<range>.+)?";
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,140 @@
namespace Tester
{
partial class AutoIndentSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AutoIndentSample));
this.label1 = new System.Windows.Forms.Label();
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.panel1 = new System.Windows.Forms.Panel();
this.label2 = new System.Windows.Forms.Label();
this.cbAutoIndentType = new System.Windows.Forms.ComboBox();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(490, 42);
this.label1.TabIndex = 2;
this.label1.Text = "This example demonstrates AutoIndent functionality.\r\nControl automatically define" +
"s indentation for each new line.";
//
// fctb
//
this.fctb.AutoScrollMinSize = new System.Drawing.Size(25, 15);
this.fctb.BackBrush = null;
this.fctb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DelayedEventsInterval = 500;
this.fctb.DelayedTextChangedInterval = 500;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F);
this.fctb.Language = FastColoredTextBoxNS.Language.CSharp;
this.fctb.LeftBracket = '(';
this.fctb.Location = new System.Drawing.Point(0, 75);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(0);
this.fctb.RightBracket = ')';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.Size = new System.Drawing.Size(490, 278);
this.fctb.TabIndex = 3;
//
// imageList1
//
this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
this.imageList1.Images.SetKeyName(0, "script_16x16.png");
this.imageList1.Images.SetKeyName(1, "app_16x16.png");
this.imageList1.Images.SetKeyName(2, "1302166543_virtualbox.png");
//
// panel1
//
this.panel1.Controls.Add(this.label2);
this.panel1.Controls.Add(this.cbAutoIndentType);
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
this.panel1.Location = new System.Drawing.Point(0, 42);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(490, 33);
this.panel1.TabIndex = 5;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(8, 8);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(85, 13);
this.label2.TabIndex = 6;
this.label2.Text = "AutoIndent type:";
//
// cbAutoIndentType
//
this.cbAutoIndentType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.cbAutoIndentType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbAutoIndentType.FormattingEnabled = true;
this.cbAutoIndentType.Items.AddRange(new object[] {
"Built-in AutoIndent for C#",
"Custom AutoIndent by AutoIndentNeeded event handler."});
this.cbAutoIndentType.Location = new System.Drawing.Point(99, 5);
this.cbAutoIndentType.Name = "cbAutoIndentType";
this.cbAutoIndentType.Size = new System.Drawing.Size(387, 21);
this.cbAutoIndentType.TabIndex = 5;
this.cbAutoIndentType.SelectedIndexChanged += new System.EventHandler(this.cbAutoIndentType_SelectedIndexChanged);
//
// AutoIndentSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(490, 353);
this.Controls.Add(this.fctb);
this.Controls.Add(this.panel1);
this.Controls.Add(this.label1);
this.Name = "AutoIndentSample";
this.Text = "AutoIndent Sample";
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private FastColoredTextBoxNS.FastColoredTextBox fctb;
private System.Windows.Forms.ImageList imageList1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.ComboBox cbAutoIndentType;
}
}

View File

@@ -0,0 +1,94 @@
using System.Windows.Forms;
using FastColoredTextBoxNS;
using System.Drawing;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Tester
{
public partial class AutoIndentSample : Form
{
public AutoIndentSample()
{
InitializeComponent();
cbAutoIndentType.SelectedIndex = 0;
}
private void cbAutoIndentType_SelectedIndexChanged(object sender, EventArgs e)
{
if(cbAutoIndentType.SelectedIndex == 0)//built-in C# AutoIndent
{
fctb.Language = Language.CSharp;
fctb.AutoIndentNeeded -= new EventHandler<AutoIndentEventArgs>(fctb_AutoIndentNeeded);
fctb.Text = @"/// Please, type next text (without slashes):
/// int Foo()
/// {
/// int i=10;
/// label:
/// while(i!=j){
/// i--;
/// j++;
/// }
/// if(i==0)
/// return i;
/// else
/// return j;
/// }
";
fctb.GoEnd();
fctb.Focus();
}
if(cbAutoIndentType.SelectedIndex == 1)//custom AutoIndent
{
fctb.Language = Language.Custom;
fctb.AutoIndentNeeded += new EventHandler<AutoIndentEventArgs>(fctb_AutoIndentNeeded);
fctb.Text = @"/// Please, type next text (without slashes):
/// begin
/// i := 1;
/// if j=0 then
/// begin
/// i := 10;
/// end
/// else
/// i := 20;
/// end
";
fctb.GoEnd();
fctb.Focus();
}
}
void fctb_AutoIndentNeeded(object sender, AutoIndentEventArgs e)
{
// if current line is "begin" then next
// line shift to right
if (e.LineText.Trim() == "begin")
{
e.ShiftNextLines = e.TabLength;
return;
}
// if current line is "end" then current
// and next line shift to left
if (e.LineText.Trim() == "end")
{
e.Shift = -e.TabLength;
e.ShiftNextLines = -e.TabLength;
return;
}
// if previous line contains "then" or "else",
// and current line does not contain "begin"
// then shift current line to right
if (Regex.IsMatch(e.PrevLineText, @"\b(then|else)\b") &&
!Regex.IsMatch(e.LineText, @"\bbegin\b"))
{
e.Shift = e.TabLength;
return;
}
}
}
}

View File

@@ -0,0 +1,165 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="imageList1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="imageList1.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAI
CAAAAk1TRnQBSQFMAgEBAwEAAUgBAAFIAQABEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABEAMAAQEBAAEYBgABDCEAA/8D9AP+OQAD/wMAA/8VAAP+A/sD9wP2A/kD/VEAA70BswGyAbED7TMA
A/kBvAG7AbwDzwO/A/0PAAP+A/UD4APSAcwBywHMAtMB1APqA/wD/0sAA/4BzwLOAcsBygHIA7sD9CoA
A/0DwQLvAfAD6QPoA90D/wkAA/4D9QHaAtgByQLFAcECvAG0AbMBtAGvAawBrgHAAb8BwAPnA/xLAAPu
AfEC8ALuAe0B5wHlAeQBwgHAAb8DwwP4GAAD/QPsA/4DAAO2A/ED9QPwA/ED6wPmBgAD/gP6AeMC4gHG
AsIBxwHAAbsBzgHHAcECvAG6AakBpwGfA6cBxwLIA/ID/UUAA/wDywP/A/gD8gHsAesB6gHjAeIB4QG9
AbwBuwPYA/oMAAP+A8YDxAPiA8sDxAOsAegB5wHoA78D9wO5A/YD5QMAA/8D/APwAdABzwHOAcsBwAG0
Ad0BugGQAdgBwgGmAcUBvQGoAcoBrwFuAboBrwGSAbQCtQPgA/gD/kIAA8gG/wP+AfwC+wL4AfcC8QHw
AewB6wHqAdMB0gHRAd0C3AkAA/0DsgPtAtMB1ALSAdMDzwPSAZoCmQLjAeID3QOOA/8D9gPwAwAD/gP2
AdwB2AHWAdUBwgGwAeUBswF4Ae0BpwFTAdoBuAGOAckBuwGcAeUBqQE4AegBrwFHAckBtQGTAccBxQHB
A+kD/AP/PAAD1Q3/Av4D/QP7A/oB6QLoA98GAAP+A9ADAAP9A/8D8gH7AfoB+QPkAsQBxQGxAbABrwPc
AvAB7wP2A+wGAAP9AewB6AHnAeABwQGjAesBrQFnAfMBrQFeAfABrAFcAdkBuAGRAcgBuQGgAegBqgFV
AfsBrgFIAfEBsAFZAdcBsgGHAdYB0gHNA/gD/zkAA+8D9Rj/A9kD+wYAA9QD5wP4A+QD5QP1A94B5QTk
AeMD0wOrA88D3QkAA/wB6AHeAdUB6gGrAWIB8wGpAVYB9QG3AXAB8AGyAWkB1wG3AZIBxgG3AaEB5gGg
AWUB+wGvAXEB/QGvAXAB8wGjAWIB2AG/AasC9gH1A/82AAP+A9MY/wPWCQAD/APFA+YD+wPlCQAD3QH2
AfUB9AHbAdoB2wPMA/8MAAP8AecB2gHNAfABvAF/AfYBvQF7AfMBrAFYAesBoQFLAdEBtgGWAcIBtgGg
AdsBjQFSAfUBkgFJAfsBrQFwAfgBsQF9AdsBuwGiAvUB9AP/NgAD2gP/A/wD/g//A9MMAAPlAf4B/QH8
A+UD1AP3CQAD8gHgAt8B4gHhAeIB9ALzA+8MAAP8AecB1wHGAfABtgF0AfMBtwFwAeoBqQFbAdsBtQGI
Ac8ByAG/AccBxAG4AcQBpgF/Ad0BmQFMAfABoQFCAfMBqwFRAdoBuAGOAfQB8wHyA/8zAAP6AcsCygH1
AvQB8gLxA/gD/QP+Bv8D6wP6DAAD+wPRAesC6gHvAe4B7QPRCQADxQP5AekC6APXA/0MAAP7AeQB0AG6
AekBpgFXAeQBsgF4AdoBxwGwAdkB0wHIAdoBzwG0AdgByQGkAc8BygG1AccBvAGhAdMBrAFnAeEBogE5
AdUBsAFxAfEB8AHuA/42AAPnAdABzwHNA/8C+QH4A/QD+QL+Af0D/wPlEgAD0QLxAfAB9wH2AfUBvQK8
A8YD4AO7A84D/wH3AvYD2Q8AA/oB3wHTAcUB3QHBAZ8B3QHQAcEB5AHUAcEB6wHHAZQB7wG8AWsB8gG+
AWoB7AHGAYkB4QHMAa0B1QHKAbcBzgG7AZAByAG1AY4B7QHsAeoD/jkAA/UDzQP9A/8C9wH2Af4C/QPQ
FQAD7AHIAscD6AL3AfYB6wLqA9EC9gH1A/8D7QO5A+4MAAP/A/gC4QHfAeUB2gHRAe0BzAG0AfUBuwGL
AfkBsQFwAfsBqgFcAf0BvAF7AfwBuQF8AfgBuAGAAe4BxQGlAd8BzQG+AdEBzgHFAuwB6wP+PwAD5wPR
Bv8D2QP/FQAD/gHCAsED/QP/A/YG/wPIA/4SAAP8A/EB7gHkAd8B8gHPAbQB+AG9AYsB/AG0AXMB/QG5
AXoB/QHIAZMB/AG9AYQB+QG6AYcB8gHJAaoB7AHbAc8B6wHqAekD+AP/QgAD/gHWAtUB4ALfA/8D0BgA
A+sD4APUA/0D1gPgAe8B7gHvFQAD/wP9A/kB8wHxAe4B7wHjAdUB8gHWAa0B9wHNAYgB+AHLAXwB9AHX
AagB7gHfAcsB8AHtAekB9wL2A/wD/0sAA/cD1wPxHgAD+gPtA/oD/x4AA/8D/QL5AfgB8gHwAewB7wHm
AdMB8AHkAcgB8AHtAecB9wH2AfUD/AP+OQABQgFNAT4HAAE+AwABKAMAAUADAAEQAwABAQEAAQEFAAGA
FwAD/wEAAfgC/wHrAfgBHwIAAfwBfwH/AcEB8AEHAgAB/AEfAf8BgAHgAQcCAAH8AQcB+AGAAcABAwIA
AfgBAQHgAQABgAEBAgAB+AEBAcABAAGAAwAB8AEBAZABAQGAAwAB4AEBAYABAwGAAwABwAMHAYADAAHA
AQ8CBwGAAwABgAEPAgcBgAMAAcABHwGAAQ8BgAMAAeABPwGAAQ8EAAH4AR8BwAEfAYADAAH8AR8B4AE/
AYABAQIAAf8BHwH4AX8B4AEHAgAL
</value>
</data>
</root>

View File

@@ -0,0 +1,110 @@
namespace Tester
{
partial class AutocompleteSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AutocompleteSample));
this.label1 = new System.Windows.Forms.Label();
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(354, 50);
this.label1.TabIndex = 2;
this.label1.Text = "This example shows how to create simplest autocomplete functionality.\r\nPopup menu" +
" contains 500000 words.";
//
// fctb
//
this.fctb.AutoCompleteBracketsList = new char[] {
'(',
')',
'{',
'}',
'[',
']',
'\"',
'\"',
'\'',
'\''};
this.fctb.AutoIndent = false;
this.fctb.AutoScrollMinSize = new System.Drawing.Size(0, 105);
this.fctb.BackBrush = null;
this.fctb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fctb.CharHeight = 15;
this.fctb.CharWidth = 7;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DelayedEventsInterval = 500;
this.fctb.DelayedTextChangedInterval = 500;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.fctb.Hotkeys = resources.GetString("fctb.Hotkeys");
this.fctb.IsReplaceMode = false;
this.fctb.LeftBracket = '(';
this.fctb.Location = new System.Drawing.Point(0, 50);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(0);
this.fctb.RightBracket = ')';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.ServiceColors = ((FastColoredTextBoxNS.ServiceColors)(resources.GetObject("fctb.ServiceColors")));
this.fctb.ShowLineNumbers = false;
this.fctb.Size = new System.Drawing.Size(354, 211);
this.fctb.TabIndex = 3;
this.fctb.Text = resources.GetString("fctb.Text");
this.fctb.WordWrap = true;
this.fctb.Zoom = 100;
this.fctb.KeyDown += new System.Windows.Forms.KeyEventHandler(this.fctb_KeyDown);
//
// AutocompleteSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(354, 261);
this.Controls.Add(this.fctb);
this.Controls.Add(this.label1);
this.Name = "AutocompleteSample";
this.Text = "AutocompleteSample";
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private FastColoredTextBoxNS.FastColoredTextBox fctb;
}
}

View File

@@ -0,0 +1,47 @@
using System.Windows.Forms;
using FastColoredTextBoxNS;
using System;
using System.Collections.Generic;
namespace Tester
{
public partial class AutocompleteSample : Form
{
FastColoredTextBoxNS.AutocompleteMenu popupMenu;
public AutocompleteSample()
{
InitializeComponent();
//create autocomplete popup menu
popupMenu = new FastColoredTextBoxNS.AutocompleteMenu(fctb);
popupMenu.MinFragmentLength = 2;
//generate 456976 words
var randomWords = new List<string>();
int codeA = Convert.ToInt32('a');
for (int i = 0; i < 26; i++)
for (int j = 0; j < 26; j++)
for (int k = 0; k < 26; k++)
for (int l = 0; l < 26; l++)
randomWords.Add(
new string(new char[]{Convert.ToChar(i + codeA), Convert.ToChar(j + codeA), Convert.ToChar(k + codeA), Convert.ToChar(l + codeA)}));
//set words as autocomplete source
popupMenu.Items.SetAutocompleteItems(randomWords);
//size of popupmenu
popupMenu.Items.MaximumSize = new System.Drawing.Size(200, 300);
popupMenu.Items.Width = 200;
}
private void fctb_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == (Keys.K | Keys.Control))
{
//forced show (MinFragmentLength will be ignored)
popupMenu.Show(true);
e.Handled = true;
}
}
}
}

View File

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="fctb.Hotkeys" xml:space="preserve">
<value>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+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</value>
</data>
<data name="fctb.ServiceColors" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFZGYXN0Q29sb3JlZFRleHRCb3gsIFZlcnNpb249Mi4xNi43LjAs
IEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49ZmI4YWExMmI5OTRlZjYxYgwDAAAAUVN5c3Rl
bS5EcmF3aW5nLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49
YjAzZjVmN2YxMWQ1MGEzYQUBAAAAIkZhc3RDb2xvcmVkVGV4dEJveE5TLlNlcnZpY2VDb2xvcnMGAAAA
KDxDb2xsYXBzZU1hcmtlckZvcmVDb2xvcj5rX19CYWNraW5nRmllbGQoPENvbGxhcHNlTWFya2VyQmFj
a0NvbG9yPmtfX0JhY2tpbmdGaWVsZCo8Q29sbGFwc2VNYXJrZXJCb3JkZXJDb2xvcj5rX19CYWNraW5n
RmllbGQmPEV4cGFuZE1hcmtlckZvcmVDb2xvcj5rX19CYWNraW5nRmllbGQmPEV4cGFuZE1hcmtlckJh
Y2tDb2xvcj5rX19CYWNraW5nRmllbGQoPEV4cGFuZE1hcmtlckJvcmRlckNvbG9yPmtfX0JhY2tpbmdG
aWVsZAQEBAQEBBRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAA
FFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAAABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRy
YXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAAAAIAAAAF/P///xRTeXN0ZW0uRHJh
d2luZy5Db2xvcgQAAAAEbmFtZQV2YWx1ZQprbm93bkNvbG9yBXN0YXRlAQAAAAkHBwMAAAAKAAAAAAAA
AACWAAEAAfv////8////CgAAAAAAAAAApAABAAH6/////P///woAAAAAAAAAAJYAAQAB+f////z///8K
AAAAAAAAAACNAAEAAfj////8////CgAAAAAAAAAApAABAAH3/////P///woAAAAAAAAAAJYAAQAL
</value>
</data>
<data name="fctb.Text" xml:space="preserve">
<value>You can start enter any word. Control will offer variants of the insert.
You can insert proposed variant by ENTER key.
Key ESC closes popup menu.
Also you can press CTRL+SPACE or CTRL+K for forced show of popup menu.
</value>
</data>
</root>

View File

@@ -0,0 +1,100 @@
namespace Tester
{
partial class AutocompleteSample2
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AutocompleteSample2));
this.label1 = new System.Windows.Forms.Label();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(490, 85);
this.label1.TabIndex = 2;
this.label1.Text = resources.GetString("label1.Text");
//
// imageList1
//
this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
this.imageList1.Images.SetKeyName(0, "script_16x16.png");
this.imageList1.Images.SetKeyName(1, "app_16x16.png");
this.imageList1.Images.SetKeyName(2, "1302166543_virtualbox.png");
//
// fctb
//
this.fctb.AutoScrollMinSize = new System.Drawing.Size(466, 330);
this.fctb.BackBrush = null;
this.fctb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DelayedEventsInterval = 500;
this.fctb.DelayedTextChangedInterval = 500;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F);
this.fctb.IsReplaceMode = false;
this.fctb.Language = FastColoredTextBoxNS.Language.CSharp;
this.fctb.LeftBracket = '(';
this.fctb.Location = new System.Drawing.Point(0, 85);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(0);
this.fctb.RightBracket = ')';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.Size = new System.Drawing.Size(490, 268);
this.fctb.TabIndex = 3;
this.fctb.Text = resources.GetString("fctb.Text");
//
// AutocompleteSample2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(490, 353);
this.Controls.Add(this.fctb);
this.Controls.Add(this.label1);
this.Name = "AutocompleteSample2";
this.Text = "AutocompleteSample2";
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private FastColoredTextBoxNS.FastColoredTextBox fctb;
private System.Windows.Forms.ImageList imageList1;
}
}

View File

@@ -0,0 +1,181 @@
using System.Windows.Forms;
using FastColoredTextBoxNS;
using System.Drawing;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Tester
{
public partial class AutocompleteSample2 : Form
{
AutocompleteMenu popupMenu;
string[] keywords = { "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while", "add", "alias", "ascending", "descending", "dynamic", "from", "get", "global", "group", "into", "join", "let", "orderby", "partial", "remove", "select", "set", "value", "var", "where", "yield" };
string[] methods = { "Equals()", "GetHashCode()", "GetType()", "ToString()"};
string[] snippets = { "if(^)\n{\n;\n}", "if(^)\n{\n;\n}\nelse\n{\n;\n}", "for(^;;)\n{\n;\n}", "while(^)\n{\n;\n}", "do${\n^;\n}while();", "switch(^)\n{\ncase : break;\n}"};
string[] declarationSnippets = {
"public class ^\n{\n}", "private class ^\n{\n}", "internal class ^\n{\n}",
"public struct ^\n{\n;\n}", "private struct ^\n{\n;\n}", "internal struct ^\n{\n;\n}",
"public void ^()\n{\n;\n}", "private void ^()\n{\n;\n}", "internal void ^()\n{\n;\n}", "protected void ^()\n{\n;\n}",
"public ^{ get; set; }", "private ^{ get; set; }", "internal ^{ get; set; }", "protected ^{ get; set; }"
};
public AutocompleteSample2()
{
InitializeComponent();
//create autocomplete popup menu
popupMenu = new AutocompleteMenu(fctb);
popupMenu.Items.ImageList = imageList1;
popupMenu.SearchPattern = @"[\w\.:=!<>]";
popupMenu.AllowTabKey = true;
//
BuildAutocompleteMenu();
}
private void BuildAutocompleteMenu()
{
List<AutocompleteItem> items = new List<AutocompleteItem>();
foreach (var item in snippets)
items.Add(new SnippetAutocompleteItem(item) { ImageIndex = 1 });
foreach (var item in declarationSnippets)
items.Add(new DeclarationSnippet(item) { ImageIndex = 0 });
foreach (var item in methods)
items.Add(new MethodAutocompleteItem(item) { ImageIndex = 2 });
foreach (var item in keywords)
items.Add(new AutocompleteItem(item));
items.Add(new InsertSpaceSnippet());
items.Add(new InsertSpaceSnippet(@"^(\w+)([=<>!:]+)(\w+)$"));
items.Add(new InsertEnterSnippet());
//set as autocomplete source
popupMenu.Items.SetAutocompleteItems(items);
}
/// <summary>
/// This item appears when any part of snippet text is typed
/// </summary>
class DeclarationSnippet : SnippetAutocompleteItem
{
public DeclarationSnippet(string snippet)
: base(snippet)
{
}
public override CompareResult Compare(string fragmentText)
{
var pattern = Regex.Escape(fragmentText);
if (Regex.IsMatch(Text, "\\b" + pattern, RegexOptions.IgnoreCase))
return CompareResult.Visible;
return CompareResult.Hidden;
}
}
/// <summary>
/// Divides numbers and words: "123AND456" -> "123 AND 456"
/// Or "i=2" -> "i = 2"
/// </summary>
class InsertSpaceSnippet : AutocompleteItem
{
string pattern;
public InsertSpaceSnippet(string pattern):base("")
{
this.pattern = pattern;
}
public InsertSpaceSnippet()
: this(@"^(\d+)([a-zA-Z_]+)(\d*)$")
{
}
public override CompareResult Compare(string fragmentText)
{
if (Regex.IsMatch(fragmentText, pattern))
{
Text = InsertSpaces(fragmentText);
if(Text != fragmentText)
return CompareResult.Visible;
}
return CompareResult.Hidden;
}
public string InsertSpaces(string fragment)
{
var m = Regex.Match(fragment, pattern);
if (m == null)
return fragment;
if (m.Groups[1].Value == "" && m.Groups[3].Value == "")
return fragment;
return (m.Groups[1].Value + " " + m.Groups[2].Value + " " + m.Groups[3].Value).Trim();
}
public override string ToolTipTitle
{
get
{
return Text;
}
}
}
/// <summary>
/// Inerts line break after '}'
/// </summary>
class InsertEnterSnippet : AutocompleteItem
{
Place enterPlace = Place.Empty;
public InsertEnterSnippet()
: base("[Line break]")
{
}
public override CompareResult Compare(string fragmentText)
{
var r = Parent.Fragment.Clone();
while (r.Start.iChar > 0)
{
if (r.CharBeforeStart == '}')
{
enterPlace = r.Start;
return CompareResult.Visible;
}
r.GoLeftThroughFolded();
}
return CompareResult.Hidden;
}
public override string GetTextForReplace()
{
//extend range
Range r = Parent.Fragment;
Place end = r.End;
r.Start = enterPlace;
r.End = r.End;
//insert line break
return Environment.NewLine + r.Text;
}
public override void OnSelected(AutocompleteMenu popupMenu, SelectedEventArgs e)
{
base.OnSelected(popupMenu, e);
if (Parent.Fragment.tb.AutoIndent)
Parent.Fragment.tb.DoAutoIndent();
}
public override string ToolTipTitle
{
get
{
return "Insert line break after '}'";
}
}
}
}
}

View File

@@ -0,0 +1,197 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="label1.Text" xml:space="preserve">
<value>This example demonstrates more flexible variant of AutocompleteMenu using.
Start typing "class" for declaration snippets demo.
Start typing "if" for code snippets demo.
Start typing "i.GetType()" for methods hint demo.
Also try "123AND456" or "i=0" for divide numbers and words.
</value>
</data>
<metadata name="imageList1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="imageList1.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAI
CAAAAk1TRnQBSQFMAgEBAwEAAZABAQGQAQEBEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABEAMAAQEBAAEYBgABDCEAA/8D9AP+OQAD/wMAA/8VAAP+A/sD9wP2A/kD/VEAA70BswGyAbED7TMA
A/kBvAG7AbwDzwO/A/0PAAP+A/UD4APSAcwBywHMAtMB1APqA/wD/0sAA/4BzwLOAcsBygHIA7sD9CoA
A/0DwQLvAfAD6QPoA90D/wkAA/4D9QHaAtgByQLFAcECvAG0AbMBtAGvAawBrgHAAb8BwAPnA/xLAAPu
AfEC8ALuAe0B5wHlAeQBwgHAAb8DwwP4GAAD/QPsA/4DAAO2A/ED9QPwA/ED6wPmBgAD/gP6AeMC4gHG
AsIBxwHAAbsBzgHHAcECvAG6AakBpwGfA6cBxwLIA/ID/UUAA/wDywP/A/gD8gHsAesB6gHjAeIB4QG9
AbwBuwPYA/oMAAP+A8YDxAPiA8sDxAOsAegB5wHoA78D9wO5A/YD5QMAA/8D/APwAdABzwHOAcsBwAG0
Ad0BugGQAdgBwgGmAcUBvQGoAcoBrwFuAboBrwGSAbQCtQPgA/gD/kIAA8gG/wP+AfwC+wL4AfcC8QHw
AewB6wHqAdMB0gHRAd0C3AkAA/0DsgPtAtMB1ALSAdMDzwPSAZoCmQLjAeID3QOOA/8D9gPwAwAD/gP2
AdwB2AHWAdUBwgGwAeUBswF4Ae0BpwFTAdoBuAGOAckBuwGcAeUBqQE4AegBrwFHAckBtQGTAccBxQHB
A+kD/AP/PAAD1Q3/Av4D/QP7A/oB6QLoA98GAAP+A9ADAAP9A/8D8gH7AfoB+QPkAsQBxQGxAbABrwPc
AvAB7wP2A+wGAAP9AewB6AHnAeABwQGjAesBrQFnAfMBrQFeAfABrAFcAdkBuAGRAcgBuQGgAegBqgFV
AfsBrgFIAfEBsAFZAdcBsgGHAdYB0gHNA/gD/zkAA+8D9Rj/A9kD+wYAA9QD5wP4A+QD5QP1A94B5QTk
AeMD0wOrA88D3QkAA/wB6AHeAdUB6gGrAWIB8wGpAVYB9QG3AXAB8AGyAWkB1wG3AZIBxgG3AaEB5gGg
AWUB+wGvAXEB/QGvAXAB8wGjAWIB2AG/AasC9gH1A/82AAP+A9MY/wPWCQAD/APFA+YD+wPlCQAD3QH2
AfUB9AHbAdoB2wPMA/8MAAP8AecB2gHNAfABvAF/AfYBvQF7AfMBrAFYAesBoQFLAdEBtgGWAcIBtgGg
AdsBjQFSAfUBkgFJAfsBrQFwAfgBsQF9AdsBuwGiAvUB9AP/NgAD2gP/A/wD/g//A9MMAAPlAf4B/QH8
A+UD1AP3CQAD8gHgAt8B4gHhAeIB9ALzA+8MAAP8AecB1wHGAfABtgF0AfMBtwFwAeoBqQFbAdsBtQGI
Ac8ByAG/AccBxAG4AcQBpgF/Ad0BmQFMAfABoQFCAfMBqwFRAdoBuAGOAfQB8wHyA/8zAAP6AcsCygH1
AvQB8gLxA/gD/QP+Bv8D6wP6DAAD+wPRAesC6gHvAe4B7QPRCQADxQP5AekC6APXA/0MAAP7AeQB0AG6
AekBpgFXAeQBsgF4AdoBxwGwAdkB0wHIAdoBzwG0AdgByQGkAc8BygG1AccBvAGhAdMBrAFnAeEBogE5
AdUBsAFxAfEB8AHuA/42AAPnAdABzwHNA/8C+QH4A/QD+QL+Af0D/wPlEgAD0QLxAfAB9wH2AfUBvQK8
A8YD4AO7A84D/wH3AvYD2Q8AA/oB3wHTAcUB3QHBAZ8B3QHQAcEB5AHUAcEB6wHHAZQB7wG8AWsB8gG+
AWoB7AHGAYkB4QHMAa0B1QHKAbcBzgG7AZAByAG1AY4B7QHsAeoD/jkAA/UDzQP9A/8C9wH2Af4C/QPQ
FQAD7AHIAscD6AL3AfYB6wLqA9EC9gH1A/8D7QO5A+4MAAP/A/gC4QHfAeUB2gHRAe0BzAG0AfUBuwGL
AfkBsQFwAfsBqgFcAf0BvAF7AfwBuQF8AfgBuAGAAe4BxQGlAd8BzQG+AdEBzgHFAuwB6wP+PwAD5wPR
Bv8D2QP/FQAD/gHCAsED/QP/A/YG/wPIA/4SAAP8A/EB7gHkAd8B8gHPAbQB+AG9AYsB/AG0AXMB/QG5
AXoB/QHIAZMB/AG9AYQB+QG6AYcB8gHJAaoB7AHbAc8B6wHqAekD+AP/QgAD/gHWAtUB4ALfA/8D0BgA
A+sD4APUA/0D1gPgAe8B7gHvFQAD/wP9A/kB8wHxAe4B7wHjAdUB8gHWAa0B9wHNAYgB+AHLAXwB9AHX
AagB7gHfAcsB8AHtAekB9wL2A/wD/0sAA/cD1wPxHgAD+gPtA/oD/x4AA/8D/QL5AfgB8gHwAewB7wHm
AdMB8AHkAcgB8AHtAecB9wH2AfUD/AP+OQABQgFNAT4HAAE+AwABKAMAAUADAAEQAwABAQEAAQEFAAGA
FwAD/wEAAfgC/wHrAfgBHwIAAfwBfwH/AcEB8AEHAgAB/AEfAf8BgAHgAQcCAAH8AQcB+AGAAcABAwIA
AfgBAQHgAQABgAEBAgAB+AEBAcABAAGAAwAB8AEBAZABAQGAAwAB4AEBAYABAwGAAwABwAMHAYADAAHA
AQ8CBwGAAwABgAEPAgcBgAMAAcABHwGAAQ8BgAMAAeABPwGAAQ8EAAH4AR8BwAEfAYADAAH8AR8B4AE/
AYABAQIAAf8BHwH4AX8B4AEHAgAL
</value>
</data>
<data name="fctb.Text" xml:space="preserve">
<value>//You can insert proposed variant by ENTER or TAB keys.
//Key ESC closes popup menu.
//Also you can press CTRL+SPACE for forced show of popup menu.
#region Char
/// &lt;summary&gt;
/// Char and style
/// &lt;/summary&gt;
struct Char
{
public char c;
public StyleIndex style;
public Char(char c)
{
this.c = c;
style = StyleIndex.None;
}
}
#endregion</value>
</data>
</root>

View File

@@ -0,0 +1,93 @@
namespace Tester
{
partial class AutocompleteSample3
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.label1 = new System.Windows.Forms.Label();
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(576, 26);
this.label1.TabIndex = 2;
this.label1.Text = "Sample demonstrates how to make dynamic autocomplete menu.";
//
// fctb
//
this.fctb.AutoScrollMinSize = new System.Drawing.Size(0, 75);
this.fctb.BackBrush = null;
this.fctb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fctb.CharHeight = 15;
this.fctb.CharWidth = 7;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DelayedEventsInterval = 500;
this.fctb.DelayedTextChangedInterval = 500;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F);
this.fctb.IsReplaceMode = false;
this.fctb.LeftBracket = '(';
this.fctb.Location = new System.Drawing.Point(0, 26);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(0);
this.fctb.RightBracket = ')';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.Size = new System.Drawing.Size(576, 327);
this.fctb.TabIndex = 3;
this.fctb.Text = "Type some static class name of standard Framework\'s library and dot after it.\r\nFo" +
"r example, type:\r\nConsole.\r\nor\r\nPath.";
this.fctb.WordWrap = true;
this.fctb.Zoom = 100;
//
// AutocompleteSample3
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(576, 353);
this.Controls.Add(this.fctb);
this.Controls.Add(this.label1);
this.Name = "AutocompleteSample3";
this.Text = "AutocompleteSample3";
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private FastColoredTextBoxNS.FastColoredTextBox fctb;
}
}

View File

@@ -0,0 +1,102 @@
using System.Reflection;
using System.Windows.Forms;
using FastColoredTextBoxNS;
using System.Drawing;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Tester
{
public partial class AutocompleteSample3 : Form
{
AutocompleteMenu popupMenu;
public AutocompleteSample3()
{
InitializeComponent();
//create autocomplete popup menu
popupMenu = new AutocompleteMenu(fctb);
popupMenu.ForeColor = Color.White;
popupMenu.BackColor = Color.Gray;
popupMenu.SelectedColor = Color.Purple;
popupMenu.SearchPattern = @"[\w\.]";
popupMenu.AllowTabKey = true;
popupMenu.AlwaysShowTooltip = true;
//assign DynamicCollection as items source
popupMenu.Items.SetAutocompleteItems(new DynamicCollection(popupMenu, fctb));
}
}
/// <summary>
/// Builds list of methods and properties for current class name was typed in the textbox
/// </summary>
internal class DynamicCollection : IEnumerable<AutocompleteItem>
{
private AutocompleteMenu menu;
private FastColoredTextBox tb;
public DynamicCollection(AutocompleteMenu menu, FastColoredTextBox tb)
{
this.menu = menu;
this.tb = tb;
}
public IEnumerator<AutocompleteItem> GetEnumerator()
{
//get current fragment of the text
var text = menu.Fragment.Text;
//extract class name (part before dot)
var parts = text.Split('.');
if (parts.Length < 2)
yield break;
var className = parts[parts.Length - 2];
//find type for given className
var type = FindTypeByName(className);
if (type == null)
yield break;
//return static methods of the class
foreach (var methodName in type.GetMethods().AsEnumerable().Select(mi => mi.Name).Distinct())
yield return new MethodAutocompleteItem(methodName + "()")
{
ToolTipTitle = methodName,
ToolTipText = "Description of method " + methodName + " goes here.",
};
//return static properties of the class
foreach (var pi in type.GetProperties())
yield return new MethodAutocompleteItem(pi.Name)
{
ToolTipTitle = pi.Name,
ToolTipText = "Description of property " + pi.Name + " goes here.",
};
}
Type FindTypeByName(string name)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
Type type = null;
foreach (var a in assemblies)
{
foreach (var t in a.GetTypes())
if (t.Name == name)
{
return t;
}
}
return null;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,94 @@
namespace Tester
{
partial class AutocompleteSample4
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AutocompleteSample4));
this.label1 = new System.Windows.Forms.Label();
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(576, 44);
this.label1.TabIndex = 2;
this.label1.Text = "Sample demonstrates how to make menu like intellisense.\r\nList of namespaces, clas" +
"ses and methods is predefined.";
//
// fctb
//
this.fctb.AutoScrollMinSize = new System.Drawing.Size(0, 240);
this.fctb.BackBrush = null;
this.fctb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fctb.CharHeight = 15;
this.fctb.CharWidth = 7;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DelayedEventsInterval = 500;
this.fctb.DelayedTextChangedInterval = 500;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F);
this.fctb.IsReplaceMode = false;
this.fctb.LeftBracket = '(';
this.fctb.Location = new System.Drawing.Point(0, 44);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(0);
this.fctb.RightBracket = ')';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.Size = new System.Drawing.Size(576, 357);
this.fctb.TabIndex = 3;
this.fctb.Text = resources.GetString("fctb.Text");
this.fctb.WordWrap = true;
this.fctb.Zoom = 100;
//
// AutocompleteSample4
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(576, 401);
this.Controls.Add(this.fctb);
this.Controls.Add(this.label1);
this.Name = "AutocompleteSample4";
this.Text = "AutocompleteSample4";
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private FastColoredTextBoxNS.FastColoredTextBox fctb;
}
}

View File

@@ -0,0 +1,116 @@
using System.Reflection;
using System.Windows.Forms;
using FastColoredTextBoxNS;
using System.Drawing;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Tester
{
public partial class AutocompleteSample4 : Form
{
AutocompleteMenu popupMenu;
static readonly string[] sources = new string[]{
"com",
"com.company",
"com.company.Class1",
"com.company.Class1.Method1",
"com.company.Class1.Method2",
"com.company.Class2",
"com.company.Class3",
"com.example",
"com.example.ClassX",
"com.example.ClassX.Method1",
"com.example.ClassY",
"com.example.ClassY.Method1"
};
public AutocompleteSample4()
{
InitializeComponent();
//create autocomplete popup menu
popupMenu = new AutocompleteMenu(fctb);
popupMenu.SearchPattern = @"[\w\.]";
//
var items = new List<AutocompleteItem>();
foreach (var item in sources)
items.Add(new MethodAutocompleteItem2(item));
popupMenu.Items.SetAutocompleteItems(items);
}
}
/// <summary>
/// This autocomplete item appears after dot
/// </summary>
public class MethodAutocompleteItem2 : MethodAutocompleteItem
{
string firstPart;
string lastPart;
public MethodAutocompleteItem2(string text)
: base(text)
{
var i = text.LastIndexOf('.');
if (i < 0)
firstPart = text;
else
{
firstPart = text.Substring(0, i);
lastPart = text.Substring(i + 1);
}
}
public override CompareResult Compare(string fragmentText)
{
int i = fragmentText.LastIndexOf('.');
if (i < 0)
{
if (firstPart.StartsWith(fragmentText) && string.IsNullOrEmpty(lastPart))
return CompareResult.VisibleAndSelected;
//if (firstPart.ToLower().Contains(fragmentText.ToLower()))
// return CompareResult.Visible;
}
else
{
var fragmentFirstPart = fragmentText.Substring(0, i);
var fragmentLastPart = fragmentText.Substring(i + 1);
if (firstPart != fragmentFirstPart)
return CompareResult.Hidden;
if (lastPart != null && lastPart.StartsWith(fragmentLastPart))
return CompareResult.VisibleAndSelected;
if (lastPart != null && lastPart.ToLower().Contains(fragmentLastPart.ToLower()))
return CompareResult.Visible;
}
return CompareResult.Hidden;
}
public override string GetTextForReplace()
{
if (lastPart == null)
return firstPart;
return firstPart + "." + lastPart;
}
public override string ToString()
{
if (lastPart == null)
return firstPart;
return lastPart;
}
}
}

View File

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="fctb.Text" xml:space="preserve">
<value>Example contains following hierarchy of namespaces, classes and methods:
com
com.company
com.company.Class1
com.company.Class1.Method1
com.company.Class1.Method2
com.company.Class2
com.company.Class3
com.example
com.example.ClassX
com.example.ClassX.Method1
com.example.ClassY
com.example.ClassY.Method1
Start to type 'com'.</value>
</data>
</root>

View File

@@ -0,0 +1,72 @@
namespace Tester
{
partial class BilingualHighlighterSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tb = new FastColoredTextBoxNS.FastColoredTextBox();
((System.ComponentModel.ISupportInitialize)(this.tb)).BeginInit();
this.SuspendLayout();
//
// tb
//
this.tb.AllowDrop = true;
this.tb.AutoScrollMinSize = new System.Drawing.Size(347, 154);
this.tb.BackBrush = null;
this.tb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.tb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.tb.Dock = System.Windows.Forms.DockStyle.Fill;
this.tb.IsReplaceMode = false;
this.tb.Location = new System.Drawing.Point(0, 0);
this.tb.Name = "tb";
this.tb.Paddings = new System.Windows.Forms.Padding(0);
this.tb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.tb.Size = new System.Drawing.Size(355, 321);
this.tb.TabIndex = 0;
this.tb.Text = "<html>\r\n <head></head>\r\n <body>\r\n <ul> \r\n <?php for($i=1;$i<=5;$i++){ ?>\r\n <li>" +
"Menu Item <?php echo $i; ?></li> \r\n <?php } ?>\r\n </ul> \r\n</body>\r\n</html>\r\n";
this.tb.TextChangedDelayed += new System.EventHandler<FastColoredTextBoxNS.TextChangedEventArgs>(this.tb_TextChangedDelayed);
//
// BilingualHighlighterSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(355, 321);
this.Controls.Add(this.tb);
this.Name = "BilingualHighlighterSample";
this.Text = "BilingualHighlighterSample";
((System.ComponentModel.ISupportInitialize)(this.tb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private FastColoredTextBoxNS.FastColoredTextBox tb;
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using FastColoredTextBoxNS;
namespace Tester
{
public partial class BilingualHighlighterSample : Form
{
public BilingualHighlighterSample()
{
InitializeComponent();
}
private void tb_TextChangedDelayed(object sender, TextChangedEventArgs e)
{
var tb = (FastColoredTextBox) sender;
//highlight html
tb.SyntaxHighlighter.InitStyleSchema(Language.HTML);
tb.SyntaxHighlighter.HTMLSyntaxHighlight(tb.Range);
tb.Range.ClearFoldingMarkers();
//find PHP fragments
foreach(var r in tb.GetRanges(@"<\?php.*?\?>", RegexOptions.Singleline))
{
//remove HTML highlighting from this fragment
r.ClearStyle(StyleIndex.All);
//do PHP highlighting
tb.SyntaxHighlighter.InitStyleSchema(Language.PHP);
tb.SyntaxHighlighter.PHPSyntaxHighlight(r);
}
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,151 @@
namespace Tester
{
partial class BookmarksSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BookmarksSample));
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.btAddBookmark = new System.Windows.Forms.ToolStripButton();
this.btRemoveBookmark = new System.Windows.Forms.ToolStripButton();
this.btGo = new System.Windows.Forms.ToolStripDropDownButton();
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
this.label2 = new System.Windows.Forms.Label();
this.toolStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// toolStrip1
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.btAddBookmark,
this.btRemoveBookmark,
this.btGo});
this.toolStrip1.Location = new System.Drawing.Point(0, 38);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.ShowItemToolTips = false;
this.toolStrip1.Size = new System.Drawing.Size(487, 25);
this.toolStrip1.TabIndex = 1;
this.toolStrip1.Text = "toolStrip1";
//
// btAddBookmark
//
this.btAddBookmark.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.btAddBookmark.Image = ((System.Drawing.Image)(resources.GetObject("btAddBookmark.Image")));
this.btAddBookmark.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btAddBookmark.Name = "btAddBookmark";
this.btAddBookmark.Size = new System.Drawing.Size(90, 22);
this.btAddBookmark.Text = "Add bookmark";
this.btAddBookmark.Click += new System.EventHandler(this.btAddBookmark_Click);
//
// btRemoveBookmark
//
this.btRemoveBookmark.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.btRemoveBookmark.Image = ((System.Drawing.Image)(resources.GetObject("btRemoveBookmark.Image")));
this.btRemoveBookmark.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btRemoveBookmark.Name = "btRemoveBookmark";
this.btRemoveBookmark.Size = new System.Drawing.Size(111, 22);
this.btRemoveBookmark.Text = "Remove bookmark";
this.btRemoveBookmark.Click += new System.EventHandler(this.btRemoveBookmark_Click);
//
// btGo
//
this.btGo.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.btGo.Image = ((System.Drawing.Image)(resources.GetObject("btGo.Image")));
this.btGo.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btGo.Name = "btGo";
this.btGo.Size = new System.Drawing.Size(61, 22);
this.btGo.Text = "Go to ...";
this.btGo.DropDownOpening += new System.EventHandler(this.btGo_DropDownOpening);
//
// fctb
//
this.fctb.AutoScrollMinSize = new System.Drawing.Size(0, 4065);
this.fctb.BackBrush = null;
this.fctb.CharHeight = 15;
this.fctb.CharWidth = 7;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DelayedEventsInterval = 500;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.fctb.IsReplaceMode = false;
this.fctb.Language = FastColoredTextBoxNS.Language.CSharp;
this.fctb.LeftBracket = '(';
this.fctb.LeftPadding = 17;
this.fctb.Location = new System.Drawing.Point(0, 63);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(0);
this.fctb.RightBracket = ')';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.Size = new System.Drawing.Size(487, 235);
this.fctb.TabIndex = 0;
this.fctb.Text = resources.GetString("fctb.Text");
this.fctb.WordWrap = true;
this.fctb.Zoom = 100;
this.fctb.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.fctb_MouseDoubleClick);
//
// label2
//
this.label2.Dock = System.Windows.Forms.DockStyle.Top;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label2.Location = new System.Drawing.Point(0, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(487, 38);
this.label2.TabIndex = 3;
this.label2.Text = "This example shows bookmarks. You can use menu or hot keys: Ctrl-B, Ctrl-Shift-B," +
" Ctrl-N";
//
// BookmarksSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(487, 298);
this.Controls.Add(this.fctb);
this.Controls.Add(this.toolStrip1);
this.Controls.Add(this.label2);
this.Name = "BookmarksSample";
this.Text = "Bookmarks Sample";
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private FastColoredTextBoxNS.FastColoredTextBox fctb;
private System.Windows.Forms.ToolStrip toolStrip1;
private System.Windows.Forms.ToolStripButton btAddBookmark;
private System.Windows.Forms.ToolStripButton btRemoveBookmark;
private System.Windows.Forms.ToolStripDropDownButton btGo;
private System.Windows.Forms.Label label2;
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Windows.Forms;
using FastColoredTextBoxNS;
namespace Tester
{
public partial class BookmarksSample : Form
{
public BookmarksSample()
{
InitializeComponent();
}
private void btAddBookmark_Click(object sender, EventArgs e)
{
fctb.Bookmarks.Add(fctb.Selection.Start.iLine);
}
private void btRemoveBookmark_Click(object sender, EventArgs e)
{
fctb.Bookmarks.Remove(fctb.Selection.Start.iLine);
}
private void btGo_DropDownOpening(object sender, EventArgs e)
{
btGo.DropDownItems.Clear();
foreach (var bookmark in fctb.Bookmarks)
{
var item = btGo.DropDownItems.Add(bookmark.Name);
item.Tag = bookmark;
item.Click += (o, a) => ((Bookmark)(o as ToolStripItem).Tag).DoVisible();
}
}
private void fctb_MouseDoubleClick(object sender, MouseEventArgs e)
{
if(e.X < fctb.LeftIndent)
{
var place = fctb.PointToPlace(e.Location);
if(fctb.Bookmarks.Contains(place.iLine))
fctb.Bookmarks.Remove(place.iLine);
else
fctb.Bookmarks.Add(place.iLine);
}
}
}
}

View File

@@ -0,0 +1,426 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>113, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="btAddBookmark.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
</value>
</data>
<data name="btRemoveBookmark.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
</value>
</data>
<data name="btGo.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
</value>
</data>
<data name="fctb.Text" xml:space="preserve">
<value>using System.Collections.Generic;
using System;
using System.Text;
using System.Drawing;
namespace FastColoredTextBoxNS
{
/// &lt;summary&gt;
/// Line of text
/// &lt;/summary&gt;
public class Line : List&lt;Char&gt;
{
List&lt;int&gt; cutOffPositions;
public string FoldingStartMarker { get; set; }
public string FoldingEndMarker { get; set; }
/// &lt;summary&gt;
/// Text of line was changed
/// &lt;/summary&gt;
public bool IsChanged { get; set; }
/// &lt;summary&gt;
/// Time of last visit of caret in this line
/// &lt;/summary&gt;
/// &lt;remarks&gt;This property can be used for forward/backward navigating&lt;/remarks&gt;
public DateTime LastVisit { get; set; }
//Y coordinate of line on screen
internal int startY = -1;
/// &lt;summary&gt;
/// Visible state
/// &lt;/summary&gt;
public VisibleState VisibleState { get; set; }
/// &lt;summary&gt;
/// AutoIndent level for this line
/// &lt;/summary&gt;
public int IndentLevel { get; set; }
/// &lt;summary&gt;
/// Background brush.
/// &lt;/summary&gt;
public Brush BackgroundBrush { get; set;}
/// &lt;summary&gt;
/// User tag
/// &lt;/summary&gt;
public object Tag { get; set; }
/// &lt;summary&gt;
/// Unique ID
/// &lt;/summary&gt;
public int UniqueId { get; private set; }
/// &lt;summary&gt;
/// Count of needed start spaces for AutoIndent
/// &lt;/summary&gt;
public int AutoIndentSpacesNeededCount
{
get;
internal set;
}
internal Line(int uid)
{
this.UniqueId = uid;
}
/// &lt;summary&gt;
/// Clears style of chars, delete folding markers
/// &lt;/summary&gt;
public void ClearStyle(StyleIndex styleIndex)
{
VisibleState = VisibleState.Visible;
FoldingStartMarker = null;
FoldingEndMarker = null;
for (int i = 0; i &lt; Count; i++)
{
Char c = this[i];
c.style &amp;= ~styleIndex;
this[i] = c;
}
}
/// &lt;summary&gt;
/// Text of the line
/// &lt;/summary&gt;
public string Text
{
get{
StringBuilder sb = new StringBuilder(Count);
foreach(Char c in this)
sb.Append(c.c);
return sb.ToString();
}
}
/// &lt;summary&gt;
/// Clears folding markers
/// &lt;/summary&gt;
public void ClearFoldingMarkers()
{
FoldingStartMarker = null;
FoldingEndMarker = null;
}
/// &lt;summary&gt;
/// Positions for wordwrap cutoffs
/// &lt;/summary&gt;
public List&lt;int&gt; CutOffPositions
{
get
{
if (cutOffPositions == null)
cutOffPositions = new List&lt;int&gt;();
return cutOffPositions;
}
}
/// &lt;summary&gt;
/// Count of wordwrap string count for this line
/// &lt;/summary&gt;
public int WordWrapStringsCount
{
get
{
if (VisibleState == VisibleState.Hidden)
return 0;
if (VisibleState == VisibleState.StartOfHiddenBlock)
return 1;
if (cutOffPositions == null)
return 1;
return cutOffPositions.Count + 1;
}
}
internal int GetWordWrapStringStartPosition(int iWordWrapLine)
{
return iWordWrapLine == 0 ? 0 : CutOffPositions[iWordWrapLine - 1];
}
internal int GetWordWrapStringFinishPosition(int iWordWrapLine)
{
if (WordWrapStringsCount &lt;= 0)
return 0;
return iWordWrapLine == WordWrapStringsCount - 1 ? Count - 1 : CutOffPositions[iWordWrapLine] - 1;
}
/// &lt;summary&gt;
/// Gets index of wordwrap string for given char position
/// &lt;/summary&gt;
public int GetWordWrapStringIndex(int iChar)
{
if (cutOffPositions == null || cutOffPositions.Count == 0) return 0;
for (int i = 0; i &lt; cutOffPositions.Count; i++)
if (cutOffPositions[i] &gt;/*&gt;=*/ iChar)
return i;
return cutOffPositions.Count;
}
/// &lt;summary&gt;
/// Calculates wordwrap cutoffs
/// &lt;/summary&gt;
internal void CalcCutOffs(int maxCharsPerLine, bool allowIME, bool charWrap)
{
int segmentLength = 0;
int cutOff = 0;
CutOffPositions.Clear();
for (int i = 0; i &lt; Count; i++)
{
char c = this[i].c;
if (charWrap)
{
//char wrapping
cutOff = Math.Min(i + 1, Count - 1);
}
else
{
//word wrapping
if (allowIME &amp;&amp; isCJKLetter(c))//in CJK languages cutoff can be in any letter
{
cutOff = i;
}
else
if (!char.IsLetterOrDigit(c) &amp;&amp; c != '_')
cutOff = Math.Min(i + 1, Count - 1);
}
segmentLength++;
if (segmentLength == maxCharsPerLine)
{
if (cutOff == 0 || (cutOffPositions.Count &gt; 0 &amp;&amp; cutOff == cutOffPositions[cutOffPositions.Count - 1]))
cutOff = i + 1;
CutOffPositions.Add(cutOff);
segmentLength = 1 + i - cutOff;
}
}
}
private bool isCJKLetter(char c)
{
int code = Convert.ToInt32(c);
return
(code &gt;= 0x3300 &amp;&amp; code &lt;= 0x33FF) ||
(code &gt;= 0xFE30 &amp;&amp; code &lt;= 0xFE4F) ||
(code &gt;= 0xF900 &amp;&amp; code &lt;= 0xFAFF) ||
(code &gt;= 0x2E80 &amp;&amp; code &lt;= 0x2EFF) ||
(code &gt;= 0x31C0 &amp;&amp; code &lt;= 0x31EF) ||
(code &gt;= 0x4E00 &amp;&amp; code &lt;= 0x9FFF) ||
(code &gt;= 0x3400 &amp;&amp; code &lt;= 0x4DBF) ||
(code &gt;= 0x3200 &amp;&amp; code &lt;= 0x32FF) ||
(code &gt;= 0x2460 &amp;&amp; code &lt;= 0x24FF) ||
(code &gt;= 0x3040 &amp;&amp; code &lt;= 0x309F) ||
(code &gt;= 0x2F00 &amp;&amp; code &lt;= 0x2FDF) ||
(code &gt;= 0x31A0 &amp;&amp; code &lt;= 0x31BF) ||
(code &gt;= 0x4DC0 &amp;&amp; code &lt;= 0x4DFF) ||
(code &gt;= 0x3100 &amp;&amp; code &lt;= 0x312F) ||
(code &gt;= 0x30A0 &amp;&amp; code &lt;= 0x30FF) ||
(code &gt;= 0x31F0 &amp;&amp; code &lt;= 0x31FF) ||
(code &gt;= 0x2FF0 &amp;&amp; code &lt;= 0x2FFF) ||
(code &gt;= 0x1100 &amp;&amp; code &lt;= 0x11FF) ||
(code &gt;= 0xA960 &amp;&amp; code &lt;= 0xA97F) ||
(code &gt;= 0xD7B0 &amp;&amp; code &lt;= 0xD7FF) ||
(code &gt;= 0x3130 &amp;&amp; code &lt;= 0x318F) ||
(code &gt;= 0xAC00 &amp;&amp; code &lt;= 0xD7AF);
}
/// &lt;summary&gt;
/// Count of start spaces
/// &lt;/summary&gt;
public int StartSpacesCount
{
get
{
int spacesCount = 0;
for (int i = 0; i &lt; Count; i++)
if (this[i].c == ' ')
spacesCount++;
else
break;
return spacesCount;
}
}
}
public enum VisibleState
{
Visible, StartOfHiddenBlock, Hidden
}
public enum IndentMarker
{
None,
Increased,
Decreased
}
}
</value>
</data>
</root>

View File

@@ -0,0 +1,113 @@
namespace Tester
{
partial class ConsoleSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConsoleSample));
this.label2 = new System.Windows.Forms.Label();
this.consoleTextBox1 = new Tester.ConsoleTextBox();
((System.ComponentModel.ISupportInitialize)(this.consoleTextBox1)).BeginInit();
this.SuspendLayout();
//
// label2
//
this.label2.Dock = System.Windows.Forms.DockStyle.Top;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label2.Location = new System.Drawing.Point(0, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(737, 38);
this.label2.TabIndex = 2;
this.label2.Text = resources.GetString("label2.Text");
//
// consoleTextBox1
//
this.consoleTextBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.consoleTextBox1.AutoCompleteBracketsList = new char[] {
'(',
')',
'{',
'}',
'[',
']',
'\"',
'\"',
'\'',
'\''};
this.consoleTextBox1.AutoScrollMinSize = new System.Drawing.Size(585, 15);
this.consoleTextBox1.BackBrush = null;
this.consoleTextBox1.BackColor = System.Drawing.Color.Black;
this.consoleTextBox1.CaretColor = System.Drawing.Color.White;
this.consoleTextBox1.CharHeight = 15;
this.consoleTextBox1.CharWidth = 7;
this.consoleTextBox1.Cursor = System.Windows.Forms.Cursors.IBeam;
this.consoleTextBox1.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.consoleTextBox1.FoldingIndicatorColor = System.Drawing.Color.Gold;
this.consoleTextBox1.Font = new System.Drawing.Font("Consolas", 9.75F);
this.consoleTextBox1.ForeColor = System.Drawing.Color.White;
this.consoleTextBox1.IndentBackColor = System.Drawing.Color.Black;
this.consoleTextBox1.IsReadLineMode = false;
this.consoleTextBox1.IsReplaceMode = false;
this.consoleTextBox1.LineNumberColor = System.Drawing.Color.Gold;
this.consoleTextBox1.Location = new System.Drawing.Point(12, 41);
this.consoleTextBox1.Name = "consoleTextBox1";
this.consoleTextBox1.PaddingBackColor = System.Drawing.Color.Black;
this.consoleTextBox1.Paddings = new System.Windows.Forms.Padding(0);
this.consoleTextBox1.PreferredLineWidth = 80;
this.consoleTextBox1.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(150)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
this.consoleTextBox1.ServiceColors = ((FastColoredTextBoxNS.ServiceColors)(resources.GetObject("consoleTextBox1.ServiceColors")));
this.consoleTextBox1.ServiceLinesColor = System.Drawing.Color.DimGray;
this.consoleTextBox1.Size = new System.Drawing.Size(713, 342);
this.consoleTextBox1.TabIndex = 0;
this.consoleTextBox1.WordWrap = true;
this.consoleTextBox1.WordWrapMode = FastColoredTextBoxNS.WordWrapMode.CharWrapPreferredWidth;
this.consoleTextBox1.Zoom = 100;
//
// ConsoleSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(737, 395);
this.Controls.Add(this.label2);
this.Controls.Add(this.consoleTextBox1);
this.Name = "ConsoleSample";
this.Text = "ConsoleSample";
((System.ComponentModel.ISupportInitialize)(this.consoleTextBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private ConsoleTextBox consoleTextBox1;
private System.Windows.Forms.Label label2;
}
}

View File

@@ -0,0 +1,158 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using FastColoredTextBoxNS;
namespace Tester
{
public partial class ConsoleSample : Form
{
private bool stop;
public ConsoleSample()
{
InitializeComponent();
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
string text = "";
stop = false;
do
{
consoleTextBox1.WriteLine("Enter some line: ");
text = consoleTextBox1.ReadLine();
} while (text != "" && !stop);
consoleTextBox1.WriteLine("End of enetering.");
}
protected override void OnClosing(CancelEventArgs e)
{
Stop();
base.OnClosing(e);
}
void Stop()
{
stop = true;
consoleTextBox1.IsReadLineMode = false;
}
}
/// <summary>
/// Console emulator.
/// </summary>
public class ConsoleTextBox : FastColoredTextBox
{
private volatile bool isReadLineMode;
private volatile bool isUpdating;
private Place StartReadPlace { get; set; }
/// <summary>
/// Control is waiting for line entering.
/// </summary>
public bool IsReadLineMode
{
get { return isReadLineMode; }
set { isReadLineMode = value; }
}
/// <summary>
/// Append line to end of text.
/// </summary>
/// <param name="text"></param>
public void WriteLine(string text)
{
IsReadLineMode = false;
isUpdating = true;
try
{
AppendText(text);
GoEnd();
}
finally
{
isUpdating = false;
ClearUndo();
}
}
/// <summary>
/// Wait for line entering.
/// Set IsReadLineMode to false for break of waiting.
/// </summary>
/// <returns></returns>
public string ReadLine()
{
GoEnd();
StartReadPlace = Range.End;
IsReadLineMode = true;
try
{
while (IsReadLineMode)
{
Application.DoEvents();
Thread.Sleep(5);
}
}
finally
{
IsReadLineMode = false;
ClearUndo();
}
return new Range(this, StartReadPlace, Range.End).Text.TrimEnd('\r', '\n');
}
public override void OnTextChanging(ref string text)
{
if (!IsReadLineMode && !isUpdating)
{
text = ""; //cancel changing
return;
}
if (IsReadLineMode)
{
if (Selection.Start < StartReadPlace || Selection.End < StartReadPlace)
GoEnd();//move caret to entering position
if (Selection.Start == StartReadPlace || Selection.End == StartReadPlace)
if (text == "\b") //backspace
{
text = ""; //cancel deleting of last char of readonly text
return;
}
if (text != null && text.Contains('\n'))
{
text = text.Substring(0, text.IndexOf('\n') + 1);
IsReadLineMode = false;
}
}
base.OnTextChanging(ref text);
}
public override void Clear()
{
var oldIsReadMode = isReadLineMode;
isReadLineMode = false;
isUpdating = true;
base.Clear();
isUpdating = false;
isReadLineMode = oldIsReadMode;
StartReadPlace = Place.Empty;
}
}
}

View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="label2.Text" xml:space="preserve">
<value>This example demonstrates console emulator. Class ConsoleTextBox contains methods WriteLine() and ReadLine().
User can enter text only if ReadLine() is calling. Also, user can not change text, written by WriteLine() method.
</value>
</data>
<data name="consoleTextBox1.ServiceColors" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFZGYXN0Q29sb3JlZFRleHRCb3gsIFZlcnNpb249Mi4xNi4yLjAs
IEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49ZmI4YWExMmI5OTRlZjYxYgwDAAAAUVN5c3Rl
bS5EcmF3aW5nLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49
YjAzZjVmN2YxMWQ1MGEzYQUBAAAAIkZhc3RDb2xvcmVkVGV4dEJveE5TLlNlcnZpY2VDb2xvcnMGAAAA
KDxDb2xsYXBzZU1hcmtlckZvcmVDb2xvcj5rX19CYWNraW5nRmllbGQoPENvbGxhcHNlTWFya2VyQmFj
a0NvbG9yPmtfX0JhY2tpbmdGaWVsZCo8Q29sbGFwc2VNYXJrZXJCb3JkZXJDb2xvcj5rX19CYWNraW5n
RmllbGQmPEV4cGFuZE1hcmtlckZvcmVDb2xvcj5rX19CYWNraW5nRmllbGQmPEV4cGFuZE1hcmtlckJh
Y2tDb2xvcj5rX19CYWNraW5nRmllbGQoPEV4cGFuZE1hcmtlckJvcmRlckNvbG9yPmtfX0JhY2tpbmdG
aWVsZAQEBAQEBBRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAA
FFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAAABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRy
YXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAAAAIAAAAF/P///xRTeXN0ZW0uRHJh
d2luZy5Db2xvcgQAAAAEbmFtZQV2YWx1ZQprbm93bkNvbG9yBXN0YXRlAQAAAAkHBwMAAAAKAAAAAAAA
AACWAAEAAfv////8////CgAAAAAAAAAApAABAAH6/////P///woAAAAAAAAAAJYAAQAB+f////z///8K
AAAAAAAAAACNAAEAAfj////8////CgAAAAAAAAAApAABAAH3/////P///woAAAAAAAAAAJYAAQAL
</value>
</data>
</root>

View File

@@ -0,0 +1,94 @@
namespace Tester
{
partial class CustomFoldingSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomFoldingSample));
this.label1 = new System.Windows.Forms.Label();
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(467, 45);
this.label1.TabIndex = 2;
this.label1.Text = "This example shows how to make custom code folding.\r\nExample creates folding for " +
"Python.";
//
// fctb
//
this.fctb.AutoIndentExistingLines = false;
this.fctb.AutoScrollMinSize = new System.Drawing.Size(501, 315);
this.fctb.BackBrush = null;
this.fctb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fctb.CharHeight = 15;
this.fctb.CharWidth = 7;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F);
this.fctb.IsReplaceMode = false;
this.fctb.Location = new System.Drawing.Point(0, 45);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(0);
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.ServiceLinesColor = System.Drawing.Color.Gray;
this.fctb.ShowFoldingLines = true;
this.fctb.Size = new System.Drawing.Size(467, 358);
this.fctb.TabIndex = 3;
this.fctb.Text = resources.GetString("fctb.Text");
this.fctb.Zoom = 100;
this.fctb.TextChangedDelayed += new System.EventHandler<FastColoredTextBoxNS.TextChangedEventArgs>(this.fctb_TextChangedDelayed);
this.fctb.AutoIndentNeeded += new System.EventHandler<FastColoredTextBoxNS.AutoIndentEventArgs>(this.fctb_AutoIndentNeeded);
//
// CustomFoldingSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(467, 403);
this.Controls.Add(this.fctb);
this.Controls.Add(this.label1);
this.Name = "CustomFoldingSample";
this.Text = "CustomCodeFolding Sample";
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private FastColoredTextBoxNS.FastColoredTextBox fctb;
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Windows.Forms;
using FastColoredTextBoxNS;
using System.Text.RegularExpressions;
namespace Tester
{
public partial class CustomFoldingSample : Form
{
public CustomFoldingSample()
{
InitializeComponent();
fctb.OnTextChangedDelayed(fctb.Range);
}
private void fctb_TextChangedDelayed(object sender, TextChangedEventArgs e)
{
//delete all markers
fctb.Range.ClearFoldingMarkers();
var currentIndent = 0;
var lastNonEmptyLine = 0;
for (int i = 0; i < fctb.LinesCount; i++)
{
var line = fctb[i];
var spacesCount = line.StartSpacesCount;
if (spacesCount == line.Count) //empty line
continue;
if (currentIndent < spacesCount)
//append start folding marker
fctb[lastNonEmptyLine].FoldingStartMarker = "m" + currentIndent;
else
if (currentIndent > spacesCount)
//append end folding marker
fctb[lastNonEmptyLine].FoldingEndMarker = "m" + spacesCount;
currentIndent = spacesCount;
lastNonEmptyLine = i;
}
}
private void fctb_AutoIndentNeeded(object sender, AutoIndentEventArgs e)
{
//we assign this handler to disable AutoIndent by folding
}
}
}

View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="fctb.Text" xml:space="preserve">
<value>
class Evaluator:
def __init__(self):
self.myNameSpace = {}
self.runpython(""from math import *"")
def doEnter(self, *args):
result = self.calc.runpython(self.current)
if result:
self.display.insert(END, '\n')
self.display.insert(END, '%s\n' % result, 'ans')
self.current = """"
def runpython(self, code):
try:
return 'eval(code, self.myNameSpace, self.myNameSpace)'
except SyntaxError:
return 'Error'
Calculator().mainloop()
</value>
</data>
</root>

View File

@@ -0,0 +1,84 @@
namespace Tester
{
partial class CustomHint
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(2, 20);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 49);
this.textBox1.TabIndex = 6;
//
// linkLabel1
//
this.linkLabel1.AutoSize = true;
this.linkLabel1.Location = new System.Drawing.Point(0, 4);
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new System.Drawing.Size(62, 13);
this.linkLabel1.TabIndex = 5;
this.linkLabel1.TabStop = true;
this.linkLabel1.Text = "Custom hint";
//
// button1
//
this.button1.Location = new System.Drawing.Point(109, 18);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(101, 23);
this.button1.TabIndex = 4;
this.button1.Text = "Do something";
this.button1.UseVisualStyleBackColor = true;
//
// CustomHint
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Controls.Add(this.textBox1);
this.Controls.Add(this.linkLabel1);
this.Controls.Add(this.button1);
this.Name = "CustomHint";
this.Size = new System.Drawing.Size(219, 73);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.LinkLabel linkLabel1;
private System.Windows.Forms.Button button1;
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Tester
{
public partial class CustomHint : UserControl
{
public CustomHint()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,183 @@
namespace Tester
{
partial class CustomScrollBarsSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomScrollBarsSample));
this.label2 = new System.Windows.Forms.Label();
this.vScrollBar = new System.Windows.Forms.VScrollBar();
this.hScrollBar = new System.Windows.Forms.HScrollBar();
this.hMyScrollBar = new Tester.MyScrollBar();
this.vMyScrollBar = new Tester.MyScrollBar();
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// label2
//
this.label2.Dock = System.Windows.Forms.DockStyle.Top;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label2.Location = new System.Drawing.Point(0, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(461, 38);
this.label2.TabIndex = 2;
this.label2.Text = "Here we create custom outside scrollbars for FCTB.";
//
// vScrollBar
//
this.vScrollBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Right)));
this.vScrollBar.Location = new System.Drawing.Point(359, 62);
this.vScrollBar.Name = "vScrollBar";
this.vScrollBar.Size = new System.Drawing.Size(17, 181);
this.vScrollBar.TabIndex = 8;
this.vScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(this.ScrollBar_Scroll);
//
// hScrollBar
//
this.hScrollBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.hScrollBar.Location = new System.Drawing.Point(41, 330);
this.hScrollBar.Name = "hScrollBar";
this.hScrollBar.Size = new System.Drawing.Size(227, 17);
this.hScrollBar.TabIndex = 9;
this.hScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(this.ScrollBar_Scroll);
//
// hMyScrollBar
//
this.hMyScrollBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.hMyScrollBar.BackColor = System.Drawing.Color.Gold;
this.hMyScrollBar.BorderColor = System.Drawing.Color.Gray;
this.hMyScrollBar.Location = new System.Drawing.Point(41, 280);
this.hMyScrollBar.Maximum = 100;
this.hMyScrollBar.Name = "hMyScrollBar";
this.hMyScrollBar.Orientation = System.Windows.Forms.ScrollOrientation.HorizontalScroll;
this.hMyScrollBar.Size = new System.Drawing.Size(227, 14);
this.hMyScrollBar.TabIndex = 7;
this.hMyScrollBar.Text = "myScrollBar2";
this.hMyScrollBar.ThumbColor = System.Drawing.Color.Red;
this.hMyScrollBar.ThumbSize = 10;
this.hMyScrollBar.Value = 0;
this.hMyScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(this.ScrollBar_Scroll);
//
// vMyScrollBar
//
this.vMyScrollBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Right)));
this.vMyScrollBar.BackColor = System.Drawing.Color.Gold;
this.vMyScrollBar.BorderColor = System.Drawing.Color.Gray;
this.vMyScrollBar.Location = new System.Drawing.Point(314, 62);
this.vMyScrollBar.Maximum = 100;
this.vMyScrollBar.Name = "vMyScrollBar";
this.vMyScrollBar.Orientation = System.Windows.Forms.ScrollOrientation.VerticalScroll;
this.vMyScrollBar.Size = new System.Drawing.Size(14, 179);
this.vMyScrollBar.TabIndex = 6;
this.vMyScrollBar.Text = "myScrollBar1";
this.vMyScrollBar.ThumbColor = System.Drawing.Color.Red;
this.vMyScrollBar.ThumbSize = 10;
this.vMyScrollBar.Value = 0;
this.vMyScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(this.ScrollBar_Scroll);
//
// fctb
//
this.fctb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.fctb.AutoCompleteBracketsList = new char[] {
'(',
')',
'{',
'}',
'[',
']',
'\"',
'\"',
'\'',
'\''};
this.fctb.AutoIndentCharsPatterns = "^\\s*[\\w\\.]+(\\s\\w+)?\\s*(?<range>=)\\s*(?<range>[^;=]+);\r\n^\\s*(case|default)\\s*[^:]*(?<range>:)\\s*(?<range>[^;]+);";
this.fctb.AutoScrollMinSize = new System.Drawing.Size(284, 315);
this.fctb.BackBrush = null;
this.fctb.BackColor = System.Drawing.Color.Gold;
this.fctb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fctb.BracketsHighlightStrategy = FastColoredTextBoxNS.BracketsHighlightStrategy.Strategy2;
this.fctb.CharHeight = 15;
this.fctb.CharWidth = 7;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F);
this.fctb.IndentBackColor = System.Drawing.Color.Orange;
this.fctb.IsReplaceMode = false;
this.fctb.Language = FastColoredTextBoxNS.Language.CSharp;
this.fctb.LeftBracket = '(';
this.fctb.LeftBracket2 = '{';
this.fctb.Location = new System.Drawing.Point(41, 62);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(0);
this.fctb.RightBracket = ')';
this.fctb.RightBracket2 = '}';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.ServiceColors = ((FastColoredTextBoxNS.ServiceColors)(resources.GetObject("fctb.ServiceColors")));
this.fctb.ServiceLinesColor = System.Drawing.Color.DarkGray;
this.fctb.ShowScrollBars = false;
this.fctb.Size = new System.Drawing.Size(227, 179);
this.fctb.TabIndex = 3;
this.fctb.Text = resources.GetString("fctb.Text");
this.fctb.Zoom = 100;
this.fctb.ScrollbarsUpdated += new System.EventHandler(this.fctb_ScrollbarsUpdated);
//
// CustomScrollBarsSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(461, 403);
this.Controls.Add(this.hScrollBar);
this.Controls.Add(this.vScrollBar);
this.Controls.Add(this.hMyScrollBar);
this.Controls.Add(this.vMyScrollBar);
this.Controls.Add(this.fctb);
this.Controls.Add(this.label2);
this.Name = "CustomScrollBarsSample";
this.Text = "CustomScrollBarsSample";
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label2;
private FastColoredTextBoxNS.FastColoredTextBox fctb;
private MyScrollBar vMyScrollBar;
private MyScrollBar hMyScrollBar;
private System.Windows.Forms.VScrollBar vScrollBar;
private System.Windows.Forms.HScrollBar hScrollBar;
}
}

View File

@@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using FastColoredTextBoxNS;
namespace Tester
{
public partial class CustomScrollBarsSample : Form
{
public CustomScrollBarsSample()
{
InitializeComponent();
}
private void AdjustScrollbars()
{
AdjustScrollbar(vMyScrollBar, fctb.VerticalScroll.Maximum, fctb.VerticalScroll.Value, fctb.ClientSize.Height);
AdjustScrollbar(hMyScrollBar, fctb.HorizontalScroll.Maximum, fctb.HorizontalScroll.Value, fctb.ClientSize.Width);
AdjustScrollbar(vScrollBar, fctb.VerticalScroll.Maximum, fctb.VerticalScroll.Value, fctb.ClientSize.Height);
AdjustScrollbar(hScrollBar, fctb.HorizontalScroll.Maximum, fctb.HorizontalScroll.Value, fctb.ClientSize.Width);
}
/// <summary>
/// This method for MyScrollBar
/// </summary>
private void AdjustScrollbar(MyScrollBar scrollBar, int max, int value, int clientSize)
{
scrollBar.Maximum = max;
scrollBar.Visible = max > 0;
scrollBar.Value = Math.Min(scrollBar.Maximum, value);
}
/// <summary>
/// This method for System.Windows.Forms.ScrollBar and inherited classes
/// </summary>
private void AdjustScrollbar(ScrollBar scrollBar, int max, int value, int clientSize)
{
scrollBar.LargeChange = clientSize / 3;
scrollBar.SmallChange = clientSize / 11;
scrollBar.Maximum = max + scrollBar.LargeChange;
scrollBar.Visible = max > 0;
scrollBar.Value = Math.Min(scrollBar.Maximum, value);
}
private void fctb_ScrollbarsUpdated(object sender, EventArgs e)
{
AdjustScrollbars();
}
private void ScrollBar_Scroll(object sender, ScrollEventArgs e)
{
fctb.OnScroll(e, e.Type != ScrollEventType.ThumbTrack && e.Type != ScrollEventType.ThumbPosition);
}
}
#region MyScrollBar
public class MyScrollBar: Control
{
private int @value;
public int Value
{
get { return value; }
set {
if (this.value == value)
return;
this.value = value;
Invalidate();
OnScroll();
}
}
private int maximum = 100;
public int Maximum
{
get { return maximum; }
set { maximum = value; Invalidate(); }
}
private int thumbSize = 10;
public int ThumbSize
{
get { return thumbSize; }
set { thumbSize = value; Invalidate(); }
}
private Color thumbColor = Color.Gray;
public Color ThumbColor
{
get { return thumbColor; }
set { thumbColor = value; Invalidate(); }
}
private Color borderColor = Color.Silver;
public Color BorderColor
{
get { return borderColor; }
set { borderColor = value; Invalidate(); }
}
private ScrollOrientation orientation;
public ScrollOrientation Orientation
{
get { return orientation; }
set { orientation = value; Invalidate(); }
}
public event ScrollEventHandler Scroll;
public MyScrollBar()
{
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
MouseScroll(e);
base.OnMouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
MouseScroll(e);
base.OnMouseMove(e);
}
/*
protected override void OnMouseUp(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
OnScroll(ScrollEventType.EndScroll);
base.OnMouseUp(e);
}*/
private void MouseScroll(MouseEventArgs e)
{
int v = 0;
switch(Orientation)
{
case ScrollOrientation.VerticalScroll: v = Maximum * (e.Y - thumbSize / 2) / (Height - thumbSize); break;
case ScrollOrientation.HorizontalScroll: v = Maximum * (e.X - thumbSize / 2) / (Width - thumbSize); break;
}
Value = Math.Max(0, Math.Min(Maximum, v));
}
public virtual void OnScroll(ScrollEventType type = ScrollEventType.ThumbPosition)
{
if (Scroll != null)
Scroll(this, new ScrollEventArgs(type, Value, Orientation));
}
protected override void OnPaint(PaintEventArgs e)
{
if (Maximum <= 0)
return;
Rectangle thumbRect = Rectangle.Empty;
switch(Orientation)
{
case ScrollOrientation.HorizontalScroll:
thumbRect = new Rectangle(value * (Width - thumbSize) / Maximum, 2, thumbSize, Height - 4);
break;
case ScrollOrientation.VerticalScroll:
thumbRect = new Rectangle(2, value * (Height - thumbSize) / Maximum, Width - 4, thumbSize);
break;
}
using(var brush = new SolidBrush(thumbColor))
e.Graphics.FillRectangle(brush, thumbRect);
using (var pen = new Pen(borderColor))
e.Graphics.DrawRectangle(pen, new Rectangle(0, 0, Width - 1, Height - 1));
}
}
#endregion
}

View File

@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="fctb.ServiceColors" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdGYXN0Q29sb3JlZFRleHRCb3gsIFZlcnNpb249Mi4xNi4yMS4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWZiOGFhMTJiOTk0ZWY2MWIMAwAAAFFTeXN0
ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2Vu
PWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACJGYXN0Q29sb3JlZFRleHRCb3hOUy5TZXJ2aWNlQ29sb3JzBgAA
ACg8Q29sbGFwc2VNYXJrZXJGb3JlQ29sb3I+a19fQmFja2luZ0ZpZWxkKDxDb2xsYXBzZU1hcmtlckJh
Y2tDb2xvcj5rX19CYWNraW5nRmllbGQqPENvbGxhcHNlTWFya2VyQm9yZGVyQ29sb3I+a19fQmFja2lu
Z0ZpZWxkJjxFeHBhbmRNYXJrZXJGb3JlQ29sb3I+a19fQmFja2luZ0ZpZWxkJjxFeHBhbmRNYXJrZXJC
YWNrQ29sb3I+a19fQmFja2luZ0ZpZWxkKDxFeHBhbmRNYXJrZXJCb3JkZXJDb2xvcj5rX19CYWNraW5n
RmllbGQEBAQEBAQUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAA
ABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5E
cmF3aW5nLkNvbG9yAwAAABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAACAAAABfz///8UU3lzdGVtLkRy
YXdpbmcuQ29sb3IEAAAABG5hbWUFdmFsdWUKa25vd25Db2xvcgVzdGF0ZQEAAAAJBwcDAAAACgAAAAAA
AAAAlgABAAH7/////P///woAAAAAAAAAAKQAAQAB+v////z///8KAAAAAAAAAACWAAEAAfn////8////
CgAAAAAAAAAAjQABAAH4/////P///woAAAAAAAAAAKQAAQAB9/////z///8KAAAAAAAAAACWAAEACw==
</value>
</data>
<data name="fctb.Text" xml:space="preserve">
<value>
#region Char
/// &lt;summary&gt;
/// Char and style
/// &lt;/summary&gt;
struct Char
{
public char c;
public StyleIndex style;
public Char(char c)
{
this.c = c;
style = StyleIndex.None;
}
}
#endregion</value>
</data>
</root>

View File

@@ -0,0 +1,97 @@
namespace Tester
{
partial class CustomStyleSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomStyleSample));
this.label1 = new System.Windows.Forms.Label();
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.BackColor = System.Drawing.Color.WhiteSmoke;
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(600, 39);
this.label1.TabIndex = 1;
this.label1.Text = "This example shows how to create own custom style.";
//
// fctb
//
this.fctb.AutoIndent = false;
this.fctb.AutoScrollMinSize = new System.Drawing.Size(595, 180);
this.fctb.BackBrush = null;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F);
this.fctb.IsReplaceMode = false;
this.fctb.LeftBracket = '(';
this.fctb.LeftPadding = 3;
this.fctb.Location = new System.Drawing.Point(0, 39);
this.fctb.Name = "fctb";
this.fctb.PaddingBackColor = System.Drawing.Color.WhiteSmoke;
this.fctb.Paddings = new System.Windows.Forms.Padding(15);
this.fctb.PreferredLineWidth = 80;
this.fctb.RightBracket = ')';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.ShowLineNumbers = false;
this.fctb.Size = new System.Drawing.Size(600, 266);
this.fctb.TabIndex = 2;
this.fctb.Text = resources.GetString("fctb.Text");
this.fctb.TextAreaBorder = FastColoredTextBoxNS.TextAreaBorderType.Shadow;
this.fctb.WordWrap = true;
this.fctb.WordWrapMode = FastColoredTextBoxNS.WordWrapMode.WordWrapPreferredWidth;
this.fctb.TextChanged += new System.EventHandler<FastColoredTextBoxNS.TextChangedEventArgs>(this.fctb_TextChanged);
//
// CustomStyleSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(600, 305);
this.Controls.Add(this.fctb);
this.Controls.Add(this.label1);
this.Name = "CustomStyleSample";
this.Text = "Custom style sample";
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private FastColoredTextBoxNS.FastColoredTextBox fctb;
}
}

View File

@@ -0,0 +1,46 @@
using System.Drawing;
using System.Windows.Forms;
using FastColoredTextBoxNS;
using System.Text.RegularExpressions;
namespace Tester
{
public partial class CustomStyleSample : Form
{
//create my custom style
EllipseStyle ellipseStyle = new EllipseStyle();
public CustomStyleSample()
{
InitializeComponent();
}
private void fctb_TextChanged(object sender, TextChangedEventArgs e)
{
//clear old styles of chars
e.ChangedRange.ClearStyle(ellipseStyle);
//append style for word 'Babylon'
e.ChangedRange.SetStyle(ellipseStyle, @"\bBabylon\b", RegexOptions.IgnoreCase);
}
}
/// <summary>
/// This style will drawing ellipse around of the word
/// </summary>
class EllipseStyle : Style
{
public override void Draw(Graphics gr, Point position, Range range)
{
//get size of rectangle
Size size = GetSizeOfRange(range);
//create rectangle
Rectangle rect = new Rectangle(position, size);
//inflate it
rect.Inflate(2, 2);
//get rounded rectangle
var path = GetRoundedRectangle(rect, 7);
//draw rounded rectangle
gr.DrawPath(Pens.Red, path);
}
}
}

View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="fctb.Text" xml:space="preserve">
<value>
Available historical resources suggest that Babylon was at first a small town which had sprung up by the beginning of the 3rd millennium BC. The town flourished and attained prominence and political repute with the rise of the First Babylonian Dynasty. Claiming to be the successor of the ancient Eridu, Babylon eclipsed Nippur as the \"holy city\" of Mesopotamia around the time Hammurabi first unified the Babylonian Empire, and again became the seat of the Neo-Babylonian Empire from 612 to 539 BC. The Hanging Gardens of Babylon were one of the Seven Wonders of the Ancient World.
</value>
</data>
</root>

View File

@@ -0,0 +1,93 @@
namespace Tester
{
partial class CustomTextSourceSample
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomTextSourceSample));
this.fctb = new FastColoredTextBoxNS.FastColoredTextBox();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.fctb)).BeginInit();
this.SuspendLayout();
//
// fctb
//
this.fctb.AutoIndent = false;
this.fctb.AutoScrollMinSize = new System.Drawing.Size(0, 17);
this.fctb.BackBrush = null;
this.fctb.CharHeight = 15;
this.fctb.CharWidth = 7;
this.fctb.Cursor = System.Windows.Forms.Cursors.IBeam;
this.fctb.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.fctb.Dock = System.Windows.Forms.DockStyle.Fill;
this.fctb.Font = new System.Drawing.Font("Consolas", 9.75F);
this.fctb.IsReplaceMode = false;
this.fctb.LeftBracket = '(';
this.fctb.Location = new System.Drawing.Point(0, 56);
this.fctb.Name = "fctb";
this.fctb.Paddings = new System.Windows.Forms.Padding(1);
this.fctb.ReadOnly = true;
this.fctb.RightBracket = ')';
this.fctb.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.fctb.Size = new System.Drawing.Size(569, 266);
this.fctb.TabIndex = 0;
this.fctb.WordWrap = true;
this.fctb.Zoom = 100;
this.fctb.VisibleRangeChanged += new System.EventHandler(this.fctb_VisibleRangeChanged);
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Top;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(569, 56);
this.label1.TabIndex = 2;
this.label1.Text = resources.GetString("label1.Text");
//
// CustomTextSourceSample
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(569, 322);
this.Controls.Add(this.fctb);
this.Controls.Add(this.label1);
this.Name = "CustomTextSourceSample";
this.Text = "CustomTextSourceSample";
this.Shown += new System.EventHandler(this.CustomTextSourceSample_Shown);
((System.ComponentModel.ISupportInitialize)(this.fctb)).EndInit();
this.ResumeLayout(false);
}
#endregion
private FastColoredTextBoxNS.FastColoredTextBox fctb;
private System.Windows.Forms.Label label1;
}
}

Some files were not shown because too many files have changed in this diff Show More