#region Disclaimer / License // Copyright (C) 2012, Jackie Ng // http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com // // 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.Linq; using System.Text; using System.Windows.Forms; using OSGeo.MapGuide.MaestroAPI.Services; using OSGeo.MapGuide.ObjectModels.Common; using System.Drawing; using OSGeo.MapGuide.MaestroAPI; namespace Maestro.Editors.Common { class DummyNode : TreeNode { } internal class RepositoryModelItem { private IRepositoryItem _item; public RepositoryModelItem(IRepositoryItem item) { _item = item; if (this.IsRoot) { this.ImageIndex = RepositoryIcons.RES_ROOT; } else { if (this.IsFolder) this.ImageIndex = RepositoryIcons.RES_FOLDER; else this.ImageIndex = RepositoryIcons.GetImageIndexForResourceType(_item.ResourceType); } } public int ImageIndex { get; private set; } public string Name { get { return _item.Name; } } public string ResourceId { get { return _item.ResourceId; } } public bool HasChildren { get { return _item.HasChildren; } } public bool IsFolder { get { return _item.IsFolder; } } public bool IsRoot { get { return this.ResourceId == StringConstants.RootIdentifier; } } public IRepositoryItem Instance { get { return _item; } } } internal class RepositoryFolderTreeModel { internal event EventHandler ItemSelected; private IResourceService _resSvc; private TreeView _tree; public RepositoryModelItem SelectedItem { get; private set; } private void StartUpdate() { _tree.BeginUpdate(); _tree.Cursor = Cursors.WaitCursor; } private void EndUpdate() { _tree.EndUpdate(); _tree.Cursor = Cursors.Default; } private bool _bOmitEmptyFolders; private bool _bFoldersOnly; public bool FoldersOnly { get { return _bFoldersOnly; } } public bool OmitEmptyFolders { get { return _bOmitEmptyFolders; } } public RepositoryFolderTreeModel(IResourceService resSvc, TreeView tree, bool bFoldersOnly, bool bOmitEmptyFolders) { _resSvc = resSvc; _tree = tree; _bFoldersOnly = bFoldersOnly; _bOmitEmptyFolders = bOmitEmptyFolders; _tree.AfterExpand += new TreeViewEventHandler(OnNodeAfterExpand); _tree.AfterSelect += new TreeViewEventHandler(OnNodeAfterSelect); _tree.Nodes.Clear(); InitRoot(); } private void InitRoot() { StartUpdate(); foreach (RepositoryModelItem item in GetChildren(null)) { var node = CreateNode(item); _tree.Nodes.Add(node); } EndUpdate(); } void OnNodeAfterSelect(object sender, TreeViewEventArgs e) { RepositoryModelItem item = (RepositoryModelItem)e.Node.Tag; SetSelectedItem(item); } private void SetSelectedItem(RepositoryModelItem item) { this.SelectedItem = item; var handler = this.ItemSelected; if (handler != null) handler(this, EventArgs.Empty); } bool IsNodeNotPopulated(TreeNode node) { return node.Nodes.Count == 1 && node.Nodes[0].GetType() == typeof(DummyNode); } void OnNodeAfterExpand(object sender, TreeViewEventArgs e) { UpdateNode(e.Node); } private void UpdateNode(TreeNode nodeToUpdate) { RepositoryModelItem item = (RepositoryModelItem)nodeToUpdate.Tag; if (IsNodeNotPopulated(nodeToUpdate)) nodeToUpdate.Nodes.Clear(); if (item.HasChildren && nodeToUpdate.Nodes.Count == 0) { StartUpdate(); foreach (RepositoryModelItem child in GetChildren(item)) { var node = CreateNode(child); nodeToUpdate.Nodes.Add(node); } EndUpdate(); } } private static TreeNode CreateNode(RepositoryModelItem item) { var node = new TreeNode(); node.Name = item.Name; node.Text = item.Name; node.Tag = item; node.ImageIndex = node.SelectedImageIndex = item.ImageIndex; if (item.IsFolder) node.Nodes.Add(new DummyNode()); return node; } private System.Collections.IEnumerable GetSorted(ResourceList list) { //Sort them before returning them SortedList folders = new SortedList(); SortedList docs = new SortedList(); foreach (var item in list.Children) { if (item.IsFolder && !item.HasChildren && this.OmitEmptyFolders) continue; if (item.IsFolder) folders.Add(item.ResourceId, new RepositoryModelItem(item)); else if (!HasFilteredTypes() || (HasFilteredTypes() && IsFilteredType(item.ResourceType))) docs.Add(item.ResourceId, new RepositoryModelItem(item)); } foreach (var folder in folders.Values) { yield return folder; } foreach (var doc in docs.Values) { yield return doc; } } private HashSet _filteredTypes = new HashSet(); public void AddResourceTypeFilter(ResourceTypes rt) { _filteredTypes.Add(rt); } public void ClearResourceTypeFilters() { _filteredTypes.Clear(); } public bool HasFilteredTypes() { return _filteredTypes.Count > 0; } public bool IsFilteredType(ResourceTypes rt) { return _filteredTypes.Contains(rt); } public System.Collections.IEnumerable GetChildren(RepositoryModelItem item) { if (item == null) { var list = _resSvc.GetRepositoryResources(StringConstants.RootIdentifier, 0); return GetSorted(list); } else { if (item.HasChildren) { var list = _resSvc.GetRepositoryResources(item.ResourceId, _bFoldersOnly ? ResourceTypes.Folder.ToString() : "", 1, true); //NOXLATE return GetSorted(list); } else { return new RepositoryModelItem[0]; } } } internal void NavigateTo(string folderId) { NavigateTo(folderId, null); } internal void NavigateTo(string folderId, TreeNode currentNode) { TreeNodeCollection nodeList = null; if (currentNode == null) { nodeList = _tree.Nodes; } else { var item = (RepositoryModelItem)currentNode.Tag; if (folderId.Equals(item.ResourceId)) { _tree.SelectedNode = currentNode; SetSelectedItem(item); return; } nodeList = currentNode.Nodes; } foreach (TreeNode node in nodeList) { var folder = (RepositoryModelItem)node.Tag; if (folderId.StartsWith(folder.ResourceId)) { UpdateNode(node); node.Expand(); NavigateTo(folderId, node); break; } } } private TreeNode FindNode(string folderId, TreeNode currentNode) { TreeNodeCollection nodeList = null; if (currentNode == null) { nodeList = _tree.Nodes; } else { var item = (RepositoryModelItem)currentNode.Tag; if (folderId.Equals(item.ResourceId)) { return currentNode; } nodeList = currentNode.Nodes; } foreach (TreeNode node in nodeList) { var folder = (RepositoryModelItem)node.Tag; if (folderId.StartsWith(folder.ResourceId)) { UpdateNode(node); node.Expand(); return FindNode(folderId, node); } } return null; } internal void Refresh(string folderId) { if (string.IsNullOrEmpty(folderId) || folderId == StringConstants.RootIdentifier) { InitRoot(); } else { var node = FindNode(folderId, null); if (node != null) { node.Nodes.Clear(); UpdateNode(node); } } } } }