// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Drawing; using System.IO; using System.Runtime.InteropServices.ComTypes; using System.Windows.Forms; using Common; using Common.Utilities; using Microsoft.PowerToys.PreviewHandler.Svg.Telemetry.Events; using Microsoft.PowerToys.PreviewHandler.Svg.Utilities; using Microsoft.PowerToys.Telemetry; using PreviewHandlerCommon; namespace Microsoft.PowerToys.PreviewHandler.Svg { /// /// Implementation of Control for Svg Preview Handler. /// public class SvgPreviewControl : FormHandlerControl { /// /// Extended Browser Control to display Svg. /// private WebBrowserExt _browser; /// /// Text box to display the information about blocked elements from Svg. /// private RichTextBox _textBox; /// /// Represent if an text box info bar is added for showing message. /// private bool _infoBarAdded; /// /// Start the preview on the Control. /// /// Stream reference to access source file. public override void DoPreview(T dataSource) { string svgData = null; bool blocked = false; try { using (var stream = new ReadonlyStream(dataSource as IStream)) { using (var reader = new StreamReader(stream)) { svgData = reader.ReadToEnd(); } } blocked = SvgPreviewHandlerHelper.CheckBlockedElements(svgData); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { PreviewError(ex, dataSource); return; } InvokeOnControlThread(() => { try { _infoBarAdded = false; // Add a info bar on top of the Preview if any blocked element is present. if (blocked) { _infoBarAdded = true; AddTextBoxControl(Resource.BlockedElementInfoText); } AddBrowserControl(svgData); Resize += FormResized; base.DoPreview(dataSource); PowerToysTelemetry.Log.WriteEvent(new SvgFilePreviewed()); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { PreviewError(ex, dataSource); } }); } /// /// Occurs when RichtextBox is resized. /// /// Reference to resized control. /// Provides data for the ContentsResized event. private void RTBContentsResized(object sender, ContentsResizedEventArgs e) { var richTextBox = sender as RichTextBox; richTextBox.Height = e.NewRectangle.Height + 5; } /// /// Occurs when form is resized. /// /// Reference to resized control. /// Provides data for the resize event. private void FormResized(object sender, EventArgs e) { if (_infoBarAdded) { _textBox.Width = Width; } } /// /// Adds a Web Browser Control to Control Collection. /// /// Svg to display on Browser Control. private void AddBrowserControl(string svgData) { _browser = new WebBrowserExt(); _browser.DocumentText = svgData; _browser.Dock = DockStyle.Fill; _browser.IsWebBrowserContextMenuEnabled = false; _browser.ScriptErrorsSuppressed = true; _browser.ScrollBarsEnabled = true; _browser.AllowNavigation = false; Controls.Add(_browser); } /// /// Adds a Text Box in Controls for showing information about blocked elements. /// /// Message to be displayed in textbox. private void AddTextBoxControl(string message) { _textBox = new RichTextBox(); _textBox.Text = message; _textBox.BackColor = Color.LightYellow; _textBox.Multiline = true; _textBox.Dock = DockStyle.Top; _textBox.ReadOnly = true; _textBox.ContentsResized += RTBContentsResized; _textBox.ScrollBars = RichTextBoxScrollBars.None; _textBox.BorderStyle = BorderStyle.None; Controls.Add(_textBox); } /// /// Called when an error occurs during preview. /// /// The exception which occurred. /// Stream reference to access source file. private void PreviewError(Exception exception, T dataSource) { PowerToysTelemetry.Log.WriteEvent(new SvgFilePreviewError { Message = exception.Message }); Controls.Clear(); _infoBarAdded = true; AddTextBoxControl(Resource.SvgNotPreviewedError); base.DoPreview(dataSource); } } }