commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r8397 - in trunk: gnue-designer/src/base gnue-designer/src/base/t


From: jcater
Subject: [gnue] r8397 - in trunk: gnue-designer/src/base gnue-designer/src/base/tools gnue-designer/src/forms gnue-designer/src/forms/PagePainter/skins gnue-designer/src/ui/wx/uihelpers/doccanvas gnue-forms/samples/intro gnue-forms/src
Date: Mon, 10 Apr 2006 12:14:45 -0500 (CDT)

Author: jcater
Date: 2006-04-10 12:14:44 -0500 (Mon, 10 Apr 2006)
New Revision: 8397

Modified:
   trunk/gnue-designer/src/base/Document.py
   trunk/gnue-designer/src/base/Incubator.py
   trunk/gnue-designer/src/base/tools/PropertyEditor.py
   trunk/gnue-designer/src/forms/PagePainter/skins/common.py
   trunk/gnue-designer/src/forms/PropertyEditor.py
   trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py
   trunk/gnue-forms/samples/intro/intro.gfd
   trunk/gnue-forms/src/GFParser.py
Log:
more work on the new property editor, allowing multiple objects to be selected

Modified: trunk/gnue-designer/src/base/Document.py
===================================================================
--- trunk/gnue-designer/src/base/Document.py    2006-04-09 17:18:40 UTC (rev 
8396)
+++ trunk/gnue-designer/src/base/Document.py    2006-04-10 17:14:44 UTC (rev 
8397)
@@ -334,7 +334,7 @@
     # Private functions
     # ================================================================
 
-    def __init__(self, app, properties, location=None, 
+    def __init__(self, app, properties, location=None,
                  buffer=None, style=None):
         EventController.__init__(self)
 
@@ -347,7 +347,7 @@
         self.startCachingEvents()
 
         self.ui = app.ui.createInstance(self)
-        
+
         # Local variables
         self.wizardName = ""
         self._isdirty = False

Modified: trunk/gnue-designer/src/base/Incubator.py
===================================================================
--- trunk/gnue-designer/src/base/Incubator.py   2006-04-09 17:18:40 UTC (rev 
8396)
+++ trunk/gnue-designer/src/base/Incubator.py   2006-04-10 17:14:44 UTC (rev 
8397)
@@ -100,7 +100,7 @@
     # ----------------------------------------------------------------------
     # Delete an object
     # ----------------------------------------------------------------------
-    def deleteObject(self, rootObject, object, 
+    def deleteObject(self, rootObject, object,
                      newCurrentObject=None, firstRun=1):
 
         if firstRun:
@@ -126,14 +126,12 @@
     # Internal stuff
     # ----------------------------------------------------------------------
 
-    def __init__(self, instance):
-        self.document = instance
+    def __init__(self, document):
+        self.document = document
 
-        # Figure out tag dependencies
-        self._calcDependencies()
 
+        # Calculate dependencies between tags
 
-    def _calcDependencies(self):
         self.elementMapping = elementMapping = {}
         elements = self.elements
 
@@ -150,6 +148,35 @@
             else:
                 parents = None
 
+            # Make sure attributes have all tags that designer requires
+            if t.has_key('Attributes'):
+                for attribute_name, attribute in t['Attributes'].items():
+                    if not attribute.has_key('Label'):
+                        # This little tidbit does mixed case
+                        # with '_' converted to spaces
+                        words = attribute_name.split(':',1)[-1].split('_')
+                        for index, text in enumerate(words):
+                            words[index] = text.capitalize()
+                        label = " ".join(words)
+
+                        # Cache it so we don't have to do this each time
+                        attribute['Label'] = label
+                    if not attribute.has_key('Required'):
+                        attribute['Required'] = False
+                    if not attribute.has_key('Unique'):
+                        attribute['Unique'] = False
+                    if not attribute.has_key('Deprecated'):
+                        attribute['Deprecated'] = False
+                    if not attribute.has_key('References'):
+                        attribute['References'] = None
+                    if not attribute.has_key('ValidSet'):
+                        attribute['ValidSet'] = {}
+                    if not attribute.has_key('Description'):
+                        attribute['Description'] = attribute['Label']
+            else:
+                t['Attributes'] = {}
+
+
             if parents != None:
                 for parent in parents:
                     try:

Modified: trunk/gnue-designer/src/base/tools/PropertyEditor.py
===================================================================
--- trunk/gnue-designer/src/base/tools/PropertyEditor.py        2006-04-09 
17:18:40 UTC (rev 8396)
+++ trunk/gnue-designer/src/base/tools/PropertyEditor.py        2006-04-10 
17:14:44 UTC (rev 8397)
@@ -20,7 +20,9 @@
 # - Suite 330, Boston, MA 02111-1307, USA.
 #
 # $Id$
+
 """
+A property editor tool
 """
 
 __all__ = ['PropertyEditor']
@@ -38,6 +40,12 @@
 
 
 class PropertyEditor(ToolBase):
+    """
+    Edit the property of the currently selected object.
+
+    If multiple objects are selected, it shows the intersection
+    of common attributes.
+    """
     runtime_section = 'PropertyEditor'
     default_dock = 'left-1'
 
@@ -50,185 +58,202 @@
 #                           'ObjectModified'      : self.object_modified_event,
 #                           'ObjectDeleted'       : self.object_deleted_event,
                           })
-                          
+
         self.listctrl = listctrl = PropertyEditorListCtrl(self)
         sizer = wx.BoxSizer(wx.VERTICAL)
         sizer.Add(listctrl, 1, wx.EXPAND|wx.ALL, 0)
         self.SetAutoLayout(True)
         self.SetSizer(sizer)
 
+        listctrl.SetFont(wx.SMALL_FONT)
 
+
     def object_selected_event (self, event):
         """
-        Called on the ObjectSelected event. 
-        
-        Display all properties of a widget, or the common 
-        properties of all selected widgets, if multiple 
+        Called on the ObjectSelected event.
+
+        Display all properties of a widget, or the common
+        properties of all selected widgets, if multiple
         widgets are selected.
         """
 
         # Get selected objects, or the current object
-        try: 
+        try:
             objects = event.selection
-        except: 
-            objects = [event.object]
+        except:
+            if event.object:
+                objects = [event.object]
+            else:
+                objects = []
 
-        self.objects = objects
+        self.__current_objects = objects
 
         # Remove any previous entries
         self.listctrl.ClearAll()
         self.listctrl.InsertColumn(0,'Property')
         self.listctrl.InsertColumn(1,'Value')
-        
 
-        for gobject in objects: 
+        if not objects:
+            return
 
-            definition_map = gobject.gparser_definition['Attributes']
-            
-            # Define our rows
-            self.row_list = row_list = []
-            add_row_list = row_list.append
-            for attribute_name, attributes in definition_map.items():
+        # Merge the attribute lists from the selected properties.
+        common_attributes = {}
+        common_values = {}
+        unique_attributes = {}
+        dropped_attributes = {}
+        first_object = True
 
+        for gobject in objects:
+
+            attributes = gobject.gparser_definition['Attributes']
+
+            for attribute_name, attribute in attributes.items():
+
                 try:
-                    label = attributes['Label']
-                except KeyError:
-                    # This little tidbit does mixed case w/'_' as separators
-                    words = attribute_name.split(':',1)[-1].split('_')
-                   index=0
-                    for text in words:
-                        words[index] = text.capitalize()
-                       index+=1
-                    label = " ".join(words)
-                    
-                    # Cache it so we don't have to do this each time
-                    attributes['Label'] = label
-                    
-                add_row_list((label, attribute_name))
+                    value = gobject[attribute_name]
+                except:
+                    value = attributes.get('Default',None)
 
-                index = self.listctrl.InsertStringItem(sys.maxint, label)
-                self.listctrl.SetStringItem(index, 0, label)
-                self.listctrl.SetStringItem(index, 1, "value")
-                #self.listctrl.SetItemData(index, attribute_name)
-            
-                print label
-                
-            row_list.sort()
-            
-            return 
-            
-                
-            # Only show properties for nondeprecated values (unless set)
-            i = 0
-            for index in row_list:
-                label, key = self.rowList[i]
-                xkey = key.replace(':','__')
-                if self.attributes[key].has_key ('Deprecated') and \
-                   self.attributes[key]['Deprecated'] and \
-                   (not hasattr(gobject, xkey) or \
-                      (self.attributes[key].has_key('Default') and \
-                       gobject.__dict__[xkey] == 
self.attributes[key]['Default'] ) ):
-                    self.rowList.pop(i)
+                # If we've already decided this attribute isn't
+                # common, don't do the tests again
+                if dropped_attributes.has_key(attribute_name):
+                    continue
+
+                # This may be a tad drastic; drop any deprecated attributes
+                if attribute['Deprecated']:
+                    continue
+
+                if first_object:
+                    # First loop thru, nothing to compare
+                    common_attributes[attribute_name] = attribute
+                    common_values[attribute_name] = value
+                elif first_object or \
+                     not common_attributes.has_key(attribute_name):
+                    # First time seeing attribute, so nothing to compare
+                    common_attributes[attribute_name] = attribute
+                    common_values[attribute_name] = value
                 else:
-                    i = i + 1
+                    # Do a diff of current and previous attribute instance
+                    common = common_attributes[attribute_name]
+                    if attribute['Typecast'] == common['Typecast'] and \
+                    attribute['Label'] == common['Label'] and \
+                    attribute['References'] == common['References'] and \
+                    attribute['ValidSet'].keys() == common['ValidSet'].keys():
 
-        return 
-        y = 2
-        maxLabel = 0
-        for text, key in self.rowList:
+                        # Attributes match.  Do the values?
+                        if common_values.has_key(attribute_name) and \
+                            value != common_values:
+                            value = MixedValues
 
-            xkey = key.replace(':','__')
+                        common_values[attribute_name] == value
+                    else:
+                        # Attributes don't match, so add to our black list
+                        dropped_attributes[attribute_name] = True
+                        del common_attributes[attribute_name]
 
-            # If an attribute has a "Label", use it;
-            # otherwise create one from its name.
+                # Keep track of attributes that are unique
+                if attribute['Unique']:
+                    unique_attributes[attribute_name] = True
 
-            if self.attributes[key]['Typecast'] == GTypecast.boolean:
-                text = u_('%s?') % text
-            else:
-                text = u_('%s:') % text
+            first_object = False
+        # Remove all "Unique" attributes if there's more than one object
+        if len(objects) > 1:
+            for attribute_name in unique_attributes.keys():
+                del common_attributes[attribute_name]
 
-            try:
-                label = wx.StaticText (self.labelPanel, -1, text)
-                label.SetFont(wx.SMALL_FONT)
+        # Sort by label
+        sorted_attributes = [(attribute['Label'], (attribute_name, attribute))
+                    for attribute_name, attribute in common_attributes.items()]
+        sorted_attributes.sort()
+        sorted_attributes = [ attribute_pair \
+                       for label, attribute_pair in sorted_attributes]
 
-            except:
-                pass
+        # Save the sorted attribute list for future use
+        self.attribute_list = sorted_attributes
 
-            # Determine the type of Cell Editor we want
-            # (Integer, Boolean, Dropdown, Char)
-            if self.attributes[key].has_key('ValueSet'):
-                field = LimitedSetEditor(self.fieldPanel,self.attributes[key])
-                wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
-            elif self.attributes[key].has_key('References'):
-                tag, attr = self.attributes[key]['References'].split('.')
-                objectList = self.editor.document.getObjectList(tag)
-                field = LinkedTextEditor(self.fieldPanel,
-                                         self.attributes[key],
-                                         objectList,
-                                         attr)
-                wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
-            elif self.attributes[key]['Typecast'] == GTypecast.boolean:
-                field = BoolEditor(self.fieldPanel,self.attributes[key])
-                wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
-            elif self.attributes[key]['Typecast'] in (GTypecast.integer,
-                    GTypecast.number, GTypecast.whole):
-                field = IntEditor(self.fieldPanel,self.attributes[key])
-                wx.EVT_SPINCTRL(field, field.GetId(), self.__valueModified)
-            else:
-                field = TextEditor(self.fieldPanel,self.attributes[key])
-            wx.EVT_TEXT(field, field.GetId(), self.__valueModified)
+        # We have all the data we need, so add them to our edit list
+        for attribute_name, attribute in sorted_attributes:
 
-            field.SetFont(wx.SMALL_FONT)
+            # Define our rows
+            index = self.listctrl.InsertStringItem(sys.maxint,
+                                                   attribute['Label'])
+            self.listctrl.SetStringItem(index, 0, attribute['Label'])
+            self.listctrl.SetStringItem(index, 1,
+                                        str(common_values[attribute_name]))
+            #self.listctrl.SetItemData(index, attribute_name)
 
-            # Generate a tooltip from the description.
-            # Note that tooltips can have {Name} tokens
-            try:
-                tooltip = self.attributes[key]['Description']
-                try:
-                    for v, l in self.attributes[key]['ValueSet'].items():
-                        tooltip = tooltip.replace('{%s}' % v,
-                                                  '"%s"' % l['Label'])
-                except KeyError:
-                    pass
-                tooltip = tooltip.replace('{Y}','"True"')
-                tooltip = tooltip.replace('{N}','"False"')
-                tooltip = tooltip.replace('{','"')
-                tooltip = tooltip.replace('}','"')
-                field.SetToolTip(wx.ToolTip(tooltip))
-            except KeyError:
-                pass
 
-            # Align the centers of the field and label
-            fx, fy = field.GetSizeTuple()
-            lx, ly = label.GetSizeTuple()
-            maxy = max(fy, ly)
-            maxLabel = max(maxLabel, lx+4)
-            field.SetPosition((2, int((maxy - fy)/2) + y))
-            label.SetPosition((4, int((maxy - ly)/2) + y))
 
-            # Next y...
-            y += maxy
+            ## Determine the type of Cell Editor we want
+            ## (Integer, Boolean, Dropdown, Char)
+            #if self.attributes[key].has_key('ValueSet'):
+                #field = LimitedSetEditor(self.fieldPanel,self.attributes[key])
+                #wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
+            #elif self.attributes[key].has_key('References'):
+                #tag, attr = self.attributes[key]['References'].split('.')
+                #objectList = self.editor.document.getObjectList(tag)
+                #field = LinkedTextEditor(self.fieldPanel,
+                                         #self.attributes[key],
+                                         #objectList,
+                                         #attr)
+                #wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
+            #elif self.attributes[key]['Typecast'] == GTypecast.boolean:
+                #field = BoolEditor(self.fieldPanel,self.attributes[key])
+                #wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
+            #elif self.attributes[key]['Typecast'] in (GTypecast.integer,
+                    #GTypecast.number, GTypecast.whole):
+                #field = IntEditor(self.fieldPanel,self.attributes[key])
+                #wx.EVT_SPINCTRL(field, field.GetId(), self.__valueModified)
+            #else:
+                #field = TextEditor(self.fieldPanel,self.attributes[key])
+            #wx.EVT_TEXT(field, field.GetId(), self.__valueModified)
 
-            # Set the initial value of the cells to the current property values
-            if hasattr(object, xkey):
-                field.SetValue(object.__dict__[xkey])
+            #field.SetFont(wx.SMALL_FONT)
 
-            self.fields.append(field)
-            self.labels.append(label)
-        
+            ## Generate a tooltip from the description.
+            ## Note that tooltips can have {Name} tokens
+            #try:
+                #tooltip = self.attributes[key]['Description']
+                #try:
+                    #for v, l in self.attributes[key]['ValueSet'].items():
+                        #tooltip = tooltip.replace('{%s}' % v,
+                                                  #'"%s"' % l['Label'])
+                #except KeyError:
+                    #pass
+                #tooltip = tooltip.replace('{Y}','"True"')
+                #tooltip = tooltip.replace('{N}','"False"')
+                #tooltip = tooltip.replace('{','"')
+                #tooltip = tooltip.replace('}','"')
+                #field.SetToolTip(wx.ToolTip(tooltip))
+            #except KeyError:
+                #pass
 
+        self.listctrl.SetColumnWidth(0, wx.LIST_AUTOSIZE)
 
-class PropertyEditorListCtrl(wx.ListCtrl, #mixins.TextEditMixin, 
-                             mixins.ListCtrlAutoWidthMixin): 
-    def __init__(self, tool): 
-        wx.ListCtrl.__init__(self, tool,  -1, 
+class MixedValues:
+    """
+    Used internally
+    """
+    def __str__(self):
+        return u_("(Multiple)")
+
+class PropertyEditorListCtrl(wx.ListCtrl, mixins.TextEditMixin,
+                             mixins.ListCtrlAutoWidthMixin):
+    def __init__(self, tool):
+        wx.ListCtrl.__init__(self, tool,  -1,
             style=wx.LC_REPORT|wx.LC_HRULES|wx.LC_VRULES)
-        #mixins.TextEditMixin.__init__(self)
-        #mixins.ListCtrlAutoWidthMixin.__init__(self)
-        self.InsertColumn(0,'Property')
-        self.InsertColumn(1,'Value')
-        self.SetColumnWidth(0, wx.LIST_AUTOSIZE)
-        
+        mixins.TextEditMixin.__init__(self)
+        mixins.ListCtrlAutoWidthMixin.__init__(self)
+
+    def OpenEditor(self, col, row):
+        """
+        Override OpenEditor to make our label column non-editable
+        """
+        if col == 0:
+            return
+
+        return mixins.TextEditMixin.OpenEditor(self, col, row)
+
 #    def SetStringItem(self, index, col, data):
 #        if col < 2:
 #            wx.ListCtrl.SetStringItem(self, index, col, data)
@@ -243,468 +268,3 @@
 
 #            data = self.GetItem(index, col-2).GetText()
 #            wx.ListCtrl.SetStringItem(self, index, col-2, data[0:datalen])
-        
-class PropertyEditorXXX: # (ToolNotebook):
-
-    runtime_section = 'PropertyEditor'
-    default_dock = 'left-1'
-
-    def init(self):
-
-        self.object = None
-
-        # EventAware provided by ToolBase
-        self.registerEventListeners({
-                           'ObjectSelected'      : self.object_selected_event,
-                           'ObjectCreated'       : self.object_created_event,
-                           'ObjectModified'      : self.object_modified_event,
-                           'ObjectDeleted'       : self.object_deleted_event,
-                          })
-
-        self.supplemental = []
-        self.main = self.createMainPage()
-        self.notebook.AddPage(self.main,'Properties')
-        self.notebook.SetFont(wx.SMALL_FONT)
-
-
-    def createMainPage(self):
-        return InspectorPanel(self, self.notebook)
-
-    def object_selected_event (self, event):
-        return
-        object = event.object
-        handler = event.originator
-        if object == None:
-            return
-        if object != self.object:
-            self.setCurrent(object)
-
-    def setCurrent(self, object):
-        self.object = object
-        self.reset()
-        self.main.setCurrent(object)
-        self.notebook.SetPageText(0, self.main.getPageText())
-        i = 1
-        for page in self.supplemental:
-            page.setCurrent(object)
-            self.notebook.SetPageText(i, page.getPageText())
-            i += 1
-
-    def addPage(self, inspector, label):
-        self.supplemental.append(inspector)
-        self.notebook.AddPage(inspector, label)
-
-    def reset(self):
-        for i in range(len(self.supplemental)):
-            self.notebook.DeletePage(1)
-        self.supplemental = []
-
-    def object_created_event (self, event):
-        object = event.object
-        handler = event.originator
-
-    def object_modified_event (self, event):
-        object = event.object
-        if object == None:
-            return
-
-        if event.originator != __name__:
-            for page in [self.main] + self.supplemental:
-                page.resetValues(object)
-
-    def object_deleted_event (self, event):
-        object = event.object
-        handler = event.originator
-        if object == None:
-            return
-        if handler != __name__:
-            pass
-
-
-#
-#
-#
-class InspectorPanel(wx.ScrolledWindow):
-
-    NAMESPACE = ""
-
-    def __init__(self, editor, parent):
-        wx.ScrolledWindow.__init__(self, parent, -1, style = wx.HSCROLL)
-        self.splitter = splitter = wx.SplitterWindow(self, -1, 
style=wx.SP_3DSASH | wx.SP_NOBORDER)
-        self.object = None
-        self.editor = editor
-        self.fields = []
-        self.labels = []
-
-        # These will be set in _setCurrent
-        self.maxy = 0
-        self.maxLabel = 0
-
-        self.labelPanel = wx.Panel(splitter, -1)
-        self.fieldPanel = wx.Panel(splitter, -1)
-        splitter.SplitVertically(self.labelPanel, self.fieldPanel)
-        wx.EVT_SPLITTER_SASH_POS_CHANGED(self, 
self.splitter.GetId(),self.__onSize)
-        wx.EVT_SIZE(self, self.__onSize)
-
-
-    def getAttributes(self, object):
-        elements = self.editor.document.incubator.elements
-        try:
-            return elements[(object._type[2:]).lower()]['Attributes']
-        except KeyError:
-            return {}
-
-
-    def _setCurrent(self, object):
-        self.object = object
-        self.attributes = self.getAttributes(object)
-
-        # Define our rows
-        self.rowList = []
-        for key, attributes in self.attributes.items():
-            try:
-                label = attributes['Label']
-            except KeyError:
-                # This little tidbit does mixed case w/'_' as separators
-                words = key.split(':',1)[-1].split('_')
-                for j in xrange(len(words)):
-                    words[j] = words[j].capitalize()
-                label = " ".join(words)
-            self.rowList.append((label, key))
-        self.rowList.sort()
-
-        # Get rid of any old fields
-        for i in range(len(self.fields)):
-            field = self.fields.pop()
-            field.Destroy()
-            label = self.labels.pop()
-            label.Destroy()
-
-        # Only show properties for nondeprecated values (unless set)
-        i = 0
-        while i < len(self.rowList):
-            label, key = self.rowList[i]
-            xkey = key.replace(':','__')
-            if self.attributes[key].has_key ('Deprecated') and \
-               self.attributes[key]['Deprecated'] and \
-               (not hasattr(object, xkey) or \
-                  (self.attributes[key].has_key('Default') and \
-                   object.__dict__[xkey] == self.attributes[key]['Default'] ) 
):
-                self.rowList.pop(i)
-            else:
-                i = i + 1
-
-        y = 2
-        maxLabel = 0
-        for text, key in self.rowList:
-
-            xkey = key.replace(':','__')
-
-            # If an attribute has a "Label", use it;
-            # otherwise create one from its name.
-
-            if self.attributes[key]['Typecast'] == GTypecast.boolean:
-                text = u_('%s?') % text
-            else:
-                text = u_('%s:') % text
-
-            try:
-                label = wx.StaticText (self.labelPanel, -1, text)
-                label.SetFont(wx.SMALL_FONT)
-
-            except:
-                pass
-
-            # Determine the type of Cell Editor we want
-            # (Integer, Boolean, Dropdown, Char)
-            if self.attributes[key].has_key('ValueSet'):
-                field = LimitedSetEditor(self.fieldPanel,self.attributes[key])
-                wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
-            elif self.attributes[key].has_key('References'):
-                tag, attr = self.attributes[key]['References'].split('.')
-                objectList = self.editor.document.getObjectList(tag)
-                field = LinkedTextEditor(self.fieldPanel,
-                                         self.attributes[key],
-                                         objectList,
-                                         attr)
-                wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
-            elif self.attributes[key]['Typecast'] == GTypecast.boolean:
-                field = BoolEditor(self.fieldPanel,self.attributes[key])
-                wx.EVT_COMBOBOX(field, field.GetId(), self.__valueModified)
-            elif self.attributes[key]['Typecast'] in (GTypecast.integer,
-                    GTypecast.number, GTypecast.whole):
-                field = IntEditor(self.fieldPanel,self.attributes[key])
-                wx.EVT_SPINCTRL(field, field.GetId(), self.__valueModified)
-            else:
-                field = TextEditor(self.fieldPanel,self.attributes[key])
-            wx.EVT_TEXT(field, field.GetId(), self.__valueModified)
-
-            field.SetFont(wx.SMALL_FONT)
-
-            # Generate a tooltip from the description.
-            # Note that tooltips can have {Name} tokens
-            try:
-                tooltip = self.attributes[key]['Description']
-                try:
-                    for v, l in self.attributes[key]['ValueSet'].items():
-                        tooltip = tooltip.replace('{%s}' % v,
-                                                  '"%s"' % l['Label'])
-                except KeyError:
-                    pass
-                tooltip = tooltip.replace('{Y}','"True"')
-                tooltip = tooltip.replace('{N}','"False"')
-                tooltip = tooltip.replace('{','"')
-                tooltip = tooltip.replace('}','"')
-                field.SetToolTip(wx.ToolTip(tooltip))
-            except KeyError:
-                pass
-
-            # Align the centers of the field and label
-            fx, fy = field.GetSizeTuple()
-            lx, ly = label.GetSizeTuple()
-            maxy = max(fy, ly)
-            maxLabel = max(maxLabel, lx+4)
-            field.SetPosition((2, int((maxy - fy)/2) + y))
-            label.SetPosition((4, int((maxy - ly)/2) + y))
-
-            # Next y...
-            y += maxy
-
-            # Set the initial value of the cells to the current property values
-            if hasattr(object, xkey):
-                field.SetValue(object.__dict__[xkey])
-
-            self.fields.append(field)
-            self.labels.append(label)
-
-        self.splitter.SetSashPosition(maxLabel+2)
-        self.maxy = y
-        self.maxLabel = maxLabel
-        self.__onSize(None)
-
-    # Reset the values displayed based on the values on the object
-    def resetValues(self, object):
-        if object != self.object:
-            return
-        for i in range(len(self.fields)):
-            xkey = self.rowList[i][1].replace(':','__')
-            field = self.fields[i]
-            # Set the initial value of the cells to the current property values
-            if hasattr(object, xkey):
-                field.SetValue(object.__dict__[xkey])
-            else:
-                try:
-                    field.Clear()
-                except AttributeError:
-                    print 'TODO: IntEditor has no Clear()'
-
-    def getPageText(self):
-        return self.object._type[2:]
-
-    def __onSize(self, event):
-        x, y = self.GetClientSizeTuple()
-        my = max(y, self.maxy)
-        self.splitter.SetSize((x, my ))
-        self.splitter.SetSashPosition(self.maxLabel+2)
-        self.SetVirtualSize((x, my))
-        if my > y:
-            self.SetScrollRate(0,10)
-        #fw = self.fieldPanel.GetSize().x - 4
-        #for field in self.fields:
-        #  field.SetSize((fw, field.GetSize().y))
-
-    # Notify system that the object has been modified
-    def __valueModified(self, event):
-        field = event.GetEventObject()
-        try:
-            attr = self.rowList[self.fields.index(field)][1]
-        except ValueError:
-            return
-
-        value = field.GetValue()
-
-        xkey = attr.replace(':','__')
-        try:
-            try:
-                ov = self.object[attr]
-            except KeyError:
-                ov = None
-
-            oldVal = {attr: ov}
-
-            # We only care if user actually changed the current value...
-            if ov != value and not (ov == None and value in (0,'')):
-                # If value is None, then user basically selected "No value"
-                if value != None:
-                    # Typecast the value, then store in the object's dictionary
-                    value = self.attributes[attr]['Typecast'](value)
-                else:
-                    # No value... try to set value as "default" value
-                    try:
-                        value = self.attributes[attr]['Default']
-                    except KeyError:
-                        # Otherwise leave as None
-                        pass
-
-                self.object.__dict__[xkey] = value
-                newVal = {attr: value}
-
-                self.editor.dispatchEvent('ObjectModified',
-                                 object=self.object,
-                                 originator=__name__,
-                                 old=oldVal,
-                                 new=newVal)
-
-        except ValueError:
-            wx.Bell()
-
-        event.Skip()
-
-
-#
-# Property Editor derived from an attribute's ValueSet
-#
-class LimitedSetEditor(wx.ComboBox):
-    def __init__(self, parent, attributes):
-        wx.ComboBox.__init__(self, parent, -1,
-           style=wx.TE_PROCESS_ENTER|wx.CB_DROPDOWN|wx.CB_READONLY)
-        self.attributes = attributes
-        self.selectionList  = []
-
-        try:
-            default = self.attributes['Default']
-        except KeyError:
-            default = None
-
-
-        if not (attributes.has_key('Required') and attributes['Required'] ):
-            self.selectionList.append(None)
-            self.Append('')
-
-        # Sort the attribute names...
-        keys = attributes['ValueSet'].keys()
-        keys.sort()
-
-        # .. but make the default always come first
-        if default:
-            keys.remove(default)
-            keys.insert(0, default)
-
-        # Add attributes to the combo box
-        for v in keys:
-            self.selectionList.append(v)
-            try:
-                text = attributes['ValueSet'][v]['Label']
-            except KeyError:
-                text = v
-            self.Append("%s%s" % (text, v == default and '*' or '' ))
-
-    def GetValue(self):
-        return self.selectionList[self.GetSelection()]
-
-    def SetValue(self, value):
-        self.SetSelection(self.selectionList.index(value))
-
-
-#
-# Property Editor whose selections are linked to lists of other objects
-#
-class LinkedTextEditor(wx.ComboBox):
-    def __init__(self, parent, attributes, objectList, attr):
-        wx.ComboBox.__init__(self, parent, -1,
-           style=wx.TE_PROCESS_ENTER|wx.CB_DROPDOWN|wx.CB_SORT)
-        self.attributes = attributes
-        self.objectList = objectList
-        self.attr = attr
-        self.updateList()
-        objectList.addListener(self.updateList)
-
-    def Destroy(self):
-        self.objectList.removeListener(self.updateList)
-        wx.ComboBox.Destroy(self)
-
-    def GetValue(self):
-        return wx.ComboBox.GetValue(self) or None
-
-    def SetValue(self, value):
-        if value in self.list:
-            self.SetSelection(self.list.index(value))
-        elif value is None:
-            wx.ComboBox.SetValue(self, "")
-        else:
-            wx.ComboBox.SetValue(self, value)
-
-    def updateList(self):
-        try:
-            self.Clear()
-            self.list = []
-            if not (self.attributes.has_key('Required') and 
self.attributes['Required'] ):
-                self.list.append(None)
-                self.Append('')
-            for v in self.objectList:
-                self.list.append(v[self.attr])
-                self.Append("%s" % v[self.attr])
-        except wx.PyDeadObjectError:
-            # TODO: why are we getting this exception?
-            # TODO: Destroy() is being explicitly called. :(
-            pass
-
-#
-# Property editor for boolean types
-#
-class BoolEditor(wx.ComboBox):
-    def __init__(self, parent, attributes):
-        wx.ComboBox.__init__(self, parent, -1,
-           style=wx.TE_PROCESS_ENTER|wx.CB_DROPDOWN|wx.CB_READONLY|wx.CB_SORT)
-        self.attributes = attributes
-
-        if not (self.attributes.has_key('Required') and 
self.attributes['Required'] ):
-            self.Append('')
-
-        try:
-            default = self.attributes['Default']
-        except KeyError:
-            default = None
-
-        self.True = u_('Yes')  + (default and '*' or '')
-        self.False = u_('No')  + (not default and '*' or '')
-
-        self.Append(self.True)
-        self.Append(self.False)
-
-
-    def GetValue(self):
-        v = wx.ComboBox.GetValue(self)
-        if v == '':
-            return None
-        else:
-            return v == self.True
-
-    def SetValue(self, value):
-        if value == None:
-            wx.ComboBox.SetValue(self,'')
-        elif value:
-            wx.ComboBox.SetValue(self,self.True)
-        else:
-            wx.ComboBox.SetValue(self,self.False)
-
-#
-#
-#
-class IntEditor(wx.SpinCtrl):
-    def __init__(self, parent, attributes):
-        wx.SpinCtrl.__init__(self, parent, -1, style=wx.TE_PROCESS_ENTER)
-        self.attributes = attributes
-
-#
-#
-#
-class TextEditor(wx.TextCtrl):
-    def __init__(self, parent, attributes):
-        wx.TextCtrl.__init__(self, parent, -1, style=wx.TE_PROCESS_ENTER)
-        self.attributes = attributes
-
-    def SetValue(self, value):
-        if value == None:
-            value = ""
-        wx.TextCtrl.SetValue(self, wxEncode(value))

Modified: trunk/gnue-designer/src/forms/PagePainter/skins/common.py
===================================================================
--- trunk/gnue-designer/src/forms/PagePainter/skins/common.py   2006-04-09 
17:18:40 UTC (rev 8396)
+++ trunk/gnue-designer/src/forms/PagePainter/skins/common.py   2006-04-10 
17:14:44 UTC (rev 8397)
@@ -150,24 +150,31 @@
         """
         self.force_canvas_refresh()
 
+        gobject = self.gobject
+
         delta_char_width = int(round(delta_width / float(char_x_scale)))
         delta_char_height = int(round(delta_height / float(char_y_scale)))
 
         if delta_char_width or delta_char_height:
             char_width = min(max(delta_char_width +
-                                 self.gobject['Char:width'],
+                                 gobject['Char:width'],
                                  self.char_min_width),
                             self.char_max_width)
 
+            try:
+                char_height = gobject['Char:height']
+            except KeyError:
+                char_height =  self.char_default_height
+
             char_height = min(max(delta_char_height +
-                                  self.gobject['Char:height'],
+                                  char_height,
                                   self.char_min_height),
-                            self.char_max_height)
+                                  self.char_max_height)
 
             if delta_char_width:
-                self.gobject['Char:width'] = char_width
+                gobject['Char:width'] = char_width
             if delta_char_height:
-                self.gobject['Char:height'] = char_height
+                gobject['Char:height'] = char_height
 
             self.recalc_metrics()
             self.force_canvas_refresh()

Modified: trunk/gnue-designer/src/forms/PropertyEditor.py
===================================================================
--- trunk/gnue-designer/src/forms/PropertyEditor.py     2006-04-09 17:18:40 UTC 
(rev 8396)
+++ trunk/gnue-designer/src/forms/PropertyEditor.py     2006-04-10 17:14:44 UTC 
(rev 8397)
@@ -24,12 +24,15 @@
 PropertyEditor wrapper for forms
 """
 
-import sys, os, string
+import sys
+import os
+import string
+
 import wx
+
 from gnue.common.apps import GDebug
 from gnue.common.formatting import GTypecast
 from gnue.designer.base.tools.PropertyEditor import PropertyEditor as 
BasePropertyEditor
-from gnue.designer.base.tools.PropertyEditor import InspectorPanel as 
BaseInspectorPanel
 from gnue.designer.base.ToolBase import *
 
 class PropertyEditor (BasePropertyEditor):
@@ -76,65 +79,65 @@
             self.addPage(CharPosInspectorPanel(self, self.notebook), 'Layout')
 
 
-#
-# Field properties (when Entry is selected)
-#
-class FieldInspectorPanel(BaseInspectorPanel):
+##
+## Field properties (when Entry is selected)
+##
+#class FieldInspectorPanel(BaseInspectorPanel):
 
-    def setCurrent(self, object):
-        self._setCurrent(object._field)
+    #def setCurrent(self, object):
+        #self._setCurrent(object._field)
 
-#
-# Block properties (when Entry/Field is selected)
-#
-class BlockInspectorPanel(BaseInspectorPanel):
+##
+## Block properties (when Entry/Field is selected)
+##
+#class BlockInspectorPanel(BaseInspectorPanel):
 
-    def setCurrent(self, object):
-        self._setCurrent(object.findParentOfType('GFBlock'))
+    #def setCurrent(self, object):
+        #self._setCurrent(object.findParentOfType('GFBlock'))
 
-class EntryBlockInspectorPanel(BaseInspectorPanel):
-    def setCurrent(self, object):
-        self._setCurrent(object._block)
+#class EntryBlockInspectorPanel(BaseInspectorPanel):
+    #def setCurrent(self, object):
+        #self._setCurrent(object._block)
 
-#
-# Datasource properties (when Block is selected)
-#
-class DatasourceInspectorPanel(BaseInspectorPanel):
-    def setCurrent(self, object):
-        try:
-            if hasattr(object,'datasource') and object.datasource:
-                
self._setCurrent(self.editor.document.datasources[object.datasource])
-        except AttributeError:
-            pass  # Happens on startup
+##
+## Datasource properties (when Block is selected)
+##
+#class DatasourceInspectorPanel(BaseInspectorPanel):
+    #def setCurrent(self, object):
+        #try:
+            #if hasattr(object,'datasource') and object.datasource:
+                
#self._setCurrent(self.editor.document.datasources[object.datasource])
+        #except AttributeError:
+            #pass  # Happens on startup
 
-#
-# Character-cell layout (x,y) properties
-#
-class CharPosInspectorPanel(BaseInspectorPanel):
+##
+## Character-cell layout (x,y) properties
+##
+#class CharPosInspectorPanel(BaseInspectorPanel):
 
-    NAMESPACE = "Char"
+    #NAMESPACE = "Char"
 
-    def getAttributes(self, object):
-        return {
-           'Char:x':      { 'Typecast': GTypecast.whole },
-           'Char:y':      { 'Typecast': GTypecast.whole },
-           'Char:width':  { 'Typecast': GTypecast.whole },
-           'Char:height': { 'Typecast': GTypecast.whole } }
+    #def getAttributes(self, object):
+        #return {
+           #'Char:x':      { 'Typecast': GTypecast.whole },
+           #'Char:y':      { 'Typecast': GTypecast.whole },
+           #'Char:width':  { 'Typecast': GTypecast.whole },
+           #'Char:height': { 'Typecast': GTypecast.whole } }
 
-    def getPageText(self):
-        return "Display"
+    #def getPageText(self):
+        #return "Display"
 
-#
-# Character-cell layout (x,y) properties
-#
-class CharSizeInspectorPanel(BaseInspectorPanel):
+##
+## Character-cell layout (x,y) properties
+##
+#class CharSizeInspectorPanel(BaseInspectorPanel):
 
-    NAMESPACE = "Char"
+    #NAMESPACE = "Char"
 
-    def getAttributes(self, object):
-        return {
-           'Char:width':  { 'Typecast': GTypecast.whole },
-           'Char:height': { 'Typecast': GTypecast.whole } }
+    #def getAttributes(self, object):
+        #return {
+           #'Char:width':  { 'Typecast': GTypecast.whole },
+           #'Char:height': { 'Typecast': GTypecast.whole } }
 
-    def getPageText(self):
-        return "Display"
+    #def getPageText(self):
+        #return "Display"

Modified: trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py
===================================================================
--- trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py 2006-04-09 
17:18:40 UTC (rev 8396)
+++ trunk/gnue-designer/src/ui/wx/uihelpers/doccanvas/canvas.py 2006-04-10 
17:14:44 UTC (rev 8397)
@@ -327,7 +327,7 @@
 
         # Draw widgets (in the reverse order they are stored in our list)
         for widget in self.ordered_widget_list[::-1]:
-                      
+
             refresh_area = widget.refresh_area
 
             (obj_x, obj_y,
@@ -502,9 +502,9 @@
                 if not new_action:
                     selected = self.select_hit_test(x, y)
                     if selected:
-                        if event.CmdDown() or event.ShiftDown(): 
+                        if event.CmdDown() or event.ShiftDown():
                             widgets = self.___merge_selections([selected])
-                        else: 
+                        else:
                             self.selected_from_canvas([selected])
                         new_action = 'move'
 
@@ -545,13 +545,13 @@
                 else:
                     widget = self.select_hit_test(area.x, area.y)
                     widgets = widget and [widget] or []
-                    
-                if event.CmdDown() or event.ShiftDown(): 
-                    # If ctrl, cmd, or shift were pressed, 
+
+                if event.CmdDown() or event.ShiftDown():
+                    # If ctrl, cmd, or shift were pressed,
                     # then the user was adding or removing widgets
-                    # and not selecting a whole new set. 
+                    # and not selecting a whole new set.
                     self.__merge_selections(widgets)
-                else: 
+                else:
                     self.selected_from_canvas(widgets)
 
             elif current_action == 'move':
@@ -707,20 +707,20 @@
 
         return results
 
-    def ___merge_selections(self, new_selection): 
+    def ___merge_selections(self, new_selection):
         """
         Merge a new selection with an old selection, eliminating
         any widgets in both. (This is used when Cmd+Click is used
         to select a widget.
         """
-        # If ctrl, cmd, or shift were pressed, 
+        # If ctrl, cmd, or shift were pressed,
         # then the user was adding or removing widgets
-        # and not selecting a whole new set. 
+        # and not selecting a whole new set.
         selection = self.get_selected_widgets()
-        for widget in new_selection: 
-            if widget in selection:  
+        for widget in new_selection:
+            if widget in selection:
                 selection.remove(widget)
-            else: 
+            else:
                 selection.append(widget)
 
         self.selected_from_canvas(selection)
@@ -744,7 +744,7 @@
 
         self.CaptureMouse()
 
-                
+
         # These will visually move, but not necessarily have their x,y changed.
         self.__mouse_move_all = all_widgets = []
 
@@ -754,40 +754,40 @@
         # Start out with the selected widgets
         selected_widgets = self.get_selected_widgets()
         self.__mouse_move_selected = selected_widgets
-                  
+
         unvisited_widgets = selected_widgets[:]
 
-        # And recursively add any siblings or children        
+        # And recursively add any siblings or children
         # (TODO: it's not recursive yet)
         area = wx.Rect()
-        while unvisited_widgets: 
+        while unvisited_widgets:
             widget = unvisited_widgets.pop()
             all_widgets.append(widget)
             movable_widgets.append(widget)
-            
+
             # Process child widgets
-            for child_widget in widget.get_movable_children(): 
-                if child_widget not in all_widgets: 
+            for child_widget in widget.get_movable_children():
+                if child_widget not in all_widgets:
                     all_widgets.append(child_widget)
-            
 
+
             # Process movable widgets
-            for child_widget in widget.get_movable_siblings(): 
-                if child_widget not in all_widgets: 
+            for child_widget in widget.get_movable_siblings():
+                if child_widget not in all_widgets:
                     all_widgets.append(child_widget)
                     movable_widgets.append(child_widget)
-                
 
+
         # Unselect any selected ones
         for widget in selected_widgets:
             widget.selected = False
-            
+
         # And hide all of them
-        for widget in all_widgets: 
+        for widget in all_widgets:
             widget.visible = False
             area = area.Union(widget.refresh_area)
-            
-            
+
+
         # Create a bitmap of our widgets in an offscreen buffer
         # so we can redraw them as the mouse moves
 
@@ -812,18 +812,18 @@
 
             memory_dc.SetDeviceOrigin(obj_x - buff_x, obj_y - buff_y)
             widget.draw_widget(memory_dc)
-            # If the widget is implicitly being moved because it is a 
-            # sibling (i.e., labels attached to fields), draw a special 
-            # border around the sibling. 
-            if wx.IntersectRect(widget.hit_test_area, 
-                    self.__selection_area) != widget.hit_test_area:  
+            # If the widget is implicitly being moved because it is a
+            # sibling (i.e., labels attached to fields), draw a special
+            # border around the sibling.
+            if wx.IntersectRect(widget.hit_test_area,
+                    self.__selection_area) != widget.hit_test_area:
               widget.draw_sibling_border(memory_dc)
-              
+
             memory_dc.SetDeviceOrigin(0,0)
 
         # Draw a selection box
         sel_x, sel_y, sel_w, sel_h = self.__selection_area.Get()
-        self.__draw_selection_box(memory_dc, sel_x - buff_x, 
+        self.__draw_selection_box(memory_dc, sel_x - buff_x,
                                   sel_y - buff_y, sel_w, sel_h)
 
         memory_dc.EndDrawing()
@@ -869,11 +869,11 @@
 
         for widget in self.__mouse_move_selected:
             widget.selected = True
-            
-        for widget in self.__mouse_move_all: 
+
+        for widget in self.__mouse_move_all:
             widget.show()
-            
-        for widget in self.__mouse_move_items: 
+
+        for widget in self.__mouse_move_items:
             if x != self.__mouse_move_start_x or \
                y != self.__mouse_move_start_y:
                 widget.move_from_canvas(x - self.__mouse_move_start_x,
@@ -882,7 +882,7 @@
         self.__mouse_move_items = None
         self.__mouse_move_all = None
         self.__mouse_move_selected = None
-        
+
         self.refresh_selection()
         self.refresh_scrolled_area(old_area)
 
@@ -988,13 +988,13 @@
 
             orientation = self.__mouse_resize_orientation
 
-            delta_width = x - self.__mouse_resize_start_x 
-            delta_height = y - self.__mouse_resize_start_y 
+            delta_width = x - self.__mouse_resize_start_x
+            delta_height = y - self.__mouse_resize_start_y
 
             # Discard width or height if only a side was moved
-            if orientation in ('top','bottom'): 
+            if orientation in ('top','bottom'):
                 delta_width = 0
-            if orientation in ('left','right'): 
+            if orientation in ('left','right'):
                 delta_height = 0
 
             # Determine if the widget moved while being resized
@@ -1006,9 +1006,9 @@
             if orientation in ('top','ul','ur') and delta_height:
                 delta_y = delta_height
                 delta_height *= -1
-                
-                
 
+
+
             # Figure out the resize amount
             for widget in self.get_selected_widgets():
                 if delta_x or delta_y:
@@ -1142,14 +1142,14 @@
         """
         Add a DocumentWidget to the canvas
         """
-        if widget.container: 
+        if widget.container:
             self.ordered_widget_bottom.insert(0,widget)
-        else: 
+        else:
             self.ordered_widget_top.insert(0,widget)
-            
+
         self.ordered_widget_list = self.ordered_widget_top + \
                                    self.ordered_widget_bottom
-                                   
+
         self.gobject_map[widget.gobject] = widget
         widget.force_canvas_refresh()
 
@@ -1159,13 +1159,13 @@
         Remove a DocumentWidget from the canvas
         """
         self.ordered_widget_list.remove(widget)
-        try: 
+        try:
            self.ordered_widget_top.remove(widget)
-        except: 
+        except:
            self.ordered_widget_bottom.remove(widget)
-        
+
         del self.gobject_map[widget.gobject]
-        
+
         area = widget.refresh_area
         self.refresh_scrolled_area(refresh_area)
         widget.Destroy()

Modified: trunk/gnue-forms/samples/intro/intro.gfd
===================================================================
--- trunk/gnue-forms/samples/intro/intro.gfd    2006-04-09 17:18:40 UTC (rev 
8396)
+++ trunk/gnue-forms/samples/intro/intro.gfd    2006-04-10 17:14:44 UTC (rev 
8397)
@@ -124,20 +124,20 @@
     <page name="Sample">
       <box name="Box_2" c:height="8" label="Sample" c:width="38" c:x="1"
            c:y="0"/>
-      <label name="Label_5" text="Your Name:" c:width="11" c:x="3" c:y="2"/>
-      <label name="Label_6" text="Year you were born:" c:width="20" c:x="3"
+      <label for="nameField" name="Label_5" text="Your Name:" c:width="11" 
c:x="3" c:y="2"/>
+      <label for="yearField" name="Label_6" text="Year you were born:" 
c:width="20" c:x="3"
              c:y="3"/>
-      <label name="Label_7" text="Your Code Name:" c:width="15" c:x="3"
+      <label for="codeField" name="Label_7" text="Your Code Name:" 
c:width="15" c:x="3"
              c:y="5"/>
-      <entry block="SampleBlock" field="NameEntry" c:width="23" c:x="14"
+      <entry name="nameField" block="SampleBlock" field="NameEntry" 
c:width="23" c:x="14"
              c:y="2"/>
-      <entry block="SampleBlock" field="YearEntry" c:width="6" c:x="22"
+      <entry name="yearField" block="SampleBlock" field="YearEntry" 
c:width="6" c:x="22"
              c:y="3"/>
       <button name="btnClear" c:height="1" label="Fortune" c:width="8"
               c:x="29" c:y="3">
         <trigger src="MyFortune" type="On-Action"/>
       </button>
-      <entry block="SampleBlock" field="CodeNameEntry" c:width="34" c:x="3"
+      <entry name="codeField" block="SampleBlock" field="CodeNameEntry" 
c:width="34" c:x="3"
              c:y="6"/>
       <entry block="SampleBlock" field="FortuneEntry" c:height="4"
              c:width="36" c:x="2" c:y="8"/>

Modified: trunk/gnue-forms/src/GFParser.py
===================================================================
--- trunk/gnue-forms/src/GFParser.py    2006-04-09 17:18:40 UTC (rev 8396)
+++ trunk/gnue-forms/src/GFParser.py    2006-04-10 17:14:44 UTC (rev 8397)
@@ -312,11 +312,12 @@
                'Required': True,
                'Typecast': GTypecast.text,
                'Description': 'The text to be displayed.' },
-            'for': { 
+            'for': {
                'Required': False,
+               'References': 'entry.name',
                'Typecast': GTypecast.name,
                'Description': 'If this label is for a specific object, '
-                              'name it here.' },            
+                              'name it here.' },
             'alignment': {
                'Typecast': GTypecast.name,
                'ValueSet': {
@@ -649,7 +650,7 @@
                'Description': 'The unique name of the image.' },
             'field': {
                'Typecast': GTypecast.name,
-               'References': 'field.name',
+               'References': 'block.name>field.name',
                'Required': True,
                'Description': 'The name of the field that this ties to.' },
             'block': {
@@ -708,7 +709,7 @@
                'Description': 'The unique name of the component.' },
             'field': {
                'Typecast': GTypecast.name,
-               'References': 'field.name',
+               'References': 'block.name>field.name',
                'Required': True,
                'Description': 'The name of the field that this ties to.' },
             'block': {





reply via email to

[Prev in Thread] Current Thread [Next in Thread]