bookmark-manager-r4/Windows/Forms/BookmarkTreeView.cs

462 lines
13 KiB
C#
Raw Normal View History

2024-07-17 00:56:17 +00:00
using System.ComponentModel;
2021-09-07 11:32:24 +00:00
using System.Drawing;
using System.Windows.Forms;
2024-07-17 00:56:17 +00:00
using bzit.bomg.Models;
using FizzyLauncher;
2021-09-07 11:32:24 +00:00
using Resources = BookmarkManager.AppResource;
namespace RyzStudio.Windows.Forms
{
2024-07-17 00:56:17 +00:00
public partial class BookmarkTreeView : TTreeView
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
public enum NodeIcon
2021-09-07 11:32:24 +00:00
{
Root = 0,
Folder1,
Folder2,
Default
}
public enum NodeType
{
None = 0,
Root,
Folder,
Page
}
protected const string DEFAULT_NEW_FOLDER_NAME = "New Folder";
public BookmarkTreeView()
{
2024-07-17 00:56:17 +00:00
if (this.ImageList == null)
2021-09-12 13:40:44 +00:00
{
2024-07-17 00:56:17 +00:00
this.ImageList = new ImageList();
2021-09-12 13:40:44 +00:00
}
2024-07-17 00:56:17 +00:00
//this.PathSeparator = PATH_SEPARATOR;
2021-09-12 13:40:44 +00:00
2024-07-17 00:56:17 +00:00
//this.AllowDrop = true;
//this.HideSelection = false;
//this.HotTracking = true;
//this.ImageIndex = 0;
//this.LabelEdit = true;
//this.PathSeparator = "\n";
//this.SelectedImageIndex = 0;
//this.ShowNodeToolTips = true;
2021-09-12 13:40:44 +00:00
2024-07-17 00:56:17 +00:00
this.ImageList.ColorDepth = ColorDepth.Depth32Bit;
this.ImageList.ImageSize = new Size(16, 16);
this.ImageList.TransparentColor = Color.Transparent;
2021-09-12 13:40:44 +00:00
2024-07-17 00:56:17 +00:00
ClearImageList();
2021-09-12 13:40:44 +00:00
}
2024-07-17 00:56:17 +00:00
#region integrated behaviour
2021-09-12 13:40:44 +00:00
protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
switch (this.GetNodeType())
{
case BookmarkTreeView.NodeType.Root:
if (this.RootContextMenu != null) this.RootContextMenu.Show(e.Node.TreeView, e.X, e.Y);
break;
case BookmarkTreeView.NodeType.Folder:
if (this.FolderContextMenu != null) this.FolderContextMenu.Show(e.Node.TreeView, e.X, e.Y);
break;
case BookmarkTreeView.NodeType.Page:
if (this.PageContextMenu != null) this.PageContextMenu.Show(e.Node.TreeView, e.X, e.Y);
break;
default:
break;
}
}
base.OnNodeMouseClick(e);
}
protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
{
TreeNode tn = this.SelectedNode;
if (tn == null)
{
return;
}
NodeType nodeType = this.GetNodeType();
switch (e.KeyCode)
{
case Keys.Insert:
if (e.Modifiers == Keys.Shift)
{
if ((nodeType == NodeType.Root) || (nodeType == NodeType.Folder))
{
this.SelectedNode = this.AddFolder();
}
else if (nodeType == NodeType.Page)
{
this.SelectedNode = tn.Parent;
this.SelectedNode = this.AddFolder();
}
}
2024-07-17 00:56:17 +00:00
else
{
if ((nodeType == NodeType.Root) || (nodeType == NodeType.Folder))
{
this.SelectedNode = this.AddNode();
}
else if (nodeType == NodeType.Page)
{
this.SelectedNode = tn.Parent;
this.SelectedNode = this.AddNode();
}
}
2021-09-12 13:40:44 +00:00
break;
case Keys.Delete:
if (!tn.IsEditing)
{
2024-07-17 00:56:17 +00:00
if (MessageBox.Show("Delete?", "Delete?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes)
{
this.DeleteNode();
}
2021-09-12 13:40:44 +00:00
}
break;
case Keys.F2:
2024-07-17 00:56:17 +00:00
this.EditNode();
2021-09-12 13:40:44 +00:00
break;
case Keys.F3:
switch (nodeType)
{
case NodeType.Root:
case NodeType.Folder:
try
{
Clipboard.SetText(tn.Text ?? string.Empty);
}
catch
{
}
break;
case NodeType.Page:
2024-07-17 00:56:17 +00:00
var viewModel = UIControl.GetTag<BookmarkModel>(this.SelectedNode);
2021-09-12 13:40:44 +00:00
if (viewModel != null)
{
try
{
2024-07-17 00:56:17 +00:00
Clipboard.SetText(viewModel.Address ?? string.Empty);
2021-09-12 13:40:44 +00:00
}
catch
{
}
}
break;
default:
break;
}
break;
case Keys.Up:
if (e.Modifiers == Keys.Control)
{
this.MoveUp();
this.HasChanged = true;
}
break;
case Keys.Down:
if (e.Modifiers == Keys.Control)
{
this.MoveDown();
this.HasChanged = true;
}
break;
case Keys.Apps:
this.OnNodeMouseClick(new TreeNodeMouseClickEventArgs(tn, MouseButtons.Right, 1, tn.Bounds.X, tn.Bounds.Y));
break;
default: break;
}
base.OnPreviewKeyDown(e);
}
#endregion
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ContextMenuStrip RootContextMenu { get; set; } = null;
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ContextMenuStrip FolderContextMenu { get; set; } = null;
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ContextMenuStrip PageContextMenu { get; set; } = null;
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new bool HasChanged
{
get => base.HasChanged;
set
{
base.HasChanged = value;
}
}
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
public TreeNode AddFolder(TreeNode node = null, string name = "", bool quol = true)
2021-09-07 11:32:24 +00:00
{
if (node == null)
{
2024-07-17 00:56:17 +00:00
node = this.SelectedNode;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
var nodeType = GetNodeType(node);
if ((nodeType != NodeType.Root) && (nodeType != NodeType.Folder))
2021-09-07 11:32:24 +00:00
{
return null;
}
if (string.IsNullOrWhiteSpace(name))
{
name = DEFAULT_NEW_FOLDER_NAME;
}
2024-07-17 00:56:17 +00:00
var key = EncodeNodeName(name);
var treeNode = node.Nodes.Add(key, name, (int)NodeIcon.Folder1, (int)NodeIcon.Folder2);
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
if (quol)
{
node.Expand();
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
this.SelectedNode = treeNode;
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
this.EditNode(treeNode);
}
2021-09-21 13:53:18 +00:00
2024-07-17 00:56:17 +00:00
return treeNode;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
public TreeNode AddNode(TreeNode node = null)
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
if (node == null)
{
node = this.SelectedNode;
}
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
var nodeType = GetNodeType(node);
if ((nodeType != NodeType.Root) && (nodeType != NodeType.Folder))
{
return null;
}
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
var form = new EditBookmarkForm();
if (form.ShowDialog() == DialogResult.OK)
{
var model = form.Result;
model.Path = GetNodePath(node);
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
var newNode = this.AddNode(model);
if (newNode != null)
{
newNode.EnsureVisible();
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
this.SelectedNode = newNode;
2021-09-14 19:36:04 +00:00
2024-07-17 00:56:17 +00:00
return newNode;
}
}
return null;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
public TreeNode AddNode(BookmarkModel model)
2021-09-07 11:32:24 +00:00
{
var parentNode = this.CreateNodePath(model?.Path?.Trim() ?? string.Empty, (int)NodeIcon.Folder1, (int)NodeIcon.Folder2);
2024-07-17 00:56:17 +00:00
int iconIndex = (int)NodeIcon.Default;
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
// Add custom favicon
if (model.Icon != null)
{
var iconKey = model.Id.ToString();
if (!string.IsNullOrWhiteSpace(iconKey))
{
if (this.ImageList.Images.ContainsKey(iconKey))
{
this.ImageList.Images.RemoveByKey(iconKey);
}
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
UIControl.Invoke(this, (x) =>
{
this.ImageList.Images.Add(iconKey, model.Icon);
});
2021-09-30 22:09:55 +00:00
2024-07-17 00:56:17 +00:00
iconIndex = this.ImageList.Images.IndexOfKey(iconKey);
}
}
2021-09-30 22:09:55 +00:00
TreeNode newNode = new TreeNode(model?.Title?.Trim() ?? string.Empty, iconIndex, iconIndex);
2024-07-17 00:56:17 +00:00
newNode.Tag = model;
newNode.ToolTipText = model.ToString();
2021-09-30 22:09:55 +00:00
2024-07-17 00:56:17 +00:00
UIControl.Add(parentNode, newNode);
2021-09-07 11:32:24 +00:00
this.HasChanged = true;
2024-07-17 00:56:17 +00:00
return newNode;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
public void Clear(string rootName)
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
ClearImageList();
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
UIControl.Clear(this);
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
UIControl.Invoke(this, (x) =>
{
this.Nodes.Add("", rootName?.Trim() ?? string.Empty, (int)NodeIcon.Root, (int)NodeIcon.Root);
});
this.HasChanged = true;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
public TreeNode EditNode(TreeNode node = null)
2021-09-07 11:32:24 +00:00
{
if (node == null)
{
2024-07-17 00:56:17 +00:00
node = this.SelectedNode;
2021-09-07 11:32:24 +00:00
}
if (node.IsEditing)
{
2024-07-17 00:56:17 +00:00
return null;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
var nodeType = GetNodeType(node);
if ((nodeType == NodeType.Root) || (nodeType == NodeType.Folder))
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
_allowBeginEdit = true;
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
node.BeginEdit();
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
else if (nodeType == NodeType.Page)
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
var model = UIControl.GetTag<BookmarkModel>(node);
model.Path = GetNodePath(node);
var form = new EditBookmarkForm(model);
if (form.ShowDialog() == DialogResult.OK)
{
this.UpdateNode(node, form.Result);
}
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
return node;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
public NodeType GetNodeType(TreeNode node = null)
2021-09-07 11:32:24 +00:00
{
if (node == null)
{
2024-07-17 00:56:17 +00:00
node = this.SelectedNode;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
if (node == null)
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
return NodeType.None;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
if (node.Tag == null)
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
if (node.Equals(node.TreeView.Nodes[0]))
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
return NodeType.Root;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
else
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
return NodeType.Folder;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
}
else
{
if (node.Tag is BookmarkModel)
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
return NodeType.Page;
2021-09-07 11:32:24 +00:00
}
else
{
2024-07-17 00:56:17 +00:00
return NodeType.None;
2021-09-07 11:32:24 +00:00
}
}
}
2024-07-17 00:56:17 +00:00
public void UpdateNode(TreeNode node, BookmarkModel model)
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
if (node == null)
2021-09-21 13:53:18 +00:00
{
2024-07-17 00:56:17 +00:00
node = this.SelectedNode;
2021-09-21 13:53:18 +00:00
}
2024-07-17 00:56:17 +00:00
if (node == null)
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
return;
2021-09-07 11:32:24 +00:00
}
2024-07-17 00:56:17 +00:00
if (model == null)
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
return;
2021-09-07 11:32:24 +00:00
}
var iconKey = "default";
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
// Update custom favicon
var key = model.Id.ToString();
if (!string.IsNullOrWhiteSpace(key))
2021-09-07 11:32:24 +00:00
{
if (model.Icon != null)
{
UIControl.Invoke(this, (x) =>
{
this.ImageList.Images.Add(key, model.Icon);
2024-07-17 00:56:17 +00:00
});
2021-09-07 11:32:24 +00:00
iconKey = key;
2021-09-07 11:32:24 +00:00
}
}
2024-07-17 00:56:17 +00:00
UIControl.Invoke(this, (x) =>
{
node.Text = model.Title;
node.ImageKey = iconKey;
node.SelectedImageKey = iconKey;
2024-07-17 00:56:17 +00:00
node.Tag = model;
node.ToolTipText = model.ToString();
});
2021-09-07 11:32:24 +00:00
2024-07-17 00:56:17 +00:00
this.HasChanged = true;
2021-09-30 22:09:55 +00:00
}
2024-07-17 00:56:17 +00:00
private void ClearImageList()
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
UIControl.Invoke(this, (x) =>
2021-09-07 11:32:24 +00:00
{
2024-07-17 00:56:17 +00:00
this.ImageList.Images.Clear();
this.ImageList.Images.Add(Resources.hexagon);
this.ImageList.Images.Add(Resources.folder);
this.ImageList.Images.Add(Resources.folder_explore);
this.ImageList.Images.Add("default", Resources.file_text);
2024-07-17 00:56:17 +00:00
});
2021-09-07 11:32:24 +00:00
}
}
}