#region Disclaimer / License // Copyright (C) 2009, Kenneth Skovhede // http://www.hexad.dk, opensource@hexad.dk // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using OSGeo.MapGuide.MaestroAPI; namespace OSGeo.MapGuide.Maestro.ResourceBrowser { /// /// A common treeview control to display the contents of the server repository /// public partial class ResourceTree : TreeView { private RepositoryCache m_cache; private bool m_hideDocuments = false; /// /// Constructs a new tree /// public ResourceTree() : base() { base.BeforeExpand += new TreeViewCancelEventHandler(ResourceTree_BeforeExpand); this.TreeViewNodeSorter = new NodeSorter(); } /// /// Constructs a new tree /// /// The cache to use when building the tree public ResourceTree(RepositoryCache cache) : this() { this.Cache = cache; } /// /// Gets or sets the current cache. Setting this value will cause the tree to refresh /// [Browsable(false)] public RepositoryCache Cache { get { return m_cache; } set { this.Nodes.Clear(); m_cache = value; if (m_cache != null) { this.ImageList = m_cache.EditorMap.SmallImageList; m_cache.BuildTree(this); } else this.Nodes.Clear(); } } private void ResourceTree_BeforeExpand(object sender, TreeViewCancelEventArgs e) { if (m_cache != null) m_cache.BuildNode(e.Node, false); } /// /// Rebuild the contents of a particular node /// /// The node to refresh public void RebuildNode(TreeNode n) { if (n.Tag is ResourceListResourceDocument) n = FindNode(new ResourceIdentifier((n.Tag as ResourceListResourceDocument).ResourceId).RepositoryPath); m_cache.BuildNode(n, true); } /// /// Rebuild the contents of a particular node /// /// The resourceId of the folder node to refresh public void RebuildNode(string path) { RebuildNode(FindNode(path)); } /// /// Gets or sets a value indicating if documents are displayed /// [Browsable(true), Description("Determines if the tree only displays folders or folders and documents"), Category("Behavior"), DefaultValue(false)] public bool HideDocuments { get { return m_hideDocuments; } set { m_hideDocuments = value; if (m_cache != null && this.Nodes.Count > 0) RefreshTreeNodes(); } } private TreeNode FindNode(string resourceId) { Queue unexamined = new Queue(); unexamined.Enqueue(this.Nodes); while (unexamined.Count > 0) { TreeNodeCollection c = unexamined.Dequeue(); foreach (TreeNode n in c) { if (n.Tag is ResourceListResourceFolder && (n.Tag as ResourceListResourceFolder).ResourceId == resourceId) return n; else if (n.Tag is ResourceListResourceDocument && (n.Tag as ResourceListResourceDocument).ResourceId == resourceId) return n; if (n.Nodes.Count > 0) unexamined.Enqueue(n.Nodes); } } return null; } /// /// Gets a list of documents at from the currently selected folder node /// /// A list of documents public List GetDocuments() { if (this.SelectedNode == null) return new List(); return GetDocuments(this.SelectedNode); } /// /// Gets a list of documents at from the given folder node /// /// The node to return the documents for /// A list of documents public List GetDocuments(TreeNode node) { string resId = null; if (node.Parent == null) resId = "Library://"; else if (node.Tag is ResourceListResourceFolder) resId = (node.Tag as ResourceListResourceFolder).ResourceId; if (resId == null) return new List(); else { List docs = m_cache.GetDocuments(resId); docs.Sort(new DocumentSorter()); return docs; } } /// /// Refreshes the entire tree, keeps as many folders open as there were before the refresh, and attempts to re-select the selected node after the refesh /// public void RefreshTreeNodes() { if (m_cache == null) throw new Exception(Strings.ResourceTree.MissingInitializationInternalError); string prevSelected = null; if (this.SelectedNode != null && this.SelectedNode.Tag != null) if (this.SelectedNode.Tag is ResourceListResourceFolder) prevSelected = (this.SelectedNode.Tag as ResourceListResourceFolder).ResourceId; else if (this.SelectedNode.Tag is ResourceListResourceDocument) prevSelected = (this.SelectedNode.Tag as ResourceListResourceDocument).ResourceId; List opennodes = new List(); FindOpenNodes(this.Nodes, opennodes); m_cache.BuildTree(this); foreach (string s in opennodes) { TreeNode n = FindNode(s); if (n != null) n.Expand(); } SelectClosestParent(prevSelected); } /// /// Selects the node that is the closest parent to the given resourceId /// /// public void SelectClosestParent(string resourceId) { if (!string.IsNullOrEmpty(resourceId)) { string endString = ResourceIdentifier.GetRepository(resourceId); while (resourceId != endString && this.SelectedNode == null) { TreeNode n = FindNode(resourceId); if (n == null) resourceId = new ResourceIdentifier(resourceId).ParentFolder; else this.SelectedNode = n; } } } private void FindOpenNodes(TreeNodeCollection nodes, List items) { foreach (TreeNode n in nodes) if (n.IsExpanded) { if (n.Tag is OSGeo.MapGuide.MaestroAPI.ResourceListResourceFolder) items.Add((n.Tag as OSGeo.MapGuide.MaestroAPI.ResourceListResourceFolder).ResourceId); FindOpenNodes(n.Nodes, items); } } } }