bookmark-manager-r4/Windows/Forms/BookmarkTreeView.cs
2024-08-04 13:51:19 +01:00

472 lines
13 KiB
C#

using System;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using bzit.bomg.Models;
using FizzyLauncher;
using Resources = BookmarkManager.AppResource;
namespace RyzStudio.Windows.Forms
{
public partial class BookmarkTreeView : TTreeView
{
public enum NodeIcon
{
Root = 0,
Folder1,
Folder2,
Default
}
public enum NodeType
{
None = 0,
Root,
Folder,
Page
}
protected const string DEFAULT_NEW_FOLDER_NAME = "New Folder";
public BookmarkTreeView()
{
if (this.ImageList == null)
{
this.ImageList = new ImageList();
}
//this.PathSeparator = PATH_SEPARATOR;
//this.AllowDrop = true;
//this.HideSelection = false;
//this.HotTracking = true;
//this.ImageIndex = 0;
//this.LabelEdit = true;
//this.PathSeparator = "\n";
//this.SelectedImageIndex = 0;
//this.ShowNodeToolTips = true;
this.ImageList.ColorDepth = ColorDepth.Depth32Bit;
this.ImageList.ImageSize = new Size(16, 16);
this.ImageList.TransparentColor = Color.Transparent;
ClearImageList();
}
#region integrated behaviour
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();
}
}
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();
}
}
break;
case Keys.Delete:
if (!tn.IsEditing)
{
if (MessageBox.Show("Delete?", "Delete?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes)
{
this.DeleteNode();
this.HasChanged = true;
}
}
break;
case Keys.F2:
this.EditNode();
break;
case Keys.F3:
switch (nodeType)
{
case NodeType.Root:
case NodeType.Folder:
try
{
Clipboard.SetText(tn.Text ?? string.Empty);
}
catch
{
}
break;
case NodeType.Page:
var viewModel = UIControl.GetTag<BookmarkModel>(this.SelectedNode);
if (viewModel != null)
{
try
{
Clipboard.SetText(viewModel.Address ?? string.Empty);
}
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;
}
}
public TreeNode AddFolder(TreeNode node = null, string name = "", bool quol = true)
{
if (node == null)
{
node = this.SelectedNode;
}
var nodeType = GetNodeType(node);
if ((nodeType != NodeType.Root) && (nodeType != NodeType.Folder))
{
return null;
}
if (string.IsNullOrWhiteSpace(name))
{
name = DEFAULT_NEW_FOLDER_NAME;
}
var key = EncodeNodeName(name);
var treeNode = node.Nodes.Add(key, name, (int)NodeIcon.Folder1, (int)NodeIcon.Folder2);
if (quol)
{
node.Expand();
this.SelectedNode = treeNode;
this.EditNode(treeNode);
}
this.HasChanged = true;
return treeNode;
}
public TreeNode AddNode(TreeNode node = null)
{
if (node == null)
{
node = this.SelectedNode;
}
var nodeType = GetNodeType(node);
if ((nodeType != NodeType.Root) && (nodeType != NodeType.Folder))
{
return null;
}
var form = new EditBookmarkForm();
if (form.ShowDialog() == DialogResult.OK)
{
var model = form.Result;
model.Path = GetNodePath(node);
var newNode = this.AddNode(model);
if (newNode != null)
{
newNode.EnsureVisible();
this.SelectedNode = newNode;
this.HasChanged = true;
return newNode;
}
}
return null;
}
public TreeNode AddNode(BookmarkModel model)
{
var parentNode = this.CreateNodePath(model?.Path?.Trim() ?? string.Empty, (int)NodeIcon.Folder1, (int)NodeIcon.Folder2);
// Add custom favicon
var n = AddImage(model.Id.ToString(), model.Icon);
TreeNode newNode = new TreeNode(model?.Title?.Trim() ?? string.Empty, n, n);
newNode.Tag = model;
newNode.ToolTipText = model.ToString();
UIControl.Add(parentNode, newNode);
this.HasChanged = true;
return newNode;
}
public void Clear(string rootName)
{
ClearImageList();
UIControl.Clear(this);
UIControl.Invoke(this, (x) =>
{
this.Nodes.Add("", rootName?.Trim() ?? string.Empty, (int)NodeIcon.Root, (int)NodeIcon.Root);
});
this.HasChanged = true;
}
public TreeNode EditNode(TreeNode node = null)
{
if (node == null)
{
node = this.SelectedNode;
}
if (node.IsEditing)
{
return null;
}
var nodeType = GetNodeType(node);
if ((nodeType == NodeType.Root) || (nodeType == NodeType.Folder))
{
_allowBeginEdit = true;
node.BeginEdit();
}
else if (nodeType == NodeType.Page)
{
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);
}
}
return node;
}
public NodeType GetNodeType(TreeNode node = null)
{
if (node == null)
{
node = this.SelectedNode;
}
if (node == null)
{
return NodeType.None;
}
if (node.Tag == null)
{
if (node.Equals(node.TreeView.Nodes[0]))
{
return NodeType.Root;
}
else
{
return NodeType.Folder;
}
}
else
{
if (node.Tag is BookmarkModel)
{
return NodeType.Page;
}
else
{
return NodeType.None;
}
}
}
public void UpdateNode(TreeNode node, BookmarkModel model)
{
if (node == null)
{
node = this.SelectedNode;
return;
}
if (model == null)
{
return;
}
if (model.Id == Guid.Empty)
{
return;
}
// Update custom favicon
var n = AddImage(model.Id.ToString(), model.Icon);
UIControl.Invoke(this, (x) =>
{
node.Text = model.Title;
node.ImageIndex = node.SelectedImageIndex = n;
node.Tag = model;
node.ToolTipText = model.ToString();
});
this.HasChanged = true;
}
private void ClearImageList()
{
UIControl.Invoke(this, (x) =>
{
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);
});
}
private int AddImage(string key, Image image)
{
if (image == null)
{
return (int)NodeIcon.Default;
}
try
{
if (image.Width <= 0)
{
return (int)NodeIcon.Default;
}
}
catch (Exception)
{
return (int)NodeIcon.Default;
}
UIControl.Invoke(this, (x) =>
{
if (this.ImageList.Images.ContainsKey(key))
{
var n = this.ImageList.Images.IndexOfKey(key);
this.ImageList.Images.SetKeyName(n, ".deleted");
}
this.ImageList.Images.Add(key, image);
});
return this.ImageList.Images.IndexOfKey(key);
}
}
}