QoiPreviewHandlerControl.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using Common; 6 using Microsoft.PowerToys.FilePreviewCommon; 7 using Microsoft.PowerToys.PreviewHandler.Qoi.Telemetry.Events; 8 using Microsoft.PowerToys.Telemetry; 9 10 namespace Microsoft.PowerToys.PreviewHandler.Qoi 11 { 12 /// <summary> 13 /// Implementation of Control for Qoi Preview Handler. 14 /// </summary> 15 public class QoiPreviewHandlerControl : FormHandlerControl 16 { 17 /// <summary> 18 /// Picture box control to display the Qoi thumbnail. 19 /// </summary> 20 private PictureBox _pictureBox; 21 22 /// <summary> 23 /// Text box to display errors. 24 /// </summary> 25 private RichTextBox _textBox; 26 27 /// <summary> 28 /// Represent if a text box info bar is added for showing message. 29 /// </summary> 30 private bool _infoBarAdded; 31 32 /// <summary> 33 /// Initializes a new instance of the <see cref="QoiPreviewHandlerControl"/> class. 34 /// </summary> 35 public QoiPreviewHandlerControl() 36 { 37 SetBackgroundColor(Settings.BackgroundColor); 38 } 39 40 /// <summary> 41 /// Start the preview on the Control. 42 /// </summary> 43 /// <param name="dataSource">Stream reference to access source file.</param> 44 public override void DoPreview<T>(T dataSource) 45 { 46 if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredQoiPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) 47 { 48 // GPO is disabling this utility. Show an error message instead. 49 _infoBarAdded = true; 50 AddTextBoxControl(Properties.Resource.GpoDisabledErrorText); 51 Resize += FormResized; 52 base.DoPreview(dataSource); 53 54 return; 55 } 56 57 try 58 { 59 Bitmap thumbnail = null; 60 61 if (!(dataSource is string filePath)) 62 { 63 throw new ArgumentException($"{nameof(dataSource)} for {nameof(QoiPreviewHandlerControl)} must be a string but was a '{typeof(T)}'"); 64 } 65 66 using FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); 67 68 thumbnail = QoiImage.FromStream(fs); 69 70 _infoBarAdded = false; 71 72 AddPictureBoxControl(thumbnail); 73 74 Resize += FormResized; 75 base.DoPreview(fs); 76 try 77 { 78 PowerToysTelemetry.Log.WriteEvent(new QoiFilePreviewed()); 79 } 80 catch 81 { // Should not crash if sending telemetry is failing. Ignore the exception. 82 } 83 } 84 catch (Exception ex) 85 { 86 PreviewError(ex, dataSource); 87 } 88 } 89 90 /// <summary> 91 /// Occurs when RichtextBox is resized. 92 /// </summary> 93 /// <param name="sender">Reference to resized control.</param> 94 /// <param name="e">Provides data for the ContentsResized event.</param> 95 private void RTBContentsResized(object sender, ContentsResizedEventArgs e) 96 { 97 var richTextBox = sender as RichTextBox; 98 richTextBox.Height = e.NewRectangle.Height + 5; 99 } 100 101 /// <summary> 102 /// Occurs when form is resized. 103 /// </summary> 104 /// <param name="sender">Reference to resized control.</param> 105 /// <param name="e">Provides data for the resize event.</param> 106 private void FormResized(object sender, EventArgs e) 107 { 108 if (_infoBarAdded) 109 { 110 _textBox.Width = Width; 111 } 112 } 113 114 /// <summary> 115 /// Adds a PictureBox Control to Control Collection. 116 /// </summary> 117 /// <param name="image">Image to display on PictureBox Control.</param> 118 private void AddPictureBoxControl(Image image) 119 { 120 _pictureBox = new PictureBox(); 121 _pictureBox.BackgroundImage = image; 122 _pictureBox.BackgroundImageLayout = Width >= image.Width && Height >= image.Height ? ImageLayout.Center : ImageLayout.Zoom; 123 _pictureBox.Dock = DockStyle.Fill; 124 Controls.Add(_pictureBox); 125 } 126 127 /// <summary> 128 /// Adds a Text Box to display errors. 129 /// </summary> 130 /// <param name="message">Message to be displayed in textbox.</param> 131 private void AddTextBoxControl(string message) 132 { 133 _textBox = new RichTextBox(); 134 _textBox.Text = message; 135 _textBox.BackColor = Color.LightYellow; 136 _textBox.Multiline = true; 137 _textBox.Dock = DockStyle.Top; 138 _textBox.ReadOnly = true; 139 _textBox.ContentsResized += RTBContentsResized; 140 _textBox.ScrollBars = RichTextBoxScrollBars.None; 141 _textBox.BorderStyle = BorderStyle.None; 142 Controls.Add(_textBox); 143 } 144 145 /// <summary> 146 /// Called when an error occurs during preview. 147 /// </summary> 148 /// <param name="exception">The exception which occurred.</param> 149 /// <param name="dataSource">Stream reference to access source file.</param> 150 private void PreviewError<T>(Exception exception, T dataSource) 151 { 152 try 153 { 154 PowerToysTelemetry.Log.WriteEvent(new QoiFilePreviewError { Message = exception.Message }); 155 } 156 catch 157 { // Should not crash if sending telemetry is failing. Ignore the exception. 158 } 159 160 Controls.Clear(); 161 _infoBarAdded = true; 162 AddTextBoxControl(Properties.Resource.QoiNotPreviewedError); 163 base.DoPreview(dataSource); 164 } 165 } 166 }