[mapguide-commits] r6932 - in trunk/Tools/Maestro: Maestro.Editors Maestro.Editors/Fusion Maestro.Editors/Fusion/WidgetEditors OSGeo.MapGuide.MaestroAPI/ObjectModels OSGeo.MapGuide.MaestroAPI/Properties OSGeo.MapGuide.MaestroAPI/Resource/Validation

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu Aug 2 06:48:05 PDT 2012


Author: jng
Date: 2012-08-02 06:48:04 -0700 (Thu, 02 Aug 2012)
New Revision: 6932

Added:
   trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.Designer.cs
   trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.cs
   trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.resx
   trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.Designer.cs
   trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.cs
   trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.resx
Modified:
   trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.Designer.cs
   trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.cs
   trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.resx
   trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetReferenceCtrl.Designer.cs
   trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetReferenceCtrl.resx
   trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetSettingsCtrl.cs
   trunk/Tools/Maestro/Maestro.Editors/Maestro.Editors.csproj
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ApplicationDefinitionInterfaces.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ApplicationDefinitionValidator.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorSet.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationStatusCode.cs
Log:
#2089, #1635: Fusion editor fixes and enhancements:
 - Generic Widget XML editor fixes/enhancements:
    - Fix Generic Widget XML editor incorrectly saving extension elements. It was previously doing it by element name which is wrong because a widget can have multiple extension elements of the same name.
    - Add a Widget Info button that shows available extension properties for the current widget
 - New validation rules:
    - Check for widget references to non-existent widgets
    - Check for non-UI widgets being attached to containers. You wouldn't want to attach a Map widget to a menu!
    - Check for referenced widgets with no labels or icons. These probably won't be displayed in such cases.
 - Widget section fixes:
    - Add missing menu properties editor for Flyout menus
    - Enable Move up/down when flyout menus are selected
    - Enable assorted functionality that was previously disabled when a flyout menu is selected.
 - Fix missing labels for widgets under the "View" menu of a new Fusion template. Thank the new validation rules in place that caught this out.
 - If a NullReferenceException is thrown during a validation run, log the full gory details instead of going through the NestedExceptionMessageProcessor

Added: trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.Designer.cs	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.Designer.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -0,0 +1,115 @@
+namespace Maestro.Editors.Fusion
+{
+    partial class MenuCtrl
+    {
+        /// <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 Component 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()
+        {
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MenuCtrl));
+            this.label1 = new System.Windows.Forms.Label();
+            this.txtMenuLabel = new System.Windows.Forms.TextBox();
+            this.txtTooltip = new System.Windows.Forms.TextBox();
+            this.label2 = new System.Windows.Forms.Label();
+            this.txtImageUrl = new System.Windows.Forms.TextBox();
+            this.label3 = new System.Windows.Forms.Label();
+            this.txtImageClass = new System.Windows.Forms.TextBox();
+            this.label4 = new System.Windows.Forms.Label();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            resources.ApplyResources(this.label1, "label1");
+            this.label1.Name = "label1";
+            // 
+            // txtMenuLabel
+            // 
+            resources.ApplyResources(this.txtMenuLabel, "txtMenuLabel");
+            this.txtMenuLabel.Name = "txtMenuLabel";
+            this.txtMenuLabel.TextChanged += new System.EventHandler(this.txtMenuLabel_TextChanged);
+            // 
+            // txtTooltip
+            // 
+            resources.ApplyResources(this.txtTooltip, "txtTooltip");
+            this.txtTooltip.Name = "txtTooltip";
+            this.txtTooltip.TextChanged += new System.EventHandler(this.txtTooltip_TextChanged);
+            // 
+            // label2
+            // 
+            resources.ApplyResources(this.label2, "label2");
+            this.label2.Name = "label2";
+            // 
+            // txtImageUrl
+            // 
+            resources.ApplyResources(this.txtImageUrl, "txtImageUrl");
+            this.txtImageUrl.Name = "txtImageUrl";
+            this.txtImageUrl.TextChanged += new System.EventHandler(this.txtImageUrl_TextChanged);
+            // 
+            // label3
+            // 
+            resources.ApplyResources(this.label3, "label3");
+            this.label3.Name = "label3";
+            // 
+            // txtImageClass
+            // 
+            resources.ApplyResources(this.txtImageClass, "txtImageClass");
+            this.txtImageClass.Name = "txtImageClass";
+            this.txtImageClass.TextChanged += new System.EventHandler(this.txtImageClass_TextChanged);
+            // 
+            // label4
+            // 
+            resources.ApplyResources(this.label4, "label4");
+            this.label4.Name = "label4";
+            // 
+            // MenuCtrl
+            // 
+            resources.ApplyResources(this, "$this");
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.txtImageClass);
+            this.Controls.Add(this.label4);
+            this.Controls.Add(this.txtImageUrl);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.txtTooltip);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.txtMenuLabel);
+            this.Controls.Add(this.label1);
+            this.Name = "MenuCtrl";
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.TextBox txtMenuLabel;
+        private System.Windows.Forms.TextBox txtTooltip;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.TextBox txtImageUrl;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.TextBox txtImageClass;
+        private System.Windows.Forms.Label label4;
+    }
+}

Added: trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.cs	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -0,0 +1,91 @@
+#region Disclaimer / License
+// Copyright (C) 2012, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.ObjectModels.ApplicationDefinition;
+
+namespace Maestro.Editors.Fusion
+{
+    [ToolboxItem(false)]
+    public partial class MenuCtrl : UserControl
+    {
+        private MenuCtrl()
+        {
+            InitializeComponent();
+        }
+
+        private IFlyoutItem _menu;
+        private IEditorService _edSvc;
+        private bool _init = false;
+
+        public MenuCtrl(IFlyoutItem menu, IEditorService edSvc)
+            : this()
+        {
+            _menu = menu;
+            _edSvc = edSvc;
+            _init = true;
+            try
+            {
+                txtMenuLabel.Text = _menu.Label;
+                txtImageClass.Text = _menu.ImageClass;
+                txtImageUrl.Text = _menu.ImageUrl;
+                txtTooltip.Text = _menu.Tooltip;
+            }
+            finally
+            {
+                _init = false;
+            }
+        }
+
+        private void txtMenuLabel_TextChanged(object sender, EventArgs e)
+        {
+            if (_init)
+                return;
+            _menu.Label = txtMenuLabel.Text;
+        }
+
+        private void txtTooltip_TextChanged(object sender, EventArgs e)
+        {
+            if (_init)
+                return;
+            _menu.Tooltip = txtTooltip.Text;
+        }
+
+        private void txtImageUrl_TextChanged(object sender, EventArgs e)
+        {
+            if (_init)
+                return;
+            _menu.ImageUrl = txtImageUrl.Text;
+        }
+
+        private void txtImageClass_TextChanged(object sender, EventArgs e)
+        {
+            if (_init)
+                return;
+            _menu.ImageClass = txtImageClass.Text;
+        }
+    }
+}

Added: trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.resx	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/MenuCtrl.resx	2012-08-02 13:48:04 UTC (rev 6932)
@@ -0,0 +1,351 @@
+<?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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="label1.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="label1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>18, 17</value>
+  </data>
+  <data name="label1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>33, 13</value>
+  </data>
+  <data name="label1.TabIndex" type="System.Int32, mscorlib">
+    <value>0</value>
+  </data>
+  <data name="label1.Text" xml:space="preserve">
+    <value>Label</value>
+  </data>
+  <data name=">>label1.Name" xml:space="preserve">
+    <value>label1</value>
+  </data>
+  <data name=">>label1.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>label1.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>label1.ZOrder" xml:space="preserve">
+    <value>7</value>
+  </data>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="txtMenuLabel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="txtMenuLabel.Location" type="System.Drawing.Point, System.Drawing">
+    <value>112, 14</value>
+  </data>
+  <data name="txtMenuLabel.Size" type="System.Drawing.Size, System.Drawing">
+    <value>260, 20</value>
+  </data>
+  <data name="txtMenuLabel.TabIndex" type="System.Int32, mscorlib">
+    <value>1</value>
+  </data>
+  <data name=">>txtMenuLabel.Name" xml:space="preserve">
+    <value>txtMenuLabel</value>
+  </data>
+  <data name=">>txtMenuLabel.Type" xml:space="preserve">
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>txtMenuLabel.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>txtMenuLabel.ZOrder" xml:space="preserve">
+    <value>6</value>
+  </data>
+  <data name="txtTooltip.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="txtTooltip.Location" type="System.Drawing.Point, System.Drawing">
+    <value>112, 40</value>
+  </data>
+  <data name="txtTooltip.Size" type="System.Drawing.Size, System.Drawing">
+    <value>260, 20</value>
+  </data>
+  <data name="txtTooltip.TabIndex" type="System.Int32, mscorlib">
+    <value>3</value>
+  </data>
+  <data name=">>txtTooltip.Name" xml:space="preserve">
+    <value>txtTooltip</value>
+  </data>
+  <data name=">>txtTooltip.Type" xml:space="preserve">
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>txtTooltip.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>txtTooltip.ZOrder" xml:space="preserve">
+    <value>4</value>
+  </data>
+  <data name="label2.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label2.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
+    <value>NoControl</value>
+  </data>
+  <data name="label2.Location" type="System.Drawing.Point, System.Drawing">
+    <value>18, 43</value>
+  </data>
+  <data name="label2.Size" type="System.Drawing.Size, System.Drawing">
+    <value>39, 13</value>
+  </data>
+  <data name="label2.TabIndex" type="System.Int32, mscorlib">
+    <value>2</value>
+  </data>
+  <data name="label2.Text" xml:space="preserve">
+    <value>Tooltip</value>
+  </data>
+  <data name=">>label2.Name" xml:space="preserve">
+    <value>label2</value>
+  </data>
+  <data name=">>label2.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>label2.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>label2.ZOrder" xml:space="preserve">
+    <value>5</value>
+  </data>
+  <data name="txtImageUrl.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="txtImageUrl.Location" type="System.Drawing.Point, System.Drawing">
+    <value>112, 66</value>
+  </data>
+  <data name="txtImageUrl.Size" type="System.Drawing.Size, System.Drawing">
+    <value>260, 20</value>
+  </data>
+  <data name="txtImageUrl.TabIndex" type="System.Int32, mscorlib">
+    <value>5</value>
+  </data>
+  <data name=">>txtImageUrl.Name" xml:space="preserve">
+    <value>txtImageUrl</value>
+  </data>
+  <data name=">>txtImageUrl.Type" xml:space="preserve">
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>txtImageUrl.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>txtImageUrl.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="label3.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label3.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
+    <value>NoControl</value>
+  </data>
+  <data name="label3.Location" type="System.Drawing.Point, System.Drawing">
+    <value>18, 69</value>
+  </data>
+  <data name="label3.Size" type="System.Drawing.Size, System.Drawing">
+    <value>61, 13</value>
+  </data>
+  <data name="label3.TabIndex" type="System.Int32, mscorlib">
+    <value>4</value>
+  </data>
+  <data name="label3.Text" xml:space="preserve">
+    <value>Image URL</value>
+  </data>
+  <data name=">>label3.Name" xml:space="preserve">
+    <value>label3</value>
+  </data>
+  <data name=">>label3.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>label3.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>label3.ZOrder" xml:space="preserve">
+    <value>3</value>
+  </data>
+  <data name="txtImageClass.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="txtImageClass.Location" type="System.Drawing.Point, System.Drawing">
+    <value>112, 92</value>
+  </data>
+  <data name="txtImageClass.Size" type="System.Drawing.Size, System.Drawing">
+    <value>260, 20</value>
+  </data>
+  <data name="txtImageClass.TabIndex" type="System.Int32, mscorlib">
+    <value>7</value>
+  </data>
+  <data name=">>txtImageClass.Name" xml:space="preserve">
+    <value>txtImageClass</value>
+  </data>
+  <data name=">>txtImageClass.Type" xml:space="preserve">
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>txtImageClass.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>txtImageClass.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="label4.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label4.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
+    <value>NoControl</value>
+  </data>
+  <data name="label4.Location" type="System.Drawing.Point, System.Drawing">
+    <value>18, 95</value>
+  </data>
+  <data name="label4.Size" type="System.Drawing.Size, System.Drawing">
+    <value>88, 13</value>
+  </data>
+  <data name="label4.TabIndex" type="System.Int32, mscorlib">
+    <value>6</value>
+  </data>
+  <data name="label4.Text" xml:space="preserve">
+    <value>Image CSS Class</value>
+  </data>
+  <data name=">>label4.Name" xml:space="preserve">
+    <value>label4</value>
+  </data>
+  <data name=">>label4.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>label4.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>label4.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
+    <value>6, 13</value>
+  </data>
+  <data name="$this.Size" type="System.Drawing.Size, System.Drawing">
+    <value>400, 330</value>
+  </data>
+  <data name=">>$this.Name" xml:space="preserve">
+    <value>MenuCtrl</value>
+  </data>
+  <data name=">>$this.Type" xml:space="preserve">
+    <value>System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+</root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.Designer.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.Designer.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -32,6 +32,7 @@
             this.label1 = new System.Windows.Forms.Label();
             this.txtXmlContent = new System.Windows.Forms.TextBox();
             this.btnSave = new System.Windows.Forms.Button();
+            this.btnWidgetInfo = new System.Windows.Forms.Button();
             this.SuspendLayout();
             // 
             // label1
@@ -52,9 +53,17 @@
             this.btnSave.UseVisualStyleBackColor = true;
             this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
             // 
+            // btnWidgetInfo
+            // 
+            resources.ApplyResources(this.btnWidgetInfo, "btnWidgetInfo");
+            this.btnWidgetInfo.Name = "btnWidgetInfo";
+            this.btnWidgetInfo.UseVisualStyleBackColor = true;
+            this.btnWidgetInfo.Click += new System.EventHandler(this.btnWidgetInfo_Click);
+            // 
             // GenericWidgetCtrl
             // 
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
+            this.Controls.Add(this.btnWidgetInfo);
             this.Controls.Add(this.btnSave);
             this.Controls.Add(this.txtXmlContent);
             this.Controls.Add(this.label1);
@@ -70,5 +79,6 @@
         private System.Windows.Forms.Label label1;
         private System.Windows.Forms.TextBox txtXmlContent;
         private System.Windows.Forms.Button btnSave;
+        private System.Windows.Forms.Button btnWidgetInfo;
     }
 }

Modified: trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -42,11 +42,14 @@
 
         private string _xml;
         private IWidget _widget;
+        private IWidgetInfo _widgetInfo;
 
         public void Setup(IWidget widget, FlexibleLayoutEditorContext context, IEditorService edsvc)
         {
             _widget = widget;
             _xml = _widget.ToXml();
+            _widgetInfo = context.GetWidgetInfo(widget.Type);
+            btnWidgetInfo.Enabled = (_widgetInfo != null);
             txtXmlContent.Text = _xml;
         }
 
@@ -85,9 +88,12 @@
                 if (node != null)
                 {
                     List<XmlElement> elements = new List<XmlElement>();
-                    foreach (XmlNode child in node.ChildNodes)
+                    //foreach (XmlNode child in node.ChildNodes)
+                    for (int i = 0; i < node.ChildNodes.Count; i++)
                     {
-                        elements.Add(node[child.Name]);
+                        var el = doc.CreateElement(node.ChildNodes[i].Name);
+                        el.InnerXml = node.ChildNodes[i].InnerXml;
+                        elements.Add(el);
                     }
                     _widget.Extension.Content = elements.ToArray();
                 }
@@ -131,5 +137,11 @@
                 MessageBox.Show(ex.Message);
             }
         }
+
+        private void btnWidgetInfo_Click(object sender, EventArgs e)
+        {
+            if (_widgetInfo != null)
+                new WidgetInfoDialog(_widgetInfo).ShowDialog();
+        }
     }
 }

Modified: trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.resx	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/GenericWidgetCtrl.resx	2012-08-02 13:48:04 UTC (rev 6932)
@@ -112,16 +112,16 @@
     <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>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.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>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="label1.AutoSize" type="System.Boolean, mscorlib">
     <value>True</value>
   </data>
-  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
   <data name="label1.Location" type="System.Drawing.Point, System.Drawing">
     <value>15, 11</value>
   </data>
@@ -138,15 +138,15 @@
     <value>label1</value>
   </data>
   <data name=">>label1.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name=">>label1.Parent" xml:space="preserve">
     <value>$this</value>
   </data>
   <data name=">>label1.ZOrder" xml:space="preserve">
-    <value>2</value>
+    <value>3</value>
   </data>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="txtXmlContent.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
     <value>Top, Bottom, Left, Right</value>
   </data>
@@ -168,17 +168,20 @@
   <data name="txtXmlContent.TabIndex" type="System.Int32, mscorlib">
     <value>1</value>
   </data>
+  <data name="txtXmlContent.WordWrap" type="System.Boolean, mscorlib">
+    <value>False</value>
+  </data>
   <data name=">>txtXmlContent.Name" xml:space="preserve">
     <value>txtXmlContent</value>
   </data>
   <data name=">>txtXmlContent.Type" xml:space="preserve">
-    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name=">>txtXmlContent.Parent" xml:space="preserve">
     <value>$this</value>
   </data>
   <data name=">>txtXmlContent.ZOrder" xml:space="preserve">
-    <value>1</value>
+    <value>2</value>
   </data>
   <data name="btnSave.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
     <value>Bottom, Left</value>
@@ -202,15 +205,45 @@
     <value>btnSave</value>
   </data>
   <data name=">>btnSave.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name=">>btnSave.Parent" xml:space="preserve">
     <value>$this</value>
   </data>
   <data name=">>btnSave.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="btnWidgetInfo.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Bottom, Left</value>
+  </data>
+  <data name="btnWidgetInfo.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
+    <value>NoControl</value>
+  </data>
+  <data name="btnWidgetInfo.Location" type="System.Drawing.Point, System.Drawing">
+    <value>99, 380</value>
+  </data>
+  <data name="btnWidgetInfo.Size" type="System.Drawing.Size, System.Drawing">
+    <value>75, 23</value>
+  </data>
+  <data name="btnWidgetInfo.TabIndex" type="System.Int32, mscorlib">
+    <value>3</value>
+  </data>
+  <data name="btnWidgetInfo.Text" xml:space="preserve">
+    <value>Widget Info</value>
+  </data>
+  <data name=">>btnWidgetInfo.Name" xml:space="preserve">
+    <value>btnWidgetInfo</value>
+  </data>
+  <data name=">>btnWidgetInfo.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>btnWidgetInfo.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>btnWidgetInfo.ZOrder" xml:space="preserve">
     <value>0</value>
   </data>
-  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>True</value>
   </metadata>
   <data name="$this.Size" type="System.Drawing.Size, System.Drawing">
@@ -220,6 +253,6 @@
     <value>GenericWidgetCtrl</value>
   </data>
   <data name=">>$this.Type" xml:space="preserve">
-    <value>System.Windows.Forms.UserControl, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
 </root>
\ No newline at end of file

Added: trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.Designer.cs	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.Designer.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -0,0 +1,78 @@
+namespace Maestro.Editors.Fusion.WidgetEditors
+{
+    partial class WidgetInfoDialog
+    {
+        /// <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()
+        {
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WidgetInfoDialog));
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.grdExtensionProperties = new System.Windows.Forms.DataGridView();
+            ((System.ComponentModel.ISupportInitialize)(this.grdExtensionProperties)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            resources.ApplyResources(this.label1, "label1");
+            this.label1.Name = "label1";
+            // 
+            // label2
+            // 
+            resources.ApplyResources(this.label2, "label2");
+            this.label2.Name = "label2";
+            // 
+            // grdExtensionProperties
+            // 
+            this.grdExtensionProperties.AllowUserToAddRows = false;
+            this.grdExtensionProperties.AllowUserToDeleteRows = false;
+            resources.ApplyResources(this.grdExtensionProperties, "grdExtensionProperties");
+            this.grdExtensionProperties.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+            this.grdExtensionProperties.Name = "grdExtensionProperties";
+            this.grdExtensionProperties.ReadOnly = true;
+            // 
+            // WidgetInfoDialog
+            // 
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
+            resources.ApplyResources(this, "$this");
+            this.Controls.Add(this.grdExtensionProperties);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.label1);
+            this.Name = "WidgetInfoDialog";
+            this.ShowIcon = false;
+            ((System.ComponentModel.ISupportInitialize)(this.grdExtensionProperties)).EndInit();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.DataGridView grdExtensionProperties;
+    }
+}
\ No newline at end of file

Added: trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.cs	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -0,0 +1,41 @@
+#region Disclaimer / License
+// Copyright (C) 2012, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.ObjectModels.ApplicationDefinition;
+
+namespace Maestro.Editors.Fusion.WidgetEditors
+{
+    public partial class WidgetInfoDialog : Form
+    {
+        public WidgetInfoDialog(IWidgetInfo info)
+        {
+            InitializeComponent();
+            this.Text += " - " + info.Type;
+            grdExtensionProperties.DataSource = info.Parameters;
+        }
+    }
+}

Added: trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.resx	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetEditors/WidgetInfoDialog.resx	2012-08-02 13:48:04 UTC (rev 6932)
@@ -0,0 +1,216 @@
+<?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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="label1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="label1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>13, 13</value>
+  </data>
+  <data name="label1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>637, 45</value>
+  </data>
+  <assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="label1.TabIndex" type="System.Int32, mscorlib">
+    <value>0</value>
+  </data>
+  <data name="label1.Text" xml:space="preserve">
+    <value>This widget defines the following extension properties. When editing a widget in XML form, such properties are specified in the <Extension> element of the given widget</value>
+  </data>
+  <data name=">>label1.Name" xml:space="preserve">
+    <value>label1</value>
+  </data>
+  <data name=">>label1.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>label1.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>label1.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="label2.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label2.Location" type="System.Drawing.Point, System.Drawing">
+    <value>13, 70</value>
+  </data>
+  <data name="label2.Size" type="System.Drawing.Size, System.Drawing">
+    <value>103, 13</value>
+  </data>
+  <data name="label2.TabIndex" type="System.Int32, mscorlib">
+    <value>1</value>
+  </data>
+  <data name="label2.Text" xml:space="preserve">
+    <value>Extension Properties</value>
+  </data>
+  <data name=">>label2.Name" xml:space="preserve">
+    <value>label2</value>
+  </data>
+  <data name=">>label2.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>label2.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>label2.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="grdExtensionProperties.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Bottom, Left, Right</value>
+  </data>
+  <data name="grdExtensionProperties.Location" type="System.Drawing.Point, System.Drawing">
+    <value>16, 86</value>
+  </data>
+  <data name="grdExtensionProperties.Size" type="System.Drawing.Size, System.Drawing">
+    <value>623, 328</value>
+  </data>
+  <data name="grdExtensionProperties.TabIndex" type="System.Int32, mscorlib">
+    <value>2</value>
+  </data>
+  <data name=">>grdExtensionProperties.Name" xml:space="preserve">
+    <value>grdExtensionProperties</value>
+  </data>
+  <data name=">>grdExtensionProperties.Type" xml:space="preserve">
+    <value>System.Windows.Forms.DataGridView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>grdExtensionProperties.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>grdExtensionProperties.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
+    <value>662, 438</value>
+  </data>
+  <data name="$this.Text" xml:space="preserve">
+    <value>Widget Info</value>
+  </data>
+  <data name=">>$this.Name" xml:space="preserve">
+    <value>WidgetInfoDialog</value>
+  </data>
+  <data name=">>$this.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+</root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetReferenceCtrl.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetReferenceCtrl.Designer.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetReferenceCtrl.Designer.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -31,6 +31,7 @@
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WidgetReferenceCtrl));
             this.label1 = new System.Windows.Forms.Label();
             this.cmbWidgetRefs = new System.Windows.Forms.ComboBox();
+            this.label2 = new System.Windows.Forms.Label();
             this.SuspendLayout();
             // 
             // label1
@@ -46,13 +47,19 @@
             this.cmbWidgetRefs.Name = "cmbWidgetRefs";
             this.cmbWidgetRefs.SelectedIndexChanged += new System.EventHandler(this.cmbWidgetRefs_SelectedIndexChanged);
             // 
+            // label2
+            // 
+            resources.ApplyResources(this.label2, "label2");
+            this.label2.Name = "label2";
+            // 
             // WidgetReferenceCtrl
             // 
-            resources.ApplyResources(this, "$this");
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
+            this.Controls.Add(this.label2);
             this.Controls.Add(this.cmbWidgetRefs);
             this.Controls.Add(this.label1);
             this.Name = "WidgetReferenceCtrl";
+            resources.ApplyResources(this, "$this");
             this.ResumeLayout(false);
             this.PerformLayout();
 
@@ -62,5 +69,6 @@
 
         private System.Windows.Forms.Label label1;
         private System.Windows.Forms.ComboBox cmbWidgetRefs;
+        private System.Windows.Forms.Label label2;
     }
 }

Modified: trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetReferenceCtrl.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetReferenceCtrl.resx	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetReferenceCtrl.resx	2012-08-02 13:48:04 UTC (rev 6932)
@@ -112,16 +112,16 @@
     <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>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.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>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="label1.AutoSize" type="System.Boolean, mscorlib">
     <value>True</value>
   </data>
-  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
   <data name="label1.Location" type="System.Drawing.Point, System.Drawing">
     <value>19, 18</value>
   </data>
@@ -138,15 +138,15 @@
     <value>label1</value>
   </data>
   <data name=">>label1.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name=">>label1.Parent" xml:space="preserve">
     <value>$this</value>
   </data>
   <data name=">>label1.ZOrder" xml:space="preserve">
-    <value>1</value>
+    <value>2</value>
   </data>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="cmbWidgetRefs.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
     <value>Top, Left, Right</value>
   </data>
@@ -163,27 +163,51 @@
     <value>cmbWidgetRefs</value>
   </data>
   <data name=">>cmbWidgetRefs.Type" xml:space="preserve">
-    <value>System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name=">>cmbWidgetRefs.Parent" xml:space="preserve">
     <value>$this</value>
   </data>
   <data name=">>cmbWidgetRefs.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="label2.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label2.Location" type="System.Drawing.Point, System.Drawing">
+    <value>19, 52</value>
+  </data>
+  <data name="label2.Size" type="System.Drawing.Size, System.Drawing">
+    <value>516, 13</value>
+  </data>
+  <data name="label2.TabIndex" type="System.Int32, mscorlib">
+    <value>2</value>
+  </data>
+  <data name="label2.Text" xml:space="preserve">
+    <value>NOTE: To customize properties of this widget. Edit the matching widget from the Widget Management dialog</value>
+  </data>
+  <data name=">>label2.Name" xml:space="preserve">
+    <value>label2</value>
+  </data>
+  <data name=">>label2.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name=">>label2.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name=">>label2.ZOrder" xml:space="preserve">
     <value>0</value>
   </data>
-  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>True</value>
   </metadata>
-  <data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
-    <value>6, 13</value>
-  </data>
   <data name="$this.Size" type="System.Drawing.Size, System.Drawing">
-    <value>575, 53</value>
+    <value>575, 90</value>
   </data>
   <data name=">>$this.Name" xml:space="preserve">
     <value>WidgetReferenceCtrl</value>
   </data>
   <data name=">>$this.Type" xml:space="preserve">
-    <value>System.Windows.Forms.UserControl, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
 </root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetSettingsCtrl.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetSettingsCtrl.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/Maestro.Editors/Fusion/WidgetSettingsCtrl.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -130,8 +130,8 @@
             {
                 string[] widgets = _flexLayout.GetAllReferenceableWidgetNames();
                 string widget = GenericItemSelectionDialog.SelectItem(
-                    Properties.Resources.AddWidgetReference, 
-                    Properties.Resources.SelectWidget, 
+                    Properties.Resources.AddWidgetReference,
+                    Properties.Resources.SelectWidget,
                     widgets);
                 if (widget != null)
                 {
@@ -141,6 +141,25 @@
                     this.SelectedNode.Nodes.Add(CreateNode(item));
                 }
             }
+            else
+            {
+                var menu = this.SelectedNode.Tag as IMenu;
+                if (menu != null)
+                {
+                    string[] widgets = _flexLayout.GetAllReferenceableWidgetNames();
+                    string widget = GenericItemSelectionDialog.SelectItem(
+                        Properties.Resources.AddWidgetReference,
+                        Properties.Resources.SelectWidget,
+                        widgets);
+                    if (widget != null)
+                    {
+                        //at end
+                        var item = _flexLayout.CreateWidgetReference(widget);
+                        menu.Insert(item, menu.ItemCount);
+                        this.SelectedNode.Nodes.Add(CreateNode(item));
+                    }
+                }
+            }
         }
 
         private void separatorToolStripMenuItem_Click(object sender, EventArgs e)
@@ -150,9 +169,20 @@
             {
                 //at end
                 var item = _flexLayout.CreateSeparator();
-                cnt.Insert(item, cnt.ItemCount - 1);
+                cnt.Insert(item, cnt.ItemCount);
                 this.SelectedNode.Nodes.Add(CreateNode(item));
             }
+            else
+            {
+                var menu = this.SelectedNode.Tag as IMenu;
+                if (menu != null)
+                {
+                    //at end
+                    var item = _flexLayout.CreateSeparator();
+                    menu.Insert(item, menu.ItemCount);
+                    this.SelectedNode.Nodes.Add(CreateNode(item));
+                }
+            }
         }
 
         private void flyoutMenuToolStripMenuItem_Click(object sender, EventArgs e)
@@ -162,9 +192,20 @@
             {
                 //at end
                 var item = _flexLayout.CreateFlyout(Properties.Resources.NewFlyout);
-                cnt.Insert(item, cnt.ItemCount - 1);
+                cnt.Insert(item, cnt.ItemCount);
                 this.SelectedNode.Nodes.Add(CreateNode(item));
             }
+            else
+            {
+                var menu = this.SelectedNode.Tag as IMenu;
+                if (menu != null)
+                {
+                    //at end
+                    var item = _flexLayout.CreateFlyout(Properties.Resources.NewFlyout);
+                    menu.Insert(item, menu.ItemCount);
+                    this.SelectedNode.Nodes.Add(CreateNode(item));
+                }
+            }
         }
 
         private TreeNode CreateNode(IUIItem item)
@@ -251,6 +292,16 @@
                     parent.Nodes.Remove(node);
                     OnResourceChanged();
                 }
+                else
+                {
+                    var menu = parent.Tag as IMenu;
+                    if (menu != null && item != null)
+                    {
+                        menu.RemoveItem(item);
+                        parent.Nodes.Remove(node);
+                        OnResourceChanged();
+                    }
+                }
             }
         }
 
@@ -275,6 +326,23 @@
                         OnResourceChanged();
                     }
                 }
+                else
+                {
+                    var menu = parent.Tag as IMenu;
+                    if (menu != null && item != null)
+                    {
+                        int index = node.Index;
+                        if (index >= 0)
+                        {
+                            index--;
+                            menu.MoveUp(item);
+                            parent.Nodes.Remove(node);
+                            parent.Nodes.Insert(index, node);
+                            trvWidgets.SelectedNode = node;
+                            OnResourceChanged();
+                        }
+                    }
+                }
             }
         }
 
@@ -299,6 +367,23 @@
                         OnResourceChanged();
                     }
                 }
+                else
+                { 
+                    var menu = parent.Tag as IMenu;
+                    if (menu != null && item != null)
+                    {
+                        int index = node.Index;
+                        if (index < parent.Nodes.Count - 1)
+                        {
+                            index++;
+                            menu.MoveDown(item);
+                            parent.Nodes.Remove(node);
+                            parent.Nodes.Insert(index, node);
+                            trvWidgets.SelectedNode = node;
+                            OnResourceChanged();
+                        }
+                    }
+                }
             }
         }
 
@@ -321,6 +406,15 @@
             if (menu != null)
             {
                 btnAddWidget.Enabled = true;
+                var fly = menu as IFlyoutItem;
+                if (fly != null) //Can only edit menus that are flyouts
+                {
+                    btnRemoveWidget.Enabled = true;
+                    btnMoveDown.Enabled = btnMoveUp.Enabled = true;
+                    var ctrl = new MenuCtrl(fly, _edsvc);
+                    ctrl.Dock = DockStyle.Fill;
+                    propertiesPanel.Controls.Add(ctrl);
+                }
             }
             else
             {

Modified: trunk/Tools/Maestro/Maestro.Editors/Maestro.Editors.csproj
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Maestro.Editors.csproj	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/Maestro.Editors/Maestro.Editors.csproj	2012-08-02 13:48:04 UTC (rev 6932)
@@ -450,6 +450,12 @@
     <Compile Include="Fusion\MapSettingsCtrl.Designer.cs">
       <DependentUpon>MapSettingsCtrl.cs</DependentUpon>
     </Compile>
+    <Compile Include="Fusion\MenuCtrl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Fusion\MenuCtrl.Designer.cs">
+      <DependentUpon>MenuCtrl.cs</DependentUpon>
+    </Compile>
     <Compile Include="Fusion\NewWidgetDialog.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -458,6 +464,12 @@
     </Compile>
     <Compile Include="Fusion\NsDoc.cs" />
     <Compile Include="Fusion\WidgetEditors\NsDoc.cs" />
+    <Compile Include="Fusion\WidgetEditors\WidgetInfoDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Fusion\WidgetEditors\WidgetInfoDialog.Designer.cs">
+      <DependentUpon>WidgetInfoDialog.cs</DependentUpon>
+    </Compile>
     <Compile Include="Fusion\WidgetManagementDialog.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -1447,9 +1459,15 @@
       <DependentUpon>MapSettingsCtrl.cs</DependentUpon>
       <SubType>Designer</SubType>
     </EmbeddedResource>
+    <EmbeddedResource Include="Fusion\MenuCtrl.resx">
+      <DependentUpon>MenuCtrl.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="Fusion\NewWidgetDialog.resx">
       <DependentUpon>NewWidgetDialog.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="Fusion\WidgetEditors\WidgetInfoDialog.resx">
+      <DependentUpon>WidgetInfoDialog.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="Fusion\WidgetManagementDialog.resx">
       <DependentUpon>WidgetManagementDialog.cs</DependentUpon>
     </EmbeddedResource>

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ApplicationDefinitionInterfaces.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ApplicationDefinitionInterfaces.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ApplicationDefinitionInterfaces.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -600,15 +600,29 @@
             Check.NotNull(appDef, "appDef");
             Check.NotEmpty(name, "name");
 
+            return appDef.FindWidget(name) != null;
+        }
+
+        /// <summary>
+        /// Gets the widget of the specified name
+        /// </summary>
+        /// <param name="appDef"></param>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        public static IWidget FindWidget(this IApplicationDefinition appDef, string name)
+        {
+            Check.NotNull(appDef, "appDef");
+            Check.NotEmpty(name, "name");
+
             foreach (var set in appDef.WidgetSets)
             {
                 foreach (var wgt in set.Widgets)
                 {
                     if (wgt.Name == name)
-                        return true;
+                        return wgt;
                 }
             }
-            return false;
+            return null;
         }
 
         /// <summary>

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -716,18 +716,22 @@
 
             //Show Overview
             var showOverview = (IUIWidget)appDef.CreateWidget("showOverview", widgets.FindWidget(KnownWidgetNames.InvokeScript));
+            showOverview.Label = "Show Overview";
             showOverview.SetValue("Script", "showOverviewMap()");
 
             //Show Task Pane
             var showTaskPane = (IUIWidget)appDef.CreateWidget("showTaskPane", widgets.FindWidget(KnownWidgetNames.InvokeScript));
+            showTaskPane.Label = "Show Task Pane";
             showTaskPane.SetValue("Script", "showTaskPane()");
 
             //Show Legend
             var showLegend = (IUIWidget)appDef.CreateWidget("showLegend", widgets.FindWidget(KnownWidgetNames.InvokeScript));
+            showLegend.Label = "Show Legend";
             showLegend.SetValue("Script", "showLegend()");
 
             //Show Selection Panel
             var showSelectionPanel = (IUIWidget)appDef.CreateWidget("showSelectionPanel", widgets.FindWidget(KnownWidgetNames.InvokeScript));
+            showSelectionPanel.Label = "Show Selection Panel";
             showSelectionPanel.SetValue("Script", "showSelectionPanel()");
 
             //Coordinate Tracker

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -88,6 +88,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to A non-existent widget by the id of {0} is being referenced from a menu/container : {1}.
+        /// </summary>
+        internal static string ADF_InvalidWidgetReferenceInContainer {
+            get {
+                return ResourceManager.GetString("ADF_InvalidWidgetReferenceInContainer", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Map with ID {0} does not point to a valid map.
         /// </summary>
         internal static string ADF_MapInvalidError {
@@ -124,6 +133,24 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to A non-UI widget by the id of {0} is residing in the menu/container ({1}). Being a non-UI widget, this may cause rendering problems for that particular container.
+        /// </summary>
+        internal static string ADF_NonUiWidgetAttachedToContainer {
+            get {
+                return ResourceManager.GetString("ADF_NonUiWidgetAttachedToContainer", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A widget by the id of {0} has no label. This may cause display problems in the menu/container ({1}) if there is no icon specified.
+        /// </summary>
+        internal static string ADF_ReferencedWidgetInMenuHasNoLabel {
+            get {
+                return ResourceManager.GetString("ADF_ReferencedWidgetInMenuHasNoLabel", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Fusion application specifies a start view that is outside the map's initial extents.
         /// </summary>
         internal static string ADF_ViewOutsideMapExtents {

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx	2012-08-02 13:48:04 UTC (rev 6932)
@@ -2775,4 +2775,13 @@
   <data name="FS_SecuredCredentialTokensWithoutSecuredCredentialData" xml:space="preserve">
     <value>Feature source content has the %MG_USERNAME% and %MG_PASSWORD% tokens, but does not have the MG_USER_CREDENTIALS resource data item</value>
   </data>
+  <data name="ADF_InvalidWidgetReferenceInContainer" xml:space="preserve">
+    <value>A non-existent widget by the id of {0} is being referenced from a menu/container : {1}</value>
+  </data>
+  <data name="ADF_NonUiWidgetAttachedToContainer" xml:space="preserve">
+    <value>A non-UI widget by the id of {0} is residing in the menu/container ({1}). Being a non-UI widget, this may cause rendering problems for that particular container</value>
+  </data>
+  <data name="ADF_ReferencedWidgetInMenuHasNoLabel" xml:space="preserve">
+    <value>A widget by the id of {0} has no label. This may cause display problems in the menu/container ({1}) if there is no icon specified</value>
+  </data>
 </root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ApplicationDefinitionValidator.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ApplicationDefinitionValidator.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ApplicationDefinitionValidator.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -124,11 +124,68 @@
                 }
             }
 
+            //Check labels of referenced widgets
+            foreach (var wset in fusionApp.WidgetSets)
+            {
+                foreach (var cnt in wset.Containers)
+                {
+                    var menu = cnt as IMenu;
+                    if (menu != null)
+                    {
+                        ValidateWidgetReferencesForMenu(fusionApp, menu, issues, context, resource);
+                    }
+                }
+            }
+
             context.MarkValidated(resource.ResourceID);
 
             return issues.ToArray();
         }
 
+        private void ValidateWidgetReferencesForMenu(IApplicationDefinition fusionApp, IMenu menu, List<ValidationIssue> issues, ResourceValidationContext context, IResource resource)
+        {
+            foreach (var item in menu.Items)
+            {
+                var subMenu = item as IMenu;
+                var widgetRef = item as IWidgetItem;
+                if (subMenu != null)
+                {
+                    ValidateWidgetReferencesForMenu(fusionApp, subMenu, issues, context, resource);
+                }
+                else if (widgetRef != null)
+                {
+                    var id = widgetRef.Widget;
+                    var wgt = fusionApp.FindWidget(id);
+                    var uiWgt = wgt as IUIWidget;
+                    string parentName = "<unknown>";
+                    var cnt = menu as IWidgetContainer;
+                    var fly = menu as IFlyoutItem;
+                    if (cnt != null)
+                        parentName = cnt.Name;
+                    else if (fly != null)
+                        parentName = fly.Label;
+                    if (wgt == null)
+                    {
+                        issues.Add(new ValidationIssue(resource, ValidationStatus.Error, ValidationStatusCode.Error_Fusion_InvalidWidgetReference, string.Format(Properties.Resources.ADF_InvalidWidgetReferenceInContainer, id, parentName)));
+                    }
+                    else
+                    {
+                        if (uiWgt == null)
+                        {
+                            issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_NonStandardUiWidgetAttachedToContainer, string.Format(Properties.Resources.ADF_NonUiWidgetAttachedToContainer, id, parentName)));
+                        }
+                        else
+                        {
+                            if (string.IsNullOrEmpty(uiWgt.Label) && string.IsNullOrEmpty(uiWgt.ImageUrl))
+                            {
+                                issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, ValidationStatusCode.Warning_Fusion_NoLabelOnWidget, string.Format(Properties.Resources.ADF_ReferencedWidgetInMenuHasNoLabel, id, parentName)));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
         private static bool IsCommercialOverlay(IMap map)
         {
             string type = map.Type.ToLower();

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorSet.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorSet.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorSet.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -93,6 +93,8 @@
                     catch (Exception ex)
                     {
                         string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                        if (ex is NullReferenceException)
+                            msg = ex.ToString();
                         issueSet.AddIssue(new ValidationIssue(item, ValidationStatus.Error, ValidationStatusCode.Error_General_ValidationError, "Failed in validator: " + msg));
                     }
                 }

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationStatusCode.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationStatusCode.cs	2012-07-31 16:32:38 UTC (rev 6931)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationStatusCode.cs	2012-08-02 13:48:04 UTC (rev 6932)
@@ -197,6 +197,16 @@
         Warning_Fusion_MapCoordSysIncompatibleWithCommericalLayers,
 
         /// <summary>
+        /// The referenced widget has no label, which may cause display problems if there is no icon specified
+        /// </summary>
+        Warning_Fusion_NoLabelOnWidget,
+
+        /// <summary>
+        /// A toolbar or container contains a reference to a non-UI widget
+        /// </summary>
+        Warning_Fusion_NonStandardUiWidgetAttachedToContainer,
+
+        /// <summary>
         /// Unrecognised layer type
         /// </summary>
         Warning_LayerDefinition_UnsupportedLayerType = 3501,
@@ -313,6 +323,11 @@
         Error_Fusion_MapValidationError,
 
         /// <summary>
+        /// A toolbar or container contains a reference to a non-existent widget
+        /// </summary>
+        Error_Fusion_InvalidWidgetReference,
+
+        /// <summary>
         /// Unclassifed validation error
         /// </summary>
         Error_LayerDefinition_Generic = 5401,



More information about the mapguide-commits mailing list