[GRASS-SVN] r38923 - grass/branches/releasebranch_6_4/gui/wxpython/gui_modules

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Aug 30 15:33:00 EDT 2009


Author: martinl
Date: 2009-08-30 15:32:58 -0400 (Sun, 30 Aug 2009)
New Revision: 38923

Modified:
   grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/dbm.py
   grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/gselect.py
   grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/sqlbuilder.py
Log:
wxGUI: changes in sqlbuilder merged from trunk/devbr6


Modified: grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/dbm.py
===================================================================
--- grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/dbm.py	2009-08-30 18:57:15 UTC (rev 38922)
+++ grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/dbm.py	2009-08-30 19:32:58 UTC (rev 38923)
@@ -74,6 +74,30 @@
     
     return value
 
+def createDbInfoDesc(panel, mapDBInfo, layer):
+    """!Create database connection information content"""
+    infoFlexSizer = wx.FlexGridSizer (cols=2, hgap=1, vgap=1)
+    infoFlexSizer.AddGrowableCol(1)
+    
+    infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label="Driver:"))
+    infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=mapDBInfo.layers[layer]['driver']))
+    infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label="Database:"))
+    infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=mapDBInfo.layers[layer]['database']))
+    infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label="Table:"))
+    infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=mapDBInfo.layers[layer]['table']))
+    infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label="Key:"))
+    infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=mapDBInfo.layers[layer]['key']))
+    
+    return infoFlexSizer
+
 class Log:
     """
     The log output is redirected to the status bar of the containing frame.
@@ -460,7 +484,10 @@
 
         # -> layers / tables description
         self.mapDBInfo = VectorDBInfo(self.vectmap)
-
+        
+        # sqlbuilder
+        self.builder = None
+        
         if len(self.mapDBInfo.layers.keys()) == 0:
             wx.MessageBox(parent=self.parent,
                           message=_("Database connection for vector map <%s> "
@@ -707,7 +734,7 @@
             dbBox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
                                           label=" %s " % _("Database connection"))
             dbSizer = wx.StaticBoxSizer(dbBox, wx.VERTICAL)
-            dbSizer.Add(item=self.__createDbInfoDesc(panel, layer),
+            dbSizer.Add(item=createDbInfoDesc(panel, self.mapDBInfo, layer),
                         proportion=1,
                         flag=wx.EXPAND | wx.ALL,
                         border=3)
@@ -1830,40 +1857,31 @@
         
         return (cols, where)
     
-    def __createDbInfoDesc(self, panel, layer):
-        """Create database connection information content"""
-        infoFlexSizer = wx.FlexGridSizer (cols=2, hgap=1, vgap=1)
-        infoFlexSizer.AddGrowableCol(1)
-        
-        infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                             label="Driver:"))
-        infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                             label=self.mapDBInfo.layers[layer]['driver']))
-        infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                             label="Database:"))
-        infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                             label=self.mapDBInfo.layers[layer]['database']))
-        infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                             label="Table:"))
-        infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                             label=self.mapDBInfo.layers[layer]['table']))
-        infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                             label="Key:"))
-        infoFlexSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                             label=self.mapDBInfo.layers[layer]['key']))
-
-        return infoFlexSizer
-        
     def OnCloseWindow(self, event):
         """Cancel button pressed"""
         self.Close()
         event.Skip()
-
+        
     def OnBuilder(self,event):
-        """SQL Builder button pressed"""
-        self.builder = sqlbuilder.SQLFrame(parent=self, id=wx.ID_ANY,
-                                           title=_("SQL Builder"),
-                                           vectmap=self.vectmap)
+        """!SQL Builder button pressed -> show the SQLBuilder dialog"""
+        if not self.builder:
+            self.builder = sqlbuilder.SQLFrame(parent = self, id = wx.ID_ANY,
+                                               title = _("SQL Builder"),
+                                               vectmap = self.vectmap,
+                                               evtheader = self.OnBuilderEvt)
+            self.builder.Show()
+        else:
+            self.builder.Raise()
+        
+    def OnBuilderEvt(self, event):
+        if event == 'apply':
+            sqlstr = self.builder.GetSQLStatement()
+            self.FindWindowById(self.layerPage[self.layer]['statement']).SetValue(sqlstr)
+            if self.builder.CloseOnApply():
+                self.builder = None
+        elif event == 'close':
+            self.builder = None
+        
     def OnTextEnter(self, event):
         pass
 

Modified: grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/gselect.py
===================================================================
--- grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/gselect.py	2009-08-30 18:57:15 UTC (rev 38922)
+++ grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/gselect.py	2009-08-30 19:32:58 UTC (rev 38923)
@@ -414,6 +414,40 @@
                 self.tables[table][name]['values'] = []
                 self.tables[table][name]['ids']    = []
         
+    def GetName(self):
+        """!Get vector name"""
+        return self.map
+    
+    def GetKeyColumn(self, layer):
+        """!Get key column of given layer
+        
+        @param layer vector layer number
+        """
+        return self.layers[layer]['key']
+    
+    def GetTable(self, layer):
+        """!Get table name of given layer
+        
+        @param layer vector layer number
+        """
+        return self.layers[layer]['table']
+    
+    def GetDbSettings(self, layer):
+        """!Get database settins
+
+        @param layer layer number
+        
+        @return (driver, database)
+        """
+        return self.layers[layer]['driver'], self.layers[layer]['database']
+    
+    def GetTableDesc(self, table):
+        """!Get table columns
+
+        @param table table name
+        """
+        return self.tables[table]
+
 class LayerSelect(wx.Choice):
     """
     Creates combo box for selecting data layers defined for vector.

Modified: grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/sqlbuilder.py
===================================================================
--- grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/sqlbuilder.py	2009-08-30 18:57:15 UTC (rev 38922)
+++ grass/branches/releasebranch_6_4/gui/wxpython/gui_modules/sqlbuilder.py	2009-08-30 19:32:58 UTC (rev 38923)
@@ -1,384 +1,457 @@
-"""
-MODULE:    sqlbuilder.py
+"""!
+ at package sqlbuilder.py
 
-CLASSES:
-    * SQLFrame
+ at brief GRASS SQL Builder
 
-PURPOSE:   GRASS SQL Builder
+Classes:
+ - SQLFrame
 
-           Usage:
-           sqlbuilder.py table_name
+ at todo Various updates are required...
 
-AUTHOR(S): GRASS Development Team
-           Original author: Jachym Cepicky <jachym.cepicky gmail.com>
-           Various updates: Martin Landa <landa.martin gmail.com>,
-                            Hamish Bowman <hamish_b yahoo com>
+Usage:
+ at code
+python sqlbuilder.py vector_map
+ at endcode
 
-COPYRIGHT: (C) 2007-2009 by the GRASS Development Team
+(C) 2007-2009 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.
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Jachym Cepicky <jachym.cepicky gmail.com> (original author)
+ at author Martin Landa <landa.martin gmail.com>,
+ at author Hamish Bowman <hamish_b yahoo com>
 """
 
-import wx
-import os,sys
+import os
+import sys
 import time
 
-from grass.script import core as grass
+### i18N
+import gettext
+gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
 
-import gcmd
 import globalvar
+if not os.getenv("GRASS_WXBUNDLED"):
+    globalvar.CheckForWx()
 
-imagePath = os.path.join(globalvar.ETCWXDIR)
-sys.path.append(imagePath)
-import images
-imagepath = images.__path__[0]
-sys.path.append(imagepath)
+import wx
 
+import grass.script as grass
+
+import dbm
+import gcmd
+
 class SQLFrame(wx.Frame):
     """!SQL Frame class"""
-    def __init__(self, parent, id, title, vectmap, qtype="select"):
-
+    def __init__(self, parent, title, vectmap, id = wx.ID_ANY,
+                 layer = 1, qtype = "select", evtheader = None):
+        
         wx.Frame.__init__(self, parent, id, title)
+        
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass_sql.ico'),
+                             wx.BITMAP_TYPE_ICO))
+        
+        self.parent = parent
+        self.evtHeader = evtheader
 
-        self.SetTitle(_("GRASS SQL Builder: %s") % (qtype.upper()))
-        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass_sql.ico'), wx.BITMAP_TYPE_ICO))
-
         #
         # variables
         #
-        self.vectmap = vectmap
+        self.vectmap = vectmap # fullname
         if not "@" in self.vectmap:
             self.vectmap = self.vectmap + "@" + grass.gisenv()['MAPSET']
-
         self.mapname, self.mapset = self.vectmap.split("@")
+        
+        # db info
+        self.layer = layer
+        self.dbInfo = dbm.VectorDBInfo(self.vectmap)
+        self.tablename = self.dbInfo.GetTable(self.layer)
+        self.driver, self.database = self.dbInfo.GetDbSettings(self.layer)
+        
+        self.qtype = qtype      # type of query: SELECT, UPDATE, DELETE, ...
+        self.colvalues = []     # array with unique values in selected column
 
-        #FIXME: pass layer number to v.db.connect ???
-        ret = gcmd.RunCommand('v.db.connect',
-                      quiet = True,
-                      read = True,
-                      flags = 'g',
-                      fs = '|',
-                      map = self.vectmap)
-        for line in ret.splitlines():
-            self.layer,self.tablename, self.column, self.database, self.driver =\
-                line.strip().split("|")
+        # set dialog title
+        self.SetTitle(_("GRASS SQL Builder (%s): vector map <%s>") % \
+                          (qtype.upper(), self.vectmap))
+        
+        self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
 
-        self.qtype = qtype      # type of the uqery: SELECT, UPDATE, DELETE, ...
-        self.column_names = []  # array with column names
-        self.columns = {}       # array with colum properties
-        self.colvalues = []     # array with uniqe values in selected column
-        self.heading = ""
-        self.parent = parent
+        # statusbar
+        self.statusbar = self.CreateStatusBar(number=1)
+        self.statusbar.SetStatusText(_("SQL statement not verified"), 0)
 
-        if self.qtype.lower()=="select":
-            self.heading = "SELECT * FROM %s WHERE" % self.tablename
-
-
-        # Init
-        self.GetColumns()
-
-
         #
-        # Buttons
+        # buttons
         #
-        self.btn_clear = wx.Button(self, -1, "Clear")
-        self.btn_verify = wx.Button(self, -1, "Verify")
-        #self.btn_help = wx.Button(self, -1, "Help")
-        # self.btn_load = wx.Button(self, -1, "Load")
-        # self.btn_save = wx.Button(self, -1, "Save")
-        self.btn_apply = wx.Button(self, -1, "Apply")
-        self.btn_close = wx.Button(self, -1, "Close")
-        self.btn_uniqe = wx.Button(self, -1, "Get all values")
-        self.btn_uniqesample = wx.Button(self, -1, "Get sample")
-
-        self.btn_is = wx.Button(self, -1, "=")
-        self.btn_isnot = wx.Button(self, -1, "!=")
-        self.btn_like = wx.Button(self, -1, "LIKE")
-        self.btn_gt = wx.Button(self, -1, ">")
-        self.btn_gtis = wx.Button(self, -1, ">=")
-        self.btn_lt = wx.Button(self, -1, "<")
-        self.btn_ltis = wx.Button(self, -1, "<=")
-        self.btn_or = wx.Button(self, -1, "OR")
-        self.btn_not = wx.Button(self, -1, "NOT")
-        self.btn_and = wx.Button(self, -1, "AND")
-        self.btn_brackets = wx.Button(self, -1, "()")
-        self.btn_prc = wx.Button(self, -1, "%")
-
+        self.btn_clear  = wx.Button(parent = self.panel, id = wx.ID_CLEAR)
+        self.btn_clear.SetToolTipString(_("Set SQL statement to default"))
+        self.btn_verify = wx.Button(parent = self.panel, id = wx.ID_ANY,
+                                    label = _("Verify"))
+        self.btn_verify.SetToolTipString(_("Verify SQL statement"))
+        # self.btn_help = wx.Button(self.panel, -1, "Help")
+        # self.btn_load = wx.Button(self.panel, -1, "Load")
+        # self.btn_save = wx.Button(self.panel, -1, "Save")
+        self.btn_apply  = wx.Button(parent = self.panel, id = wx.ID_APPLY)
+        self.btn_apply.SetToolTipString(_("Apply SQL statement and close the dialog"))
+        self.btn_close  = wx.Button(parent = self.panel, id = wx.ID_CLOSE)
+        self.btn_close.SetToolTipString(_("Close the dialog"))
+        self.btn_unique = wx.Button(parent = self.panel, id = wx.ID_ANY,
+                                    label = _("Get all values"))
+        self.btn_unique.Enable(False)
+        self.btn_uniquesample = wx.Button(parent = self.panel, id = wx.ID_ANY,
+                                          label = _("Get sample"))
+        self.btn_uniquesample.Enable(False)
+        
+        self.btn_lv = { 'is'    : ['=', ],
+                        'isnot' : ['!=', ],
+                        'like'  : ['LIKE', ],
+                        'gt'    : ['>', ],
+                        'ge'    : ['>=', ],
+                        'lt'    : ['<', ],
+                        'le'    : ['<=', ],
+                        'or'    : ['OR', ],
+                        'not'   : ['NOT', ],
+                        'and'   : ['AND', ],
+                        'brac'  : ['()', ],
+                        'prc'   : ['%', ] }
+        
+        for key, value in self.btn_lv.iteritems():
+            btn = wx.Button(parent = self.panel, id = wx.ID_ANY,
+                            label = value[0])
+            self.btn_lv[key].append(btn.GetId())
+        
         #
-        # Text labels
+        # text areas
         #
-        #self.label_headding = wx.StaticText(self, -1, '')
+        self.text_sql = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
+                                    value = '', size = (-1, 75),
+                                    style=wx.TE_MULTILINE)
+        if self.qtype.lower() == "select":
+            self.text_sql.SetValue("SELECT * FROM %s" % self.tablename)
+        self.text_sql.SetInsertionPointEnd()
+        wx.CallAfter(self.text_sql.SetFocus)
 
         #
-        # Textareas
+        # list boxes (columns, values)
         #
-        self.text_sql = wx.TextCtrl(self, -1, '', size=(-1,75),style=wx.TE_MULTILINE)
+        self.list_columns = wx.ListBox(parent = self.panel, id = wx.ID_ANY,
+                                       choices = self.dbInfo.GetColumns(self.tablename),
+                                       style = wx.LB_MULTIPLE)
+        self.list_values = wx.ListBox(parent = self.panel, id = wx.ID_ANY,
+                                      choices = self.colvalues,
+                                      style = wx.LB_MULTIPLE)
+        
+        self.radio_cv = wx.RadioBox(parent = self.panel, id = wx.ID_ANY,
+                                    label = " %s " % _("Add on double-click"),
+                                    choices = [_("columns"), _("values")])
+        self.radio_cv.SetSelection(1) # default 'values'
 
+        self.close_onapply = wx.CheckBox(parent = self.panel, id = wx.ID_ANY,
+                                         label = _("Close dialog on apply"))
+        self.close_onapply.SetValue(True)
+        
         #
-        # List Boxes
+        # bindings
         #
-        self.list_columns = wx.ListBox(self, -1, wx.DefaultPosition, (-1, -1), self.columns.keys(), wx.LB_MULTIPLE|wx.LB_SORT)
-        self.list_values = wx.ListBox(self, -1, wx.DefaultPosition, (-1, -1), self.colvalues, wx.LB_MULTIPLE|wx.LB_SORT)
+        self.btn_unique.Bind(wx.EVT_BUTTON,       self.OnUniqueValues)
+        self.btn_uniquesample.Bind(wx.EVT_BUTTON, self.OnSampleValues)
+        
+        for key, value in self.btn_lv.iteritems():
+            self.FindWindowById(value[1]).Bind(wx.EVT_BUTTON, self.OnAddMark)
+        
+        self.btn_close.Bind(wx.EVT_BUTTON,       self.OnClose)
+        self.btn_clear.Bind(wx.EVT_BUTTON,       self.OnClear)
+        self.btn_verify.Bind(wx.EVT_BUTTON,      self.OnVerify)
+        self.btn_apply.Bind(wx.EVT_BUTTON,       self.OnApply)
 
-        #
-        # Bindings
-        #
-        self.btn_uniqe.Bind(wx.EVT_BUTTON, self.GetUniqueValues)
-        self.btn_uniqesample.Bind(wx.EVT_BUTTON, self.GetSampleValues)
-        self.btn_is.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_isnot.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_like.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_gt.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_gtis.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_or.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_lt.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_ltis.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_not.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_brackets.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_prc.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_and.Bind(wx.EVT_BUTTON, self.AddMark)
-        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
-        self.btn_clear.Bind(wx.EVT_BUTTON, self.OnClear)
-        self.btn_verify.Bind(wx.EVT_BUTTON, self.OnVerify)
-        self.btn_apply.Bind(wx.EVT_BUTTON, self.OnApply)
+        self.list_columns.Bind(wx.EVT_LISTBOX,   self.OnAddColumn)
+        self.list_values.Bind(wx.EVT_LISTBOX,    self.OnAddValue)
+        
+        self.text_sql.Bind(wx.EVT_TEXT,          self.OnText)
+        
+        self.Bind(wx.EVT_CLOSE,                  self.OnClose)
 
-        self.list_columns.Bind(wx.EVT_LISTBOX, self.AddColumnName)
-        self.list_values.Bind(wx.EVT_LISTBOX, self.AddValue)
-
         self.__doLayout()
 
     def __doLayout(self):
-        databasebox = wx.StaticBox(self, -1, "Database connection")
-        databaseboxsizer = wx.StaticBoxSizer(databasebox,wx.VERTICAL)
-        dbstr = "Database: %s\n" % (self.database)
-        dbstr += "Driver: %s\n" % (self.driver)
-        dbstr += "Table: %s" % (self.tablename)
-        databaseboxsizer.Add(wx.StaticText(self,-1,dbstr), flag=wx.EXPAND)
+        """!Do dialog layout"""
+      
+        # dbInfo
+        databasebox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
+                                   label = " %s " % _("Database connection"))
+        databaseboxsizer = wx.StaticBoxSizer(databasebox, wx.VERTICAL)
+        databaseboxsizer.Add(item=dbm.createDbInfoDesc(self.panel, self.dbInfo, layer = self.layer),
+                             proportion=1,
+                             flag=wx.EXPAND | wx.ALL,
+                             border=3)
 
-        sqlbox = wx.StaticBox(self, -1, "%s" % self.heading)
-        sqlboxsizer = wx.StaticBoxSizer(sqlbox,wx.VERTICAL)
-        sqlboxsizer.Add(self.text_sql, flag=wx.EXPAND)
-
-
+        # sql box
+        sqlbox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
+                              label = " %s " % _("Query"))
+        sqlboxsizer = wx.StaticBoxSizer(sqlbox, wx.VERTICAL)
+        sqlboxsizer.Add(item = self.text_sql, flag = wx.EXPAND)
+        
         pagesizer = wx.BoxSizer(wx.VERTICAL)
-
-        buttonsizer1 = wx.GridBagSizer(2,2)
-        buttonsizer1.Add(self.btn_clear, (0,0))
-        buttonsizer1.Add(self.btn_verify, (0,1))
-        #buttonsizer1.Add(self.btn_help,  (0,2))
-        #buttonsizer1.Add(self.btn_load,  (0,2))
+        
+        # buttons
+        buttonsizer = wx.FlexGridSizer(cols = 4, hgap = 5, vgap = 5)
+        buttonsizer.Add(item = self.btn_clear)
+        buttonsizer.Add(item = self.btn_verify)
+        # buttonsizer1.Add(self.btn_help,  (0,2))
+        # buttonsizer1.Add(self.btn_load,  (0,2))
         # buttonsizer1.Add(self.btn_save,  (0,3))
-        buttonsizer1.Add(self.btn_apply, (0,2))
+        buttonsizer.Add(item = self.btn_apply)
+        buttonsizer.Add(item = self.btn_close)
+        
+        buttonsizer2 = wx.GridBagSizer(5, 5)
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['is'][1]), pos = (0,0))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['isnot'][1]), pos = (1,0))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['like'][1]), pos = (2, 0))
 
-        buttonsizer2 = wx.GridBagSizer(2, 2)
-        buttonsizer2.Add(self.btn_is, (0,0))
-        buttonsizer2.Add(self.btn_isnot, (1,0))
-        buttonsizer2.Add(self.btn_like, (2, 0))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['gt'][1]), pos = (0, 1))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['ge'][1]), pos = (1, 1))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['or'][1]), pos = (2, 1))
 
-        buttonsizer2.Add(self.btn_gt, (0, 1))
-        buttonsizer2.Add(self.btn_gtis, (1, 1))
-        buttonsizer2.Add(self.btn_or, (2, 1))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['lt'][1]), pos = (0, 2))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['le'][1]), pos = (1, 2))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['not'][1]), pos = (2, 2))
 
-        buttonsizer2.Add(self.btn_lt, (0, 2))
-        buttonsizer2.Add(self.btn_ltis, (1, 2))
-        buttonsizer2.Add(self.btn_not, (2, 2))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['brac'][1]), pos = (0, 3))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['prc'][1]), pos = (1, 3))
+        buttonsizer2.Add(item = self.FindWindowById(self.btn_lv['and'][1]), pos = (2, 3))
 
-        buttonsizer2.Add(self.btn_brackets, (0, 3))
-        buttonsizer2.Add(self.btn_prc, (1, 3))
-        buttonsizer2.Add(self.btn_and, (2, 3))
+        buttonsizer3 = wx.BoxSizer(wx.HORIZONTAL)
+        buttonsizer3.Add(item = self.btn_uniquesample, proportion = 0,
+                         flag = wx.ALIGN_CENTER_HORIZONTAL | wx.RIGHT, border = 5)
+        buttonsizer3.Add(item = self.btn_unique, proportion = 0,
+                         flag = wx.ALIGN_CENTER_HORIZONTAL)
 
-        buttonsizer3 = wx.GridSizer(4, 3, 3, 3)
-        buttonsizer3.Add(self.btn_apply,0,wx.RIGHT,5)
-        buttonsizer3.Add(self.btn_close,0,wx.RIGHT,5)
-
-        buttonsizer4 = wx.BoxSizer(wx.HORIZONTAL)
-        buttonsizer4.Add(self.btn_uniqesample,0,flag=wx.ALIGN_CENTER_HORIZONTAL,border=5)
-        buttonsizer4.Add(self.btn_uniqe,0,flag=wx.ALIGN_CENTER_HORIZONTAL,border=5)
-
-        hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
-        #hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
-
-        columnsbox = wx.StaticBox(self,-1,"Columns: ")
-        valuesbox = wx.StaticBox(self,-1,"Values: ")
-        #hsizer1.Add(wx.StaticText(self,-1, "Unique values: "), border=0, proportion=1)
-        columnsizer = wx.StaticBoxSizer(columnsbox,wx.VERTICAL)
-        valuesizer = wx.StaticBoxSizer(valuesbox,wx.VERTICAL)
-        columnsizer.Add(self.list_columns,  flag=wx.EXPAND,)
-        valuesizer.Add(self.list_values,  flag=wx.EXPAND)
-        self.list_columns.SetMinSize((-1,130))
-        self.list_values.SetMinSize((-1,100))
-        valuesizer.Add(buttonsizer4)
-        hsizer1.Add(columnsizer,border=0, proportion=1)
-        hsizer1.Add(valuesizer,border=0, proportion=1)
-
-        pagesizer.Add(databaseboxsizer,flag=wx.EXPAND,border=5)
-        pagesizer.Add(hsizer1, 1,flag=wx.EXPAND,border=5)
-        #pagesizer.Add(self.btn_uniqe,0,wx.ALIGN_LEFT|wx.TOP,border=5)
-        #pagesizer.Add(self.btn_uniqesample,0,wx.ALIGN_LEFT|wx.TOP,border=5)
-        pagesizer.Add(buttonsizer2, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, border=5)
-        pagesizer.Add(sqlboxsizer, flag=wx.EXPAND,border=5)
-        pagesizer.Add(buttonsizer1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, border=5)
-        pagesizer.Add(buttonsizer3, proportion=0, flag=wx.TOP, border=5)
-        self.SetAutoLayout(True)
-        self.SetSizer(pagesizer)
-        pagesizer.Fit(self)
-        #pagesizer.SetSizeHints(self)
+        radiosizer = wx.BoxSizer(wx.HORIZONTAL)
+        radiosizer.Add(item = self.radio_cv, proportion = 1,
+                       flag = wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND, border = 5)
+        
+        hsizer = wx.BoxSizer(wx.HORIZONTAL)
+        
+        columnsbox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
+                                  label = " %s " % _("Columns"))
+        valuesbox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
+                                 label = " %s " % _("Values"))
+        # hsizer1.Add(wx.StaticText(self.panel,-1, "Unique values: "), border=0, proportion=1)
+        columnsizer = wx.StaticBoxSizer(columnsbox, wx.VERTICAL)
+        valuesizer = wx.StaticBoxSizer(valuesbox, wx.VERTICAL)
+        columnsizer.Add(item = self.list_columns, proportion = 1,
+                        flag = wx.EXPAND)
+        columnsizer.Add(item = radiosizer, proportion = 0,
+                        flag = wx.TOP | wx.EXPAND, border = 5)
+        valuesizer.Add(item = self.list_values, proportion = 1,
+                       flag = wx.EXPAND)
+        # self.list_columns.SetMinSize((-1,130))
+        # self.list_values.SetMinSize((-1,100))
+        valuesizer.Add(item = buttonsizer3, proportion = 0,
+                       flag = wx.TOP, border = 5)
+        hsizer.Add(item = columnsizer, proportion = 1,
+                   flag = wx.EXPAND)
+        hsizer.Add(item = valuesizer, proportion = 1,
+                   flag = wx.EXPAND)
+        
+        pagesizer.Add(item = databaseboxsizer,
+                      flag = wx.ALL | wx.EXPAND, border = 5)
+        pagesizer.Add(item = hsizer, proportion = 1,
+                      flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
+        # pagesizer.Add(self.btn_uniqe,0,wx.ALIGN_LEFT|wx.TOP,border=5)
+        # pagesizer.Add(self.btn_uniqesample,0,wx.ALIGN_LEFT|wx.TOP,border=5)
+        pagesizer.Add(item = buttonsizer2, proportion = 0,
+                      flag = wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM, border = 5)
+        pagesizer.Add(item = sqlboxsizer, proportion = 0,
+                      flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
+        pagesizer.Add(item = buttonsizer, proportion = 0,
+                      flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
+        pagesizer.Add(item = self.close_onapply, proportion = 0,
+                      flag = wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
+        
+        self.panel.SetAutoLayout(True)
+        self.panel.SetSizer(pagesizer)
+        pagesizer.Fit(self.panel)
+        
         self.Layout()
-        self.Show(True)
-
-    def GetColumns(self):
-        """!Get columns"""
-        ret = gcmd.RunCommand('db.describe',
-                              quiet = True,
-                              read = True,
-                              flags = 'c',
-                              table = self.tablename,
-                              database = self.database,
-                              driver = self.driver)
+        self.SetMinSize((660, 525))
         
-        for line in ret.splitlines():
-            # skip ncols and nrows lines
-            linetype = line.strip().split(":")[0]
-            if linetype == "ncols" or linetype == "nrows":
-                continue
-
-            num, name, ctype, length = line.strip().split(":")
-            name.strip()
-            #self.columns_names.append(name)
-            self.columns[name] = {'type' : ctype}
-
-
-    def GetUniqueValues(self,event,justsample=False):
+    def OnUniqueValues(self, event, justsample = False):
+        """!Get unique values"""
         vals = []
         try:
             idx = self.list_columns.GetSelections()[0]
+            column = self.list_columns.GetString(idx)
         except:
+            self.list_values.Clear()
             return
+        
         self.list_values.Clear()
-        column = self.list_columns.GetString(idx)
+        
+        querystring = "SELECT %s FROM %s" % (column, self.tablename)
+        
+        cmd = gcmd.Command(['db.select',
+                            '-c',
+                            'table=%s' % self.tablename,
+                            'sql=%s' % querystring,
+                            'database=%s' % self.database,
+                            'driver=%s' % self.driver])
         i = 0
-        querystring = "SELECT %s FROM %s" % (column, self.tablename)
-
-        ret = gcmd.RunCommand('db.select',
-                              read = True,
-                              quiet = True,
-                              flags = 'c',
-                              database = self.database,
-                              driver = self.driver,
-                              sql = querystring)
-
-        for line in ret.splitlines():
+        for line in cmd.ReadStdOutput():
             if justsample and i < 256 or \
                not justsample:
-                self.list_values.Insert(line.strip(),0)
+                self.list_values.Append(line.strip())
             else:
                 break
-            i += 1
+            i += 0
+        
+    def OnSampleValues(self, event):
+        """!Get sample values"""
+        self.OnUniqueValues(None, True)
 
-    def GetSampleValues(self,event):
-        self.GetUniqueValues(None,True)
-
-    def AddColumnName(self,event):
-        idx = self.list_columns.GetSelections()[0]
-        column = self.list_columns.GetString(idx)
-        self.__addSomething(column)
-
-    def AddValue(self,event):
+    def OnAddColumn(self, event):
+        """!Add column name to the query"""
+        idx = self.list_columns.GetSelections()
+        for i in idx:
+            column = self.list_columns.GetString(i)
+            self.__Add(element = 'column', value = column)
+        
+        if not self.btn_uniquesample.IsEnabled():
+            self.btn_uniquesample.Enable(True)
+            self.btn_unique.Enable(True)
+        
+    def OnAddValue(self, event):
+        """!Add value"""
         idx = self.list_values.GetSelections()[0]
         value = self.list_values.GetString(idx)
         idx = self.list_columns.GetSelections()[0]
         column = self.list_columns.GetString(idx)
-
-        if self.columns[column]['type'].lower().find("chara") > -1:
+        
+        ctype = self.dbInfo.GetTableDesc(self.dbInfo.GetTable(self.layer))[column]['type']
+        
+        if ctype == 'character':
             value = "'%s'" % value
-        self.__addSomething(value)
+        
+        self.__Add(element = 'value', value = value)
 
-    def AddMark(self,event):
-        if event.GetId() == self.btn_is.GetId(): mark = "="
-        elif event.GetId() == self.btn_isnot.GetId(): mark = "!="
-        elif event.GetId() == self.btn_like.GetId(): mark = "LIKE"
-        elif event.GetId() == self.btn_gt.GetId(): mark = ">"
-        elif event.GetId() == self.btn_gtis.GetId(): mark = ">="
-        elif event.GetId() == self.btn_lt.GetId(): mark = "<"
-        elif event.GetId() == self.btn_ltis.GetId(): mark =  "<="
-        elif event.GetId() == self.btn_or.GetId(): mark =  "OR"
-        elif event.GetId() == self.btn_not.GetId(): mark = "NOT"
-        elif event.GetId() == self.btn_and.GetId(): mark = "AND"
-        elif event.GetId() == self.btn_brackets.GetId(): mark = "()"
-        elif event.GetId() == self.btn_prc.GetId(): mark = "%"
-        self.__addSomething(mark)
+    def OnAddMark(self, event):
+        """!Add mark"""
+        mark = None
+        for key, value in self.btn_lv.iteritems():
+            if event.GetId() == value[1]:
+                mark = value[0]
+                break
+        
+        self.__Add(element = 'mark', value = mark)
 
+    def __Add(self, element, value):
+        """!Add element to the query
 
-    def __addSomething(self,what):
+        @param element element to add (column, value)
+        """
         sqlstr = self.text_sql.GetValue()
         newsqlstr = ''
-        position = self.text_sql.GetPosition()[0]
-        selection = self.text_sql.GetSelection()
+        if element == 'column':
+            if self.radio_cv.GetSelection() == 0: # -> column
+                idx1 = len('select')
+                idx2 = sqlstr.lower().find('from')
+                colstr = sqlstr[idx1:idx2].strip()
+                if colstr == '*':
+                    cols = []
+                else:
+                    cols = colstr.split(',')
+                if value in cols:
+                        cols.remove(value)
+                else:
+                    cols.append(value)
+                
+                if len(cols) < 1:
+                    cols = ['*',]
+                
+                newsqlstr = 'SELECT ' + ','.join(cols) + ' ' + sqlstr[idx2:]
+            else: # -> where
+                newsqlstr = sqlstr
+                if sqlstr.lower().find('where') < 0:
+                    newsqlstr += ' WHERE'
+                
+                newsqlstr += ' ' + value
+        
+        elif element == 'value':
+            newsqlstr = sqlstr + ' ' + value
+        elif element == 'mark':
+            newsqlstr = sqlstr + ' ' + value
+        
+        if newsqlstr:
+            self.text_sql.SetValue(newsqlstr)
 
-        newsqlstr = sqlstr[:position]
-        try:
-            if newsqlstr[-1] != " ":
-                newsqlstr += " "
-        except:
-            pass
+    def GetSQLStatement(self):
+        """!Return SQL statement"""
+        return self.text_sql.GetValue().strip().replace("\n"," ")
+    
+    def CloseOnApply(self):
+        """!Return True if the dialog will be close on apply"""
+        return self.close_onapply.IsChecked()
+    
+    def OnText(self, event):
+        """Query string changed"""
+        if len(self.text_sql.GetValue()) > 0:
+            self.btn_verify.Enable(True)
+        else:
+            self.btn_verify.Enable(False)
+        
+    def OnApply(self, event):
+        """Apply button pressed"""
+        if self.evtHeader:
+            self.evtHeader(event = 'apply')
 
-        newsqlstr += what
-        newsqlstr += " "+sqlstr[position:]
+        if self.close_onapply.IsChecked():
+            self.Destroy()
+            
+        event.Skip()
+    
+    def OnVerify(self, event):
+        """!Verify button pressed"""
+        ret, msg = gcmd.RunCommand('db.select',
+                                   getErrorMsg = True,
+                                   table = self.tablename,
+                                   sql = self.text_sql.GetValue(),
+                                   flags = 't',
+                                   driver = self.driver,
+                                   database = self.database)
 
-        self.text_sql.SetValue(newsqlstr)
-        # FIXME: cursor position is messed up
-        #   see also   http://trac.wxwidgets.org/ticket/10051
-        #DEBUG: print "before: %d" % (position)
-        self.text_sql.SetInsertionPoint(position)
-        #? self.text_sql.SetInsertionPoint(position+len(what))
-        #? self.text_sql.SetInsertionPointEnd()
-        #DEBUG: print "len(what)=%d" % (len(what))
-        #DEBUG: print "after: %d" % (self.text_sql.GetPosition()[0])
-        #DEBUG: print " "
+        if ret != 0 and msg:
+            self.statusbar.SetStatusText(_("SQL statement is not valid"), 0)
+            wx.MessageBox(parent=self,
+                          message=_("SQL statement is not valid.\n\n%s") % msg,
+                          caption=_("Warning"), style=wx.OK | wx.ICON_WARNING | wx.CENTRE)
+        else:
+            self.statusbar.SetStatusText(_("SQL statement is valid"), 0)
 
-    def OnApply(self,event):
-        if self.parent:
-            try:
-                self.parent.text_query.SetValue= self.text_sql.GetValue().strip().replace("\n"," ")
-            except:
-                pass
-
-    def OnVerify(self,event):
-        if self.text_sql.GetValue():
-            querystring = "SELECT * FROM %s WHERE %s" % \
-                          (self.tablename,
-                           self.text_sql.GetValue().strip().replace("\n"," "))
-            # FIXME: LOG
-            # print self.text_sql.GetValue().strip().replace("\n"," "), "not correct!"
-
-            print "Testing [%s] ..." % (querystring)
-            ret, msg = gcmd.RunCommand('db.select',
-                                  getErrorMsg = True,
-                                  verbose = True,
-                                  flags = 't',
-                                  driver = self.driver,
-                                  database = self.database,
-                                  sql = querystring)
-            print msg, " "
-            if ret == 0:
-                pass
-
     def OnClear(self, event):
-        self.text_sql.SetValue("")
-
-    def OnClose(self,event):
+        """!Clear button pressed"""
+        if self.qtype.lower() == "select":
+            self.text_sql.SetValue("SELECT * FROM %s" % self.tablename)
+        else:
+            self.text_sql.SetValue("")
+    
+    def OnClose(self, event):
+        """!Close button pressed"""
+        if self.evtHeader:
+            self.evtHeader(event = 'close')
         self.Destroy()
 
+        event.Skip()
+        
 if __name__ == "__main__":
-
     if len(sys.argv) != 2:
         print >>sys.stderr, __doc__
         sys.exit()
-
+    
     app = wx.App(0)
-    sqlb = SQLFrame(None, -1, 'SQL Builder',sys.argv[1])
+    sqlb = SQLFrame(parent = None, title = _('SQL Builder'), vectmap = sys.argv[1])
+    sqlb.Show()
+    
     app.MainLoop()
-
-



More information about the grass-commit mailing list