GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
dbmgr/dialogs.py
Go to the documentation of this file.
1 """!
2 @package dbmgr.dialogs
3 
4 @brief DBM-related dialogs
5 
6 List of classes:
7  - dialogs::DisplayAttributesDialog
8  - dialogs::ModifyTableRecord
9 
10 (C) 2007-2011 by the GRASS Development Team
11 
12 This program is free software under the GNU General Public License
13 (>=v2). Read the file COPYING that comes with GRASS for details.
14 
15 @author Martin Landa <landa.martin gmail.com>
16 """
17 
18 import os
19 import types
20 
21 from core import globalvar
22 import wx
23 import wx.lib.scrolledpanel as scrolled
24 
25 from core.gcmd import RunCommand, GError
26 from core.debug import Debug
27 from core.settings import UserSettings
28 from dbmgr.vinfo import VectorDBInfo
29 from gui_core.widgets import IntegerValidator, FloatValidator
30 
31 class DisplayAttributesDialog(wx.Dialog):
32  def __init__(self, parent, map,
33  query = None, cats = None, line = None,
34  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
35  pos = wx.DefaultPosition,
36  action = "add", ignoreError = False):
37  """!Standard dialog used to add/update/display attributes linked
38  to the vector map.
39 
40  Attribute data can be selected based on layer and category number
41  or coordinates.
42 
43  @param parent
44  @param map vector map
45  @param query query coordinates and distance (used for v.edit)
46  @param cats {layer: cats}
47  @param line feature id (requested for cats)
48  @param style
49  @param pos
50  @param action (add, update, display)
51  @param ignoreError True to ignore errors
52  """
53  self.parent = parent # mapdisplay.BufferedWindow
54  self.map = map
55  self.action = action
56 
57  # ids/cats of selected features
58  # fid : {layer : cats}
59  self.cats = {}
60  self.fid = -1 # feature id
61 
62  # get layer/table/column information
63  self.mapDBInfo = VectorDBInfo(self.map)
64 
65  layers = self.mapDBInfo.layers.keys() # get available layers
66 
67  # check if db connection / layer exists
68  if len(layers) <= 0:
69  if not ignoreError:
70  dlg = wx.MessageDialog(parent = self.parent,
71  message = _("No attribute table found.\n\n"
72  "Do you want to create a new attribute table "
73  "and defined a link to vector map <%s>?") % self.map,
74  caption = _("Create table?"),
75  style = wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
76  if dlg.ShowModal() == wx.ID_YES:
77  lmgr = self.parent.lmgr
78  lmgr.OnShowAttributeTable(event = None, selection = 'layers')
79 
80  dlg.Destroy()
81 
82  self.mapDBInfo = None
83 
84  wx.Dialog.__init__(self, parent = self.parent, id = wx.ID_ANY,
85  title = "", style = style, pos = pos)
86 
87  # dialog body
88  mainSizer = wx.BoxSizer(wx.VERTICAL)
89 
90  # notebook
91  self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
92 
93  self.closeDialog = wx.CheckBox(parent = self, id = wx.ID_ANY,
94  label = _("Close dialog on submit"))
95  self.closeDialog.SetValue(True)
96  if self.action == 'display':
97  self.closeDialog.Enable(False)
98 
99  # feature id (text/choice for duplicates)
100  self.fidMulti = wx.Choice(parent = self, id = wx.ID_ANY,
101  size = (150, -1))
102  self.fidMulti.Bind(wx.EVT_CHOICE, self.OnFeature)
103  self.fidText = wx.StaticText(parent = self, id = wx.ID_ANY)
104 
105  self.noFoundMsg = wx.StaticText(parent = self, id = wx.ID_ANY,
106  label = _("No attributes found"))
107 
108  self.UpdateDialog(query = query, cats = cats)
109 
110  # set title
111  if self.action == "update":
112  self.SetTitle(_("Update attributes"))
113  elif self.action == "add":
114  self.SetTitle(_("Define attributes"))
115  else:
116  self.SetTitle(_("Display attributes"))
117 
118  # buttons
119  btnCancel = wx.Button(self, wx.ID_CANCEL)
120  btnReset = wx.Button(self, wx.ID_UNDO, _("&Reload"))
121  btnSubmit = wx.Button(self, wx.ID_OK, _("&Submit"))
122  if self.action == 'display':
123  btnSubmit.Enable(False)
124 
125  btnSizer = wx.StdDialogButtonSizer()
126  btnSizer.AddButton(btnCancel)
127  btnSizer.AddButton(btnReset)
128  btnSizer.SetNegativeButton(btnReset)
129  btnSubmit.SetDefault()
130  btnSizer.AddButton(btnSubmit)
131  btnSizer.Realize()
132 
133  mainSizer.Add(item = self.noFoundMsg, proportion = 0,
134  flag = wx.EXPAND | wx.ALL, border = 5)
135  mainSizer.Add(item = self.notebook, proportion = 1,
136  flag = wx.EXPAND | wx.ALL, border = 5)
137  fidSizer = wx.BoxSizer(wx.HORIZONTAL)
138  fidSizer.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY,
139  label = _("Feature id:")),
140  proportion = 0, border = 5,
141  flag = wx.ALIGN_CENTER_VERTICAL)
142  fidSizer.Add(item = self.fidMulti, proportion = 0,
143  flag = wx.EXPAND | wx.ALL, border = 5)
144  fidSizer.Add(item = self.fidText, proportion = 0,
145  flag = wx.EXPAND | wx.ALL, border = 5)
146  mainSizer.Add(item = fidSizer, proportion = 0,
147  flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 5)
148  mainSizer.Add(item = self.closeDialog, proportion = 0, flag = wx.EXPAND | wx.LEFT | wx.RIGHT,
149  border = 5)
150  mainSizer.Add(item = btnSizer, proportion = 0,
151  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
152 
153  # bindigs
154  btnReset.Bind(wx.EVT_BUTTON, self.OnReset)
155  btnSubmit.Bind(wx.EVT_BUTTON, self.OnSubmit)
156  btnCancel.Bind(wx.EVT_BUTTON, self.OnClose)
157  self.Bind(wx.EVT_CLOSE, self.OnClose)
158 
159  self.SetSizer(mainSizer)
160  mainSizer.Fit(self)
161 
162  # set min size for dialog
163  w, h = self.GetBestSize()
164  w += 50
165  if h < 200:
166  self.SetMinSize((w, 200))
167  else:
168  self.SetMinSize((w, h))
169 
170  if self.notebook.GetPageCount() == 0:
171  Debug.msg(2, "DisplayAttributesDialog(): Nothing found!")
172  ### self.mapDBInfo = None
173 
174  def __SelectAttributes(self, layer):
175  """!Select attributes"""
176  pass
177 
178  def OnSQLStatement(self, event):
179  """!Update SQL statement"""
180  pass
181 
182  def IsFound(self):
183  """!Check for status
184 
185  @return True on attributes found
186  @return False attributes not found
187  """
188  return bool(self.notebook.GetPageCount())
189 
190  def GetSQLString(self, updateValues = False):
191  """!Create SQL statement string based on self.sqlStatement
192 
193  Show error message when invalid values are entered.
194 
195  If updateValues is True, update dataFrame according to values
196  in textfields.
197  """
198  sqlCommands = []
199  # find updated values for each layer/category
200  for layer in self.mapDBInfo.layers.keys(): # for each layer
201  table = self.mapDBInfo.GetTable(layer)
202  key = self.mapDBInfo.GetKeyColumn(layer)
203  columns = self.mapDBInfo.GetTableDesc(table)
204  for idx in range(len(columns[key]['values'])): # for each category
205  updatedColumns = []
206  updatedValues = []
207  for name in columns.keys():
208  if name == key:
209  cat = columns[name]['values'][idx]
210  continue
211  ctype = columns[name]['ctype']
212  value = columns[name]['values'][idx]
213  id = columns[name]['ids'][idx]
214  try:
215  newvalue = self.FindWindowById(id).GetValue()
216  except:
217  newvalue = self.FindWindowById(id).GetLabel()
218 
219  if newvalue:
220  try:
221  if ctype == int:
222  newvalue = int(newvalue)
223  elif ctype == float:
224  newvalue = float(newvalue)
225  except ValueError:
226  GError(parent = self,
227  message = _("Column <%(col)s>: Value '%(value)s' needs to be entered as %(type)s.") % \
228  {'col' : name,
229  'value' : str(newvalue),
230  'type' : columns[name]['type'].lower()},
231  showTraceback = False)
232  sqlCommands.append(None)
233  continue
234  else:
235  if self.action == 'add':
236  continue
237 
238  if newvalue != value:
239  updatedColumns.append(name)
240  if not newvalue:
241  updatedValues.append('NULL')
242  else:
243  if ctype != str:
244  updatedValues.append(str(newvalue))
245  else:
246  updatedValues.append("'" + str(newvalue) + "'")
247  columns[name]['values'][idx] = newvalue
248 
249  if self.action != "add" and len(updatedValues) == 0:
250  continue
251 
252  if self.action == "add":
253  sqlString = "INSERT INTO %s (%s," % (table, key)
254  else:
255  sqlString = "UPDATE %s SET " % table
256 
257  for idx in range(len(updatedColumns)):
258  name = updatedColumns[idx]
259  if self.action == "add":
260  sqlString += name + ","
261  else:
262  sqlString += name + "=" + updatedValues[idx] + ","
263 
264  sqlString = sqlString[:-1] # remove last comma
265 
266  if self.action == "add":
267  sqlString += ") VALUES (%s," % cat
268  for value in updatedValues:
269  sqlString += str(value) + ","
270  sqlString = sqlString[:-1] # remove last comma
271  sqlString += ")"
272  else:
273  sqlString += " WHERE cat=%s" % cat
274  sqlCommands.append(sqlString)
275  # for each category
276  # for each layer END
277 
278  Debug.msg(3, "DisplayAttributesDialog.GetSQLString(): %s" % sqlCommands)
279 
280  return sqlCommands
281 
282  def OnReset(self, event = None):
283  """!Reset form"""
284  for layer in self.mapDBInfo.layers.keys():
285  table = self.mapDBInfo.layers[layer]["table"]
286  key = self.mapDBInfo.layers[layer]["key"]
287  columns = self.mapDBInfo.tables[table]
288  for idx in range(len(columns[key]['values'])):
289  for name in columns.keys():
290  type = columns[name]['type']
291  value = columns[name]['values'][idx]
292  if value is None:
293  value = ''
294  try:
295  id = columns[name]['ids'][idx]
296  except IndexError:
297  id = wx.NOT_FOUND
298 
299  if name != key and id != wx.NOT_FOUND:
300  self.FindWindowById(id).SetValue(str(value))
301 
302  def OnClose(self, event):
303  """!Closes dialog and removes query layer.
304  """
305  frame = self.parent.parent
306  frame.dialogs['attributes'] = None
307  if hasattr(self, "digit"):
308  self.parent.digit.GetDisplay().SetSelected([])
309  if frame.IsAutoRendered():
310  self.parent.UpdateMap(render = False)
311  elif frame.IsAutoRendered():
312  frame.RemoveQueryLayer()
313  self.parent.UpdateMap(render = True)
314 
315  self.Destroy()
316 
317  def OnSubmit(self, event):
318  """!Submit records"""
319  close = True
320  enc = UserSettings.Get(group = 'atm', key = 'encoding', subkey = 'value')
321  if not enc and 'GRASS_DB_ENCODING' in os.environ:
322  enc = os.environ['GRASS_DB_ENCODING']
323 
324  for sql in self.GetSQLString(updateValues = True):
325  if not sql:
326  close = False
327  continue
328  if enc:
329  sql = sql.encode(enc)
330 
331  RunCommand('db.execute',
332  parent = self,
333  quiet = True,
334  stdin = sql)
335 
336  if close and self.closeDialog.IsChecked():
337  self.OnClose(event)
338 
339  def OnFeature(self, event):
340  self.fid = int(event.GetString())
341  self.UpdateDialog(cats = self.cats, fid = self.fid)
342 
343  def GetCats(self):
344  """!Get id of selected vector object or 'None' if nothing selected
345 
346  @param id if true return ids otherwise cats
347  """
348  if self.fid < 0:
349  return None
350 
351  return self.cats[self.fid]
352 
353  def GetFid(self):
354  """!Get selected feature id"""
355  return self.fid
356 
357  def UpdateDialog(self, map = None, query = None, cats = None, fid = -1,
358  action = None):
359  """!Update dialog
360 
361  @param map name of vector map
362  @param query
363  @param cats
364  @param fid feature id
365  @param action add, update, display or None
366 
367  @return True if updated
368  @return False
369  """
370  if action:
371  self.action = action
372  if action == 'display':
373  enabled = False
374  else:
375  enabled = True
376  self.closeDialog.Enable(enabled)
377  self.FindWindowById(wx.ID_OK).Enable(enabled)
378 
379  if map:
380  self.map = map
381  # get layer/table/column information
382  self.mapDBInfo = VectorDBInfo(self.map)
383 
384  if not self.mapDBInfo:
385  return False
386 
387  self.mapDBInfo.Reset()
388 
389  layers = self.mapDBInfo.layers.keys() # get available layers
390 
391  # id of selected line
392  if query: # select by position
393  data = self.mapDBInfo.SelectByPoint(query[0],
394  query[1])
395  self.cats = {}
396  if data and 'Layer' in data:
397  idx = 0
398  for layer in data['Layer']:
399  layer = int(layer)
400  if data['Id'][idx] is not None:
401  tfid = int(data['Id'][idx])
402  else:
403  tfid = 0 # Area / Volume
404  if not tfid in self.cats:
405  self.cats[tfid] = {}
406  if not layer in self.cats[tfid]:
407  self.cats[tfid][layer] = []
408  cat = int(data['Category'][idx])
409  self.cats[tfid][layer].append(cat)
410  idx += 1
411  else:
412  self.cats = cats
413 
414  if fid > 0:
415  self.fid = fid
416  elif len(self.cats.keys()) > 0:
417  self.fid = self.cats.keys()[0]
418  else:
419  self.fid = -1
420 
421  if len(self.cats.keys()) == 1:
422  self.fidMulti.Show(False)
423  self.fidText.Show(True)
424  if self.fid > 0:
425  self.fidText.SetLabel("%d" % self.fid)
426  else:
427  self.fidText.SetLabel(_("Unknown"))
428  else:
429  self.fidMulti.Show(True)
430  self.fidText.Show(False)
431  choices = []
432  for tfid in self.cats.keys():
433  choices.append(str(tfid))
434  self.fidMulti.SetItems(choices)
435  self.fidMulti.SetStringSelection(str(self.fid))
436 
437  # reset notebook
438  self.notebook.DeleteAllPages()
439 
440  for layer in layers: # for each layer
441  if not query: # select by layer/cat
442  if self.fid > 0 and layer in self.cats[self.fid]:
443  for cat in self.cats[self.fid][layer]:
444  nselected = self.mapDBInfo.SelectFromTable(layer,
445  where = "%s=%d" % \
446  (self.mapDBInfo.layers[layer]['key'],
447  cat))
448  else:
449  nselected = 0
450 
451  # if nselected <= 0 and self.action != "add":
452  # continue # nothing selected ...
453 
454  if self.action == "add":
455  if nselected <= 0:
456  if layer in self.cats[self.fid]:
457  table = self.mapDBInfo.layers[layer]["table"]
458  key = self.mapDBInfo.layers[layer]["key"]
459  columns = self.mapDBInfo.tables[table]
460  for name in columns.keys():
461  if name == key:
462  for cat in self.cats[self.fid][layer]:
463  self.mapDBInfo.tables[table][name]['values'].append(cat)
464  else:
465  self.mapDBInfo.tables[table][name]['values'].append(None)
466  else: # change status 'add' -> 'update'
467  self.action = "update"
468 
469  table = self.mapDBInfo.layers[layer]["table"]
470  key = self.mapDBInfo.layers[layer]["key"]
471  columns = self.mapDBInfo.tables[table]
472 
473  for idx in range(len(columns[key]['values'])):
474  for name in columns.keys():
475  if name == key:
476  cat = int(columns[name]['values'][idx])
477  break
478 
479  # use scrolled panel instead (and fix initial max height of the window to 480px)
480  panel = scrolled.ScrolledPanel(parent = self.notebook, id = wx.ID_ANY,
481  size = (-1, 150))
482  panel.SetupScrolling(scroll_x = False)
483 
484  self.notebook.AddPage(page = panel, text = " %s %d / %s %d" % (_("Layer"), layer,
485  _("Category"), cat))
486 
487  # notebook body
488  border = wx.BoxSizer(wx.VERTICAL)
489 
490  flexSizer = wx.FlexGridSizer (cols = 3, hgap = 3, vgap = 3)
491  flexSizer.AddGrowableCol(2)
492  # columns (sorted by index)
493  names = [''] * len(columns.keys())
494  for name in columns.keys():
495  names[columns[name]['index']] = name
496 
497  for name in names:
498  if name == key: # skip key column (category)
499  continue
500 
501  vtype = columns[name]['type'].lower()
502  ctype = columns[name]['ctype']
503 
504  if columns[name]['values'][idx] is not None:
505  if columns[name]['ctype'] != types.StringType:
506  value = str(columns[name]['values'][idx])
507  else:
508  value = columns[name]['values'][idx]
509  else:
510  value = ''
511 
512  colName = wx.StaticText(parent = panel, id = wx.ID_ANY,
513  label = name)
514  colType = wx.StaticText(parent = panel, id = wx.ID_ANY,
515  label = "[%s]:" % vtype)
516  colValue = wx.TextCtrl(parent = panel, id = wx.ID_ANY, value = value)
517  colValue.SetName(name)
518  if ctype == int:
519  colValue.SetValidator(IntegerValidator())
520  elif ctype == float:
521  colValue.SetValidator(FloatValidator())
522 
523  self.Bind(wx.EVT_TEXT, self.OnSQLStatement, colValue)
524  if self.action == 'display':
525  colValue.SetWindowStyle(wx.TE_READONLY)
526 
527  flexSizer.Add(colName, proportion = 0,
528  flag = wx.ALIGN_CENTER_VERTICAL)
529  flexSizer.Add(colType, proportion = 0,
530  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
531  flexSizer.Add(colValue, proportion = 1,
532  flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
533  # add widget reference to self.columns
534  columns[name]['ids'].append(colValue.GetId()) # name, type, values, id
535  # for each attribute (including category) END
536  border.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
537  panel.SetSizer(border)
538  # for each category END
539  # for each layer END
540 
541  if self.notebook.GetPageCount() == 0:
542  self.noFoundMsg.Show(True)
543  else:
544  self.noFoundMsg.Show(False)
545 
546  self.Layout()
547 
548  return True
549 
550  def SetColumnValue(self, layer, column, value):
551  """!Set attrbute value
552 
553  @param column column name
554  @param value value
555  """
556  table = self.mapDBInfo.GetTable(layer)
557  columns = self.mapDBInfo.GetTableDesc(table)
558 
559  for key, col in columns.iteritems():
560  if key == column:
561  col['values'] = [col['ctype'](value),]
562  break
563 
564 class ModifyTableRecord(wx.Dialog):
565  def __init__(self, parent, title, data, keyEditable = (-1, True),
566  id = wx.ID_ANY, style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
567  """!Dialog for inserting/updating table record
568 
569  @param data a list: [(column, value)]
570  @param KeyEditable (id, editable?) indicates if textarea for key column
571  is editable(True) or not
572  """
573  # parent -> VDigitWindow
574  wx.Dialog.__init__(self, parent, id, title, style = style)
575 
576  self.CenterOnParent()
577 
578  self.keyId = keyEditable[0]
579 
580  box = wx.StaticBox(parent = self, id = wx.ID_ANY)
581  box.Hide()
582  self.dataPanel = scrolled.ScrolledPanel(parent = self, id = wx.ID_ANY,
583  style = wx.TAB_TRAVERSAL)
584  self.dataPanel.SetupScrolling(scroll_x = False)
585 
586  # buttons
587  self.btnCancel = wx.Button(self, wx.ID_CANCEL)
588  self.btnSubmit = wx.Button(self, wx.ID_OK, _("&Submit"))
589  self.btnSubmit.SetDefault()
590 
591  # data area
592  self.widgets = []
593  cId = 0
594  self.usebox = False
595  self.cat = None
596  winFocus = False
597 
598  for column, ctype, ctypeStr, value in data:
599  if self.keyId == cId:
600  self.cat = int(value)
601  if not keyEditable[1]:
602  self.usebox = True
603  box.SetLabel(" %s %d " % (_("Category"), self.cat))
604  box.Show()
605  self.boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
606  cId += 1
607  continue
608  else:
609  valueWin = wx.SpinCtrl(parent = self.dataPanel, id = wx.ID_ANY,
610  value = value, min = -1e9, max = 1e9, size = (250, -1))
611  else:
612  valueWin = wx.TextCtrl(parent = self.dataPanel, id = wx.ID_ANY,
613  value = value, size = (250, -1))
614  if ctype == int:
615  valueWin.SetValidator(IntegerValidator())
616  elif ctype == float:
617  valueWin.SetValidator(FloatValidator())
618  if not winFocus:
619  wx.CallAfter(valueWin.SetFocus)
620  winFocus = True
621 
622  label = wx.StaticText(parent = self.dataPanel, id = wx.ID_ANY,
623  label = column)
624  ctype = wx.StaticText(parent = self.dataPanel, id = wx.ID_ANY,
625  label = "[%s]:" % ctypeStr.lower())
626  self.widgets.append((label.GetId(), ctype.GetId(), valueWin.GetId()))
627 
628  cId += 1
629 
630  self._layout()
631 
632  def _layout(self):
633  """!Do layout"""
634  sizer = wx.BoxSizer(wx.VERTICAL)
635 
636  # data area
637  dataSizer = wx.FlexGridSizer(cols = 3, hgap = 3, vgap = 3)
638  dataSizer.AddGrowableCol(2)
639 
640  for labelId, ctypeId, valueId in self.widgets:
641  label = self.FindWindowById(labelId)
642  ctype = self.FindWindowById(ctypeId)
643  value = self.FindWindowById(valueId)
644 
645  dataSizer.Add(label, proportion = 0,
646  flag = wx.ALIGN_CENTER_VERTICAL)
647  dataSizer.Add(ctype, proportion = 0,
648  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
649  dataSizer.Add(value, proportion = 0,
650  flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
651 
652  self.dataPanel.SetAutoLayout(True)
653  self.dataPanel.SetSizer(dataSizer)
654  dataSizer.Fit(self.dataPanel)
655 
656  if self.usebox:
657  self.boxSizer.Add(item = self.dataPanel, proportion = 1,
658  flag = wx.EXPAND | wx.ALL, border = 5)
659 
660  # buttons
661  btnSizer = wx.StdDialogButtonSizer()
662  btnSizer.AddButton(self.btnCancel)
663  btnSizer.AddButton(self.btnSubmit)
664  btnSizer.Realize()
665 
666  if not self.usebox:
667  sizer.Add(item = self.dataPanel, proportion = 1,
668  flag = wx.EXPAND | wx.ALL, border = 5)
669  else:
670  sizer.Add(item = self.boxSizer, proportion = 1,
671  flag = wx.EXPAND | wx.ALL, border = 5)
672 
673  sizer.Add(item = btnSizer, proportion = 0,
674  flag = wx.EXPAND | wx.ALL, border = 5)
675 
676  framewidth = self.GetBestSize()[0] + 25
677  self.SetMinSize((framewidth, 250))
678 
679  self.SetAutoLayout(True)
680  self.SetSizer(sizer)
681  sizer.Fit(self)
682 
683  self.Layout()
684 
685  def GetValues(self, columns = None):
686  """!Return list of values (casted to string).
687 
688  If columns is given (list), return only values of given columns.
689  """
690  valueList = []
691  for labelId, ctypeId, valueId in self.widgets:
692  column = self.FindWindowById(labelId).GetLabel().replace(':', '')
693  if columns is None or column in columns:
694  value = str(self.FindWindowById(valueId).GetValue())
695  valueList.append(value)
696 
697  # add key value
698  if self.usebox:
699  valueList.insert(self.keyId, str(self.cat))
700 
701  return valueList
def GetValues
Return list of values (casted to string).
def GetValue
Definition: widgets.py:118
wxGUI command interface
wxGUI debugging
Core GUI widgets.
def SetValue
Definition: widgets.py:115
def SetColumnValue
Set attrbute value.
def OnClose
Closes dialog and removes query layer.
def UpdateDialog
Update dialog.
def GetFid
Get selected feature id.
def GetSQLString
Create SQL statement string based on self.sqlStatement.
def OnSQLStatement
Update SQL statement.
def OnSubmit
Submit records.
def IsFound
Check for status.
def GetCats
Get id of selected vector object or &#39;None&#39; if nothing selected.
def __init__
Standard dialog used to add/update/display attributes linked to the vector map.
def __init__
Dialog for inserting/updating table record.
Default GUI settings.
tuple range
Definition: tools.py:1406
def RunCommand
Run GRASS command.
Definition: gcmd.py:625