From 682af23f55d788f49a4355fa8e7d75c60307492e Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 17 Sep 2021 16:37:01 +0100 Subject: [PATCH] WIP: web parser + ui --- AppResource.Designer.cs | 10 + AppResource.resx | 3 + BookmarkForm.cs | 131 ++++++++- BookmarkManager.csproj | 1 - Classes/SupportedFile/JSNXSupportedFile.cs | 4 +- Classes/WebParser.cs | 249 ++++++++++++++++++ MainForm.cs | 4 +- ...okmarkItemViewModel.cs => BookmarkItem.cs} | 2 +- Resources/loading-block.gif | Bin 0 -> 33840 bytes RyzStudio/Windows/Forms/ThreadControl.cs | 182 +++++++------ Windows/Forms/BookmarkTreeView.cs | 101 ++++--- 11 files changed, 540 insertions(+), 147 deletions(-) create mode 100644 Classes/WebParser.cs rename Models/{BookmarkItemViewModel.cs => BookmarkItem.cs} (97%) create mode 100644 Resources/loading-block.gif diff --git a/AppResource.Designer.cs b/AppResource.Designer.cs index 502b3a3..f7bb2f8 100644 --- a/AppResource.Designer.cs +++ b/AppResource.Designer.cs @@ -128,6 +128,16 @@ namespace BookmarkManager { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap loading_block { + get { + object obj = ResourceManager.GetObject("loading_block", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized string similar to https://www.hiimray.co.uk/software-bookmark-manager. /// diff --git a/AppResource.resx b/AppResource.resx index 97991b2..4562d76 100644 --- a/AppResource.resx +++ b/AppResource.resx @@ -139,6 +139,9 @@ Resources\hexagon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + Resources\loading-block.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + https://www.hiimray.co.uk/software-bookmark-manager diff --git a/BookmarkForm.cs b/BookmarkForm.cs index e3a4618..4325cbf 100644 --- a/BookmarkForm.cs +++ b/BookmarkForm.cs @@ -5,6 +5,11 @@ using System; using RyzStudio.Windows.Forms; using bzit.bomg.Models; using System.Drawing; +using BookmarkManager; +using System.Threading.Tasks; +using System.ComponentModel; +using System.Net; +using System.IO; namespace FizzyLauncher { @@ -18,21 +23,23 @@ namespace FizzyLauncher private Label label2; private Label label3; private TMemoBox memoBox1; - - private TMemoBox memoBox2; private Label label4; private TButtonTextBox textBox2; private PictureBox pictureBox1; + private PictureBox pictureBox2; - - protected TreeNode treeNode = null; private ToolTip toolTip1; private System.ComponentModel.IContainer components; + + protected bool isBusy = false; protected string faviconAddress = null; + protected WebParser webParser = null; + protected WebClient webClient = null; - public BookmarkForm(BookmarkItemViewModel model) : base() + + public BookmarkForm(BookmarkItem model) : base() { InitializeComponent(); @@ -61,7 +68,9 @@ namespace FizzyLauncher this.textBox2 = new RyzStudio.Windows.ThemedForms.TButtonTextBox(); this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.pictureBox2 = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); this.SuspendLayout(); // // label1 @@ -240,11 +249,25 @@ namespace FizzyLauncher this.pictureBox1.TabIndex = 201; this.pictureBox1.TabStop = false; // + // pictureBox2 + // + this.pictureBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.pictureBox2.BackColor = System.Drawing.Color.Transparent; + this.pictureBox2.ErrorImage = null; + this.pictureBox2.InitialImage = null; + this.pictureBox2.Location = new System.Drawing.Point(196, 469); + this.pictureBox2.Name = "pictureBox2"; + this.pictureBox2.Size = new System.Drawing.Size(32, 32); + this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.pictureBox2.TabIndex = 202; + this.pictureBox2.TabStop = false; + // // BookmarkForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(384, 521); + this.Controls.Add(this.pictureBox2); this.Controls.Add(this.pictureBox1); this.Controls.Add(this.textBox2); this.Controls.Add(this.memoBox2); @@ -261,6 +284,7 @@ namespace FizzyLauncher this.Name = "BookmarkForm"; this.Text = "Edit Bookmark"; ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -270,13 +294,23 @@ namespace FizzyLauncher { base.OnShown(e); - this.DialogResult = System.Windows.Forms.DialogResult.None; + this.DialogResult = DialogResult.None; + } + + protected override void OnClosing(CancelEventArgs e) + { + base.OnClosing(e); + + if (IsBusy) + { + e.Cancel = true; + } } - public BookmarkItemViewModel Model + public BookmarkItem Model { - get => new BookmarkItemViewModel() + get => new BookmarkItem() { SiteName = textBox1.Text?.Trim() ?? string.Empty, SiteAddress = textBox2.Text?.Trim() ?? string.Empty, @@ -288,6 +322,23 @@ namespace FizzyLauncher public Image Favicon { get => pictureBox1.Image; } + protected bool IsBusy + { + get => isBusy; + set + { + isBusy = value; + + ThreadControl.SetValue(pictureBox2, (isBusy ? AppResource.loading_block : null)); + + ThreadControl.SetEnable(textBox1, !isBusy); + ThreadControl.SetEnable(textBox2, !isBusy); + ThreadControl.SetEnable(memoBox1 , !isBusy); + ThreadControl.SetEnable(memoBox2, !isBusy); + ThreadControl.SetEnable(button1, !isBusy); + } + } + private void button1_MouseClick(object sender, MouseEventArgs e) { @@ -295,9 +346,71 @@ namespace FizzyLauncher this.Close(); } - private void textBox2_OnButtonClick(object sender, EventArgs e) + private async void textBox2_OnButtonClick(object sender, EventArgs e) { + await Task.Run(() => + { + if (IsBusy) return; + IsBusy = true; + + if (webParser == null) webParser = new WebParser(); + + if (string.IsNullOrWhiteSpace(textBox1.Text)) + { + IsBusy = false; + return; + } + + BookmarkItem rs = webParser.RetrieveDetails(textBox2.Text); + if (rs == null) + { + IsBusy = false; + return; + } + + if (!string.IsNullOrWhiteSpace(rs.SiteName)) ThreadControl.SetText(textBox1, rs.SiteName); + if (!string.IsNullOrWhiteSpace(rs.SiteDescription)) ThreadControl.SetText(memoBox1, rs.SiteDescription); + + if (string.IsNullOrWhiteSpace(rs.FaviconAddress)) + { + ThreadControl.Clear(pictureBox1); + } + else + { + ThreadControl.SetValue(pictureBox1, RetrieveImage(rs.FaviconAddress)); + } + + IsBusy = false; + }); + } + + private Image RetrieveImage(string url) + { + if (string.IsNullOrWhiteSpace(url)) + { + return null; + } + + if (webClient == null) webClient = new WebClient(); + webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore); + + try + { + byte[] byteData = webClient.DownloadData(url); + + if (!RyzStudio.IO.FileType.IsImage(byteData)) + { + throw new Exception("Not a supported image"); + } + + Image img = Image.FromStream(new MemoryStream(byteData)); + return new Bitmap(img, 16, 16); + } + catch (Exception) + { + return null; + } } } diff --git a/BookmarkManager.csproj b/BookmarkManager.csproj index 694f0a8..a9f1e44 100644 --- a/BookmarkManager.csproj +++ b/BookmarkManager.csproj @@ -49,7 +49,6 @@ - diff --git a/Classes/SupportedFile/JSNXSupportedFile.cs b/Classes/SupportedFile/JSNXSupportedFile.cs index 5fd90c2..bbfee06 100644 --- a/Classes/SupportedFile/JSNXSupportedFile.cs +++ b/Classes/SupportedFile/JSNXSupportedFile.cs @@ -37,7 +37,7 @@ namespace BookmarkManager return Result.Create(false, "Could not read file, unexpected format"); } - List rs = JsonConvert.DeserializeObject>(sourceCode); + List rs = JsonConvert.DeserializeObject>(sourceCode); if (rs == null) { return Result.Create(false, "Could not read file, incorrect format"); @@ -69,7 +69,7 @@ namespace BookmarkManager public override Result Save(BookmarkTreeView treeview, string filename, string password) { - List rs = treeview.GetBookmarkList(); + List rs = treeview.GetBookmarkList(); bool rv = SharpZipLib.CreateSingle(filename, password, "bookmarks.json", JsonConvert.SerializeObject(rs)); diff --git a/Classes/WebParser.cs b/Classes/WebParser.cs new file mode 100644 index 0000000..6fbe2dc --- /dev/null +++ b/Classes/WebParser.cs @@ -0,0 +1,249 @@ +using bzit.bomg.Models; +using HtmlAgilityPack; +using RyzStudio.Net; +using System; +using System.Net; + +namespace BookmarkManager +{ + public class WebParser + { + protected HttpWeb webClient = null; + + + public BookmarkItem RetrieveDetails(string url) + { + string sourceCode = retrieveSourceCode(url); + if (string.IsNullOrWhiteSpace(sourceCode)) + { + return null; + } + + BookmarkItem rs = new BookmarkItem(); + + HtmlDocument document = new HtmlDocument(); + document.LoadHtml(sourceCode); + + rs.SiteName = parseSiteTitle(document); + rs.SiteAddress = url; + rs.SiteDescription = parseSiteDescription(document); + rs.FaviconAddress = parseSiteIcon(document); + + // resolve relative URL + if (!string.IsNullOrWhiteSpace(rs.FaviconAddress)) + { + Uri iconAddressURI; + bool rv = Uri.TryCreate(new Uri(url), rs.FaviconAddress, out iconAddressURI); + if (rv) + { + rs.FaviconAddress = iconAddressURI.ToString(); + } + } + + return rs; + } + + + protected string retrieveSourceCode(string url) + { + if (webClient == null) webClient = new HttpWeb(); + + string sourceCode; + + try + { + int statusCode = webClient.GetResponse(out sourceCode, url); + if ((statusCode == 200) || (statusCode == 301) || (statusCode == 302)) + { + return sourceCode; + } + } + catch (Exception) + { + return null; + } + + return null; + } + + protected string parseSiteDescription(HtmlDocument doc) + { + string rs = null; + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[@name='description']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[@property='og:description']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[@name='twitter:description']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[@property='og:description']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[@itemprop='description']", "content", string.Empty); + } + + return rs; + } + + protected string parseSiteIcon(HtmlDocument doc) + { + string rs = null; + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//link[translate(@rel, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'shortcut icon']", "href", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//link[translate(@rel, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'icon']", "href", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//link[translate(@rel, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'apple-touch-icon']", "href", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//link[translate(@rel, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'apple-touch-icon-precomposed']", "href", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[translate(@property, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'og:image']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[translate(@name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'twitter:image']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[translate(@property, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'og:image']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[translate(@itemprop, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'image']", "content", string.Empty); + } + + //if (string.IsNullOrWhiteSpace(rs)) + //{ + // rs = "/favicon.ico"; + //} + + return rs; + } + + protected string parseSiteTitle(HtmlDocument doc) + { + string rs = null; + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue(doc, "//title", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[@property='og:title']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[@name='twitter:title']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[@property='og:site_name']", "content", string.Empty); + } + + if (string.IsNullOrWhiteSpace(rs)) + { + rs = parseTagValue_Attr(doc, "//meta[@itemprop='name']", "content", string.Empty); + } + + return rs?.Trim() ?? string.Empty; + } + + protected string parseTagValue(HtmlDocument doc, string xpath, string defaultValue = "") + { + HtmlNodeCollection hnc = doc.DocumentNode.SelectNodes(xpath); + if (hnc == null) + { + return defaultValue; + } + + if (hnc.Count <= 0) + { + return defaultValue; + } + + foreach (HtmlNode hn in hnc) + { + if (string.IsNullOrWhiteSpace(hn.InnerHtml)) + { + continue; + } + + string rs = WebUtility.HtmlDecode(hn.InnerHtml)?.Replace("\r", "")?.Replace("\n", " ")?.Trim(); + if (string.IsNullOrWhiteSpace(rs)) + { + continue; + } + + return rs; + } + + return defaultValue; + } + + protected string parseTagValue_Attr(HtmlDocument doc, string xpath, string attr, string defaultValue = "") + { + HtmlNodeCollection hnc = doc.DocumentNode.SelectNodes(xpath); + if (hnc == null) + { + return defaultValue; + } + + if (hnc.Count <= 0) + { + return defaultValue; + } + + foreach (HtmlNode hn in hnc) + { + if (hn.Attributes[attr] == null) + { + continue; + } + + if (string.IsNullOrWhiteSpace(hn.Attributes[attr].Value)) + { + continue; + } + + return System.Web.HttpUtility.HtmlDecode(hn.Attributes[attr].Value?.Trim()); + } + + return defaultValue; + } + + } +} \ No newline at end of file diff --git a/MainForm.cs b/MainForm.cs index 3ee41c9..0935e87 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -701,7 +701,7 @@ namespace FizzyLauncher } // add placeholder - TreeNode node = treeView1.AddItem(treeView1.SelectedNode, new BookmarkItemViewModel() + TreeNode node = treeView1.AddItem(treeView1.SelectedNode, new BookmarkItem() { SiteName = "New Bookmark" }); @@ -946,7 +946,7 @@ namespace FizzyLauncher return; } - BookmarkItemViewModel viewModel = (BookmarkItemViewModel)node.Tag; + BookmarkItem viewModel = (BookmarkItem)node.Tag; if (viewModel == null) { return; diff --git a/Models/BookmarkItemViewModel.cs b/Models/BookmarkItem.cs similarity index 97% rename from Models/BookmarkItemViewModel.cs rename to Models/BookmarkItem.cs index 7bf7436..8088bd0 100644 --- a/Models/BookmarkItemViewModel.cs +++ b/Models/BookmarkItem.cs @@ -3,7 +3,7 @@ using System.Text; namespace bzit.bomg.Models { - public class BookmarkItemViewModel + public class BookmarkItem { public string SiteName { get; set; } diff --git a/Resources/loading-block.gif b/Resources/loading-block.gif new file mode 100644 index 0000000000000000000000000000000000000000..a5aa827c5c7c5793e09d4650e66f29d74df36ad8 GIT binary patch literal 33840 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 FindChildControl(Control control) where T : Control { List rs = new List(); @@ -355,6 +354,24 @@ namespace RyzStudio.Windows.Forms return rs; } + public static string GetSelectedValue(ListBox sender) + { + string rv = string.Empty; + + if (sender.InvokeRequired) + { + sender.Invoke(new MethodInvoker(() => { + rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString(); + })); + } + else + { + rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString(); + } + + return rv; + } + public static string GetText(Control control, bool doTrim = true) { string rv = string.Empty; @@ -373,6 +390,45 @@ namespace RyzStudio.Windows.Forms return rv; } + public static int GetValue(NumericUpDown sender) + { + int rv = 0; + + if (sender.InvokeRequired) + { + sender.Invoke(new MethodInvoker(() => { + rv = (int)sender.Value; + })); + } + else + { + rv = (int)sender.Value; + } + + return rv; + } + + public static bool IsChild(TreeNode dragNode, TreeNode dropNode) + { + TreeNode tn = dropNode; + while (true) + { + if (tn.Parent == null) + { + break; + } + + if (tn.Equals(dragNode)) + { + return true; + } + + tn = tn.Parent; + } + + return false; + } + public static void SetChecked(ToolStripMenuItem control, bool value) { if (control.GetCurrentParent().InvokeRequired) @@ -388,6 +444,50 @@ namespace RyzStudio.Windows.Forms } } + public static void SetClientHeight(Control control, int value) + { + if (control.InvokeRequired) + { + control.Invoke(new MethodInvoker(() => { + control.ClientSize = new Size(control.ClientSize.Width, value); + })); + } + else + { + control.ClientSize = new Size(control.ClientSize.Width, value); + } + } + + public static void SetClientSize(Control control, int width, int height) => SetClientSize(control, new Size(width, height)); + + public static void SetClientSize(Control control, Size value) + { + if (control.InvokeRequired) + { + control.Invoke(new MethodInvoker(() => { + control.ClientSize = value; + })); + } + else + { + control.ClientSize = value; + } + } + + public static void SetClientWidth(Control control, int value) + { + if (control.InvokeRequired) + { + control.Invoke(new MethodInvoker(() => { + control.ClientSize = new Size(value, control.ClientSize.Height); + })); + } + else + { + control.ClientSize = new Size(value, control.ClientSize.Height); + } + } + public static void SetEnable(Control control, bool value) { if (control.InvokeRequired) @@ -439,42 +539,6 @@ namespace RyzStudio.Windows.Forms } } - public static int GetValue(NumericUpDown sender) - { - int rv = 0; - - if (sender.InvokeRequired) - { - sender.Invoke(new MethodInvoker(() => { - rv = (int)sender.Value; - })); - } - else - { - rv = (int)sender.Value; - } - - return rv; - } - - public static string GetSelectedValue(ListBox sender) - { - string rv = string.Empty; - - if (sender.InvokeRequired) - { - sender.Invoke(new MethodInvoker(() => { - rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString(); - })); - } - else - { - rv = (sender.SelectedItem == null) ? string.Empty : sender.SelectedItem.ToString(); - } - - return rv; - } - public static void SetHeight(Control control, int value) { if (control.InvokeRequired) @@ -503,36 +567,6 @@ namespace RyzStudio.Windows.Forms } } - public static void SetClientSize(Control control, int width, int height) => SetClientSize(control, new Size(width, height)); - - public static void SetClientSize(Control control, Size value) - { - if (control.InvokeRequired) - { - control.Invoke(new MethodInvoker(() => { - control.ClientSize = value; - })); - } - else - { - control.ClientSize = value; - } - } - - public static void SetClientHeight(Control control, int value) - { - if (control.InvokeRequired) - { - control.Invoke(new MethodInvoker(() => { - control.ClientSize = new Size(control.ClientSize.Width, value); - })); - } - else - { - control.ClientSize = new Size(control.ClientSize.Width, value); - } - } - public static void SetSize(Control control, int width, int height) => SetSize(control, new Size(width, height)); public static void SetSize(Control control, Size value) @@ -671,19 +705,5 @@ namespace RyzStudio.Windows.Forms } } - public static void SetClientWidth(Control control, int value) - { - if (control.InvokeRequired) - { - control.Invoke(new MethodInvoker(() => { - control.ClientSize = new Size(value, control.ClientSize.Height); - })); - } - else - { - control.ClientSize = new Size(value, control.ClientSize.Height); - } - } - } } \ No newline at end of file diff --git a/Windows/Forms/BookmarkTreeView.cs b/Windows/Forms/BookmarkTreeView.cs index d3617aa..0ad3d48 100644 --- a/Windows/Forms/BookmarkTreeView.cs +++ b/Windows/Forms/BookmarkTreeView.cs @@ -39,14 +39,14 @@ namespace RyzStudio.Windows.Forms return System.Web.HttpUtility.UrlEncode(value); } - public static BookmarkItemViewModel GetNodeModel(TreeNode node) + public static BookmarkItem GetNodeModel(TreeNode node) { if (node == null) { return null; } - return (BookmarkItemViewModel)node.Tag; + return (BookmarkItem)node.Tag; } public static string GetNodePath(TreeNode node) @@ -90,7 +90,7 @@ namespace RyzStudio.Windows.Forms } else { - if (node.Tag is BookmarkItemViewModel) + if (node.Tag is BookmarkItem) { return NodeType.Page; } @@ -259,27 +259,27 @@ namespace RyzStudio.Windows.Forms return; } - TreeNode en = this.GetNodeAt(this.PointToClient(new Point(e.X, e.Y))); - if (en == null) + TreeNode node = this.GetNodeAt(this.PointToClient(new Point(e.X, e.Y))); + if (node == null) { return; } - if (IsNodeChild(draggingNode, en)) + if (ThreadControl.IsChild(draggingNode, node)) { return; } TreeNode dn = draggingNode; - if (en.Tag == null) + if (node.Tag == null) { dn.Parent.Nodes.Remove(dn); - en.Nodes.Insert(0, dn); + node.Nodes.Insert(0, dn); } else { - en.Parent.Nodes.Remove(dn); - en.Parent.Nodes.Insert(en.Index + 1, dn); + node.Parent.Nodes.Remove(dn); + node.Parent.Nodes.Insert(node.Index + 1, dn); } this.HasChanged = true; @@ -428,7 +428,7 @@ namespace RyzStudio.Windows.Forms break; case NodeType.Page: - BookmarkItemViewModel viewModel = this.GetNodeModel(); + BookmarkItem viewModel = this.GetNodeModel(); if (viewModel != null) { try @@ -612,33 +612,33 @@ namespace RyzStudio.Windows.Forms // this.HasChanged = false; //} - public void AddItem(BookmarkItemViewModel viewModel) + public void AddItem(BookmarkItem item) { - int iconIndex = addIcon(viewModel); + int iconIndex = addIcon(item); - TreeNode tn = new TreeNode(viewModel.SiteName, iconIndex, iconIndex); - tn.Tag = viewModel; - tn.ToolTipText = viewModel.ToString(); + TreeNode tn = new TreeNode(item.SiteName, iconIndex, iconIndex); + tn.Tag = item; + tn.ToolTipText = item.ToString(); - TreeNode tn2 = AddFolderPath(viewModel.TreeviewPath); + TreeNode tn2 = AddFolderPath(item.TreeviewPath); ThreadControl.Add(tn2, tn); this.HasChanged = true; } - public TreeNode AddItem(TreeNode treeNode, BookmarkItemViewModel viewModel) + public TreeNode AddItem(TreeNode treeNode, BookmarkItem item) { if (treeNode == null) { return null; } - int iconIndex = addIcon(viewModel); + int iconIndex = addIcon(item); - TreeNode tn = new TreeNode(viewModel.SiteName, iconIndex, iconIndex); - tn.Tag = viewModel; - tn.ToolTipText = viewModel.ToString(); + TreeNode tn = new TreeNode(item.SiteName, iconIndex, iconIndex); + tn.Tag = item; + tn.ToolTipText = item.ToString(); treeNode.Nodes.Add(tn); @@ -734,16 +734,15 @@ namespace RyzStudio.Windows.Forms } } - public NodeType GetNodeType() => GetNodeType(this.SelectedNode); public string GetNodePath() => GetNodePath(this.SelectedNode); - public BookmarkItemViewModel GetNodeModel() => GetNodeModel(this.SelectedNode); + public BookmarkItem GetNodeModel() => GetNodeModel(this.SelectedNode); - public List GetBookmarkList() + public List GetBookmarkList() { - List rs = new List(); + List rs = new List(); if (this.Nodes.Count <= 0) { @@ -856,26 +855,26 @@ namespace RyzStudio.Windows.Forms public new void Sort() => Sort(this.SelectedNode); - public void UpdateItem(TreeNode treeNode, BookmarkItemViewModel model, Image image) + public void UpdateItem(TreeNode treeNode, BookmarkItem item, Image image) { if (treeNode == null) { return; } - int iconIndex = addIcon(model); + int iconIndex = addIcon(item); - treeNode.Text = model.SiteName; + treeNode.Text = item.SiteName; treeNode.ImageIndex = iconIndex; treeNode.SelectedImageIndex = iconIndex; - treeNode.Tag = model; - treeNode.ToolTipText = model.ToString(); + treeNode.Tag = item; + treeNode.ToolTipText = item.ToString(); this.HasChanged = true; } - protected int addIcon(BookmarkItemViewModel viewModel) + protected int addIcon(BookmarkItem viewModel) { return (int)IconSet.Default; } @@ -973,28 +972,28 @@ namespace RyzStudio.Windows.Forms return tn; } - protected bool IsNodeChild(TreeNode dragNode, TreeNode dropNode) - { - TreeNode tn = dropNode; - while (true) - { - if (tn.Parent == null) - { - break; - } + //protected bool IsNodeChild(TreeNode dragNode, TreeNode dropNode) + //{ + // TreeNode tn = dropNode; + // while (true) + // { + // if (tn.Parent == null) + // { + // break; + // } - if (tn.Equals(dragNode)) - { - return true; - } + // if (tn.Equals(dragNode)) + // { + // return true; + // } - tn = tn.Parent; - } + // tn = tn.Parent; + // } - return false; - } + // return false; + //} - protected void TraverseBookmarkList(List rs, TreeNode node) + protected void TraverseBookmarkList(List rs, TreeNode node) { foreach (TreeNode tn in node.Nodes) { @@ -1005,7 +1004,7 @@ namespace RyzStudio.Windows.Forms } else if (nodeType == NodeType.Page) { - BookmarkItemViewModel nodeTag = GetNodeModel(tn); + BookmarkItem nodeTag = GetNodeModel(tn); nodeTag.TreeviewPath = GetNodePath(tn); if (nodeTag != null)