From 407f3328e8619fb1adeb1d31465e70780ef10f0d Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 27 Mar 2009 19:24:22 +0000 Subject: [PATCH] AvalonEdit: when creating a new TextEditor instance, create a new TextDocument. Fixed bugs when setting Document to null. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3930 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../ICSharpCode.AvalonEdit/Gui/TextArea.cs | 8 +++- .../ICSharpCode.AvalonEdit/Gui/TextEditor.cs | 23 ++++----- .../ICSharpCode.AvalonEdit/Gui/TextView.cs | 47 ++++++++++++------- .../ICSharpCode.AvalonEdit/Utils/ThrowUtil.cs | 5 ++ 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextArea.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextArea.cs index 5a35d7827a..56f2fee901 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextArea.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextArea.cs @@ -632,6 +632,8 @@ namespace ICSharpCode.AvalonEdit internal void RemoveSelectedText() { + if (this.Document == null) + throw ThrowUtil.NoDocumentAssigned(); selection.RemoveSelectedText(this); #if DEBUG if (!selection.IsEmpty) { @@ -646,11 +648,13 @@ namespace ICSharpCode.AvalonEdit { if (newText == null) throw new ArgumentNullException("newText"); - using (Document.RunUpdate()) { + if (this.Document == null) + throw ThrowUtil.NoDocumentAssigned(); + using (this.Document.RunUpdate()) { RemoveSelectedText(); if (newText.Length > 0) { if (ReadOnlySectionProvider.CanInsert(Caret.Offset)) { - Document.Insert(Caret.Offset, newText); + this.Document.Insert(Caret.Offset, newText); } } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditor.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditor.cs index 9776a1e577..0e9b8aefd0 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditor.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditor.cs @@ -43,7 +43,9 @@ namespace ICSharpCode.AvalonEdit /// /// Creates a new TextEditor instance. /// - public TextEditor() : this(new TextArea()) {} + public TextEditor() : this(new TextArea()) + { + } // Forward focus to TextArea. /// @@ -65,6 +67,7 @@ namespace ICSharpCode.AvalonEdit throw new ArgumentNullException("textArea"); this.textArea = textArea; this.Options = textArea.Options; + this.Document = new TextDocument(); textArea.SetBinding(TextArea.DocumentProperty, new Binding("Document") { Source = this }); textArea.SetBinding(TextArea.OptionsProperty, new Binding("Options") { Source = this }); } @@ -184,7 +187,7 @@ namespace ICSharpCode.AvalonEdit set { if (value == null) value = string.Empty; - TextDocument document = GetOrCreateDocument(); + TextDocument document = GetDocument(); document.Text = value; // after replacing the full text, the caret is positioned at the end of the document // - reset it to the beginning. @@ -193,13 +196,11 @@ namespace ICSharpCode.AvalonEdit } } - TextDocument GetOrCreateDocument() + TextDocument GetDocument() { TextDocument document = this.Document; - if (document == null) { - document = new TextDocument(); - this.Document = document; - } + if (document == null) + throw ThrowUtil.NoDocumentAssigned(); return document; } @@ -300,7 +301,7 @@ namespace ICSharpCode.AvalonEdit /// public void AppendText(string textData) { - TextDocument document = GetOrCreateDocument(); + var document = GetDocument(); document.Insert(document.TextLength, textData); } @@ -309,7 +310,7 @@ namespace ICSharpCode.AvalonEdit /// public void BeginChange() { - GetOrCreateDocument().BeginUpdate(); + GetDocument().BeginUpdate(); } /// @@ -334,7 +335,7 @@ namespace ICSharpCode.AvalonEdit /// public IDisposable DeclareChangeBlock() { - return GetOrCreateDocument().RunUpdate(); + return GetDocument().RunUpdate(); } /// @@ -342,7 +343,7 @@ namespace ICSharpCode.AvalonEdit /// public void EndChange() { - GetOrCreateDocument().EndUpdate(); + GetDocument().EndUpdate(); } /// diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextView.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextView.cs index 5872d99201..1c10715287 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextView.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextView.cs @@ -562,28 +562,34 @@ namespace ICSharpCode.AvalonEdit.Gui InvalidateVisual(); // = InvalidateArrange+InvalidateRender textLayer.InvalidateVisual(); - if (document == null) - return Size.Empty; - double maxWidth; - inMeasure = true; - try { - maxWidth = CreateAndMeasureVisualLines(availableSize); - } finally { - inMeasure = false; + if (document == null) { + // no document -> create empty list of lines + allVisualLines = new List(); + visibleVisualLines = allVisualLines.AsReadOnly(); + maxWidth = 0; + } else { + inMeasure = true; + try { + maxWidth = CreateAndMeasureVisualLines(availableSize); + } finally { + inMeasure = false; + } } textLayer.RemoveInlineObjectsNow(); + double heightTreeHeight = this.DocumentHeight; + SetScrollData(availableSize, - new Size(maxWidth, heightTree.TotalHeight), + new Size(maxWidth, heightTreeHeight), scrollOffset); if (VisualLinesChanged != null) VisualLinesChanged(this, EventArgs.Empty); return new Size( canHorizontallyScroll ? Math.Min(availableSize.Width, maxWidth) : maxWidth, - canVerticallyScroll ? Math.Min(availableSize.Height, heightTree.TotalHeight) : heightTree.TotalHeight + canVerticallyScroll ? Math.Min(availableSize.Height, heightTreeHeight) : heightTreeHeight ); } @@ -734,6 +740,10 @@ namespace ICSharpCode.AvalonEdit.Gui /// protected override Size ArrangeOverride(Size finalSize) { + foreach (UIElement layer in layers) { + layer.Arrange(new Rect(new Point(0, 0), finalSize)); + } + if (document == null || allVisualLines.Count == 0) return finalSize; @@ -752,10 +762,6 @@ namespace ICSharpCode.AvalonEdit.Gui // double maxWidth = 0; - foreach (UIElement adorner in layers) { - adorner.Arrange(new Rect(new Point(0, 0), finalSize)); - } - if (visibleVisualLines != null) { Point pos = new Point(-scrollOffset.X, -clippedPixelsOnTop); foreach (VisualLine visualLine in visibleVisualLines) { @@ -1222,7 +1228,7 @@ namespace ICSharpCode.AvalonEdit.Gui { VerifyAccess(); if (this.Document == null) - throw new InvalidOperationException("There is no document assigned to the TextView"); + throw ThrowUtil.NoDocumentAssigned(); DocumentLine documentLine = this.Document.GetLineByNumber(position.Line); VisualLine visualLine = GetOrConstructVisualLine(documentLine); int visualColumn = position.VisualColumn; @@ -1243,7 +1249,7 @@ namespace ICSharpCode.AvalonEdit.Gui { VerifyAccess(); if (this.Document == null) - throw new InvalidOperationException("There is no document assigned to the TextView"); + throw ThrowUtil.NoDocumentAssigned(); VisualLine line = GetVisualLineFromVisualTop(visualPosition.Y); if (line == null) return null; @@ -1425,6 +1431,8 @@ namespace ICSharpCode.AvalonEdit.Gui public CollapsedLineSection CollapseLines(DocumentLine start, DocumentLine end) { VerifyAccess(); + if (heightTree == null) + throw ThrowUtil.NoDocumentAssigned(); return heightTree.CollapseText(start, end); } @@ -1432,7 +1440,10 @@ namespace ICSharpCode.AvalonEdit.Gui /// Gets the height of the document. /// public double DocumentHeight { - get { return heightTree.TotalHeight; } + get { + // return 0 if there is no document = no heightTree + return heightTree != null ? heightTree.TotalHeight : 0; + } } /// @@ -1442,7 +1453,7 @@ namespace ICSharpCode.AvalonEdit.Gui { VerifyAccess(); if (heightTree == null) - throw new InvalidOperationException(); + throw ThrowUtil.NoDocumentAssigned(); return heightTree.GetLineByVisualPosition(visualTop); } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/ThrowUtil.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/ThrowUtil.cs index fd5d22c738..b9d27259ef 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/ThrowUtil.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/ThrowUtil.cs @@ -31,5 +31,10 @@ namespace ICSharpCode.AvalonEdit.Utils throw new ArgumentNullException(parameterName); return val; } + + public static InvalidOperationException NoDocumentAssigned() + { + throw new InvalidOperationException("Document is null"); + } } }