[GRASS-SVN] r72547 - in grass/trunk: gui/wxpython/dbmgr gui/wxpython/gui_core lib/gis

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Mar 24 04:09:29 PDT 2018


Author: martinl
Date: 2018-03-24 04:09:29 -0700 (Sat, 24 Mar 2018)
New Revision: 72547

Modified:
   grass/trunk/gui/wxpython/dbmgr/sqlbuilder.py
   grass/trunk/gui/wxpython/gui_core/forms.py
   grass/trunk/gui/wxpython/gui_core/gselect.py
   grass/trunk/lib/gis/parser_standard_options.c
Log:
wxGUI: implement widget for SQL WHERE params

Modified: grass/trunk/gui/wxpython/dbmgr/sqlbuilder.py
===================================================================
--- grass/trunk/gui/wxpython/dbmgr/sqlbuilder.py	2018-03-24 09:04:40 UTC (rev 72546)
+++ grass/trunk/gui/wxpython/dbmgr/sqlbuilder.py	2018-03-24 11:09:29 UTC (rev 72547)
@@ -46,7 +46,7 @@
     Base class for classes, which builds SQL statements.
     """
 
-    def __init__(self, parent, title, vectmap, modeChoices, id=wx.ID_ANY,
+    def __init__(self, parent, title, vectmap, modeChoices=[], id=wx.ID_ANY,
                  layer=1):
         wx.Frame.__init__(self, parent, id, title)
 
@@ -68,6 +68,7 @@
         self.layer = layer
         self.dbInfo = VectorDBInfo(self.vectmap)
         self.tablename = self.dbInfo.GetTable(self.layer)
+                
         self.driver, self.database = self.dbInfo.GetDbSettings(self.layer)
 
         self.colvalues = []     # array with unique values in selected column
@@ -130,7 +131,7 @@
         self.btn_clear.SetToolTipString(_("Set SQL statement to default"))
         self.btn_apply = wx.Button(parent=self.panel, id=wx.ID_APPLY)
         self.btn_apply.SetToolTipString(
-            _("Apply SQL statement in Attribute Table Manager"))
+            _("Apply SQL statement"))
         self.btn_close = wx.Button(parent=self.panel, id=wx.ID_CLOSE)
         self.btn_close.SetToolTipString(_("Close the dialog"))
 
@@ -230,18 +231,19 @@
         columnsizer.Add(self.list_columns, proportion=1,
                         flag=wx.EXPAND)
 
-        modesizer = wx.BoxSizer(wx.VERTICAL)
+        if modeChoices:
+            modesizer = wx.BoxSizer(wx.VERTICAL)
+            
+            self.mode = wx.RadioBox(parent=self.panel, id=wx.ID_ANY,
+                                    label=" %s " % _("Interactive insertion"),
+                                    choices=modeChoices,
+                                    style=wx.RA_SPECIFY_COLS,
+                                    majorDimension=1)
+            
+            self.mode.SetSelection(1)  # default 'values'
+            modesizer.Add(self.mode, proportion=1,
+                          flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND, border=5)
 
-        self.mode = wx.RadioBox(parent=self.panel, id=wx.ID_ANY,
-                                label=" %s " % _("Interactive insertion"),
-                                choices=modeChoices,
-                                style=wx.RA_SPECIFY_COLS,
-                                majorDimension=1)
-
-        self.mode.SetSelection(1)  # default 'values'
-        modesizer.Add(self.mode, proportion=1,
-                      flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND, border=5)
-
         # self.list_columns.SetMinSize((-1,130))
         # self.list_values.SetMinSize((-1,100))
 
@@ -302,12 +304,13 @@
         if showDbInfo:
             self.pagesizer.Add(databaseboxsizer,
                                flag=wx.ALL | wx.EXPAND, border=5)
+        if modeChoices:
+            self.pagesizer.Add(
+                modesizer,
+                proportion=0,
+                flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
+                border=5)
         self.pagesizer.Add(
-            modesizer,
-            proportion=0,
-            flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
-            border=5)
-        self.pagesizer.Add(
             self.hsizer,
             proportion=1,
             flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
@@ -329,7 +332,8 @@
         #
         # bindings
         #
-        self.mode.Bind(wx.EVT_RADIOBOX, self.OnMode)
+        if modeChoices:
+            self.mode.Bind(wx.EVT_RADIOBOX, self.OnMode)
         # self.text_sql.Bind(wx.EVT_ACTIVATE, self.OnTextSqlActivate)TODO
 
         self.btn_unique.Bind(wx.EVT_BUTTON, self.OnUniqueValues)
@@ -840,6 +844,52 @@
             'TRIM': ['TRIM (,)']
         }
 
+class SQLBuilderWhere(SQLBuilder):
+    """Class for building SELECT SQL WHERE statement"""
+
+    def __init__(self, parent, vectmap, id=wx.ID_ANY,
+                 layer=1):
+
+        title = _("GRASS SQL Builder (%(type)s) - <%(map)s>") % \
+                {'type': "WHERE", 'map': vectmap}
+
+        super(SQLBuilderWhere, self).__init__(
+            parent, title, vectmap, id=wx.ID_ANY, 
+            layer=layer)
+        
+    def OnClear(self, event):
+        self.text_sql.SetValue('')
+        
+    def OnApply(self, event):
+        self.parent.SetValue(self.text_sql.GetValue())
+
+        if self.close_onapply.IsChecked():
+            self.Destroy()
+
+        event.Skip()
+
+    def _add(self, element, value):
+        """Add element to the query
+
+        :param element: element to add (column, value)
+        """
+        sqlstr = self.text_sql.GetValue()
+        inspoint = self.text_sql.GetInsertionPoint()
+
+        newsqlstr = ''
+        if inspoint > 0 and sqlstr[inspoint-1] != ' ':
+            newsqlstr += ' '
+        newsqlstr += value
+        if inspoint < len(sqlstr):
+            newsqlstr += ' ' if sqlstr[inspoint] != ' ' else ''
+        
+        if newsqlstr:
+            self.text_sql.SetValue(sqlstr[:inspoint] + newsqlstr + sqlstr[inspoint:])
+            self.text_sql.SetInsertionPoint(inspoint + len(newsqlstr))
+                    
+        wx.CallAfter(self.text_sql.SetFocus)
+
+        
 if __name__ == "__main__":
     if len(sys.argv) not in [3, 4]:
         print(__doc__, file=sys.stderr)

Modified: grass/trunk/gui/wxpython/gui_core/forms.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/forms.py	2018-03-24 09:04:40 UTC (rev 72546)
+++ grass/trunk/gui/wxpython/gui_core/forms.py	2018-03-24 11:09:29 UTC (rev 72547)
@@ -240,7 +240,7 @@
 
             map = layer = None
             driver = db = None
-            if name in ('LayerSelect', 'ColumnSelect'):
+            if name in ('LayerSelect', 'ColumnSelect', 'SqlWhereSelect'):
                 if p.get('element', '') == 'vector':  # -> vector
                     # get map name
                     map = p.get('value', '')
@@ -325,7 +325,7 @@
 
                     if not cparams[map]['dbInfo']:
                         cparams[map]['dbInfo'] = gselect.VectorDBInfo(map)
-                    self.data[win.GetParent().InsertColumns] = {
+                    self.data[win.GetParent().SetData] = {
                         'vector': map, 'layer': layer,
                         'dbInfo': cparams[map]['dbInfo']}
                 else:  # table
@@ -397,6 +397,18 @@
                             'value', ''), 'mapset': pMapset.get(
                             'value', '')}
 
+            elif name == 'SqlWhereSelect':
+                if map:
+                    self.data[win.GetParent().SetData] = {
+                        'vector': map, 'layer': layer }
+                else:  # table
+                    if driver and db:
+                        self.data[win.GetParent().InsertTableColumns] = {
+                            'table': pTable.get('value'),
+                            'driver': driver, 'database': db}
+                    elif pTable:
+                        self.data[win.GetParent().InsertTableColumns] = {
+                            'table': pTable.get('value')}
 
 def UpdateDialog(parent, event, eventId, task):
     return UpdateThread(parent, event, eventId, task)
@@ -1394,7 +1406,8 @@
                                                'barscale',
                                                'northarrow',
                                                'datasource',
-                                               'datasource_layer'):
+                                               'datasource_layer',
+                                               'sql_query'):
                     multiple = p.get('multiple', False)
                     if p.get('age', '') == 'new':
                         mapsets = [grass.gisenv()['MAPSET'], ]
@@ -2060,6 +2073,17 @@
                             self.OnUpdateValues()  # TODO: replace by signal
 
                         self.win1.OnCheckItem = OnCheckItem
+                        
+                elif prompt == 'sql_query':
+                    win = gselect.SqlWhereSelect(
+                        parent=which_panel, param=p)
+                    p['wxId'] = [win.GetTextWin().GetId()]
+                    win.GetTextWin().Bind(wx.EVT_TEXT, self.OnSetValue)
+                    which_sizer.Add(
+                        win,
+                        proportion=0,
+                        flag=wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT,
+                        border=5)
 
             if self.parent.GetName() == 'MainFrame' and (
                     self._giface and hasattr(self._giface, "_model")):
@@ -2110,6 +2134,7 @@
         pDbase = None
         pLocation = None
         pMapset = None
+        pSqlWhere = []
         for p in self.task.params:
             if self.task.blackList['enabled'] and self.task.get_name() in self.task.blackList['items'] and \
                p.get('name', '') in self.task.blackList['items'][self.task.get_name()]['params']:
@@ -2157,6 +2182,8 @@
                 pLocation = p
             elif prompt == 'mapset':
                 pMapset = p
+            elif prompt == 'sql_query':
+                pSqlWhere.append(p)
 
         # collect ids
         pColumnIds = []
@@ -2168,7 +2195,10 @@
         pSigFileIds = []
         for p in pSigFile:
             pSigFileIds += p['wxId']
-
+        pSqlWhereIds = []
+        for p in pSqlWhere:
+            pSqlWhereIds += p['wxId']
+        
         # set wxId-bindings
         if pMap:
             pMap['wxId-bind'] = []
@@ -2175,10 +2205,13 @@
             if pLayer:
                 pMap['wxId-bind'] += pLayerIds
             pMap['wxId-bind'] += copy.copy(pColumnIds)
+            pMap['wxId-bind'] += copy.copy(pSqlWhereIds)
         if pLayer:
             for p in pLayer:
                 p['wxId-bind'] = copy.copy(pColumnIds)
+                p['wxId-bind'] += copy.copy(pSqlWhereIds)
 
+
         if pDriver and pTable:
             pDriver['wxId-bind'] = pTable['wxId']
 

Modified: grass/trunk/gui/wxpython/gui_core/gselect.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/gselect.py	2018-03-24 09:04:40 UTC (rev 72546)
+++ grass/trunk/gui/wxpython/gui_core/gselect.py	2018-03-24 11:09:29 UTC (rev 72547)
@@ -27,8 +27,9 @@
  - :class:`VectorCategorySelect`
  - :class:`SignatureSelect`
  - :class:`SeparatorSelect`
+ - :class:`SqlWhereSelect`
 
-(C) 2007-2014 by the GRASS Development Team
+(C) 2007-2018 by the GRASS Development Team
 
 This program is free software under the GNU General Public License
 (>=v2). Read the file COPYING that comes with GRASS for details.
@@ -74,7 +75,7 @@
 
 from gui_core.widgets import ManageSettingsWidget, CoordinatesValidator
 
-from core.gcmd import RunCommand, GError, GMessage, GWarning
+from core.gcmd import RunCommand, GError, GMessage, GWarning, GException
 from core.utils    import GetListOfLocations, GetListOfMapsets, \
     GetFormats, rasterFormatExtension, vectorFormatExtension
 from core.utils import GetSettingsPath, GetValidLayerName, ListSortLower
@@ -885,6 +886,8 @@
 
         :param layer: vector layer number
         """
+        if layer not in self.layers:
+            raise GException(_("No table linked to layer <{}>.".format(layer)))
         return self.layers[layer]['table']
 
     def GetDbSettings(self, layer):
@@ -2711,3 +2714,57 @@
                                               **kwargs)
         self.SetName("SeparatorSelect")
         self.SetItems(['pipe', 'comma', 'space', 'tab', 'newline'])
+
+
+class SqlWhereSelect(wx.Panel):
+
+    def __init__(self, parent, **kwargs):
+        """Widget to define SQL WHERE condition.
+
+        :param parent: parent window
+        """
+        super(SqlWhereSelect, self).__init__(parent=parent, id=wx.ID_ANY)
+        self.parent = parent
+
+        self.sqlField = wx.TextCtrl(parent=self, id=wx.ID_ANY,
+                                    size=globalvar.DIALOG_TEXTCTRL_SIZE)
+        self.GetChildren()[0].SetName("SqlWhereSelect")
+        icon = wx.Bitmap(
+            os.path.join(
+                globalvar.ICONDIR,
+                "grass",
+                "table.png"))
+        self.buttonInsSql = buttons.ThemedGenBitmapButton(
+            parent=self, id=wx.ID_ANY, bitmap=icon, size=globalvar.DIALOG_COLOR_SIZE)
+        self.buttonInsSql.Bind(wx.EVT_BUTTON, self._onClick)
+
+        self._doLayout()
+
+
+    def _doLayout(self):
+        self.dialogSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.dialogSizer.Add(self.sqlField,
+                             proportion=1,
+                             flag=wx.EXPAND)
+        self.dialogSizer.Add(self.buttonInsSql)
+        self.SetSizer(self.dialogSizer)
+
+    def GetTextWin(self):
+        return self.sqlField
+
+    def _onClick(self, event):
+        from dbmgr.sqlbuilder import SQLBuilderWhere
+        try:
+            win = SQLBuilderWhere(parent=self,
+                                  vectmap=self.vector_map,
+                                  layer=self.vector_layer)
+            win.Show()
+        except GException as e:
+            GMessage(parent=self.parent, message='{}'.format(e))
+        
+    def SetData(self, vector, layer):
+        self.vector_map = vector
+        self.vector_layer = int(layer) # TODO: support layer names
+
+    def SetValue(self, value):
+        self.sqlField.SetValue(value)

Modified: grass/trunk/lib/gis/parser_standard_options.c
===================================================================
--- grass/trunk/lib/gis/parser_standard_options.c	2018-03-24 09:04:40 UTC (rev 72546)
+++ grass/trunk/lib/gis/parser_standard_options.c	2018-03-24 11:09:29 UTC (rev 72547)
@@ -151,6 +151,7 @@
     case G_OPT_DB_WHERE:
 	Opt->key = "where";
 	Opt->type = TYPE_STRING;
+        Opt->gisprompt = "old,sql_query,sql_query";
 	Opt->key_desc = "sql_query";
 	Opt->required = NO;
 	Opt->label = _("WHERE conditions of SQL statement without 'where' keyword");



More information about the grass-commit mailing list