[mapguide-commits] r6653 - in branches/2.4/MgDev/Desktop: . MapViewer MapViewer/AppLayoutEngine MapViewer/Properties MapViewer/Tasks MgAppLayout MgAppLayout/Properties SampleExtension SampleExtension/Properties

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed May 16 12:34:58 EDT 2012


Author: jng
Date: 2012-05-16 09:34:57 -0700 (Wed, 16 May 2012)
New Revision: 6653

Added:
   branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/
   branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/AppLayout.cs
   branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/MgQuitComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.Designer.cs
   branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs
   branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.resx
   branches/2.4/MgDev/Desktop/MgAppLayout/
   branches/2.4/MgDev/Desktop/MgAppLayout/MgAppLayout.csproj
   branches/2.4/MgDev/Desktop/MgAppLayout/Program.cs
   branches/2.4/MgDev/Desktop/MgAppLayout/Properties/
   branches/2.4/MgDev/Desktop/MgAppLayout/Properties/AssemblyInfo.cs
   branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Resources.Designer.cs
   branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Resources.resx
   branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Settings.Designer.cs
   branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Settings.settings
   branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout
   branches/2.4/MgDev/Desktop/SampleExtension/
   branches/2.4/MgDev/Desktop/SampleExtension/MgPlotToDwfComponent.cs
   branches/2.4/MgDev/Desktop/SampleExtension/MgProfileComponent.cs
   branches/2.4/MgDev/Desktop/SampleExtension/MgStartupComponent.cs
   branches/2.4/MgDev/Desktop/SampleExtension/Properties/
   branches/2.4/MgDev/Desktop/SampleExtension/Properties/AssemblyInfo.cs
   branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.cs
   branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.resx
   branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj
   branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.cs
   branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.resx
Modified:
   branches/2.4/MgDev/Desktop/MapViewer/MapViewer.csproj
   branches/2.4/MgDev/Desktop/MapViewer/MgBufferComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgGenericInvokeComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgInvokeComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgLoadMapComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgLoadPackageComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgMapViewerProvider.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgMeasureComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs
   branches/2.4/MgDev/Desktop/MapViewer/Properties/Resources.resx
   branches/2.4/MgDev/Desktop/MapViewer/Tasks/MgTaskPaneStub.Designer.cs
   branches/2.4/MgDev/Desktop/MapViewer/Util.cs
   branches/2.4/MgDev/Desktop/MgDesktopDotNet.sln
Log:
This mg-desktop submission includes the following changes:
 - Implement what is effectively the mg-desktop version of an AJAX Viewer WebLayout
   - Introduce a new MgComponentPropertyAttribute which we use to tag all viewer component properties with
   - Introduce a new IMapComponent interface which allows for dynamic get/set of MgComponentProperty tagged properties by their name
   - Introduce a new AppLayout class. This is effectively our version of the WebLayout with structurally similar syntax
     - We declare component definitions instead of commands
     - Each component definition specifies
       - A unique name/id
       - The fully qualified .net class name of the component to instantiate
       - If not from the OSGeo.MapGuide.Viewer assembly, the path to the assembly containing the implementation of the specified class
       - A list of key-value pairs denoting component properties to set. The AppLayout engine will use these key-value pairs, in conjunction with the IMapComponent interface to set the appropriate properties during initialization
          - We use a special prefixing scheme in the string values to hint to the AppLayout engine as to what type of object the string value should be deserialized into.
     - Like the WebLayout, we reference these components through toolbar/menu item entries
     - Unlike the WebLayout, we offer also the ability to:
       - Specify a custom icon for the application
       - Specify a component to invoke on startup
       - Set viewer properties (same properties available via the Viewer Options component)
   - Add a new Shell class. This is the main window that is driven by the AppLayout.
   - Add a new MgQuitComponent. The is mainly for providing an easy quit function for the new AppLayout engine.
   - Add a new MgAppLayout exe project, this executable accepts a single parameter: The path to the AppLayout document.
   - Add a new SampleExtension project, this contains some sample external components. The included Sheboygan.AppLayout demonstrates how external components are consumed by the AppLayout engine.


Property changes on: branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine
___________________________________________________________________
Added: bugtraq:number
   + true

Added: branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/AppLayout.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/AppLayout.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/AppLayout.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,422 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace OSGeo.MapGuide.Viewer.AppLayoutEngine
+{
+    public class AppLayout
+    {
+        [XmlElement]
+        public string Title { get; set; }
+
+        [XmlElement]
+        public string Icon { get; set; }
+
+        [XmlElement]
+        public AppLayoutSettings Settings { get; set; }
+
+        [XmlElement]
+        public InfoPaneSettings InfoPane { get; set; }
+
+        [XmlElement]
+        public MapReference Map { get; set; }
+
+        [XmlElement]
+        public MenuDefinition Menu { get; set; }
+
+        [XmlElement]
+        public ToolbarDefinition Toolbar { get; set; }
+
+        [XmlElement]
+        public MenuDefinition ContextMenu { get; set; }
+
+        [XmlElement]
+        public TaskPaneDefinition TaskPane { get; set; }
+
+        [XmlArray]
+        public List<ComponentDefinition> Components { get; set; }
+
+        public static AppLayout CreateDefault(string title, string mapDefinition)
+        {
+            var layout = new AppLayout();
+            layout.Title = title;
+            layout.Settings = new AppLayoutSettings()
+            {
+                ConvertTiledGroupsToNonTiled = true,
+                SelectionColor = Util.ToHtmlColor(System.Drawing.Color.Blue),
+                ShowVertexCoordinatesWhenDigitizing = false,
+                ZoomInFactor = 0.5,
+                ZoomOutFactor = 2.0
+            };
+            layout.InfoPane = new InfoPaneSettings()
+            {
+                Legend = new LegendSettings() 
+                {
+                    Visible = true
+                },
+                PropertyPane = new PropertyPaneSettings() 
+                {
+                    Visible = true
+                },
+                Width = 200
+            };
+            layout.Map = new MapReference()
+            {
+                MapDefinition = mapDefinition
+            };
+            layout.Menu = new MenuDefinition()
+            {
+                Items = new List<ItemBase>()
+                {
+                    new SubMenu("File") 
+                    {
+                        Items = new List<ItemBase>()
+                        {
+                            new CommandItem("LoadMap"),
+                            new CommandItem("LoadPackage"),
+                            new SeparatorItem(),
+                            new CommandItem("Quit")
+                        }
+                    },
+                    new SubMenu("Tools")
+                    {
+                        Items = new List<ItemBase>()
+                        {
+                            new CommandItem("Buffer"),
+                            new CommandItem("Measure"),
+                            new CommandItem("Query"),
+                            new CommandItem("Theme"),
+                            new SeparatorItem(),
+                            new CommandItem("ViewerOptions")
+                        }
+                    }
+                }
+            };
+            layout.Toolbar = new ToolbarDefinition()
+            {
+                Items = new List<ItemBase>()
+                {
+                    new CommandItem("PrintMap", false),
+                    new SeparatorItem(),
+                    new CommandItem("CopyMap", false),
+                    new SeparatorItem(),
+                    new CommandItem("ZoomIn", false),
+                    new CommandItem("ZoomOut", false),
+                    new CommandItem("InitialView", false),
+                    new SeparatorItem(),
+                    new CommandItem("Select", false),
+                    new CommandItem("SelectRadius", false),
+                    new CommandItem("SelectPolygon", false),
+                    new CommandItem("Pan", false),
+                    new SeparatorItem(),
+                    new CommandItem("ClearSelection", false),
+                    new CommandItem("RefreshMap", false),
+                    new SeparatorItem(),
+                    new CommandItem("TooltipToggle", true),
+                    new SeparatorItem(),
+                    new SubMenu("Tools")
+                    {
+                        Items = new List<ItemBase>()
+                        {
+                            new CommandItem("Buffer"),
+                            new CommandItem("Measure"),
+                            new CommandItem("Query"),
+                            new CommandItem("Theme"),
+                            new SeparatorItem(),
+                            new CommandItem("ViewerOptions")
+                        }
+                    }
+                }
+            };
+            layout.ContextMenu = new MenuDefinition()
+            {
+                Items = new List<ItemBase>()
+                {
+                    new CommandItem("RefreshMap"),
+                    new SeparatorItem(),
+                    new CommandItem("ZoomIn"),
+                    new CommandItem("ZoomOut"),
+                    new CommandItem("ZoomToSelection"),
+                    new CommandItem("InitialView"),
+                    new SeparatorItem(),
+                    new CommandItem("Pan"),
+                    new CommandItem("Select"),
+                    new CommandItem("ClearSelection"),
+                    new SeparatorItem(),
+                    new SubMenu("Tools") 
+                    {
+                        Items = new List<ItemBase>() 
+                        {
+                            new CommandItem("Buffer"),
+                            new CommandItem("Measure"),
+                            new CommandItem("Query"),
+                            new CommandItem("Theme")
+                        }
+                    },
+                    new SeparatorItem(),
+                    new CommandItem("ViewerOptions"),
+                }
+            };
+            layout.TaskPane = new TaskPaneDefinition()
+            {
+                Width = 250,
+                TaskMenu = new MenuDefinition()
+                {
+                    Items = new List<ItemBase>()
+                    {
+                        new CommandItem("Buffer"),
+                        new CommandItem("Measure"),
+                        new CommandItem("Query"),
+                        new CommandItem("Theme")
+                    }
+                }
+            };
+            layout.Components = new List<ComponentDefinition>()
+            {
+                new ComponentDefinition()
+                {
+                    ClassName = typeof(Viewer.MgBufferComponent).FullName,
+                    Assembly = null,
+                    ComponentID = "Buffer",
+                    Properties = new List<NameValue>()
+                    {
+                        new NameValue("DefaultLayerName", "BufferLayer"),
+                        new NameValue("DefaultBufferUnits", "enum:" + typeof(MeasurementUnit).FullName + ":" + MeasurementUnit.Meters.ToString()),
+                        new NameValue("Target", "enum:" + typeof(MgViewerTarget).FullName + ":" + MgViewerTarget.TaskPane),
+                        new NameValue("TaskPane", "taskpane:")
+                    }
+                },
+                new ComponentDefinition(typeof(Viewer.MgCircleSelectComponent).FullName, "SelectRadius"),
+                new ComponentDefinition(typeof(Viewer.MgClearSelectionComponent).FullName, "ClearSelection"),
+                new ComponentDefinition(typeof(Viewer.MgCopyMapComponent).FullName, "CopyMap"),
+                new ComponentDefinition(typeof(Viewer.MgInitialViewComponent).FullName, "InitialView"),
+                new ComponentDefinition(typeof(Viewer.MgLoadMapComponent).FullName, "LoadMap")
+                {
+                    Properties = new List<NameValue>()
+                    {
+                        new NameValue("MapDefinition", mapDefinition)
+                    }
+                },
+                new ComponentDefinition(typeof(Viewer.MgLoadPackageComponent).FullName, "LoadPackage")
+                {
+                    Properties = new List<NameValue>()
+                    {
+                        new NameValue("InvokeOnPackageLoad", "component:LoadMap")
+                    }
+                },
+                new ComponentDefinition(typeof(Viewer.MgMeasureComponent).FullName, "Measure")
+                {
+                    Properties = new List<NameValue>()
+                    {
+                        new NameValue("MeasureMode", "enum:" + typeof(MeasureMode).FullName + ":" + MeasureMode.Line.ToString()),
+                        new NameValue("PreferredUnits", "enum:" + typeof(MeasurementUnit).FullName + ":" + MeasurementUnit.Meters.ToString()),
+                        new NameValue("Target", "enum:" + typeof(MgViewerTarget).FullName + ":" + MgViewerTarget.TaskPane),
+                        new NameValue("TaskPane", "taskpane:")
+                    }
+                },
+                new ComponentDefinition(typeof(Viewer.MgPanComponent).FullName, "Pan"),
+                new ComponentDefinition(typeof(Viewer.MgPolygonSelectComponent).FullName, "SelectPolygon"),
+                new ComponentDefinition(typeof(Viewer.MgPrintComponent).FullName, "PrintMap"),
+                new ComponentDefinition(typeof(Viewer.MgQueryComponent).FullName, "Query")
+                {
+                    Properties = new List<NameValue>()
+                    {
+                        new NameValue("Target", "enum:" + typeof(MgViewerTarget).FullName + ":" + MgViewerTarget.TaskPane),
+                        new NameValue("TaskPane", "taskpane:")
+                    }
+                },
+                new ComponentDefinition(typeof(Viewer.AppLayoutEngine.MgQuitComponent).FullName, "Quit"),
+                new ComponentDefinition(typeof(Viewer.MgRefreshMapComponent).FullName, "RefreshMap"),
+                new ComponentDefinition(typeof(Viewer.MgSelectComponent).FullName, "Select"),
+                new ComponentDefinition(typeof(Viewer.MgThemeComponent).FullName, "Theme")
+                {
+                    Properties = new List<NameValue>()
+                    {
+                        new NameValue("Target", "enum:" + typeof(MgViewerTarget).FullName + ":" + MgViewerTarget.TaskPane),
+                        new NameValue("TaskPane", "taskpane:")
+                    }
+                },
+                new ComponentDefinition(typeof(Viewer.MgTooltipToggleComponent).FullName, "TooltipToggle"),
+                new ComponentDefinition(typeof(Viewer.MgViewerOptionsComponent).FullName, "ViewerOptions"),
+                new ComponentDefinition(typeof(Viewer.MgZoomInComponent).FullName, "ZoomIn"),
+                new ComponentDefinition(typeof(Viewer.MgZoomOutComponent).FullName, "ZoomOut"),
+                new ComponentDefinition(typeof(Viewer.MgZoomToSelectionComponent).FullName, "ZoomToSelection")
+            };
+            return layout;
+        }
+    }
+
+    public class AppLayoutSettings
+    {
+        [XmlElement]
+        public string InvokeOnStartup { get; set; }
+
+        [XmlElement]
+        public string SelectionColor { get; set; }
+
+        [XmlElement]
+        public bool ConvertTiledGroupsToNonTiled { get; set; }
+
+        [XmlElement]
+        public bool ShowVertexCoordinatesWhenDigitizing { get; set; }
+
+        [XmlElement]
+        public double ZoomInFactor { get; set; }
+
+        [XmlElement]
+        public double ZoomOutFactor { get; set; }
+    }
+
+    public class InfoPaneSettings
+    {
+        [XmlElement]
+        public uint Width { get; set; }
+
+        [XmlElement]
+        public LegendSettings Legend { get; set; }
+
+        [XmlElement]
+        public PropertyPaneSettings PropertyPane { get; set; }
+
+        [XmlIgnore]
+        public bool IsVisible { get { return this.Legend.Visible || this.PropertyPane.Visible; } }
+    }
+
+    public class LegendSettings
+    {
+        [XmlElement]
+        public bool Visible { get; set; }
+    }
+
+    public class PropertyPaneSettings
+    {
+        [XmlElement]
+        public bool Visible { get; set; }
+    }
+
+    public class MapReference
+    {
+        [XmlElement]
+        public string MapDefinition { get; set; }
+    }
+
+    public class MenuDefinition
+    {
+        [XmlArray]
+        public List<ItemBase> Items { get; set; }
+    }
+
+    public class ToolbarDefinition
+    {
+        [XmlArray]
+        public List<ItemBase> Items { get; set; }
+    }
+
+    public class TaskPaneDefinition
+    {
+        [XmlElement]
+        public uint Width { get; set; }
+
+        [XmlElement]
+        public string InitialComponentID { get; set; }
+
+        [XmlElement]
+        public MenuDefinition TaskMenu { get; set; }
+    }
+
+    [XmlInclude(typeof(CommandItem))]
+    [XmlInclude(typeof(SeparatorItem))]
+    [XmlInclude(typeof(SubMenu))]
+    public class ItemBase
+    {
+        
+    }
+
+    public class SeparatorItem : ItemBase
+    {
+    }
+
+    public class SubMenu : ItemBase
+    {
+        public SubMenu() { }
+
+        public SubMenu(string label) { this.Label = label; }
+
+        [XmlElement]
+        public string Label { get; set; }
+
+        [XmlArray]
+        public List<ItemBase> Items { get; set; }
+    }
+
+    public class CommandItem : ItemBase
+    {
+        public CommandItem() { }
+
+        public CommandItem(string componentId) { this.ComponentID = componentId; }
+
+        public CommandItem(string componentId, bool showLabel) { this.ComponentID = componentId; this.ShowLabel = showLabel; }
+
+        [XmlElement]
+        public string ComponentID { get; set; }
+
+        [XmlElement]
+        public bool ShowLabel { get; set; }
+    }
+
+    public class ComponentDefinition
+    {
+        public ComponentDefinition() { this.Properties = new List<NameValue>(); }
+
+        public ComponentDefinition(string typeName, string componentID) : base()
+        {
+            this.Assembly = null;
+            this.ClassName = typeName;
+            this.ComponentID = componentID;
+        }
+
+        [XmlElement]
+        public string ComponentID { get; set; }
+
+        [XmlElement]
+        public string ClassName { get; set; }
+
+        [XmlElement]
+        public string Assembly { get; set; }
+
+        [XmlArray]
+        public List<NameValue> Properties { get; set; }
+    }
+
+    public class NameValue
+    {
+        public NameValue() { }
+
+        public NameValue(string name, string value)
+        {
+            this.Name = name;
+            this.Value = value;
+        }
+
+        [XmlElement]
+        public string Name { get; set; }
+
+        [XmlElement]
+        public string Value { get; set; }
+    }
+
+    /// <summary>
+    /// Defines the set of prefixes for serialized component property string values
+    /// to hint at what type to deserialize this value as. CLR property values are
+    /// serialized/deserialized as is without any need for prefixing.
+    /// </summary>
+    public class StringPrefixes
+    {
+        public const string COMPONENTID = "component:";
+        public const string COLOR = "color:";
+        public const string ENUM = "enum:";
+        public const string VIEWERID = "viewer:";
+        public const string TASKPANEID = "taskpane:";
+    }
+}

Added: branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/MgQuitComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/MgQuitComponent.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/MgQuitComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+
+namespace OSGeo.MapGuide.Viewer.AppLayoutEngine
+{
+    [ToolboxItem(true)]
+    public class MgQuitComponent : MgComponent
+    {
+        public MgQuitComponent()
+        {
+            this.Label = Properties.Resources.TextExitApplication;
+        }
+
+        public override void Invoke()
+        {
+            System.Windows.Forms.Application.Exit();
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.Designer.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,366 @@
+namespace OSGeo.MapGuide.Viewer.AppLayoutEngine
+{
+    partial class Shell
+    {
+        /// <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.components = new System.ComponentModel.Container();
+            this.appContainer = new System.Windows.Forms.SplitContainer();
+            this.infoPaneViewerContainer = new System.Windows.Forms.SplitContainer();
+            this.layerPropertiesContainer = new System.Windows.Forms.SplitContainer();
+            this.tabControl1 = new System.Windows.Forms.TabControl();
+            this.tabPage2 = new System.Windows.Forms.TabPage();
+            this.tabControl2 = new System.Windows.Forms.TabControl();
+            this.tabPage3 = new System.Windows.Forms.TabPage();
+            this.viewerContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+            this.viewerToolbar = new System.Windows.Forms.ToolStrip();
+            this.taskPaneToolbar = new System.Windows.Forms.ToolStrip();
+            this.btnInitialTask = new System.Windows.Forms.ToolStripButton();
+            this.taskMenu = new System.Windows.Forms.ToolStripDropDownButton();
+            this.mainMenu = new System.Windows.Forms.MenuStrip();
+            this.appStatusBar = new System.Windows.Forms.StatusStrip();
+            this.lblCoordinates = new System.Windows.Forms.ToolStripStatusLabel();
+            this.lblSelected = new System.Windows.Forms.ToolStripStatusLabel();
+            this.lblMapScale = new System.Windows.Forms.ToolStripStatusLabel();
+            this.lblMapSize = new System.Windows.Forms.ToolStripStatusLabel();
+            this.lblPoweredBy = new System.Windows.Forms.ToolStripStatusLabel();
+            this.legend = new OSGeo.MapGuide.Viewer.MgLegend();
+            this.propertyPane = new OSGeo.MapGuide.Viewer.MgPropertyPane();
+            this.mapViewer = new OSGeo.MapGuide.Viewer.MgMapViewer();
+            this.taskPane = new OSGeo.MapGuide.Viewer.MgTaskPane();
+            this.appContainer.Panel1.SuspendLayout();
+            this.appContainer.Panel2.SuspendLayout();
+            this.appContainer.SuspendLayout();
+            this.infoPaneViewerContainer.Panel1.SuspendLayout();
+            this.infoPaneViewerContainer.Panel2.SuspendLayout();
+            this.infoPaneViewerContainer.SuspendLayout();
+            this.layerPropertiesContainer.Panel1.SuspendLayout();
+            this.layerPropertiesContainer.Panel2.SuspendLayout();
+            this.layerPropertiesContainer.SuspendLayout();
+            this.tabControl1.SuspendLayout();
+            this.tabPage2.SuspendLayout();
+            this.tabControl2.SuspendLayout();
+            this.tabPage3.SuspendLayout();
+            this.taskPaneToolbar.SuspendLayout();
+            this.appStatusBar.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // appContainer
+            // 
+            this.appContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.appContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
+            this.appContainer.Location = new System.Drawing.Point(0, 24);
+            this.appContainer.Name = "appContainer";
+            // 
+            // appContainer.Panel1
+            // 
+            this.appContainer.Panel1.Controls.Add(this.infoPaneViewerContainer);
+            this.appContainer.Panel1.Controls.Add(this.viewerToolbar);
+            // 
+            // appContainer.Panel2
+            // 
+            this.appContainer.Panel2.Controls.Add(this.taskPane);
+            this.appContainer.Panel2.Controls.Add(this.taskPaneToolbar);
+            this.appContainer.Size = new System.Drawing.Size(881, 528);
+            this.appContainer.SplitterDistance = 662;
+            this.appContainer.TabIndex = 1;
+            // 
+            // infoPaneViewerContainer
+            // 
+            this.infoPaneViewerContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.infoPaneViewerContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+            this.infoPaneViewerContainer.Location = new System.Drawing.Point(0, 25);
+            this.infoPaneViewerContainer.Name = "infoPaneViewerContainer";
+            // 
+            // infoPaneViewerContainer.Panel1
+            // 
+            this.infoPaneViewerContainer.Panel1.Controls.Add(this.layerPropertiesContainer);
+            // 
+            // infoPaneViewerContainer.Panel2
+            // 
+            this.infoPaneViewerContainer.Panel2.Controls.Add(this.mapViewer);
+            this.infoPaneViewerContainer.Size = new System.Drawing.Size(662, 503);
+            this.infoPaneViewerContainer.SplitterDistance = 220;
+            this.infoPaneViewerContainer.TabIndex = 0;
+            // 
+            // layerPropertiesContainer
+            // 
+            this.layerPropertiesContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.layerPropertiesContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
+            this.layerPropertiesContainer.Location = new System.Drawing.Point(0, 0);
+            this.layerPropertiesContainer.Name = "layerPropertiesContainer";
+            this.layerPropertiesContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+            // 
+            // layerPropertiesContainer.Panel1
+            // 
+            this.layerPropertiesContainer.Panel1.Controls.Add(this.tabControl1);
+            // 
+            // layerPropertiesContainer.Panel2
+            // 
+            this.layerPropertiesContainer.Panel2.Controls.Add(this.tabControl2);
+            this.layerPropertiesContainer.Size = new System.Drawing.Size(220, 503);
+            this.layerPropertiesContainer.SplitterDistance = 271;
+            this.layerPropertiesContainer.TabIndex = 0;
+            // 
+            // tabControl1
+            // 
+            this.tabControl1.Controls.Add(this.tabPage2);
+            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.tabControl1.Location = new System.Drawing.Point(0, 0);
+            this.tabControl1.Name = "tabControl1";
+            this.tabControl1.SelectedIndex = 0;
+            this.tabControl1.Size = new System.Drawing.Size(220, 271);
+            this.tabControl1.TabIndex = 0;
+            // 
+            // tabPage2
+            // 
+            this.tabPage2.Controls.Add(this.legend);
+            this.tabPage2.Location = new System.Drawing.Point(4, 22);
+            this.tabPage2.Name = "tabPage2";
+            this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
+            this.tabPage2.Size = new System.Drawing.Size(212, 245);
+            this.tabPage2.TabIndex = 1;
+            this.tabPage2.Text = "Layers";
+            this.tabPage2.UseVisualStyleBackColor = true;
+            // 
+            // tabControl2
+            // 
+            this.tabControl2.Controls.Add(this.tabPage3);
+            this.tabControl2.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.tabControl2.Location = new System.Drawing.Point(0, 0);
+            this.tabControl2.Name = "tabControl2";
+            this.tabControl2.SelectedIndex = 0;
+            this.tabControl2.Size = new System.Drawing.Size(220, 228);
+            this.tabControl2.TabIndex = 0;
+            // 
+            // tabPage3
+            // 
+            this.tabPage3.Controls.Add(this.propertyPane);
+            this.tabPage3.Location = new System.Drawing.Point(4, 22);
+            this.tabPage3.Name = "tabPage3";
+            this.tabPage3.Padding = new System.Windows.Forms.Padding(3);
+            this.tabPage3.Size = new System.Drawing.Size(212, 202);
+            this.tabPage3.TabIndex = 1;
+            this.tabPage3.Text = "Properties";
+            this.tabPage3.UseVisualStyleBackColor = true;
+            // 
+            // viewerContextMenu
+            // 
+            this.viewerContextMenu.Name = "viewerContextMenu";
+            this.viewerContextMenu.Size = new System.Drawing.Size(61, 4);
+            // 
+            // viewerToolbar
+            // 
+            this.viewerToolbar.Location = new System.Drawing.Point(0, 0);
+            this.viewerToolbar.Name = "viewerToolbar";
+            this.viewerToolbar.Size = new System.Drawing.Size(662, 25);
+            this.viewerToolbar.TabIndex = 1;
+            this.viewerToolbar.Text = "toolStrip2";
+            // 
+            // taskPaneToolbar
+            // 
+            this.taskPaneToolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.btnInitialTask,
+            this.taskMenu});
+            this.taskPaneToolbar.Location = new System.Drawing.Point(0, 0);
+            this.taskPaneToolbar.Name = "taskPaneToolbar";
+            this.taskPaneToolbar.Size = new System.Drawing.Size(215, 25);
+            this.taskPaneToolbar.TabIndex = 0;
+            this.taskPaneToolbar.Text = "toolStrip3";
+            // 
+            // btnInitialTask
+            // 
+            this.btnInitialTask.Image = global::OSGeo.MapGuide.Viewer.Properties.Resources.icon_home;
+            this.btnInitialTask.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.btnInitialTask.Name = "btnInitialTask";
+            this.btnInitialTask.Size = new System.Drawing.Size(83, 22);
+            this.btnInitialTask.Text = "Initial Task";
+            this.btnInitialTask.Click += new System.EventHandler(this.btnInitialTask_Click);
+            // 
+            // taskMenu
+            // 
+            this.taskMenu.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
+            this.taskMenu.Image = global::OSGeo.MapGuide.Viewer.Properties.Resources.icon_tasks;
+            this.taskMenu.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.taskMenu.Name = "taskMenu";
+            this.taskMenu.Size = new System.Drawing.Size(65, 22);
+            this.taskMenu.Text = "Tasks";
+            // 
+            // mainMenu
+            // 
+            this.mainMenu.Location = new System.Drawing.Point(0, 0);
+            this.mainMenu.Name = "mainMenu";
+            this.mainMenu.Size = new System.Drawing.Size(881, 24);
+            this.mainMenu.TabIndex = 2;
+            this.mainMenu.Text = "menuStrip1";
+            // 
+            // appStatusBar
+            // 
+            this.appStatusBar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.lblCoordinates,
+            this.lblSelected,
+            this.lblMapScale,
+            this.lblMapSize,
+            this.lblPoweredBy});
+            this.appStatusBar.Location = new System.Drawing.Point(0, 552);
+            this.appStatusBar.Name = "appStatusBar";
+            this.appStatusBar.Size = new System.Drawing.Size(881, 23);
+            this.appStatusBar.TabIndex = 3;
+            this.appStatusBar.Text = "statusStrip1";
+            // 
+            // lblCoordinates
+            // 
+            this.lblCoordinates.Name = "lblCoordinates";
+            this.lblCoordinates.Size = new System.Drawing.Size(0, 18);
+            // 
+            // lblSelected
+            // 
+            this.lblSelected.Name = "lblSelected";
+            this.lblSelected.Size = new System.Drawing.Size(729, 18);
+            this.lblSelected.Spring = true;
+            this.lblSelected.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // lblMapScale
+            // 
+            this.lblMapScale.Name = "lblMapScale";
+            this.lblMapScale.Size = new System.Drawing.Size(0, 18);
+            // 
+            // lblMapSize
+            // 
+            this.lblMapSize.Name = "lblMapSize";
+            this.lblMapSize.Size = new System.Drawing.Size(0, 18);
+            // 
+            // lblPoweredBy
+            // 
+            this.lblPoweredBy.Image = global::OSGeo.MapGuide.Viewer.Properties.Resources.PoweredBy_en;
+            this.lblPoweredBy.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
+            this.lblPoweredBy.Name = "lblPoweredBy";
+            this.lblPoweredBy.Size = new System.Drawing.Size(137, 18);
+            // 
+            // legend
+            // 
+            this.legend.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.legend.GroupContextMenu = null;
+            this.legend.LayerContextMenu = null;
+            this.legend.Location = new System.Drawing.Point(3, 3);
+            this.legend.Name = "legend";
+            this.legend.Size = new System.Drawing.Size(206, 239);
+            this.legend.TabIndex = 0;
+            this.legend.ThemeCompressionLimit = 0;
+            // 
+            // propertyPane
+            // 
+            this.propertyPane.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.propertyPane.Location = new System.Drawing.Point(3, 3);
+            this.propertyPane.Name = "propertyPane";
+            this.propertyPane.Size = new System.Drawing.Size(206, 196);
+            this.propertyPane.TabIndex = 0;
+            // 
+            // mapViewer
+            // 
+            this.mapViewer.ContextMenuStrip = this.viewerContextMenu;
+            this.mapViewer.Cursor = System.Windows.Forms.Cursors.Default;
+            this.mapViewer.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.mapViewer.Location = new System.Drawing.Point(0, 0);
+            this.mapViewer.Name = "mapViewer";
+            this.mapViewer.SelectionColor = System.Drawing.Color.Blue;
+            this.mapViewer.Size = new System.Drawing.Size(438, 503);
+            this.mapViewer.TabIndex = 0;
+            this.mapViewer.Text = "mgMapViewer1";
+            this.mapViewer.ZoomInFactor = 0.5;
+            this.mapViewer.ZoomOutFactor = 2;
+            // 
+            // taskPane
+            // 
+            this.taskPane.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.taskPane.Location = new System.Drawing.Point(0, 25);
+            this.taskPane.Name = "taskPane";
+            this.taskPane.Size = new System.Drawing.Size(215, 503);
+            this.taskPane.TabIndex = 1;
+            // 
+            // Shell
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(881, 575);
+            this.Controls.Add(this.appContainer);
+            this.Controls.Add(this.mainMenu);
+            this.Controls.Add(this.appStatusBar);
+            this.MainMenuStrip = this.mainMenu;
+            this.Name = "Shell";
+            this.Text = "Shell";
+            this.appContainer.Panel1.ResumeLayout(false);
+            this.appContainer.Panel1.PerformLayout();
+            this.appContainer.Panel2.ResumeLayout(false);
+            this.appContainer.Panel2.PerformLayout();
+            this.appContainer.ResumeLayout(false);
+            this.infoPaneViewerContainer.Panel1.ResumeLayout(false);
+            this.infoPaneViewerContainer.Panel2.ResumeLayout(false);
+            this.infoPaneViewerContainer.ResumeLayout(false);
+            this.layerPropertiesContainer.Panel1.ResumeLayout(false);
+            this.layerPropertiesContainer.Panel2.ResumeLayout(false);
+            this.layerPropertiesContainer.ResumeLayout(false);
+            this.tabControl1.ResumeLayout(false);
+            this.tabPage2.ResumeLayout(false);
+            this.tabControl2.ResumeLayout(false);
+            this.tabPage3.ResumeLayout(false);
+            this.taskPaneToolbar.ResumeLayout(false);
+            this.taskPaneToolbar.PerformLayout();
+            this.appStatusBar.ResumeLayout(false);
+            this.appStatusBar.PerformLayout();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.SplitContainer appContainer;
+        private System.Windows.Forms.SplitContainer infoPaneViewerContainer;
+        private System.Windows.Forms.SplitContainer layerPropertiesContainer;
+        private System.Windows.Forms.TabControl tabControl1;
+        private System.Windows.Forms.TabPage tabPage2;
+        private System.Windows.Forms.TabControl tabControl2;
+        private System.Windows.Forms.TabPage tabPage3;
+        private System.Windows.Forms.ToolStrip viewerToolbar;
+        private MgTaskPane taskPane;
+        private System.Windows.Forms.ToolStrip taskPaneToolbar;
+        private MgMapViewer mapViewer;
+        private System.Windows.Forms.ToolStripButton btnInitialTask;
+        private System.Windows.Forms.ToolStripDropDownButton taskMenu;
+        private System.Windows.Forms.MenuStrip mainMenu;
+        private MgLegend legend;
+        private MgPropertyPane propertyPane;
+        private System.Windows.Forms.StatusStrip appStatusBar;
+        private System.Windows.Forms.ToolStripStatusLabel lblCoordinates;
+        private System.Windows.Forms.ToolStripStatusLabel lblSelected;
+        private System.Windows.Forms.ToolStripStatusLabel lblMapScale;
+        private System.Windows.Forms.ToolStripStatusLabel lblMapSize;
+        private System.Windows.Forms.ToolStripStatusLabel lblPoweredBy;
+        private System.Windows.Forms.ContextMenuStrip viewerContextMenu;
+    }
+}
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,390 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+namespace OSGeo.MapGuide.Viewer.AppLayoutEngine
+{
+    public partial class Shell : Form, IMapStatusBar
+    {
+        public Shell(AppLayout layout, MgMapViewerProvider provider)
+        {
+            InitializeComponent();
+            this.Text = layout.Title;
+            _menuInvoker = new MgMenuItemComponentInvoker();
+            _toolInvoker = new MgToolButtonComponentInvoker();
+
+            InitializeComponentSet(layout);
+            InitializeMenu(layout.Menu);
+            InitializeToolbar(layout.Toolbar);
+            InitializeContextMenu(layout.ContextMenu);
+            InitializeTaskPaneMenu(layout.TaskPane.TaskMenu);
+
+            _layout = layout;
+            if (!string.IsNullOrEmpty(_layout.Icon) && System.IO.File.Exists(_layout.Icon))
+            {
+                this.Icon = new System.Drawing.Icon(_layout.Icon);
+            }
+
+            SetInfoPaneWidth(_layout.InfoPane.Width);
+            SetInfoPaneVisible(_layout.InfoPane.IsVisible);
+            if (_layout.InfoPane.IsVisible)
+            {
+                SetLegendVisbility(_layout.InfoPane.Legend.Visible);
+                SetPropertyPaneVisbility(_layout.InfoPane.PropertyPane.Visible);
+            }
+            SetTaskPaneWidth(_layout.TaskPane.Width);
+
+            //Apply viewer properties
+            mapViewer.ConvertTiledGroupsToNonTiled = _layout.Settings.ConvertTiledGroupsToNonTiled;
+            mapViewer.SelectionColor = Util.FromHtmlColor(_layout.Settings.SelectionColor);
+            mapViewer.ShowVertexCoordinatesWhenDigitizing = _layout.Settings.ShowVertexCoordinatesWhenDigitizing;
+            mapViewer.ZoomInFactor = _layout.Settings.ZoomInFactor;
+            mapViewer.ZoomOutFactor = _layout.Settings.ZoomOutFactor;
+
+            _provider = provider;
+            mapViewer.PropertyChanged += new PropertyChangedEventHandler(OnMapViewerPropertyChanged);
+        }
+
+        public void SetTaskPaneWidth(uint width)
+        {
+            if (appContainer.Panel2Collapsed)
+                appContainer.Panel2Collapsed = false;
+            //appContainer.Panel2.Width = (int)width;
+            appContainer.SplitterDistance = (int)(appContainer.Width - width);
+        }
+
+        public void SetInfoPaneWidth(uint width)
+        {
+            if (infoPaneViewerContainer.Panel1Collapsed)
+                infoPaneViewerContainer.Panel1Collapsed = false;
+            //infoPaneViewerContainer.Panel1.Width = (int)width;
+            infoPaneViewerContainer.SplitterDistance = (int)width;
+        }
+
+        public void SetLegendVisbility(bool visible)
+        {
+            layerPropertiesContainer.Panel1Collapsed = !visible;
+        }
+
+        public void SetPropertyPaneVisbility(bool visible)
+        {
+            layerPropertiesContainer.Panel2Collapsed = !visible;
+        }
+
+        public void SetTaskPaneVisible(bool visible)
+        {
+            appContainer.Panel2Collapsed = !visible;
+        }
+
+        public void SetInfoPaneVisible(bool visible)
+        {
+            infoPaneViewerContainer.Panel1Collapsed = !visible;
+        }
+
+        void OnMapViewerPropertyChanged(object sender, PropertyChangedEventArgs e)
+        {
+            if (e.PropertyName == "IsBusy")
+            {
+                if (_loader != null)
+                    _loader.Visible = mapViewer.IsBusy;
+            }
+        }
+
+        private AppLayout _layout;
+        private MgMapViewerProvider _provider;
+
+        protected override void OnLoad(EventArgs e)
+        {
+            //Optimization: If legend or property pane aren't visible
+            //don't wire them up to the controller
+            var theLegend = legend;
+            var thePropertyPane = propertyPane;
+            if (!_layout.InfoPane.Legend.Visible)
+                theLegend = null;
+            if (!_layout.InfoPane.PropertyPane.Visible)
+                thePropertyPane = null;
+
+            new MapViewerController(mapViewer, theLegend, this, thePropertyPane);
+            mapViewer.Init(_provider);
+
+            if (!string.IsNullOrEmpty(_layout.Settings.InvokeOnStartup))
+            {
+                if (_components.ContainsKey(_layout.Settings.InvokeOnStartup))
+                {
+                    _components[_layout.Settings.InvokeOnStartup].Invoke();
+                }
+                else
+                {
+                    MessageBox.Show("WARNING: Attempted to invoke the component with ID (" + _layout.Settings.InvokeOnStartup + "), but could not find any component with this ID. The application will continue");
+                }
+            }
+        }
+
+        private MgMenuItemComponentInvoker _menuInvoker;
+        private MgToolButtonComponentInvoker _toolInvoker;
+        private Dictionary<string, MgComponent> _components;
+
+        private void InitializeTaskPaneMenu(MenuDefinition menuDefinition)
+        {
+            taskMenu.DropDown.Items.Clear();
+            taskMenu.DropDownDirection = ToolStripDropDownDirection.BelowLeft;
+            foreach (var item in menuDefinition.Items)
+            {
+                taskMenu.DropDown.Items.Add(CreateMenuItem(item));
+            }
+        }
+
+        private void InitializeContextMenu(MenuDefinition menuDefinition)
+        {
+            viewerContextMenu.Items.Clear();
+            foreach (var item in menuDefinition.Items)
+            {
+                viewerContextMenu.Items.Add(CreateMenuItem(item));
+            }
+        }
+
+        private ToolStripLabel _loader;
+
+        private void InitializeToolbar(ToolbarDefinition toolbarDefinition)
+        {
+            viewerToolbar.Items.Clear();
+            foreach (var item in toolbarDefinition.Items)
+            {
+                viewerToolbar.Items.Add(CreateToolbarItem(item));
+            }
+
+            if (_loader == null)
+            {
+                _loader = new ToolStripLabel(Properties.Resources.icon_loading);
+                _loader.Alignment = ToolStripItemAlignment.Right;
+                _loader.Text = "";
+                _loader.ImageScaling = ToolStripItemImageScaling.None;
+            }
+            viewerToolbar.Items.Add(_loader);
+            _loader.Visible = mapViewer.IsBusy;
+        }
+
+        private ToolStripItem CreateToolbarItem(ItemBase item)
+        {
+            if (item == null)
+                throw new ArgumentNullException("item");
+
+            if (item is SeparatorItem)
+            {
+                return new ToolStripSeparator();
+            }
+            else if (item is CommandItem)
+            {
+                var cmd = (CommandItem)item;
+                var tsi = new ToolStripButton();
+                _toolInvoker.SetTargetComponent(tsi, _components[cmd.ComponentID]);
+                if (cmd.ShowLabel)
+                    tsi.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
+                else
+                    tsi.DisplayStyle = ToolStripItemDisplayStyle.Image;
+                return tsi;
+            }
+            else if (item is SubMenu)
+            {
+                var sm = (SubMenu)item;
+                var tsi = new ToolStripDropDownButton();
+                tsi.Image = Properties.Resources.icon_tasks;
+                tsi.Text = sm.Label;
+                tsi.ToolTipText = sm.Label;
+
+                foreach (var child in sm.Items)
+                {
+                    tsi.DropDown.Items.Add(CreateMenuItem(child));
+                }
+                return tsi;
+            }
+            else
+            {
+                throw new NotSupportedException("Unsupported item type: " + item.GetType().Name);
+            }
+        }
+
+        private ToolStripItem CreateMenuItem(ItemBase item)
+        {
+            if (item == null)
+                throw new ArgumentNullException("item");
+
+            if (item is SeparatorItem)
+            {
+                return new ToolStripSeparator();
+            }
+            else if (item is CommandItem)
+            {
+                var cmd = (CommandItem)item;
+                var tsi = new ToolStripMenuItem();
+                _menuInvoker.SetTargetComponent(tsi, _components[cmd.ComponentID]);
+                //Disregard ShowLabel property
+                tsi.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
+                //if (cmd.ShowLabel)
+                //    tsi.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
+                //else
+                //    tsi.DisplayStyle = ToolStripItemDisplayStyle.Image;
+                return tsi;
+            }
+            else if (item is SubMenu)
+            {
+                var sm = (SubMenu)item;
+                var tsi = new ToolStripMenuItem();
+                //tsi.Image = Properties.Resources.icon_tasks;
+                tsi.Text = sm.Label;
+                tsi.ToolTipText = sm.Label;
+
+                foreach (var child in sm.Items)
+                {
+                    tsi.DropDown.Items.Add(CreateMenuItem(child));
+                }
+                return tsi;
+            }
+            else
+            {
+                throw new NotSupportedException("Unsupported item type: " + item.GetType().Name);
+            }
+        }
+
+        private void InitializeMenu(MenuDefinition menuDefinition)
+        {
+            mainMenu.Items.Clear();
+            foreach (var item in menuDefinition.Items)
+            {
+                mainMenu.Items.Add(CreateMenuItem(item));
+            }
+        }
+
+        private void InitializeComponentSet(AppLayout layout)
+        {
+            var thisAsm = this.GetType().Assembly;
+            var thisPublicTypes = thisAsm.GetExportedTypes();
+            var assemblies = new Dictionary<string, Assembly>();
+            _components = new Dictionary<string, MgComponent>();
+
+            // We do this in 3 passes:
+            //
+            // 1. Create the components in the component set
+            // 2. Then set the properties of the instantiated components
+            // 3. Assign the viewer to all these components
+
+            // 1st pass
+            foreach (var compDef in layout.Components)
+            {
+                if (compDef.Assembly == null)
+                {
+                    foreach (var type in thisPublicTypes)
+                    {
+                        if (type.FullName == compDef.ClassName)
+                        {
+                            if (_components.ContainsKey(compDef.ComponentID))
+                                throw new InvalidOperationException("A component with ID " + compDef.ComponentID + " already exists");
+                            var comp = (MgComponent)Activator.CreateInstance(type);
+                            _components[compDef.ComponentID] = comp;
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    if (!assemblies.ContainsKey(compDef.Assembly))
+                    {
+                        assemblies[compDef.Assembly] = Assembly.LoadFrom(compDef.Assembly);
+                    }
+
+                    foreach (var type in assemblies[compDef.Assembly].GetExportedTypes())
+                    {
+                        if (type.FullName == compDef.ClassName)
+                        {
+                            if (_components.ContainsKey(compDef.ComponentID))
+                                throw new InvalidOperationException("A component with ID " + compDef.ComponentID + " already exists");
+                            var comp = (MgComponent)Activator.CreateInstance(type);
+                            _components[compDef.ComponentID] = comp;
+                            break;
+                        }
+                    }
+                }
+            }
+            //2nd pass
+            foreach (var compDef in layout.Components)
+            {
+                var comp = _components[compDef.ComponentID];
+                if (compDef.Properties == null)
+                    continue;
+
+                foreach (var prop in compDef.Properties)
+                {
+                    if (prop.Value.StartsWith(StringPrefixes.COLOR))
+                    {
+                        var colorStr = prop.Value.Substring(StringPrefixes.COLOR.Length);
+                        var color = Util.FromHtmlColor(colorStr);
+                        comp.SetPropertyValue(prop.Name, color);
+                    }
+                    else if (prop.Value.StartsWith(StringPrefixes.COMPONENTID))
+                    {
+                        var compID = prop.Value.Substring(StringPrefixes.COMPONENTID.Length);
+                        if (!_components.ContainsKey(compID))
+                            throw new InvalidOperationException("Component " + compID + " does not exist");
+
+                        comp.SetPropertyValue(prop.Name, _components[compID]);
+                    }
+                    else if (prop.Value.StartsWith(StringPrefixes.ENUM))
+                    {
+                        string [] tokens = prop.Value.Split(':');
+                        if (tokens.Length != 3)
+                            throw new InvalidOperationException("Malformed enum string. Expected enum:className:value");
+                        comp.SetPropertyValue(prop.Name, Enum.Parse(Type.GetType(tokens[1]), tokens[2]));
+                    }
+                    else if (prop.Value.StartsWith(StringPrefixes.TASKPANEID)) //NOTE: only one taskpane instance, but we're checking this as a forward-looking measure
+                    {
+                        comp.SetPropertyValue(prop.Name, taskPane);
+                    }
+                    else if (prop.Value.StartsWith(StringPrefixes.VIEWERID)) //NOTE: only one viewer instance, but we're checking this as a forward-looking measure
+                    {
+                        comp.SetPropertyValue(prop.Name, mapViewer);
+                    }
+                    else
+                    {
+                        comp.SetPropertyValue(prop.Name, prop.Value);
+                    }
+                }
+            }
+
+            //3rd pass
+            foreach (var compDef in layout.Components)
+            {
+                _components[compDef.ComponentID].Viewer = mapViewer;
+            }
+        }
+
+        void IMapStatusBar.SetCursorPositionMessage(string message)
+        {
+            lblCoordinates.Text = message;
+        }
+
+        void IMapStatusBar.SetFeatureSelectedMessage(string message)
+        {
+            lblSelected.Text = message;
+        }
+
+        void IMapStatusBar.SetMapScaleMessage(string message)
+        {
+            lblMapScale.Text = message;
+        }
+
+        void IMapStatusBar.SetMapSizeMessage(string message)
+        {
+            lblMapSize.Text = message;
+        }
+
+        private void btnInitialTask_Click(object sender, EventArgs e)
+        {
+            taskPane.LoadInitialTask();
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.resx
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.resx	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,135 @@
+<?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>
+  <metadata name="viewerContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>565, 17</value>
+  </metadata>
+  <metadata name="viewerToolbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>122, 17</value>
+  </metadata>
+  <metadata name="taskPaneToolbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>227, 17</value>
+  </metadata>
+  <metadata name="mainMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>332, 17</value>
+  </metadata>
+  <metadata name="appStatusBar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>442, 17</value>
+  </metadata>
+</root>
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MapViewer/MapViewer.csproj
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MapViewer.csproj	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MapViewer.csproj	2012-05-16 16:34:57 UTC (rev 6653)
@@ -59,6 +59,16 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="AppLayoutEngine\AppLayout.cs" />
+    <Compile Include="AppLayoutEngine\MgQuitComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="AppLayoutEngine\Shell.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="AppLayoutEngine\Shell.Designer.cs">
+      <DependentUpon>Shell.cs</DependentUpon>
+    </Compile>
     <Compile Include="BaseInteractionComponents.cs">
       <SubType>Component</SubType>
     </Compile>
@@ -197,6 +207,9 @@
     <Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
   </ItemGroup>
   <ItemGroup>
+    <EmbeddedResource Include="AppLayoutEngine\Shell.resx">
+      <DependentUpon>Shell.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="Debug.resx">
       <Generator>ResXFileCodeGenerator</Generator>
       <LastGenOutput>Debug.Designer.cs</LastGenOutput>

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgBufferComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgBufferComponent.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgBufferComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -20,9 +20,11 @@
         }
 
         [Description("The default name of the buffer layer that is created")]
+        [MgComponentProperty]
         public string DefaultLayerName { get; set; }
 
         [Description("The default buffer unit selection")]
+        [MgComponentProperty]
         public MeasurementUnit DefaultBufferUnits { get; set; }
 
         protected override MgControlImpl CreateControlImpl()

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgComponent.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -5,15 +5,34 @@
 using System.Windows.Forms;
 using System.Drawing;
 using System.Diagnostics;
+using System.Reflection;
 
 namespace OSGeo.MapGuide.Viewer
 {
+    public interface IMapComponent
+    {
+        IEnumerable<PropertyInfo> ComponentProperties { get; }
+
+        void SetPropertyValue(string propertyName, object value);
+
+        object GetPropertyValue(string propertyName);
+    }
+
     /// <summary>
+    /// Indicates that a given CLR property is dynamically invokable
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Property)]
+    public class MgComponentPropertyAttribute : Attribute
+    {
+
+    }
+
+    /// <summary>
     /// The base class of all viewer components. This is analogous to a command in the MapGuide
     /// AJAX viewer and a widget in the Fusion viewer.
     /// </summary>
     [ToolboxItem(false)]
-    public class MgComponent : Component
+    public class MgComponent : Component, IMapComponent
     {
         private IMapViewer _viewer;
 
@@ -23,6 +42,7 @@
         /// </summary>
         [Category("MapGuide Component Properties")]
         [Description("Disables this component while the digitizing is happening")]
+        [MgComponentProperty]
         public virtual bool DisableWhenDigitizing { get { return true; } }
 
         /// <summary>
@@ -31,6 +51,7 @@
         /// </summary>
         [Category("MapGuide Component Properties")]
         [Description("Disables this component while the map is loading")]
+        [MgComponentProperty]
         public virtual bool DisableWhenMapIsLoading { get { return true; } }
 
         /// <summary>
@@ -38,6 +59,7 @@
         /// </summary>
         [Category("MapGuide Component Properties")]
         [Description("The description of this component")]
+        [MgComponentProperty]
         public string Label { get; set; }
 
         /// <summary>
@@ -45,6 +67,7 @@
         /// </summary>
         [Category("MapGuide Component Properties")]
         [Description("The tooltip text of this component")]
+        [MgComponentProperty]
         public string ToolTipText { get; set; }
 
         /// <summary>
@@ -52,6 +75,7 @@
         /// </summary>
         [Category("MapGuide Component Properties")]
         [Description("The icon for this component")]
+        [MgComponentProperty]
         public Image Icon { get; set; }
 
         /// <summary>
@@ -59,6 +83,7 @@
         /// </summary>
         [Category("MapGuide Component Properties")]
         [Description("The viewer instance to subscribe events to")]
+        [MgComponentProperty]
         public IMapViewer Viewer
         {
             get { return _viewer; }
@@ -156,6 +181,57 @@
         {
             
         }
+
+        private Dictionary<string, PropertyInfo> _properties;
+
+        public IEnumerable<PropertyInfo> ComponentProperties
+        {
+            get 
+            {
+                CheckAndInitProperties();
+                return _properties.Values;
+            }
+        }
+
+        private void CheckAndInitProperties()
+        {
+            if (_properties == null)
+            {
+                _properties = new Dictionary<string, PropertyInfo>();
+                var props = this.GetType().GetProperties();
+                foreach (var p in props)
+                {
+                    var attributes = p.GetCustomAttributes(true);
+                    foreach (var att in attributes)
+                    {
+                        var compAttr = att as MgComponentPropertyAttribute;
+                        if (compAttr != null)
+                        {
+                            _properties[p.Name] = p;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        public void SetPropertyValue(string propertyName, object value)
+        {
+            CheckAndInitProperties();
+            if (!_properties.ContainsKey(propertyName))
+                throw new InvalidOperationException("Property " + propertyName + " is not a valid component property as it has not been marked with the MgComponentProperty attribute");
+
+            _properties[propertyName].SetValue(this, value, null);
+        }
+
+        public object GetPropertyValue(string propertyName)
+        {
+            CheckAndInitProperties();
+            if (!_properties.ContainsKey(propertyName))
+                throw new InvalidOperationException("Property " + propertyName + " is not a valid component property as it has not been marked with the MgComponentProperty attribute");
+
+            return _properties[propertyName].GetValue(propertyName, null);
+        }
     }
 
     public delegate void ViewerBusyStateEventHandler(bool busy);
@@ -200,6 +276,7 @@
         /// </summary>
         [Category("MapGuide Component Properties")]
         [Description("The task pane which will host the UI view")]
+        [MgComponentProperty]
         public MgTaskPane TaskPane
         {
             get;
@@ -214,6 +291,7 @@
         [Category("MapGuide Component Properties")]
         [DefaultValue(MgViewerTarget.NewWindow)]
         [Description("Target that this component should display its UI view in")]
+        [MgComponentProperty]
         public MgViewerTarget Target
         {
             get { return _target; }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgGenericInvokeComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgGenericInvokeComponent.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgGenericInvokeComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -15,6 +15,7 @@
 
         [Category("MapGuide Viewer")]
         [Description("Indicates whether this component can be invoked without a loaded map")]
+        [MgComponentProperty]
         public bool CanInvokeWithoutLoadedMap
         {
             get;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgInvokeComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgInvokeComponent.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgInvokeComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -40,6 +40,15 @@
                 return null;
         }
 
+        public void Clear()
+        {
+            foreach (var key in _bindings.Keys)
+            {
+                TeardownComponent(key, _bindings[key]);
+            }
+            _bindings.Clear();
+        }
+
         void OnComponentClicked(object sender, EventArgs e)
         {
             var item = sender as T;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgLoadMapComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgLoadMapComponent.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgLoadMapComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -9,6 +9,7 @@
     public class MgLoadMapComponent : MgComponent
     {
         [Description("The map definition to load")]
+        [MgComponentProperty]
         public string MapDefinition
         {
             get;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgLoadPackageComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgLoadPackageComponent.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgLoadPackageComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -24,6 +24,7 @@
         }
 
         [Description("The LoadMap component to invoke once the package has been loaded")]
+        [MgComponentProperty]
         public MgLoadMapComponent InvokeOnPackageLoad
         {
             get;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgMapViewerProvider.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgMapViewerProvider.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgMapViewerProvider.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -69,7 +69,7 @@
             }
         }
 
-        internal void LoadMap(MgMapBase map)
+        public void LoadMap(MgMapBase map)
         {
             if (map == null)
                 return;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgMeasureComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgMeasureComponent.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgMeasureComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -33,6 +33,7 @@
         [Category("MapGuide Component Properties")]
         [Description("The default units to measure in")]
         [DefaultValue(MeasurementUnit.Meters)]
+        [MgComponentProperty]
         public MeasurementUnit PreferredUnits
         {
             get;
@@ -45,6 +46,7 @@
         [DefaultValue(MeasureMode.Line)]
         [Browsable(true)]
         [Description("The mode of measurement")]
+        [MgComponentProperty]
         public MeasureMode MeasureMode
         {
             get { return _measureMode; }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsComponent.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -20,6 +20,7 @@
         }
         
         [Description("The directory where the preferences are saved to and loaded from")]
+        [MgComponentProperty]
         public string PreferencesDirectory
         {
             get;

Modified: branches/2.4/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -586,6 +586,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Exit.
+        /// </summary>
+        internal static string TextExitApplication {
+            get {
+                return ResourceManager.GetString("TextExitApplication", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Load Package.
         /// </summary>
         internal static string TextLoadPackage {

Modified: branches/2.4/MgDev/Desktop/MapViewer/Properties/Resources.resx
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/Properties/Resources.resx	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/Properties/Resources.resx	2012-05-16 16:34:57 UTC (rev 6653)
@@ -433,4 +433,7 @@
   <data name="AreaRuleTemplate" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\AreaRuleTemplate.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
   </data>
+  <data name="TextExitApplication" xml:space="preserve">
+    <value>Exit</value>
+  </data>
 </root>
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MapViewer/Tasks/MgTaskPaneStub.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/Tasks/MgTaskPaneStub.Designer.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/Tasks/MgTaskPaneStub.Designer.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -34,6 +34,9 @@
             // 
             // label2
             // 
+            this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                        | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
             this.label2.Location = new System.Drawing.Point(17, 15);
             this.label2.Name = "label2";
             this.label2.Size = new System.Drawing.Size(208, 427);

Modified: branches/2.4/MgDev/Desktop/MapViewer/Util.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/Util.cs	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MapViewer/Util.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -13,6 +13,12 @@
             return String.Format("{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
         }
 
+        public static Color FromHtmlColor(string html)
+        {
+            int rgb = int.Parse(html, System.Globalization.NumberStyles.HexNumber);
+            return Color.FromArgb(rgb);
+        }
+
         public static MgLayerBase FindLayer(MgLayerCollection layers, String layerName)
         {
             MgLayerBase layer = null;


Property changes on: branches/2.4/MgDev/Desktop/MgAppLayout
___________________________________________________________________
Added: svn:ignore
   + bin
obj
MgAppLayout.csproj.user


Added: branches/2.4/MgDev/Desktop/MgAppLayout/MgAppLayout.csproj
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/MgAppLayout.csproj	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/MgAppLayout.csproj	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>MgAppLayout</RootNamespace>
+    <AssemblyName>MgAppLayout</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>..\bin\Release64\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>..\bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="OSGeo.MapGuide.Desktop, Version=2.4.0.0, Culture=neutral, PublicKeyToken=e75f9fd7cf82dc3f, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\Assemblies\OSGeo.MapGuide.Desktop.dll</HintPath>
+    </Reference>
+    <Reference Include="OSGeo.MapGuide.Foundation, Version=1.0.0.1, Culture=neutral, PublicKeyToken=f526c48929fda856, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\Assemblies\OSGeo.MapGuide.Foundation.dll</HintPath>
+    </Reference>
+    <Reference Include="OSGeo.MapGuide.Geometry, Version=1.0.0.1, Culture=neutral, PublicKeyToken=f526c48929fda856, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\Assemblies\OSGeo.MapGuide.Geometry.dll</HintPath>
+    </Reference>
+    <Reference Include="OSGeo.MapGuide.PlatformBase, Version=1.0.0.1, Culture=neutral, PublicKeyToken=f526c48929fda856, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\Assemblies\OSGeo.MapGuide.PlatformBase.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <None Include="Sheboygan.AppLayout">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\MapViewer.Desktop\MapViewer.Desktop.csproj">
+      <Project>{E2001B46-F226-4F7B-911E-252B9644236E}</Project>
+      <Name>MapViewer.Desktop</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\MapViewer\MapViewer.csproj">
+      <Project>{D46ED17B-329B-4D80-9181-FEF8307EFCBB}</Project>
+      <Name>MapViewer</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/MgAppLayout/Program.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Program.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Program.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using OSGeo.MapGuide;
+using OSGeo.MapGuide.Viewer.AppLayoutEngine;
+using System.Xml.Serialization;
+using System.IO;
+using OSGeo.MapGuide.Viewer.Desktop;
+using System.Diagnostics;
+
+namespace MgAppLayout
+{
+    static class Program
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main(string [] args)
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
+            
+            //Must call MgPlatform.Initialize() before we can work with anything from the MapGuide API
+            try
+            {
+                var sw = new Stopwatch();
+                sw.Start();
+                MgPlatform.Initialize("Platform.ini");
+                sw.Stop();
+                Trace.TraceInformation("Platform initialization took {0}ms", sw.ElapsedMilliseconds);
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show(ex.ToString(), "Error");
+                return;
+            }
+
+            AppLayout layout = null;
+
+            var ser = new XmlSerializer(typeof(AppLayout));
+            if (args.Length == 1)
+            {
+                using (var file = File.OpenRead(args[0]))
+                {
+                    layout = (AppLayout)ser.Deserialize(file);
+                }
+            }/*
+            else
+            {
+                layout = AppLayout.CreateDefault("MapGuide Desktop App Layout Example", "Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition");
+                using (var file = File.OpenWrite("Sheboygan.AppLayout"))
+                {
+                    ser.Serialize(file, layout);
+                }
+            }*/
+
+            var mdfId = new MgResourceIdentifier(layout.Map.MapDefinition);
+            var provider = new MgDesktopMapViewerProvider(null);
+            var resSvc = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+            if (resSvc.ResourceExists(mdfId))
+                provider.LoadMap(new MgdMap(mdfId));
+            var frm = new Shell(layout, provider);
+            Application.ApplicationExit += new EventHandler(OnAppExit);
+            Application.Run(frm);
+        }
+
+        static void OnAppExit(object sender, EventArgs e)
+        {
+            MgPlatform.Terminate();
+        }
+
+        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
+        {
+            MessageBox.Show(e.Exception.ToString());
+        }
+    }
+}


Property changes on: branches/2.4/MgDev/Desktop/MgAppLayout/Properties
___________________________________________________________________
Added: bugtraq:number
   + true

Added: branches/2.4/MgDev/Desktop/MgAppLayout/Properties/AssemblyInfo.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Properties/AssemblyInfo.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Properties/AssemblyInfo.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MgAppLayout")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MgAppLayout")]
+[assembly: AssemblyCopyright("Copyright ©  2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("0f10bb70-3ad7-415d-9ad6-b14fcd81fb74")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

Added: branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Resources.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Resources.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Resources.Designer.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.5420
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace MgAppLayout.Properties
+{
+
+
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources
+    {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources()
+        {
+        }
+
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager
+        {
+            get
+            {
+                if ((resourceMan == null))
+                {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MgAppLayout.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture
+        {
+            get
+            {
+                return resourceCulture;
+            }
+            set
+            {
+                resourceCulture = value;
+            }
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Resources.resx
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Resources.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Resources.resx	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,117 @@
+<?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.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: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" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </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" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </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

Added: branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Settings.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Settings.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Settings.Designer.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.5420
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace MgAppLayout.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Settings.settings
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Settings.settings	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Properties/Settings.settings	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

Added: branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,432 @@
+<?xml version="1.0"?>
+<AppLayout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <Title>MapGuide Desktop App Layout Example</Title>
+  <Icon>app.ico</Icon>
+  <Settings>
+    <InvokeOnStartup>Startup</InvokeOnStartup>
+    <SelectionColor>0000FF</SelectionColor>
+    <ConvertTiledGroupsToNonTiled>true</ConvertTiledGroupsToNonTiled>
+    <ShowVertexCoordinatesWhenDigitizing>false</ShowVertexCoordinatesWhenDigitizing>
+    <ZoomInFactor>0.5</ZoomInFactor>
+    <ZoomOutFactor>2</ZoomOutFactor>
+  </Settings>
+  <InfoPane>
+    <Width>200</Width>
+    <Legend>
+      <Visible>true</Visible>
+    </Legend>
+    <PropertyPane>
+      <Visible>true</Visible>
+    </PropertyPane>
+  </InfoPane>
+  <Map>
+    <MapDefinition>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</MapDefinition>
+  </Map>
+  <Menu>
+    <Items>
+      <ItemBase xsi:type="SubMenu">
+        <Label>File</Label>
+        <Items>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>LoadMap</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>LoadPackage</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="SeparatorItem" />
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Quit</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+        </Items>
+      </ItemBase>
+      <ItemBase xsi:type="SubMenu">
+        <Label>Tools</Label>
+        <Items>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Buffer</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Measure</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Query</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Theme</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="SeparatorItem" />
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>ViewerOptions</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+        </Items>
+      </ItemBase>
+    </Items>
+  </Menu>
+  <Toolbar>
+    <Items>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>PrintMap</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>CopyMap</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomIn</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomOut</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>InitialView</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>Select</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>SelectRadius</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>SelectPolygon</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>Pan</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ClearSelection</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>RefreshMap</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>TooltipToggle</ComponentID>
+        <ShowLabel>true</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="SubMenu">
+        <Label>Tools</Label>
+        <Items>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Buffer</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Measure</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Query</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Theme</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="SeparatorItem" />
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>ViewerOptions</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+        </Items>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="SubMenu">
+        <Label>Custom</Label>
+        <Items>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>PlotToDwf</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Profile</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+        </Items>
+      </ItemBase>
+    </Items>
+  </Toolbar>
+  <ContextMenu>
+    <Items>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>RefreshMap</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomIn</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomOut</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomToSelection</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>InitialView</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>Pan</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>Select</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ClearSelection</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="SubMenu">
+        <Label>Tools</Label>
+        <Items>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Buffer</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Measure</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Query</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Theme</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+        </Items>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ViewerOptions</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+    </Items>
+  </ContextMenu>
+  <TaskPane>
+    <Width>250</Width>
+    <TaskMenu>
+      <Items>
+        <ItemBase xsi:type="CommandItem">
+          <ComponentID>Buffer</ComponentID>
+          <ShowLabel>false</ShowLabel>
+        </ItemBase>
+        <ItemBase xsi:type="CommandItem">
+          <ComponentID>Measure</ComponentID>
+          <ShowLabel>false</ShowLabel>
+        </ItemBase>
+        <ItemBase xsi:type="CommandItem">
+          <ComponentID>Query</ComponentID>
+          <ShowLabel>false</ShowLabel>
+        </ItemBase>
+        <ItemBase xsi:type="CommandItem">
+          <ComponentID>Theme</ComponentID>
+          <ShowLabel>false</ShowLabel>
+        </ItemBase>
+      </Items>
+    </TaskMenu>
+  </TaskPane>
+  <Components>
+    <ComponentDefinition>
+      <ComponentID>Buffer</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgBufferComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>DefaultLayerName</Name>
+          <Value>BufferLayer</Value>
+        </NameValue>
+        <NameValue>
+          <Name>DefaultBufferUnits</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MeasurementUnit:Meters</Value>
+        </NameValue>
+        <NameValue>
+          <Name>Target</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MgViewerTarget:TaskPane</Value>
+        </NameValue>
+        <NameValue>
+          <Name>TaskPane</Name>
+          <Value>taskpane:</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>SelectRadius</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgCircleSelectComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ClearSelection</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgClearSelectionComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>CopyMap</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgCopyMapComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>InitialView</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgInitialViewComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>LoadMap</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgLoadMapComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>Label</Name>
+          <Value>Load Sheboygan Map</Value>
+        </NameValue>
+        <NameValue>
+          <Name>MapDefinition</Name>
+          <Value>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>LoadPackage</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgLoadPackageComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>InvokeOnPackageLoad</Name>
+          <Value>component:LoadMap</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Measure</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgMeasureComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>MeasureMode</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MeasureMode:Line</Value>
+        </NameValue>
+        <NameValue>
+          <Name>PreferredUnits</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MeasurementUnit:Meters</Value>
+        </NameValue>
+        <NameValue>
+          <Name>Target</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MgViewerTarget:TaskPane</Value>
+        </NameValue>
+        <NameValue>
+          <Name>TaskPane</Name>
+          <Value>taskpane:</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Pan</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgPanComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>SelectPolygon</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgPolygonSelectComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>PrintMap</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgPrintComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Query</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgQueryComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>Target</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MgViewerTarget:TaskPane</Value>
+        </NameValue>
+        <NameValue>
+          <Name>TaskPane</Name>
+          <Value>taskpane:</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Quit</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.AppLayoutEngine.MgQuitComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>RefreshMap</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgRefreshMapComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Select</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgSelectComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Theme</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgThemeComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>Target</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MgViewerTarget:TaskPane</Value>
+        </NameValue>
+        <NameValue>
+          <Name>TaskPane</Name>
+          <Value>taskpane:</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>TooltipToggle</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgTooltipToggleComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ViewerOptions</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgViewerOptionsComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ZoomIn</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgZoomInComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ZoomOut</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgZoomOutComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ZoomToSelection</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgZoomToSelectionComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>PlotToDwf</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgPlotToDwfComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Profile</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgProfileComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Startup</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgStartupComponent</ClassName>
+    </ComponentDefinition>
+  </Components>
+</AppLayout>
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MgDesktopDotNet.sln
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktopDotNet.sln	2012-05-15 13:41:04 UTC (rev 6652)
+++ branches/2.4/MgDev/Desktop/MgDesktopDotNet.sln	2012-05-16 16:34:57 UTC (rev 6653)
@@ -11,6 +11,10 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapViewerTest", "MapViewerTest\MapViewerTest.csproj", "{E2FC8B99-0638-4C01-86C4-1B625D966981}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MgAppLayout", "MgAppLayout\MgAppLayout.csproj", "{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleExtension", "SampleExtension\SampleExtension.csproj", "{B97E7D94-E693-4081-8229-2FE87E5502E4}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x64 = Debug|x64
@@ -55,6 +59,22 @@
 		{E2FC8B99-0638-4C01-86C4-1B625D966981}.Release|x64.Build.0 = Release|x64
 		{E2FC8B99-0638-4C01-86C4-1B625D966981}.Release|x86.ActiveCfg = Release|x86
 		{E2FC8B99-0638-4C01-86C4-1B625D966981}.Release|x86.Build.0 = Release|x86
+		{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}.Debug|x64.ActiveCfg = Debug|x64
+		{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}.Debug|x64.Build.0 = Debug|x64
+		{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}.Debug|x86.ActiveCfg = Debug|x86
+		{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}.Debug|x86.Build.0 = Debug|x86
+		{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}.Release|x64.ActiveCfg = Release|x64
+		{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}.Release|x64.Build.0 = Release|x64
+		{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}.Release|x86.ActiveCfg = Release|x86
+		{F7FCC5EB-FB46-41FE-AC4B-430DF52C4066}.Release|x86.Build.0 = Release|x86
+		{B97E7D94-E693-4081-8229-2FE87E5502E4}.Debug|x64.ActiveCfg = Debug|x64
+		{B97E7D94-E693-4081-8229-2FE87E5502E4}.Debug|x64.Build.0 = Debug|x64
+		{B97E7D94-E693-4081-8229-2FE87E5502E4}.Debug|x86.ActiveCfg = Debug|x86
+		{B97E7D94-E693-4081-8229-2FE87E5502E4}.Debug|x86.Build.0 = Debug|x86
+		{B97E7D94-E693-4081-8229-2FE87E5502E4}.Release|x64.ActiveCfg = Release|x64
+		{B97E7D94-E693-4081-8229-2FE87E5502E4}.Release|x64.Build.0 = Release|x64
+		{B97E7D94-E693-4081-8229-2FE87E5502E4}.Release|x86.ActiveCfg = Release|x86
+		{B97E7D94-E693-4081-8229-2FE87E5502E4}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE


Property changes on: branches/2.4/MgDev/Desktop/SampleExtension
___________________________________________________________________
Added: svn:ignore
   + bin
obj


Added: branches/2.4/MgDev/Desktop/SampleExtension/MgPlotToDwfComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/MgPlotToDwfComponent.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/MgPlotToDwfComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.Viewer;
+using System.Windows.Forms;
+using OSGeo.MapGuide;
+
+namespace SampleExtension
+{
+    public class MgPlotToDwfComponent : MgComponent
+    {
+        public MgPlotToDwfComponent()
+        {
+            this.Label = "Plot to DWF";
+        }
+
+        public override void Invoke()
+        {
+            var diag = new ResourceIdDialog();
+            if (diag.ShowDialog() == DialogResult.OK)
+            {
+                var layoutId = diag.ResourceID;
+                using (var save = new SaveFileDialog())
+                {
+                    save.Filter = "DWF Files (*.dwf)|*.dwf";
+                    if (save.ShowDialog() == DialogResult.OK)
+                    {
+                        var renderSvc = (MgRenderingService)this.Viewer.GetProvider().CreateService(MgServiceType.RenderingService);
+                        var map = (MgdMap)this.Viewer.GetMap();
+                        var dwfVer = new MgDwfVersion("6.01", "1.2");
+
+                        var layout = new MgLayout(layoutId, "TestPlot", MgPageUnitsType.Inches);
+                        var plotSpec = new MgPlotSpecification(8.5f, 11.0f, MgPageUnitsType.Inches, 0.5f, 0.5f, 0.5f, 0.5f);
+
+                        var result = renderSvc.GeneratePlot(map, plotSpec, layout, dwfVer);
+                        var sink = new MgByteSink(result);
+                        sink.ToFile(save.FileName);
+
+                        MessageBox.Show("Saved to " + save.FileName);
+                    }
+                }
+            }
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/MgProfileComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/MgProfileComponent.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/MgProfileComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.Viewer;
+using OSGeo.MapGuide;
+
+namespace SampleExtension
+{
+    public class MgProfileComponent : MgComponent
+    {
+        public MgProfileComponent()
+        {
+            this.Label = "Profile";
+        }
+
+        public override void Invoke()
+        {
+            var provider = this.Viewer.GetProvider();
+            var map = this.Viewer.GetMap();
+            var prof = (MgProfilingService)provider.CreateService(MgServiceType.ProfilingService);
+            var opts = new MgRenderingOptions("PNG", 2, new MgColor(this.Viewer.SelectionColor));
+            var result = prof.ProfileRenderDynamicOverlay((MgdMap)map, (MgdSelection)this.Viewer.GetSelection(), opts);
+            new XmlResponseDialog(result).ShowDialog(); 
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/MgStartupComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/MgStartupComponent.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/MgStartupComponent.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.Viewer;
+using System.Windows.Forms;
+
+namespace SampleExtension
+{
+    public class MgStartupComponent : MgComponent
+    {
+        public override void Invoke()
+        {
+            MessageBox.Show("If you see this message. It is because I was automatically invoked by the AppLayout's InvokeOnStartup property", "SampleExtension: MgStartupComponent");
+        }
+    }
+}


Property changes on: branches/2.4/MgDev/Desktop/SampleExtension/Properties
___________________________________________________________________
Added: bugtraq:number
   + true

Added: branches/2.4/MgDev/Desktop/SampleExtension/Properties/AssemblyInfo.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Properties/AssemblyInfo.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Properties/AssemblyInfo.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("SampleExtension")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SampleExtension")]
+[assembly: AssemblyCopyright("Copyright ©  2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("32bca14c-b821-4aab-853f-7babe74abb9f")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

Added: branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.Designer.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,97 @@
+namespace SampleExtension
+{
+    partial class ResourceIdDialog
+    {
+        /// <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.txtResourceId = new System.Windows.Forms.TextBox();
+            this.btnOk = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(13, 22);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(67, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "Resource ID";
+            // 
+            // txtResourceId
+            // 
+            this.txtResourceId.Location = new System.Drawing.Point(16, 38);
+            this.txtResourceId.Name = "txtResourceId";
+            this.txtResourceId.Size = new System.Drawing.Size(256, 20);
+            this.txtResourceId.TabIndex = 1;
+            // 
+            // btnOk
+            // 
+            this.btnOk.Location = new System.Drawing.Point(116, 64);
+            this.btnOk.Name = "btnOk";
+            this.btnOk.Size = new System.Drawing.Size(75, 23);
+            this.btnOk.TabIndex = 2;
+            this.btnOk.Text = "OK";
+            this.btnOk.UseVisualStyleBackColor = true;
+            this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
+            // 
+            // btnCancel
+            // 
+            this.btnCancel.Location = new System.Drawing.Point(197, 64);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 3;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.UseVisualStyleBackColor = true;
+            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+            // 
+            // ResourceIdDialog
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(284, 100);
+            this.ControlBox = false;
+            this.Controls.Add(this.btnCancel);
+            this.Controls.Add(this.btnOk);
+            this.Controls.Add(this.txtResourceId);
+            this.Controls.Add(this.label1);
+            this.Name = "ResourceIdDialog";
+            this.Text = "Enter Resource ID";
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.TextBox txtResourceId;
+        private System.Windows.Forms.Button btnOk;
+        private System.Windows.Forms.Button btnCancel;
+    }
+}
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide;
+
+namespace SampleExtension
+{
+    public partial class ResourceIdDialog : Form
+    {
+        public ResourceIdDialog()
+        {
+            InitializeComponent();
+        }
+
+        private void btnCancel_Click(object sender, EventArgs e)
+        {
+            this.DialogResult = DialogResult.Cancel;
+        }
+
+        public MgResourceIdentifier ResourceID { get; private set; }
+
+        private void btnOk_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                var resId = new MgResourceIdentifier(txtResourceId.Text);
+                resId.Validate();
+
+                var fact = new MgServiceFactory();
+                var resSvc = (MgResourceService)fact.CreateService(MgServiceType.ResourceService);
+                if (!resSvc.ResourceExists(resId))
+                {
+                    MessageBox.Show("The specified resource does not exist");
+                    return;
+                }
+                this.ResourceID = resId;
+                this.DialogResult = DialogResult.OK;
+            }
+            catch (MgException ex)
+            {
+                MessageBox.Show(ex.Message);
+                ex.Dispose();
+            }
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/ResourceIdDialog.resx	2012-05-16 16:34:57 UTC (rev 6653)
@@ -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

Added: branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{B97E7D94-E693-4081-8229-2FE87E5502E4}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>SampleExtension</RootNamespace>
+    <AssemblyName>SampleExtension</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>..\bin\Release64\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>..\bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="OSGeo.MapGuide.Desktop, Version=2.4.0.0, Culture=neutral, PublicKeyToken=e75f9fd7cf82dc3f, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\Assemblies\OSGeo.MapGuide.Desktop.dll</HintPath>
+    </Reference>
+    <Reference Include="OSGeo.MapGuide.Foundation, Version=1.0.0.1, Culture=neutral, PublicKeyToken=f526c48929fda856, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\Assemblies\OSGeo.MapGuide.Foundation.dll</HintPath>
+    </Reference>
+    <Reference Include="OSGeo.MapGuide.Geometry, Version=1.0.0.1, Culture=neutral, PublicKeyToken=f526c48929fda856, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\Assemblies\OSGeo.MapGuide.Geometry.dll</HintPath>
+    </Reference>
+    <Reference Include="OSGeo.MapGuide.PlatformBase, Version=1.0.0.1, Culture=neutral, PublicKeyToken=f526c48929fda856, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\Assemblies\OSGeo.MapGuide.PlatformBase.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="MgProfileComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgPlotToDwfComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgStartupComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ResourceIdDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="ResourceIdDialog.Designer.cs">
+      <DependentUpon>ResourceIdDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="XmlResponseDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="XmlResponseDialog.Designer.cs">
+      <DependentUpon>XmlResponseDialog.cs</DependentUpon>
+    </Compile>
+    <Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\MapViewer\MapViewer.csproj">
+      <Project>{D46ED17B-329B-4D80-9181-FEF8307EFCBB}</Project>
+      <Name>MapViewer</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="ResourceIdDialog.resx">
+      <DependentUpon>ResourceIdDialog.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="XmlResponseDialog.resx">
+      <DependentUpon>XmlResponseDialog.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.Designer.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,78 @@
+namespace SampleExtension
+{
+    partial class XmlResponseDialog
+    {
+        /// <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.button1 = new System.Windows.Forms.Button();
+            this.textBox1 = new System.Windows.Forms.TextBox();
+            this.SuspendLayout();
+            // 
+            // button1
+            // 
+            this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.button1.Location = new System.Drawing.Point(389, 352);
+            this.button1.Name = "button1";
+            this.button1.Size = new System.Drawing.Size(75, 23);
+            this.button1.TabIndex = 0;
+            this.button1.Text = "Close";
+            this.button1.UseVisualStyleBackColor = true;
+            this.button1.Click += new System.EventHandler(this.button1_Click);
+            // 
+            // textBox1
+            // 
+            this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                        | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.textBox1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.textBox1.Location = new System.Drawing.Point(13, 13);
+            this.textBox1.Multiline = true;
+            this.textBox1.Name = "textBox1";
+            this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.textBox1.Size = new System.Drawing.Size(451, 333);
+            this.textBox1.TabIndex = 1;
+            // 
+            // XmlResponseDialog
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(476, 387);
+            this.Controls.Add(this.textBox1);
+            this.Controls.Add(this.button1);
+            this.Name = "XmlResponseDialog";
+            this.Text = "XmlResponseDialog";
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Button button1;
+        private System.Windows.Forms.TextBox textBox1;
+    }
+}
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.cs	2012-05-16 16:34:57 UTC (rev 6653)
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide;
+using System.Xml;
+using System.IO;
+
+namespace SampleExtension
+{
+    public partial class XmlResponseDialog : Form
+    {
+        public XmlResponseDialog()
+        {
+            InitializeComponent();
+        }
+
+        public XmlResponseDialog(MgByteReader reader)
+            : this()
+        {
+            this.Content = reader.ToString();
+        }
+
+        public string Content
+        {
+            get { return textBox1.Text; }
+            set
+            {
+                textBox1.Text = FormatXml(value);
+            }
+        }
+
+        private string FormatXml(string sUnformattedXml)
+        {
+            //load unformatted xml into a dom
+            XmlDocument xd = new XmlDocument();
+            xd.LoadXml(sUnformattedXml);
+
+            //will hold formatted xml
+            StringBuilder sb = new StringBuilder();
+
+            //pumps the formatted xml into the StringBuilder above
+            StringWriter sw = new StringWriter(sb);
+
+            //does the formatting
+            XmlTextWriter xtw = null;
+
+            try
+            {
+                //point the xtw at the StringWriter
+                xtw = new XmlTextWriter(sw);
+
+                //we want the output formatted
+                xtw.Formatting = Formatting.Indented;
+
+                //get the dom to dump its contents into the xtw
+                xd.WriteTo(xtw);
+            }
+            finally
+            {
+                //clean up even if error
+                if (xtw != null)
+                    xtw.Close();
+            }
+
+            //return the formatted xml
+            return sb.ToString();
+        }
+
+        private void button1_Click(object sender, EventArgs e)
+        {
+            this.Close();
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/XmlResponseDialog.resx	2012-05-16 16:34:57 UTC (rev 6653)
@@ -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



More information about the mapguide-commits mailing list