760 lines
22 KiB
C#
760 lines
22 KiB
C#
// <file>
|
|
// <copyright see="prj:///doc/copyright.txt"/>
|
|
// <license see="prj:///doc/license.txt"/>
|
|
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
|
// <version>$Revision$</version>
|
|
// </file>
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Drawing.Text;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
|
|
using ICSharpCode.TextEditor.Actions;
|
|
using ICSharpCode.TextEditor.Document;
|
|
|
|
namespace ICSharpCode.TextEditor
|
|
{
|
|
/// <summary>
|
|
/// This class is used for a basic text area control
|
|
/// </summary>
|
|
[ToolboxItem(false)]
|
|
public abstract class TextEditorControlBase : UserControl
|
|
{
|
|
string currentFileName = null;
|
|
int updateLevel = 0;
|
|
protected IDocument document; // Stef Heyenrath : Changed to protected
|
|
|
|
/// <summary>
|
|
/// This hashtable contains all editor keys, where
|
|
/// the key is the key combination and the value the
|
|
/// action.
|
|
/// </summary>
|
|
protected Dictionary<Keys, IEditAction> editactions = new Dictionary<Keys, IEditAction>();
|
|
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public ITextEditorProperties TextEditorProperties {
|
|
get {
|
|
return document.TextEditorProperties;
|
|
}
|
|
set {
|
|
document.TextEditorProperties = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
Encoding encoding;
|
|
|
|
/// <value>
|
|
/// Current file's character encoding
|
|
/// </value>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public Encoding Encoding {
|
|
get {
|
|
if (encoding == null)
|
|
return TextEditorProperties.Encoding;
|
|
return encoding;
|
|
}
|
|
set {
|
|
encoding = value;
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// The current file name
|
|
/// </value>
|
|
[Browsable(false)]
|
|
[ReadOnly(true)]
|
|
public string FileName {
|
|
get {
|
|
return currentFileName;
|
|
}
|
|
set {
|
|
if (currentFileName != value) {
|
|
currentFileName = value;
|
|
OnFileNameChanged(EventArgs.Empty);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// The current document
|
|
/// </value>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public IDocument Document {
|
|
get {
|
|
return document;
|
|
}
|
|
set {
|
|
if (value == null)
|
|
throw new ArgumentNullException("value");
|
|
if (document != null) {
|
|
document.DocumentChanged -= OnDocumentChanged;
|
|
}
|
|
document = value;
|
|
document.UndoStack.TextEditorControl = this;
|
|
document.DocumentChanged += OnDocumentChanged;
|
|
}
|
|
}
|
|
|
|
protected void OnDocumentChanged(object sender, EventArgs e) // Stef Heyenrath : changed to protected
|
|
{
|
|
OnTextChanged(e);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
|
[Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))]
|
|
public override string Text {
|
|
get {
|
|
return Document.TextContent;
|
|
}
|
|
set {
|
|
Document.TextContent = value;
|
|
}
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true)]
|
|
public new event EventHandler TextChanged
|
|
{
|
|
add { base.TextChanged += value; }
|
|
remove { base.TextChanged -= value; }
|
|
}
|
|
|
|
static Font ParseFont(string font)
|
|
{
|
|
string[] descr = font.Split(new char[]{',', '='});
|
|
return new Font(descr[1], float.Parse(descr[3]));
|
|
}
|
|
|
|
/// <value>
|
|
/// If set to true the contents can't be altered.
|
|
/// </value>
|
|
[Browsable(false)]
|
|
public bool IsReadOnly {
|
|
get {
|
|
return Document.ReadOnly;
|
|
}
|
|
set {
|
|
Document.ReadOnly = value;
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// true, if the textarea is updating it's status, while
|
|
/// it updates it status no redraw operation occurs.
|
|
/// </value>
|
|
[Browsable(false)]
|
|
public bool IsInUpdate {
|
|
get {
|
|
return updateLevel > 0;
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// supposedly this is the way to do it according to .NET docs,
|
|
/// as opposed to setting the size in the constructor
|
|
/// </value>
|
|
protected override Size DefaultSize {
|
|
get {
|
|
return new Size(100, 100);
|
|
}
|
|
}
|
|
|
|
#region Document Properties
|
|
/// <value>
|
|
/// If true spaces are shown in the textarea
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(false)]
|
|
[Description("If true spaces are shown in the textarea")]
|
|
public bool ShowSpaces {
|
|
get {
|
|
return document.TextEditorProperties.ShowSpaces;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.ShowSpaces = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// Specifies the quality of text rendering (whether to use hinting and/or anti-aliasing).
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(TextRenderingHint.SystemDefault)]
|
|
[Description("Specifies the quality of text rendering (whether to use hinting and/or anti-aliasing).")]
|
|
public TextRenderingHint TextRenderingHint {
|
|
get {
|
|
return document.TextEditorProperties.TextRenderingHint;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.TextRenderingHint = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// If true tabs are shown in the textarea
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(false)]
|
|
[Description("If true tabs are shown in the textarea")]
|
|
public bool ShowTabs {
|
|
get {
|
|
return document.TextEditorProperties.ShowTabs;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.ShowTabs = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// If true EOL markers are shown in the textarea
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(false)]
|
|
[Description("If true EOL markers are shown in the textarea")]
|
|
public bool ShowEOLMarkers {
|
|
get {
|
|
return document.TextEditorProperties.ShowEOLMarker;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.ShowEOLMarker = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// If true the horizontal ruler is shown in the textarea
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(false)]
|
|
[Description("If true the horizontal ruler is shown in the textarea")]
|
|
public bool ShowHRuler {
|
|
get {
|
|
return document.TextEditorProperties.ShowHorizontalRuler;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.ShowHorizontalRuler = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// If true the vertical ruler is shown in the textarea
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(true)]
|
|
[Description("If true the vertical ruler is shown in the textarea")]
|
|
public bool ShowVRuler {
|
|
get {
|
|
return document.TextEditorProperties.ShowVerticalRuler;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.ShowVerticalRuler = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// The row in which the vertical ruler is displayed
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(80)]
|
|
[Description("The row in which the vertical ruler is displayed")]
|
|
public int VRulerRow {
|
|
get {
|
|
return document.TextEditorProperties.VerticalRulerRow;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.VerticalRulerRow = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// If true line numbers are shown in the textarea
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(true)]
|
|
[Description("If true line numbers are shown in the textarea")]
|
|
public bool ShowLineNumbers {
|
|
get {
|
|
return document.TextEditorProperties.ShowLineNumbers;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.ShowLineNumbers = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// If true invalid lines are marked in the textarea
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(false)]
|
|
[Description("If true invalid lines are marked in the textarea")]
|
|
public bool ShowInvalidLines {
|
|
get {
|
|
return document.TextEditorProperties.ShowInvalidLines;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.ShowInvalidLines = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// If true folding is enabled in the textarea
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(true)]
|
|
[Description("If true folding is enabled in the textarea")]
|
|
public bool EnableFolding {
|
|
get {
|
|
return document.TextEditorProperties.EnableFolding;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.EnableFolding = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
[Category("Appearance")]
|
|
[DefaultValue(true)]
|
|
[Description("If true matching brackets are highlighted")]
|
|
public bool ShowMatchingBracket {
|
|
get {
|
|
return document.TextEditorProperties.ShowMatchingBracket;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.ShowMatchingBracket = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
[Category("Appearance")]
|
|
[DefaultValue(false)]
|
|
[Description("If true the icon bar is displayed")]
|
|
public bool IsIconBarVisible {
|
|
get {
|
|
return document.TextEditorProperties.IsIconBarVisible;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.IsIconBarVisible = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// The width in spaces of a tab character
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(4)]
|
|
[Description("The width in spaces of a tab character")]
|
|
public int TabIndent {
|
|
get {
|
|
return document.TextEditorProperties.TabIndent;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.TabIndent = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// The line viewer style
|
|
/// </value>
|
|
[Category("Appearance")]
|
|
[DefaultValue(LineViewerStyle.None)]
|
|
[Description("The line viewer style")]
|
|
public LineViewerStyle LineViewerStyle {
|
|
get {
|
|
return document.TextEditorProperties.LineViewerStyle;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.LineViewerStyle = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// The indent style
|
|
/// </value>
|
|
[Category("Behavior")]
|
|
[DefaultValue(IndentStyle.Smart)]
|
|
[Description("The indent style")]
|
|
public IndentStyle IndentStyle {
|
|
get {
|
|
return document.TextEditorProperties.IndentStyle;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.IndentStyle = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// if true spaces are converted to tabs
|
|
/// </value>
|
|
[Category("Behavior")]
|
|
[DefaultValue(false)]
|
|
[Description("Converts tabs to spaces while typing")]
|
|
public bool ConvertTabsToSpaces {
|
|
get {
|
|
return document.TextEditorProperties.ConvertTabsToSpaces;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.ConvertTabsToSpaces = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// if true spaces are converted to tabs
|
|
/// </value>
|
|
[Category("Behavior")]
|
|
[DefaultValue(false)]
|
|
[Description("Hide the mouse cursor while typing")]
|
|
public bool HideMouseCursor {
|
|
get {
|
|
return document.TextEditorProperties.HideMouseCursor;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.HideMouseCursor = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// if true spaces are converted to tabs
|
|
/// </value>
|
|
[Category("Behavior")]
|
|
[DefaultValue(false)]
|
|
[Description("Allows the caret to be placed beyond the end of line")]
|
|
public bool AllowCaretBeyondEOL {
|
|
get {
|
|
return document.TextEditorProperties.AllowCaretBeyondEOL;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.AllowCaretBeyondEOL = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
/// <value>
|
|
/// if true spaces are converted to tabs
|
|
/// </value>
|
|
[Category("Behavior")]
|
|
[DefaultValue(BracketMatchingStyle.After)]
|
|
[Description("Specifies if the bracket matching should match the bracket before or after the caret.")]
|
|
public BracketMatchingStyle BracketMatchingStyle {
|
|
get {
|
|
return document.TextEditorProperties.BracketMatchingStyle;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.BracketMatchingStyle = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
/// <value>
|
|
/// The base font of the text area. No bold or italic fonts
|
|
/// can be used because bold/italic is reserved for highlighting
|
|
/// purposes.
|
|
/// </value>
|
|
[Browsable(true)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
|
[DefaultValue(typeof(Font), null)] // Stef_H
|
|
[Description("The base font of the text area. No bold or italic fonts can be used because bold/italic is reserved for highlighting purposes.")]
|
|
public override Font Font {
|
|
get {
|
|
return document.TextEditorProperties.Font;
|
|
}
|
|
set {
|
|
document.TextEditorProperties.Font = value;
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
public abstract TextAreaControl ActiveTextAreaControl {
|
|
get;
|
|
}
|
|
|
|
protected TextEditorControlBase()
|
|
{
|
|
GenerateDefaultActions();
|
|
HighlightingManager.Manager.ReloadSyntaxHighlighting += new EventHandler(OnReloadHighlighting);
|
|
}
|
|
|
|
protected virtual void OnReloadHighlighting(object sender, EventArgs e)
|
|
{
|
|
if (Document.HighlightingStrategy != null) {
|
|
try {
|
|
Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy(Document.HighlightingStrategy.Name);
|
|
} catch (HighlightingDefinitionInvalidException ex) {
|
|
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
OptionsChanged();
|
|
}
|
|
}
|
|
|
|
public bool IsEditAction(Keys keyData)
|
|
{
|
|
return editactions.ContainsKey(keyData);
|
|
}
|
|
|
|
internal IEditAction GetEditAction(Keys keyData)
|
|
{
|
|
if (!IsEditAction(keyData)) {
|
|
return null;
|
|
}
|
|
return (IEditAction)editactions[keyData];
|
|
}
|
|
|
|
void GenerateDefaultActions()
|
|
{
|
|
editactions[Keys.Left] = new CaretLeft();
|
|
editactions[Keys.Left | Keys.Shift] = new ShiftCaretLeft();
|
|
editactions[Keys.Left | Keys.Control] = new WordLeft();
|
|
editactions[Keys.Left | Keys.Control | Keys.Shift] = new ShiftWordLeft();
|
|
editactions[Keys.Right] = new CaretRight();
|
|
editactions[Keys.Right | Keys.Shift] = new ShiftCaretRight();
|
|
editactions[Keys.Right | Keys.Control] = new WordRight();
|
|
editactions[Keys.Right | Keys.Control | Keys.Shift] = new ShiftWordRight();
|
|
editactions[Keys.Up] = new CaretUp();
|
|
editactions[Keys.Up | Keys.Shift] = new ShiftCaretUp();
|
|
editactions[Keys.Up | Keys.Control] = new ScrollLineUp();
|
|
editactions[Keys.Down] = new CaretDown();
|
|
editactions[Keys.Down | Keys.Shift] = new ShiftCaretDown();
|
|
editactions[Keys.Down | Keys.Control] = new ScrollLineDown();
|
|
|
|
editactions[Keys.Insert] = new ToggleEditMode();
|
|
editactions[Keys.Insert | Keys.Control] = new Copy();
|
|
editactions[Keys.Insert | Keys.Shift] = new Paste();
|
|
editactions[Keys.Delete] = new Delete();
|
|
editactions[Keys.Delete | Keys.Shift] = new Cut();
|
|
editactions[Keys.Home] = new Home();
|
|
editactions[Keys.Home | Keys.Shift] = new ShiftHome();
|
|
editactions[Keys.Home | Keys.Control] = new MoveToStart();
|
|
editactions[Keys.Home | Keys.Control | Keys.Shift] = new ShiftMoveToStart();
|
|
editactions[Keys.End] = new End();
|
|
editactions[Keys.End | Keys.Shift] = new ShiftEnd();
|
|
editactions[Keys.End | Keys.Control] = new MoveToEnd();
|
|
editactions[Keys.End | Keys.Control | Keys.Shift] = new ShiftMoveToEnd();
|
|
editactions[Keys.PageUp] = new MovePageUp();
|
|
editactions[Keys.PageUp | Keys.Shift] = new ShiftMovePageUp();
|
|
editactions[Keys.PageDown] = new MovePageDown();
|
|
editactions[Keys.PageDown | Keys.Shift] = new ShiftMovePageDown();
|
|
|
|
editactions[Keys.Return] = new Return();
|
|
editactions[Keys.Tab] = new Tab();
|
|
editactions[Keys.Tab | Keys.Shift] = new ShiftTab();
|
|
editactions[Keys.Back] = new Backspace();
|
|
editactions[Keys.Back | Keys.Shift] = new Backspace();
|
|
|
|
editactions[Keys.X | Keys.Control] = new Cut();
|
|
editactions[Keys.C | Keys.Control] = new Copy();
|
|
editactions[Keys.V | Keys.Control] = new Paste();
|
|
|
|
editactions[Keys.A | Keys.Control] = new SelectWholeDocument();
|
|
editactions[Keys.Escape] = new ClearAllSelections();
|
|
|
|
editactions[Keys.Divide | Keys.Control] = new ToggleComment();
|
|
editactions[Keys.OemQuestion | Keys.Control] = new ToggleComment();
|
|
|
|
editactions[Keys.Back | Keys.Alt] = new Actions.Undo();
|
|
editactions[Keys.Z | Keys.Control] = new Actions.Undo();
|
|
editactions[Keys.Y | Keys.Control] = new Redo();
|
|
|
|
editactions[Keys.Delete | Keys.Control] = new DeleteWord();
|
|
editactions[Keys.Back | Keys.Control] = new WordBackspace();
|
|
editactions[Keys.D | Keys.Control] = new DeleteLine();
|
|
editactions[Keys.D | Keys.Shift | Keys.Control] = new DeleteToLineEnd();
|
|
|
|
editactions[Keys.B | Keys.Control] = new GotoMatchingBrace();
|
|
}
|
|
|
|
/// <remarks>
|
|
/// Call this method before a long update operation this
|
|
/// 'locks' the text area so that no screen update occurs.
|
|
/// </remarks>
|
|
public virtual void BeginUpdate()
|
|
{
|
|
++updateLevel;
|
|
}
|
|
|
|
/// <remarks>
|
|
/// Call this method to 'unlock' the text area. After this call
|
|
/// screen update can occur. But no automatical refresh occurs you
|
|
/// have to commit the updates in the queue.
|
|
/// </remarks>
|
|
public virtual void EndUpdate()
|
|
{
|
|
Debug.Assert(updateLevel > 0);
|
|
updateLevel = Math.Max(0, updateLevel - 1);
|
|
}
|
|
|
|
public void LoadFile(string fileName)
|
|
{
|
|
LoadFile(fileName, true, true);
|
|
}
|
|
|
|
/// <remarks>
|
|
/// Loads a file given by fileName
|
|
/// </remarks>
|
|
/// <param name="fileName">The name of the file to open</param>
|
|
/// <param name="autoLoadHighlighting">Automatically load the highlighting for the file</param>
|
|
/// <param name="autodetectEncoding">Automatically detect file encoding and set Encoding property to the detected encoding.</param>
|
|
public void LoadFile(string fileName, bool autoLoadHighlighting, bool autodetectEncoding)
|
|
{
|
|
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
|
|
LoadFile(fileName, fs, autoLoadHighlighting, autodetectEncoding);
|
|
}
|
|
}
|
|
|
|
/// <remarks>
|
|
/// Loads a file from the specified stream.
|
|
/// </remarks>
|
|
/// <param name="fileName">The name of the file to open. Used to find the correct highlighting strategy
|
|
/// if autoLoadHighlighting is active, and sets the filename property to this value.</param>
|
|
/// <param name="stream">The stream to actually load the file content from.</param>
|
|
/// <param name="autoLoadHighlighting">Automatically load the highlighting for the file</param>
|
|
/// <param name="autodetectEncoding">Automatically detect file encoding and set Encoding property to the detected encoding.</param>
|
|
public void LoadFile(string fileName, Stream stream, bool autoLoadHighlighting, bool autodetectEncoding)
|
|
{
|
|
if (stream == null)
|
|
throw new ArgumentNullException("stream");
|
|
|
|
BeginUpdate();
|
|
document.TextContent = string.Empty;
|
|
document.UndoStack.ClearAll();
|
|
document.BookmarkManager.Clear();
|
|
if (autoLoadHighlighting) {
|
|
try {
|
|
document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategyForFile(fileName);
|
|
} catch (HighlightingDefinitionInvalidException ex) {
|
|
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
|
|
if (autodetectEncoding) {
|
|
Encoding encoding = this.Encoding;
|
|
Document.TextContent = Util.FileReader.ReadFileContent(stream, ref encoding);
|
|
this.Encoding = encoding;
|
|
} else {
|
|
using (StreamReader reader = new StreamReader(fileName, this.Encoding)) {
|
|
Document.TextContent = reader.ReadToEnd();
|
|
}
|
|
}
|
|
|
|
this.FileName = fileName;
|
|
Document.UpdateQueue.Clear();
|
|
EndUpdate();
|
|
|
|
OptionsChanged();
|
|
Refresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets if the document can be saved with the current encoding without losing data.
|
|
/// </summary>
|
|
public bool CanSaveWithCurrentEncoding()
|
|
{
|
|
if (encoding == null || Util.FileReader.IsUnicode(encoding))
|
|
return true;
|
|
// not a unicode codepage
|
|
string text = document.TextContent;
|
|
return encoding.GetString(encoding.GetBytes(text)) == text;
|
|
}
|
|
|
|
/// <remarks>
|
|
/// Saves the text editor content into the file.
|
|
/// </remarks>
|
|
public void SaveFile(string fileName)
|
|
{
|
|
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) {
|
|
SaveFile(fs);
|
|
}
|
|
this.FileName = fileName;
|
|
}
|
|
|
|
/// <remarks>
|
|
/// Saves the text editor content into the specified stream.
|
|
/// Does not close the stream.
|
|
/// </remarks>
|
|
public void SaveFile(Stream stream)
|
|
{
|
|
StreamWriter streamWriter = new StreamWriter(stream, this.Encoding ?? Encoding.UTF8);
|
|
|
|
// save line per line to apply the LineTerminator to all lines
|
|
// (otherwise we might save files with mixed-up line endings)
|
|
foreach (LineSegment line in Document.LineSegmentCollection) {
|
|
streamWriter.Write(Document.GetText(line.Offset, line.Length));
|
|
if (line.DelimiterLength > 0) {
|
|
char charAfterLine = Document.GetCharAt(line.Offset + line.Length);
|
|
if (charAfterLine != '\n' && charAfterLine != '\r')
|
|
throw new InvalidOperationException("The document cannot be saved because it is corrupted.");
|
|
// only save line terminator if the line has one
|
|
streamWriter.Write(document.TextEditorProperties.LineTerminator);
|
|
}
|
|
}
|
|
streamWriter.Flush();
|
|
}
|
|
|
|
public abstract void OptionsChanged();
|
|
|
|
// Localization ISSUES
|
|
|
|
// used in insight window
|
|
public virtual string GetRangeDescription(int selectedItem, int itemCount)
|
|
{
|
|
StringBuilder sb=new StringBuilder(selectedItem.ToString());
|
|
sb.Append(" from ");
|
|
sb.Append(itemCount.ToString());
|
|
return sb.ToString();
|
|
}
|
|
|
|
/// <remarks>
|
|
/// Overwritten refresh method that does nothing if the control is in
|
|
/// an update cycle.
|
|
/// </remarks>
|
|
public override void Refresh()
|
|
{
|
|
if (IsInUpdate) {
|
|
return;
|
|
}
|
|
base.Refresh();
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing) {
|
|
HighlightingManager.Manager.ReloadSyntaxHighlighting -= new EventHandler(OnReloadHighlighting);
|
|
document.HighlightingStrategy = null;
|
|
document.UndoStack.TextEditorControl = null;
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
protected virtual void OnFileNameChanged(EventArgs e)
|
|
{
|
|
if (FileNameChanged != null) {
|
|
FileNameChanged(this, e);
|
|
}
|
|
}
|
|
|
|
public event EventHandler FileNameChanged;
|
|
}
|
|
}
|