|
GRASS Programmer's Manual
6.5.svn(2012)-r51648
|
00001 """! 00002 @package dbmgr.dialogs 00003 00004 @brief DBM-related dialogs 00005 00006 List of classes: 00007 - dialogs::DisplayAttributesDialog 00008 - dialogs::ModifyTableRecord 00009 00010 (C) 2007-2011 by the GRASS Development Team 00011 00012 This program is free software under the GNU General Public License 00013 (>=v2). Read the file COPYING that comes with GRASS for details. 00014 00015 @author Martin Landa <landa.martin gmail.com> 00016 """ 00017 00018 import os 00019 import types 00020 00021 from core import globalvar 00022 import wx 00023 import wx.lib.scrolledpanel as scrolled 00024 00025 from core.gcmd import RunCommand, GError 00026 from core.debug import Debug 00027 from core.settings import UserSettings 00028 from dbmgr.vinfo import VectorDBInfo 00029 from gui_core.widgets import IntegerValidator, FloatValidator 00030 00031 class DisplayAttributesDialog(wx.Dialog): 00032 def __init__(self, parent, map, 00033 query = None, cats = None, line = None, 00034 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, 00035 pos = wx.DefaultPosition, 00036 action = "add", ignoreError = False): 00037 """!Standard dialog used to add/update/display attributes linked 00038 to the vector map. 00039 00040 Attribute data can be selected based on layer and category number 00041 or coordinates. 00042 00043 @param parent 00044 @param map vector map 00045 @param query query coordinates and distance (used for v.edit) 00046 @param cats {layer: cats} 00047 @param line feature id (requested for cats) 00048 @param style 00049 @param pos 00050 @param action (add, update, display) 00051 @param ignoreError True to ignore errors 00052 """ 00053 self.parent = parent # mapdisplay.BufferedWindow 00054 self.map = map 00055 self.action = action 00056 00057 # ids/cats of selected features 00058 # fid : {layer : cats} 00059 self.cats = {} 00060 self.fid = -1 # feature id 00061 00062 # get layer/table/column information 00063 self.mapDBInfo = VectorDBInfo(self.map) 00064 00065 layers = self.mapDBInfo.layers.keys() # get available layers 00066 00067 # check if db connection / layer exists 00068 if len(layers) <= 0: 00069 if not ignoreError: 00070 dlg = wx.MessageDialog(parent = self.parent, 00071 message = _("No attribute table found.\n\n" 00072 "Do you want to create a new attribute table " 00073 "and defined a link to vector map <%s>?") % self.map, 00074 caption = _("Create table?"), 00075 style = wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) 00076 if dlg.ShowModal() == wx.ID_YES: 00077 lmgr = self.parent.lmgr 00078 lmgr.OnShowAttributeTable(event = None, selection = 'layers') 00079 00080 dlg.Destroy() 00081 00082 self.mapDBInfo = None 00083 00084 wx.Dialog.__init__(self, parent = self.parent, id = wx.ID_ANY, 00085 title = "", style = style, pos = pos) 00086 00087 # dialog body 00088 mainSizer = wx.BoxSizer(wx.VERTICAL) 00089 00090 # notebook 00091 self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT) 00092 00093 self.closeDialog = wx.CheckBox(parent = self, id = wx.ID_ANY, 00094 label = _("Close dialog on submit")) 00095 self.closeDialog.SetValue(True) 00096 if self.action == 'display': 00097 self.closeDialog.Enable(False) 00098 00099 # feature id (text/choice for duplicates) 00100 self.fidMulti = wx.Choice(parent = self, id = wx.ID_ANY, 00101 size = (150, -1)) 00102 self.fidMulti.Bind(wx.EVT_CHOICE, self.OnFeature) 00103 self.fidText = wx.StaticText(parent = self, id = wx.ID_ANY) 00104 00105 self.noFoundMsg = wx.StaticText(parent = self, id = wx.ID_ANY, 00106 label = _("No attributes found")) 00107 00108 self.UpdateDialog(query = query, cats = cats) 00109 00110 # set title 00111 if self.action == "update": 00112 self.SetTitle(_("Update attributes")) 00113 elif self.action == "add": 00114 self.SetTitle(_("Define attributes")) 00115 else: 00116 self.SetTitle(_("Display attributes")) 00117 00118 # buttons 00119 btnCancel = wx.Button(self, wx.ID_CANCEL) 00120 btnReset = wx.Button(self, wx.ID_UNDO, _("&Reload")) 00121 btnSubmit = wx.Button(self, wx.ID_OK, _("&Submit")) 00122 if self.action == 'display': 00123 btnSubmit.Enable(False) 00124 00125 btnSizer = wx.StdDialogButtonSizer() 00126 btnSizer.AddButton(btnCancel) 00127 btnSizer.AddButton(btnReset) 00128 btnSizer.SetNegativeButton(btnReset) 00129 btnSubmit.SetDefault() 00130 btnSizer.AddButton(btnSubmit) 00131 btnSizer.Realize() 00132 00133 mainSizer.Add(item = self.noFoundMsg, proportion = 0, 00134 flag = wx.EXPAND | wx.ALL, border = 5) 00135 mainSizer.Add(item = self.notebook, proportion = 1, 00136 flag = wx.EXPAND | wx.ALL, border = 5) 00137 fidSizer = wx.BoxSizer(wx.HORIZONTAL) 00138 fidSizer.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY, 00139 label = _("Feature id:")), 00140 proportion = 0, border = 5, 00141 flag = wx.ALIGN_CENTER_VERTICAL) 00142 fidSizer.Add(item = self.fidMulti, proportion = 0, 00143 flag = wx.EXPAND | wx.ALL, border = 5) 00144 fidSizer.Add(item = self.fidText, proportion = 0, 00145 flag = wx.EXPAND | wx.ALL, border = 5) 00146 mainSizer.Add(item = fidSizer, proportion = 0, 00147 flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 5) 00148 mainSizer.Add(item = self.closeDialog, proportion = 0, flag = wx.EXPAND | wx.LEFT | wx.RIGHT, 00149 border = 5) 00150 mainSizer.Add(item = btnSizer, proportion = 0, 00151 flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5) 00152 00153 # bindigs 00154 btnReset.Bind(wx.EVT_BUTTON, self.OnReset) 00155 btnSubmit.Bind(wx.EVT_BUTTON, self.OnSubmit) 00156 btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel) 00157 00158 self.SetSizer(mainSizer) 00159 mainSizer.Fit(self) 00160 00161 # set min size for dialog 00162 w, h = self.GetBestSize() 00163 w += 50 00164 if h < 200: 00165 self.SetMinSize((w, 200)) 00166 else: 00167 self.SetMinSize((w, h)) 00168 00169 if self.notebook.GetPageCount() == 0: 00170 Debug.msg(2, "DisplayAttributesDialog(): Nothing found!") 00171 ### self.mapDBInfo = None 00172 00173 def __SelectAttributes(self, layer): 00174 """!Select attributes""" 00175 pass 00176 00177 def OnSQLStatement(self, event): 00178 """!Update SQL statement""" 00179 pass 00180 00181 def IsFound(self): 00182 """!Check for status 00183 00184 @return True on attributes found 00185 @return False attributes not found 00186 """ 00187 return bool(self.notebook.GetPageCount()) 00188 00189 def GetSQLString(self, updateValues = False): 00190 """!Create SQL statement string based on self.sqlStatement 00191 00192 Show error message when invalid values are entered. 00193 00194 If updateValues is True, update dataFrame according to values 00195 in textfields. 00196 """ 00197 sqlCommands = [] 00198 # find updated values for each layer/category 00199 for layer in self.mapDBInfo.layers.keys(): # for each layer 00200 table = self.mapDBInfo.GetTable(layer) 00201 key = self.mapDBInfo.GetKeyColumn(layer) 00202 columns = self.mapDBInfo.GetTableDesc(table) 00203 for idx in range(len(columns[key]['values'])): # for each category 00204 updatedColumns = [] 00205 updatedValues = [] 00206 for name in columns.keys(): 00207 if name == key: 00208 cat = columns[name]['values'][idx] 00209 continue 00210 ctype = columns[name]['ctype'] 00211 value = columns[name]['values'][idx] 00212 id = columns[name]['ids'][idx] 00213 try: 00214 newvalue = self.FindWindowById(id).GetValue() 00215 except: 00216 newvalue = self.FindWindowById(id).GetLabel() 00217 00218 if newvalue: 00219 try: 00220 if ctype == int: 00221 newvalue = int(newvalue) 00222 elif ctype == float: 00223 newvalue = float(newvalue) 00224 except ValueError: 00225 GError(parent = self, 00226 message = _("Column <%(col)s>: Value '%(value)s' needs to be entered as %(type)s.") % \ 00227 {'col' : name, 00228 'value' : str(newvalue), 00229 'type' : columns[name]['type'].lower()}, 00230 showTraceback = False) 00231 sqlCommands.append(None) 00232 continue 00233 else: 00234 if self.action == 'add': 00235 continue 00236 00237 if newvalue != value: 00238 updatedColumns.append(name) 00239 if not newvalue: 00240 updatedValues.append('NULL') 00241 else: 00242 if ctype != str: 00243 updatedValues.append(str(newvalue)) 00244 else: 00245 updatedValues.append("'" + str(newvalue) + "'") 00246 columns[name]['values'][idx] = newvalue 00247 00248 if self.action != "add" and len(updatedValues) == 0: 00249 continue 00250 00251 if self.action == "add": 00252 sqlString = "INSERT INTO %s (%s," % (table, key) 00253 else: 00254 sqlString = "UPDATE %s SET " % table 00255 00256 for idx in range(len(updatedColumns)): 00257 name = updatedColumns[idx] 00258 if self.action == "add": 00259 sqlString += name + "," 00260 else: 00261 sqlString += name + "=" + updatedValues[idx] + "," 00262 00263 sqlString = sqlString[:-1] # remove last comma 00264 00265 if self.action == "add": 00266 sqlString += ") VALUES (%s," % cat 00267 for value in updatedValues: 00268 sqlString += str(value) + "," 00269 sqlString = sqlString[:-1] # remove last comma 00270 sqlString += ")" 00271 else: 00272 sqlString += " WHERE cat=%s" % cat 00273 sqlCommands.append(sqlString) 00274 # for each category 00275 # for each layer END 00276 00277 Debug.msg(3, "DisplayAttributesDialog.GetSQLString(): %s" % sqlCommands) 00278 00279 return sqlCommands 00280 00281 def OnReset(self, event = None): 00282 """!Reset form""" 00283 for layer in self.mapDBInfo.layers.keys(): 00284 table = self.mapDBInfo.layers[layer]["table"] 00285 key = self.mapDBInfo.layers[layer]["key"] 00286 columns = self.mapDBInfo.tables[table] 00287 for idx in range(len(columns[key]['values'])): 00288 for name in columns.keys(): 00289 type = columns[name]['type'] 00290 value = columns[name]['values'][idx] 00291 if value is None: 00292 value = '' 00293 try: 00294 id = columns[name]['ids'][idx] 00295 except IndexError: 00296 id = wx.NOT_FOUND 00297 00298 if name != key and id != wx.NOT_FOUND: 00299 self.FindWindowById(id).SetValue(str(value)) 00300 00301 def OnCancel(self, event): 00302 """!Cancel button pressed 00303 """ 00304 self.parent.parent.dialogs['attributes'] = None 00305 00306 if hasattr(self, "digit"): 00307 self.parent.digit.GetDisplay().SetSelected([]) 00308 self.parent.UpdateMap(render = False) 00309 else: 00310 self.parent.parent.OnRender(None) 00311 00312 self.Close() 00313 00314 def OnSubmit(self, event): 00315 """!Submit records""" 00316 close = True 00317 enc = UserSettings.Get(group = 'atm', key = 'encoding', subkey = 'value') 00318 if not enc and 'GRASS_DB_ENCODING' in os.environ: 00319 enc = os.environ['GRASS_DB_ENCODING'] 00320 00321 for sql in self.GetSQLString(updateValues = True): 00322 if not sql: 00323 close = False 00324 continue 00325 if enc: 00326 sql = sql.encode(enc) 00327 00328 RunCommand('db.execute', 00329 parent = self, 00330 quiet = True, 00331 stdin = sql) 00332 00333 if close and self.closeDialog.IsChecked(): 00334 self.OnCancel(event) 00335 00336 def OnFeature(self, event): 00337 self.fid = int(event.GetString()) 00338 self.UpdateDialog(cats = self.cats, fid = self.fid) 00339 00340 def GetCats(self): 00341 """!Get id of selected vector object or 'None' if nothing selected 00342 00343 @param id if true return ids otherwise cats 00344 """ 00345 if self.fid < 0: 00346 return None 00347 00348 return self.cats[self.fid] 00349 00350 def GetFid(self): 00351 """!Get selected feature id""" 00352 return self.fid 00353 00354 def UpdateDialog(self, map = None, query = None, cats = None, fid = -1, 00355 action = None): 00356 """!Update dialog 00357 00358 @param map name of vector map 00359 @param query 00360 @param cats 00361 @param fid feature id 00362 @param action add, update, display or None 00363 00364 @return True if updated 00365 @return False 00366 """ 00367 if action: 00368 self.action = action 00369 if action == 'display': 00370 enabled = False 00371 else: 00372 enabled = True 00373 self.closeDialog.Enable(enabled) 00374 self.FindWindowById(wx.ID_OK).Enable(enabled) 00375 00376 if map: 00377 self.map = map 00378 # get layer/table/column information 00379 self.mapDBInfo = VectorDBInfo(self.map) 00380 00381 if not self.mapDBInfo: 00382 return False 00383 00384 self.mapDBInfo.Reset() 00385 00386 layers = self.mapDBInfo.layers.keys() # get available layers 00387 00388 # id of selected line 00389 if query: # select by position 00390 data = self.mapDBInfo.SelectByPoint(query[0], 00391 query[1]) 00392 self.cats = {} 00393 if data and 'Layer' in data: 00394 idx = 0 00395 for layer in data['Layer']: 00396 layer = int(layer) 00397 if 'Id' in data: 00398 tfid = int(data['Id'][idx]) 00399 else: 00400 tfid = 0 # Area / Volume 00401 if not tfid in self.cats: 00402 self.cats[tfid] = {} 00403 if not layer in self.cats[tfid]: 00404 self.cats[tfid][layer] = [] 00405 cat = int(data['Category'][idx]) 00406 self.cats[tfid][layer].append(cat) 00407 idx += 1 00408 else: 00409 self.cats = cats 00410 00411 if fid > 0: 00412 self.fid = fid 00413 elif len(self.cats.keys()) > 0: 00414 self.fid = self.cats.keys()[0] 00415 else: 00416 self.fid = -1 00417 00418 if len(self.cats.keys()) == 1: 00419 self.fidMulti.Show(False) 00420 self.fidText.Show(True) 00421 if self.fid > 0: 00422 self.fidText.SetLabel("%d" % self.fid) 00423 else: 00424 self.fidText.SetLabel(_("Unknown")) 00425 else: 00426 self.fidMulti.Show(True) 00427 self.fidText.Show(False) 00428 choices = [] 00429 for tfid in self.cats.keys(): 00430 choices.append(str(tfid)) 00431 self.fidMulti.SetItems(choices) 00432 self.fidMulti.SetStringSelection(str(self.fid)) 00433 00434 # reset notebook 00435 self.notebook.DeleteAllPages() 00436 00437 for layer in layers: # for each layer 00438 if not query: # select by layer/cat 00439 if self.fid > 0 and layer in self.cats[self.fid]: 00440 for cat in self.cats[self.fid][layer]: 00441 nselected = self.mapDBInfo.SelectFromTable(layer, 00442 where = "%s=%d" % \ 00443 (self.mapDBInfo.layers[layer]['key'], 00444 cat)) 00445 else: 00446 nselected = 0 00447 00448 # if nselected <= 0 and self.action != "add": 00449 # continue # nothing selected ... 00450 00451 if self.action == "add": 00452 if nselected <= 0: 00453 if layer in self.cats[self.fid]: 00454 table = self.mapDBInfo.layers[layer]["table"] 00455 key = self.mapDBInfo.layers[layer]["key"] 00456 columns = self.mapDBInfo.tables[table] 00457 for name in columns.keys(): 00458 if name == key: 00459 for cat in self.cats[self.fid][layer]: 00460 self.mapDBInfo.tables[table][name]['values'].append(cat) 00461 else: 00462 self.mapDBInfo.tables[table][name]['values'].append(None) 00463 else: # change status 'add' -> 'update' 00464 self.action = "update" 00465 00466 table = self.mapDBInfo.layers[layer]["table"] 00467 key = self.mapDBInfo.layers[layer]["key"] 00468 columns = self.mapDBInfo.tables[table] 00469 00470 for idx in range(len(columns[key]['values'])): 00471 for name in columns.keys(): 00472 if name == key: 00473 cat = int(columns[name]['values'][idx]) 00474 break 00475 00476 # use scrolled panel instead (and fix initial max height of the window to 480px) 00477 panel = scrolled.ScrolledPanel(parent = self.notebook, id = wx.ID_ANY, 00478 size = (-1, 150)) 00479 panel.SetupScrolling(scroll_x = False) 00480 00481 self.notebook.AddPage(page = panel, text = " %s %d / %s %d" % (_("Layer"), layer, 00482 _("Category"), cat)) 00483 00484 # notebook body 00485 border = wx.BoxSizer(wx.VERTICAL) 00486 00487 flexSizer = wx.FlexGridSizer (cols = 3, hgap = 3, vgap = 3) 00488 flexSizer.AddGrowableCol(2) 00489 # columns (sorted by index) 00490 names = [''] * len(columns.keys()) 00491 for name in columns.keys(): 00492 names[columns[name]['index']] = name 00493 00494 for name in names: 00495 if name == key: # skip key column (category) 00496 continue 00497 00498 vtype = columns[name]['type'].lower() 00499 ctype = columns[name]['ctype'] 00500 00501 if columns[name]['values'][idx] is not None: 00502 if columns[name]['ctype'] != types.StringType: 00503 value = str(columns[name]['values'][idx]) 00504 else: 00505 value = columns[name]['values'][idx] 00506 else: 00507 value = '' 00508 00509 colName = wx.StaticText(parent = panel, id = wx.ID_ANY, 00510 label = name) 00511 colType = wx.StaticText(parent = panel, id = wx.ID_ANY, 00512 label = "[%s]:" % vtype) 00513 colValue = wx.TextCtrl(parent = panel, id = wx.ID_ANY, value = value) 00514 colValue.SetName(name) 00515 if ctype == int: 00516 colValue.SetValidator(IntegerValidator()) 00517 elif ctype == float: 00518 colValue.SetValidator(FloatValidator()) 00519 00520 self.Bind(wx.EVT_TEXT, self.OnSQLStatement, colValue) 00521 if self.action == 'display': 00522 colValue.SetWindowStyle(wx.TE_READONLY) 00523 00524 flexSizer.Add(colName, proportion = 0, 00525 flag = wx.ALIGN_CENTER_VERTICAL) 00526 flexSizer.Add(colType, proportion = 0, 00527 flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) 00528 flexSizer.Add(colValue, proportion = 1, 00529 flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL) 00530 # add widget reference to self.columns 00531 columns[name]['ids'].append(colValue.GetId()) # name, type, values, id 00532 # for each attribute (including category) END 00533 border.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 5) 00534 panel.SetSizer(border) 00535 # for each category END 00536 # for each layer END 00537 00538 if self.notebook.GetPageCount() == 0: 00539 self.noFoundMsg.Show(True) 00540 else: 00541 self.noFoundMsg.Show(False) 00542 00543 self.Layout() 00544 00545 return True 00546 00547 def SetColumnValue(self, layer, column, value): 00548 """!Set attrbute value 00549 00550 @param column column name 00551 @param value value 00552 """ 00553 table = self.mapDBInfo.GetTable(layer) 00554 columns = self.mapDBInfo.GetTableDesc(table) 00555 00556 for key, col in columns.iteritems(): 00557 if key == column: 00558 col['values'] = [col['ctype'](value),] 00559 break 00560 00561 class ModifyTableRecord(wx.Dialog): 00562 def __init__(self, parent, title, data, keyEditable = (-1, True), 00563 id = wx.ID_ANY, style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER): 00564 """!Dialog for inserting/updating table record 00565 00566 @param data a list: [(column, value)] 00567 @param KeyEditable (id, editable?) indicates if textarea for key column 00568 is editable(True) or not 00569 """ 00570 # parent -> VDigitWindow 00571 wx.Dialog.__init__(self, parent, id, title, style = style) 00572 00573 self.CenterOnParent() 00574 00575 self.keyId = keyEditable[0] 00576 00577 box = wx.StaticBox(parent = self, id = wx.ID_ANY) 00578 box.Hide() 00579 self.dataPanel = scrolled.ScrolledPanel(parent = self, id = wx.ID_ANY, 00580 style = wx.TAB_TRAVERSAL) 00581 self.dataPanel.SetupScrolling(scroll_x = False) 00582 00583 # buttons 00584 self.btnCancel = wx.Button(self, wx.ID_CANCEL) 00585 self.btnSubmit = wx.Button(self, wx.ID_OK, _("&Submit")) 00586 self.btnSubmit.SetDefault() 00587 00588 # data area 00589 self.widgets = [] 00590 cId = 0 00591 self.usebox = False 00592 self.cat = None 00593 winFocus = False 00594 00595 for column, ctype, ctypeStr, value in data: 00596 if self.keyId == cId: 00597 self.cat = int(value) 00598 if not keyEditable[1]: 00599 self.usebox = True 00600 box.SetLabel(" %s %d " % (_("Category"), self.cat)) 00601 box.Show() 00602 self.boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL) 00603 cId += 1 00604 continue 00605 else: 00606 valueWin = wx.SpinCtrl(parent = self.dataPanel, id = wx.ID_ANY, 00607 value = value, min = -1e9, max = 1e9, size = (250, -1)) 00608 else: 00609 valueWin = wx.TextCtrl(parent = self.dataPanel, id = wx.ID_ANY, 00610 value = value, size = (250, -1)) 00611 if ctype == int: 00612 valueWin.SetValidator(IntegerValidator()) 00613 elif ctype == float: 00614 valueWin.SetValidator(FloatValidator()) 00615 if not winFocus: 00616 wx.CallAfter(valueWin.SetFocus) 00617 winFocus = True 00618 00619 label = wx.StaticText(parent = self.dataPanel, id = wx.ID_ANY, 00620 label = column) 00621 ctype = wx.StaticText(parent = self.dataPanel, id = wx.ID_ANY, 00622 label = "[%s]:" % ctypeStr.lower()) 00623 self.widgets.append((label.GetId(), ctype.GetId(), valueWin.GetId())) 00624 00625 cId += 1 00626 00627 self._layout() 00628 00629 def _layout(self): 00630 """!Do layout""" 00631 sizer = wx.BoxSizer(wx.VERTICAL) 00632 00633 # data area 00634 dataSizer = wx.FlexGridSizer(cols = 3, hgap = 3, vgap = 3) 00635 dataSizer.AddGrowableCol(2) 00636 00637 for labelId, ctypeId, valueId in self.widgets: 00638 label = self.FindWindowById(labelId) 00639 ctype = self.FindWindowById(ctypeId) 00640 value = self.FindWindowById(valueId) 00641 00642 dataSizer.Add(label, proportion = 0, 00643 flag = wx.ALIGN_CENTER_VERTICAL) 00644 dataSizer.Add(ctype, proportion = 0, 00645 flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT) 00646 dataSizer.Add(value, proportion = 0, 00647 flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL) 00648 00649 self.dataPanel.SetAutoLayout(True) 00650 self.dataPanel.SetSizer(dataSizer) 00651 dataSizer.Fit(self.dataPanel) 00652 00653 if self.usebox: 00654 self.boxSizer.Add(item = self.dataPanel, proportion = 1, 00655 flag = wx.EXPAND | wx.ALL, border = 5) 00656 00657 # buttons 00658 btnSizer = wx.StdDialogButtonSizer() 00659 btnSizer.AddButton(self.btnCancel) 00660 btnSizer.AddButton(self.btnSubmit) 00661 btnSizer.Realize() 00662 00663 if not self.usebox: 00664 sizer.Add(item = self.dataPanel, proportion = 1, 00665 flag = wx.EXPAND | wx.ALL, border = 5) 00666 else: 00667 sizer.Add(item = self.boxSizer, proportion = 1, 00668 flag = wx.EXPAND | wx.ALL, border = 5) 00669 00670 sizer.Add(item = btnSizer, proportion = 0, 00671 flag = wx.EXPAND | wx.ALL, border = 5) 00672 00673 framewidth = self.GetBestSize()[0] + 25 00674 self.SetMinSize((framewidth, 250)) 00675 00676 self.SetAutoLayout(True) 00677 self.SetSizer(sizer) 00678 sizer.Fit(self) 00679 00680 self.Layout() 00681 00682 def GetValues(self, columns = None): 00683 """!Return list of values (casted to string). 00684 00685 If columns is given (list), return only values of given columns. 00686 """ 00687 valueList = [] 00688 for labelId, ctypeId, valueId in self.widgets: 00689 column = self.FindWindowById(labelId).GetLabel().replace(':', '') 00690 if columns is None or column in columns: 00691 value = str(self.FindWindowById(valueId).GetValue()) 00692 valueList.append(value) 00693 00694 # add key value 00695 if self.usebox: 00696 valueList.insert(self.keyId, str(self.cat)) 00697 00698 return valueList