⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textareacontrol.cs

📁 c#精彩编程百例(源代码)
💻 CS
📖 第 1 页 / 共 2 页
字号:
//  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 + -