예제 #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 imageUrl;
            double scale;
            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;
                ImageCommentParser.TryParse(matchedText, out imageUrl, out scale, 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 = null;
                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.Scale != scale) // URL same but scale changed
                    {
                        existingImage.Scale = scale;
                    }
                    else if (existingImage.Url != imageUrl) // URL different, so set new source
                    {
                        existingImage.TrySet(imageUrl, scale, out imageLoadingException);
                    }
                }
                else // No existing image, so create new one
                {
                    image = new MyImage(_variableExpander);
                    image.TrySet(imageUrl, scale, out imageLoadingException);
                    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);
                }
            }
        }