// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for details. using System; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Drawing.Text; using System.Globalization; using System.IO; using System.Net; using System.Windows.Forms; using OpenLiveWriter.ApplicationFramework; using OpenLiveWriter.Controls; using OpenLiveWriter.CoreServices; using OpenLiveWriter.CoreServices.Layout; using OpenLiveWriter.Interop.Windows; using OpenLiveWriter.Localization; using OpenLiveWriter.Localization.Bidi; using OpenLiveWriter.PostEditor.PostHtmlEditing; namespace OpenLiveWriter.PostEditor.ImageInsertion { /// <summary> /// Summary description for WebImageControl. /// </summary> public class WebImageSource : InsertImageSource { private Label _labelOne; private TextBoxWithPaste _webImageUrl; private BorderControl _pictureBorder; private PictureBox _previewBox; private Button _previewButton; private Label _labelSize; private Label _fileSize; private bool _selected = false; UserControl _control; private int _width; private int _height; private const int WebImageUrlPadding = 6; private const int SizeLabelPadding = 6; public void Init(int width, int height) { _width = width; _height = height; } public string TabName { get { return Res.Get(StringId.InsertImageInsertFromWeb); } } public Bitmap TabBitmap { get { return ResourceHelper.LoadAssemblyResourceBitmap("ImageInsertion.Images.TabInsertFromWeb.png"); } } public UserControl ImageSelectionControls { get { if (_control == null) { _control = new UserControl(); _control.Location = new Point(0, 0); _control.Size = new Size(_width, _height); _control.Load += new EventHandler(_control_Load); _control.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom; _control.Font = Res.DefaultFont; _labelOne = new Label(); _labelOne.FlatStyle = FlatStyle.System; _labelOne.Text = Res.Get(StringId.InsertImageImageUrl); _labelOne.Location = new Point(10, 13); _labelOne.Size = new Size(87, 15); _labelOne.Anchor = AnchorStyles.Left | AnchorStyles.Top; _webImageUrl = new TextBoxWithPaste(); _webImageUrl.Location = new Point(10, 31); _webImageUrl.Size = new Size(377, 20); _webImageUrl.Name = "imageUrl"; _webImageUrl.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right; _webImageUrl.OnPaste += new TextBoxWithPaste.OnPasteEventHandler(this._imageUrl_Paste); _webImageUrl.RightToLeft = RightToLeft.No; if (BidiHelper.IsRightToLeft) _webImageUrl.TextAlign = HorizontalAlignment.Right; _previewButton = new Button(); _previewButton.Location = new Point(395, 31); _previewButton.Size = new Size(75, 23); _previewButton.FlatStyle = FlatStyle.System; _previewButton.Text = Res.Get(StringId.InsertImagePreviewButton); _previewButton.Name = "previewButton"; _previewButton.Click += new EventHandler(_previewButton_Click); _previewButton.Anchor = AnchorStyles.Right | AnchorStyles.Top; _previewBox = new PictureBox(); _previewBox.BackColor = Color.White; _previewBox.BorderStyle = BorderStyle.None; _previewBox.SizeMode = PictureBoxSizeMode.CenterImage; _previewBox.Name = "previewBox"; _pictureBorder = new BorderControl(); _pictureBorder.Location = new Point(10, 59); _pictureBorder.Size = new Size(460, 283); _pictureBorder.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom; _pictureBorder.Control = _previewBox; _labelSize = new Label(); _labelSize.FlatStyle = FlatStyle.System; _labelSize.Text = Res.Get(StringId.InsertImageSize); _labelSize.Size = new Size(35, 15); _labelSize.Location = new Point(10, 347); _labelSize.Anchor = AnchorStyles.Left | AnchorStyles.Bottom; _fileSize = new Label(); _fileSize.FlatStyle = FlatStyle.System; _fileSize.Text = ""; _fileSize.Size = new Size(438, 15); _fileSize.Location = new Point(51, 347); _fileSize.Anchor = AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right; _control.Controls.Add(_labelOne); _control.Controls.Add(_webImageUrl); _control.Controls.Add(_previewButton); _control.Controls.Add(_pictureBorder); _control.Controls.Add(_labelSize); _control.Controls.Add(_fileSize); _control.Name = "WebImageSource"; _control.RightToLeft = BidiHelper.IsRightToLeft ? RightToLeft.Yes : RightToLeft.No; } return _control; } } private void _control_Load(object sender, EventArgs e) { LayoutHelper.AutoFitLabels(_labelSize); DisplayHelper.AutoFitSystemLabel(_labelOne, _labelOne.Width, int.MaxValue); DisplayHelper.AutoFitSystemButton(_previewButton, 0, int.MaxValue); if (_control.RightToLeft == RightToLeft.Yes) { _webImageUrl.Left = _previewButton.Right + (int)DisplayHelper.ScaleX(WebImageUrlPadding); _webImageUrl.Width = _pictureBorder.Right - _previewButton.Right - (int)DisplayHelper.ScaleX(WebImageUrlPadding); _fileSize.Left = _pictureBorder.Left; _fileSize.Width = _labelSize.Left - _fileSize.Left - SizeLabelPadding; } else { _webImageUrl.Left = _pictureBorder.Left; _webImageUrl.Width = _previewButton.Left - _webImageUrl.Left - (int)DisplayHelper.ScaleX(WebImageUrlPadding); _fileSize.Left = _labelSize.Right + SizeLabelPadding; _fileSize.Width = _pictureBorder.Right - _fileSize.Left; } BidiHelper.RtlLayoutFixup(_control); _webImageUrl.Select(); } private void _imageUrl_Paste(object sender, TextBoxWithPaste.PasteEventArgs eventArgs) { //special case...image on clipboard if (_webImageUrl.Text.Trim() == String.Empty) { DataObjectMeister dataObject = new DataObjectMeister(Clipboard.GetDataObject()); if (dataObject.HTMLData != null && dataObject.HTMLData.OnlyImagePath != null) { _webImageUrl.Text = dataObject.HTMLData.OnlyImagePath; } } PopulatePreviewBox(); _webImageUrl.SelectAll(); } public void Repaint(Size newSize) { _control.Size = newSize; } public string SourceImageLink { get { return FileName; } } public void TabSelected() { _webImageUrl.Focus(); } public event EventHandler OnSelectionMade; public string FileName { get { return UrlHelper.FixUpUrl(_webImageUrl.Text); } } public bool ValidateSelection() { if (!UrlHelper.IsUrl(UrlHelper.FixUpUrl(_webImageUrl.Text))) { DisplayMessage.Show(MessageId.InvalidWebImage); _webImageUrl.Focus(); return false; } return true; } public bool HandleEnter(int cmdId) { int previewButtonId = (int)User32.GetDlgCtrlID(_previewButton.Handle) & 0xFFFF; if (previewButtonId == cmdId) { _previewButton.PerformClick(); return true; } return false; } public bool Selected { get { return _selected; } set { _selected = value; } } private void _previewButton_Click(object sender, EventArgs e) { PopulatePreviewBox(); } private void PopulatePreviewBox() { string imageUrl = _webImageUrl.Text.Trim(); if (imageUrl != String.Empty && UrlHelper.IsUrl(imageUrl)) { using (new WaitCursor()) { try { HttpWebResponse response = HttpRequestHelper.SendRequest(UrlHelper.FixUpUrl(imageUrl)); Bitmap webImage; using (Stream responseStream = response.GetResponseStream()) webImage = new Bitmap(StreamHelper.CopyToMemoryStream(responseStream)); SetPreviewPicture(webImage, imageUrl); if (OnSelectionMade != null) OnSelectionMade(this, new EventArgs()); } catch (Exception) { _previewBox.Image = null; DisplayMessage.Show(MessageId.NoPreviewAvailable); _webImageUrl.Focus(); } } } else { _previewBox.Image = null; DisplayMessage.Show(MessageId.NoPreviewAvailable); _webImageUrl.Focus(); } } private void SetPreviewPicture(Bitmap image, string filename) { int maxWidth = _previewBox.Width - 2; int maxHeight = _previewBox.Height - 2; bool scaled = true; int currentWidth = image.Width; int currentHeight = image.Height; double ratio = 1.00; //if height and width are too big if (currentWidth > maxWidth && currentHeight > maxHeight) { //size according to the one that is more off of the available area if ((maxWidth / currentWidth) < (maxHeight / currentHeight)) { ratio = (double)maxWidth / (double)currentWidth; } else { ratio = (double)maxHeight / (double)currentHeight; } } //if just width else if (currentWidth > maxWidth) { ratio = (double)maxWidth / (double)currentWidth; } //if just height else if (currentHeight > maxHeight) { ratio = (double)maxHeight / (double)currentHeight; } //else fine else { scaled = false; } ImageFormat format; string fileExt; ImageHelper2.GetImageFormat(filename, out fileExt, out format); int newWidth = (int)(currentWidth * ratio); int newHeight = (int)(currentHeight * ratio); Bitmap newImage = ImageHelper2.CreateResizedBitmap(image, newWidth, newHeight, format); //if image is small enough, add border if (newWidth <= maxWidth && newHeight <= maxHeight) { Bitmap borderPic = new Bitmap(newWidth + 2, newHeight + 2); //Get a graphics object for it using (Graphics g = Graphics.FromImage(borderPic)) { g.TextRenderingHint = TextRenderingHint.AntiAlias; int R = SystemColors.Control.R; int G = SystemColors.Control.G; int B = SystemColors.Control.B; Color dark = Color.FromArgb((int)(R * 0.9), (int)(G * 0.9), (int)(B * 0.9)); //draw the border g.FillRectangle(new SolidBrush(dark), new Rectangle(0, 0, borderPic.Width, 1)); g.FillRectangle(new SolidBrush(dark), new Rectangle(0, borderPic.Height - 1, borderPic.Width, 1)); g.FillRectangle(new SolidBrush(dark), new Rectangle(0, 0, 1, borderPic.Height)); g.FillRectangle(new SolidBrush(dark), new Rectangle(borderPic.Width - 1, 0, 1, borderPic.Height)); //draw our image back in the middle g.DrawImage(newImage, new Rectangle(1, 1, newWidth, newHeight), 0, 0, newWidth, newHeight, GraphicsUnit.Pixel); } _previewBox.Image = borderPic; } else { _previewBox.Image = newImage; } string picsize; if (!scaled) picsize = MakeDimensions(currentWidth, currentHeight); else { picsize = string.Format(CultureInfo.CurrentCulture, Res.Get(StringId.InsertImageDimensionsFormatScaled), MakeDimensions(currentWidth, currentHeight)); } _fileSize.Text = picsize; } private static string MakeDimensions(int width, int height) { return string.Format(CultureInfo.CurrentCulture, Res.Get(StringId.InsertImageDimensionsFormat), width, height); } } }