[mapguide-commits] r5219 - in sandbox/maestro-3.0/Maestro.Base: . Commands Commands/Conditions Commands/SiteExplorer Editor Properties Services UI UI/Preferences

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu Sep 30 01:23:02 EDT 2010


Author: jng
Date: 2010-09-30 05:23:01 +0000 (Thu, 30 Sep 2010)
New Revision: 5219

Added:
   sandbox/maestro-3.0/Maestro.Base/Commands/Conditions/CutCopyConditionEvaluator.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/Conditions/PasteConditionEvaluator.cs
   sandbox/maestro-3.0/Maestro.Base/Services/ClipboardService.cs
Modified:
   sandbox/maestro-3.0/Maestro.Base/Commands/CopyCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/CutCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/PasteCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/OpenResourceCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.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/Services/OpenResourceManager.cs
   sandbox/maestro-3.0/Maestro.Base/UI/ISiteExplorer.cs
   sandbox/maestro-3.0/Maestro.Base/UI/Preferences/ConfigProperties.cs
   sandbox/maestro-3.0/Maestro.Base/UI/RepositoryTreeModel.cs
   sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.cs
Log:
More 3.0 sandbox changes:
 - Implement cut/copy/paste functionality
 - Forward-port site explorer features from 2.x stream
   - Highlight open resources
   - Highlight open resources w/ dirty state


Added: sandbox/maestro-3.0/Maestro.Base/Commands/Conditions/CutCopyConditionEvaluator.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/Conditions/CutCopyConditionEvaluator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/Conditions/CutCopyConditionEvaluator.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -0,0 +1,43 @@
+#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;
+
+namespace Maestro.Base.Commands.Conditions
+{
+    internal class CutCopyConditionEvaluator : IConditionEvaluator
+    {
+        public bool IsValid(object caller, Condition condition)
+        {
+            var wb = Workbench.Instance;
+            if (wb != null)
+            {
+                var exp = wb.ActiveSiteExplorer;
+                if (exp != null)
+                {
+                    return exp.SelectedItems.Length > 0;
+                }
+            }
+            return false;
+        }
+    }
+}

Added: sandbox/maestro-3.0/Maestro.Base/Commands/Conditions/PasteConditionEvaluator.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/Conditions/PasteConditionEvaluator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/Conditions/PasteConditionEvaluator.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -0,0 +1,36 @@
+#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.Conditions
+{
+    internal class PasteConditionEvaluator : IConditionEvaluator
+    {
+        public bool IsValid(object caller, Condition condition)
+        {
+            var svc = ServiceRegistry.GetService<ClipboardService>();
+            return svc.HasContent();
+        }
+    }
+}

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/CopyCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/CopyCommand.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/CopyCommand.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -20,10 +20,76 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using ICSharpCode.Core;
+using Maestro.Base.Services;
+using Maestro.Base.UI;
 
 namespace Maestro.Base.Commands
 {
-    internal class CopyCommand : NotImplementedCommand
+    internal class CopyCommand : ClipboardCommand
     {
+        public override void Run()
+        {
+            var wb = Workbench.Instance;
+            var exp = wb.ActiveSiteExplorer;
+            var clip = ServiceRegistry.GetService<ClipboardService>();
+            var omgr = ServiceRegistry.GetService<OpenResourceManager>();
+
+            ResetClipboardedItems(clip, omgr);
+
+            if (exp.SelectedItems.Length > 0)
+            {
+                var items = new List<RepositoryItem>();
+                foreach (var item in exp.SelectedItems)
+                {
+                    item.ClipboardState = RepositoryItem.ClipboardAction.Copy;
+                    items.Add(item);
+                }
+                clip.Put(items.ToArray());
+                LoggingService.InfoFormatted(Properties.Resources.ItemsCopied, items.Count);
+            }
+        }
     }
+
+    internal abstract class ClipboardCommand : AbstractMenuCommand
+    {
+        protected static void ResetClipboardedItems(ClipboardService clip, OpenResourceManager omgr)
+        {
+            //Reset state of clipboarded items
+            if (clip.HasContent())
+            {
+                object o = clip.Get();
+                var r = o as RepositoryItem;
+                var rs = o as RepositoryItem[];
+                if (r != null)
+                {
+                    ResetItem(omgr, r);
+                }
+                else if (rs != null)
+                {
+                    ResetItems(omgr, rs);
+                }
+            }
+        }
+
+        protected static void ResetItems(OpenResourceManager omgr, IEnumerable<RepositoryItem> rs)
+        {
+            foreach (var ri in rs)
+            {
+                ResetItem(omgr, ri);
+            }
+        }
+
+        protected static void ResetItem(OpenResourceManager omgr, RepositoryItem ri)
+        {
+            ri.Reset();
+            if (omgr.IsOpen(ri.ResourceId))
+            {
+                ri.IsOpen = true;
+                var ed = omgr.GetOpenEditor(ri.ResourceId);
+                if (ed.IsDirty)
+                    ri.IsDirty = true;
+            }
+        }
+    }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/CutCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/CutCommand.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/CutCommand.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -20,10 +20,70 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using ICSharpCode.Core;
+using Maestro.Base.Services;
+using Maestro.Base.UI;
 
 namespace Maestro.Base.Commands
 {
-    internal class CutCommand : NotImplementedCommand
+    internal class CutCommand : ClipboardCommand
     {
+        public override void Run()
+        {
+            var wb = Workbench.Instance;
+            var exp = wb.ActiveSiteExplorer;
+            var clip = ServiceRegistry.GetService<ClipboardService>();
+            var omgr = ServiceRegistry.GetService<OpenResourceManager>();
+
+            ResetClipboardedItems(clip, omgr);
+
+            if (exp.SelectedItems.Length > 0)
+            {
+                var items = new List<RepositoryItem>();
+                foreach (var item in exp.SelectedItems)
+                {
+                    item.ClipboardState = RepositoryItem.ClipboardAction.Cut;
+                    items.Add(item);
+                }
+                clip.Put(items.ToArray());
+                LoggingService.InfoFormatted(Properties.Resources.ItemsCut, items.Count);
+            }
+        }
+
+        private static void ResetClipboardedItems(ClipboardService clip, OpenResourceManager omgr)
+        {
+            //Reset state of clipboarded items
+            if (clip.HasContent())
+            {
+                object o = clip.Get();
+                var r = o as RepositoryItem;
+                var rs = o as RepositoryItem[];
+                if (r != null)
+                {
+                    r.Reset();
+                    if (omgr.IsOpen(r.ResourceId))
+                    {
+                        r.IsOpen = true;
+                        var ed = omgr.GetOpenEditor(r.ResourceId);
+                        if (ed.IsDirty)
+                            r.IsDirty = true;
+                    }
+                }
+                else if (rs != null)
+                {
+                    foreach (var ri in rs)
+                    {
+                        ri.Reset();
+                        if (omgr.IsOpen(ri.ResourceId))
+                        {
+                            ri.IsOpen = true;
+                            var ed = omgr.GetOpenEditor(ri.ResourceId);
+                            if (ed.IsDirty)
+                                ri.IsDirty = true;
+                        }
+                    }
+                }
+            }
+        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/PasteCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/PasteCommand.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/PasteCommand.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -20,10 +20,97 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using ICSharpCode.Core;
+using Maestro.Base.Services;
+using Maestro.Base.UI;
+using OSGeo.MapGuide.MaestroAPI.Resource;
+using Maestro.Shared.UI;
 
 namespace Maestro.Base.Commands
 {
-    internal class PasteCommand : NotImplementedCommand
+    internal class PasteCommand : ClipboardCommand
     {
+        public override void Run()
+        {
+            var wb = Workbench.Instance;
+            var exp = wb.ActiveSiteExplorer;
+            var clip = ServiceRegistry.GetService<ClipboardService>();
+            var omgr = ServiceRegistry.GetService<OpenResourceManager>();
+            var connMgr = ServiceRegistry.GetService<ServerConnectionManager>();
+            var conn = connMgr.GetConnection(exp.ConnectionName);
+
+            if (!clip.HasContent())
+                return;
+
+            if (exp.SelectedItems.Length != 1)
+                return;
+
+            if (!exp.SelectedItems[0].IsFolder)
+                return;
+
+            var itemsToPaste = GetItems(clip);
+            if (itemsToPaste.Length == 0)
+                return;
+
+            var folder = exp.SelectedItems[0];
+
+            //.net FX 2.0 hack to compensate for lack of set collection
+            Dictionary<string, string> folders = new Dictionary<string, string>();
+
+            foreach (var item in itemsToPaste)
+            {
+                LoggingService.InfoFormatted("{0} item {1} into {2}", item.ClipboardState, item.ResourceId, folder.ResourceId); //LOCALIZEME
+                
+                //Keep testing until we find a target resource identifier that 
+                //doesn't already exists
+                var name = ResourceIdentifier.GetName(item.ResourceId) + "." + ResourceIdentifier.GetResourceType(item.ResourceId).ToString();
+                var resId = folder.ResourceId + name;
+                int counter = 0;
+                while (conn.ResourceService.ResourceExists(resId))
+                {
+                    counter++;
+                    var rname = name.Substring(0, name.IndexOf("."));
+                    var type = name.Substring(name.IndexOf("."));
+
+                    rname += " (" + counter + ")";
+
+                    resId = folder.ResourceId + rname + type;
+                }
+
+                if (item.ClipboardState == RepositoryItem.ClipboardAction.Copy)
+                {
+                    conn.ResourceService.CopyResource(item.ResourceId, resId, false);
+                }
+                else if (item.ClipboardState == RepositoryItem.ClipboardAction.Cut)
+                {
+                    //TODO: Should we prompt? That may be equivalent to saying
+                    //"Shall I break your resources because you're moving" isn't it?
+                    var res = conn.ResourceService.MoveResourceWithReferences(item.ResourceId, resId, null, null);
+                    if (!res)
+                        LoggingService.InfoFormatted("Failed to move {0} to {1}", item.ResourceId, resId); //LOCALIZEME
+                    else
+                        folders[item.Parent.ResourceId] = item.Parent.ResourceId;
+                }
+            }
+
+            ResetItems(omgr, itemsToPaste);
+            exp.RefreshModel(folder.ResourceId);
+            foreach (var f in folders.Keys)
+            {
+                exp.RefreshModel(f);
+            }
+        }
+
+        private static RepositoryItem[] GetItems(ClipboardService clip)
+        {
+            object o = clip.Get();
+            if (o == null)
+                return new RepositoryItem[0];
+            else if (o is RepositoryItem[])
+                return (RepositoryItem[])o;
+            else if (o is RepositoryItem)
+                return new RepositoryItem[] { (RepositoryItem)o };
+            return new RepositoryItem[0];
+        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/OpenResourceCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/OpenResourceCommand.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/OpenResourceCommand.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -39,19 +39,21 @@
             var connMgr = ServiceRegistry.GetService<ServerConnectionManager>();
             _conn = connMgr.GetConnection(wb.ActiveSiteExplorer.ConnectionName);
 
-            if (items.Length == 1)
+            if (items.Length > 0)
             {
-                var item = items[0];
-                if (!item.IsFolder)
+                foreach (var item in items)
                 {
-                    if (openMgr.IsOpen(item.ResourceId))
+                    if (!item.IsFolder)
                     {
-                        openMgr.GetOpenEditor(item.ResourceId).Activate();
+                        if (openMgr.IsOpen(item.ResourceId))
+                        {
+                            openMgr.GetOpenEditor(item.ResourceId).Activate();
+                        }
+                        else
+                        {
+                            openMgr.Open(item.ResourceId, _conn, false, exp);
+                        }
                     }
-                    else
-                    {
-                        openMgr.Open(item.ResourceId, _conn, false, exp);
-                    }
                 }
             }
         }

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -98,10 +98,20 @@
             }
         }
 
+        public event EventHandler DirtyStateChanged;
+
+        private bool _dirty;
+
         public bool IsDirty
         {
-            get;
-            private set;
+            get { return _dirty; }
+            set
+            {
+                _dirty = value;
+                var handler = this.DirtyStateChanged;
+                if (handler != null)
+                    handler(this, EventArgs.Empty);
+            }
         }
 
         public virtual bool CanProfile

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -76,5 +76,10 @@
         /// <param name="mapguideRootUrl"></param>
         /// <returns></returns>
         string SetupPreviewUrl(string mapguideRootUrl);
+
+        /// <summary>
+        /// Raised when the value of <see cref="IsDirty"/> changes
+        /// </summary>
+        event EventHandler DirtyStateChanged;
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-09-30 05:23:01 UTC (rev 5219)
@@ -17,6 +17,8 @@
             <ConditionEvaluator name="EditorFunction" class="Maestro.Base.Commands.Conditions.ActiveEditorConditionEvaluator" />
             <ConditionEvaluator name="CanClose" class="Maestro.Base.Commands.Conditions.CloseableDocumentConditionEvaluator" />
             <ConditionEvaluator name="SelectedItem" class="Maestro.Base.Commands.Conditions.SelectedItemConditionEvaluator" />
+            <ConditionEvaluator name="CanPaste" class="Maestro.Base.Commands.Conditions.PasteConditionEvaluator" />
+            <ConditionEvaluator name="CanCutOrCopy" class="Maestro.Base.Commands.Conditions.CutCopyConditionEvaluator" />
             <ConditionEvaluator name="MultipleSelected" class="Maestro.Base.Commands.Conditions.MultipleSelectedItemConditionEvaluator" />
         </Import>
     </Runtime>
@@ -150,6 +152,7 @@
 
     <!-- Application-level services -->
     <Path name="/Maestro/ApplicationServices">
+        <Class id="ClipboardService" class="Maestro.Base.Services.ClipboardService" />
         <Class id="ServerConnectionManager" class="Maestro.Base.Services.ServerConnectionManager" />
         <Class id="UrlLauncher" class="Maestro.Base.Services.UrlLauncherService" />
         <Class id="OpenResourceManager" class="Maestro.Base.Services.OpenResourceManager" />
@@ -180,18 +183,22 @@
                          tooltip="${res:Menu_File_NewResource}"
                          class="Maestro.Base.Commands.NewItemCommand" />
             <ToolbarItem type="Separator" />
-            <ToolbarItem id="CopyItem"
-                         icon="document_copy"
-                         tooltip="${res:Menu_Edit_Copy}"
-                         class="Maestro.Base.Commands.NotImplementedCommand" />
-            <ToolbarItem id="CutItem"
-                         icon="scissors_blue"
-                         tooltip="${res:Menu_Edit_Cut}"
-                         class="Maestro.Base.Commands.NotImplementedCommand" />
-            <ToolbarItem id="PasteItem"
-                         icon="clipboard_paste"
-                         tooltip="${res:Menu_Edit_Paste}"
-                         class="Maestro.Base.Commands.NotImplementedCommand" />
+            <Condition action="Disable" name="CanCutOrCopy">
+                <ToolbarItem id="CopyItem"
+                             icon="document_copy"
+                             tooltip="${res:Menu_Edit_Copy}"
+                             class="Maestro.Base.Commands.CopyCommand" />
+                <ToolbarItem id="CutItem"
+                             icon="scissors_blue"
+                             tooltip="${res:Menu_Edit_Cut}"
+                             class="Maestro.Base.Commands.CutCommand" />
+            </Condition>
+            <Condition action="Disable" name="CanPaste">
+                <ToolbarItem id="PasteItem"
+                             icon="clipboard_paste"
+                             tooltip="${res:Menu_Edit_Paste}"
+                             class="Maestro.Base.Commands.PasteCommand" />
+            </Condition>
             <ToolbarItem type="Separator" />
         </Condition>
         <Condition action="Disable" name="EditorFunction">
@@ -291,16 +298,20 @@
                       class="Maestro.Base.Commands.CreatePackageCommand" />
             <MenuItem type="Separator" />
             <Condition action="Disable" name="IsNotRoot">
-                <MenuItem id="Copy"
-                          label="${res:SiteExplorer_SelectedItem_Copy}"
-                          class="Maestro.Base.Commands.NotImplementedCommand" />
-                <MenuItem id="Cut"
-                          label="${res:SiteExplorer_SelectedItem_Cut}"
-                          class="Maestro.Base.Commands.NotImplementedCommand" />
+                <Condition action="Disable" name="CanCutOrCopy">
+                    <MenuItem id="Copy"
+                              label="${res:SiteExplorer_SelectedItem_Copy}"
+                              class="Maestro.Base.Commands.CopyCommand" />
+                    <MenuItem id="Cut"
+                              label="${res:SiteExplorer_SelectedItem_Cut}"
+                              class="Maestro.Base.Commands.CutCommand" />
+                </Condition>
             </Condition>
-            <MenuItem id="Paste"
-                      label="${res:SiteExplorer_SelectedFolder_Paste}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+            <Condition action="Disable" name="CanPaste">
+                <MenuItem id="Paste"
+                          label="${res:SiteExplorer_SelectedFolder_Paste}"
+                          class="Maestro.Base.Commands.PasteCommand" />
+            </Condition>
             <MenuItem type="Separator" />
             <Condition action="Disable" name="IsNotRoot">
                 <MenuItem id="Delete"
@@ -316,12 +327,14 @@
     <!-- Site Explorer Context Menu -->
     <Path name="/Maestro/Shell/SiteExplorer/SelectedFolders">
         <Condition action="Disable" name="MultipleSelected">
-            <MenuItem id="Copy"
-                      label="${res:SiteExplorer_SelectedItem_Copy}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
-            <MenuItem id="Cut"
-                      label="${res:SiteExplorer_SelectedItem_Cut}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+            <Condition action="Disable" name="CanCutOrCopy">
+                <MenuItem id="Copy"
+                          label="${res:SiteExplorer_SelectedItem_Copy}"
+                          class="Maestro.Base.Commands.CopyCommand" />
+                <MenuItem id="Cut"
+                          label="${res:SiteExplorer_SelectedItem_Cut}"
+                          class="Maestro.Base.Commands.CutCommand" />
+            </Condition>
             <MenuItem id="Validate"
                       label="${res:SiteExplorer_ValidateResources}"
                       class="Maestro.Base.Commands.SiteExplorer.ValidateCommand" />
@@ -348,12 +361,14 @@
                       label="${res:SiteExplorer_SelectedItem_Delete}"
                       class="Maestro.Base.Commands.SiteExplorer.DeleteSelectedItemsCommand" />
             <MenuItem type="Separator" />
-            <MenuItem id="Copy"
-                      label="${res:SiteExplorer_SelectedItem_Copy}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
-            <MenuItem id="Cut"
-                      label="${res:SiteExplorer_SelectedItem_Cut}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+            <Condition action="Disable" name="CanCutOrCopy">
+                <MenuItem id="Copy"
+                          label="${res:SiteExplorer_SelectedItem_Copy}"
+                          class="Maestro.Base.Commands.CopyCommand" />
+                <MenuItem id="Cut"
+                          label="${res:SiteExplorer_SelectedItem_Cut}"
+                          class="Maestro.Base.Commands.CutCommand" />
+            </Condition>
             <MenuItem type="Separator" />
             <MenuItem id="Validate"
                       label="${res:SiteExplorer_ValidateResources}"
@@ -370,17 +385,19 @@
         <Condition action="Disable" name="MultipleSelected">
             <MenuItem id="Open"
                       label="${res:SiteExplorer_SelectedItem_Open}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+                      class="Maestro.Base.Commands.SiteExplorer.OpenResourceCommand" />
             <MenuItem id="Delete"
                       label="${res:SiteExplorer_SelectedItem_Delete}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+                      class="Maestro.Base.Commands.SiteExplorer.DeleteSelectedItemsCommand" />
             <MenuItem type="Separator" />
-            <MenuItem id="Copy"
-                      label="${res:SiteExplorer_SelectedItem_Copy}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
-            <MenuItem id="Cut"
-                      label="${res:SiteExplorer_SelectedItem_Cut}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+            <Condition action="Disable" name="CanCutOrCopy">
+                <MenuItem id="Copy"
+                          label="${res:SiteExplorer_SelectedItem_Copy}"
+                          class="Maestro.Base.Commands.CopyCommand" />
+                <MenuItem id="Cut"
+                          label="${res:SiteExplorer_SelectedItem_Cut}"
+                          class="Maestro.Base.Commands.CutCommand" />
+            </Condition>
             <MenuItem id="Validate"
                       label="${res:SiteExplorer_ValidateResources}"
                       class="Maestro.Base.Commands.SiteExplorer.ValidateCommand" />
@@ -392,17 +409,19 @@
         <Condition action="Disable" name="MultipleSelected">
             <MenuItem id="Open"
                       label="${res:SiteExplorer_SelectedItem_Open}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />s
+                      class="Maestro.Base.SiteExplorer.OpenResourceCommand" />
             <MenuItem id="Delete"
                       label="${res:SiteExplorer_SelectedItem_Delete}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+                      class="Maestro.Base.SiteExplorer.DeleteSelectedItemsCommand" />
             <MenuItem type="Separator" />
-            <MenuItem id="Copy"
-                      label="${res:SiteExplorer_SelectedItem_Copy}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
-            <MenuItem id="Cut"
-                      label="${res:SiteExplorer_SelectedItem_Cut}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+            <Condition action="Disable" name="CanCutOrCopy">
+                <MenuItem id="Copy"
+                          label="${res:SiteExplorer_SelectedItem_Copy}"
+                          class="Maestro.Base.Commands.CopyCommand" />
+                <MenuItem id="Cut"
+                          label="${res:SiteExplorer_SelectedItem_Cut}"
+                          class="Maestro.Base.Commands.CutCommand" />
+            </Condition>
             <MenuItem id="Validate"
                       label="${res:SiteExplorer_ValidateResources}"
                       class="Maestro.Base.Commands.SiteExplorer.ValidateCommand" />

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-09-30 05:23:01 UTC (rev 5219)
@@ -43,10 +43,12 @@
     <Compile Include="Commands\CloseActiveDocumentCommand.cs" />
     <Compile Include="Commands\Conditions\ActiveEditorConditionEvaluator.cs" />
     <Compile Include="Commands\Conditions\CloseableDocumentConditionEvaluator.cs" />
+    <Compile Include="Commands\Conditions\CutCopyConditionEvaluator.cs" />
     <Compile Include="Commands\Conditions\IsConnectedConditionEvaluator.cs" />
     <Compile Include="Commands\Conditions\MultipleSelectedItemConditionEvaluator.cs" />
     <Compile Include="Commands\Conditions\NotConnectedConditionEvaluator.cs" />
     <Compile Include="Commands\Conditions\DebugModeConditionEvaluator.cs" />
+    <Compile Include="Commands\Conditions\PasteConditionEvaluator.cs" />
     <Compile Include="Commands\Conditions\SelectedItemConditionEvaluator.cs" />
     <Compile Include="Commands\Conditions\SelectedRootItemConditionEvaluator.cs" />
     <Compile Include="Commands\CopyCommand.cs" />
@@ -153,6 +155,7 @@
       <DesignTime>True</DesignTime>
       <DependentUpon>Resources.resx</DependentUpon>
     </Compile>
+    <Compile Include="Services\ClipboardService.cs" />
     <Compile Include="Services\NewItemTemplateService.cs" />
     <Compile Include="Services\OpenResourceManager.cs" />
     <Compile Include="Services\ServerConnectionManager.cs" />

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -506,6 +506,24 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to {0} items copied and placed in clipboard.
+        /// </summary>
+        internal static string ItemsCopied {
+            get {
+                return ResourceManager.GetString("ItemsCopied", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} items cut and placed in clipboard.
+        /// </summary>
+        internal static string ItemsCut {
+            get {
+                return ResourceManager.GetString("ItemsCut", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap layer {
             get {
                 object obj = ResourceManager.GetObject("layer", resourceCulture);

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-09-30 05:23:01 UTC (rev 5219)
@@ -664,4 +664,10 @@
   <data name="PrefsRestartRequired" xml:space="preserve">
     <value>A restart is required for some changes to take effect</value>
   </data>
+  <data name="ItemsCopied" xml:space="preserve">
+    <value>{0} items copied and placed in clipboard</value>
+  </data>
+  <data name="ItemsCut" xml:space="preserve">
+    <value>{0} items cut and placed in clipboard</value>
+  </data>
 </root>
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Base/Services/ClipboardService.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Services/ClipboardService.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Services/ClipboardService.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -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 System.Windows.Forms;
+using ICSharpCode.Core;
+using Maestro.Base.UI;
+using OSGeo.MapGuide.MaestroAPI;
+
+namespace Maestro.Base.Services
+{
+    /// <summary>
+    /// Clipboard service. This simulates the behaviour of a clipboard, it does 
+    /// not actually put and retrieve data from the system clipboard.
+    /// </summary>
+    public class ClipboardService : ServiceBase
+    {
+        public override void Initialize()
+        {
+            base.Initialize();
+        }
+
+        private object _item;
+
+        public bool HasContent()
+        {
+            lock (_clipLock)
+            {
+                return _item != null;
+            }
+        }
+
+        public void Put(object item)
+        {
+            Check.NotNull(item, "item");
+            lock (_clipLock)
+            {
+                _item = item;
+            }
+        }
+
+        public object Get()
+        {
+            if (!HasContent())
+                return null;
+
+            lock (_clipLock)
+            {
+                return _item;
+            }
+        }
+
+        private readonly object _clipLock = new object();
+
+        internal RepositoryItem.ClipboardAction GetClipboardState(string resId)
+        {
+            Check.NotEmpty(resId, "resId");
+            var state = RepositoryItem.ClipboardAction.None;
+            object o = null;
+            lock (_clipLock)
+            {
+                o = _item;
+            }
+            if (o == null)
+            {
+                state = RepositoryItem.ClipboardAction.None;
+            }
+            else if (o is RepositoryItem[])
+            {
+                foreach (RepositoryItem r in (RepositoryItem[])o)
+                {
+                    if (resId.Equals(r.ResourceId))
+                    {
+                        state = r.ClipboardState;
+                        break;
+                    }
+                }
+            }
+            else if (o is RepositoryItem)
+            {
+                var r = ((RepositoryItem)o);
+                if (resId.Equals(r.ResourceId))
+                {
+                    state = r.ClipboardState;
+                }
+            }
+            return state;
+        }
+    }
+}

Modified: sandbox/maestro-3.0/Maestro.Base/Services/OpenResourceManager.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Services/OpenResourceManager.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/Services/OpenResourceManager.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -102,9 +102,15 @@
                 ed.ViewContentClosing += (sender, e) =>
                 {
                     _openItems.Remove(resourceId);
+                    siteExp.FlagNode(resourceId, NodeFlagAction.None);
                 };
+                ed.DirtyStateChanged += (sender, e) =>
+                {
+                    siteExp.FlagNode(resourceId, ed.IsDirty ? NodeFlagAction.HighlightDirty : NodeFlagAction.HighlightOpen);
+                };
             }
             _openItems[resourceId].Activate();
+            siteExp.FlagNode(resourceId, NodeFlagAction.HighlightOpen);
         }
 
         /// <summary>

Modified: sandbox/maestro-3.0/Maestro.Base/UI/ISiteExplorer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/ISiteExplorer.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/UI/ISiteExplorer.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -54,8 +54,40 @@
         void SelectNode(string resourceId);
 
         /// <summary>
+        /// Flags the node indicated by the specified action
+        /// </summary>
+        /// <param name="resourceId"></param>
+        /// <param name="action"></param>
+        void FlagNode(string resourceId, NodeFlagAction action);
+
+        /// <summary>
         /// Gets the items currently selected
         /// </summary>
         RepositoryItem[] SelectedItems { get; }
     }
+
+    public enum NodeFlagAction
+    {
+        /*
+        /// <summary>
+        /// Indicate that the node has been cut and placed on the clipboard
+        /// </summary>
+        IndicateCut,
+        /// <summary>
+        /// Indicate that the node has been copied and placed on the clipboard
+        /// </summary>
+        IndicateCopy,*/
+        /// <summary>
+        /// Highlight the affected node with a pre-defined back color to indicate open
+        /// </summary>
+        HighlightOpen,
+        /// <summary>
+        /// Highlight the affected node with a pre-defined back color to indicate dirty state
+        /// </summary>
+        HighlightDirty,
+        /// <summary>
+        /// Reset node to default styles
+        /// </summary>
+        None
+    }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/UI/Preferences/ConfigProperties.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/Preferences/ConfigProperties.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/UI/Preferences/ConfigProperties.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -23,6 +23,7 @@
 using ICSharpCode.Core;
 using Props = ICSharpCode.Core.PropertyService;
 using System.IO;
+using System.Drawing;
 
 namespace Maestro.Base.UI.Preferences
 {
@@ -32,6 +33,8 @@
         public const string UserTemplatesDirectory = "General.UserTemplatesDirectory";
         public const string ShowMessages = "General.ShowMessages";
         public const string ShowOutboundRequests = "General.ShowOutboundRequests";
+        public const string OpenColor = "General.OpenColor";
+        public const string DirtyColor = "General.DirtyColor";
 
         internal static void ApplyDefaults()
         {
@@ -39,6 +42,8 @@
             Props.Set(ConfigProperties.UserTemplatesDirectory, Path.Combine(FileUtility.ApplicationRootPath, "UserTemplates"));
             Props.Set(ConfigProperties.ShowMessages, true);
             Props.Set(ConfigProperties.ShowOutboundRequests, false);
+            Props.Set(ConfigProperties.OpenColor, Color.LightGreen);
+            Props.Set(ConfigProperties.DirtyColor, Color.Pink);
         }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/UI/RepositoryTreeModel.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/RepositoryTreeModel.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/UI/RepositoryTreeModel.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -27,6 +27,7 @@
 using System.Diagnostics;
 using OSGeo.MapGuide.MaestroAPI.Resource;
 using System.Collections.ObjectModel;
+using Maestro.Base.Services;
 
 namespace Maestro.Base.UI
 {
@@ -297,6 +298,59 @@
         {
             _children.Clear();
         }
+
+        private bool _open = false;
+        private bool _dirty = false;
+        private bool _clipboarded = false;
+
+        internal bool IsOpen
+        {
+            get { return _open; }
+            set 
+            { 
+                _open = value;
+                _dirty = !value;
+                this.NotifyNodesChanged();
+            }
+        }
+
+        internal bool IsDirty
+        {
+            get { return _dirty; }
+            set 
+            { 
+                _dirty = value;
+                _open = !value;
+                this.NotifyNodesChanged();
+            }
+        }
+
+        public enum ClipboardAction
+        {
+            Copy,
+            Cut,
+            None
+        }
+
+        private ClipboardAction _action = ClipboardAction.None;
+        
+        public ClipboardAction ClipboardState
+        {
+            get { return _action; }
+            set
+            {
+                _action = value;
+                this.NotifyNodesChanged();
+            }
+        }
+
+        internal void Reset()
+        {
+            _action = ClipboardAction.None;
+            _dirty = false;
+            _open = false;
+            this.NotifyNodesChanged();
+        }
     }
 
     public class RepositoryItemToolTipProvider : IToolTipProvider
@@ -323,12 +377,16 @@
         private string _connectionName;
 
         private IServerConnection _conn;
+        private OpenResourceManager _openResMgr;
+        private ClipboardService _clip;
 
-        public RepositoryTreeModel(IServerConnection conn, TreeViewAdv tree, string connName)
+        public RepositoryTreeModel(IServerConnection conn, TreeViewAdv tree, string connName, OpenResourceManager openResMgr, ClipboardService clip)
         {
             _conn = conn;
             _tree = tree;
             _connectionName = connName;
+            _openResMgr = openResMgr;
+            _clip = clip;
         }
 
         private System.Collections.IEnumerable GetSorted(ResourceList list)
@@ -355,6 +413,22 @@
             }
         }
 
+        /// <summary>
+        /// Restores node ui state from before refresh
+        /// </summary>
+        /// <param name="item"></param>
+        private void ApplyCurrentItemState(RepositoryItem item)
+        {
+            if (_openResMgr.IsOpen(item.ResourceId))
+            {
+                item.IsOpen = true;
+                var ed = _openResMgr.GetOpenEditor(item.ResourceId);
+                if (ed.IsDirty)
+                    item.IsDirty = true;
+            }
+            item.ClipboardState = _clip.GetClipboardState(item.ResourceId);
+        }
+
         public override System.Collections.IEnumerable GetChildren(TreePath treePath)
         {
             if (treePath.IsEmpty())
@@ -379,6 +453,7 @@
                     foreach (RepositoryItem item in GetSorted(list))
                     {
                         node.AddChildWithoutNotification(item);
+                        ApplyCurrentItemState(item);
                         yield return item;
                     }
                 }

Modified: sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.cs	2010-09-30 02:30:40 UTC (rev 5218)
+++ sandbox/maestro-3.0/Maestro.Base/UI/SiteExplorer.cs	2010-09-30 05:23:01 UTC (rev 5219)
@@ -29,6 +29,8 @@
 using Maestro.Base.Services;
 using OSGeo.MapGuide.MaestroAPI;
 using OSGeo.MapGuide.MaestroAPI.Resource;
+using ICSharpCode.Core;
+using Maestro.Base.UI.Preferences;
 
 namespace Maestro.Base.UI
 {
@@ -44,6 +46,7 @@
             InitializeComponent();
             Application.Idle += new EventHandler(OnIdle);
             ndResource.ToolTipProvider = new RepositoryItemToolTipProvider();
+            ndResource.DrawText += new EventHandler<Aga.Controls.Tree.NodeControls.DrawEventArgs>(OnNodeDrawText);
         }
 
         void OnIdle(object sender, EventArgs e)
@@ -79,7 +82,9 @@
             var mgr = ServiceRegistry.GetService<ServerConnectionManager>();
             _conn = mgr.GetConnection(this.ConnectionName);
 
-            _model = new RepositoryTreeModel(_conn, trvResources, this.ConnectionName);
+            var omgr = ServiceRegistry.GetService<OpenResourceManager>();
+            var clip = ServiceRegistry.GetService<ClipboardService>(); 
+            _model = new RepositoryTreeModel(_conn, trvResources, this.ConnectionName, omgr, clip);
             trvResources.Model = _model;
         }
 
@@ -256,5 +261,55 @@
                 }
             }
         }
+
+        public void FlagNode(string resourceId, NodeFlagAction action)
+        {
+            var path = _model.GetPathFromResourceId(resourceId);
+            if (path != null)
+            {
+                var node = trvResources.FindNode(path, true);
+                if (node != null)
+                {
+                    var item = (RepositoryItem)node.Tag;
+                    switch (action)
+                    {
+                        //case NodeFlagAction.IndicateCopy:
+                        //case NodeFlagAction.IndicateCut:
+                        //    item.IsClipboarded = true;
+                        //    break;
+                        case NodeFlagAction.HighlightDirty:
+                            item.IsDirty = true;
+                            break;
+                        case NodeFlagAction.HighlightOpen:
+                            item.IsOpen = true;
+                            break;
+                        case NodeFlagAction.None:
+                            item.Reset();
+                            break;
+                    }
+                }
+            }
+        }
+
+        void OnNodeDrawText(object sender, Aga.Controls.Tree.NodeControls.DrawEventArgs e)
+        {
+            if (e.Node.Tag == null)
+                return;
+
+            var ocolor = PropertyService.Get(ConfigProperties.OpenColor, Color.LightGreen);
+            var dcolor = PropertyService.Get(ConfigProperties.DirtyColor, Color.Pink);
+
+            var item = (RepositoryItem)e.Node.Tag;
+            var ctx = e.Context;
+            if (item.ClipboardState != RepositoryItem.ClipboardAction.None)
+            {
+                var oldFont = e.Font;
+                e.Font = new Font(oldFont.FontFamily, oldFont.Size, oldFont.Style | FontStyle.Italic);
+            }
+            if (item.IsDirty)
+                e.BackgroundBrush = new SolidBrush(dcolor);
+            else if (item.IsOpen)
+                e.BackgroundBrush = new SolidBrush(ocolor);
+        }
     }
 }



More information about the mapguide-commits mailing list