internal void Redraw(FoldingSection fs) { foreach (TextView textView in textViews) { textView.Redraw(fs); } }
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; } } } }
/// <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; }
/// <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); } }
/// <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(); }
/// <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); }
/// <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; }
/// <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); } }
/// <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); }
/// <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); }
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; } }
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); }
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); }
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);
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); }
private bool IsAmlFolding(FoldingSection f) { return f.Title.StartsWith("<Item") || f.Title.StartsWith("<Properties ") || f.Title.StartsWith("<Relationships"); }
string GetTooltipTextForCollapsedSection(ToolTipRequestEventArgs args, FoldingSection foldingSection) { return ToolTipUtils.GetAlignedText(args.Editor.Document, foldingSection.StartOffset, foldingSection.EndOffset); }