📄 textareacontrol.cs
字号:
// TextAreaControl.cs
// Copyright (C) 2000 Mike Krueger
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Collections;
using System.IO;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.Remoting;
using System.Runtime.InteropServices;
using System.Xml;
using SharpDevelop.Internal.Templates;
using SharpDevelop.Tool.Data;
using SharpDevelop.Internal.Text;
using SharpDevelop.Internal.Undo;
using SharpDevelop.Actions;
using SharpDevelop.Actions.Edit;
using SharpDevelop.Gui.Window;
namespace SharpDevelop.Gui.Edit.Text {
/// <summary>
/// This class puts all textarea components together and makes a nice control
/// out of it.
/// </summary>
public class TextAreaControl : UserControl, ISdEditable, ISdEditActionExecutor
{
Ruler ruler = null;
Panel rowpanel = new Panel();
Panel textareapanel = new Panel();
Panel linenumberpanel = new Panel();
VScrollBar vscrollbar = new VScrollBar();
HScrollBar hscrollbar = new HScrollBar();
Panel mainpanel = new Panel();
MainWindow mainwindow = null;
public bool ClearSelectionMove = true;
TextAreaMouseHandler mouseeventhandler = null;
TextAreaPainter textarea;
LineNumberView lineview = null;
SharpTextAreaClipboardHandler clipboardhandler = null;
public bool hidden = false; // mouse cursor hidden ?
// Thread errorfindthread;
Thread caretthread;
public int lastVisibleChar;
public int lastVisibleLine;
public ErrorDrawer ErrorDrawer;
public event EventHandler Changed;
public event EventHandler FileTransaction;
public event ProgressEventHandler FileTransactionProgress;
public event EventHandler FileTransactionComplete;
public TextAreaControl TextArea { // implement ISdEditActionExecutor interface member.
get {
return this;
}
}
public PrintDocument PrintDocument {
get { // TODO
return textarea.PrintDocument;
}
}
public ISdClipboardHandable ClipboardHandler {
get {
return clipboardhandler;
}
}
public UndoStack UndoStack {
get {
return textarea.Buffer.UndoStack;
}
}
public bool WriteProtected {
get {
return textarea.Buffer.ReadOnly;
}
set {
textarea.Buffer.ReadOnly = value;
}
}
public Selection Selection {
get {
return textarea.Selection;
}
}
public Caret Caret {
get {
return textarea.Caret;
}
}
public TextBuffer Buffer {
get {
return textarea.Buffer;
}
}
public BufferOptions Options {
get {
return textarea.Options;
}
}
public void LoadFile(string filename)
{
OnFileTransaction("Load");
ProgressEventHandler peh = new ProgressEventHandler(OnFileTransactionProgress);
Buffer.Progress += peh;
Buffer.Load(filename);
Buffer.Progress -= peh;
OnFileTransactionComplete("done.");
}
public void SaveFile(string filename)
{
OnFileTransaction("Save");
ProgressEventHandler peh = new ProgressEventHandler(OnFileTransactionProgress);
Buffer.Progress += peh;
Buffer.Save(filename);
Buffer.Progress -= peh;
OnFileTransactionComplete("done.");
}
public override void Dispose()
{
// errorfindthread.Abort();
caretthread.Abort();
textarea.Dispose();
base.Dispose();
}
public TextAreaControl(MainWindow main) : this(main, new TextBuffer())
{
}
public TextAreaControl(MainWindow main, TextBuffer buffer)
{
this.mainwindow = main;
textarea = new TextAreaPainter(buffer, main);
ErrorDrawer = new ErrorDrawer(this);
lineview = new LineNumberView(textarea);
clipboardhandler = new SharpTextAreaClipboardHandler(this);
mouseeventhandler = new TextAreaMouseHandler(this);
textareapanel.Controls.Add(textarea);
linenumberpanel.Controls.Add(lineview);
mainpanel.Dock = DockStyle.Fill;
mainpanel.Controls.Add(rowpanel);
mainpanel.Controls.Add(linenumberpanel);
mainpanel.Controls.Add(textareapanel);
mainpanel.Controls.Add(vscrollbar);
mainpanel.Controls.Add(hscrollbar);
Controls.Add(mainpanel);
vscrollbar.ValueChanged += new EventHandler(ScrollVScrollBar);
hscrollbar.ValueChanged += new EventHandler(ScrollHScrollBar);
mainpanel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
mainpanel.Resize += new System.EventHandler(panel_resize);
linenumberpanel.Location = new Point(0, 0);
lineview.Location = new Point(0, 0);
lineview.Width = textarea.Options.ShowLineNumbers ? 40 : 10;
textarea.Size = new Size(100, 100);
textareapanel.Location = new Point(lineview.Width, 0);
textarea.Resize += new System.EventHandler(MyResize);
Resize += new System.EventHandler(MyResize);
textarea.Buffer.Changed += new EventHandler(BufferChange);
Buffer.UndoStack.AfterRedo += new EventHandler(TextAreaRefreshEvt);
Buffer.UndoStack.AfterUndo += new EventHandler(TextAreaRefreshEvt);
textarea.KeyPress += new KeyPressEventHandler(KeyPressed);
Caret.Changed += new EventHandler(NewCaretPos);
textarea.MouseDown += new MouseEventHandler(mouseeventhandler.OnMouseDown);
textarea.MouseMove += new MouseEventHandler(mouseeventhandler.OnMouseMove);
textarea.DoubleClick += new EventHandler(mouseeventhandler.OnDoubleClick);
XmlDocument xd = new XmlDocument();
xd.Load(Application.StartupPath + "\\options\\TextAreaContextMenu.xml");
Selection.SelectionChanged += new EventHandler(UpdateSelection);
caretthread = new Thread(new ThreadStart(CaretThreadMethod));
caretthread.Start();
// errorfindthread = new Thread(new ThreadStart(ErrorFindThread));
// errorfindthread.Priority = ThreadPriority.Lowest;
// errorfindthread.Start();
ResizeRedraw = false;
ruler = new Ruler(textarea);
rowpanel.Controls.Add(ruler);
Options.OptionChanged += new EventHandler(OptionsChanged);
OptionsChanged(null, null);
Buffer.Changed += new EventHandler(OnChangedTextBuffer);
Buffer.Bookmark.BeforeChanged += new EventHandler(OnBeforeChangedBookMarks);
Buffer.Bookmark.Changed += new EventHandler(OnChangedBookMarks);
textarea.ContextMenu = new ContextMenu(SharpDevelop.Tool.Function.MenuCreator.CreateMenu(main, "", xd.DocumentElement["CONTEXTMENU"]));
}
/*
void ErrorFindThread()
{
int line = 0;
int brackets = 0;
while (true) {
if (line < Buffer.Length)
for (int i = 0; i < Buffer[line].Text.Length; ++i) {
if (Buffer[line].Text[i] == '{')
++brackets;
if (Buffer[line].Text[i] == '}') {
--brackets;
if (brackets < 0) {
if (ErrorDrawer.AddError(new VisualError(line, i, 1, "No opening bracket found"))) {
InvalidateLines(i, 1, line, line);
}
}
}
}
if (++line > Buffer.Length) {
line = 0;
brackets = 0;
}
}
}*/
ArrayList oldmarks;
void OnBeforeChangedBookMarks(object sender, EventArgs e)
{
oldmarks = (ArrayList)Buffer.Bookmark.Marks.Clone();
}
void OnChangedBookMarks(object sender, EventArgs e)
{
foreach (int line in oldmarks)
UpdateLines(line, line);
foreach (int line in Buffer.Bookmark.Marks)
UpdateLines(line, line);
}
void OnChangedTextBuffer(object sender, EventArgs e)
{
if (Changed != null)
Changed(sender, e);
}
void OptionsChanged(object sender, EventArgs e)
{
textarea.CalculateFontSize();
rowpanel.Visible = Options.ShowVRuler;
lineview.Width = (int)(15 + (Options.ShowLineNumbers ? (Math.Max(3, (int)(Math.Log10(Buffer.Length) + 1))) * textarea.FontWidth : 0));
OnResize(null);
MyResize(null, null);
panel_resize(null, null);
linenumberpanel.Refresh();
TextAreaPainter.Refresh();
}
void OnFileTransaction(string transaction)
{
if (FileTransaction != null)
FileTransaction(transaction, null);
}
void OnFileTransactionProgress(object sender, int percent)
{
if (FileTransactionProgress != null)
FileTransactionProgress(this, percent);
}
void OnFileTransactionComplete(string transaction)
{
if (FileTransactionComplete != null)
FileTransactionComplete(transaction, null);
}
void CaretThreadMethod()
{
while (true) {
ContentWindow w = mainwindow.ActiveContentWindow;
// if (w != null && w.HasTextArea && w.TextArea == this)
if (textarea.IHaveTheFocus)
{ // sorry, hack use Focused in future versions.
Caret.Visible = !Caret.Visible;
textarea.InvalidatePos(Caret.PhysicalCaretPos);
textarea.Update();
}
else {
if (Caret.Visible) {
Caret.Visible = false;
textarea.InvalidatePos(Caret.PhysicalCaretPos);
textarea.Update();
}
}
Thread.Sleep(400);
}
}
public string GetWordBeforeCaret()
{
int x = Caret.CaretPos.X - 1;
while (x > 0) {
if (Char.IsWhiteSpace(Buffer[Caret.CaretPos.Y].Text[x])) {
++x;
break;
}
--x;
}
if (x >= 0 && x < Caret.CaretPos.X && Char.IsWhiteSpace(Buffer[Caret.CaretPos.Y].Text[x]))
++x;
string word = "";
if (x >= 0 && x < Caret.CaretPos.X)
word = Buffer[Caret.CaretPos.Y].Text.Substring(x, Caret.CaretPos.X - x);
return word;
}
public void DeleteWordBeforeCaret()
{
int x = Caret.CaretPos.X - 1;
while (x > 0) {
if (Char.IsWhiteSpace(Buffer[Caret.CaretPos.Y].Text[x])) {
++x;
break;
}
--x;
}
if (x >= 0 && x < Caret.CaretPos.X && Char.IsWhiteSpace(Buffer[Caret.CaretPos.Y].Text[x]))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -