[mapguide-commits] r5083 - in sandbox/maestro-3.0/Maestro.Base: . Commands/SiteExplorer Properties Resources UI

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Aug 11 07:10:29 EDT 2010


Author: jng
Date: 2010-08-11 11:10:29 +0000 (Wed, 11 Aug 2010)
New Revision: 5083

Added:
   sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DeleteSelectedItemsCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/NewFolderCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/RenameCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Resources/folder--plus.png
   sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.Designer.cs
   sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.cs
   sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.resx
Modified:
   sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/RefreshCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin
   sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj
   sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs
   sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx
   sandbox/maestro-3.0/Maestro.Base/UI/ISiteExplorer.cs
   sandbox/maestro-3.0/Maestro.Base/UI/RepositoryTreeModel.cs
   sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.Designer.cs
   sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.cs
Log:
This submission enables functionality to modify/update the repository tree model. The following commands have been now added/enabled:
 - Delete Selected Items
 - Rename (there is a problem involving child folder expansion of renamed items that is yet to be fixed)
 - New Folder
 - Refresh


Added: sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DeleteSelectedItemsCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DeleteSelectedItemsCommand.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DeleteSelectedItemsCommand.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -0,0 +1,108 @@
+#region Disclaimer / License
+// Copyright (C) 2010, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at 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.Text;
+using ICSharpCode.Core;
+using Maestro.Base.Services;
+using Maestro.Shared.UI;
+using Maestro.Base.UI;
+
+namespace Maestro.Base.Commands.SiteExplorer
+{
+    internal class DeleteSelectedItemsCommand : AbstractMenuCommand
+    {
+        public override void Run()
+        {
+            var wb = Workbench.Instance;
+            var svc = ServiceRegistry.GetService<ServerConnectionManager>();
+            var exp = wb.ActiveSiteExplorer;
+            if (exp != null)
+            {
+                var conn = svc.GetConnection(exp.ConnectionName);
+                var resSvc = conn.ResourceService;
+                var items = exp.SelectedItems;
+                if (items.Length > 0)
+                {
+                    if (MessageService.AskQuestion(Properties.Resources.ConfirmDelete))
+                    {
+                        DoDelete(wb, resSvc, items);
+                    }
+                }
+            }
+        }
+
+        private void DoDelete(Workbench wb, OSGeo.MapGuide.MaestroAPI.Services.IResourceService resSvc, RepositoryItem[] items)
+        {
+            var pdlg = new ProgressDialog();
+            pdlg.CancelAbortsThread = true;
+
+            string[] args = new string[items.Length];
+            for (int i = 0; i < items.Length; i++)
+            {
+                args[i] = items[i].ResourceId;
+            }
+
+            var work = new Maestro.Shared.UI.ProgressDialog.DoBackgroundWork((worker, e, target) =>
+            {
+                int deleted = 0;
+
+                if (target == null || target.Length == 0)
+                    return deleted;
+
+                int step = 100 / target.Length;
+                int current = 0;
+
+                foreach (RepositoryItem item in target)
+                {
+                    if (worker.CancellationPending || e.Cancel)
+                        return deleted;
+
+                    current += step;
+
+                    if (item.IsRoot) //Wait a minute...!
+                    {
+                        continue;
+                    }
+                    else
+                    {
+                        resSvc.DeleteResource(item.ResourceId);
+                        deleted++;
+                        worker.ReportProgress(current, item.ResourceId);
+                    }
+                }
+
+                //collect affected parents and update the model
+                foreach (RepositoryItem item in target)
+                {
+                    var parent = item.Parent;
+                    if (parent != null)
+                    {
+                        parent.RemoveChild(item);
+                    }
+                }
+
+                return deleted;
+            });
+
+            pdlg.RunOperationAsync(wb, work, items);
+        }
+    }
+}

Added: sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/NewFolderCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/NewFolderCommand.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/NewFolderCommand.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -0,0 +1,56 @@
+#region Disclaimer / License
+// Copyright (C) 2010, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at 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.Text;
+using ICSharpCode.Core;
+using Maestro.Base.Services;
+
+namespace Maestro.Base.Commands.SiteExplorer
+{
+    internal class NewFolderCommand : AbstractMenuCommand
+    {
+        public override void Run()
+        {
+            var wb = Workbench.Instance;
+            var exp = wb.ActiveSiteExplorer;
+            var connMgr = ServiceRegistry.GetService<ServerConnectionManager>();
+            var conn = connMgr.GetConnection(exp.ConnectionName);
+            if (exp.SelectedItems.Length == 1)
+            {
+                var item = exp.SelectedItems[0];
+                if (item.IsFolder)
+                {
+                    string defaultName = "New Folder";
+                    string name = defaultName;
+                    int counter = -1;
+                    while (item.Contains(name))
+                    {
+                        counter++;
+                        name = defaultName + counter;
+                    }
+                    conn.ResourceService.CreateFolder(item.ResourceId + name);
+                    var path = item.Model.GetPath(item);
+                    item.Model.RaiseStructureChanged(new Aga.Controls.Tree.TreeModelEventArgs(path, new object[0]));
+                }
+            }
+        }
+    }
+}

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/RefreshCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/RefreshCommand.cs	2010-08-11 05:18:46 UTC (rev 5082)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/RefreshCommand.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -20,10 +20,20 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using ICSharpCode.Core;
 
 namespace Maestro.Base.Commands.SiteExplorer
 {
-    internal class RefreshCommand : NotImplementedCommand
+    internal class RefreshCommand : AbstractMenuCommand
     {
+        public override void Run()
+        {
+            var wb = Workbench.Instance;
+            var exp = wb.ActiveSiteExplorer;
+            if (exp != null)
+            {
+                exp.RefreshModel();
+            }
+        }
     }
 }

Added: sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/RenameCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/RenameCommand.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/RenameCommand.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -0,0 +1,89 @@
+#region Disclaimer / License
+// Copyright (C) 2010, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at 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.Text;
+using ICSharpCode.Core;
+using Maestro.Base.Services;
+using Maestro.Base.UI;
+
+namespace Maestro.Base.Commands.SiteExplorer
+{
+    internal class RenameCommand : AbstractMenuCommand
+    {
+        public override void Run()
+        {
+            var wb = Workbench.Instance;
+            var exp = wb.ActiveSiteExplorer;
+            var connMgr = ServiceRegistry.GetService<ServerConnectionManager>();
+            var conn = connMgr.GetConnection(exp.ConnectionName);
+            if (exp.SelectedItems.Length == 1)
+            {
+                var current = exp.SelectedItems[0];
+                var parent = current.Parent;
+                List<string> names = new List<string>();
+                foreach (var item in parent.Children)
+                {
+                    if (item != exp.SelectedItems[0])
+                    {
+                        names.Add(item.Name);
+                    }
+                }
+
+                var dlg = new RenameItemDialog(current.Name, names);
+                if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+                {
+                    string oldid = string.Empty;
+                    string newid = string.Empty;
+                    if (current.IsFolder)
+                    {
+                        oldid = parent.ResourceId + current.Name + "/";
+                        newid = parent.ResourceId + dlg.NewName + "/";
+                    }
+                    else
+                    {
+                        oldid = parent.ResourceId + current.Name + "." + current.ResourceType;
+                        newid = parent.ResourceId + dlg.NewName + "." + current.ResourceType;
+                    }
+
+                    //Perform the operation
+                    if (current.IsFolder)
+                    {
+                        if (dlg.UpdateReferences)
+                            conn.ResourceService.MoveFolderWithReferences(oldid, newid, null, null);
+                        else
+                            conn.ResourceService.MoveFolder(oldid, newid, dlg.Overwrite);
+                    }
+                    else
+                    {
+                        if (dlg.UpdateReferences)
+                            conn.ResourceService.MoveResourceWithReferences(oldid, newid, null, null);
+                        else
+                            conn.ResourceService.MoveResource(oldid, newid, dlg.Overwrite);
+                    }
+
+                    current.Name = dlg.NewName;
+                    if (dlg.Overwrite)
+                        parent.RemoveChild(parent[dlg.NewName]);
+                }
+            }
+        }
+    }
+}

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-08-11 05:18:46 UTC (rev 5082)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-08-11 11:10:29 UTC (rev 5083)
@@ -255,7 +255,7 @@
             </Condition>
             <ToolbarItem id="SiteExplorer_Refresh"
                          icon="arrow-circle-045-left"
-                         class="Maestro.Base.Commands.NotImplementedCommand" />
+                         class="Maestro.Base.Commands.SiteExplorer.RefreshCommand" />
             <ToolbarItem id="SiteExplorer_Disconnect"
                          icon="plug--minus"
                          class="Maestro.Base.Commands.SiteExplorer.DisconnectCommand" />
@@ -270,6 +270,14 @@
                       label="${res:Menu_File_NewResource}"
                       tooltip="${res:Menu_File_NewResource}"
                       class="Maestro.Base.Commands.NewItemCommand" />
+            <MenuItem id="NewItem"
+                      icon="folder__plus"
+                      label="${res:SiteExplorer_NewFolder}"
+                      tooltip="${res:SiteExplorer_NewFolder}"
+                      class="Maestro.Base.Commands.SiteExplorer.NewFolderCommand" />
+            <MenuItem id="Rename"
+                      label="${res:SiteExplorer_SelectedItem_Rename}"
+                      class="Maestro.Base.Commands.SiteExplorer.RenameCommand" />
             <MenuItem type="Separator" />
             <MenuItem id="CreatePackage"
                       label="${res:SiteExplorer_SelectedFolder_CreatePackage}"
@@ -293,7 +301,7 @@
             <Condition action="Disable" name="IsNotRoot">
                 <MenuItem id="Delete"
                           label="${res:SiteExplorer_SelectedItem_Delete}"
-                          class="Maestro.Base.Commands.NotImplementedCommand" />
+                          class="Maestro.Base.Commands.SiteExplorer.DeleteSelectedItemsCommand" />
             </Condition>
             <MenuItem id="Validate"
                       label="${res:SiteExplorer_ValidateResources}"
@@ -334,7 +342,7 @@
                       class="Maestro.Base.Commands.SiteExplorer.OpenWithXmlEditorCommand" />
             <MenuItem id="Rename"
                       label="${res:SiteExplorer_SelectedItem_Rename}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+                      class="Maestro.Base.Commands.SiteExplorer.RenameCommand" />
             <MenuItem id="Delete"
                       label="${res:SiteExplorer_SelectedItem_Delete}"
                       class="Maestro.Base.Commands.NotImplementedCommand" />

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-08-11 05:18:46 UTC (rev 5082)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-08-11 11:10:29 UTC (rev 5083)
@@ -62,10 +62,13 @@
     <Compile Include="Commands\QuitCommand.cs" />
     <Compile Include="Commands\SaveResourceAsCommand.cs" />
     <Compile Include="Commands\SaveResourceCommand.cs" />
+    <Compile Include="Commands\SiteExplorer\DeleteSelectedItemsCommand.cs" />
     <Compile Include="Commands\SiteExplorer\DisconnectCommand.cs" />
+    <Compile Include="Commands\SiteExplorer\NewFolderCommand.cs" />
     <Compile Include="Commands\SiteExplorer\OpenResourceCommand.cs" />
     <Compile Include="Commands\SiteExplorer\OpenWithXmlEditorCommand.cs" />
     <Compile Include="Commands\SiteExplorer\RefreshCommand.cs" />
+    <Compile Include="Commands\SiteExplorer\RenameCommand.cs" />
     <Compile Include="Commands\SiteExplorer\ResourcePropertiesCommand.cs" />
     <Compile Include="Commands\SiteExplorer\ValidateCommand.cs" />
     <Compile Include="Commands\StartupCommand.cs" />
@@ -197,6 +200,12 @@
     <Compile Include="UI\NewResourceDialog.Designer.cs">
       <DependentUpon>NewResourceDialog.cs</DependentUpon>
     </Compile>
+    <Compile Include="UI\RenameItemDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="UI\RenameItemDialog.Designer.cs">
+      <DependentUpon>RenameItemDialog.cs</DependentUpon>
+    </Compile>
     <Compile Include="UI\RepositoryTreeModel.cs" />
     <Compile Include="UI\ResourceIconCache.cs" />
     <Compile Include="UI\ResourcePropertiesDialog.cs">
@@ -252,6 +261,7 @@
   </ItemGroup>
   <ItemGroup>
     <Content Include="Maestro.Base.addin" />
+    <None Include="Resources\folder--plus.png" />
     <None Include="Resources\cross.png" />
     <None Include="Resources\blueprints.png" />
     <None Include="Resources\folder-horizontal.png" />
@@ -352,6 +362,9 @@
       <DependentUpon>NewResourceDialog.cs</DependentUpon>
       <SubType>Designer</SubType>
     </EmbeddedResource>
+    <EmbeddedResource Include="UI\RenameItemDialog.resx">
+      <DependentUpon>RenameItemDialog.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="UI\ResourcePropertiesDialog.resx">
       <DependentUpon>ResourcePropertiesDialog.cs</DependentUpon>
       <SubType>Designer</SubType>

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-08-11 05:18:46 UTC (rev 5082)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -260,6 +260,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Are you sure you want to delete?.
+        /// </summary>
+        internal static string ConfirmDelete {
+            get {
+                return ResourceManager.GetString("ConfirmDelete", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Messages.
         /// </summary>
         internal static string Content_Messages {
@@ -440,6 +449,13 @@
             }
         }
         
+        internal static System.Drawing.Bitmap folder__plus {
+            get {
+                object obj = ResourceManager.GetObject("folder__plus", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
         internal static System.Drawing.Bitmap folder_horizontal {
             get {
                 object obj = ResourceManager.GetObject("folder_horizontal", resourceCulture);
@@ -447,6 +463,15 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Question.
+        /// </summary>
+        internal static string Global_QuestionText {
+            get {
+                return ResourceManager.GetString("Global.QuestionText", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap images_stack {
             get {
                 object obj = ResourceManager.GetObject("images_stack", resourceCulture);
@@ -763,6 +788,15 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Rename to.
+        /// </summary>
+        internal static string RenameTo {
+            get {
+                return ResourceManager.GetString("RenameTo", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap reports_stack {
             get {
                 object obj = ResourceManager.GetObject("reports_stack", resourceCulture);
@@ -987,6 +1021,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to New Folder.
+        /// </summary>
+        internal static string SiteExplorer_NewFolder {
+            get {
+                return ResourceManager.GetString("SiteExplorer_NewFolder", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Refresh.
         /// </summary>
         internal static string SiteExplorer_Refresh {

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-08-11 05:18:46 UTC (rev 5082)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-08-11 11:10:29 UTC (rev 5083)
@@ -628,4 +628,19 @@
   <data name="Filter_Shp_Files" xml:space="preserve">
     <value>ESRI Shapefile (*.shp)|*.shp</value>
   </data>
+  <data name="ConfirmDelete" xml:space="preserve">
+    <value>Are you sure you want to delete?</value>
+  </data>
+  <data name="Global.QuestionText" xml:space="preserve">
+    <value>Question</value>
+  </data>
+  <data name="SiteExplorer_NewFolder" xml:space="preserve">
+    <value>New Folder</value>
+  </data>
+  <data name="folder__plus" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\folder--plus.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="RenameTo" xml:space="preserve">
+    <value>Rename to</value>
+  </data>
 </root>
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Base/Resources/folder--plus.png
===================================================================
(Binary files differ)


Property changes on: sandbox/maestro-3.0/Maestro.Base/Resources/folder--plus.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Modified: sandbox/maestro-3.0/Maestro.Base/UI/ISiteExplorer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/ISiteExplorer.cs	2010-08-11 05:18:46 UTC (rev 5082)
+++ sandbox/maestro-3.0/Maestro.Base/UI/ISiteExplorer.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -27,18 +27,9 @@
     {
         string ConnectionName { get; }
 
-        /// <summary>
-        /// Refreshes the contents of entire repository
-        /// </summary>
-        void Refresh();
+        void RefreshModel();
 
         /// <summary>
-        /// Refreshes the contents from the specified folder id
-        /// </summary>
-        /// <param name="folderID"></param>
-        void Refresh(string folderID);
-
-        /// <summary>
         /// Gets the items currently selected
         /// </summary>
         RepositoryItem[] SelectedItems { get; }

Added: sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.Designer.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.Designer.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -0,0 +1,176 @@
+namespace Maestro.Base.UI
+{
+    partial class RenameItemDialog
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.chkOverwrite = new System.Windows.Forms.CheckBox();
+            this.chkUpdateRefs = new System.Windows.Forms.CheckBox();
+            this.btnRename = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.txtOld = new System.Windows.Forms.TextBox();
+            this.txtNew = new System.Windows.Forms.TextBox();
+            this.lblExists = new System.Windows.Forms.Label();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(14, 20);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(54, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "Old Name";
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(13, 44);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(60, 13);
+            this.label2.TabIndex = 1;
+            this.label2.Text = "New Name";
+            // 
+            // chkOverwrite
+            // 
+            this.chkOverwrite.AutoSize = true;
+            this.chkOverwrite.Location = new System.Drawing.Point(16, 77);
+            this.chkOverwrite.Name = "chkOverwrite";
+            this.chkOverwrite.Size = new System.Drawing.Size(153, 17);
+            this.chkOverwrite.TabIndex = 2;
+            this.chkOverwrite.Text = "Overwrite existing resource";
+            this.chkOverwrite.UseVisualStyleBackColor = true;
+            // 
+            // chkUpdateRefs
+            // 
+            this.chkUpdateRefs.AutoSize = true;
+            this.chkUpdateRefs.Checked = true;
+            this.chkUpdateRefs.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkUpdateRefs.Location = new System.Drawing.Point(16, 101);
+            this.chkUpdateRefs.Name = "chkUpdateRefs";
+            this.chkUpdateRefs.Size = new System.Drawing.Size(209, 17);
+            this.chkUpdateRefs.TabIndex = 3;
+            this.chkUpdateRefs.Text = "Update any references to this resource";
+            this.chkUpdateRefs.UseVisualStyleBackColor = true;
+            this.chkUpdateRefs.CheckedChanged += new System.EventHandler(this.chkUpdateRefs_CheckedChanged);
+            // 
+            // btnRename
+            // 
+            this.btnRename.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnRename.Enabled = false;
+            this.btnRename.Location = new System.Drawing.Point(173, 129);
+            this.btnRename.Name = "btnRename";
+            this.btnRename.Size = new System.Drawing.Size(75, 23);
+            this.btnRename.TabIndex = 4;
+            this.btnRename.Text = "Rename";
+            this.btnRename.UseVisualStyleBackColor = true;
+            this.btnRename.Click += new System.EventHandler(this.btnRename_Click);
+            // 
+            // btnCancel
+            // 
+            this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(254, 129);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 5;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.UseVisualStyleBackColor = true;
+            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+            // 
+            // txtOld
+            // 
+            this.txtOld.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtOld.Location = new System.Drawing.Point(91, 17);
+            this.txtOld.Name = "txtOld";
+            this.txtOld.ReadOnly = true;
+            this.txtOld.Size = new System.Drawing.Size(238, 20);
+            this.txtOld.TabIndex = 6;
+            // 
+            // txtNew
+            // 
+            this.txtNew.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtNew.Location = new System.Drawing.Point(91, 41);
+            this.txtNew.Name = "txtNew";
+            this.txtNew.Size = new System.Drawing.Size(238, 20);
+            this.txtNew.TabIndex = 7;
+            this.txtNew.TextChanged += new System.EventHandler(this.txtNew_TextChanged);
+            this.txtNew.MouseLeave += new System.EventHandler(this.txtNew_MouseLeave);
+            // 
+            // lblExists
+            // 
+            this.lblExists.AutoSize = true;
+            this.lblExists.ForeColor = System.Drawing.Color.Red;
+            this.lblExists.Location = new System.Drawing.Point(14, 134);
+            this.lblExists.Name = "lblExists";
+            this.lblExists.Size = new System.Drawing.Size(104, 13);
+            this.lblExists.TabIndex = 8;
+            this.lblExists.Text = "Name already exists!";
+            this.lblExists.Visible = false;
+            // 
+            // RenameItemDialog
+            // 
+            this.AcceptButton = this.btnRename;
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(341, 164);
+            this.ControlBox = false;
+            this.Controls.Add(this.lblExists);
+            this.Controls.Add(this.txtNew);
+            this.Controls.Add(this.txtOld);
+            this.Controls.Add(this.btnCancel);
+            this.Controls.Add(this.btnRename);
+            this.Controls.Add(this.chkUpdateRefs);
+            this.Controls.Add(this.chkOverwrite);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.label1);
+            this.Name = "RenameItemDialog";
+            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+            this.Text = "Rename Item";
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.CheckBox chkOverwrite;
+        private System.Windows.Forms.CheckBox chkUpdateRefs;
+        private System.Windows.Forms.Button btnRename;
+        private System.Windows.Forms.Button btnCancel;
+        private System.Windows.Forms.TextBox txtOld;
+        private System.Windows.Forms.TextBox txtNew;
+        private System.Windows.Forms.Label lblExists;
+    }
+}
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -0,0 +1,87 @@
+#region Disclaimer / License
+// Copyright (C) 2010, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at 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.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Maestro.Base.UI
+{
+    public partial class RenameItemDialog : Form
+    {
+        private RenameItemDialog()
+        {
+            InitializeComponent();
+        }
+
+        public RenameItemDialog(string oldName, IEnumerable<string> names)
+            : this()
+        {
+            txtOld.Text = oldName;
+            existingNames.AddRange(names);
+        }
+
+        public string NewName
+        {
+            get { return txtNew.Text; }
+        }
+
+        public bool UpdateReferences
+        {
+            get { return chkUpdateRefs.Checked; }
+        }
+
+        public bool Overwrite
+        {
+            get { return chkOverwrite.Checked; }
+        }
+
+        private List<string> existingNames = new List<string>();
+
+        private void btnCancel_Click(object sender, EventArgs e)
+        {
+            this.DialogResult = DialogResult.Cancel;
+        }
+
+        private void btnRename_Click(object sender, EventArgs e)
+        {
+            this.DialogResult = DialogResult.OK;
+        }
+
+        private void txtNew_TextChanged(object sender, EventArgs e)
+        {
+            btnRename.Enabled = (txtNew.Text.Length > 0) && (txtNew.Text != txtOld.Text);
+        }
+
+        private void txtNew_MouseLeave(object sender, EventArgs e)
+        {
+            lblExists.Visible = existingNames.Contains(txtNew.Text);
+        }
+
+        private void chkUpdateRefs_CheckedChanged(object sender, EventArgs e)
+        {
+            if (chkUpdateRefs.Checked)
+                chkOverwrite.Checked = true;
+        }
+    }
+}

Added: sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.resx	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/UI/RenameItemDialog.resx	2010-08-11 11:10:29 UTC (rev 5083)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file

Modified: sandbox/maestro-3.0/Maestro.Base/UI/RepositoryTreeModel.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/RepositoryTreeModel.cs	2010-08-11 05:18:46 UTC (rev 5082)
+++ sandbox/maestro-3.0/Maestro.Base/UI/RepositoryTreeModel.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -26,6 +26,7 @@
 using System.Drawing;
 using System.Diagnostics;
 using OSGeo.MapGuide.MaestroAPI.Resource;
+using System.Collections.ObjectModel;
 
 namespace Maestro.Base.UI
 {
@@ -34,13 +35,141 @@
     /// </summary>
     public class RepositoryItem
     {
-        private IRepositoryItem _item;
+        private Dictionary<string, RepositoryItem> _children;
 
+        private bool _notify = false;
+
         public RepositoryItem(IRepositoryItem item)
         {
-            _item = item;
+            _name = string.Empty;
+            _children = new Dictionary<string, RepositoryItem>();
+
+            this.CreatedDate = item.CreatedDate;
+            this.ModifiedDate = item.ModifiedDate;
+            this.Owner = item.Owner;
+            this.ResourceId = item.ResourceId;
+            this.ResourceType = item.ResourceType.ToString();
+            this.Name = item.Name; //set name last because update logic requires other properties be set already
+            
+
+            if (this.IsRoot)
+            {
+                this.Icon = Properties.Resources.server;
+            }
+            else
+            {
+                switch (item.ResourceType)
+                {
+                    case ResourceTypes.DrawingSource:
+                        this.Icon = Properties.Resources.blueprints;
+                        break;
+                    case ResourceTypes.FeatureSource:
+                        this.Icon = Properties.Resources.database_share;
+                        break;
+                    case ResourceTypes.Folder:
+                        this.Icon = Properties.Resources.folder_horizontal;
+                        break;
+                    case ResourceTypes.LayerDefinition:
+                        this.Icon = Properties.Resources.layer;
+                        break;
+                    case ResourceTypes.MapDefinition:
+                        this.Icon = Properties.Resources.map;
+                        break;
+                    case ResourceTypes.WebLayout:
+                        this.Icon = Properties.Resources.application_browser;
+                        break;
+                    case ResourceTypes.ApplicationDefinition:
+                        this.Icon = Properties.Resources.applications_stack;
+                        break;
+                    case ResourceTypes.SymbolLibrary:
+                        this.Icon = Properties.Resources.images_stack;
+                        break;
+                    case ResourceTypes.PrintLayout:
+                        this.Icon = Properties.Resources.printer;
+                        break;
+                    default:
+                        this.Icon = Properties.Resources.document;
+                        break;
+                }
+            }
+
+            _notify = true;
         }
 
+        public bool Contains(string name)
+        {
+            return _children.ContainsKey(name);
+        }
+
+        public RepositoryItem this[string name]
+        {
+            get { return _children[name]; }
+        }
+
+        internal RepositoryTreeModel Model
+        {
+            get;
+            set;
+        }
+
+        public RepositoryItem Parent
+        {
+            get;
+            private set;
+        }
+
+        public IEnumerable<RepositoryItem> Children
+        {
+            get { return _children.Values; }
+        }
+
+        public string NameQualified
+        {
+            get 
+            {
+                if (this.ResourceType == ResourceTypes.Folder.ToString())
+                    return this.Name;
+                else
+                    return this.Name + "." + this.ResourceType; 
+            }
+        }
+
+        internal void AddChildWithoutNotification(RepositoryItem item)
+        {
+            item.Parent = this;
+            _children.Add(item.NameQualified, item);
+        }
+
+        internal void RemoveChildWithoutNotification(RepositoryItem item)
+        {
+            if (_children.ContainsKey(item.NameQualified) && item.Parent == this)
+            {
+                if (_children.Remove(item.NameQualified))
+                {
+                    item.Parent = null;
+                }
+            }
+        }
+
+        public void AddChild(RepositoryItem item)
+        {
+            item.Parent = this;
+            _children.Add(item.NameQualified, item);
+            NotifyStructureChanged();
+        }
+
+        public void RemoveChild(RepositoryItem item)
+        {
+            if (_children.ContainsKey(item.NameQualified) && item.Parent == this)
+            {
+                if (_children.Remove(item.NameQualified))
+                {
+                    item.Parent = null;
+                    NotifyStructureChanged();
+                }
+            }
+        }
+
         public bool IsRoot
         {
             get { return this.ResourceId == "Library://"; }
@@ -48,75 +177,126 @@
 
         public string ResourceId
         {
-            get { return _item.ResourceId; }
+            get;
+            internal set;
         }
 
+        private string _name;
+
         public string Name
         {
-            get { return _item.Name; }
+            get { return _name; }
+            set
+            {
+                var oldq = this.NameQualified;
+                _name = value;
+                if (!oldq.Equals(this.NameQualified))
+                {
+                    if (IsRoot)
+                        return;
+
+                    string parentid = ResourceIdentifier.GetParentFolder(this.ResourceId);
+                    this.ResourceId = parentid + this.NameQualified + ((IsFolder) ? "/" : "");
+                    NotifyNodesChanged();
+                }
+            }
         }
 
+        /// <summary>
+        /// Finds the first attached model
+        /// </summary>
+        /// <returns></returns>
+        private RepositoryTreeModel FindModel()
+        {
+            RepositoryItem item = this;
+            while (item != null)
+            {
+                if (item.Model != null)
+                    return item.Model;
+                item = item.Parent;
+            }
+            return null;
+        }
+
+        private void NotifyNodesChanged()
+        {
+            if (!_notify)
+                return;
+
+            var model = FindModel();
+            if (model != null)
+            {
+                TreePath path = model.GetPath(this);
+                if (path != null)
+                {
+                    var args = new TreeModelEventArgs(path, new object[] { this });
+                    model.RaiseNodesChanged(args);
+                }
+            }
+        }
+
+        private void NotifyStructureChanged()
+        {
+            if (!_notify)
+                return;
+
+            var model = FindModel();
+            if (model != null && this.Parent != null)
+            {
+                TreePath path = model.GetPath(this.Parent);
+                if (path != null)
+                {
+                    var args = new TreeModelEventArgs(path, new object[] { this });
+                    model.RaiseStructureChanged(args);
+                }
+            }
+        }
+
         public string ResourceType
         {
-            get { return _item.ResourceType.ToString(); }
+            get;
+            internal set;
         }
 
+        private string _owner;
+
         public string Owner
         {
-            get { return _item.Owner; }
+            get { return _owner; }
+            set
+            {
+                _owner = value;
+                NotifyNodesChanged();
+            }
         }
 
         public DateTime CreatedDate
         {
-            get { return _item.CreatedDate; }
+            get;
+            internal set;
         }
 
         public DateTime ModifiedDate
         {
-            get { return _item.ModifiedDate; }
+            get;
+            internal set;
         }
 
         public bool IsFolder
         {
-            get { return _item.IsFolder; }
+            get { return this.ResourceId.EndsWith("/"); }
         }
 
         public Image Icon
         {
-            get
-            {
-                if (IsRoot)
-                {
-                    return Properties.Resources.server;
-                }
-                else
-                {
-                    switch (_item.ResourceType)
-                    {
-                        case ResourceTypes.DrawingSource:
-                            return Properties.Resources.blueprints;
-                        case ResourceTypes.FeatureSource:
-                            return Properties.Resources.database_share;
-                        case ResourceTypes.Folder:
-                            return Properties.Resources.folder_horizontal;
-                        case ResourceTypes.LayerDefinition:
-                            return Properties.Resources.layer;
-                        case ResourceTypes.MapDefinition:
-                            return Properties.Resources.map;
-                        case ResourceTypes.WebLayout:
-                            return Properties.Resources.application_browser;
-                        case ResourceTypes.ApplicationDefinition:
-                            return Properties.Resources.applications_stack;
-                        case ResourceTypes.SymbolLibrary:
-                            return Properties.Resources.images_stack;
-                        case ResourceTypes.PrintLayout:
-                            return Properties.Resources.printer;
-                        default:
-                            return Properties.Resources.document;
-                    }
-                }
-            }
+            get;
+            internal set;
         }
+
+        internal void ClearChildrenWithoutNotification()
+        {
+            _children.Clear();
+        }
     }
 
     public class RepositoryItemToolTipProvider : IToolTipProvider
@@ -136,8 +316,10 @@
     /// <summary>
     /// Defines the repository model for the treeview
     /// </summary>
-    public class RepositoryTreeModel : ITreeModel
+    public class RepositoryTreeModel : TreeModelBase
     {
+        private RepositoryItem _rootNode;
+
         private IServerConnection _conn;
 
         public RepositoryTreeModel(IServerConnection conn)
@@ -153,6 +335,7 @@
             foreach (var item in list.Children)
             {
                 var it = new RepositoryItem(item);
+                it.Model = this;
                 if (it.IsFolder)
                     folders.Add(it.ResourceId, it);
                 else
@@ -168,67 +351,87 @@
             }
         }
 
-        public System.Collections.IEnumerable GetChildren(TreePath treePath)
+        public override System.Collections.IEnumerable GetChildren(TreePath treePath)
         {
             if (treePath.IsEmpty())
             {
                 var list = _conn.ResourceService.GetRepositoryResources("Library://", 0);
-                return GetSorted(list);
+                if (list.Items.Count != 1)
+                {
+                    throw new InvalidOperationException(); //Huh?
+                }
+                _rootNode = new RepositoryItem((IRepositoryItem)list.Items[0]);
+                _rootNode.Model = this;
+                yield return _rootNode;
             }
             else
             {
                 var node = treePath.LastNode as RepositoryItem;
                 if (node != null && node.IsFolder) //Can't enumerate children of documents
                 {
+                    node.ClearChildrenWithoutNotification();
                     var list = _conn.ResourceService.GetRepositoryResources(node.ResourceId, "", 1, false);
-                    return GetSorted(list);
+                    foreach (RepositoryItem item in GetSorted(list))
+                    {
+                        node.AddChildWithoutNotification(item);
+                        yield return item;
+                    }
                 }
                 else
                 {
-                    return new RepositoryItem[0];
+                    yield break;
                 }
             }
         }
 
-        public bool IsLeaf(TreePath treePath)
+        public override bool IsLeaf(TreePath treePath)
         {
             return !((RepositoryItem)treePath.LastNode).IsFolder;
         }
 
-        protected void OnNodesChanged(TreeModelEventArgs e)
+        internal void RaiseNodesChanged(TreeModelEventArgs args)
         {
-            var handler = this.NodesChanged;
-            if (handler != null)
-                handler(this, e);
+            base.OnNodesChanged(args);
         }
 
-        public event EventHandler<TreeModelEventArgs> NodesChanged;
-
-        protected void OnNodesInserted(TreeModelEventArgs e)
+        internal TreePath GetPath(RepositoryItem node)
         {
-            var handler = this.NodesInserted;
-            if (handler != null)
-                handler(this, e);
+            if (node == _rootNode)
+            {
+                return new TreePath(node);
+            }
+            else
+            {
+                Stack<object> stack = new Stack<object>();
+                while (node != _rootNode)
+                {
+                    stack.Push(node);
+                    node = node.Parent;
+                }
+                stack.Push(node);
+                return new TreePath(stack.ToArray());
+            }
         }
 
-        public event EventHandler<TreeModelEventArgs> NodesInserted;
-
-        protected void OnNodesRemoved(TreeModelEventArgs e)
+        internal void RaiseStructureChanged(TreeModelEventArgs args)
         {
-            var handler = this.NodesRemoved;
-            if (handler != null)
-                handler(this, e);
+            base.OnStructureChanged(args);
         }
 
-        public event EventHandler<TreeModelEventArgs> NodesRemoved;
-
-        protected void OnStructureChanged(TreePathEventArgs e)
+        internal TreePath GetPathFromResourceId(string resId)
         {
-            var handler = this.StructureChanged;
-            if (handler != null)
-                handler(this, e);
+            string[] components = ResourceIdentifier.GetPath(resId).Split('/');
+            if (!ResourceIdentifier.IsFolderResource(resId))
+            {
+                //Fix extension to last component
+                components[components.Length - 1] = components[components.Length - 1] + "." + ResourceIdentifier.GetResourceType(resId).ToString();
+            }
+            RepositoryItem current = _rootNode;
+            for (int i = 0; i < components.Length; i++)
+            {
+                current = current[components[i]];
+            }
+            return GetPath(current);
         }
-
-        public event EventHandler<TreePathEventArgs> StructureChanged;
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.Designer.cs	2010-08-11 05:18:46 UTC (rev 5082)
+++ sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.Designer.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -77,7 +77,6 @@
             // ndResource
             // 
             this.ndResource.DataPropertyName = "Name";
-            this.ndResource.EditEnabled = true;
             this.ndResource.IncrementalSearchEnabled = true;
             this.ndResource.LeftMargin = 3;
             this.ndResource.ParentColumn = null;

Modified: sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.cs	2010-08-11 05:18:46 UTC (rev 5082)
+++ sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.cs	2010-08-11 11:10:29 UTC (rev 5083)
@@ -65,6 +65,8 @@
             this.ConnectionName = name;
         }
 
+        private RepositoryTreeModel _model;
+
         protected override void OnLoad(EventArgs e)
         {
             this.Title = Properties.Resources.Content_SiteExplorer;
@@ -76,8 +78,8 @@
             var mgr = ServiceRegistry.GetService<ServerConnectionManager>();
             _conn = mgr.GetConnection(this.ConnectionName);
 
-            var model = new RepositoryTreeModel(_conn);
-            trvResources.Model = model;
+            _model = new RepositoryTreeModel(_conn);
+            trvResources.Model = _model;
         }
 
         public override bool AllowUserClose
@@ -96,11 +98,43 @@
             }
         }
 
-        public void Refresh(string folderID)
+        public void RefreshModel()
         {
-            
+            string resId = null;
+            if (this.SelectedItems.Length == 1)
+            {
+                resId = this.SelectedItems[0].ResourceId;
+            }
+            _model.Refresh();
+            ExpandRoot();
+
+            //This doesn't actually work yet :(
+
+            //if (!string.IsNullOrEmpty(resId))
+            //{
+            //    var path = _model.GetPathFromResourceId(resId);
+            //    if (path != TreePath.Empty)
+            //    {
+            //        var node = trvResources.FindNode(path);
+            //        if (node != null)
+            //        {
+            //            while (node.Parent != null)
+            //            {
+            //                node = node.Parent;
+            //                if (!node.IsExpanded)
+            //                    node.Expand();
+            //            }
+            //        }
+            //    }
+            //}
         }
 
+        private void ExpandRoot()
+        {
+            //"Root" of the model is actually the child of the tree root
+            trvResources.Root.Children[0].Expand();
+        }
+
         private void trvResources_MouseDoubleClick(object sender, MouseEventArgs e)
         {
             TreeNodeAdv node = trvResources.GetNodeAt(new Point(e.X, e.Y));



More information about the mapguide-commits mailing list