using System; using System.ComponentModel; using System.Drawing; using System.Threading.Tasks; using System.Windows.Forms; using BukkuBuddy.DTOs.SaveFile; using BukkuBuddy.Services; using RyzStudio; using RyzStudio.Windows.Forms; using RyzStudio.Windows.ThemedForms; using RyzStudio.Windows.ThemedForms.ButtonTextBox; namespace BukkuBuddy.Forms { public class EditBookmarkForm : Form { private Label label1; private ThClearableTextBox textBox1; private Label label2; private Label label3; private ThToolbarMemoBox memoBox1; private Label label4; private ThIconButtonTextBox textBox2; private PictureBox pictureBox1; private System.ComponentModel.IContainer components; private ThClearableTextBox textBox3; private RyzStudio.Windows.ThemedForms.Composite.DialogFooter dialogFooter1; private THorizontalSeparator horizontalSeparator1; private readonly WebPageService _webPageService; private bool isBusy = false; private App6Options.Item result = null; public EditBookmarkForm(App6Options.Item model, App6Options options) { InitializeComponent(); UISetup.Dialog(this); this.Text = (result == null) ? "Add Bookmark" : "Edit Bookmark"; result = model; _webPageService = new WebPageService(options.AllowUnsafeSSL, options.Timeout, options.AllowCookies, options.AllowRedirects); } private void InitializeComponent() { components = new Container(); label1 = new Label(); textBox1 = new ThClearableTextBox(); label2 = new Label(); label3 = new Label(); memoBox1 = new ThToolbarMemoBox(); label4 = new Label(); textBox2 = new ThIconButtonTextBox(); pictureBox1 = new PictureBox(); textBox3 = new ThClearableTextBox(); dialogFooter1 = new RyzStudio.Windows.ThemedForms.Composite.DialogFooter(); horizontalSeparator1 = new THorizontalSeparator(); ((ISupportInitialize)pictureBox1).BeginInit(); SuspendLayout(); // // label1 // label1.AutoSize = true; label1.BackColor = Color.Transparent; label1.ForeColor = SystemColors.ControlText; label1.Location = new Point(10, 20); label1.Margin = new Padding(0); label1.Name = "label1"; label1.Padding = new Padding(0, 8, 0, 0); label1.Size = new Size(29, 23); label1.TabIndex = 153; label1.Text = "Title"; label1.TextAlign = ContentAlignment.MiddleLeft; // // textBox1 // textBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; textBox1.BackColor = Color.Transparent; textBox1.ClearedValue = ""; textBox1.EnableMovable = false; textBox1.Icon = "O"; textBox1.IconSize = 13F; textBox1.Location = new Point(95, 20); textBox1.Name = "textBox1"; textBox1.Size = new Size(280, 32); textBox1.TabIndex = 0; textBox1.TabStop = false; textBox1.UseSystemPasswordChar = false; // // label2 // label2.AutoSize = true; label2.BackColor = Color.Transparent; label2.ForeColor = SystemColors.ControlText; label2.Location = new Point(9, 61); label2.Margin = new Padding(0); label2.Name = "label2"; label2.Padding = new Padding(0, 8, 0, 0); label2.Size = new Size(49, 23); label2.TabIndex = 193; label2.Text = "Address"; label2.TextAlign = ContentAlignment.MiddleLeft; // // label3 // label3.AutoSize = true; label3.BackColor = Color.Transparent; label3.ForeColor = SystemColors.ControlText; label3.Location = new Point(9, 104); label3.Margin = new Padding(0); label3.Name = "label3"; label3.Padding = new Padding(0, 8, 0, 0); label3.Size = new Size(67, 23); label3.TabIndex = 195; label3.Text = "Description"; label3.TextAlign = ContentAlignment.MiddleLeft; // // memoBox1 // memoBox1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; memoBox1.BackColor = Color.Transparent; memoBox1.ClearedValue = ""; memoBox1.EnableMovable = false; memoBox1.Location = new Point(95, 158); memoBox1.Name = "memoBox1"; memoBox1.ReadOnly = false; memoBox1.ScrollBars = ScrollBars.Vertical; memoBox1.Size = new Size(280, 283); memoBox1.TabIndex = 3; memoBox1.TabStop = false; memoBox1.WordWrap = false; // // label4 // label4.AutoSize = true; label4.BackColor = Color.Transparent; label4.ForeColor = SystemColors.ControlText; label4.Location = new Point(10, 158); label4.Margin = new Padding(0); label4.Name = "label4"; label4.Padding = new Padding(0, 8, 0, 0); label4.Size = new Size(38, 23); label4.TabIndex = 198; label4.Text = "Notes"; label4.TextAlign = ContentAlignment.MiddleLeft; // // textBox2 // textBox2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; textBox2.BackColor = Color.Transparent; textBox2.EnableMovable = false; textBox2.Icon = "M"; textBox2.IconSize = 13F; textBox2.Location = new Point(115, 62); textBox2.Name = "textBox2"; textBox2.Size = new Size(260, 32); textBox2.TabIndex = 1; textBox2.TabStop = false; textBox2.UseSystemPasswordChar = false; textBox2.OnButtonClick += textBox2_OnButtonClick; // // pictureBox1 // pictureBox1.BackColor = Color.White; pictureBox1.ErrorImage = null; pictureBox1.InitialImage = null; pictureBox1.Location = new Point(61, 20); pictureBox1.Name = "pictureBox1"; pictureBox1.Size = new Size(32, 32); pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage; pictureBox1.TabIndex = 201; pictureBox1.TabStop = false; pictureBox1.MouseClick += pictureBox1_MouseClick; pictureBox1.MouseDoubleClick += pictureBox1_MouseDoubleClick; // // textBox3 // textBox3.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; textBox3.BackColor = Color.Transparent; textBox3.ClearedValue = ""; textBox3.EnableMovable = false; textBox3.Icon = "O"; textBox3.IconSize = 13F; textBox3.Location = new Point(115, 104); textBox3.Name = "textBox3"; textBox3.Size = new Size(260, 32); textBox3.TabIndex = 203; textBox3.TabStop = false; textBox3.UseSystemPasswordChar = false; // // dialogFooter1 // dialogFooter1.BackColor = Color.FromArgb(240, 240, 240); dialogFooter1.Dock = DockStyle.Bottom; dialogFooter1.EnableMovable = false; dialogFooter1.IsBusy = false; dialogFooter1.Location = new Point(0, 451); dialogFooter1.Name = "dialogFooter1"; dialogFooter1.Size = new Size(384, 70); dialogFooter1.TabIndex = 210; dialogFooter1.TabStop = false; // // horizontalSeparator1 // horizontalSeparator1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; horizontalSeparator1.Location = new Point(5, 141); horizontalSeparator1.Name = "horizontalSeparator1"; horizontalSeparator1.Size = new Size(375, 10); // // EditBookmarkForm // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; BackColor = Color.White; ClientSize = new Size(384, 521); Controls.Add(horizontalSeparator1); Controls.Add(pictureBox1); Controls.Add(dialogFooter1); Controls.Add(textBox3); Controls.Add(textBox2); Controls.Add(memoBox1); Controls.Add(label4); Controls.Add(label3); Controls.Add(label2); Controls.Add(textBox1); Controls.Add(label1); KeyPreview = true; MinimumSize = new Size(400, 560); Name = "EditBookmarkForm"; Text = "Edit Bookmark"; ((ISupportInitialize)pictureBox1).EndInit(); ResumeLayout(false); PerformLayout(); } protected override void OnShown(EventArgs e) { base.OnShown(e); textBox1.Text = result?.Title?.Trim() ?? string.Empty; textBox2.Text = result?.Address?.Trim() ?? string.Empty; textBox3.Text = result?.Description?.Trim() ?? string.Empty; memoBox1.Text = result?.Notes?.Trim() ?? string.Empty; if (result != null) { try { if (result.Icon != null) { if (result.Icon.Width > 16) { result.Icon = RyzStudio.Drawing.ImageEditor.Resize(result.Icon, 16, 16); } } pictureBox1.Image = result.Icon; } catch (Exception) { pictureBox1.Image = result.Icon = null; } } textBox2.Focus(); } protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); if (this.IsBusy) { e.Cancel = true; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public App6Options.Item Result { get { if (result == null) { result = new App6Options.Item(); } result.Title = textBox1.Text?.Trim() ?? string.Empty; result.Address = textBox2.Text?.Trim() ?? string.Empty; result.Description = textBox3.Text?.Trim() ?? string.Empty; try { result.Icon = pictureBox1.Image; } catch (Exception) { // do nothing } result.Notes = memoBox1.Text?.Trim() ?? string.Empty; return result; } } protected bool IsBusy { get => isBusy; set { isBusy = value; UIControl.SetEnable(textBox1, !isBusy); UIControl.SetEnable(textBox2, !isBusy); UIControl.SetEnable(textBox3, !isBusy); UIControl.SetEnable(memoBox1, !isBusy); dialogFooter1.IsBusy = isBusy; } } /// /// Retrieve favicon /// /// /// private async void pictureBox1_MouseDoubleClick(object sender, MouseEventArgs e) { if (this.IsBusy) { return; } if (e.Button == MouseButtons.Left) { if (string.IsNullOrWhiteSpace(textBox2.Text)) { return; } DialogResult result = DialogResult.Yes; if (pictureBox1.Image != null) { result = MessageBox.Show("Do you want to (try to) retrieve the favicon?", "Retrieve Favicon", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); } if (result == DialogResult.Yes) { await Task.Run(async () => { this.IsBusy = true; var image = await GetFavicon(textBox2.Text); UIControl.SetImage(pictureBox1, image); this.IsBusy = false; }); } } } /// /// Clear favicon /// /// /// private void pictureBox1_MouseClick(object sender, MouseEventArgs e) { if (this.IsBusy) { return; } if (e.Button == MouseButtons.Right) { if (pictureBox1.Image == null) { return; } //if (MessageBox.Show("Are you sure you want to clear the favicon?", "Clear Favicon", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes) //{ pictureBox1.Image = null; //} } } private async void textBox2_OnButtonClick(object sender, EventArgs e) { if (this.IsBusy) { return; } this.IsBusy = true; await Task.Run(async () => { var result = await UpdateBookmarkInfo(textBox2.Text); if (!result.Success) { MessageBox.Show(result.Message, "Update Bookmark", MessageBoxButtons.OK, MessageBoxIcon.Error); } }); this.IsBusy = false; textBox2.Focus(); } private async Task GetFavicon(string url) { if (!_webPageService.IsValidUrl(url)) { return null; } HtmlAgilityPack.HtmlDocument htmlDocument = null; try { htmlDocument = await _webPageService.GetDocument(url); } catch (Exception exc) { MessageBox.Show(exc.Message, "Update Icon", MessageBoxButtons.OK, MessageBoxIcon.Error); return null; } if (htmlDocument == null) { return null; } var faviconUrl = _webPageService.ParseFavicon(htmlDocument); if (string.IsNullOrWhiteSpace(faviconUrl)) { return null; } var favicon = await _webPageService.GetImage(faviconUrl); if (favicon != null) { if (favicon.Width > 16) { favicon = RyzStudio.Drawing.ImageEditor.Resize(favicon, 16, 16); } } return favicon; } private async Task UpdateBookmarkInfo(string url) { if (!_webPageService.IsValidUrl(url)) { return MethodResult.Error("Invalid URL."); } HtmlAgilityPack.HtmlDocument htmlDocument = null; try { htmlDocument = await _webPageService.GetDocument(url); } catch (Exception exc) { MessageBox.Show(exc.Message, "Update Icon", MessageBoxButtons.OK, MessageBoxIcon.Error); return MethodResult.Error(exc.Message); } if (htmlDocument == null) { return null; } var title = _webPageService.ParseTitle(htmlDocument) ?? string.Empty; var description = _webPageService.ParseDescription(htmlDocument) ?? string.Empty; UIControl.SetText(textBox1, title); UIControl.SetText(textBox3, description); var faviconUrl = _webPageService.ParseFavicon(htmlDocument); if (!string.IsNullOrWhiteSpace(faviconUrl)) { var favicon = await _webPageService.GetImage(faviconUrl); if (favicon != null) { if (favicon.Width > 16) { favicon = RyzStudio.Drawing.ImageEditor.Resize(favicon, 16, 16); } } UIControl.SetImage(pictureBox1, favicon); } return MethodResult.Create(); } } }