using System; using System.Collections.Generic; using System.Drawing; using System.Reflection; using System.Windows.Forms; using DelftTools.Shell.Core; using log4net; namespace DelftTools.Controls.Swf.TreeViewControls { public class TreeNode : System.Windows.Forms.TreeNode, ITreeNode, IObserver { private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly TreeNodeList nodes; private readonly ITreeView treeView; protected bool isLoaded; private object tag; private IObservable observable; public TreeNode(ITreeView treeView) { this.treeView = treeView; nodes = new TreeNodeList(base.Nodes); IsVisible = true; } /// /// Called when a user right clicks in the network tree /// public override ContextMenuStrip ContextMenuStrip { get { return Presenter != null ? Presenter.GetContextMenu(this, Tag) : null; } } /// /// Used in rendering (has children indicates if a plus or minus must be drawn) /// public bool HasChildren { get; set; } public new ITreeView TreeView { get { return treeView; } } public ITreeNodePresenter Presenter { get; set; } public new string Text { get { return base.Text; } set { if (base.Text != value) { base.Text = value; } } } public new object Tag { get { return tag; } set { if (value == null) { throw new ArgumentNullException(); } if (tag == value) { return; } if (observable != null) { observable.Detach(this); } tag = value; observable = tag as IObservable; if (observable != null) { observable.Attach(this); } } } public new bool IsVisible { get; set; } public new ITreeNode Parent { get { return (ITreeNode) base.Parent; } } public new string FullPath { get { return base.TreeView == null ? string.Empty : base.FullPath; } } public new ITreeNode NextNode { get { return (ITreeNode) base.NextNode; } } public new ITreeNode NextVisibleNode { get { return (ITreeNode) base.NextVisibleNode; } } public new IList Nodes { get { if (!isLoaded) { RefreshChildNodes(); } return nodes; } } public ITreeNode PreviousNode { get { return (ITreeNode) PrevNode; } } public ITreeNode PreviousVisibleNode { get { return (ITreeNode) PrevVisibleNode; } } public bool IsLoaded { get { return isLoaded; } } public bool ShowCheckBox { get; set; } public Color BackgroundColor { get { return BackColor; } set { BackColor = value; } } public Color ForegroundColor { get { return ForeColor; } set { ForeColor = value; } } public bool Bold { get; set; } public Image Image { get; set; } public bool IsUpdating { get; private set; } public void RefreshChildNodes(bool forcedRefresh = false) { if (IsUpdating && !forcedRefresh) { return; //prevent 're-entrancy' issues } IsUpdating = true; TreeView.RefreshChildNodes(this); isLoaded = true; IsUpdating = false; } /// /// Check if the node is a descendent of another node /// /// /// public bool IsChildOf(ITreeNode node) { ITreeNode parentNode = this; while (parentNode != null && parentNode.Parent != null) { if (parentNode.Parent.Equals(node)) { return true; } parentNode = parentNode.Parent; } return false; } public void UpdateObserver() { Update(); } public new void EnsureVisible() { base.EnsureVisible(); } public new void Expand() { if (!isLoaded) { TreeView.RefreshChildNodes(this); } base.Expand(); } public void Update() { if (IsUpdating) { return; //prevent 're-entrancy' issues } IsUpdating = true; TreeView.UpdateNode(this); IsUpdating = false; } public ITreeNode GetParentOfLevel(int level) { ITreeNode node = this; for (var i = Level; i != level; i--) { node = node.Parent; } return node; } public void ScrollTo() { EnsureVisible(); } public ITreeNode GetNodeByTag(object item) { foreach (ITreeNode node in nodes) { if (node.Tag == item) { return node; } } return null; } public void ShowContextMenu(Point location) { if (base.ContextMenuStrip != null) { base.ContextMenuStrip.Show(location); } } public void Dispose() { if (observable != null) { observable.Detach(this); } } private static Font CreateBoldFont(Font font, bool bold) { if (font.Bold != bold) { FontStyle style; if (bold) { style = font.Style | FontStyle.Bold; } else { //'substract' the bold style = (FontStyle) ((int) font.Style - (int) FontStyle.Bold); } return new Font(font.Name, font.Size, style, font.Unit, font.GdiCharSet, font.GdiVerticalFont); } return new Font(font, font.Style); } } }