示例#1
0
 public HeightTree(TextDocument document, double defaultLineHeight)
 {
     this.document = document;
     weakLineTracker = WeakLineTracker.Register(document, this);
     this.DefaultLineHeight = defaultLineHeight;
     RebuildDocument();
 }
示例#2
0
 internal DocumentLine(TextDocument document)
 {
     #if DEBUG
     Debug.Assert(document != null);
     this.document = document;
     #endif
 }
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, XmlReader reader, out int firstErrorOffset)
        {
            Stack<XmlFoldStart> stack = new Stack<XmlFoldStart>();
            List<NewFolding> foldMarkers = new List<NewFolding>();
            try {
                while (reader.Read()) {
                    switch (reader.NodeType) {
                        case XmlNodeType.Element:
                            if (!reader.IsEmptyElement) {
                                XmlFoldStart newFoldStart = CreateElementFoldStart(document, reader);
                                stack.Push(newFoldStart);
                            }
                            break;

                        case XmlNodeType.EndElement:
                            XmlFoldStart foldStart = stack.Pop();
                            CreateElementFold(document, foldMarkers, reader, foldStart);
                            break;

                        case XmlNodeType.Comment:
                            CreateCommentFold(document, foldMarkers, reader);
                            break;
                    }
                }
                firstErrorOffset = -1;
            } catch (XmlException ex) {
                // ignore errors at invalid positions (prevent ArgumentOutOfRangeException)
                if (ex.LineNumber >= 1 && ex.LineNumber <= document.LineCount)
                    firstErrorOffset = document.GetOffset(ex.LineNumber, ex.LinePosition);
                else
                    firstErrorOffset = 0;
            }
            foldMarkers.Sort((a,b) => a.StartOffset.CompareTo(b.StartOffset));
            return foldMarkers;
        }
示例#4
0
        /// <summary>
        /// Creates a HTML fragment from a part of a document.
        /// </summary>
        /// <param name="document">The document to create HTML from.</param>
        /// <param name="highlighter">The highlighter used to highlight the document. <c>null</c> is valid and will create HTML without any highlighting.</param>
        /// <param name="segment">The part of the document to create HTML for. You can pass <c>null</c> to create HTML for the whole document.</param>
        /// <param name="options">The options for the HTML creation.</param>
        /// <returns>HTML code for the document part.</returns>
        public static string CreateHtmlFragment(TextDocument document, IHighlighter highlighter, ISegment segment, HtmlOptions options)
        {
            if (document == null)
                throw new ArgumentNullException("document");
            if (options == null)
                throw new ArgumentNullException("options");
            if (highlighter != null && highlighter.Document != document)
                throw new ArgumentException("Highlighter does not belong to the specified document.");
            if (segment == null)
                segment = new SimpleSegment(0, document.TextLength);

            StringBuilder html = new StringBuilder();
            int segmentEndOffset = segment.EndOffset;
            DocumentLine line = document.GetLineByOffset(segment.Offset);
            while (line != null && line.Offset < segmentEndOffset) {
                HighlightedLine highlightedLine;
                if (highlighter != null)
                    highlightedLine = highlighter.HighlightLine(line.LineNumber);
                else
                    highlightedLine = new HighlightedLine(document, line);
                SimpleSegment s = segment.GetOverlap(line);
                if (html.Length > 0)
                    html.AppendLine("<br>");
                html.Append(highlightedLine.ToHtml(s.Offset, s.EndOffset, options));
                line = line.NextLine;
            }
            return html.ToString();
        }
示例#5
0
 /// <summary>
 /// Deregisters the weak line tracker.
 /// </summary>
 public void Deregister()
 {
     if (textDocument != null) {
         textDocument.LineTrackers.Remove(this);
         textDocument = null;
     }
 }
示例#6
0
 /// <summary>
 /// Creates a new TextDocumentAccessor.
 /// </summary>
 public TextDocumentAccessor(TextDocument document)
 {
     if (document == null)
         throw new ArgumentNullException("document");
     doc = document;
     this.minLine = 1;
     this.maxLine = doc.LineCount;
 }
示例#7
0
 /// <summary>
 /// Creates a new FoldingManager instance.
 /// </summary>
 public FoldingManager(TextDocument document)
 {
     if (document == null)
         throw new ArgumentNullException("document");
     this.document = document;
     this.foldings = new TextSegmentCollection<FoldingSection>();
     document.VerifyAccess();
     TextDocumentWeakEventManager.Changed.AddListener(document, this);
 }
示例#8
0
 /// <summary>
 /// Registers the <paramref name="targetTracker"/> as line tracker for the <paramref name="textDocument"/>.
 /// A weak reference to the target tracker will be used, and the WeakLineTracker will deregister itself
 /// when the target tracker is garbage collected.
 /// </summary>
 public static WeakLineTracker Register(TextDocument textDocument, ILineTracker targetTracker)
 {
     if (textDocument == null)
         throw new ArgumentNullException("textDocument");
     if (targetTracker == null)
         throw new ArgumentNullException("targetTracker");
     WeakLineTracker wlt = new WeakLineTracker(textDocument, targetTracker);
     textDocument.LineTrackers.Add(wlt);
     return wlt;
 }
 /// <summary>
 /// Create <see cref="NewFolding"/>s for the specified document.
 /// </summary>
 public override IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset)
 {
     try {
         XmlTextReader reader = new XmlTextReader(document.CreateReader());
         reader.XmlResolver = null; // don't resolve DTDs
         return CreateNewFoldings(document, reader, out firstErrorOffset);
     } catch (XmlException) {
         firstErrorOffset = 0;
         return Enumerable.Empty<NewFolding>();
     }
 }
示例#10
0
 /// <summary>
 /// Creates a new DocumentHighlighter instance.
 /// </summary>
 public DocumentHighlighter(TextDocument document, HighlightingRuleSet baseRuleSet)
 {
     if (document == null)
         throw new ArgumentNullException("document");
     if (baseRuleSet == null)
         throw new ArgumentNullException("baseRuleSet");
     this.document = document;
     this.baseRuleSet = baseRuleSet;
     WeakLineTracker.Register(document, this);
     InvalidateHighlighting();
 }
示例#11
0
 /// <inheritdoc/>
 protected override void OnDocumentChanged(TextDocument oldDocument, TextDocument newDocument)
 {
     if (oldDocument != null) {
         PropertyChangedEventManager.RemoveListener(oldDocument, this, "LineCount");
     }
     base.OnDocumentChanged(oldDocument, newDocument);
     if (newDocument != null) {
         PropertyChangedEventManager.AddListener(newDocument, this, "LineCount");
     }
     OnDocumentLineCountChanged();
 }
        /// <inheritdoc cref="IIndentationStrategy.IndentLine"/>
        public override void IndentLine(TextDocument document, DocumentLine line)
        {
            int lineNr = line.LineNumber;
            TextDocumentAccessor acc = new TextDocumentAccessor(document, lineNr, lineNr);
            Indent(acc, false);

            string t = acc.Text;
            if (t.Length == 0) {
                // use AutoIndentation for new lines in comments / verbatim strings.
                base.IndentLine(document, line);
            }
        }
 /// <inheritdoc/>
 public virtual void IndentLine(TextDocument document, DocumentLine line)
 {
     if (document == null)
         throw new ArgumentNullException("document");
     if (line == null)
         throw new ArgumentNullException("line");
     DocumentLine previousLine = line.PreviousLine;
     if (previousLine != null) {
         ISegment indentationSegment = TextUtilities.GetWhitespaceAfter(document, previousLine.Offset);
         string indentation = document.GetText(indentationSegment);
         // copy indentation to line
         indentationSegment = TextUtilities.GetWhitespaceAfter(document, line.Offset);
         document.Replace(indentationSegment, indentation);
     }
 }
 /// <inheritdoc cref="IIndentationStrategy.IndentLines"/>
 public override void IndentLines(TextDocument document, int beginLine, int endLine)
 {
     Indent(new TextDocumentAccessor(document, beginLine, endLine), true);
 }
示例#15
0
 /// <summary>
 /// Gets the newline sequence used in the document at the specified line.
 /// </summary>
 public static string GetNewLineFromDocument(TextDocument document, int lineNumber)
 {
     DocumentLine line = document.GetLineByNumber(lineNumber);
     if (line.DelimiterLength == 0) {
         // at the end of the document, there's no line delimiter, so use the delimiter
         // from the previous line
         line = line.PreviousLine;
         if (line == null)
             return Environment.NewLine;
     }
     return document.GetText(line.Offset + line.Length, line.DelimiterLength);
 }
示例#16
0
 void OnDocumentChanged(TextDocument oldValue, TextDocument newValue)
 {
     if (oldValue != null) {
         TextDocumentWeakEventManager.Changing.RemoveListener(oldValue, this);
         TextDocumentWeakEventManager.Changed.RemoveListener(oldValue, this);
         TextDocumentWeakEventManager.UpdateStarted.RemoveListener(oldValue, this);
         TextDocumentWeakEventManager.UpdateFinished.RemoveListener(oldValue, this);
     }
     textView.Document = newValue;
     if (newValue != null) {
         TextDocumentWeakEventManager.Changing.AddListener(newValue, this);
         TextDocumentWeakEventManager.Changed.AddListener(newValue, this);
         TextDocumentWeakEventManager.UpdateStarted.AddListener(newValue, this);
         TextDocumentWeakEventManager.UpdateFinished.AddListener(newValue, this);
     }
     // Reset caret location and selection: this is necessary because the caret/selection might be invalid
     // in the new document (e.g. if new document is shorter than the old document).
     caret.Location = new TextLocation(1, 1);
     this.ClearSelection();
     if (DocumentChanged != null)
         DocumentChanged(this, EventArgs.Empty);
     CommandManager.InvalidateRequerySuggested();
 }
示例#17
0
 static int GetOffset(TextDocument document, XmlReader reader)
 {
     IXmlLineInfo info = reader as IXmlLineInfo;
     if (info != null && info.HasLineInfo()) {
         return document.GetOffset(info.LineNumber, info.LinePosition);
     } else {
         throw new ArgumentException("XmlReader does not have positioning information.");
     }
 }
示例#18
0
 void textArea_DocumentChanged(object sender, EventArgs e)
 {
     if (currentDocument != null)
         currentDocument.TextChanged -= textArea_Document_TextChanged;
     currentDocument = textArea.Document;
     if (currentDocument != null) {
         currentDocument.TextChanged += textArea_Document_TextChanged;
         DoSearch(false);
     }
 }
 public DocumentChangeOperation(TextDocument document, DocumentChangeEventArgs change)
 {
     this.document = document;
     this.change = change;
 }
 /// <summary>
 /// Creates the IHighlighter instance for the specified text document.
 /// </summary>
 protected virtual IHighlighter CreateHighlighter(TextView textView, TextDocument document)
 {
     return new TextViewDocumentHighlighter(this, textView, document, ruleSet);
 }
示例#21
0
        /// <summary>
        /// Creates an XmlFoldStart for the start tag of an element.
        /// </summary>
        XmlFoldStart CreateElementFoldStart(TextDocument document, XmlReader reader)
        {
            // Take off 1 from the offset returned
            // from the xml since it points to the start
            // of the element name and not the beginning
            // tag.
            //XmlFoldStart newFoldStart = new XmlFoldStart(reader.Prefix, reader.LocalName, reader.LineNumber - 1, reader.LinePosition - 2);
            XmlFoldStart newFoldStart = new XmlFoldStart();

            IXmlLineInfo lineInfo = (IXmlLineInfo)reader;
            newFoldStart.StartLine = lineInfo.LineNumber;
            newFoldStart.StartOffset = document.GetOffset(newFoldStart.StartLine, lineInfo.LinePosition - 1);

            if (this.ShowAttributesWhenFolded && reader.HasAttributes) {
                newFoldStart.Name = String.Concat("<", reader.Name, " ", GetAttributeFoldText(reader), ">");
            } else {
                newFoldStart.Name = String.Concat("<", reader.Name, ">");
            }

            return newFoldStart;
        }
示例#22
0
 private WeakLineTracker(TextDocument textDocument, ILineTracker targetTracker)
 {
     this.textDocument = textDocument;
     this.targetObject = new WeakReference(targetTracker);
 }
示例#23
0
        /// <summary>
        /// Creates a comment fold if the comment spans more than one line.
        /// </summary>
        /// <remarks>The text displayed when the comment is folded is the first
        /// line of the comment.</remarks>
        static void CreateCommentFold(TextDocument document, List<NewFolding> foldMarkers, XmlReader reader)
        {
            string comment = reader.Value;
            if (comment != null) {
                int firstNewLine = comment.IndexOf('\n');
                if (firstNewLine >= 0) {

                    // Take off 4 chars to get the actual comment start (takes
                    // into account the <!-- chars.

                    int startOffset = GetOffset(document, reader) - 4;
                    int endOffset = startOffset + comment.Length + 7;

                    string foldText = String.Concat("<!--", comment.Substring(0, firstNewLine).TrimEnd('\r') , "-->");
                    foldMarkers.Add(new NewFolding(startOffset, endOffset) { Name = foldText } );
                }
            }
        }
 /// <summary>
 /// Does nothing: indenting multiple lines is useless without a smart indentation strategy.
 /// </summary>
 public virtual void IndentLines(TextDocument document, int beginLine, int endLine)
 {
 }
 public TextViewDocumentHighlighter(HighlightingColorizer colorizer, TextView textView, TextDocument document, HighlightingRuleSet baseRuleSet)
     : base(document, baseRuleSet)
 {
     Debug.Assert(colorizer != null);
     Debug.Assert(textView != null);
     this.colorizer = colorizer;
     this.textView = textView;
 }
示例#26
0
 /// <summary>
 /// Called when the <see cref="Document"/> is changing.
 /// </summary>
 protected virtual void OnDocumentChanged(TextDocument oldDocument, TextDocument newDocument)
 {
     document = newDocument;
 }
示例#27
0
        /// <summary>
        /// Attaches this SearchPanel to a TextArea instance.
        /// </summary>
        public void Attach(TextArea textArea)
        {
            if (textArea == null)
                throw new ArgumentNullException("textArea");
            this.textArea = textArea;
            adorner = new SearchPanelAdorner(textArea, this);
            DataContext = this;

            renderer = new SearchResultBackgroundRenderer();
            currentDocument = textArea.Document;
            if (currentDocument != null)
                currentDocument.TextChanged += textArea_Document_TextChanged;
            textArea.DocumentChanged += textArea_DocumentChanged;
            KeyDown += SearchLayerKeyDown;

            this.CommandBindings.Add(new CommandBinding(SearchCommands.FindNext, (sender, e) => FindNext()));
            this.CommandBindings.Add(new CommandBinding(SearchCommands.FindPrevious, (sender, e) => FindPrevious()));
            this.CommandBindings.Add(new CommandBinding(SearchCommands.CloseSearchPanel, (sender, e) => Close()));
            IsClosed = true;
        }
示例#28
0
 public FoldingManager(TextView textView, TextDocument document)
     : this(document)
 {
 }
 /// <summary>
 /// Creates a change tracking checkpoint for the specified document.
 /// This method is thread-safe.
 /// If you need a ChangeTrackingCheckpoint that's consistent with a snapshot of the document,
 /// use <see cref="TextDocument.CreateSnapshot(out ChangeTrackingCheckpoint)"/>.
 /// </summary>
 public static ChangeTrackingCheckpoint Create(TextDocument document)
 {
     if (document == null)
         throw new ArgumentNullException("document");
     return document.CreateChangeTrackingCheckpoint();
 }
示例#30
0
 /// <summary>
 /// Create an element fold if the start and end tag are on
 /// different lines.
 /// </summary>
 static void CreateElementFold(TextDocument document, List<NewFolding> foldMarkers, XmlReader reader, XmlFoldStart foldStart)
 {
     IXmlLineInfo lineInfo = (IXmlLineInfo)reader;
     int endLine = lineInfo.LineNumber;
     if (endLine > foldStart.StartLine) {
         int endCol = lineInfo.LinePosition + reader.Name.Length + 1;
         foldStart.EndOffset = document.GetOffset(endLine, endCol);
         foldMarkers.Add(foldStart);
     }
 }