#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);
}
}
}
}