Ctrl K
ComunidadGuías…

src/TextViewerForm.cs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Clipman
{
    internal sealed class FocusableImagePreview : Control
    {
        private readonly Image previewImage;

        public FocusableImagePreview(Image image, string accessibleName, string accessibleDescription)
        {
            if (image == null) throw new ArgumentNullException("image");
            previewImage = image;
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer |
                     ControlStyles.ResizeRedraw | ControlStyles.Selectable | ControlStyles.UserPaint, true);
            TabStop = true;
            BackColor = SystemColors.Window;
            AccessibleRole = AccessibleRole.Graphic;
            AccessibleName = accessibleName ?? "Image preview";
            AccessibleDescription = accessibleDescription ?? string.Empty;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.Clear(BackColor);
            if (previewImage.Width > 0 && previewImage.Height > 0 && ClientSize.Width > 0 && ClientSize.Height > 0)
            {
                var scale = Math.Min((double)ClientSize.Width / previewImage.Width, (double)ClientSize.Height / previewImage.Height);
                var width = Math.Max(1, (int)Math.Round(previewImage.Width * scale));
                var height = Math.Max(1, (int)Math.Round(previewImage.Height * scale));
                var bounds = new Rectangle((ClientSize.Width - width) / 2, (ClientSize.Height - height) / 2, width, height);
                e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                e.Graphics.DrawImage(previewImage, bounds);
            }
            if (Focused && ShowFocusCues && ClientSize.Width > 4 && ClientSize.Height > 4)
            {
                var focusBounds = ClientRectangle;
                focusBounds.Inflate(-2, -2);
                ControlPaint.DrawFocusRectangle(e.Graphics, focusBounds);
            }
        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            Invalidate();
        }
    }

    internal sealed class TextViewerForm : Form
    {
        private readonly TextBoxBase textBox;
        private readonly Control focusControl;
        private readonly Image previewImage;

        public TextViewerForm(string text)
            : this("Clipman Entry Text", text, "Clipboard entry text", "Read-only clipboard entry text.", false, null)
        {
        }

        public TextViewerForm(string title, string text, string accessibleName, string accessibleDescription, bool showCopyButton)
            : this(title, text, accessibleName, accessibleDescription, showCopyButton, null)
        {
        }

        public TextViewerForm(string title, string text, string accessibleName, string accessibleDescription, bool showCopyButton, IReadOnlyList<KeyValuePair<string, string>> details)
            : this(title, text, accessibleName, accessibleDescription, showCopyButton, details, null)
        {
        }

        public TextViewerForm(string title, string text, string accessibleName, string accessibleDescription, bool showCopyButton, IReadOnlyList<KeyValuePair<string, string>> details, RichTextPayload richText)
        {
            Text = title;
            StartPosition = FormStartPosition.CenterParent;
            Width = 850;
            Height = 600;
            KeyPreview = true;

            var normalizedRichText = RichTextData.Normalize(richText);
            RichImageInfo embeddedImage;
            var hasEmbeddedImage = RichImageData.TryDecode(normalizedRichText, out embeddedImage);
            if (normalizedRichText != null && !string.IsNullOrEmpty(normalizedRichText.RtfBase64))
            {
                var richViewer = new RichTextBox
                {
                    Dock = DockStyle.Fill,
                    ReadOnly = true,
                    ScrollBars = RichTextBoxScrollBars.Both,
                    WordWrap = false,
                    DetectUrls = true,
                    AccessibleName = accessibleName,
                    AccessibleDescription = accessibleDescription
                };
                try
                {
                    richViewer.Rtf = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(normalizedRichText.RtfBase64));
                }
                catch
                {
                    richViewer.Text = text ?? string.Empty;
                }
                textBox = richViewer;
            }
            else
            {
                textBox = new TextBox
                {
                    Dock = DockStyle.Fill,
                    Multiline = true,
                    ReadOnly = true,
                    ScrollBars = ScrollBars.Both,
                    WordWrap = false,
                    Text = text ?? string.Empty,
                    AccessibleName = accessibleName,
                    AccessibleDescription = accessibleDescription
                };
            }
            TextBoundaryNavigator.Attach(textBox);

            Control primaryControl = textBox;
            if (hasEmbeddedImage)
            {
                previewImage = new Bitmap(embeddedImage.Image);
                var imageName = string.IsNullOrWhiteSpace(embeddedImage.FileName) ? "clipboard image" : embeddedImage.FileName;
                var picture = new FocusableImagePreview(
                    previewImage,
                    "Image preview, " + imageName + ", " + embeddedImage.Width + " by " + embeddedImage.Height + " pixels",
                    embeddedImage.MimeType + ".")
                {
                    Dock = DockStyle.Fill
                };
                embeddedImage.Dispose();
                var imagePanel = new TableLayoutPanel
                {
                    Dock = DockStyle.Fill,
                    ColumnCount = 1,
                    RowCount = 2
                };
                imagePanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
                imagePanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
                imagePanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 64));
                imagePanel.Controls.Add(picture, 0, 0);
                imagePanel.Controls.Add(textBox, 0, 1);
                primaryControl = imagePanel;
                focusControl = picture;
            }
            else
            {
                if (embeddedImage != null) embeddedImage.Dispose();
                focusControl = textBox;
            }

            var content = new TableLayoutPanel
            {
                Dock = DockStyle.Fill,
                ColumnCount = 1,
                RowCount = details != null && details.Count > 0 ? 2 : 1
            };
            content.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
            content.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
            content.Controls.Add(primaryControl, 0, 0);

            if (details != null && details.Count > 0)
            {
                content.RowStyles.Add(new RowStyle(SizeType.Absolute, 145));
                var detailsList = new ListView
                {
                    Dock = DockStyle.Fill,
                    View = View.Details,
                    FullRowSelect = true,
                    HeaderStyle = ColumnHeaderStyle.None,
                    HideSelection = false,
                    AccessibleName = "Entry details",
                    AccessibleDescription = "Metadata for the selected clipboard entry."
                };
                detailsList.Columns.Add("Property", 180);
                detailsList.Columns.Add("Value", 590);
                foreach (var detail in details)
                {
                    var item = new ListViewItem(detail.Key);
                    item.SubItems.Add(detail.Value ?? string.Empty);
                    detailsList.Items.Add(item);
                }
                content.Controls.Add(detailsList, 0, 1);
            }

            Controls.Add(content);

            var buttons = new FlowLayoutPanel
            {
                Dock = DockStyle.Bottom,
                FlowDirection = FlowDirection.RightToLeft,
                Height = 42
            };
            var close = new Button
            {
                Text = "Close",
                Width = 90,
                DialogResult = DialogResult.OK
            };
            buttons.Controls.Add(close);
            if (showCopyButton)
            {
                var copy = new Button
                {
                    Text = "Copy",
                    Width = 90
                };
                copy.Click += (s, e) =>
                {
                    Clipboard.SetText(textBox.Text ?? string.Empty, TextDataFormat.UnicodeText);
                };
                buttons.Controls.Add(copy);
            }
            Controls.Add(buttons);

            AcceptButton = close;
            CancelButton = close;
            ContextHelp.Prepare(this, true);
            Shown += (s, e) =>
            {
                textBox.SelectionStart = 0;
                textBox.SelectionLength = 0;
                focusControl.Focus();
            };
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && previewImage != null) previewImage.Dispose();
            base.Dispose(disposing);
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.A)
            {
                textBox.SelectAll();
                e.Handled = true;
                e.SuppressKeyPress = true;
                return;
            }
            if (e.KeyCode == Keys.Escape)
            {
                Close();
                e.Handled = true;
                return;
            }
            base.OnKeyDown(e);
        }
    }
}