예제 #1
0
        /// <summary>
        /// Scans text line for matching image comment signature, then adds new or updates existing image adornment
        /// </summary>
        private void CreateVisuals(ITextViewLine line, int lineNumber)
        {
#pragma warning disable 219
            bool imageDetected = false; // useful for tracing
#pragma warning restore 219

            string lineText = line.Extent.GetText();
            string matchedText;
            int    matchIndex = ImageCommentParser.Match(_contentTypeName, lineText, out matchedText);
            if (matchIndex >= 0)
            {
                // Get coordinates of text
                int start = line.Extent.Start.Position + matchIndex;
                int end   = line.Start + (line.Extent.Length - 1);
                var span  = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(start, end));

                Exception xmlParseException;
                string    imageUrl;
                double    scale;
                Color     bgColor = new Color();
                ImageCommentParser.TryParse(matchedText, out imageUrl, out scale, ref bgColor, out xmlParseException);

                if (xmlParseException != null)
                {
                    if (Images.ContainsKey(lineNumber))
                    {
                        _layer.RemoveAdornment(Images[lineNumber]);
                        Images.Remove(lineNumber);
                    }

                    _errorTags.Add(new TagSpan <ErrorTag>(span, new ErrorTag("XML parse error", GetErrorMessage(xmlParseException))));

                    return;
                }

                MyImage   image;
                Exception imageLoadingException = null;

                // Check for and update existing image
                MyImage existingImage = Images.ContainsKey(lineNumber) ? Images[lineNumber] : null;
                if (existingImage != null)
                {
                    image = existingImage;
                    if (existingImage.Url != imageUrl || existingImage.BgColor != bgColor) // URL different, so set new source
                    {
                        existingImage.TrySet(imageUrl, scale, bgColor, out imageLoadingException, () => CreateVisuals(line, lineNumber));
                    }
                    else if (existingImage.Url == imageUrl && Math.Abs(existingImage.Scale - scale) > 0.0001)   // URL same but scale changed
                    {
                        existingImage.Scale = scale;
                    }
                }
                else // No existing image, so create new one
                {
                    image = new MyImage(_variableExpander);
                    image.TrySet(imageUrl, scale, bgColor, out imageLoadingException, () => CreateVisuals(line, lineNumber));
                    Images.Add(lineNumber, image);
                }

                // Position image and add as adornment
                if (imageLoadingException == null)
                {
                    Geometry g = _view.TextViewLines.GetMarkerGeometry(span);
                    if (g == null) // Exceptional case when image dimensions are massive (e.g. specifying very large scale factor)
                    {
                        throw new InvalidOperationException("Couldn't get source code line geometry. Is the loaded image massive?");
                    }
                    double textLeft   = g.Bounds.Left;
                    double textBottom = line.TextBottom;
                    Canvas.SetLeft(image, textLeft);
                    Canvas.SetTop(image, textBottom);

                    // Add image to editor view
                    try
                    {
                        _layer.RemoveAdornment(image);
                        _layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, line.Extent, null, image, null);
                    }
                    catch (Exception ex)
                    {
                        // No expected exceptions, so tell user something is wrong.
                        ExceptionHandler.Notify(ex, true);
                    }
                }
                else
                {
                    if (Images.ContainsKey(lineNumber))
                    {
                        Images.Remove(lineNumber);
                    }

                    _errorTags.Add(new TagSpan <ErrorTag>(span, new ErrorTag("Trouble loading image", GetErrorMessage(imageLoadingException))));
                }
                imageDetected = true;
            }
            else
            {
                if (Images.ContainsKey(lineNumber))
                {
                    Images.Remove(lineNumber);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Scans text line for matching image comment signature, then adds new or updates existing image adornment
        /// </summary>
        private void CreateVisuals(ITextViewLine line, int lineNumber, string absFilename)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            var directory = absFilename != null?System.IO.Path.GetDirectoryName(absFilename) : null;

            var lineText   = line.Extent.GetText().Split(new[] { "\r\n", "\r" }, StringSplitOptions.None)[0];
            var matchIndex = ImageCommentParser.Match(_contentTypeName, lineText, out var matchedText);

            if (matchIndex >= 0)
            {
                //lineText = line.Extent.GetText().Split(new string[] { "\r\n", "\r" }, StringSplitOptions.None)[0];
                // Get coordinates of text
                var start = line.Extent.Start.Position + matchIndex;
                var end   = line.Start + (line.Extent.Length - 1);
                var span  = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(start, end));

                ImageCommentParser.TryParse(matchedText, out var parsedImgData, out var parsingError);

                if (parsingError != null)
                {
                    if (Images.ContainsKey(lineNumber))
                    {
                        _layer.RemoveAdornment(Images[lineNumber]);
                        Images.Remove(lineNumber);
                    }

                    _errorTags.Add(new TagSpan <ErrorTag>(span,
                                                          new ErrorTag("XML parse error", $"Problem with comment format: {parsingError}")));

                    return;
                }

                string loadingMessage = null;

                // Check for and update existing image
                CommentImage image = Images.ContainsKey(lineNumber) ? Images[lineNumber] : null;
                if (image != null)
                {
                    if (!image.Attributes.IsEqual(parsedImgData))
                    {
                        image.TrySet(directory, parsedImgData, out loadingMessage, () => CreateVisuals(line, lineNumber, absFilename));
                    }
                }
                else // No existing image, so create new one
                {
                    image = new CommentImage(_variableExpander);
                    image.TrySet(directory, parsedImgData, out loadingMessage, () => CreateVisuals(line, lineNumber, absFilename));
                    Images.Add(lineNumber, image);
                }

                // Position image and add as adornment
                if (loadingMessage == null && image.Source != null)
                {
                    var geometry = _view.TextViewLines.GetMarkerGeometry(span);
                    if (geometry == null) // Exceptional case when image dimensions are massive (e.g. specifying very large scale factor)
                    {
                        throw new InvalidOperationException("Couldn't get source code line geometry. Is the loaded image massive?");
                    }
                    var textLeft   = geometry.Bounds.Left;
                    var textBottom = line.TextBottom;
                    Canvas.SetLeft(image, textLeft);
                    Canvas.SetTop(image, textBottom);

                    // Add image to editor view
                    try
                    {
                        _layer.RemoveAdornment(image);
                        _layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, line.Extent, null, image, null);
                    }
                    catch (Exception ex)
                    {
                        // No expected exceptions, so tell user something is wrong.
                        ExceptionHandler.Notify(ex, true);
                    }
                }
                else
                {
                    if (Images.ContainsKey(lineNumber))
                    {
                        Images.Remove(lineNumber);
                    }

                    _errorTags.Add(new TagSpan <ErrorTag>(span, loadingMessage == null ?
                                                          new ErrorTag("No image set", "No image set") :
                                                          new ErrorTag("Trouble loading image", loadingMessage)));
                }
            }
            else
            {
                if (Images.ContainsKey(lineNumber))
                {
                    Images.Remove(lineNumber);
                }
            }
        }
        /// <summary>
        /// Scans text line for matching image comment signature, then adds new or updates existing image adornment
        /// </summary>
        private void CreateVisuals(ITextViewLine line, int lineNumber)
        {
#pragma warning disable 219
            bool imageDetected = false; // useful for tracing
#pragma warning restore 219

            string lineText = line.Extent.GetText();
            string matchedText;
            int    matchIndex = ImageCommentParser.Match(_contentTypeName, lineText, out matchedText);
            if (matchIndex >= 0)
            {
                // Get coordinates of text
                int start = line.Extent.Start.Position + matchIndex;
                int end   = line.Start + (line.Extent.Length - 1);
                var span  = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(start, end));

                Exception xmlParseException;
                string    imageUrl;
                double    scale;
                Color     bgColor = new Color();
                ImageCommentParser.TryParse(matchedText, out imageUrl, out scale, ref bgColor, out xmlParseException);

                if (xmlParseException != null)
                {
                    if (Images.ContainsKey(lineNumber))
                    {
                        _layer.RemoveAdornment(Images[lineNumber]);
                        Images.Remove(lineNumber);
                    }

                    _errorTags.Add(new TagSpan <ErrorTag>(span, new ErrorTag("XML parse error", GetErrorMessage(xmlParseException))));

                    return;
                }

                MyImage   image;
                Exception imageLoadingException = null;

                // Check for and update existing image
                MyImage existingImage = Images.ContainsKey(lineNumber) ? Images[lineNumber] : null;
                if (existingImage != null)
                {
                    image = existingImage;
                    if (existingImage.Url != imageUrl) // URL different, so set new source
                    {
                        existingImage.TrySet(imageUrl, scale, bgColor, out imageLoadingException, () => CreateVisuals(line, lineNumber));
                        if (image.BgColor != null)
                        {
                            image.BgColor.R = 254;
                        }
                    }
                }
                else // No existing image, so create new one
                {
                    image = new MyImage(_variableExpander);
                    image.TrySet(imageUrl, scale, bgColor, out imageLoadingException, () => CreateVisuals(line, lineNumber));
                    if (image.BgColor != null)
                    {
                        image.BgColor.R = 254;
                    }

                    Images.Add(lineNumber, image);
                }

                // Position image and add as adornment
                if (imageLoadingException == null)
                {
                    try
                    {
                        _layer.RemoveAdornment(image);
                    }
                    catch (Exception ex)
                    {
                        // No expected exceptions, so tell user something is wrong.
                        ExceptionHandler.Notify(ex, true);
                    }

                    if ((image.Source as BitmapFrame)?.IsDownloading ?? false)
                    {
                        (image.Source as BitmapFrame).DownloadCompleted += (x, y) =>
                        {
                            if (x == image.Source)
                            {
                                ShowDownloadedImage(line, span, bgColor, image);
                            }
                        };
                    }
                    else
                    {
                        ShowDownloadedImage(line, span, bgColor, image);
                    }
                }
                else
                {
                    if (Images.ContainsKey(lineNumber))
                    {
                        Images.Remove(lineNumber);
                    }

                    _errorTags.Add(new TagSpan <ErrorTag>(span, new ErrorTag("Trouble loading image", GetErrorMessage(imageLoadingException))));
                }
                imageDetected = true;
            }
            else
            {
                if (Images.ContainsKey(lineNumber))
                {
                    Images.Remove(lineNumber);
                }
            }
        }