A section that can be folded.
Inheritance: ICSharpCode.AvalonEdit.Document.TextSegment
Esempio n. 1
0
 internal void Redraw(FoldingSection fs)
 {
     foreach (TextView textView in textViews)
     {
         textView.Redraw(fs);
     }
 }
Esempio n. 2
0
        void TextViewVisualLinesChanged(object sender, EventArgs e)
        {
            foreach (FoldingMarginMarker m in markers)
            {
                RemoveVisualChild(m);
            }
            markers.Clear();
            InvalidateVisual();
            if (TextView != null && FoldingManager != null && TextView.VisualLinesValid)
            {
                foreach (VisualLine line in TextView.VisualLines)
                {
                    FoldingSection fs = FoldingManager.GetNextFolding(line.FirstDocumentLine.Offset);
                    if (fs == null)
                    {
                        continue;
                    }
                    if (fs.StartOffset <= line.LastDocumentLine.Offset + line.LastDocumentLine.Length)
                    {
                        FoldingMarginMarker m = new FoldingMarginMarker {
                            IsExpanded     = !fs.IsFolded,
                            VisualLine     = line,
                            FoldingSection = fs
                        };
                        markers.Add(m);
                        AddVisualChild(m);

                        m.IsMouseDirectlyOverChanged += delegate { InvalidateVisual(); };

                        InvalidateMeasure();
                        continue;
                    }
                }
            }
        }
Esempio n. 3
0
		/// <summary>
		/// Gets the first offset greater or equal to <paramref name="startOffset"/> where a folded folding starts.
		/// Returns -1 if there are no foldings after <paramref name="startOffset"/>.
		/// </summary>
		public int GetNextFoldedFoldingStart(int startOffset)
		{
			FoldingSection fs = foldings.FindFirstSegmentWithStartAfter(startOffset);
			while (fs != null && !fs.IsFolded)
				fs = foldings.GetNextSegment(fs);
			return fs != null ? fs.StartOffset : -1;
		}
Esempio n. 4
0
		/// <summary>
		/// Removes a folding section from this manager.
		/// </summary>
		public void RemoveFolding(FoldingSection fs)
		{
			if (fs == null)
				throw new ArgumentNullException("fs");
			fs.IsFolded = false;
			foldings.Remove(fs);
			Redraw(fs);
		}
        /// <inheritdoc/>
        public override VisualLineElement ConstructElement(int offset)
        {
            if (foldingManager == null)
            {
                return(null);
            }
            int            foldedUntil    = -1;
            FoldingSection foldingSection = null;

            foreach (FoldingSection fs in foldingManager.GetFoldingsContaining(offset))
            {
                if (fs.IsFolded)
                {
                    if (fs.EndOffset > foldedUntil)
                    {
                        foldedUntil    = fs.EndOffset;
                        foldingSection = fs;
                    }
                }
            }
            if (foldedUntil > offset && foldingSection != null)
            {
                // Handle overlapping foldings: if there's another folded folding
                // (starting within the foldingSection) that continues after the end of the folded section,
                // then we'll extend our fold element to cover that overlapping folding.
                bool foundOverlappingFolding;
                do
                {
                    foundOverlappingFolding = false;
                    foreach (FoldingSection fs in FoldingManager.GetFoldingsContaining(foldedUntil))
                    {
                        if (fs.IsFolded && fs.EndOffset > foldedUntil)
                        {
                            foldedUntil             = fs.EndOffset;
                            foundOverlappingFolding = true;
                        }
                    }
                } while (foundOverlappingFolding);

                string title = foldingSection.Title;
                if (string.IsNullOrEmpty(title))
                {
                    title = "...";
                }
                var p = new VisualLineElementTextRunProperties(CurrentContext.GlobalTextRunProperties);
                p.SetForegroundBrush(textBrush);
                var textFormatter = TextFormatterFactory.Create(CurrentContext.TextView);
                var text          = FormattedTextElement.PrepareText(textFormatter, title, p);
                return(new FoldingLineElement(foldingSection, text, foldedUntil - offset)
                {
                    textBrush = textBrush
                });
            }
            else
            {
                return(null);
            }
        }
Esempio n. 6
0
		/// <summary>
		/// Gets all foldings that start exactly at <paramref name="startOffset"/>.
		/// </summary>
		public ReadOnlyCollection<FoldingSection> GetFoldingsAt(int startOffset)
		{
			List<FoldingSection> result = new List<FoldingSection>();
			FoldingSection fs = foldings.FindFirstSegmentWithStartAfter(startOffset);
			while (fs != null && fs.StartOffset == startOffset) {
				result.Add(fs);
				fs = foldings.GetNextSegment(fs);
			}
			return result.AsReadOnly();
		}
Esempio n. 7
0
 /// <summary>
 /// Removes a folding section from this manager.
 /// </summary>
 public void RemoveFolding(FoldingSection fs)
 {
     if (fs == null)
     {
         throw new ArgumentNullException("fs");
     }
     fs.IsFolded = false;
     foldings.Remove(fs);
     textView.Redraw(fs, DispatcherPriority.Normal);
 }
Esempio n. 8
0
		/// <summary>
		/// Creates a folding for the specified text section.
		/// </summary>
		public FoldingSection CreateFolding(int startOffset, int endOffset)
		{
			if (startOffset >= endOffset)
				throw new ArgumentException("startOffset must be less than endOffset");
			if (startOffset < 0 || endOffset > document.TextLength)
				throw new ArgumentException("Folding must be within document boundary");
			FoldingSection fs = new FoldingSection(this, startOffset, endOffset);
			foldings.Add(fs);
			Redraw(fs);
			return fs;
		}
Esempio n. 9
0
		/// <summary>
		/// Updates the foldings in this <see cref="FoldingManager"/> using the given new foldings.
		/// This method will try to detect which new foldings correspond to which existing foldings; and will keep the state
		/// (<see cref="FoldingSection.IsFolded"/>) for existing foldings.
		/// </summary>
		/// <param name="newFoldings">The new set of foldings. These must be sorted by starting offset.</param>
		/// <param name="firstErrorOffset">The first position of a parse error. Existing foldings starting after
		/// this offset will be kept even if they don't appear in <paramref name="newFoldings"/>.
		/// Use -1 for this parameter if there were no parse errors.</param>
		public void UpdateFoldings(IEnumerable<NewFolding> 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;
				
				int startOffset = newFolding.StartOffset.CoerceValue(0, document.TextLength);
				int endOffset = newFolding.EndOffset.CoerceValue(0, document.TextLength);
				
				if (newFolding.StartOffset == newFolding.EndOffset)
					continue; // ignore zero-length foldings
				
				// 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
					if (isFirstUpdate) {
						section.IsFolded = newFolding.DefaultClosed;
						isFirstUpdate = false;
					}
					section.Tag = newFolding;
				}
				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);
			}
		}
Esempio n. 10
0
        /// <summary>
        /// Creates a folding for the specified text section.
        /// </summary>
        public FoldingSection CreateFolding(int startOffset, int endOffset)
        {
            if (startOffset >= endOffset)
            {
                throw new ArgumentException("startOffset must be less than endOffset");
            }
            FoldingSection fs = new FoldingSection(this, startOffset, endOffset);

            foldings.Add(fs);
            Redraw(fs);
            return(fs);
        }
Esempio n. 11
0
        /// <summary>
        /// Creates a folding for the specified text section.
        /// </summary>
        public FoldingSection CreateFolding(int startOffset, int endOffset)
        {
            if (startOffset >= endOffset)
            {
                throw new ArgumentException("startOffset must be less than endOffset");
            }
            FoldingSection fs = new FoldingSection(this, startOffset, endOffset);

            foldings.Add(fs);
            textView.Redraw(fs, DispatcherPriority.Normal);
            return(fs);
        }
Esempio n. 12
0
        void OnDocumentChanged(DocumentChangeEventArgs e)
        {
            foldings.UpdateOffsets(e);
            FoldingSection s = foldings.FindFirstSegmentWithStartAfter(e.Offset);

            while (s != null && s.StartOffset == e.Offset)
            {
                FoldingSection next = foldings.GetNextSegment(s);
                if (s.Length == 0)
                {
                    RemoveFolding(s);
                }
                s = next;
            }
        }
Esempio n. 13
0
 internal override string FoldTitle(FoldingSection section, TextDocument doc)
 {
     if (doc == null)
     {
         throw new ArgumentNullException("doc");
     }
     var array = Regex.Split(section.Title, "æ");
     var offset = section.StartOffset + array[0].Length;
     var length = section.Length - array[0].Length;
     return doc.GetText(offset, length);
 }
Esempio n. 14
0
 internal override string FoldTitle(FoldingSection section, TextDocument doc)
 {
     var array = Regex.Split(section.Title, "æ");
     var text = section.TextContent.ToLower().Trim();
     var text2 = section.TextContent.Trim();
     var num = section.TextContent.Trim().IndexOf("%{PE}%", StringComparison.Ordinal) - "%{PE}%".Length;
     var num2 = section.TextContent.Trim().IndexOf("\r\n", StringComparison.Ordinal);
     var num3 = section.StartOffset + array[0].Length;
     text2 = text2.Substring(text.IndexOf(array[0], StringComparison.Ordinal) + array[0].Length);
     var num4 = text2.Length - array[0].Length;
     if (num > -1)
     {
         num4 = ((num < num2) ? num : num4);
     }
     return text2.Substring(0, num4);
 }
Esempio n. 15
0
 public FoldingLineElement(FoldingSection fs, TextLine text, int documentLength) : base(text, documentLength)
 {
     this.fs = fs;
 }
		string GetTooltipTextForCollapsedSection(ToolTipRequestEventArgs args, FoldingSection foldingSection)
		{
			// This fixes SD-1394:
			// Each line is checked for leading indentation whitespaces. If
			// a line has the same or more indentation than the first line,
			// it is reduced. If a line is less indented than the first line
			// the indentation is removed completely.
			//
			// See the following example:
			// 	line 1
			// 		line 2
			// 			line 3
			//  line 4
			//
			// is reduced to:
			// line 1
			// 	line 2
			// 		line 3
			// line 4
			
			const int maxLineCount = 15;
			
			TextDocument document = (TextDocument)args.Editor.Document;
			int startOffset = foldingSection.StartOffset;
			int endOffset = foldingSection.EndOffset;
			
			DocumentLine startLine = document.GetLineByOffset(startOffset);
			DocumentLine endLine = document.GetLineByOffset(endOffset);
			StringBuilder builder = new StringBuilder();
			
			DocumentLine current = startLine;
			ISegment startIndent = TextUtilities.GetLeadingWhitespace(document, startLine);
			int lineCount = 0;
			while (current != endLine.NextLine && lineCount < maxLineCount) {
				ISegment currentIndent = TextUtilities.GetLeadingWhitespace(document, current);
				
				if (current == startLine && current == endLine)
					builder.Append(document.GetText(startOffset, endOffset - startOffset));
				else if (current == startLine) {
					if (current.EndOffset - startOffset > 0)
						builder.AppendLine(document.GetText(startOffset, current.EndOffset - startOffset).TrimStart());
				} else if (current == endLine) {
					if (startIndent.Length <= currentIndent.Length)
						builder.Append(document.GetText(current.Offset + startIndent.Length, endOffset - current.Offset - startIndent.Length));
					else
						builder.Append(document.GetText(current.Offset + currentIndent.Length, endOffset - current.Offset - currentIndent.Length));
				} else {
					if (startIndent.Length <= currentIndent.Length)
						builder.AppendLine(document.GetText(current.Offset + startIndent.Length, current.Length - startIndent.Length));
					else
						builder.AppendLine(document.GetText(current.Offset + currentIndent.Length, current.Length - currentIndent.Length));
				}
				
				current = current.NextLine;
				lineCount++;
			}
			if (current != endLine.NextLine)
				builder.Append("...");
			
			return builder.ToString();
		}
 internal abstract string FoldTitle(FoldingSection section, TextDocument doc);
Esempio n. 18
0
 internal override string FoldTitle(FoldingSection section, TextDocument doc)
 {
     var array = Regex.Split(section.Title, "æ");
     var offset = section.StartOffset + array[0].Length;
     var length = section.Length - (array[0].Length + array[1].Length);
     return doc.GetText(offset, length);
 }
Esempio n. 19
0
 private bool IsAmlFolding(FoldingSection f)
 {
   return f.Title.StartsWith("<Item") || f.Title.StartsWith("<Properties ") || f.Title.StartsWith("<Relationships");
 }
Esempio n. 20
0
			public FoldingLineElement(FoldingSection fs, TextLine text, int documentLength) : base(text, documentLength)
			{
				this.fs = fs;
			}
		string GetTooltipTextForCollapsedSection(ToolTipRequestEventArgs args, FoldingSection foldingSection)
		{
			return ToolTipUtils.GetAlignedText(args.Editor.Document, foldingSection.StartOffset, foldingSection.EndOffset);
		}