浏览代码

wxGUI: refactor ElementDialog; include validator

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@54838 15284696-431f-4ddb-bdfa-cd5b030d7da7
Anna Petrášová 12 年之前
父节点
当前提交
58a29b9284

+ 34 - 11
gui/wxpython/gmodeler/dialogs.py

@@ -32,33 +32,36 @@ import wx.lib.mixins.listctrl as listmix
 from core                 import globalvar
 from core                 import globalvar
 from core                 import utils
 from core                 import utils
 from core.modulesdata     import ModulesData
 from core.modulesdata     import ModulesData
-from gui_core.widgets     import SearchModuleWidget, EVT_MODULE_SELECTED
+from gui_core.widgets     import SearchModuleWidget, EVT_MODULE_SELECTED, SimpleValidator
 from core.gcmd            import GError, EncodeString
 from core.gcmd            import GError, EncodeString
-from gui_core.dialogs     import ElementDialog, MapLayersDialogForModeler
+from gui_core.dialogs     import SimpleDialog, MapLayersDialogForModeler
 from gui_core.prompt      import GPromptSTC, EVT_GPROMPT_RUN_CMD
 from gui_core.prompt      import GPromptSTC, EVT_GPROMPT_RUN_CMD
 from gui_core.forms       import CmdPanel
 from gui_core.forms       import CmdPanel
-from gui_core.gselect     import Select
+from gui_core.gselect     import Select, ElementSelect
 from gmodeler.model       import *
 from gmodeler.model       import *
 
 
 from grass.script import task as gtask
 from grass.script import task as gtask
 
 
-class ModelDataDialog(ElementDialog):
+class ModelDataDialog(SimpleDialog):
     """!Data item properties dialog"""
     """!Data item properties dialog"""
-    def __init__(self, parent, shape, id = wx.ID_ANY, title = _("Data properties"),
-                 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
+    def __init__(self, parent, shape, title = _("Data properties")):
         self.parent = parent
         self.parent = parent
         self.shape = shape
         self.shape = shape
         
         
         label, etype = self._getLabel()
         label, etype = self._getLabel()
-        ElementDialog.__init__(self, parent, title, label = label, etype = etype)
+        self.etype = etype
+        SimpleDialog.__init__(self, parent, title)
                 
                 
-        self.element = Select(parent = self.panel)
+        self.element = Select(parent = self.panel,
+                              validator = SimpleValidator(callback = self.ValidatorCallback))
         self.element.SetValue(shape.GetValue())
         self.element.SetValue(shape.GetValue())
         
         
         self.Bind(wx.EVT_BUTTON, self.OnOK,     self.btnOK)
         self.Bind(wx.EVT_BUTTON, self.OnOK,     self.btnOK)
         self.Bind(wx.EVT_BUTTON, self.OnCancel, self.btnCancel)
         self.Bind(wx.EVT_BUTTON, self.OnCancel, self.btnCancel)
-        
-        self.PostInit()
+        if self.etype:
+            self.typeSelect = ElementSelect(parent = self.panel,
+                                            size = globalvar.DIALOG_GSELECT_SIZE)
+            self.typeSelect.Bind(wx.EVT_CHOICE, self.OnType)
         
         
         if shape.GetValue():
         if shape.GetValue():
             self.btnOK.Enable()
             self.btnOK.Enable()
@@ -81,15 +84,35 @@ class ModelDataDialog(ElementDialog):
     
     
     def _layout(self):
     def _layout(self):
         """!Do layout"""
         """!Do layout"""
+        if self.etype:
+            self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
+                                                    label = _("Type of element:")),
+                               proportion = 0, flag = wx.ALL, border = 1)
+            self.dataSizer.Add(item = self.typeSelect,
+                               proportion = 0, flag = wx.ALL, border = 1)
+        self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
+                                                label = _("Name of element:")),
+                           proportion = 0, flag = wx.ALL, border = 1)
         self.dataSizer.Add(self.element, proportion=0,
         self.dataSizer.Add(self.element, proportion=0,
                       flag=wx.EXPAND | wx.ALL, border=1)
                       flag=wx.EXPAND | wx.ALL, border=1)
         
         
         self.panel.SetSizer(self.sizer)
         self.panel.SetSizer(self.sizer)
         self.sizer.Fit(self)
         self.sizer.Fit(self)
 
 
+    def GetType(self):
+        """!Get element type"""
+        if not self.etype:
+            return
+        return self.element.tcp.GetType()
+
+    def OnType(self, event):
+        """!Select element type"""
+        evalue = self.typeSelect.GetValue(event.GetString())
+        self.element.SetType(evalue)
+
     def OnOK(self, event):
     def OnOK(self, event):
         """!Ok pressed"""
         """!Ok pressed"""
-        self.shape.SetValue(self.GetElement())
+        self.shape.SetValue(self.element.GetValue())
         if self.etype:
         if self.etype:
             elem = self.GetType()
             elem = self.GetType()
             if elem == 'rast':
             if elem == 'rast':

+ 69 - 113
gui/wxpython/gui_core/dialogs.py

@@ -4,7 +4,7 @@
 @brief Various dialogs used in wxGUI.
 @brief Various dialogs used in wxGUI.
 
 
 List of classes:
 List of classes:
- - dialogs::ElementDialog
+ - dialogs::SimpleDialog
  - dialogs::LocationDialog
  - dialogs::LocationDialog
  - dialogs::MapsetDialog
  - dialogs::MapsetDialog
  - dialogs::NewVectorDialog
  - dialogs::NewVectorDialog
@@ -47,9 +47,9 @@ from grass.script import task as gtask
 
 
 from core             import globalvar
 from core             import globalvar
 from core.gcmd        import GError, RunCommand, GMessage
 from core.gcmd        import GError, RunCommand, GMessage
-from gui_core.gselect import ElementSelect, LocationSelect, MapsetSelect, Select, OgrTypeSelect, GdalSelect, MapsetSelect
+from gui_core.gselect import LocationSelect, MapsetSelect, Select, OgrTypeSelect, GdalSelect, MapsetSelect
 from gui_core.forms   import GUI
 from gui_core.forms   import GUI
-from gui_core.widgets import SingleSymbolPanel, EVT_SYMBOL_SELECTION_CHANGED, GListCtrl
+from gui_core.widgets import SingleSymbolPanel, EVT_SYMBOL_SELECTION_CHANGED, GListCtrl, SimpleValidator
 from core.utils       import GetLayerNameFromCmd, GetValidLayerName
 from core.utils       import GetLayerNameFromCmd, GetValidLayerName
 from core.settings    import UserSettings, GetDisplayVectSettings
 from core.settings    import UserSettings, GetDisplayVectSettings
 from core.debug       import Debug
 from core.debug       import Debug
@@ -57,74 +57,32 @@ from core.debug       import Debug
 wxApplyMapLayers, EVT_APPLY_MAP_LAYERS = NewEvent()
 wxApplyMapLayers, EVT_APPLY_MAP_LAYERS = NewEvent()
 wxApplyOpacity, EVT_APPLY_OPACITY = NewEvent()
 wxApplyOpacity, EVT_APPLY_OPACITY = NewEvent()
 
 
-class ElementDialog(wx.Dialog):
-    def __init__(self, parent, title, label, id = wx.ID_ANY,
-                 etype = False, style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+class SimpleDialog(wx.Dialog):
+    def __init__(self, parent, title, id = wx.ID_ANY,
+                 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
                  **kwargs):
                  **kwargs):
         """!General dialog to choose given element (location, mapset, vector map, etc.)
         """!General dialog to choose given element (location, mapset, vector map, etc.)
         
         
         @param parent window
         @param parent window
         @param title window title
         @param title window title
-        @param label element label
-        @param etype show also ElementSelect
         """
         """
         wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
         wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
-        
-        self.etype = etype
-        self.label = label
-        
+        self.SetExtraStyle(wx.WS_EX_VALIDATE_RECURSIVELY)
         self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
         self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
         
         
         self.btnCancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL)
         self.btnCancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL)
         self.btnOK     = wx.Button(parent = self.panel, id = wx.ID_OK)
         self.btnOK     = wx.Button(parent = self.panel, id = wx.ID_OK)
         self.btnOK.SetDefault()
         self.btnOK.SetDefault()
-        
-        if self.etype:
-            self.typeSelect = ElementSelect(parent = self.panel,
-                                            size = globalvar.DIALOG_GSELECT_SIZE)
-            self.typeSelect.Bind(wx.EVT_CHOICE, self.OnType)
-        
-        self.element = None # must be defined 
-        
         self.__layout()
         self.__layout()
-        
-    def PostInit(self):
-        self.element.SetFocus()
-        self.element.Bind(wx.EVT_TEXT, self.OnElement)
-        if not self.element.GetValue():
-            self.btnOK.Disable()
-            
-    def OnType(self, event):
-        """!Select element type"""
-        if not self.etype:
-            return
-        evalue = self.typeSelect.GetValue(event.GetString())
-        self.element.SetType(evalue)
-        
-    def OnElement(self, event):
-        """!Name for vector map layer given"""
-        if len(event.GetString()) > 0:
-            self.btnOK.Enable(True)
-        else:
-            self.btnOK.Enable(False)
-        
+        self.warning = _("Required item is not set.")
+
     def __layout(self):
     def __layout(self):
         """!Do layout"""
         """!Do layout"""
         self.sizer = wx.BoxSizer(wx.VERTICAL)
         self.sizer = wx.BoxSizer(wx.VERTICAL)
         
         
         self.dataSizer = wx.BoxSizer(wx.VERTICAL)
         self.dataSizer = wx.BoxSizer(wx.VERTICAL)
         
         
-        if self.etype:
-            self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
-                                                    label = _("Type of element:")),
-                               proportion = 0, flag = wx.ALL, border = 1)
-            self.dataSizer.Add(item = self.typeSelect,
-                               proportion = 0, flag = wx.ALL, border = 1)
-        
-        self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
-                                                label = self.label),
-                           proportion = 0, flag = wx.ALL, border = 1)
-        
+        # self.informLabel = wx.StaticText(self.panel, id = wx.ID_ANY)
         # buttons
         # buttons
         btnSizer = wx.StdDialogButtonSizer()
         btnSizer = wx.StdDialogButtonSizer()
         btnSizer.AddButton(self.btnCancel)
         btnSizer.AddButton(self.btnCancel)
@@ -134,119 +92,119 @@ class ElementDialog(wx.Dialog):
         self.sizer.Add(item = self.dataSizer, proportion = 1,
         self.sizer.Add(item = self.dataSizer, proportion = 1,
                        flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
                        flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
         
         
+        # self.sizer.Add(item = self.informLabel, proportion = 0, flag = wx.ALL, border = 5)
         self.sizer.Add(item = btnSizer, proportion = 0,
         self.sizer.Add(item = btnSizer, proportion = 0,
                        flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
                        flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
-        
-    def GetElement(self):
-        """!Return (mapName, overwrite)"""
-        return self.element.GetValue()
-    
-    def GetType(self):
-        """!Get element type"""
-        return self.element.tcp.GetType()
-        
-class LocationDialog(ElementDialog):
-    """!Dialog used to select location"""
-    def __init__(self, parent, title = _("Select GRASS location and mapset"), id =  wx.ID_ANY):
-        ElementDialog.__init__(self, parent, title, label = _("Name of GRASS location:"))
 
 
-        self.element = LocationSelect(parent = self.panel, id = wx.ID_ANY,
-                                      size = globalvar.DIALOG_GSELECT_SIZE)
-        
-        self.element1 = MapsetSelect(parent = self.panel, id = wx.ID_ANY,
+    def ValidatorCallback(self, win):
+        GMessage(parent = self, message = self.warning)
+        # self.informLabel.SetForegroundColour(wx.Color(255, 0, 0))
+        # self.informLabel.SetLabel(self.warning)
+
+
+class LocationDialog(SimpleDialog):
+    """!Dialog used to select location"""
+    def __init__(self, parent, title = _("Select GRASS location and mapset")):
+        SimpleDialog.__init__(self, parent, title)
+
+        self.element1 = LocationSelect(parent = self.panel, id = wx.ID_ANY,
+                                      size = globalvar.DIALOG_GSELECT_SIZE,
+                                      validator = SimpleValidator(callback = self.ValidatorCallback))
+        self.element1.Bind(wx.EVT_TEXT, self.OnLocation)
+        self.element2 = MapsetSelect(parent = self.panel, id = wx.ID_ANY,
                                      size = globalvar.DIALOG_GSELECT_SIZE,
                                      size = globalvar.DIALOG_GSELECT_SIZE,
-                                     setItems = False, skipCurrent = True)
-        
-        self.PostInit()
-        
+                                     setItems = False, skipCurrent = True,
+                                     validator = SimpleValidator(callback = self.ValidatorCallback))
+        self.element1.SetFocus()
+        self.warning = _("Location or mapset is missing.")
         self._layout()
         self._layout()
         self.SetMinSize(self.GetSize())
         self.SetMinSize(self.GetSize())
 
 
     def _layout(self):
     def _layout(self):
         """!Do layout"""
         """!Do layout"""
-        self.dataSizer.Add(self.element, proportion = 0,
+        self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
+                                                label = _("Name of GRASS location:")),
+                           proportion = 0, flag = wx.ALL, border = 1)
+        self.dataSizer.Add(self.element1, proportion = 0,
                            flag = wx.EXPAND | wx.ALL, border = 1)
                            flag = wx.EXPAND | wx.ALL, border = 1)
  
  
         self.dataSizer.Add(wx.StaticText(parent = self.panel, id = wx.ID_ANY,
         self.dataSizer.Add(wx.StaticText(parent = self.panel, id = wx.ID_ANY,
                                          label = _("Name of mapset:")), proportion = 0,
                                          label = _("Name of mapset:")), proportion = 0,
                            flag = wx.EXPAND | wx.ALL, border = 1)
                            flag = wx.EXPAND | wx.ALL, border = 1)
 
 
-        self.dataSizer.Add(self.element1, proportion = 0,
+        self.dataSizer.Add(self.element2, proportion = 0,
                            flag = wx.EXPAND | wx.ALL, border = 1)
                            flag = wx.EXPAND | wx.ALL, border = 1)
        
        
         self.panel.SetSizer(self.sizer)
         self.panel.SetSizer(self.sizer)
         self.sizer.Fit(self)
         self.sizer.Fit(self)
 
 
-    def OnElement(self, event):
+    def OnLocation(self, event):
         """!Select mapset given location name"""
         """!Select mapset given location name"""
         location = event.GetString()
         location = event.GetString()
         
         
         if location:
         if location:
             dbase = grass.gisenv()['GISDBASE']
             dbase = grass.gisenv()['GISDBASE']
-            self.element1.UpdateItems(dbase = dbase, location = location)
-            self.element1.SetSelection(0)
-            mapset = self.element1.GetStringSelection()
-        
-        if location and mapset:
-            self.btnOK.Enable(True)
-        else:
-            self.btnOK.Enable(False)
+            self.element2.UpdateItems(dbase = dbase, location = location)
+            self.element2.SetSelection(0)
+            mapset = self.element2.GetStringSelection()
 
 
     def GetValues(self):
     def GetValues(self):
         """!Get location, mapset"""
         """!Get location, mapset"""
-        return (self.GetElement(), self.element1.GetStringSelection())
+        return (self.element1.GetValue(), self.element2.GetValue())
     
     
-class MapsetDialog(ElementDialog):
+class MapsetDialog(SimpleDialog):
     """!Dialog used to select mapset"""
     """!Dialog used to select mapset"""
     def __init__(self, parent, title = _("Select mapset in GRASS location"),
     def __init__(self, parent, title = _("Select mapset in GRASS location"),
-                 location = None, id =  wx.ID_ANY):
-        ElementDialog.__init__(self, parent, title, label = _("Name of mapset:"))
+                 location = None):
+        SimpleDialog.__init__(self, parent, title)
+
         if location:
         if location:
             self.SetTitle(self.GetTitle() + ' <%s>' % location)
             self.SetTitle(self.GetTitle() + ' <%s>' % location)
         else:
         else:
             self.SetTitle(self.GetTitle() + ' <%s>' % grass.gisenv()['LOCATION_NAME'])
             self.SetTitle(self.GetTitle() + ' <%s>' % grass.gisenv()['LOCATION_NAME'])
         
         
         self.element = MapsetSelect(parent = self.panel, id = wx.ID_ANY, skipCurrent = True,
         self.element = MapsetSelect(parent = self.panel, id = wx.ID_ANY, skipCurrent = True,
-                                    size = globalvar.DIALOG_GSELECT_SIZE)
+                                    size = globalvar.DIALOG_GSELECT_SIZE,
+                                    validator = SimpleValidator(callback = self.ValidatorCallback))
         
         
-        self.PostInit()
+        self.element.SetFocus()
+        self.warning = _("Name of mapset is missing.")
         
         
-        self.__Layout()
+        self._layout()
         self.SetMinSize(self.GetSize())
         self.SetMinSize(self.GetSize())
 
 
-    def __Layout(self):
+    def _layout(self):
         """!Do layout"""
         """!Do layout"""
+        self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
+                                                label = _("Name of mapset:")),
+                           proportion = 0, flag = wx.ALL, border = 1)
         self.dataSizer.Add(self.element, proportion = 0,
         self.dataSizer.Add(self.element, proportion = 0,
-                      flag = wx.EXPAND | wx.ALL, border = 1)
-        
+                           flag = wx.EXPAND | wx.ALL, border = 1)
         self.panel.SetSizer(self.sizer)
         self.panel.SetSizer(self.sizer)
         self.sizer.Fit(self)
         self.sizer.Fit(self)
 
 
     def GetMapset(self):
     def GetMapset(self):
-        return self.GetElement()
+        return self.element.GetValue()
     
     
-class NewVectorDialog(ElementDialog):
-    def __init__(self, parent, id = wx.ID_ANY, title = _('Create new vector map'),
-                 disableAdd = False, disableTable = False, showType = False,
-                 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, *kwargs):
+class NewVectorDialog(SimpleDialog):
+    def __init__(self, parent, title = _("Create new vector map"),
+                 disableAdd = False, disableTable = False, showType = False):
         """!Dialog for creating new vector map
         """!Dialog for creating new vector map
 
 
         @param parent parent window
         @param parent parent window
-        @param id window id
         @param title window title
         @param title window title
         @param disableAdd disable 'add layer' checkbox
         @param disableAdd disable 'add layer' checkbox
         @param disableTable disable 'create table' checkbox
         @param disableTable disable 'create table' checkbox
         @param showType True to show feature type selector (used for creating new empty OGR layers)
         @param showType True to show feature type selector (used for creating new empty OGR layers)
-        @param style window style
-        @param kwargs other argumentes for ElementDialog
         
         
-        @return dialog instance       
+        @return dialog instance
         """
         """
-        ElementDialog.__init__(self, parent, title, label = _("Name for new vector map:"))
+        SimpleDialog.__init__(self, parent, title)
         
         
         self.element = Select(parent = self.panel, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
         self.element = Select(parent = self.panel, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
-                              type = 'vector', mapsets = [grass.gisenv()['MAPSET'],])
-        
+                              type = 'vector', mapsets = [grass.gisenv()['MAPSET'],],
+                              validator = SimpleValidator(callback = self.ValidatorCallback))
+        self.element.SetFocus()
         # determine output format
         # determine output format
         if showType:
         if showType:
             self.ftype = OgrTypeSelect(parent = self, panel = self.panel)
             self.ftype = OgrTypeSelect(parent = self, panel = self.panel)
@@ -278,21 +236,19 @@ class NewVectorDialog(ElementDialog):
 
 
         self.table.Bind(wx.EVT_CHECKBOX, self.OnTable)
         self.table.Bind(wx.EVT_CHECKBOX, self.OnTable)
         
         
-        self.PostInit()
-        
+        self.warning = _("Name of new vector map is missing.")
         self._layout()
         self._layout()
         self.SetMinSize(self.GetSize())
         self.SetMinSize(self.GetSize())
         
         
-    def OnMapName(self, event):
-        """!Name for vector map layer given"""
-        self.OnElement(event)
-        
     def OnTable(self, event):
     def OnTable(self, event):
         if self.keycol:
         if self.keycol:
             self.keycol.Enable(event.IsChecked())
             self.keycol.Enable(event.IsChecked())
         
         
     def _layout(self):
     def _layout(self):
         """!Do layout"""
         """!Do layout"""
+        self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
+                                                label = _("Name for new vector map:")),
+                           proportion = 0, flag = wx.ALL, border = 1)
         self.dataSizer.Add(item = self.element, proportion = 0,
         self.dataSizer.Add(item = self.element, proportion = 0,
                       flag = wx.EXPAND | wx.ALL, border = 1)
                       flag = wx.EXPAND | wx.ALL, border = 1)
         if self.ftype:
         if self.ftype:
@@ -327,7 +283,7 @@ class NewVectorDialog(ElementDialog):
 
 
         @param full True to get fully qualified name
         @param full True to get fully qualified name
         """
         """
-        name = self.GetElement()
+        name = self.element.GetValue()
         if full:
         if full:
             if '@' in name:
             if '@' in name:
                 return name
                 return name

+ 4 - 2
gui/wxpython/gui_core/gselect.py

@@ -68,7 +68,8 @@ class Select(wx.combo.ComboCtrl):
     def __init__(self, parent, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
     def __init__(self, parent, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
                  type = None, multiple = False, nmaps = 1,
                  type = None, multiple = False, nmaps = 1,
                  mapsets = None, updateOnPopup = True, onPopup = None,
                  mapsets = None, updateOnPopup = True, onPopup = None,
-                 fullyQualified = True, extraItems = {}):
+                 fullyQualified = True, extraItems = {},
+                 validator = wx.DefaultValidator):
         """!Custom control to create a ComboBox with a tree control to
         """!Custom control to create a ComboBox with a tree control to
         display and select GIS elements within acessible mapsets.
         display and select GIS elements within acessible mapsets.
         Elements can be selected with mouse. Can allow multiple
         Elements can be selected with mouse. Can allow multiple
@@ -83,8 +84,9 @@ class Select(wx.combo.ComboCtrl):
         @param onPopup function to be called on Popup
         @param onPopup function to be called on Popup
         @param fullyQualified True to provide fully qualified names (map@mapset)
         @param fullyQualified True to provide fully qualified names (map@mapset)
         @param extraItems extra items to add (given as dictionary) - see gmodeler for usage
         @param extraItems extra items to add (given as dictionary) - see gmodeler for usage
+        @param validator validator for TextCtrl
         """
         """
-        wx.combo.ComboCtrl.__init__(self, parent=parent, id=id, size=size)
+        wx.combo.ComboCtrl.__init__(self, parent=parent, id=id, size=size, validator=validator)
         self.GetChildren()[0].SetName("Select")
         self.GetChildren()[0].SetName("Select")
         self.GetChildren()[0].type = type
         self.GetChildren()[0].type = type
         
         

+ 46 - 1
gui/wxpython/gui_core/widgets.py

@@ -555,7 +555,52 @@ class NTCValidator(wx.PyValidator):
         # Returning without calling even.Skip eats the event before it
         # Returning without calling even.Skip eats the event before it
         # gets to the text control
         # gets to the text control
         return  
         return  
-    
+
+class SimpleValidator(wx.PyValidator):
+    """ This validator is used to ensure that the user has entered something
+        into the text object editor dialog's text field.
+    """
+    def __init__(self, callback):
+        """ Standard constructor.
+        """
+        wx.PyValidator.__init__(self)
+        self.callback = callback
+
+    def Clone(self):
+        """ Standard cloner.
+
+        Note that every validator must implement the Clone() method.
+        """
+        return SimpleValidator(self.callback)
+
+    def Validate(self, win):
+        """ Validate the contents of the given text control.
+        """
+        ctrl = self.GetWindow()
+        text = ctrl.GetValue()
+        if len(text) == 0:
+            self.callback(ctrl)
+            return False
+        else:
+            return True
+
+    def TransferToWindow(self):
+        """ Transfer data from validator to window.
+
+        The default implementation returns False, indicating that an error
+        occurred.  We simply return True, as we don't do any data transfer.
+        """
+        return True # Prevent wxDialog from complaining.
+
+
+    def TransferFromWindow(self):
+        """ Transfer data from window to validator.
+
+            The default implementation returns False, indicating that an error
+            occurred.  We simply return True, as we don't do any data transfer.
+        """
+        return True # Prevent wxDialog from complaining.
+
 class ItemTree(CT.CustomTreeCtrl):
 class ItemTree(CT.CustomTreeCtrl):
     def __init__(self, parent, id = wx.ID_ANY,
     def __init__(self, parent, id = wx.ID_ANY,
                  ctstyle = CT.TR_HIDE_ROOT | CT.TR_FULL_ROW_HIGHLIGHT | CT.TR_HAS_BUTTONS |
                  ctstyle = CT.TR_HIDE_ROOT | CT.TR_FULL_ROW_HIGHLIGHT | CT.TR_HAS_BUTTONS |

+ 40 - 29
gui/wxpython/iclass/dialogs.py

@@ -28,13 +28,14 @@ import wx.lib.scrolledpanel as scrolled
 from core               import globalvar
 from core               import globalvar
 from core.settings      import UserSettings
 from core.settings      import UserSettings
 from core.gcmd          import GMessage
 from core.gcmd          import GMessage
-from gui_core.dialogs   import ElementDialog, GroupDialog
+from gui_core.dialogs   import SimpleDialog, GroupDialog
 from gui_core           import gselect
 from gui_core           import gselect
+from gui_core.widgets   import SimpleValidator
 from iclass.statistics  import Statistics, BandStatistics
 from iclass.statistics  import Statistics, BandStatistics
 
 
 import grass.script as grass
 import grass.script as grass
 
 
-class IClassGroupDialog(ElementDialog):
+class IClassGroupDialog(SimpleDialog):
     """!Dialog for imagery group selection"""
     """!Dialog for imagery group selection"""
     def __init__(self, parent, group = None, title = _("Select imagery group"), id = wx.ID_ANY):
     def __init__(self, parent, group = None, title = _("Select imagery group"), id = wx.ID_ANY):
         """!
         """!
@@ -44,23 +45,28 @@ class IClassGroupDialog(ElementDialog):
         @param title dialog window title
         @param title dialog window title
         @param id wx id
         @param id wx id
         """
         """
-        ElementDialog.__init__(self, parent, title, label = _("Name of imagery group:"))
+        SimpleDialog.__init__(self, parent, title)
         
         
         self.element = gselect.Select(parent = self.panel, type = 'group',
         self.element = gselect.Select(parent = self.panel, type = 'group',
-                                          mapsets = [grass.gisenv()['MAPSET']],
-                                          size = globalvar.DIALOG_GSELECT_SIZE)
+                                      mapsets = [grass.gisenv()['MAPSET']],
+                                      size = globalvar.DIALOG_GSELECT_SIZE,
+                                      validator = SimpleValidator(callback = self.ValidatorCallback))
+        self.element.SetFocus()
         if group:
         if group:
             self.element.SetValue(group)
             self.element.SetValue(group)
         self.editGroup = wx.Button(parent = self.panel, id = wx.ID_ANY,
         self.editGroup = wx.Button(parent = self.panel, id = wx.ID_ANY,
                                    label = _("Create/edit group..."))
                                    label = _("Create/edit group..."))
         self.editGroup.Bind(wx.EVT_BUTTON, self.OnEditGroup)
         self.editGroup.Bind(wx.EVT_BUTTON, self.OnEditGroup)
-        self.PostInit()
-        
-        self.__Layout()
+
+        self.warning = _("Name of imagery group is missing.")
+        self._layout()
         self.SetMinSize(self.GetSize())
         self.SetMinSize(self.GetSize())
 
 
-    def __Layout(self):
+    def _layout(self):
         """!Do layout"""
         """!Do layout"""
+        self.dataSizer.Add(wx.StaticText(self.panel, id = wx.ID_ANY,
+                                         label = _("Name of imagery group:")),
+                           proportion = 0, flag = wx.EXPAND | wx.ALL, border = 5)
         self.dataSizer.Add(self.element, proportion = 0,
         self.dataSizer.Add(self.element, proportion = 0,
                       flag = wx.EXPAND | wx.ALL, border = 5)
                       flag = wx.EXPAND | wx.ALL, border = 5)
         self.dataSizer.Add(self.editGroup, proportion = 0,
         self.dataSizer.Add(self.editGroup, proportion = 0,
@@ -70,7 +76,7 @@ class IClassGroupDialog(ElementDialog):
 
 
     def GetGroup(self):
     def GetGroup(self):
         """!Returns selected group"""
         """!Returns selected group"""
-        return self.GetElement()
+        return self.element.GetValue()
         
         
     def OnEditGroup(self, event):
     def OnEditGroup(self, event):
         """!Launch edit group dialog"""
         """!Launch edit group dialog"""
@@ -82,32 +88,37 @@ class IClassGroupDialog(ElementDialog):
             self.element.SetValue(gr)
             self.element.SetValue(gr)
         dlg.Destroy()
         dlg.Destroy()
         
         
-class IClassMapDialog(ElementDialog):
+class IClassMapDialog(SimpleDialog):
     """!Dialog for adding raster/vector map"""
     """!Dialog for adding raster/vector map"""
     def __init__(self, parent, title, element):
     def __init__(self, parent, title, element):
         """!
         """!
-        Does post init and layout.
         
         
-        @param gui parent
+        @param parent gui parent
+        @param title dialog title
         @param element element type ('raster', 'vector')
         @param element element type ('raster', 'vector')
         """
         """
-        if element == 'raster':
-            label = _("Name of raster map:")
-        elif element == 'vector':
-            label = _("Name of vector map:")
-        
-        ElementDialog.__init__(self, parent, title = title, label = label)
-            
-        self.element = gselect.Select(parent = self.panel, type = element,
-                                      size = globalvar.DIALOG_GSELECT_SIZE)
         
         
-        self.PostInit()
+        SimpleDialog.__init__(self, parent, title = title)
         
         
-        self.__Layout()
+        self.elementType = element
+        self.element = gselect.Select(parent = self.panel, type = element,
+                                      size = globalvar.DIALOG_GSELECT_SIZE,
+                                      validator = SimpleValidator(callback = self.ValidatorCallback))
+        self.element.SetFocus()
+
+        self.warning = _("Name of map is missing.")
+        self._layout()
         self.SetMinSize(self.GetSize())
         self.SetMinSize(self.GetSize())
-        
-    def __Layout(self):
+
+    def _layout(self):
         """!Do layout"""
         """!Do layout"""
+        if self.elementType == 'raster':
+            label = _("Name of raster map:")
+        elif self.elementType == 'vector':
+            label = _("Name of vector map:")
+        self.dataSizer.Add(wx.StaticText(self.panel, id = wx.ID_ANY,
+                                         label = label),
+                           proportion = 0, flag = wx.EXPAND | wx.ALL, border = 5)
         self.dataSizer.Add(self.element, proportion = 0,
         self.dataSizer.Add(self.element, proportion = 0,
                       flag = wx.EXPAND | wx.ALL, border = 5)
                       flag = wx.EXPAND | wx.ALL, border = 5)
         
         
@@ -116,9 +127,9 @@ class IClassMapDialog(ElementDialog):
 
 
     def GetMap(self):
     def GetMap(self):
         """!Returns selected raster/vector map"""
         """!Returns selected raster/vector map"""
-        return self.GetElement()
-        
-        
+        return self.element.GetValue()
+
+
 class IClassCategoryManagerDialog(wx.Dialog):
 class IClassCategoryManagerDialog(wx.Dialog):
     """!Dialog for managing categories (classes).
     """!Dialog for managing categories (classes).
     
     

+ 24 - 12
gui/wxpython/mapswipe/dialogs.py

@@ -17,24 +17,27 @@ This program is free software under the GNU General Public License
 import wx
 import wx
 
 
 from core               import globalvar
 from core               import globalvar
-from gui_core.dialogs   import ElementDialog
+from gui_core.dialogs   import SimpleDialog
 from gui_core           import gselect
 from gui_core           import gselect
+from gui_core.widgets   import SimpleValidator
+from core.gcmd          import GMessage
 
 
-class SwipeMapDialog(ElementDialog):
+class SwipeMapDialog(SimpleDialog):
     """!Dialog used to select raster maps"""
     """!Dialog used to select raster maps"""
-    def __init__(self, parent, title = _("Select raster maps"), id =  wx.ID_ANY, first = None, second = None):
-        ElementDialog.__init__(self, parent, title, id = id, label = _("Name of top/left raster map:"))
+    def __init__(self, parent, title = _("Select raster maps"), first = None, second = None):
+        SimpleDialog.__init__(self, parent, title)
 
 
-        self.element = gselect.Select(parent = self.panel, type = 'raster',
-                                      size = globalvar.DIALOG_GSELECT_SIZE)
+        self.element1 = gselect.Select(parent = self.panel, type = 'raster',
+                                      size = globalvar.DIALOG_GSELECT_SIZE,
+                                      validator = SimpleValidator(callback = self.ValidatorCallback))
         
         
         self.element2 = gselect.Select(parent = self.panel, type = 'raster',
         self.element2 = gselect.Select(parent = self.panel, type = 'raster',
-                                       size = globalvar.DIALOG_GSELECT_SIZE)
-        
-        self.PostInit()
+                                       size = globalvar.DIALOG_GSELECT_SIZE,
+                                       validator = SimpleValidator(callback = self.ValidatorCallback))
         
         
+        self.element1.SetFocus()
         if first:
         if first:
-            self.element.SetValue(first)
+            self.element1.SetValue(first)
         if second:
         if second:
             self.element2.SetValue(second)
             self.element2.SetValue(second)
             
             
@@ -43,7 +46,10 @@ class SwipeMapDialog(ElementDialog):
 
 
     def _layout(self):
     def _layout(self):
         """!Do layout"""
         """!Do layout"""
-        self.dataSizer.Add(self.element, proportion = 0,
+        self.dataSizer.Add(wx.StaticText(self.panel, id = wx.ID_ANY,
+                                         label = _("Name of top/left raster map:")),
+                           proportion = 0, flag = wx.EXPAND | wx.ALL, border = 5)
+        self.dataSizer.Add(self.element1, proportion = 0,
                            flag = wx.EXPAND | wx.ALL, border = 1)
                            flag = wx.EXPAND | wx.ALL, border = 1)
  
  
         self.dataSizer.Add(wx.StaticText(parent = self.panel, id = wx.ID_ANY,
         self.dataSizer.Add(wx.StaticText(parent = self.panel, id = wx.ID_ANY,
@@ -56,7 +62,13 @@ class SwipeMapDialog(ElementDialog):
         self.panel.SetSizer(self.sizer)
         self.panel.SetSizer(self.sizer)
         self.sizer.Fit(self)
         self.sizer.Fit(self)
 
 
+    def ValidatorCallback(self, win):
+        if win == self.element1.GetTextCtrl():
+            GMessage(parent = self, message = _("Name of the first map is missing."))
+        else:
+            GMessage(parent = self, message = _("Name of the second map is missing."))
+
     def GetValues(self):
     def GetValues(self):
         """!Get raster maps"""
         """!Get raster maps"""
-        return (self.GetElement(), self.element2.GetValue())
+        return (self.element1.GetValue(), self.element2.GetValue())
 
 

+ 2 - 1
gui/wxpython/wxpythonlib.dox

@@ -94,7 +94,7 @@ available in GRASS 5 and GRASS 6.
 \subsection gui_core GUI core modules
 \subsection gui_core GUI core modules
 
 
 - gui_core::dialogs
 - gui_core::dialogs
- - dialogs::ElementDialog
+ - dialogs::SimpleDialog
  - dialogs::LocationDialog
  - dialogs::LocationDialog
  - dialogs::MapsetDialog
  - dialogs::MapsetDialog
  - dialogs::NewVectorDialog
  - dialogs::NewVectorDialog
@@ -166,6 +166,7 @@ available in GRASS 5 and GRASS 6.
 - gui_core::widgets
 - gui_core::widgets
  - widgets::ScrolledPanel
  - widgets::ScrolledPanel
  - widgets::NTCValidator
  - widgets::NTCValidator
+ - widgets::SimpleValidator
  - widgets::NumTextCtrl
  - widgets::NumTextCtrl
  - widgets::FloatSlider
  - widgets::FloatSlider
  - widgets::SymbolButton
  - widgets::SymbolButton