c90a34904d
Fixed update-icon close button
470 lines
14 KiB
C#
470 lines
14 KiB
C#
using System.ComponentModel;
|
|
using System.Drawing;
|
|
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();
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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;
|
|
|
|
return newNode;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public TreeNode AddNode(BookmarkModel model)
|
|
{
|
|
var parentNode = this.CreateNodePath(model?.Path?.Trim() ?? string.Empty, (int)NodeIcon.Folder1, (int)NodeIcon.Folder2);
|
|
int iconIndex = (int)NodeIcon.Default;
|
|
|
|
// 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);
|
|
}
|
|
|
|
UIControl.Invoke(this, (x) =>
|
|
{
|
|
this.ImageList.Images.Add(iconKey, model.Icon);
|
|
});
|
|
|
|
iconIndex = this.ImageList.Images.IndexOfKey(iconKey);
|
|
}
|
|
}
|
|
|
|
TreeNode newNode = new TreeNode(model?.Title?.Trim() ?? string.Empty, iconIndex, iconIndex);
|
|
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;
|
|
}
|
|
|
|
if (node == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (model == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var iconIndex = (int)NodeIcon.Default;
|
|
|
|
// Update custom favicon
|
|
var iconKey = model.Id.ToString();
|
|
if (!string.IsNullOrWhiteSpace(iconKey))
|
|
{
|
|
UIControl.Invoke(this, (x) =>
|
|
{
|
|
if (this.ImageList.Images.ContainsKey(iconKey))
|
|
{
|
|
this.ImageList.Images.RemoveByKey(iconKey);
|
|
}
|
|
});
|
|
|
|
if (model.Icon != null)
|
|
{
|
|
UIControl.Invoke(this, (x) =>
|
|
{
|
|
this.ImageList.Images.Add(iconKey, model.Icon);
|
|
});
|
|
|
|
iconIndex = this.ImageList.Images.IndexOfKey(iconKey);
|
|
}
|
|
}
|
|
|
|
UIControl.Invoke(this, (x) =>
|
|
{
|
|
node.Text = model.Title;
|
|
node.ImageIndex = iconIndex;
|
|
node.SelectedImageIndex = iconIndex;
|
|
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(Resources.file_text);
|
|
});
|
|
}
|
|
|
|
}
|
|
} |