diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs index 9f6d8ace59..acc9510526 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs @@ -146,6 +146,9 @@ namespace ICSharpCode.AvalonEdit.AddIn primaryTextEditorAdapter = (CodeEditorAdapter)primaryTextEditor.TextArea.GetService(typeof(ITextEditor)); Debug.Assert(primaryTextEditorAdapter != null); + // always support scrolling below the end of the document - it's better when folding is enabled + primaryTextEditor.Options.AllowScrollBelowDocument = true; + this.primaryBracketRenderer = new BracketHighlightRenderer(primaryTextEditor.TextArea.TextView); this.Document = primaryTextEditor.Document; @@ -239,6 +242,7 @@ namespace ICSharpCode.AvalonEdit.AddIn secondaryTextEditor.SetBinding(TextEditor.DocumentProperty, new Binding(TextEditor.DocumentProperty.Name) { Source = primaryTextEditor }); secondaryTextEditor.SyntaxHighlighting = primaryTextEditor.SyntaxHighlighting; + secondaryTextEditor.Options = primaryTextEditor.Options; SetRow(secondaryTextEditor, 2); this.Children.Add(secondaryTextEditor); diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ParserFoldingStrategy.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ParserFoldingStrategy.cs index 78f1b8a36e..d12a2a072b 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ParserFoldingStrategy.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ParserFoldingStrategy.cs @@ -23,60 +23,26 @@ namespace ICSharpCode.AvalonEdit.AddIn { readonly FoldingManager foldingManager; TextArea textArea; - FoldingMargin margin; - FoldingElementGenerator generator; bool isFirstUpdate = true; public ParserFoldingStrategy(TextArea textArea) { this.textArea = textArea; - foldingManager = new FoldingManager(textArea.TextView, textArea.Document); - foldingManager.ExpandFoldingsWhenCaretIsMovedIntoThem(textArea.Caret); - margin = new FoldingMargin() { FoldingManager = foldingManager }; - generator = new FoldingElementGenerator() { FoldingManager = foldingManager }; - textArea.LeftMargins.Add(margin); - textArea.TextView.ElementGenerators.Add(generator); + foldingManager = FoldingManager.Install(textArea); } public void Dispose() { if (textArea != null) { - textArea.LeftMargins.Remove(margin); - textArea.TextView.ElementGenerators.Remove(generator); - foldingManager.Clear(); + FoldingManager.Uninstall(foldingManager); textArea = null; } } public void UpdateFoldings(ParseInformation parseInfo) { - var oldFoldings = foldingManager.AllFoldings.ToArray(); IEnumerable newFoldings = GetNewFoldings(parseInfo); - int oldFoldingIndex = 0; - // merge new foldings into old foldings so that sections keep being collapsed - // both oldFoldings and newFoldings are sorted by start offset - foreach (NewFolding newFolding in newFoldings) { - // remove old foldings that were skipped - while (oldFoldingIndex < oldFoldings.Length && newFolding.StartOffset > oldFoldings[oldFoldingIndex].StartOffset) { - foldingManager.RemoveFolding(oldFoldings[oldFoldingIndex++]); - } - FoldingSection section; - // reuse current folding if its matching: - if (oldFoldingIndex < oldFoldings.Length && newFolding.StartOffset == oldFoldings[oldFoldingIndex].StartOffset) { - section = oldFoldings[oldFoldingIndex++]; - section.Length = newFolding.EndOffset - newFolding.StartOffset; - } else { - // no matching current folding; create a new one: - section = foldingManager.CreateFolding(newFolding.StartOffset, newFolding.EndOffset); - // auto-close #regions only when opening the document - section.IsFolded = isFirstUpdate && newFolding.DefaultClosed; - } - section.Title = newFolding.Name; - } - // remove all outstanding old foldings: - while (oldFoldingIndex < oldFoldings.Length) { - foldingManager.RemoveFolding(oldFoldings[oldFoldingIndex++]); - } + foldingManager.UpdateFoldings(newFoldings, -1); isFirstUpdate = false; } @@ -91,12 +57,12 @@ namespace ICSharpCode.AvalonEdit.AddIn foreach (FoldingRegion foldingRegion in parseInfo.CompilationUnit.FoldingRegions) { NewFolding f = new NewFolding(textArea.Document.GetOffset(foldingRegion.Region.BeginLine, foldingRegion.Region.BeginColumn), textArea.Document.GetOffset(foldingRegion.Region.EndLine, foldingRegion.Region.EndColumn)); - f.DefaultClosed = true; + f.DefaultClosed = isFirstUpdate; f.Name = foldingRegion.Name; newFoldMarkers.Add(f); } } - return newFoldMarkers.Where(f => f.EndOffset > f.StartOffset).OrderBy(f=>f.StartOffset); + return newFoldMarkers.OrderBy(f => f.StartOffset); } void AddClassMembers(IClass c, List newFoldMarkers) @@ -122,21 +88,5 @@ namespace ICSharpCode.AvalonEdit.AddIn } } } - - struct NewFolding - { - public readonly int StartOffset, EndOffset; - public string Name; - public bool DefaultClosed; - - public NewFolding(int start, int end) - { - Debug.Assert(start < end); - this.StartOffset = start; - this.EndOffset = end; - this.Name = null; - this.DefaultClosed = false; - } - } } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/BraceFoldingStrategy.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/BraceFoldingStrategy.cs new file mode 100644 index 0000000000..d93c66eaf0 --- /dev/null +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/BraceFoldingStrategy.cs @@ -0,0 +1,67 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.AvalonEdit.Document; +using System.Collections.Generic; + +namespace ICSharpCode.AvalonEdit.Folding +{ + /// + /// Allows producing foldings from a document based on braces. + /// + public class BraceFoldingStrategy + { + /// + /// Gets/Sets the opening brace. The default value is '{'. + /// + public char OpeningBrace { get; set; } + + /// + /// Gets/Sets the closing brace. The default value is '}'. + /// + public char ClosingBrace { get; set; } + + /// + /// Creates a new BraceFoldingStrategy. + /// + public BraceFoldingStrategy() + { + this.OpeningBrace = '{'; + this.ClosingBrace = '}'; + } + + /// + /// Create s for the specified document. + /// + public IEnumerable CreateNewFoldings(ITextSource document) + { + List newFoldings = new List(); + + Stack startOffsets = new Stack(); + int lastNewLineOffset = 0; + char openingBrace = this.OpeningBrace; + char closingBrace = this.ClosingBrace; + for (int i = 0; i < document.TextLength; i++) { + char c = document.GetCharAt(i); + if (c == openingBrace) { + startOffsets.Push(i); + } else if (c == closingBrace && startOffsets.Count > 0) { + int startOffset = startOffsets.Pop(); + // don't fold if opening and closing brace are on the same line + if (startOffset < lastNewLineOffset) { + newFoldings.Add(new NewFolding(startOffset, i + 1)); + } + } else if (c == '\n' || c == '\r') { + lastNewLineOffset = i + 1; + } + } + newFoldings.Sort((a,b) => a.StartOffset.CompareTo(b.StartOffset)); + return newFoldings; + } + } +} diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/FoldingManager.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/FoldingManager.cs index 67390a18f0..1bc2c718e7 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/FoldingManager.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/FoldingManager.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using System.Windows; using System.Windows.Threading; @@ -28,14 +29,7 @@ namespace ICSharpCode.AvalonEdit.Folding readonly TextSegmentCollection foldings; - /// - /// Creates a new FoldingManager instance. - /// - public FoldingManager(TextView textView) - : this(textView, ThrowUtil.CheckNotNull(textView, "textView").Document) - { - } - + #region Constructor /// /// Creates a new FoldingManager instance. /// @@ -49,48 +43,9 @@ namespace ICSharpCode.AvalonEdit.Folding this.document = document; this.foldings = new TextSegmentCollection(document); } - - #region ExpandFoldingsWhenCaretIsMovedIntoThem - // keep a reference to the helper as long as the folding manager exists - ExpandFoldingsWhenCaretIsMovedIntoThemHelper helper; - - /// - /// Will listen to Caret.PositionChanged events and automatically expand folding sections - /// when the caret is moved into them. - /// - public void ExpandFoldingsWhenCaretIsMovedIntoThem(Caret caret) - { - if (helper == null) - helper = new ExpandFoldingsWhenCaretIsMovedIntoThemHelper(this); - CaretWeakEventManager.PositionChanged.AddListener(caret, helper); - } - - sealed class ExpandFoldingsWhenCaretIsMovedIntoThemHelper : IWeakEventListener - { - FoldingManager manager; - - public ExpandFoldingsWhenCaretIsMovedIntoThemHelper(FoldingManager manager) - { - this.manager = manager; - } - - bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e) - { - if (managerType == typeof(CaretWeakEventManager.PositionChanged)) { - Caret caret = (Caret)sender; - int caretOffset = caret.Offset; - foreach (FoldingSection s in manager.GetFoldingsContaining(caretOffset)) { - if (s.IsFolded && s.StartOffset < caretOffset && caretOffset < s.EndOffset) { - s.IsFolded = false; - } - } - return true; - } - return false; - } - } #endregion + #region Create / Remove / Clear /// /// Creates a folding for the specified text section. /// @@ -100,7 +55,7 @@ namespace ICSharpCode.AvalonEdit.Folding throw new ArgumentException("startOffset must be less than endOffset"); FoldingSection fs = new FoldingSection(this, startOffset, endOffset); foldings.Add(fs); - textView.Redraw(); + textView.Redraw(fs, DispatcherPriority.Normal); return fs; } @@ -111,7 +66,6 @@ namespace ICSharpCode.AvalonEdit.Folding { if (fs == null) throw new ArgumentNullException("fs"); - document.VerifyAccess(); fs.IsFolded = false; foldings.Remove(fs); textView.Redraw(fs, DispatcherPriority.Normal); @@ -128,7 +82,9 @@ namespace ICSharpCode.AvalonEdit.Folding foldings.Clear(); textView.Redraw(); } + #endregion + #region Get...Folding /// /// Gets all foldings in this manager. /// The foldings are returned sorted by start offset; @@ -182,5 +138,158 @@ namespace ICSharpCode.AvalonEdit.Folding { return foldings.FindSegmentsContaining(offset); } + #endregion + + #region UpdateFoldings + /// + /// Updates the foldings in this using the given new foldings. + /// This method will try to detect which new foldings correspond to which existing foldings; and will keep the state + /// () for existing foldings. + /// + /// The new set of foldings. These must be sorted by starting offset. + /// The first position of a parse error. Existing foldings starting after + /// this offset will be kept even if they don't appear in . + /// Use -1 for this parameter if there were no parse errors. + public void UpdateFoldings(IEnumerable newFoldings, int firstErrorOffset) + { + if (newFoldings == null) + throw new ArgumentNullException("newFoldings"); + + if (firstErrorOffset < 0) + firstErrorOffset = int.MaxValue; + + var oldFoldings = this.AllFoldings.ToArray(); + int oldFoldingIndex = 0; + int previousStartOffset = 0; + // merge new foldings into old foldings so that sections keep being collapsed + // both oldFoldings and newFoldings are sorted by start offset + foreach (NewFolding newFolding in newFoldings) { + // ensure newFoldings are sorted correctly + if (newFolding.StartOffset < previousStartOffset) + throw new ArgumentException("newFoldings must be sorted by start offset"); + previousStartOffset = newFolding.StartOffset; + + // remove old foldings that were skipped + while (oldFoldingIndex < oldFoldings.Length && newFolding.StartOffset > oldFoldings[oldFoldingIndex].StartOffset) { + this.RemoveFolding(oldFoldings[oldFoldingIndex++]); + } + FoldingSection section; + // reuse current folding if its matching: + if (oldFoldingIndex < oldFoldings.Length && newFolding.StartOffset == oldFoldings[oldFoldingIndex].StartOffset) { + section = oldFoldings[oldFoldingIndex++]; + section.Length = newFolding.EndOffset - newFolding.StartOffset; + } else { + // no matching current folding; create a new one: + section = this.CreateFolding(newFolding.StartOffset, newFolding.EndOffset); + // auto-close #regions only when opening the document + section.IsFolded = newFolding.DefaultClosed; + } + section.Title = newFolding.Name; + } + // remove all outstanding old foldings: + while (oldFoldingIndex < oldFoldings.Length) { + FoldingSection oldSection = oldFoldings[oldFoldingIndex]; + if (oldSection.StartOffset >= firstErrorOffset) + break; + this.RemoveFolding(oldSection); + } + } + #endregion + + #region Install + /// + /// Adds Folding support to the specified text area. + /// Warning: The folding manager is only valid for the text area's current document. The folding manager + /// must be uninstalled before the text area is bound to a different document. + /// + /// The that manages the list of foldings inside the text area. + public static FoldingManager Install(TextArea textArea) + { + if (textArea == null) + throw new ArgumentNullException("textArea"); + return new FoldingManagerInstallation(textArea); + } + + /// + /// Uninstalls the folding manager. + /// + /// The specified manager was not created using . + public static void Uninstall(FoldingManager manager) + { + if (manager == null) + throw new ArgumentNullException("manager"); + FoldingManagerInstallation installation = manager as FoldingManagerInstallation; + if (installation != null) { + installation.Uninstall(); + } else { + throw new ArgumentException("FoldingManager was not created using FoldingManager.Install"); + } + } + + sealed class FoldingManagerInstallation : FoldingManager + { + TextArea textArea; + FoldingMargin margin; + FoldingElementGenerator generator; + + public FoldingManagerInstallation(TextArea textArea) : base(textArea.TextView, textArea.Document) + { + this.textArea = textArea; + margin = new FoldingMargin() { FoldingManager = this }; + generator = new FoldingElementGenerator() { FoldingManager = this }; + textArea.LeftMargins.Add(margin); + textArea.TextView.ElementGenerators.Add(generator); + textArea.Caret.PositionChanged += textArea_Caret_PositionChanged; + } + + /* + void DemoMode() + { + foldingGenerator = new FoldingElementGenerator() { FoldingManager = fm }; + foldingMargin = new FoldingMargin { FoldingManager = fm }; + foldingMarginBorder = new Border { + Child = foldingMargin, + Background = new LinearGradientBrush(Colors.White, Colors.Transparent, 0) + }; + foldingMarginBorder.SizeChanged += UpdateTextViewClip; + textEditor.TextArea.TextView.ElementGenerators.Add(foldingGenerator); + textEditor.TextArea.LeftMargins.Add(foldingMarginBorder); + } + + void UpdateTextViewClip(object sender, SizeChangedEventArgs e) + { + textEditor.TextArea.TextView.Clip = new RectangleGeometry( + new Rect(-foldingMarginBorder.ActualWidth, + 0, + textEditor.TextArea.TextView.ActualWidth + foldingMarginBorder.ActualWidth, + textEditor.TextArea.TextView.ActualHeight)); + } + */ + + public void Uninstall() + { + Clear(); + if (textArea != null) { + textArea.Caret.PositionChanged -= textArea_Caret_PositionChanged; + textArea.LeftMargins.Remove(margin); + textArea.TextView.ElementGenerators.Remove(generator); + margin = null; + generator = null; + textArea = null; + } + } + + void textArea_Caret_PositionChanged(object sender, EventArgs e) + { + // Expand Foldings when Caret is moved into them. + int caretOffset = textArea.Caret.Offset; + foreach (FoldingSection s in GetFoldingsContaining(caretOffset)) { + if (s.IsFolded && s.StartOffset < caretOffset && caretOffset < s.EndOffset) { + s.IsFolded = false; + } + } + } + } + #endregion } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/NewFolding.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/NewFolding.cs new file mode 100644 index 0000000000..371866788f --- /dev/null +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Folding/NewFolding.cs @@ -0,0 +1,67 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Windows; +using System.Windows.Threading; + +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Editing; +using ICSharpCode.AvalonEdit.Rendering; +using ICSharpCode.AvalonEdit.Utils; + +namespace ICSharpCode.AvalonEdit.Folding +{ + /// + /// Helper class used for . + /// + public sealed class NewFolding : ISegment + { + /// + /// Gets the start offset. + /// + public int StartOffset { get; private set; } + + /// + /// Gets the end offset. + /// + public int EndOffset { get; private set; } + + /// + /// Gets/Sets the name displayed for the folding. + /// + public string Name { get; set; } + + /// + /// Gets/Sets whether the folding is closed by default. + /// + public bool DefaultClosed { get; set; } + + /// + /// Creates a new NewFolding instance. + /// + public NewFolding(int start, int end) + { + if (!(start < end)) + throw new ArgumentException("'start' must be less than 'end'"); + this.StartOffset = start; + this.EndOffset = end; + this.Name = null; + this.DefaultClosed = false; + } + + int ISegment.Offset { + get { return this.StartOffset; } + } + + int ISegment.Length { + get { return this.EndOffset - this.StartOffset; } + } + } +} diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj index 276e6c66ba..937c218c46 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj @@ -68,6 +68,9 @@ 3.0 + + 3.0 + 3.0 @@ -135,6 +138,7 @@ + @@ -167,6 +171,7 @@ IReadOnlySectionProvider.cs + diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs index d4f93e6087..95e2ccefcc 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs @@ -636,6 +636,10 @@ namespace ICSharpCode.AvalonEdit.Rendering maxWidth += AdditionalHorizontalScrollAmount; double heightTreeHeight = this.DocumentHeight; + TextEditorOptions options = this.Options; + if (options.AllowScrollBelowDocument) { + heightTreeHeight = Math.Max(heightTreeHeight, Math.Min(heightTreeHeight - 50, scrollOffset.Y) + scrollViewport.Height); + } SetScrollData(availableSize, new Size(maxWidth, heightTreeHeight), diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs index 19fafd4978..0728803351 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs @@ -14,13 +14,13 @@ using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; using System.Windows.Markup; +using System.Windows.Threading; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Rendering; using ICSharpCode.AvalonEdit.Utils; -using System.Windows.Threading; namespace ICSharpCode.AvalonEdit { @@ -353,11 +353,18 @@ namespace ICSharpCode.AvalonEdit static void OnIsReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - TextEditor editor = (TextEditor)d; - if ((bool)e.NewValue) - editor.TextArea.ReadOnlySectionProvider = ReadOnlyDocument.Instance; - else - editor.TextArea.ReadOnlySectionProvider = NoReadOnlySections.Instance; + TextEditor editor = d as TextEditor; + if (editor != null) { + if ((bool)e.NewValue) + editor.TextArea.ReadOnlySectionProvider = ReadOnlyDocument.Instance; + else + editor.TextArea.ReadOnlySectionProvider = NoReadOnlySections.Instance; + + TextEditorAutomationPeer peer = TextEditorAutomationPeer.FromElement(editor) as TextEditorAutomationPeer; + if (peer != null) { + peer.RaiseIsReadOnlyChanged((bool)e.OldValue, (bool)e.NewValue); + } + } } #endregion @@ -922,6 +929,15 @@ namespace ICSharpCode.AvalonEdit return textView.GetPosition(TranslatePoint(point, textView) + textView.ScrollOffset); } + /// + /// Scrolls to the specified line. + /// This method requires that the TextEditor was already assigned a size (WPF layout must have run prior). + /// + public void ScrollToLine(int line) + { + ScrollTo(line, -1); + } + /// /// Scrolls to the specified line/column. /// This method requires that the TextEditor was already assigned a size (WPF layout must have run prior). @@ -930,19 +946,22 @@ namespace ICSharpCode.AvalonEdit { const double MinimumScrollPercentage = 0.3; + ScrollToLine(line); if (scrollViewer != null) { - Point p = textArea.TextView.GetVisualPosition(new TextViewPosition(line, column), VisualYPosition.LineMiddle); + Point p = textArea.TextView.GetVisualPosition(new TextViewPosition(line, Math.Max(1, column)), VisualYPosition.LineMiddle); double verticalPos = p.Y - scrollViewer.ViewportHeight / 2; if (Math.Abs(verticalPos - scrollViewer.VerticalOffset) > MinimumScrollPercentage * scrollViewer.ViewportHeight) { scrollViewer.ScrollToVerticalOffset(Math.Max(0, verticalPos)); } - if (p.X > scrollViewer.ViewportWidth - Caret.MinimumDistanceToViewBorder * 2) { - double horizontalPos = Math.Max(0, p.X - scrollViewer.ViewportWidth / 2); - if (Math.Abs(horizontalPos - scrollViewer.HorizontalOffset) > MinimumScrollPercentage * scrollViewer.ViewportWidth) { - scrollViewer.ScrollToHorizontalOffset(horizontalPos); + if (column > 0) { + if (p.X > scrollViewer.ViewportWidth - Caret.MinimumDistanceToViewBorder * 2) { + double horizontalPos = Math.Max(0, p.X - scrollViewer.ViewportWidth / 2); + if (Math.Abs(horizontalPos - scrollViewer.HorizontalOffset) > MinimumScrollPercentage * scrollViewer.ViewportWidth) { + scrollViewer.ScrollToHorizontalOffset(horizontalPos); + } + } else { + scrollViewer.ScrollToHorizontalOffset(0); } - } else { - scrollViewer.ScrollToHorizontalOffset(0); } } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorAutomationPeer.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorAutomationPeer.cs index 3fe34f027e..b43d591ea4 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorAutomationPeer.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorAutomationPeer.cs @@ -1,17 +1,19 @@ -/* - * Created by SharpDevelop. - * User: Daniel - * Date: 04.06.2009 - * Time: 20:46 - * - * To change this template use Tools | Options | Coding | Edit Standard Headers. - */ +// +// +// +// +// $Revision$ +// using System; +using System.Diagnostics; +using System.Windows.Automation; using System.Windows.Automation.Peers; using System.Windows.Automation.Provider; using System.Windows.Controls; +using ICSharpCode.AvalonEdit.Utils; + namespace ICSharpCode.AvalonEdit { /// @@ -24,6 +26,7 @@ namespace ICSharpCode.AvalonEdit /// public TextEditorAutomationPeer(TextEditor owner) : base(owner) { + Debug.WriteLine("TextEditorAutomationPeer was created"); } private TextEditor TextEditor { @@ -40,7 +43,7 @@ namespace ICSharpCode.AvalonEdit } bool IValueProvider.IsReadOnly { - get { return false; } + get { return this.TextEditor.IsReadOnly; } } /// @@ -57,5 +60,10 @@ namespace ICSharpCode.AvalonEdit return base.GetPattern(patternInterface); } + + internal void RaiseIsReadOnlyChanged(bool oldValue, bool newValue) + { + RaisePropertyChangedEvent(ValuePatternIdentifiers.IsReadOnlyProperty, Boxes.Box(oldValue), Boxes.Box(newValue)); + } } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs index 2e5e14a310..fe6a01bd02 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs @@ -145,7 +145,7 @@ namespace ICSharpCode.AvalonEdit } } } - + bool requireControlModifierForHyperlinkClick = true; /// @@ -247,5 +247,22 @@ namespace ICSharpCode.AvalonEdit } } } + + 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"); + } + } + } } }