GRASS Programmer's Manual  6.4.3(2013)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties 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.OnCancel)
157 
158  self.SetSizer(mainSizer)
159  mainSizer.Fit(self)
160 
161  # set min size for dialog
162  w, h = self.GetBestSize()
163  w += 50
164  if h < 200:
165  self.SetMinSize((w, 200))
166  else:
167  self.SetMinSize((w, h))
168 
169  if self.notebook.GetPageCount() == 0:
170  Debug.msg(2, "DisplayAttributesDialog(): Nothing found!")
171  ### self.mapDBInfo = None
172 
173  def __SelectAttributes(self, layer):
174  """!Select attributes"""
175  pass
176 
177  def OnSQLStatement(self, event):
178  """!Update SQL statement"""
179  pass
180 
181  def IsFound(self):
182  """!Check for status
183 
184  @return True on attributes found
185  @return False attributes not found
186  """
187  return bool(self.notebook.GetPageCount())
188 
189  def GetSQLString(self, updateValues = False):
190  """!Create SQL statement string based on self.sqlStatement
191 
192  Show error message when invalid values are entered.
193 
194  If updateValues is True, update dataFrame according to values
195  in textfields.
196  """
197  sqlCommands = []
198  # find updated values for each layer/category
199  for layer in self.mapDBInfo.layers.keys(): # for each layer
200  table = self.mapDBInfo.GetTable(layer)
201  key = self.mapDBInfo.GetKeyColumn(layer)
202  columns = self.mapDBInfo.GetTableDesc(table)
203  for idx in range(len(columns[key]['values'])): # for each category
204  updatedColumns = []
205  updatedValues = []
206  for name in columns.keys():
207  if name == key:
208  cat = columns[name]['values'][idx]
209  continue
210  ctype = columns[name]['ctype']
211  value = columns[name]['values'][idx]
212  id = columns[name]['ids'][idx]
213  try:
214  newvalue = self.FindWindowById(id).GetValue()
215  except:
216  newvalue = self.FindWindowById(id).GetLabel()
217 
218  if newvalue:
219  try:
220  if ctype == int:
221  newvalue = int(newvalue)
222  elif ctype == float:
223  newvalue = float(newvalue)
224  except ValueError:
225  GError(parent = self,
226  message = _("Column <%(col)s>: Value '%(value)s' needs to be entered as %(type)s.") % \
227  {'col' : name,
228  'value' : str(newvalue),
229  'type' : columns[name]['type'].lower()},
230  showTraceback = False)
231  sqlCommands.append(None)
232  continue
233  else:
234  if self.action == 'add':
235  continue
236 
237  if newvalue != value:
238  updatedColumns.append(name)
239  if not newvalue:
240  updatedValues.append('NULL')
241  else:
242  if ctype != str:
243  updatedValues.append(str(newvalue))
244  else:
245  updatedValues.append("'" + str(newvalue) + "'")
246  columns[name]['values'][idx] = newvalue
247 
248  if self.action != "add" and len(updatedValues) == 0:
249  continue
250 
251  if self.action == "add":
252  sqlString = "INSERT INTO %s (%s," % (table, key)
253  else:
254  sqlString = "UPDATE %s SET " % table
255 
256  for idx in range(len(updatedColumns)):
257  name = updatedColumns[idx]
258  if self.action == "add":
259  sqlString += name + ","
260  else:
261  sqlString += name + "=" + updatedValues[idx] + ","
262 
263  sqlString = sqlString[:-1] # remove last comma
264 
265  if self.action == "add":
266  sqlString += ") VALUES (%s," % cat
267  for value in updatedValues:
268  sqlString += str(value) + ","
269  sqlString = sqlString[:-1] # remove last comma
270  sqlString += ")"
271  else:
272  sqlString += " WHERE cat=%s" % cat
273  sqlCommands.append(sqlString)
274  # for each category
275  # for each layer END
276 
277  Debug.msg(3, "DisplayAttributesDialog.GetSQLString(): %s" % sqlCommands)
278 
279  return sqlCommands
280 
281  def OnReset(self, event = None):
282  """!Reset form"""
283  for layer in self.mapDBInfo.layers.keys():
284  table = self.mapDBInfo.layers[layer]["table"]
285  key = self.mapDBInfo.layers[layer]["key"]
286  columns = self.mapDBInfo.tables[table]
287  for idx in range(len(columns[key]['values'])):
288  for name in columns.keys():
289  type = columns[name]['type']
290  value = columns[name]['values'][idx]
291  if value is None:
292  value = ''
293  try:
294  id = columns[name]['ids'][idx]
295  except IndexError:
296  id = wx.NOT_FOUND
297 
298  if name != key and id != wx.NOT_FOUND:
299  self.FindWindowById(id).SetValue(str(value))
300 
301  def OnCancel(self, event):
302  """!Cancel button pressed
303  """
304  frame = self.parent.parent
305  frame.dialogs['attributes'] = None
306  if hasattr(self, "digit"):
307  self.parent.digit.GetDisplay().SetSelected([])
308  if frame.IsAutoRendered():
309  self.parent.UpdateMap(render = False)
310  elif frame.IsAutoRendered():
311  frame.RemoveQueryLayer()
312  self.parent.UpdateMap(render = True)
313 
314  self.Close()
315 
316  def OnSubmit(self, event):
317  """!Submit records"""
318  close = True
319  enc = UserSettings.Get(group = 'atm', key = 'encoding', subkey = 'value')
320  if not enc and 'GRASS_DB_ENCODING' in os.environ:
321  enc = os.environ['GRASS_DB_ENCODING']
322 
323  for sql in self.GetSQLString(updateValues = True):
324  if not sql:
325  close = False
326  continue
327  if enc:
328  sql = sql.encode(enc)
329 
330  RunCommand('db.execute',
331  parent = self,
332  quiet = True,
333  stdin = sql)
334 
335  if close and self.closeDialog.IsChecked():
336  self.OnCancel(event)
337 
338  def OnFeature(self, event):
339  self.fid = int(event.GetString())
340  self.UpdateDialog(cats = self.cats, fid = self.fid)
341 
342  def GetCats(self):
343  """!Get id of selected vector object or 'None' if nothing selected
344 
345  @param id if true return ids otherwise cats
346  """
347  if self.fid < 0:
348  return None
349 
350  return self.cats[self.fid]
351 
352  def GetFid(self):
353  """!Get selected feature id"""
354  return self.fid
355 
356  def UpdateDialog(self, map = None, query = None, cats = None, fid = -1,
357  action = None):
358  """!Update dialog
359 
360  @param map name of vector map
361  @param query
362  @param cats
363  @param fid feature id
364  @param action add, update, display or None
365 
366  @return True if updated
367  @return False
368  """
369  if action:
370  self.action = action
371  if action == 'display':
372  enabled = False
373  else:
374  enabled = True
375  self.closeDialog.Enable(enabled)
376  self.FindWindowById(wx.ID_OK).Enable(enabled)
377 
378  if map:
379  self.map = map
380  # get layer/table/column information
381  self.mapDBInfo = VectorDBInfo(self.map)
382 
383  if not self.mapDBInfo:
384  return False
385 
386  self.mapDBInfo.Reset()
387 
388  layers = self.mapDBInfo.layers.keys() # get available layers
389 
390  # id of selected line
391  if query: # select by position
392  data = self.mapDBInfo.SelectByPoint(query[0],
393  query[1])
394  self.cats = {}
395  if data and 'Layer' in data:
396  idx = 0
397  for layer in data['Layer']:
398  layer = int(layer)
399  if data['Id'][idx] is not None:
400  tfid = int(data['Id'][idx])
401  else:
402  tfid = 0 # Area / Volume
403  if not tfid in self.cats:
404  self.cats[tfid] = {}
405  if not layer in self.cats[tfid]:
406  self.cats[tfid][layer] = []
407  cat = int(data['Category'][idx])
408  self.cats[tfid][layer].append(cat)
409  idx += 1
410  else:
411  self.cats = cats
412 
413  if fid > 0:
414  self.fid = fid
415  elif len(self.cats.keys()) > 0:
416  self.fid = self.cats.keys()[0]
417  else:
418  self.fid = -1
419 
420  if len(self.cats.keys()) == 1:
421  self.fidMulti.Show(False)
422  self.fidText.Show(True)
423  if self.fid > 0:
424  self.fidText.SetLabel("%d" % self.fid)
425  else:
426  self.fidText.SetLabel(_("Unknown"))
427  else:
428  self.fidMulti.Show(True)
429  self.fidText.Show(False)
430  choices = []
431  for tfid in self.cats.keys():
432  choices.append(str(tfid))
433  self.fidMulti.SetItems(choices)
434  self.fidMulti.SetStringSelection(str(self.fid))
435 
436  # reset notebook
437  self.notebook.DeleteAllPages()
438 
439  for layer in layers: # for each layer
440  if not query: # select by layer/cat
441  if self.fid > 0 and layer in self.cats[self.fid]:
442  for cat in self.cats[self.fid][layer]:
443  nselected = self.mapDBInfo.SelectFromTable(layer,
444  where = "%s=%d" % \
445  (self.mapDBInfo.layers[layer]['key'],
446  cat))
447  else:
448  nselected = 0
449 
450  # if nselected <= 0 and self.action != "add":
451  # continue # nothing selected ...
452 
453  if self.action == "add":
454  if nselected <= 0:
455  if layer in self.cats[self.fid]:
456  table = self.mapDBInfo.layers[layer]["table"]
457  key = self.mapDBInfo.layers[layer]["key"]
458  columns = self.mapDBInfo.tables[table]
459  for name in columns.keys():
460  if name == key:
461  for cat in self.cats[self.fid][layer]:
462  self.mapDBInfo.tables[table][name]['values'].append(cat)
463  else:
464  self.mapDBInfo.tables[table][name]['values'].append(None)
465  else: # change status 'add' -> 'update'
466  self.action = "update"
467 
468  table = self.mapDBInfo.layers[layer]["table"]
469  key = self.mapDBInfo.layers[layer]["key"]
470  columns = self.mapDBInfo.tables[table]
471 
472  for idx in range(len(columns[key]['values'])):
473  for name in columns.keys():
474  if name == key:
475  cat = int(columns[name]['values'][idx])
476  break
477 
478  # use scrolled panel instead (and fix initial max height of the window to 480px)
479  panel = scrolled.ScrolledPanel(parent = self.notebook, id = wx.ID_ANY,
480  size = (-1, 150))
481  panel.SetupScrolling(scroll_x = False)
482 
483  self.notebook.AddPage(page = panel, text = " %s %d / %s %d" % (_("Layer"), layer,
484  _("Category"), cat))
485 
486  # notebook body
487  border = wx.BoxSizer(wx.VERTICAL)
488 
489  flexSizer = wx.FlexGridSizer (cols = 3, hgap = 3, vgap = 3)
490  flexSizer.AddGrowableCol(2)
491  # columns (sorted by index)
492  names = [''] * len(columns.keys())
493  for name in columns.keys():
494  names[columns[name]['index']] = name
495 
496  for name in names:
497  if name == key: # skip key column (category)
498  continue
499 
500  vtype = columns[name]['type'].lower()
501  ctype = columns[name]['ctype']
502 
503  if columns[name]['values'][idx] is not None:
504  if columns[name]['ctype'] != types.StringType:
505  value = str(columns[name]['values'][idx])
506  else:
507  value = columns[name]['values'][idx]
508  else:
509  value = ''
510 
511  colName = wx.StaticText(parent = panel, id = wx.ID_ANY,
512  label = name)
513  colType = wx.StaticText(parent = panel, id = wx.ID_ANY,
514  label = "[%s]:" % vtype)
515  colValue = wx.TextCtrl(parent = panel, id = wx.ID_ANY, value = value)
516  colValue.SetName(name)
517  if ctype == int:
518  colValue.SetValidator(IntegerValidator())
519  elif ctype == float:
520  colValue.SetValidator(FloatValidator())
521 
522  self.Bind(wx.EVT_TEXT, self.OnSQLStatement, colValue)
523  if self.action == 'display':
524  colValue.SetWindowStyle(wx.TE_READONLY)
525 
526  flexSizer.Add(colName, proportion = 0,
527  flag = wx.ALIGN_CENTER_VERTICAL)
528  flexSizer.Add(colType, proportion = 0,
529  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
530  flexSizer.Add(colValue, proportion = 1,
531  flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
532  # add widget reference to self.columns
533  columns[name]['ids'].append(colValue.GetId()) # name, type, values, id
534  # for each attribute (including category) END
535  border.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5)
536  panel.SetSizer(border)
537  # for each category END
538  # for each layer END
539 
540  if self.notebook.GetPageCount() == 0:
541  self.noFoundMsg.Show(True)
542  else:
543  self.noFoundMsg.Show(False)
544 
545  self.Layout()
546 
547  return True
548 
549  def SetColumnValue(self, layer, column, value):
550  """!Set attrbute value
551 
552  @param column column name
553  @param value value
554  """
555  table = self.mapDBInfo.GetTable(layer)
556  columns = self.mapDBInfo.GetTableDesc(table)
557 
558  for key, col in columns.iteritems():
559  if key == column:
560  col['values'] = [col['ctype'](value),]
561  break
562 
563 class ModifyTableRecord(wx.Dialog):
564  def __init__(self, parent, title, data, keyEditable = (-1, True),
565  id = wx.ID_ANY, style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
566  """!Dialog for inserting/updating table record
567 
568  @param data a list: [(column, value)]
569  @param KeyEditable (id, editable?) indicates if textarea for key column
570  is editable(True) or not
571  """
572  # parent -> VDigitWindow
573  wx.Dialog.__init__(self, parent, id, title, style = style)
574 
575  self.CenterOnParent()
576 
577  self.keyId = keyEditable[0]
578 
579  box = wx.StaticBox(parent = self, id = wx.ID_ANY)
580  box.Hide()
581  self.dataPanel = scrolled.ScrolledPanel(parent = self, id = wx.ID_ANY,
582  style = wx.TAB_TRAVERSAL)
583  self.dataPanel.SetupScrolling(scroll_x = False)
584 
585  # buttons
586  self.btnCancel = wx.Button(self, wx.ID_CANCEL)
587  self.btnSubmit = wx.Button(self, wx.ID_OK, _("&Submit"))
588  self.btnSubmit.SetDefault()
589 
590  # data area
591  self.widgets = []
592  cId = 0
593  self.usebox = False
594  self.cat = None
595  winFocus = False
596 
597  for column, ctype, ctypeStr, value in data:
598  if self.keyId == cId:
599  self.cat = int(value)
600  if not keyEditable[1]:
601  self.usebox = True
602  box.SetLabel(" %s %d " % (_("Category"), self.cat))
603  box.Show()
604  self.boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
605  cId += 1
606  continue
607  else:
608  valueWin = wx.SpinCtrl(parent = self.dataPanel, id = wx.ID_ANY,
609  value = value, min = -1e9, max = 1e9, size = (250, -1))
610  else:
611  valueWin = wx.TextCtrl(parent = self.dataPanel, id = wx.ID_ANY,
612  value = value, size = (250, -1))
613  if ctype == int:
614  valueWin.SetValidator(IntegerValidator())
615  elif ctype == float:
616  valueWin.SetValidator(FloatValidator())
617  if not winFocus:
618  wx.CallAfter(valueWin.SetFocus)
619  winFocus = True
620 
621  label = wx.StaticText(parent = self.dataPanel, id = wx.ID_ANY,
622  label = column)
623  ctype = wx.StaticText(parent = self.dataPanel, id = wx.ID_ANY,
624  label = "[%s]:" % ctypeStr.lower())
625  self.widgets.append((label.GetId(), ctype.GetId(), valueWin.GetId()))
626 
627  cId += 1
628 
629  self._layout()
630 
631  def _layout(self):
632  """!Do layout"""
633  sizer = wx.BoxSizer(wx.VERTICAL)
634 
635  # data area
636  dataSizer = wx.FlexGridSizer(cols = 3, hgap = 3, vgap = 3)
637  dataSizer.AddGrowableCol(2)
638 
639  for labelId, ctypeId, valueId in self.widgets:
640  label = self.FindWindowById(labelId)
641  ctype = self.FindWindowById(ctypeId)
642  value = self.FindWindowById(valueId)
643 
644  dataSizer.Add(label, proportion = 0,
645  flag = wx.ALIGN_CENTER_VERTICAL)
646  dataSizer.Add(ctype, proportion = 0,
647  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
648  dataSizer.Add(value, proportion = 0,
649  flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
650 
651  self.dataPanel.SetAutoLayout(True)
652  self.dataPanel.SetSizer(dataSizer)
653  dataSizer.Fit(self.dataPanel)
654 
655  if self.usebox:
656  self.boxSizer.Add(item = self.dataPanel, proportion = 1,
657  flag = wx.EXPAND | wx.ALL, border = 5)
658 
659  # buttons
660  btnSizer = wx.StdDialogButtonSizer()
661  btnSizer.AddButton(self.btnCancel)
662  btnSizer.AddButton(self.btnSubmit)
663  btnSizer.Realize()
664 
665  if not self.usebox:
666  sizer.Add(item = self.dataPanel, proportion = 1,
667  flag = wx.EXPAND | wx.ALL, border = 5)
668  else:
669  sizer.Add(item = self.boxSizer, proportion = 1,
670  flag = wx.EXPAND | wx.ALL, border = 5)
671 
672  sizer.Add(item = btnSizer, proportion = 0,
673  flag = wx.EXPAND | wx.ALL, border = 5)
674 
675  framewidth = self.GetBestSize()[0] + 25
676  self.SetMinSize((framewidth, 250))
677 
678  self.SetAutoLayout(True)
679  self.SetSizer(sizer)
680  sizer.Fit(self)
681 
682  self.Layout()
683 
684  def GetValues(self, columns = None):
685  """!Return list of values (casted to string).
686 
687  If columns is given (list), return only values of given columns.
688  """
689  valueList = []
690  for labelId, ctypeId, valueId in self.widgets:
691  column = self.FindWindowById(labelId).GetLabel().replace(':', '')
692  if columns is None or column in columns:
693  value = str(self.FindWindowById(valueId).GetValue())
694  valueList.append(value)
695 
696  # add key value
697  if self.usebox:
698  valueList.insert(self.keyId, str(self.cat))
699 
700  return valueList
def GetValues
Return list of values (casted to string).
def GetValue
Definition: widgets.py:118
wxGUI command interface
int
Definition: y.tab.c:1344
wxGUI debugging
Core GUI widgets.
def SetValue
Definition: widgets.py:115
def SetColumnValue
Set attrbute value.
def OnCancel
Cancel button pressed.
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:1402
def RunCommand
Run GRASS command.
Definition: gcmd.py:633