[GRASS-SVN] r36382 - grass/trunk/gui/wxpython/gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Mar 14 15:31:41 EDT 2009
Author: martinl
Date: 2009-03-14 15:31:40 -0400 (Sat, 14 Mar 2009)
New Revision: 36382
Added:
grass/trunk/gui/wxpython/gui_modules/dbm_dialogs.py
Modified:
grass/trunk/gui/wxpython/gui_modules/__init__.py
grass/trunk/gui/wxpython/gui_modules/dbm.py
grass/trunk/gui/wxpython/gui_modules/mapdisp.py
grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py
Log:
wxGUI: dialogs from dbm moved to dbm_dialogs
(merge from devbr6, r36381)
Modified: grass/trunk/gui/wxpython/gui_modules/__init__.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/__init__.py 2009-03-14 19:29:22 UTC (rev 36381)
+++ grass/trunk/gui/wxpython/gui_modules/__init__.py 2009-03-14 19:31:40 UTC (rev 36382)
@@ -1,6 +1,7 @@
all = [
"colorrules.py",
"dbm.py",
+ "dbm_dialogs.py",
"debug.py",
"disp_print.py",
"gcmd.py",
Modified: grass/trunk/gui/wxpython/gui_modules/dbm.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/dbm.py 2009-03-14 19:29:22 UTC (rev 36381)
+++ grass/trunk/gui/wxpython/gui_modules/dbm.py 2009-03-14 19:31:40 UTC (rev 36382)
@@ -17,11 +17,9 @@
- Log
- VirtualAttributeList
- AttributeManager
- - DisplayAttributesDialog
- VectorDBInfo
- - ModifyTableRecord
-(C) 2007-2008 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
@@ -48,14 +46,14 @@
import wx
import wx.lib.mixins.listctrl as listmix
import wx.lib.flatnotebook as FN
-import wx.lib.scrolledpanel as scrolled
import sqlbuilder
import gcmd
import utils
import gdialogs
import gselect
-from debug import Debug as Debug
+from debug import Debug
+from dbm_dialogs import ModifyTableRecord
from preferences import globalSettings as UserSettings
def unicodeValue(value):
@@ -2894,460 +2892,6 @@
event.Skip()
-class DisplayAttributesDialog(wx.Dialog):
- """
- Standard dialog used to add/update/display attributes linked
- to the vector map.
-
- Attribute data can be selected based on layer and category number
- or coordinates.
-
- @param parent
- @param map vector map
- @param query query coordinates and distance (used for v.edit)
- @param cats {layer: cats}
- @param line feature id (requested for cats)
- @param style
- @param pos
- @param action (add, update, display)
- """
- def __init__(self, parent, map,
- query=None, cats=None, line=None,
- style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
- pos=wx.DefaultPosition,
- action="add"):
- self.parent = parent # mapdisplay.BufferedWindow
- self.map = map
- self.action = action
-
- # ids/cats of selected features
- # fid : {layer : cats}
- self.cats = {}
- self.fid = -1 # feature id
-
- # get layer/table/column information
- self.mapDBInfo = VectorDBInfo(self.map)
-
- layers = self.mapDBInfo.layers.keys() # get available layers
-
- # check if db connection / layer exists
- if len(layers) <= 0:
- label = _("Database connection "
- "is not defined in DB file.")
-
- wx.MessageBox(parent=self.parent,
- message=_("No attribute table linked to "
- "vector map <%(vector)s> found. %(msg)s"
- "\nYou can disable this message from digitization settings. Or "
- "you can create and link attribute table to the vector map "
- "using Attribute Table Manager.") %
- {'vector' : self.map, 'msg' : label},
- caption=_("Message"), style=wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE)
- self.mapDBInfo = None
-
- wx.Dialog.__init__(self, parent=self.parent, id=wx.ID_ANY,
- title="", style=style, pos=pos)
-
- # dialog body
- mainSizer = wx.BoxSizer(wx.VERTICAL)
-
- # notebook
- self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
-
- self.closeDialog = wx.CheckBox(parent=self, id=wx.ID_ANY,
- label=_("Close dialog on submit"))
- self.closeDialog.SetValue(True)
-
- # feature id (text/choice for duplicates)
- self.fidMulti = wx.Choice(parent=self, id=wx.ID_ANY,
- size=(150, -1))
- self.fidMulti.Bind(wx.EVT_CHOICE, self.OnFeature)
- self.fidText = wx.StaticText(parent=self, id=wx.ID_ANY)
-
- self.noFoundMsg = wx.StaticText(parent=self, id=wx.ID_ANY,
- label=_("No attributes found"))
-
- self.UpdateDialog(query=query, cats=cats)
-
- # set title
- if self.action == "update":
- self.SetTitle(_("Update attributes"))
- elif self.action == "add":
- self.SetTitle(_("Add attributes"))
- else:
- self.SetTitle(_("Display attributes"))
-
- # buttons
- btnCancel = wx.Button(self, wx.ID_CANCEL)
- btnReset = wx.Button(self, wx.ID_UNDO, _("&Reload"))
- btnSubmit = wx.Button(self, wx.ID_OK, _("&Submit"))
-
- btnSizer = wx.StdDialogButtonSizer()
- btnSizer.AddButton(btnCancel)
- btnSizer.AddButton(btnReset)
- btnSizer.SetNegativeButton(btnReset)
- btnSubmit.SetDefault()
- btnSizer.AddButton(btnSubmit)
- btnSizer.Realize()
-
- mainSizer.Add(item=self.noFoundMsg, proportion=0,
- flag=wx.EXPAND | wx.ALL, border=5)
- mainSizer.Add(item=self.notebook, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=5)
- fidSizer = wx.BoxSizer(wx.HORIZONTAL)
- fidSizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY,
- label=_("Feature id:")),
- proportion=0, border=5,
- flag=wx.ALIGN_CENTER_VERTICAL)
- fidSizer.Add(item=self.fidMulti, proportion=0,
- flag=wx.EXPAND | wx.ALL, border=5)
- fidSizer.Add(item=self.fidText, proportion=0,
- flag=wx.EXPAND | wx.ALL, border=5)
- mainSizer.Add(item=fidSizer, proportion=0,
- flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5)
- mainSizer.Add(item=self.closeDialog, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
- border=5)
- mainSizer.Add(item=btnSizer, proportion=0,
- flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
-
- # bindigs
- btnReset.Bind(wx.EVT_BUTTON, self.OnReset)
- btnSubmit.Bind(wx.EVT_BUTTON, self.OnSubmit)
- btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
-
- self.SetSizer(mainSizer)
- mainSizer.Fit(self)
-
- # set min size for dialog
- w, h = self.GetBestSize()
- if h < 200:
- self.SetMinSize((w, 200))
- else:
- self.SetMinSize(self.GetBestSize())
-
- if self.notebook.GetPageCount() == 0:
- Debug.msg(2, "DisplayAttributesDialog(): Nothing found!")
- ### self.mapDBInfo = None
-
- def __SelectAttributes(self, layer):
- """Select attributes"""
- pass
-
- def OnSQLStatement(self, event):
- """Update SQL statement"""
- pass
-
- def GetSQLString(self, updateValues=False):
- """Create SQL statement string based on self.sqlStatement
-
- If updateValues is True, update dataFrame according to values
- in textfields.
- """
- sqlCommands = []
- # find updated values for each layer/category
- for layer in self.mapDBInfo.layers.keys(): # for each layer
- table = self.mapDBInfo.layers[layer]["table"]
- key = self.mapDBInfo.layers[layer]["key"]
- columns = self.mapDBInfo.tables[table]
- for idx in range(len(columns[key]['values'])): # for each category
- updatedColumns = []
- updatedValues = []
- for name in columns.keys():
- if name == key:
- cat = columns[name]['values'][idx]
- continue
- type = columns[name]['type']
- value = columns[name]['values'][idx]
- id = columns[name]['ids'][idx]
- try:
- newvalue = self.FindWindowById(id).GetValue()
- except:
- newvalue = self.FindWindowById(id).GetLabel()
-
- if newvalue == '':
- newvalue = None
-
- if newvalue != value:
- updatedColumns.append(name)
- if newvalue is None:
- updatedValues.append('NULL')
- else:
- if type != 'character':
- updatedValues.append(newvalue)
- else:
- updatedValues.append("'" + newvalue + "'")
- columns[name]['values'][idx] = newvalue
-
- if self.action != "add" and len(updatedValues) == 0:
- continue
-
- if self.action == "add":
- sqlString = "INSERT INTO %s (%s," % (table, key)
- else:
- sqlString = "UPDATE %s SET " % table
-
- for idx in range(len(updatedColumns)):
- name = updatedColumns[idx]
- if self.action == "add":
- sqlString += name + ","
- else:
- sqlString += name + "=" + updatedValues[idx] + ","
-
- sqlString = sqlString[:-1] # remove last comma
-
- if self.action == "add":
- sqlString += ") VALUES (%s," % cat
- for value in updatedValues:
- sqlString += str(value) + ","
- sqlString = sqlString[:-1] # remove last comma
- sqlString += ")"
- else:
- sqlString += " WHERE cat=%s" % cat
- sqlCommands.append(sqlString)
- # for each category
- # for each layer END
-
- Debug.msg(3, "DisplayAttributesDialog.GetSQLString(): %s" % sqlCommands)
-
- return sqlCommands
-
- def OnReset(self, event):
- """Reset form"""
- for layer in self.mapDBInfo.layers.keys():
- table = self.mapDBInfo.layers[layer]["table"]
- key = self.mapDBInfo.layers[layer]["key"]
- columns = self.mapDBInfo.tables[table]
- for idx in range(len(columns[key]['values'])):
- for name in columns.keys():
- type = columns[name]['type']
- value = columns[name]['values'][idx]
- try:
- id = columns[name]['ids'][idx]
- except IndexError:
- id = wx.NOT_FOUND
-
- if name != key and id != wx.NOT_FOUND:
- self.FindWindowById(id).SetValue(str(value))
-
- def OnCancel(self, event):
- """Cancel button pressed"""
- self.parent.parent.dialogs['attributes'] = None
- if self.parent.parent.digit:
- self.parent.parent.digit.driver.SetSelected([])
- self.parent.UpdateMap(render=False)
- else:
- self.parent.parent.OnRender(None)
-
- self.Close()
-
- def OnSubmit(self, event):
- """Submit records"""
- for sql in self.GetSQLString(updateValues=True):
- enc = UserSettings.Get(group='atm', key='encoding', subkey='value')
- if not enc and \
- os.environ.has_key('GRASS_DB_ENCODING'):
- enc = os.environ['GRASS_DB_ENCODING']
- if enc:
- sql = sql.encode(enc)
-
- gcmd.RunCommand('db.execute',
- quiet = True,
- stdin = sql)
-
- if self.closeDialog.IsChecked():
- self.OnCancel(event)
-
- def OnFeature(self, event):
- self.fid = int(event.GetString())
- self.UpdateDialog(cats=self.cats, fid=self.fid)
-
- def GetCats(self):
- """Get id of selected vector object or 'None' if nothing selected
-
- @param id if true return ids otherwise cats
- """
- if self.fid < 0:
- return None
-
- return self.cats[self.fid]
-
- def GetFid(self):
- """Get selected feature id"""
- return self.fid
-
- def UpdateDialog(self, map=None, query=None, cats=None, fid=-1):
- """Update dialog
-
- Return True if updated otherwise False
- """
- if map:
- self.map = map
- # get layer/table/column information
- self.mapDBInfo = VectorDBInfo(self.map)
-
- if not self.mapDBInfo:
- return False
-
- self.mapDBInfo.Reset()
-
- layers = self.mapDBInfo.layers.keys() # get available layers
-
- # id of selected line
- if query: # select by position
- data = self.mapDBInfo.SelectByPoint(query[0],
- query[1])
- self.cats = {}
- if data and data.has_key('Layer'):
- idx = 0
- for layer in data['Layer']:
- layer = int(layer)
- if data.has_key('Id'):
- tfid = int(data['Id'][idx])
- else:
- tfid = 0 # Area / Volume
- if not self.cats.has_key(tfid):
- self.cats[tfid] = {}
- if not self.cats[tfid].has_key(layer):
- self.cats[tfid][layer] = []
- cat = int(data['Category'][idx])
- self.cats[tfid][layer].append(cat)
- idx += 1
- else:
- self.cats = cats
-
- if fid > 0:
- self.fid = fid
- elif len(self.cats.keys()) > 0:
- self.fid = self.cats.keys()[0]
- else:
- self.fid = -1
-
- if len(self.cats.keys()) == 1:
- self.fidMulti.Show(False)
- self.fidText.Show(True)
- if self.fid > 0:
- self.fidText.SetLabel("%d" % self.fid)
- else:
- self.fidText.SetLabel(_("Unknown"))
- else:
- self.fidMulti.Show(True)
- self.fidText.Show(False)
- choices = []
- for tfid in self.cats.keys():
- choices.append(str(tfid))
- self.fidMulti.SetItems(choices)
- self.fidMulti.SetStringSelection(str(self.fid))
-
- # reset notebook
- self.notebook.DeleteAllPages()
-
- for layer in layers: # for each layer
- if not query: # select by layer/cat
- if self.fid > 0 and self.cats[self.fid].has_key(layer):
- for cat in self.cats[self.fid][layer]:
- nselected = self.mapDBInfo.SelectFromTable(layer,
- where="%s=%d" % \
- (self.mapDBInfo.layers[layer]['key'],
- cat))
- else:
- nselected = 0
-
- # if nselected <= 0 and self.action != "add":
- # continue # nothing selected ...
-
- if self.action == "add":
- if nselected <= 0:
- if self.cats[self.fid].has_key(layer):
- table = self.mapDBInfo.layers[layer]["table"]
- key = self.mapDBInfo.layers[layer]["key"]
- columns = self.mapDBInfo.tables[table]
- for name in columns.keys():
- if name == key:
- for cat in self.cats[self.fid][layer]:
- self.mapDBInfo.tables[table][name]['values'].append(cat)
- else:
- self.mapDBInfo.tables[table][name]['values'].append(None)
- else: # change status 'add' -> 'update'
- self.action = "update"
-
- table = self.mapDBInfo.layers[layer]["table"]
- key = self.mapDBInfo.layers[layer]["key"]
- columns = self.mapDBInfo.tables[table]
-
- for idx in range(len(columns[key]['values'])):
- for name in columns.keys():
- if name == key:
- cat = int(columns[name]['values'][idx])
- break
-
- # use scrolled panel instead (and fix initial max height of the window to 480px)
- panel = scrolled.ScrolledPanel(parent=self.notebook, id=wx.ID_ANY,
- size=(-1, 150))
- panel.SetupScrolling(scroll_x=False)
-
- self.notebook.AddPage(page=panel, text=" %s %d / %s %d" % (_("Layer"), layer,
- _("Category"), cat))
-
- # notebook body
- border = wx.BoxSizer(wx.VERTICAL)
-
- flexSizer = wx.FlexGridSizer (cols=4, hgap=3, vgap=3)
- flexSizer.AddGrowableCol(3)
- # columns (sorted by index)
- names = [''] * len(columns.keys())
- for name in columns.keys():
- names[columns[name]['index']] = name
-
- for name in names:
- if name == key: # skip key column (category)
- continue
-
- vtype = columns[name]['type']
-
- if columns[name]['values'][idx] is not None:
- if columns[name]['ctype'] != type(''):
- value = str(columns[name]['values'][idx])
- else:
- value = columns[name]['values'][idx]
- else:
- value = ''
-
- colName = wx.StaticText(parent=panel, id=wx.ID_ANY,
- label=name)
- colType = wx.StaticText(parent=panel, id=wx.ID_ANY,
- label="[" + vtype.lower() + "]")
- delimiter = wx.StaticText(parent=panel, id=wx.ID_ANY, label=":")
-
- colValue = wx.TextCtrl(parent=panel, id=wx.ID_ANY, value=value)
-
- colValue.SetName(name)
- self.Bind(wx.EVT_TEXT, self.OnSQLStatement, colValue)
-
- flexSizer.Add(colName, proportion=0,
- flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
- flexSizer.Add(colType, proportion=0,
- flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
- flexSizer.Add(delimiter, proportion=0,
- flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
- flexSizer.Add(colValue, proportion=1,
- flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
- # add widget reference to self.columns
- columns[name]['ids'].append(colValue.GetId()) # name, type, values, id
- # for each attribute (including category) END
- border.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
- panel.SetSizer(border)
- # for each category END
- # for each layer END
-
- if self.notebook.GetPageCount() == 0:
- self.noFoundMsg.Show(True)
- else:
- self.noFoundMsg.Show(False)
-
- self.Layout()
-
- return True
-
class VectorDBInfo(gselect.VectorDBInfo):
"""Class providing information about attribute tables
linked to the vector map"""
@@ -3471,156 +3015,6 @@
return nselected
-class ModifyTableRecord(wx.Dialog):
- """Dialog for inserting/updating table record"""
- def __init__(self, parent, id, title, data, keyEditable=(-1, True),
- style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
- """
- Notes:
- 'Data' is a list: [(column, value)]
- 'KeyEditable' (id, editable?) indicates if textarea for key column
- is editable(True) or not.
- """
- wx.Dialog.__init__(self, parent, id, title, style=style)
-
- self.keyId = keyEditable[0]
-
- self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
-
- self.dataPanel = scrolled.ScrolledPanel(parent=self.panel, id=wx.ID_ANY,
- style=wx.TAB_TRAVERSAL)
- self.dataPanel.SetupScrolling(scroll_x=False)
-
- #
- # buttons
- #
- self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
- self.btnSubmit = wx.Button(self.panel, wx.ID_OK, _("Submit"))
- self.btnSubmit.SetDefault()
-
- #
- # data area
- #
- self.widgets = []
- id = 0
- self.box = False
- self.cat = None
- for column, value in data:
- if keyEditable[0] == id:
- self.cat = int(value)
- if keyEditable[1] == False:
- self.box = True
- id += 1
- continue
- else:
- valueWin = wx.SpinCtrl(parent=self.dataPanel, id=wx.ID_ANY,
- value=value, min=-1e9, max=1e9, size=(250, -1))
- else:
- valueWin = wx.TextCtrl(parent=self.dataPanel, id=wx.ID_ANY,
- value=value, size=(250, -1))
-
- label = wx.StaticText(parent=self.dataPanel, id=wx.ID_ANY,
- label=column + ":")
-
- self.widgets.append((label.GetId(),
- valueWin.GetId()))
-
- id += 1
-
- self.__Layout()
-
- # winSize = self.GetSize()
- # fix height of window frame if needed
- # if winSize[1] > 480:
- # winSize[1] = 480
- # self.SetSize(winSize)
- # self.SetMinSize(winSize)
-
- def __Layout(self):
- """Do layout"""
- sizer = wx.BoxSizer(wx.VERTICAL)
-
- if self.box:
- box = wx.StaticBox(parent=self.panel, id=wx.ID_ANY,
- label=" %s %d " % (_("Category"), self.cat))
- boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-
- # data area
- dataSizer = wx.FlexGridSizer (cols=2, hgap=3, vgap=3)
- dataSizer.AddGrowableCol(1)
-
- for labelId, valueId in self.widgets:
- label = self.FindWindowById(labelId)
- value = self.FindWindowById(valueId)
-
- dataSizer.Add(label, proportion=0,
- flag=wx.ALIGN_CENTER_VERTICAL)
- dataSizer.Add(value, proportion=0,
- flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
-
- self.dataPanel.SetAutoLayout(True)
- self.dataPanel.SetSizer(dataSizer)
- dataSizer.Fit(self.dataPanel)
-
- if self.box:
- boxSizer.Add(item=self.dataPanel, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=5)
-
- # buttons
- btnSizer = wx.StdDialogButtonSizer()
- btnSizer.AddButton(self.btnCancel)
- btnSizer.AddButton(self.btnSubmit)
- btnSizer.Realize()
-
- if not self.box:
- sizer.Add(item=self.dataPanel, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=5)
- else:
- sizer.Add(item=boxSizer, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=5)
-
-
- sizer.Add(item=btnSizer, proportion=0,
- flag=wx.EXPAND | wx.ALL, border=5)
-
- #sizer.SetSizeHints(self.panel)
- self.panel.SetAutoLayout(True)
- self.panel.SetSizer(sizer)
- sizer.Fit(self.panel)
-
- self.Layout()
-
- # set window frame size (min & max)
- minFrameHeight = 150
- maxFrameHeight = 2 * minFrameHeight
- if self.GetSize()[1] > minFrameHeight:
- self.SetMinSize((self.GetSize()[0], minFrameHeight))
- else:
- self.SetMinSize(self.GetSize())
-
- if self.GetSize()[1] > maxFrameHeight:
- self.SetSize((self.GetSize()[0], maxFrameHeight))
- else:
- self.SetSize(self.panel.GetSize())
-
- def GetValues(self, columns=None):
- """Return list of values (casted to string).
-
- If columns is given (list), return only values of given columns.
- """
- valueList = []
- for labelId, valueId in self.widgets:
- column = self.FindWindowById(labelId).GetLabel().replace(':', '')
- if columns is None or column in columns:
- value = str(self.FindWindowById(valueId).GetValue())
- valueList.append(value)
-
- # add key value
- if self.box:
- valueList.insert(self.keyId, str(self.cat))
-
- return valueList
-
def main(argv=None):
if argv is None:
argv = sys.argv
Copied: grass/trunk/gui/wxpython/gui_modules/dbm_dialogs.py (from rev 36381, grass/branches/develbranch_6/gui/wxpython/gui_modules/dbm_dialogs.py)
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/dbm_dialogs.py (rev 0)
+++ grass/trunk/gui/wxpython/gui_modules/dbm_dialogs.py 2009-03-14 19:31:40 UTC (rev 36382)
@@ -0,0 +1,635 @@
+"""
+ at package dbm_dialogs.py
+
+ at brief DBM-related dialogs
+
+List of classes:
+ - DisplayAttributesDialog
+ - ModifyTableRecord
+
+(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.
+
+ at author Martin Landa <landa.martin gmail.com>
+"""
+
+import os
+
+import globalvar
+if not os.getenv("GRASS_WXBUNDLED"):
+ globalvar.CheckForWx()
+
+import wx
+import wx.lib.scrolledpanel as scrolled
+
+import dbm
+import gcmd
+from debug import Debug
+from preferences import globalSettings as UserSettings
+
+class DisplayAttributesDialog(wx.Dialog):
+ """
+ Standard dialog used to add/update/display attributes linked
+ to the vector map.
+
+ Attribute data can be selected based on layer and category number
+ or coordinates.
+
+ @param parent
+ @param map vector map
+ @param query query coordinates and distance (used for v.edit)
+ @param cats {layer: cats}
+ @param line feature id (requested for cats)
+ @param style
+ @param pos
+ @param action (add, update, display)
+ """
+ def __init__(self, parent, map,
+ query=None, cats=None, line=None,
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+ pos=wx.DefaultPosition,
+ action="add"):
+ self.parent = parent # mapdisplay.BufferedWindow
+ self.map = map
+ self.action = action
+
+ # ids/cats of selected features
+ # fid : {layer : cats}
+ self.cats = {}
+ self.fid = -1 # feature id
+
+ # get layer/table/column information
+ self.mapDBInfo = dbm.VectorDBInfo(self.map)
+
+ layers = self.mapDBInfo.layers.keys() # get available layers
+
+ # check if db connection / layer exists
+ if len(layers) <= 0:
+ label = _("Database connection "
+ "is not defined in DB file.")
+
+ wx.MessageBox(parent=self.parent,
+ message=_("No attribute table linked to "
+ "vector map <%(vector)s> found. %(msg)s"
+ "\nYou can disable this message from digitization settings. Or "
+ "you can create and link attribute table to the vector map "
+ "using Attribute Table Manager.") %
+ {'vector' : self.map, 'msg' : label},
+ caption=_("Message"), style=wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE)
+ self.mapDBInfo = None
+
+ wx.Dialog.__init__(self, parent=self.parent, id=wx.ID_ANY,
+ title="", style=style, pos=pos)
+
+ # dialog body
+ mainSizer = wx.BoxSizer(wx.VERTICAL)
+
+ # notebook
+ self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
+
+ self.closeDialog = wx.CheckBox(parent=self, id=wx.ID_ANY,
+ label=_("Close dialog on submit"))
+ self.closeDialog.SetValue(True)
+
+ # feature id (text/choice for duplicates)
+ self.fidMulti = wx.Choice(parent=self, id=wx.ID_ANY,
+ size=(150, -1))
+ self.fidMulti.Bind(wx.EVT_CHOICE, self.OnFeature)
+ self.fidText = wx.StaticText(parent=self, id=wx.ID_ANY)
+
+ self.noFoundMsg = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("No attributes found"))
+
+ self.UpdateDialog(query=query, cats=cats)
+
+ # set title
+ if self.action == "update":
+ self.SetTitle(_("Update attributes"))
+ elif self.action == "add":
+ self.SetTitle(_("Add attributes"))
+ else:
+ self.SetTitle(_("Display attributes"))
+
+ # buttons
+ btnCancel = wx.Button(self, wx.ID_CANCEL)
+ btnReset = wx.Button(self, wx.ID_UNDO, _("&Reload"))
+ btnSubmit = wx.Button(self, wx.ID_OK, _("&Submit"))
+
+ btnSizer = wx.StdDialogButtonSizer()
+ btnSizer.AddButton(btnCancel)
+ btnSizer.AddButton(btnReset)
+ btnSizer.SetNegativeButton(btnReset)
+ btnSubmit.SetDefault()
+ btnSizer.AddButton(btnSubmit)
+ btnSizer.Realize()
+
+ mainSizer.Add(item=self.noFoundMsg, proportion=0,
+ flag=wx.EXPAND | wx.ALL, border=5)
+ mainSizer.Add(item=self.notebook, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=5)
+ fidSizer = wx.BoxSizer(wx.HORIZONTAL)
+ fidSizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Feature id:")),
+ proportion=0, border=5,
+ flag=wx.ALIGN_CENTER_VERTICAL)
+ fidSizer.Add(item=self.fidMulti, proportion=0,
+ flag=wx.EXPAND | wx.ALL, border=5)
+ fidSizer.Add(item=self.fidText, proportion=0,
+ flag=wx.EXPAND | wx.ALL, border=5)
+ mainSizer.Add(item=fidSizer, proportion=0,
+ flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5)
+ mainSizer.Add(item=self.closeDialog, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
+ border=5)
+ mainSizer.Add(item=btnSizer, proportion=0,
+ flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+
+ # bindigs
+ btnReset.Bind(wx.EVT_BUTTON, self.OnReset)
+ btnSubmit.Bind(wx.EVT_BUTTON, self.OnSubmit)
+ btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
+
+ self.SetSizer(mainSizer)
+ mainSizer.Fit(self)
+
+ # set min size for dialog
+ w, h = self.GetBestSize()
+ if h < 200:
+ self.SetMinSize((w, 200))
+ else:
+ self.SetMinSize(self.GetBestSize())
+
+ if self.notebook.GetPageCount() == 0:
+ Debug.msg(2, "DisplayAttributesDialog(): Nothing found!")
+ ### self.mapDBInfo = None
+
+ def __SelectAttributes(self, layer):
+ """Select attributes"""
+ pass
+
+ def OnSQLStatement(self, event):
+ """Update SQL statement"""
+ pass
+
+ def GetSQLString(self, updateValues=False):
+ """Create SQL statement string based on self.sqlStatement
+
+ If updateValues is True, update dataFrame according to values
+ in textfields.
+ """
+ sqlCommands = []
+ # find updated values for each layer/category
+ for layer in self.mapDBInfo.layers.keys(): # for each layer
+ table = self.mapDBInfo.layers[layer]["table"]
+ key = self.mapDBInfo.layers[layer]["key"]
+ columns = self.mapDBInfo.tables[table]
+ for idx in range(len(columns[key]['values'])): # for each category
+ updatedColumns = []
+ updatedValues = []
+ for name in columns.keys():
+ if name == key:
+ cat = columns[name]['values'][idx]
+ continue
+ type = columns[name]['type']
+ value = columns[name]['values'][idx]
+ id = columns[name]['ids'][idx]
+ try:
+ newvalue = self.FindWindowById(id).GetValue()
+ except:
+ newvalue = self.FindWindowById(id).GetLabel()
+
+ if newvalue == '':
+ newvalue = None
+
+ if newvalue != value:
+ updatedColumns.append(name)
+ if newvalue is None:
+ updatedValues.append('NULL')
+ else:
+ if type != 'character':
+ updatedValues.append(newvalue)
+ else:
+ updatedValues.append("'" + newvalue + "'")
+ columns[name]['values'][idx] = newvalue
+
+ if self.action != "add" and len(updatedValues) == 0:
+ continue
+
+ if self.action == "add":
+ sqlString = "INSERT INTO %s (%s," % (table, key)
+ else:
+ sqlString = "UPDATE %s SET " % table
+
+ for idx in range(len(updatedColumns)):
+ name = updatedColumns[idx]
+ if self.action == "add":
+ sqlString += name + ","
+ else:
+ sqlString += name + "=" + updatedValues[idx] + ","
+
+ sqlString = sqlString[:-1] # remove last comma
+
+ if self.action == "add":
+ sqlString += ") VALUES (%s," % cat
+ for value in updatedValues:
+ sqlString += str(value) + ","
+ sqlString = sqlString[:-1] # remove last comma
+ sqlString += ")"
+ else:
+ sqlString += " WHERE cat=%s" % cat
+ sqlCommands.append(sqlString)
+ # for each category
+ # for each layer END
+
+ Debug.msg(3, "DisplayAttributesDialog.GetSQLString(): %s" % sqlCommands)
+
+ return sqlCommands
+
+ def OnReset(self, event):
+ """Reset form"""
+ for layer in self.mapDBInfo.layers.keys():
+ table = self.mapDBInfo.layers[layer]["table"]
+ key = self.mapDBInfo.layers[layer]["key"]
+ columns = self.mapDBInfo.tables[table]
+ for idx in range(len(columns[key]['values'])):
+ for name in columns.keys():
+ type = columns[name]['type']
+ value = columns[name]['values'][idx]
+ try:
+ id = columns[name]['ids'][idx]
+ except IndexError:
+ id = wx.NOT_FOUND
+
+ if name != key and id != wx.NOT_FOUND:
+ self.FindWindowById(id).SetValue(str(value))
+
+ def OnCancel(self, event):
+ """Cancel button pressed"""
+ self.parent.parent.dialogs['attributes'] = None
+ if self.parent.parent.digit:
+ self.parent.parent.digit.driver.SetSelected([])
+ self.parent.UpdateMap(render=False)
+ else:
+ self.parent.parent.OnRender(None)
+
+ self.Close()
+
+ def OnSubmit(self, event):
+ """Submit records"""
+ for sql in self.GetSQLString(updateValues=True):
+ enc = UserSettings.Get(group='atm', key='encoding', subkey='value')
+ if not enc and \
+ os.environ.has_key('GRASS_DB_ENCODING'):
+ enc = os.environ['GRASS_DB_ENCODING']
+ if enc:
+ sql = sql.encode(enc)
+
+ gcmd.RunCommand('db.execute',
+ quiet = True,
+ stdin = sql)
+
+ if self.closeDialog.IsChecked():
+ self.OnCancel(event)
+
+ def OnFeature(self, event):
+ self.fid = int(event.GetString())
+ self.UpdateDialog(cats=self.cats, fid=self.fid)
+
+ def GetCats(self):
+ """Get id of selected vector object or 'None' if nothing selected
+
+ @param id if true return ids otherwise cats
+ """
+ if self.fid < 0:
+ return None
+
+ return self.cats[self.fid]
+
+ def GetFid(self):
+ """Get selected feature id"""
+ return self.fid
+
+ def UpdateDialog(self, map=None, query=None, cats=None, fid=-1):
+ """Update dialog
+
+ Return True if updated otherwise False
+ """
+ if map:
+ self.map = map
+ # get layer/table/column information
+ self.mapDBInfo = VectorDBInfo(self.map)
+
+ if not self.mapDBInfo:
+ return False
+
+ self.mapDBInfo.Reset()
+
+ layers = self.mapDBInfo.layers.keys() # get available layers
+
+ # id of selected line
+ if query: # select by position
+ data = self.mapDBInfo.SelectByPoint(query[0],
+ query[1])
+ self.cats = {}
+ if data and data.has_key('Layer'):
+ idx = 0
+ for layer in data['Layer']:
+ layer = int(layer)
+ if data.has_key('Id'):
+ tfid = int(data['Id'][idx])
+ else:
+ tfid = 0 # Area / Volume
+ if not self.cats.has_key(tfid):
+ self.cats[tfid] = {}
+ if not self.cats[tfid].has_key(layer):
+ self.cats[tfid][layer] = []
+ cat = int(data['Category'][idx])
+ self.cats[tfid][layer].append(cat)
+ idx += 1
+ else:
+ self.cats = cats
+
+ if fid > 0:
+ self.fid = fid
+ elif len(self.cats.keys()) > 0:
+ self.fid = self.cats.keys()[0]
+ else:
+ self.fid = -1
+
+ if len(self.cats.keys()) == 1:
+ self.fidMulti.Show(False)
+ self.fidText.Show(True)
+ if self.fid > 0:
+ self.fidText.SetLabel("%d" % self.fid)
+ else:
+ self.fidText.SetLabel(_("Unknown"))
+ else:
+ self.fidMulti.Show(True)
+ self.fidText.Show(False)
+ choices = []
+ for tfid in self.cats.keys():
+ choices.append(str(tfid))
+ self.fidMulti.SetItems(choices)
+ self.fidMulti.SetStringSelection(str(self.fid))
+
+ # reset notebook
+ self.notebook.DeleteAllPages()
+
+ for layer in layers: # for each layer
+ if not query: # select by layer/cat
+ if self.fid > 0 and self.cats[self.fid].has_key(layer):
+ for cat in self.cats[self.fid][layer]:
+ nselected = self.mapDBInfo.SelectFromTable(layer,
+ where="%s=%d" % \
+ (self.mapDBInfo.layers[layer]['key'],
+ cat))
+ else:
+ nselected = 0
+
+ # if nselected <= 0 and self.action != "add":
+ # continue # nothing selected ...
+
+ if self.action == "add":
+ if nselected <= 0:
+ if self.cats[self.fid].has_key(layer):
+ table = self.mapDBInfo.layers[layer]["table"]
+ key = self.mapDBInfo.layers[layer]["key"]
+ columns = self.mapDBInfo.tables[table]
+ for name in columns.keys():
+ if name == key:
+ for cat in self.cats[self.fid][layer]:
+ self.mapDBInfo.tables[table][name]['values'].append(cat)
+ else:
+ self.mapDBInfo.tables[table][name]['values'].append(None)
+ else: # change status 'add' -> 'update'
+ self.action = "update"
+
+ table = self.mapDBInfo.layers[layer]["table"]
+ key = self.mapDBInfo.layers[layer]["key"]
+ columns = self.mapDBInfo.tables[table]
+
+ for idx in range(len(columns[key]['values'])):
+ for name in columns.keys():
+ if name == key:
+ cat = int(columns[name]['values'][idx])
+ break
+
+ # use scrolled panel instead (and fix initial max height of the window to 480px)
+ panel = scrolled.ScrolledPanel(parent=self.notebook, id=wx.ID_ANY,
+ size=(-1, 150))
+ panel.SetupScrolling(scroll_x=False)
+
+ self.notebook.AddPage(page=panel, text=" %s %d / %s %d" % (_("Layer"), layer,
+ _("Category"), cat))
+
+ # notebook body
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ flexSizer = wx.FlexGridSizer (cols=4, hgap=3, vgap=3)
+ flexSizer.AddGrowableCol(3)
+ # columns (sorted by index)
+ names = [''] * len(columns.keys())
+ for name in columns.keys():
+ names[columns[name]['index']] = name
+
+ for name in names:
+ if name == key: # skip key column (category)
+ continue
+
+ vtype = columns[name]['type']
+
+ if columns[name]['values'][idx] is not None:
+ if columns[name]['ctype'] != type(''):
+ value = str(columns[name]['values'][idx])
+ else:
+ value = columns[name]['values'][idx]
+ else:
+ value = ''
+
+ colName = wx.StaticText(parent=panel, id=wx.ID_ANY,
+ label=name)
+ colType = wx.StaticText(parent=panel, id=wx.ID_ANY,
+ label="[" + vtype.lower() + "]")
+ delimiter = wx.StaticText(parent=panel, id=wx.ID_ANY, label=":")
+
+ colValue = wx.TextCtrl(parent=panel, id=wx.ID_ANY, value=value)
+
+ colValue.SetName(name)
+ self.Bind(wx.EVT_TEXT, self.OnSQLStatement, colValue)
+
+ flexSizer.Add(colName, proportion=0,
+ flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+ flexSizer.Add(colType, proportion=0,
+ flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+ flexSizer.Add(delimiter, proportion=0,
+ flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+ flexSizer.Add(colValue, proportion=1,
+ flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
+ # add widget reference to self.columns
+ columns[name]['ids'].append(colValue.GetId()) # name, type, values, id
+ # for each attribute (including category) END
+ border.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
+ panel.SetSizer(border)
+ # for each category END
+ # for each layer END
+
+ if self.notebook.GetPageCount() == 0:
+ self.noFoundMsg.Show(True)
+ else:
+ self.noFoundMsg.Show(False)
+
+ self.Layout()
+
+ return True
+
+class ModifyTableRecord(wx.Dialog):
+ """Dialog for inserting/updating table record"""
+ def __init__(self, parent, id, title, data, keyEditable=(-1, True),
+ style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
+ """
+ Notes:
+ 'Data' is a list: [(column, value)]
+ 'KeyEditable' (id, editable?) indicates if textarea for key column
+ is editable(True) or not.
+ """
+ wx.Dialog.__init__(self, parent, id, title, style=style)
+
+ self.keyId = keyEditable[0]
+
+ self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
+
+ self.dataPanel = scrolled.ScrolledPanel(parent=self.panel, id=wx.ID_ANY,
+ style=wx.TAB_TRAVERSAL)
+ self.dataPanel.SetupScrolling(scroll_x=False)
+
+ #
+ # buttons
+ #
+ self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
+ self.btnSubmit = wx.Button(self.panel, wx.ID_OK, _("Submit"))
+ self.btnSubmit.SetDefault()
+
+ #
+ # data area
+ #
+ self.widgets = []
+ id = 0
+ self.box = False
+ self.cat = None
+ for column, value in data:
+ if keyEditable[0] == id:
+ self.cat = int(value)
+ if keyEditable[1] == False:
+ self.box = True
+ id += 1
+ continue
+ else:
+ valueWin = wx.SpinCtrl(parent=self.dataPanel, id=wx.ID_ANY,
+ value=value, min=-1e9, max=1e9, size=(250, -1))
+ else:
+ valueWin = wx.TextCtrl(parent=self.dataPanel, id=wx.ID_ANY,
+ value=value, size=(250, -1))
+
+ label = wx.StaticText(parent=self.dataPanel, id=wx.ID_ANY,
+ label=column + ":")
+
+ self.widgets.append((label.GetId(),
+ valueWin.GetId()))
+
+ id += 1
+
+ self.__Layout()
+
+ # winSize = self.GetSize()
+ # fix height of window frame if needed
+ # if winSize[1] > 480:
+ # winSize[1] = 480
+ # self.SetSize(winSize)
+ # self.SetMinSize(winSize)
+
+ def __Layout(self):
+ """Do layout"""
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ if self.box:
+ box = wx.StaticBox(parent=self.panel, id=wx.ID_ANY,
+ label=" %s %d " % (_("Category"), self.cat))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
+ # data area
+ dataSizer = wx.FlexGridSizer (cols=2, hgap=3, vgap=3)
+ dataSizer.AddGrowableCol(1)
+
+ for labelId, valueId in self.widgets:
+ label = self.FindWindowById(labelId)
+ value = self.FindWindowById(valueId)
+
+ dataSizer.Add(label, proportion=0,
+ flag=wx.ALIGN_CENTER_VERTICAL)
+ dataSizer.Add(value, proportion=0,
+ flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
+
+ self.dataPanel.SetAutoLayout(True)
+ self.dataPanel.SetSizer(dataSizer)
+ dataSizer.Fit(self.dataPanel)
+
+ if self.box:
+ boxSizer.Add(item=self.dataPanel, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=5)
+
+ # buttons
+ btnSizer = wx.StdDialogButtonSizer()
+ btnSizer.AddButton(self.btnCancel)
+ btnSizer.AddButton(self.btnSubmit)
+ btnSizer.Realize()
+
+ if not self.box:
+ sizer.Add(item=self.dataPanel, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=5)
+ else:
+ sizer.Add(item=boxSizer, proportion=1,
+ flag=wx.EXPAND | wx.ALL, border=5)
+
+
+ sizer.Add(item=btnSizer, proportion=0,
+ flag=wx.EXPAND | wx.ALL, border=5)
+
+ #sizer.SetSizeHints(self.panel)
+ self.panel.SetAutoLayout(True)
+ self.panel.SetSizer(sizer)
+ sizer.Fit(self.panel)
+
+ self.Layout()
+
+ # set window frame size (min & max)
+ minFrameHeight = 150
+ maxFrameHeight = 2 * minFrameHeight
+ if self.GetSize()[1] > minFrameHeight:
+ self.SetMinSize((self.GetSize()[0], minFrameHeight))
+ else:
+ self.SetMinSize(self.GetSize())
+
+ if self.GetSize()[1] > maxFrameHeight:
+ self.SetSize((self.GetSize()[0], maxFrameHeight))
+ else:
+ self.SetSize(self.panel.GetSize())
+
+ def GetValues(self, columns=None):
+ """Return list of values (casted to string).
+
+ If columns is given (list), return only values of given columns.
+ """
+ valueList = []
+ for labelId, valueId in self.widgets:
+ column = self.FindWindowById(labelId).GetLabel().replace(':', '')
+ if columns is None or column in columns:
+ value = str(self.FindWindowById(valueId).GetValue())
+ valueList.append(value)
+
+ # add key value
+ if self.box:
+ valueList.insert(self.keyId, str(self.cat))
+
+ return valueList
Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp.py 2009-03-14 19:29:22 UTC (rev 36381)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp.py 2009-03-14 19:31:40 UTC (rev 36382)
@@ -57,6 +57,7 @@
import disp_print
import gcmd
import dbm
+import dbm_dialogs
import histogram
import profile
import globalvar
@@ -1195,11 +1196,12 @@
mapName = self.tree.GetPyData(self.tree.layer_selected)[0]['maplayer'].name
if self.dialogs['attributes'] is None:
- self.dialogs['attributes'] = dbm.DisplayAttributesDialog(parent=self.MapWindow,
- map=mapName,
- query=((east, north), qdist),
- pos=posWindow,
- action="update")
+ self.dialogs['attributes'] = \
+ dbm_dialogs.DisplayAttributesDialog(parent=self.MapWindow,
+ map=mapName,
+ query=((east, north), qdist),
+ pos=posWindow,
+ action="update")
else:
# selection changed?
if not self.dialogs['attributes'].mapDBInfo or \
Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py 2009-03-14 19:29:22 UTC (rev 36381)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py 2009-03-14 19:31:40 UTC (rev 36382)
@@ -25,6 +25,7 @@
import wx
import dbm
+import dbm_dialogs
import gdialogs
import gcmd
import utils
@@ -1139,10 +1140,10 @@
posWindow = self.ClientToScreen((self.mouse['end'][0] + self.dialogOffset,
self.mouse['end'][1] + self.dialogOffset))
- addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=mapLayer,
- cats=cats,
- pos=posWindow,
- action="add")
+ addRecordDlg = dbm_dialogs.DisplayAttributesDialog(parent=self, map=mapLayer,
+ cats=cats,
+ pos=posWindow,
+ action="add")
if addRecordDlg.mapDBInfo and \
addRecordDlg.ShowModal() == wx.ID_OK:
sqlfile = tempfile.NamedTemporaryFile(mode="w")
@@ -1234,9 +1235,10 @@
if digitToolbar.GetAction() == "displayAttrs":
# select attributes based on coordinates (all layers)
if self.parent.dialogs['attributes'] is None:
- self.parent.dialogs['attributes'] = dbm.DisplayAttributesDialog(parent=self, map=mapLayer,
- cats=cats,
- action="update")
+ self.parent.dialogs['attributes'] = \
+ dbm_dialogs.DisplayAttributesDialog(parent=self, map=mapLayer,
+ cats=cats,
+ action="update")
else:
# upgrade dialog
self.parent.dialogs['attributes'].UpdateDialog(cats=cats)
@@ -1925,10 +1927,10 @@
(UserSettings.Get(group='vdigit', key="category", subkey='value'), )
}}
- addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map,
- cats=cats,
- pos=posWindow,
- action="add")
+ addRecordDlg = dbm_dialogs.DisplayAttributesDialog(parent=self, map=map,
+ cats=cats,
+ pos=posWindow,
+ action="add")
if addRecordDlg.mapDBInfo and \
addRecordDlg.ShowModal() == wx.ID_OK:
sqlfile = tempfile.NamedTemporaryFile(mode="w")
More information about the grass-commit
mailing list