[GRASS-SVN] r29496 - in grass/trunk/gui/wxpython: . gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Dec 22 17:39:05 EST 2007
Author: martinl
Date: 2007-12-22 17:39:05 -0500 (Sat, 22 Dec 2007)
New Revision: 29496
Modified:
grass/trunk/gui/wxpython/gui_modules/dbm.py
grass/trunk/gui/wxpython/wxgrass
grass/trunk/gui/wxpython/wxgui.py
Log:
wxGUI: Ability to specify workspace file from command-line, e.g. wxgrass file.grc
Fix Attribute Table Manager when no DB connection is defined.
Modified: grass/trunk/gui/wxpython/gui_modules/dbm.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/dbm.py 2007-12-21 23:48:55 UTC (rev 29495)
+++ grass/trunk/gui/wxpython/gui_modules/dbm.py 2007-12-22 22:39:05 UTC (rev 29496)
@@ -40,6 +40,7 @@
import wx.lib.mixins.listctrl as listmix
import wx.lib.flatnotebook as FN
import wx.lib.colourselect as csel
+import wx.lib.scrolledpanel as scrolled
import sqlbuilder
import grassenv
@@ -362,11 +363,11 @@
self.mapDBInfo = VectorDBInfo(self.vectmap)
if len(self.mapDBInfo.layers.keys()) == 0:
- wx.MessageBox(patent=self.parent,
+ wx.MessageBox(parent=self.parent,
message=_("Database connection for map <%s> "
- "is not defined in DB file") % self.vectmap,
- caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
- return
+ "is not defined in DB file.") % self.vectmap,
+ caption=_("Attribute Table Manager"),
+ style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
#
# default settings (TODO global settings file)
@@ -439,7 +440,7 @@
# buttons
#
self.btnApply = wx.Button(parent=self, id=wx.ID_APPLY)
- self.btnQuit = wx.Button(parent=self, id=wx.ID_CANCEL)
+ self.btnQuit = wx.Button(parent=self, id=wx.ID_EXIT)
# self.btn_unselect = wx.Button(self, -1, "Unselect")
# events
@@ -593,11 +594,15 @@
self.browsePage.SetSelection(0) # select first layer
- self.layer = self.mapDBInfo.layers.keys()[0]
- self.OnChangeSql(None)
- self.log.write(_("Number of loaded records: %d") % \
+ try:
+ self.layer = self.mapDBInfo.layers.keys()[0]
+ self.OnChangeSql(None)
+ self.log.write(_("Number of loaded records: %d") % \
self.FindWindowById(self.layerPage[self.layer]['data']).GetItemCount())
-
+ except IndexError:
+ self.layer = None
+
+
def __createManageTablePage(self, onlyLayer=-1):
"""Create manage page (create/link and alter tables)"""
for layer in self.mapDBInfo.layers.keys():
@@ -744,7 +749,10 @@
self.layerPage[layer]['dbinfo'] = infoCollapse.GetId()
self.manageTablePage.SetSelection(0) # select first layer
- self.layer = self.mapDBInfo.layers.keys()[0]
+ try:
+ self.layer = self.mapDBInfo.layers.keys()[0]
+ except IndexError:
+ self.layer = None
def __createTableDesc(self, parent, table):
"""Create list with table description"""
@@ -866,10 +874,11 @@
mainSizer = wx.BoxSizer(wx.VERTICAL)
# buttons
- btnSizer = wx.StdDialogButtonSizer()
- btnSizer.AddButton(self.btnQuit)
- btnSizer.AddButton(self.btnApply)
- btnSizer.Realize()
+ btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+ btnSizer.Add(item=self.btnQuit, proportion=1,
+ flag=wx.ALL | wx.ALIGN_RIGHT | wx.SHAPED, border=5)
+ btnSizer.Add(item=self.btnApply,
+ flag=wx.ALL, border=5)
mainSizer.Add(item=self.notebook, proportion=1, flag=wx.EXPAND)
mainSizer.Add(item=btnSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
@@ -1678,11 +1687,11 @@
# if self.browsePage.GetPageText(page).replace('Layer ', '').strip() == str(layer):
# self.browsePage.DeletePage(page)
# break
- self.browsePage.RemovePage(self.mapDBInfo.layers.keys().index(layer))
- self.manageTablePage.RemovePage(self.mapDBInfo.layers.keys().index(layer))
+ self.browsePage.DeletePage(self.mapDBInfo.layers.keys().index(layer))
+ self.manageTablePage.DeletePage(self.mapDBInfo.layers.keys().index(layer))
# set current page selection
self.notebook.SetSelection(2)
-
+
# fetch fresh db info
self.mapDBInfo = VectorDBInfo(self.vectmap)
@@ -1705,15 +1714,25 @@
self.layerList.Populate(update=True)
# update selected widgets
listOfLayers = map(str, self.mapDBInfo.layers.keys())
+ ### delete layer page
self.manageLayerBook.deleteLayer.SetItems(listOfLayers)
- self.manageLayerBook.deleteLayer.SetStringSelection(listOfLayers[0])
- tableName = self.mapDBInfo.layers[int(listOfLayers[0])]['table']
+ if len(listOfLayers) > 0:
+ self.manageLayerBook.deleteLayer.SetStringSelection(listOfLayers[0])
+ tableName = self.mapDBInfo.layers[int(listOfLayers[0])]['table']
+ maxLayer = max(self.mapDBInfo.layers.keys())
+ else:
+ tableName = ''
+ maxLayer = 0
self.manageLayerBook.deleteTable.SetLabel( \
_('Drop also linked attribute table (%s)') % \
tableName)
+ ### add layer page
self.manageLayerBook.addLayerWidgets['layer'][1].SetValue(\
- max(self.mapDBInfo.layers.keys())+1)
-
+ maxLayer+1)
+ ### modify layer
+ self.manageLayerBook.modifyLayerWidgets['layer'][1].SetItems(listOfLayers)
+ self.manageLayerBook.OnChangeLayer(event=None)
+
# def OnMapClick(self, event):
# """
# Gets coordinates from mouse clicking on display window
@@ -1858,6 +1877,8 @@
int(self.table[column]['length']))
i = i + 1
+ self.SendSizeEvent()
+
return itemData
class LayerListCtrl(wx.ListCtrl,
@@ -1921,6 +1942,8 @@
if self.GetColumnWidth(col=i) < 60:
self.SetColumnWidth(col=i, width=60)
+ self.SendSizeEvent()
+
return itemData
class LayerBook(wx.Notebook):
@@ -1962,8 +1985,8 @@
self.defaultTables = self.__getTables(self.defaultDriver, self.defaultDatabase)
try:
self.defaultColumns = self.__getColumns(self.defaultDriver, self.defaultDatabase,
- listOfTables[0])
- except:
+ self.defaultTables[0])
+ except IndexError:
self.defaultColumns = []
self.__createAddPage()
@@ -1975,6 +1998,10 @@
self.addPanel = wx.Panel(parent=self, id=wx.ID_ANY)
self.AddPage(page=self.addPanel, text=_("Add new layer"))
+ try:
+ maxLayer = max(self.mapDBInfo.layers.keys())
+ except ValueError:
+ maxLayer = 0
#
# list of layer widgets (label, value)
#
@@ -1982,7 +2009,7 @@
(wx.StaticText(parent=self.addPanel, id=wx.ID_ANY,
label='%s:' % _("Layer")),
wx.SpinCtrl(parent=self.addPanel, id=wx.ID_ANY, size=(65, -1),
- initial=max(self.mapDBInfo.layers.keys())+1,
+ initial=maxLayer+1,
min=1, max=1e6)),
'driver':
(wx.StaticText(parent=self.addPanel, id=wx.ID_ANY,
@@ -2148,15 +2175,22 @@
self.deleteLayer = wx.ComboBox(parent=self.deletePanel, id=wx.ID_ANY, size=(100, -1),
style=wx.CB_SIMPLE | wx.CB_READONLY,
choices=map(str, self.mapDBInfo.layers.keys()))
- self.deleteLayer.SetSelection(0)
+ self.deleteLayer.SetSelection(0)
self.deleteLayer.Bind(wx.EVT_COMBOBOX, self.OnChangeLayer)
- tableName = self.mapDBInfo.layers[int(self.deleteLayer.GetStringSelection())]['table']
-
+ try:
+ tableName = self.mapDBInfo.layers[int(self.deleteLayer.GetStringSelection())]['table']
+ except ValueError:
+ tableName = ''
+
self.deleteTable = wx.CheckBox(parent=self.deletePanel, id=wx.ID_ANY,
label=_('Drop also linked attribute table (%s)') % \
- tableName)
+ tableName)
+ if tableName == '':
+ self.deleteLayer.Enable(False)
+ self.deleteTable.Enable(False)
+
btnDelete = wx.Button(self.deletePanel, wx.ID_DELETE, _("&Delete layer"),
size=(125,-1))
btnDelete.Bind(wx.EVT_BUTTON, self.OnDeleteLayer)
@@ -2241,17 +2275,24 @@
# set default values for widgets
self.modifyLayerWidgets['layer'][1].SetSelection(0)
- layer = int(self.modifyLayerWidgets['layer'][1].GetStringSelection())
- driver = self.mapDBInfo.layers[layer]['driver']
- database = self.mapDBInfo.layers[layer]['database']
- table = self.mapDBInfo.layers[layer]['table']
- listOfColumns = self.__getColumns(driver, database, table)
- self.modifyLayerWidgets['driver'][1].SetStringSelection(driver)
- self.modifyLayerWidgets['database'][1].SetValue(database)
- self.modifyLayerWidgets['table'][1].SetStringSelection(table)
- self.modifyLayerWidgets['key'][1].SetItems(listOfColumns)
- self.modifyLayerWidgets['key'][1].SetSelection(0)
+ try:
+ layer = int(self.modifyLayerWidgets['layer'][1].GetStringSelection())
+ except ValueError:
+ layer = None
+ for label in self.modifyLayerWidgets.keys():
+ self.modifyLayerWidgets[label][1].Enable(False)
+ if layer:
+ driver = self.mapDBInfo.layers[layer]['driver']
+ database = self.mapDBInfo.layers[layer]['database']
+ table = self.mapDBInfo.layers[layer]['table']
+ listOfColumns = self.__getColumns(driver, database, table)
+ self.modifyLayerWidgets['driver'][1].SetStringSelection(driver)
+ self.modifyLayerWidgets['database'][1].SetValue(database)
+ self.modifyLayerWidgets['table'][1].SetStringSelection(table)
+ self.modifyLayerWidgets['key'][1].SetItems(listOfColumns)
+ self.modifyLayerWidgets['key'][1].SetSelection(0)
+
# events
self.modifyLayerWidgets['layer'][1].Bind(wx.EVT_COMBOBOX, self.OnChangeLayer)
# self.modifyLayerWidgets['driver'][1].Bind(wx.EVT_CHOICE, self.OnDriverChanged)
@@ -2447,6 +2488,13 @@
# increase layer number
layerWin.SetValue(layer+1)
+ if len(self.mapDBInfo.layers.keys()) == 1:
+ # first layer add --- enable previously disabled widgets
+ self.deleteLayer.Enable()
+ self.deleteTable.Enable()
+ for label in self.modifyLayerWidgets.keys():
+ self.modifyLayerWidgets[label][1].Enable()
+
def OnDeleteLayer(self, event):
"""Delete layer"""
@@ -2478,6 +2526,13 @@
# update db info
self.mapDBInfo = self.parentDialog.mapDBInfo
+ if len(self.mapDBInfo.layers.keys()) == 0:
+ # disable selected widgets
+ self.deleteLayer.Enable(False)
+ self.deleteTable.Enable(False)
+ for label in self.modifyLayerWidgets.keys():
+ self.modifyLayerWidgets[label][1].Enable(False)
+
event.Skip()
def OnChangeLayer(self, event):
@@ -2488,7 +2543,7 @@
try:
layer = self.mapDBInfo.layers.keys()[0]
except:
- layer = 1
+ return
if self.GetCurrentPage() == self.modifyPanel:
driver = self.mapDBInfo.layers[layer]['driver']
@@ -2821,9 +2876,14 @@
else: # change status 'add' -> 'update'
self.action = "update"
- panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
+ # use scrolled panel instead (and fix initial max height of the window to 480px)
+ ### panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
+ panel = scrolled.ScrolledPanel(parent=self.notebook, id=wx.ID_ANY,
+ size=(-1, 300))
+ panel.SetupScrolling(scroll_x=False)
+
self.notebook.AddPage(page=panel, text=_(" %s %d ") % (_("Layer"), layer))
-
+
# notebook body
border = wx.BoxSizer(wx.VERTICAL)
@@ -2847,8 +2907,9 @@
flexSizer.AddGrowableCol(3)
# columns
for name in columns.keys():
- type = columns[name]['type']
- value = columns[name]['values'][idx]
+ vtype = columns[name]['type']
+ value = str(columns[name]['values'][idx])
+
if name.lower() == "cat":
box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
label=" %s %s " % (_("Category"), value))
@@ -2861,11 +2922,10 @@
colName = wx.StaticText(parent=panel, id=wx.ID_ANY,
label=name)
colType = wx.StaticText(parent=panel, id=wx.ID_ANY,
- label="[" + type.lower() + "]")
+ label="[" + vtype.lower() + "]")
delimiter = wx.StaticText(parent=panel, id=wx.ID_ANY, label=":")
- colValue = wx.TextCtrl(parent=panel, id=wx.ID_ANY, value=value,
- size=(-1, -1)) # TODO: validator
+ colValue = wx.TextCtrl(parent=panel, id=wx.ID_ANY, value=value) # TODO: validator
colValue.SetName(name)
self.Bind(wx.EVT_TEXT, self.OnSQLStatement, colValue)
@@ -3083,7 +3143,7 @@
for column, value in data:
label = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
label=column + ":")
- value = wx.TextCtrl(parent=self.panel, id=wx.ID_ANY,
+ value = wx.Texttrl(parent=self.panel, id=wx.ID_ANY,
value=value, size=(250, -1))
if keyEditable[0] > -1: # id given
if keyEditable[0] == id:
Modified: grass/trunk/gui/wxpython/wxgrass
===================================================================
--- grass/trunk/gui/wxpython/wxgrass 2007-12-21 23:48:55 UTC (rev 29495)
+++ grass/trunk/gui/wxpython/wxgrass 2007-12-22 22:39:05 UTC (rev 29496)
@@ -10,7 +10,12 @@
#if [ "$SYSTEM" = "Darwin" ] ; then
# pythonw "$GISBASE/etc/wx/wxgui.py" -name wxgui_py
#else
- python "$GISBASE/etc/wx/wxgui.py" -name wxgui_py &
+if [ ! -z "$1" ] ; then
+ # load workspace file
+ python "$GISBASE/etc/wx/wxgui.py" "--workspace" "$1" &
+else
+ python "$GISBASE/etc/wx/wxgui.py" &
+fi
#fi
exit 0
Modified: grass/trunk/gui/wxpython/wxgui.py
===================================================================
--- grass/trunk/gui/wxpython/wxgui.py 2007-12-21 23:48:55 UTC (rev 29495)
+++ grass/trunk/gui/wxpython/wxgui.py 2007-12-22 22:39:05 UTC (rev 29496)
@@ -28,7 +28,7 @@
import traceback
import types
import re
-# for GRC (workspace file) parsering
+### for GRC (workspace file) parsering
# xmlproc not available on Mac OS
# from xml.parsers.xmlproc import xmlproc
# from xml.parsers.xmlproc import xmlval
@@ -77,8 +77,8 @@
import gui_modules.georect as georect
import gui_modules.dbm as dbm
import gui_modules.globalvar as globalvar
+from gui_modules.debug import Debug as Debug
from icons.icon import Icons as Icons
-from gui_modules.debug import Debug as Debug
menucmd = {}
@@ -88,7 +88,8 @@
GRASS GIS. Includes command console page for typing GRASS
(and other) commands, tree widget page for managing GIS map layers.
"""
- def __init__(self, parent, id=wx.ID_ANY, title=_("GRASS GIS Layer Manager")):
+ def __init__(self, parent, id=wx.ID_ANY, title=_("GRASS GIS Layer Manager"),
+ workspace=None):
self.parent = parent
self.baseTitle = title
self.iconsize = (16, 16)
@@ -117,7 +118,7 @@
self.curr_page = '' # currently selected page for layer tree notebook
self.curr_pagenum = '' # currently selected page number for layer tree notebook
self.encoding = 'ISO-8859-1' # default encoding for display fonts
- self.workspaceFile = None # workspace file
+ self.workspaceFile = workspace # workspace file
# bindings
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
@@ -145,6 +146,14 @@
# start default initial display
self.NewDisplay()
+
+ # load workspace file if requested
+ if (self.workspaceFile):
+ # load given workspace file
+ if self.LoadGrcXmlToLayerTree(self.workspaceFile):
+ self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
+ else:
+ self.workspaceFile = None
def __doLayout(self):
"""Do Layout (unused bacause of aui manager...)"""
@@ -534,13 +543,11 @@
maptree.Map.ReverseListOfLayers()
file.close()
- except Exception, err:
- dlg = wx.MessageDialog(parent=self,
- message=_("Unable to read workspace file <%s>.\n\n%s") % \
- (filename, err),
- caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
- dlg.ShowModal()
- dlg.Destroy()
+ except IOError, err:
+ wx.MessageBox(parent=self,
+ message=_("Unable to read workspace file <%s>.%s%s") % \
+ (filename, os.linesep, err),
+ caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
return False
return True
@@ -1235,9 +1242,13 @@
"""
GMApp class
"""
+ def __init__(self, workspace=None):
+ self.workspaceFile = workspace
+
+ # call parent class initializer
+ wx.App.__init__(self)
+
def OnInit(self):
- # reexec_with_pythonw()
-
# initialize all available image handlers
wx.InitAllImageHandlers()
@@ -1250,7 +1261,9 @@
wx.Yield()
# create and show main frame
- mainframe = GMFrame(parent=None, id=wx.ID_ANY, title=_("GRASS GIS Layer Manager"))
+ mainframe = GMFrame(parent=None, id=wx.ID_ANY,
+ title=_("GRASS GIS Layer Manager"),
+ workspace = self.workspaceFile)
mainframe.Show()
self.SetTopWindow(mainframe)
@@ -1376,57 +1389,73 @@
self.value += ch
def reexec_with_pythonw():
- if sys.platform == 'darwin' and\
+ if sys.platform == 'darwin' and \
not sys.executable.endswith('MacOS/Python'):
print >> sys.stderr, _('re-executing using pythonw')
- os.execvp('pythonw',['pythonw',__file__] + sys.argv[1:])
+ os.execvp('pythonw', ['pythonw', __file__] + sys.argv[1:])
-### 2007/11 -- seems to be unused...
-# class GRasterDialog(wx.Frame):
-# def __init__(self,parent,id=-1,title="Set raster layer"):
-# wx.Frame.__init__(self, parent, id , title, size=(50,600))
+class Usage(Exception):
+ def __init__(self, msg):
+ self.msg = msg
-# # sizers
-# sizer = wx.BoxSizer(wx.VERTICAL)
-# buttsizer = wx.BoxSizer(wx.HORIZONTAL)
+def printHelp():
+ """Print program help"""
+ print >> sys.stderr, "Usage:"
+ print >> sys.stderr, " python wxgui.py [options]"
+ print >> sys.stderr, "%sOptions:" % os.linesep
+ print >> sys.stderr, " -w\t--workspace file\tWorkspace file to load"
+ sys.exit(0)
-# # labels
-# lmap = wx.StaticText(self,-1,"Map name")
-# lvalues = wx.StaticText(self,-1,"List of values to be displayed")
-# lopaque = wx.StaticText(self,-1,"Transparency")
+def process_opt(opts, args):
+ """Process command-line arguments"""
+ workspaceFile = None
+ for o, a in opts:
+ if o in ("-h", "--help"):
+ printHelp()
+
+ if o in ("-w", "--workspace"):
+ if a != '':
+ workspaceFile = str(a)
+ else:
+ workspaceFile = args.pop(0)
-# # checkboxes
-# cboverlay = wx.CheckBox(self, -1, "Overlay (non-null values)")
-# cboverlay.SetValue(True)
+ return (workspaceFile,)
-# # text entries
-# tmapname = wx.TextCtrl(self,-1,size=(-1,-1))
-# tvalues = wx.TextCtrl(self,-1,size=(-1,-1))
+def main(argv=None):
+ #
+ # reexec for MacOS
+ #
+ reexec_with_pythonw()
-# # buttons
-# bsize=(75,-1)
-# bok = wx.Button(self,-1, "OK",size=bsize)
-# bapply = wx.Button(self,-1, "Apply", size=bsize)
-# bcancel = wx.Button(self,-1, "Cancel", size=bsize)
+ #
+ # process command-line arguments
+ #
+ if argv is None:
+ argv = sys.argv
+ try:
+ try:
+ opts, args = getopt.getopt(argv[1:], "hw:",
+ ["help", "workspace"])
+ except getopt.error, msg:
+ raise Usage(msg)
-# buttsizer.Add(bok, 0, wx.ADJUST_MINSIZE, 1)
-# buttsizer.Add(bapply, 0, wx.ADJUST_MINSIZE, 1)
-# buttsizer.Add(bcancel, 0, wx.ADJUST_MINSIZE, 1)
-# sizer.Add(lopaque,1, wx.EXPAND, 1)
-# sizer.Add(lmap,0, wx.EXPAND, 1)
-# sizer.Add(tmapname,0, wx.EXPAND, 1)
-# sizer.Add(lvalues,0, wx.EXPAND, 1)
-# sizer.Add(tvalues,0, wx.EXPAND, 1)
-# sizer.Add(cboverlay,1, wx.EXPAND, 1)
-# sizer.Add(buttsizer,0, wx.ADJUST_MINSIZE, 1)
-# self.SetSizer(sizer)
-# sizer.Fit(self)
-# self.Layout()
+ except Usage, err:
+ print >> sys.stderr, err.msg
+ print >> sys.stderr, "for help use --help"
+ printHelp()
+ workspaceFile = process_opt(opts, args)[0]
+
+ # replace with the appropriate catalog name
+ gettext.install("GMApp")
+
+ #
+ # run application
+ #
+ app = GMApp(workspaceFile)
+ app.MainLoop()
+
if __name__ == "__main__":
- reexec_with_pythonw()
-
- import gettext
- gettext.install("GMApp") # replace with the appropriate catalog name
- app = GMApp(0)
- app.MainLoop()
+ import getopt
+ import gettext
+ sys.exit(main())
More information about the grass-commit
mailing list