// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software // without restriction, including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons // to whom the Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or // substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. using System; using System.ComponentModel; using System.Reflection; using System.Text; namespace ICSharpCode.AvalonEdit { /// /// A container for the text editor options. /// [Serializable] public class TextEditorOptions : INotifyPropertyChanged { #region ctor /// /// Initializes an empty instance of TextEditorOptions. /// public TextEditorOptions() { } /// /// Initializes a new instance of TextEditorOptions by copying all values /// from to the new instance. /// public TextEditorOptions(TextEditorOptions options) { // get all the fields in the class FieldInfo[] fields = typeof(TextEditorOptions).GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); // copy each value over to 'this' foreach(FieldInfo fi in fields) { if (!fi.IsNotSerialized) fi.SetValue(this, fi.GetValue(options)); } } #endregion #region PropertyChanged handling /// [field: NonSerialized] public event PropertyChangedEventHandler PropertyChanged; /// /// Raises the PropertyChanged event. /// /// The name of the changed property. protected void OnPropertyChanged(string propertyName) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } /// /// Raises the PropertyChanged event. /// protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) { PropertyChanged(this, e); } } #endregion #region ShowSpaces / ShowTabs / ShowEndOfLine / ShowBoxForControlCharacters bool showSpaces; /// /// Gets/Sets whether to show · for spaces. /// /// The default value is false. [DefaultValue(false)] public virtual bool ShowSpaces { get { return showSpaces; } set { if (showSpaces != value) { showSpaces = value; OnPropertyChanged("ShowSpaces"); } } } bool showTabs; /// /// Gets/Sets whether to show » for tabs. /// /// The default value is false. [DefaultValue(false)] public virtual bool ShowTabs { get { return showTabs; } set { if (showTabs != value) { showTabs = value; OnPropertyChanged("ShowTabs"); } } } bool showEndOfLine; /// /// Gets/Sets whether to show ¶ at the end of lines. /// /// The default value is false. [DefaultValue(false)] public virtual bool ShowEndOfLine { get { return showEndOfLine; } set { if (showEndOfLine != value) { showEndOfLine = value; OnPropertyChanged("ShowEndOfLine"); } } } bool showBoxForControlCharacters = true; /// /// Gets/Sets whether to show a box with the hex code for control characters. /// /// The default value is true. [DefaultValue(true)] public virtual bool ShowBoxForControlCharacters { get { return showBoxForControlCharacters; } set { if (showBoxForControlCharacters != value) { showBoxForControlCharacters = value; OnPropertyChanged("ShowBoxForControlCharacters"); } } } #endregion #region EnableHyperlinks bool enableHyperlinks = true; /// /// Gets/Sets whether to enable clickable hyperlinks in the editor. /// /// The default value is true. [DefaultValue(true)] public virtual bool EnableHyperlinks { get { return enableHyperlinks; } set { if (enableHyperlinks != value) { enableHyperlinks = value; OnPropertyChanged("EnableHyperlinks"); } } } bool enableEmailHyperlinks = true; /// /// Gets/Sets whether to enable clickable hyperlinks for e-mail addresses in the editor. /// /// The default value is true. [DefaultValue(true)] public virtual bool EnableEmailHyperlinks { get { return enableEmailHyperlinks; } set { if (enableEmailHyperlinks != value) { enableEmailHyperlinks = value; OnPropertyChanged("EnableEMailHyperlinks"); } } } bool requireControlModifierForHyperlinkClick = true; /// /// Gets/Sets whether the user needs to press Control to click hyperlinks. /// The default value is true. /// /// The default value is true. [DefaultValue(true)] public virtual bool RequireControlModifierForHyperlinkClick { get { return requireControlModifierForHyperlinkClick; } set { if (requireControlModifierForHyperlinkClick != value) { requireControlModifierForHyperlinkClick = value; OnPropertyChanged("RequireControlModifierForHyperlinkClick"); } } } #endregion #region TabSize / IndentationSize / ConvertTabsToSpaces / GetIndentationString // I'm using '_' prefixes for the fields here to avoid confusion with the local variables // in the methods below. // The fields should be accessed only by their property - the fields might not be used // if someone overrides the property. int indentationSize = 4; /// /// Gets/Sets the width of one indentation unit. /// /// The default value is 4. [DefaultValue(4)] public virtual int IndentationSize { get { return indentationSize; } set { if (value < 1) throw new ArgumentOutOfRangeException("value", value, "value must be positive"); // sanity check; a too large value might cause WPF to crash internally much later // (it only crashed in the hundred thousands for me; but might crash earlier with larger fonts) if (value > 1000) throw new ArgumentOutOfRangeException("value", value, "indentation size is too large"); if (indentationSize != value) { indentationSize = value; OnPropertyChanged("IndentationSize"); OnPropertyChanged("IndentationString"); } } } bool convertTabsToSpaces; /// /// Gets/Sets whether to use spaces for indentation instead of tabs. /// /// The default value is false. [DefaultValue(false)] public virtual bool ConvertTabsToSpaces { get { return convertTabsToSpaces; } set { if (convertTabsToSpaces != value) { convertTabsToSpaces = value; OnPropertyChanged("ConvertTabsToSpaces"); OnPropertyChanged("IndentationString"); } } } /// /// Gets the text used for indentation. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")] [Browsable(false)] public string IndentationString { get { return GetIndentationString(1); } } /// /// Gets text required to indent from the specified to the next indentation level. /// public virtual string GetIndentationString(int column) { if (column < 1) throw new ArgumentOutOfRangeException("column", column, "Value must be at least 1."); int indentationSize = this.IndentationSize; if (ConvertTabsToSpaces) { return new string(' ', indentationSize - ((column - 1) % indentationSize)); } else { return "\t"; } } #endregion bool cutCopyWholeLine = true; /// /// Gets/Sets whether copying without a selection copies the whole current line. /// [DefaultValue(true)] public virtual bool CutCopyWholeLine { get { return cutCopyWholeLine; } set { if (cutCopyWholeLine != value) { cutCopyWholeLine = value; OnPropertyChanged("CutCopyWholeLine"); } } } bool allowScrollBelowDocument; /// /// Gets/Sets whether the user can scroll below the bottom of the document. /// The default value is false; but it a good idea to set this property to true when using folding. /// [DefaultValue(false)] public virtual bool AllowScrollBelowDocument { get { return allowScrollBelowDocument; } set { if (allowScrollBelowDocument != value) { allowScrollBelowDocument = value; OnPropertyChanged("AllowScrollBelowDocument"); } } } double wordWrapIndentation = 0; /// /// Gets/Sets the indentation used for all lines except the first when word-wrapping. /// The default value is 0. /// [DefaultValue(0.0)] public virtual double WordWrapIndentation { get { return wordWrapIndentation; } set { if (double.IsNaN(value) || double.IsInfinity(value)) throw new ArgumentOutOfRangeException("value", value, "value must not be NaN/infinity"); if (value != wordWrapIndentation) { wordWrapIndentation = value; OnPropertyChanged("WordWrapIndentation"); } } } bool inheritWordWrapIndentation = true; /// /// Gets/Sets whether the indentation is inherited from the first line when word-wrapping. /// The default value is true. /// /// When combined with , the inherited indentation is added to the word wrap indentation. [DefaultValue(true)] public virtual bool InheritWordWrapIndentation { get { return inheritWordWrapIndentation; } set { if (value != inheritWordWrapIndentation) { inheritWordWrapIndentation = value; OnPropertyChanged("InheritWordWrapIndentation"); } } } bool enableRectangularSelection = true; /// /// Enables rectangular selection (press ALT and select a rectangle) /// [DefaultValue(true)] public bool EnableRectangularSelection { get { return enableRectangularSelection; } set { if (enableRectangularSelection != value) { enableRectangularSelection = value; OnPropertyChanged("EnableRectangularSelection"); } } } bool enableTextDragDrop = true; /// /// Enable dragging text within the text area. /// [DefaultValue(true)] public bool EnableTextDragDrop { get { return enableTextDragDrop; } set { if (enableTextDragDrop != value) { enableTextDragDrop = value; OnPropertyChanged("EnableTextDragDrop"); } } } bool enableVirtualSpace; /// /// Gets/Sets whether the user can set the caret behind the line ending /// (into "virtual space"). /// Note that virtual space is always used (independent from this setting) /// when doing rectangle selections. /// [DefaultValue(false)] public virtual bool EnableVirtualSpace { get { return enableVirtualSpace; } set { if (enableVirtualSpace != value) { enableVirtualSpace = value; OnPropertyChanged("EnableVirtualSpace"); } } } bool enableImeSupport = true; /// /// Gets/Sets whether the support for Input Method Editors (IME) /// for non-alphanumeric scripts (Chinese, Japanese, Korean, ...) is enabled. /// [DefaultValue(true)] public virtual bool EnableImeSupport { get { return enableImeSupport; } set { if (enableImeSupport != value) { enableImeSupport = value; OnPropertyChanged("EnableImeSupport"); } } } bool showColumnRuler = false; /// /// Gets/Sets whether the column ruler should be shown. /// [DefaultValue(false)] public virtual bool ShowColumnRuler { get { return showColumnRuler; } set { if (showColumnRuler != value) { showColumnRuler = value; OnPropertyChanged("ShowColumnRuler"); } } } int columnRulerPosition = 80; /// /// Gets/Sets where the column ruler should be shown. /// [DefaultValue(80)] public virtual int ColumnRulerPosition { get { return columnRulerPosition; } set { if (columnRulerPosition != value) { columnRulerPosition = value; OnPropertyChanged("ColumnRulerPosition"); } } } bool highlightCurrentLine = false; /// /// Gets/Sets if current line should be shown. /// [DefaultValue(false)] public virtual bool HighlightCurrentLine { get { return highlightCurrentLine; } set { if (highlightCurrentLine != value) { highlightCurrentLine = value; OnPropertyChanged("HighlightCurrentLine"); } } } bool hideCursorWhileTyping = true; /// /// Gets/Sets if mouse cursor should be hidden while user is typing. /// [DefaultValue(true)] public bool HideCursorWhileTyping { get { return hideCursorWhileTyping; } set { if (hideCursorWhileTyping != value) { hideCursorWhileTyping = value; OnPropertyChanged("HideCursorWhileTyping"); } } } bool allowToggleOverstrikeMode = false; /// /// Gets/Sets if the user is allowed to enable/disable overstrike mode. /// [DefaultValue(false)] public bool AllowToggleOverstrikeMode { get { return allowToggleOverstrikeMode; } set { if (allowToggleOverstrikeMode != value) { allowToggleOverstrikeMode = value; OnPropertyChanged("AllowToggleOverstrikeMode"); } } } } }