From neteler at itc.it Fri Mar 23 11:16:28 2007 From: neteler at itc.it (Markus Neteler) Date: Fri Mar 23 11:19:15 2007 Subject: [GRASS-Addons] GRASS Addons SVN commit list activation Message-ID: <20070323101628.GA30014@bartok.itc.it> Hi GRASS Addons SVN Committers, (cc user list FYI) to simplify the email notification and to enable you to manage this yourself and to enable others to subscribe to the diff email broadcast, I have set up a mailing list for this: http://grass.itc.it/mailman/listinfo/grass-commit-addons I have taken liberty to subscribe the current SVN committers. Please manage your account as desired, you will receive a related Mailman message with password. Any interested folks may subscribe to the list as well. Regards, Markus -- Markus Neteler http://mpa.itc.it/markus/ FBK-irst - Centro per la Ricerca Scientifica e Tecnologica MPBA - Predictive Models for Biol. & Environ. Data Analysis Via Sommarive, 18 - 38050 Povo (Trento), Italy From neteler at grass.itc.it Fri Mar 23 11:27:02 2007 From: neteler at grass.itc.it (neteler@grass.itc.it) Date: Fri Mar 23 11:27:03 2007 Subject: [grass-addons] r264 - trunk/grassaddons Message-ID: <200703231027.l2NAR2W3015742@grass.itc.it> Author: neteler Date: 2007-03-23 11:27:02 +0100 (Fri, 23 Mar 2007) New Revision: 264 Added: trunk/grassaddons/contributors.csv Log: started list of contributors with login ID Added: trunk/grassaddons/contributors.csv =================================================================== --- trunk/grassaddons/contributors.csv (rev 0) +++ trunk/grassaddons/contributors.csv 2007-03-23 10:27:02 UTC (rev 264) @@ -0,0 +1,8 @@ +barton,Michael Barton +calvelo,Daniel Calvelo Aros +cepicky,Jachym Cepicky +chemin,Yann Chemin +clements,Glynn Clements +kindl,Florian Kindl +landa,Martin Landa +neteler,Markus Neteler From neteler at grass.itc.it Fri Mar 23 11:40:18 2007 From: neteler at grass.itc.it (neteler@grass.itc.it) Date: Fri Mar 23 11:40:19 2007 Subject: [grass-addons] r265 - trunk/grassaddons Message-ID: <200703231040.l2NAeIwh015843@grass.itc.it> Author: neteler Date: 2007-03-23 11:40:17 +0100 (Fri, 23 Mar 2007) New Revision: 265 Modified: trunk/grassaddons/README Log: link to RFC 2: Legal aspects of code contributions Modified: trunk/grassaddons/README =================================================================== --- trunk/grassaddons/README 2007-03-23 10:27:02 UTC (rev 264) +++ trunk/grassaddons/README 2007-03-23 10:40:17 UTC (rev 265) @@ -5,8 +5,11 @@ The submmission must be compliant with the GRASS submission rules as found in the GRASS 6 source code -and RFC2 (Legal aspects of submission). +and RFC2 (Legal aspects of submission): + http://mpa.itc.it/markus/grass63progman/rfc/pages.html + + Read access is granted to the public, write access must be requested. From barton at grass.itc.it Fri Mar 23 16:13:14 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Mar 23 16:13:16 2007 Subject: [grass-addons] r266 - trunk/grassaddons/gui/Gism Message-ID: <200703231513.l2NFDEMC017515@grass.itc.it> Author: barton Date: 2007-03-23 16:13:05 +0100 (Fri, 23 Mar 2007) New Revision: 266 Modified: trunk/grassaddons/gui/Gism/menuform.py Log: Controls now show in dialog as soon as it's opened (no need to resize window). Also improved error trapping for trying to press OK or Cancel with no options selected. Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-23 10:40:17 UTC (rev 265) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-23 15:13:05 UTC (rev 266) @@ -444,16 +444,19 @@ self.tabsizer[section].Fit( self.tab[section] ) self.tab[section].SetAutoLayout(True) self.tab[section].SetSizer( self.tabsizer[section] ) + self.tab[section].Layout() - self.panelsizer.Fit( self.notebookpanel ) +# self.panelsizer.Fit( self.notebookpanel ) self.panelsizer.SetSizeHints( self.notebookpanel ) self.notebookpanel.SetSizer(self.panelsizer) self.notebookpanel.SetAutoLayout(True) + self.notebookpanel.Layout() self.guisizer.SetSizeHints(self) self.SetAutoLayout(True) self.SetSizer(self.guisizer) - self.guisizer.Fit(self) +# self.guisizer.Fit(self) + self.Layout() def OnColorButton(self, event): @@ -512,7 +515,7 @@ errors = 0 errStr = "" for flag in grass_task.flags: - if flag['value']: + if 'value' in flag: cmd += ' -' + flag['name'] for p in grass_task.params: if p['value'] == '' and p['required'] != 'no': @@ -523,7 +526,6 @@ if errors: self.OnError(errStr) return None -# print cmd return cmd def OnOK(self, event): From barton at grass.itc.it Fri Mar 23 16:21:27 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Mar 23 16:21:28 2007 Subject: [grass-addons] r267 - trunk/grassaddons/gui/Gism Message-ID: <200703231521.l2NFLRrn017540@grass.itc.it> Author: barton Date: 2007-03-23 16:21:18 +0100 (Fri, 23 Mar 2007) New Revision: 267 Modified: trunk/grassaddons/gui/Gism/select.py Log: GIS element selector (select.Select) now automatically expands current mapset item at startup. Also, mapset explicitly added to all map names. Modified: trunk/grassaddons/gui/Gism/select.py =================================================================== --- trunk/grassaddons/gui/Gism/select.py 2007-03-23 15:13:05 UTC (rev 266) +++ trunk/grassaddons/gui/Gism/select.py 2007-03-23 15:21:18 UTC (rev 267) @@ -109,13 +109,13 @@ #TODO: make current mapset node expanded dir_node = self.AddItem('Mapset: '+dir) self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) - self.tree.Expand(dir_node) try: elem_list = os.listdir(os.path.join (location_path, dir, element)) for elem in elem_list: - self.AddItem(elem, parent=dir_node) + self.AddItem(elem+'@'+dir, parent=dir_node) except: continue + self.tree.Expand(dir_node) else: dir_node = self.AddItem('Mapset: '+dir) self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) From barton at grass.itc.it Fri Mar 23 23:26:32 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Mar 23 23:26:33 2007 Subject: [grass-addons] r268 - trunk/grassaddons/gui/Gism Message-ID: <200703232226.l2NMQWNE000341@grass.itc.it> Author: barton Date: 2007-03-23 23:26:23 +0100 (Fri, 23 Mar 2007) New Revision: 268 Modified: trunk/grassaddons/gui/Gism/menuform.py Log: Fix bug in flags that I introduced this morning. Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-23 15:21:18 UTC (rev 267) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-23 22:26:23 UTC (rev 268) @@ -515,7 +515,7 @@ errors = 0 errStr = "" for flag in grass_task.flags: - if 'value' in flag: + if 'value' in flag and flag['value'] == True: cmd += ' -' + flag['name'] for p in grass_task.params: if p['value'] == '' and p['required'] != 'no': From barton at grass.itc.it Fri Mar 23 23:27:39 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Mar 23 23:27:42 2007 Subject: [grass-addons] r269 - in trunk/grassaddons/gui: . Gism Message-ID: <200703232227.l2NMRdDM000365@grass.itc.it> Author: barton Date: 2007-03-23 23:27:27 +0100 (Fri, 23 Mar 2007) New Revision: 269 Modified: trunk/grassaddons/gui/Gism/gismutils.py trunk/grassaddons/gui/gism.py Log: Add many more layer types (RGB, HIS, legends, thematic maps, thematic charts) Modified: trunk/grassaddons/gui/Gism/gismutils.py =================================================================== --- trunk/grassaddons/gui/Gism/gismutils.py 2007-03-23 22:26:23 UTC (rev 268) +++ trunk/grassaddons/gui/Gism/gismutils.py 2007-03-23 22:27:27 UTC (rev 269) @@ -71,11 +71,37 @@ trgif.Rescale(16, 16) trgif = trgif.ConvertToBitmap() self.rast_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.rgb.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.rgb_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/channel-his.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.his_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.legend.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.leg_icon = il.Add(trgif) + trgif = wx.Image(icons + r'/element-vector.gif', wx.BITMAP_TYPE_GIF) trgif.Rescale(16, 16) trgif = trgif.ConvertToBitmap() self.vect_icon = il.Add(trgif) + trgif = wx.Image(icons + r'/module-d.vect.thematic.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.theme_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.vect.chart.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.chart_icon = il.Add(trgif) + trgif = wx.Image(icons + r'/gui-cmd.gif', wx.BITMAP_TYPE_GIF) trgif.Rescale(16, 16) trgif = trgif.ConvertToBitmap() @@ -120,11 +146,13 @@ '', ct_type=1, wnd=self.ctrl ) else: layer = self.PrependItem(self.root, '', ct_type=1, wnd=self.ctrl) + print 'layer added' self.SelectItem(layer) # add to layertype and layerctrl dictionaries self.layertype[layer] = type + print 'layertype =', self.layertype[layer] self.layerctrl[self.ctrl] = layer # add a data object to hold the layer's command (does not apply to generic command layers) @@ -143,11 +171,37 @@ self.SetItemText(layer, 'raster (double click to set properties)') # launch the properties dialog menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif type == 'rgb': + print 'in rgb' + self.SetItemImage(layer, self.rgb_icon) + self.SetItemText(layer, 'RGB (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif type == 'his': + self.SetItemImage(layer, self.his_icon) + self.SetItemText(layer, 'HIS (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif type == 'rastleg': + self.SetItemImage(layer, self.leg_icon) + self.SetItemText(layer, 'legend (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer), parentframe=self) elif type == 'vector': self.SetItemImage(layer, self.vect_icon) self.SetItemText(layer, 'vector (double click to set properties)') # launch the properties dialog menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif type == 'thememap': + self.SetItemImage(layer, self.theme_icon) + self.SetItemText(layer, 'thematic map (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif type == 'themechart': + self.SetItemImage(layer, self.chart_icon) + self.SetItemText(layer, 'thematic charts (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer), parentframe=self) elif type == 'command': self.SetItemImage(layer, self.cmd_icon) self.first = False @@ -293,6 +347,10 @@ for item in dcmd.split(' '): if 'map=' in item: mapname = item.split('=')[1] + elif 'red=' in item: + mapname = item.split('=')[1] + elif 'h_map=' in item: + mapname = item.split('=')[1] # set layer text to map name self.SetItemText(layer, mapname) Modified: trunk/grassaddons/gui/gism.py =================================================================== --- trunk/grassaddons/gui/gism.py 2007-03-23 22:26:23 UTC (rev 268) +++ trunk/grassaddons/gui/gism.py 2007-03-23 22:27:27 UTC (rev 269) @@ -9,11 +9,19 @@ import sys import os import wx +import wx.combo import wx.lib.customtreectrl as CT import wx.lib.flatnotebook as FN import wx.stc import wx.richtext +import sys, os, time, traceback, types + +import wx # This module uses the new wx namespace +import wx.html + +import images + # try: # import subprocess #except: @@ -108,7 +116,7 @@ self.notebook = self.__createNoteBook() self.cmdinput = self.__createCommandInput() self.menubar = self.__createMenuBar() - self.toolbar = self.__createToolBar() + toolbar = self.__createToolBar() #self.panel = wx.Panel(self,-1, style= wx.EXPAND) self.sizer= wx.BoxSizer(wx.VERTICAL) self.cmdsizer = wx.BoxSizer(wx.HORIZONTAL) @@ -125,6 +133,7 @@ self.mapfocus = 0 #track which display currently has focus self.Bind(wx.EVT_CLOSE, self.onCloseWindow) + self.Bind(wx.EVT_LEFT_DOWN, self.addRaster) # item, proportion, flag, border, userData self.sizer.Add(self.notebook, proportion=1, flag=wx.EXPAND, border=1) @@ -301,12 +310,43 @@ return ( ('newdisplay', wx.Bitmap(os.path.join(gismutils.icons,'gui-startmon.gif'), wx.BITMAP_TYPE_ANY), 'Start new display', self.newDisplay), ('', '', '', ''), - ('addrast', wx.Bitmap(os.path.join(gismutils.icons,'element-cell.gif'), wx.BITMAP_TYPE_ANY), 'Add raster layer', self.addRaster), - ('addvect', wx.Bitmap(os.path.join(gismutils.icons,'element-vector.gif'), wx.BITMAP_TYPE_ANY), 'Add vector layer', self.addVector), + ('addrast', wx.Bitmap(os.path.join(gismutils.icons,'element-cell.gif'), wx.BITMAP_TYPE_ANY), 'Add raster layer', self.onRaster), + ('addvect', wx.Bitmap(os.path.join(gismutils.icons,'element-vector.gif'), wx.BITMAP_TYPE_ANY), 'Add vector layer', self.onVector), ('addcmd', wx.Bitmap(os.path.join(gismutils.icons,'gui-cmd.gif'), wx.BITMAP_TYPE_ANY), 'Add command layer', self.addCommand), ('delcmd', wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_TOOLBAR, (16,16)), 'Delete selected layer', self.deleteLayer), ) + def addToolbarCombo(self, toolbar, indx, type): + tbcb = wx.combo.BitmapComboBox(toolbar, pos=(25,25), size=(100,-1), style=wx.TE_PROCESS_ENTER) + self.comboItems(tbcb, type) + toolbar.InsertControl(indx, tbcb) + toolbar.Realize() + + self.Bind(wx.EVT_COMBOBOX, self.onCombo, tbcb) + self.Bind(wx.EVT_TEXT_ENTER, self.onCombo, tbcb) + + def onCombo(self, event): + bcb = event.GetEventObject() + idx = event.GetInt() + st = bcb.GetString(idx) + cd = bcb.GetClientData(idx) + if 'Add raster map' in st: + self.addRaster() + elif 'Add RGB' in st: + self.addRGB() + elif 'Add raster legend' in st: + self.addRastLeg() + elif 'Add vector map' in st: + self.addVector() + elif 'Add thematic map' in st: + self.addThemeMap() + elif 'Add thematic chart' in st: + self.addThemeChart() + +# self.log.write("EVT_COMBOBOX: Id %d, string '%s', clientData '%s'" % (idx, st, cd)) + evt.Skip() + + def newDisplay(self, event=None): """Create new map display frame""" @@ -353,14 +393,108 @@ self.disp_idx += 1 # toolBar button handlers + def onRaster(self, event): + """Add raster item menu""" + point = wx.GetMousePosition() + rastmenu = wx.Menu() + # Add items to the menu + addrast = wx.MenuItem(rastmenu, -1,'Add raster map layer') + bmp = wx.Image(os.path.join(gismutils.icons,'element-cell.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addrast.SetBitmap(bmp) + rastmenu.AppendItem(addrast) + self.Bind(wx.EVT_MENU, self.addRaster, addrast) + + addrgb = wx.MenuItem(rastmenu, -1,'Add RGB layer') + bmp = wx.Image(os.path.join(gismutils.icons,'module-d.rgb.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addrgb.SetBitmap(bmp) + rastmenu.AppendItem(addrgb) + self.Bind(wx.EVT_MENU, self.addRGB, addrgb) + + addhis = wx.MenuItem(rastmenu, -1,'Add HIS layer') + bmp = wx.Image(os.path.join(gismutils.icons,'channel-his.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addhis.SetBitmap(bmp) + rastmenu.AppendItem(addhis) + self.Bind(wx.EVT_MENU, self.addHIS, addhis) + + addrleg = wx.MenuItem(rastmenu, -1,'Add raster legend layer') + bmp = wx.Image(os.path.join(gismutils.icons,'module-d.legend.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addrleg.SetBitmap(bmp) + rastmenu.AppendItem(addrleg) + self.Bind(wx.EVT_MENU, self.addRastLeg, addrleg) + + # Popup the menu. If an item is selected then its handler + # will be called before PopupMenu returns. + self.PopupMenu(rastmenu) + rastmenu.Destroy() + + def onVector(self, event): + """Add raster item menu""" + point = wx.GetMousePosition() + vectmenu = wx.Menu() + + addvect = wx.MenuItem(vectmenu, -1,'Add vector map layer') + bmp = wx.Image(os.path.join(gismutils.icons,'element-vector.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addvect.SetBitmap(bmp) + vectmenu.AppendItem(addvect) + self.Bind(wx.EVT_MENU, self.addVector, addvect) + + addtheme = wx.MenuItem(vectmenu, -1,'Add thematic map layer') + bmp = wx.Image(os.path.join(gismutils.icons,'module-d.vect.thematic.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addtheme.SetBitmap(bmp) + vectmenu.AppendItem(addtheme) + self.Bind(wx.EVT_MENU, self.addThemeMap, addtheme) + + addchart = wx.MenuItem(vectmenu, -1,'Add thematic chart layer') + bmp = wx.Image(os.path.join(gismutils.icons,'module-d.vect.chart.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addchart.SetBitmap(bmp) + vectmenu.AppendItem(addchart) + self.Bind(wx.EVT_MENU, self.addThemeChart, addchart) + # Popup the menu. If an item is selected then its handler + # will be called before PopupMenu returns. + self.PopupMenu(vectmenu) + vectmenu.Destroy() + def addRaster(self, event): - """Add raster layer""" self.SetTree('raster') + def addRGB(self, event): + """Add RGB layer""" + self.SetTree('rgb') + + def addHIS(self, event): + """Add HIS layer""" + self.SetTree('his') + + def addRastLeg(self, event): + """Add raster legend""" + self.SetTree('rastleg') + def addVector(self, event): """Add vector layer""" self.SetTree('vector') + def addThemeMap(self, event): + """Add thematic map layer""" + self.SetTree('thememap') + + def addThemeChart(self, event): + """Add thematic chart layer""" + self.SetTree('themechart') + def addCommand(self, event): """Add command line layer""" self.SetTree('command') @@ -395,26 +529,11 @@ self.DestroyChildren() self.Destroy() + def Nomethod(self, event): + '''Stub for testing''' + pass + event.Skip() -class SetVal: - """ - Class to store and set values needed by map, gism, - and other modules. This should work but doesn't for some reason. - """ - - def setMdFocus(self, mdnum=-1): - #get the id number of map display that has the focus - #and use it to set md - global mdfocus - if mdnum > -1: - mdfocus = mdnum - else: - return mdfocus - - def getMdFocus(self): - global mdfocus - return mdfocus - class GMApp(wx.App): """ GMApp class From calvelo at grass.itc.it Fri Mar 23 23:54:32 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Fri Mar 23 23:54:33 2007 Subject: [grass-addons] r270 - trunk/grassaddons/gui/Gism Message-ID: <200703232254.l2NMsWwH000968@grass.itc.it> Author: calvelo Date: 2007-03-23 23:54:21 +0100 (Fri, 23 Mar 2007) New Revision: 270 Modified: trunk/grassaddons/gui/Gism/menuform.py Log: - Added full color name handling Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-23 22:27:27 UTC (rev 269) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-23 22:54:21 UTC (rev 270) @@ -95,9 +95,11 @@ (128, 0,128) ) t_color = t_colors.split(',') -named_color = {} +color_str2rgb = {} +color_rgb2str = {} for c in range(0,len(t_rgb)): - named_color[ t_color[c] ] = t_rgb[ c ] + color_str2rgb[ t_color[c] ] = t_rgb[ c ] + color_rgb2str[ t_rgb[ c ] ] = t_color[ c ] def normalize_whitespace(text): @@ -387,7 +389,7 @@ else: # Convert color names to RGB try: - default_color = named_color[ p['default'] ] + default_color = color_str2rgb[ p['default'] ] label_color = p['default'] label_color_pad = ' '*(11-len(label_color)/2) label_color = label_color_pad + label_color + label_color_pad @@ -446,8 +448,8 @@ self.tab[section].SetSizer( self.tabsizer[section] ) self.tab[section].Layout() -# self.panelsizer.Fit( self.notebookpanel ) self.panelsizer.SetSizeHints( self.notebookpanel ) + self.panelsizer.Fit( self.notebookpanel ) self.notebookpanel.SetSizer(self.panelsizer) self.notebookpanel.SetAutoLayout(True) self.notebookpanel.Layout() @@ -455,14 +457,16 @@ self.guisizer.SetSizeHints(self) self.SetAutoLayout(True) self.SetSizer(self.guisizer) -# self.guisizer.Fit(self) self.Layout() def OnColorButton(self, event): colorchooser = wx.FindWindowById( event.GetId() ) new_color = colorchooser.GetValue() - colorchooser.SetLabel( ':'.join(map(str,new_color)) ) + # This is weird: new_color is a 4-tuple and new_color[:] is a 3-tuple + # under wx2.8.1 + new_label = color_rgb2str.get( new_color[:], ':'.join(map(str,new_color)) ) + colorchooser.SetLabel( new_label ) colorchooser.SetColour( new_color ) colorchooser.Refresh() self.getValues() @@ -515,7 +519,7 @@ errors = 0 errStr = "" for flag in grass_task.flags: - if 'value' in flag and flag['value'] == True: + if 'value' in flag and flag['value']: cmd += ' -' + flag['name'] for p in grass_task.params: if p['value'] == '' and p['required'] != 'no': From calvelo at grass.itc.it Sat Mar 24 00:30:55 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Sat Mar 24 00:30:56 2007 Subject: [grass-addons] r271 - trunk/grassaddons/gui/Gism Message-ID: <200703232330.l2NNUtaE001063@grass.itc.it> Author: calvelo Date: 2007-03-24 00:30:47 +0100 (Sat, 24 Mar 2007) New Revision: 271 Modified: trunk/grassaddons/gui/Gism/render.py Log: - Make it (almost) work under qgis0.8+grass-plugin: have explicit splits for parsing of both WIND and g.region output Modified: trunk/grassaddons/gui/Gism/render.py =================================================================== --- trunk/grassaddons/gui/Gism/render.py 2007-03-23 22:54:21 UTC (rev 270) +++ trunk/grassaddons/gui/Gism/render.py 2007-03-23 23:30:47 UTC (rev 271) @@ -280,7 +280,7 @@ for line in windfile.readlines(): line = line.strip() - key, value = line.split(":") + key, value = line.split(":",1) key = key.strip() value = value.strip() self.wind[key] = value @@ -393,8 +393,11 @@ for reg in os.popen("g.region -gp").readlines(): reg = reg.strip() - key, val = reg.split("=") - region[key] = float(val) + key, val = reg.split("=",1) + try: + region[key] = float(val) + except ValueError: + region[key] = val if tmpreg: os.environ["GRASS_REGION"] = tmpreg From barton at grass.itc.it Sat Mar 24 01:08:02 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 24 01:08:03 2007 Subject: [grass-addons] r272 - trunk/grassaddons/gui/Gism Message-ID: <200703240008.l2O082Fi001231@grass.itc.it> Author: barton Date: 2007-03-24 01:07:52 +0100 (Sat, 24 Mar 2007) New Revision: 272 Modified: trunk/grassaddons/gui/Gism/gismutils.py Log: Added command line support for d.rgb, d.his, d.legend, d.vect.thematic, and d.vect.chart. For some reason, entering d.vect.thematic on the command line starts up the TclTk dialog rather than adding it to the layer tree. Maybe because it's a script??? Modified: trunk/grassaddons/gui/Gism/gismutils.py =================================================================== --- trunk/grassaddons/gui/Gism/gismutils.py 2007-03-23 23:30:47 UTC (rev 271) +++ trunk/grassaddons/gui/Gism/gismutils.py 2007-03-24 00:07:52 UTC (rev 272) @@ -146,13 +146,11 @@ '', ct_type=1, wnd=self.ctrl ) else: layer = self.PrependItem(self.root, '', ct_type=1, wnd=self.ctrl) - print 'layer added' self.SelectItem(layer) # add to layertype and layerctrl dictionaries self.layertype[layer] = type - print 'layertype =', self.layertype[layer] self.layerctrl[self.ctrl] = layer # add a data object to hold the layer's command (does not apply to generic command layers) @@ -636,8 +634,18 @@ if cmd[0:2] == "d.": if cmd == 'd.rast': layertype = 'raster' + elif cmd == 'd.rgb': + layertype = 'rgb' + elif cmd == 'd.his': + layertype = 'his' + elif cmd == 'd.legend': + layertype = 'rastleg' elif cmd == 'd.vect': layertype = 'vector' + elif cmd == 'd.vect.thematic': + layertype = 'thememap' + elif cmd == 'd.vect.chart': + layertype = 'themechart' else: print 'Command type not yet implemented' return From barton at grass.itc.it Sat Mar 24 01:31:53 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 24 01:31:54 2007 Subject: [grass-addons] r273 - trunk/grassaddons/gui/Gism Message-ID: <200703240031.l2O0Vr5Z001269@grass.itc.it> Author: barton Date: 2007-03-24 01:31:45 +0100 (Sat, 24 Mar 2007) New Revision: 273 Modified: trunk/grassaddons/gui/Gism/gismutils.py Log: d.vect.thematic now adds properly as a layer. Modified: trunk/grassaddons/gui/Gism/gismutils.py =================================================================== --- trunk/grassaddons/gui/Gism/gismutils.py 2007-03-24 00:07:52 UTC (rev 272) +++ trunk/grassaddons/gui/Gism/gismutils.py 2007-03-24 00:31:45 UTC (rev 273) @@ -170,7 +170,6 @@ # launch the properties dialog menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer), parentframe=self) elif type == 'rgb': - print 'in rgb' self.SetItemImage(layer, self.rgb_icon) self.SetItemText(layer, 'RGB (double click to set properties)') # launch the properties dialog @@ -598,14 +597,15 @@ self.SetSizer(boxsizer1) def getGRASSCmds(self): - ''' + ''' Create list of all available GRASS commands to use when parsing string from the command line ''' - gisbase = os.environ['GISBASE'] - self.gcmdlst = os.listdir(gisbase+r'/bin') - self.gcmdlst.append(os.listdir(gisbase+r'/scripts')) - return self.gcmdlst + self.gcmdlst = [] + gisbase = os.environ['GISBASE'] + self.gcmdlst = os.listdir(gisbase+r'/bin') + self.gcmdlst = self.gcmdlst + os.listdir(gisbase+r'/scripts') + return self.gcmdlst def runCmd(self, cmd): """ From barton at grass.itc.it Sat Mar 24 02:04:09 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 24 02:04:09 2007 Subject: [grass-addons] r274 - trunk/grassaddons/gui/Gism Message-ID: <200703240104.l2O14938002220@grass.itc.it> Author: barton Date: 2007-03-24 02:04:01 +0100 (Sat, 24 Mar 2007) New Revision: 274 Modified: trunk/grassaddons/gui/Gism/menuform.py Log: Improved spacing for new color and other controls. Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 00:31:45 UTC (rev 273) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 01:04:01 UTC (rev 274) @@ -378,7 +378,7 @@ if p['prompt'] != 'color': self.selection = select.Select(which_panel, id=wx.ID_ANY, size=(250,-1), type=p['element']) - which_sizer.Add(self.selection, 0, wx.ADJUST_MINSIZE, 5) + which_sizer.Add(self.selection, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) self.paramdict[self.selection] = ID_PARAM_START + p_count self.selection.Bind(wx.EVT_TEXT, self.EvtText) elif p['prompt'] == 'color': @@ -400,7 +400,7 @@ default_color = (200,200,200) label_color = 'Select Color' btn_colour = csel.ColourSelect(which_panel, -1, label_color, default_color ) - which_sizer.Add(btn_colour, 0, wx.ADJUST_MINSIZE, 5) + which_sizer.Add(btn_colour, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) self.paramdict[btn_colour] = ID_PARAM_START + p_count self.Bind(csel.EVT_COLOURSELECT, self.OnColorButton, btn_colour) f_count = -1 @@ -414,7 +414,7 @@ which_panel = self.tab[ 'Main' ] title = escape_ampersand(f['description']) self.chk = wx.CheckBox(which_panel,-1, label = title, style = wx.NO_BORDER) - which_sizer.Add(self.chk, 0, wx.EXPAND, 5) + which_sizer.Add(self.chk, 0, wx.EXPAND| wx.ALL, 5) self.paramdict[self.chk] = ID_FLAG_START + f_count self.chk.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox) From barton at grass.itc.it Sat Mar 24 02:17:04 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 24 02:17:05 2007 Subject: [grass-addons] r275 - trunk/grassaddons/gui/Gism Message-ID: <200703240117.l2O1H4nW002276@grass.itc.it> Author: barton Date: 2007-03-24 02:16:56 +0100 (Sat, 24 Mar 2007) New Revision: 275 Modified: trunk/grassaddons/gui/Gism/menuform.py Log: Standardized colour button size Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 01:04:01 UTC (rev 274) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 01:16:56 UTC (rev 275) @@ -399,7 +399,7 @@ else: default_color = (200,200,200) label_color = 'Select Color' - btn_colour = csel.ColourSelect(which_panel, -1, label_color, default_color ) + btn_colour = csel.ColourSelect(which_panel, -1, label_color, default_color, wx.DefaultPosition, (150,-1) ) which_sizer.Add(btn_colour, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) self.paramdict[btn_colour] = ID_PARAM_START + p_count self.Bind(csel.EVT_COLOURSELECT, self.OnColorButton, btn_colour) From barton at grass.itc.it Sat Mar 24 05:57:03 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 24 05:57:03 2007 Subject: [grass-addons] r276 - trunk/grassaddons/gui/Gism Message-ID: <200703240457.l2O4v3IH005248@grass.itc.it> Author: barton Date: 2007-03-24 05:56:54 +0100 (Sat, 24 Mar 2007) New Revision: 276 Modified: trunk/grassaddons/gui/Gism/menuform.py Log: Gradient background to command dialog tabs to match look of GIS Manager. Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 01:16:56 UTC (rev 275) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 04:56:54 UTC (rev 276) @@ -300,8 +300,9 @@ self.notebookpanel.SetScrollRate(10,10) self.panelsizer = wx.BoxSizer(wx.VERTICAL) - nbStyle=FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS|FN.FNB_VC8 + nbStyle=FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS|FN.FNB_VC8|FN.FNB_BACKGROUND_GRADIENT self.notebook = FN.FlatNotebook(self.notebookpanel, id=wx.ID_ANY, style=nbStyle) + self.notebook.SetTabAreaColour(wx.Colour(125,200,175)) self.tab = {} self.tabsizer = {} is_first = True From calvelo at grass.itc.it Sat Mar 24 09:12:15 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Sat Mar 24 09:12:16 2007 Subject: [grass-addons] r277 - trunk/grassaddons/gui/Gism Message-ID: <200703240812.l2O8CFOg023107@grass.itc.it> Author: calvelo Date: 2007-03-24 09:12:06 +0100 (Sat, 24 Mar 2007) New Revision: 277 Modified: trunk/grassaddons/gui/Gism/menuform.py Log: - Better handling of tab creation: the order is given by the command options, and the default is now 'Options' instead of 'Main' Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 04:56:54 UTC (rev 276) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 08:12:06 UTC (rev 277) @@ -35,7 +35,7 @@ import string import select import wx.lib.flatnotebook as FN -import wx.lib.colourselect as csel +import wx.lib.colourselect as csel # Do the python 2.0 standard xml thing and map it on the old names import xml.sax @@ -289,12 +289,14 @@ self.SetMenuBar(menuBar) self.guisizer = wx.BoxSizer(wx.VERTICAL) + sections = [] is_section = {} for task in grass_task.params + grass_task.flags: - if task.has_key('guisection') and task['guisection'] != '': + if not task.has_key('guisection') or task['guisection']=='': + task['guisection'] = 'Options' + if not is_section.has_key(task['guisection']): is_section[task['guisection']] = 1 - sections = is_section.keys() - sections.sort() + sections.append( task['guisection'] ) self.notebookpanel = wx.ScrolledWindow( self, id=wx.ID_ANY ) self.notebookpanel.SetScrollRate(10,10) @@ -306,7 +308,7 @@ self.tab = {} self.tabsizer = {} is_first = True - for section in ['Main']+sections: + for section in sections: self.tab[section] = wx.Panel(self.notebook, id = wx.ID_ANY ) self.tabsizer[section] = wx.BoxSizer(wx.VERTICAL) self.notebook.AddPage( self.tab[section], text = section, select = is_first ) @@ -318,12 +320,8 @@ p_count = -1 for p in grass_task.params: p_count += 1 # Needed for checkboxes hack - if p.has_key('guisection') and p['guisection'] != '': - which_sizer = self.tabsizer[ p['guisection'] ] - which_panel = self.tab[ p['guisection'] ] - else: - which_sizer = self.tabsizer[ 'Main' ] - which_panel = self.tab[ 'Main' ] + which_sizer = self.tabsizer[ p['guisection'] ] + which_panel = self.tab[ p['guisection'] ] title = escape_ampersand(p['description']) if p['required'] == 'no': title = "[optional] " + title @@ -392,11 +390,9 @@ try: default_color = color_str2rgb[ p['default'] ] label_color = p['default'] - label_color_pad = ' '*(11-len(label_color)/2) - label_color = label_color_pad + label_color + label_color_pad except KeyError: default_color = (200,200,200) - label_color = ' Select Color ' + label_color = 'Select Color' else: default_color = (200,200,200) label_color = 'Select Color' @@ -407,12 +403,8 @@ f_count = -1 for f in grass_task.flags: f_count += 1 - if f.has_key('guisection') and f['guisection'] != '': - which_sizer = self.tabsizer[ f['guisection'] ] - which_panel = self.tab[ f['guisection'] ] - else: - which_sizer = self.tabsizer[ 'Main' ] - which_panel = self.tab[ 'Main' ] + which_sizer = self.tabsizer[ f['guisection'] ] + which_panel = self.tab[ f['guisection'] ] title = escape_ampersand(f['description']) self.chk = wx.CheckBox(which_panel,-1, label = title, style = wx.NO_BORDER) which_sizer.Add(self.chk, 0, wx.EXPAND| wx.ALL, 5) @@ -442,7 +434,7 @@ self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) - for section in sections+['Main']: + for section in sections: self.tabsizer[section].SetSizeHints( self.tab[section] ) self.tabsizer[section].Fit( self.tab[section] ) self.tab[section].SetAutoLayout(True) From barton at grass.itc.it Sat Mar 24 17:00:26 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 24 17:00:27 2007 Subject: [grass-addons] r278 - trunk/grassaddons/gui Message-ID: <200703241600.l2OG0QQe027985@grass.itc.it> Author: barton Date: 2007-03-24 17:00:17 +0100 (Sat, 24 Mar 2007) New Revision: 278 Modified: trunk/grassaddons/gui/gis_set.py Log: EPSG option screen polished. Browse codes fixed. Datum transform selection fixed. It all should work well now. Modified: trunk/grassaddons/gui/gis_set.py =================================================================== --- trunk/grassaddons/gui/gis_set.py 2007-03-24 08:12:06 UTC (rev 277) +++ trunk/grassaddons/gui/gis_set.py 2007-03-24 16:00:17 UTC (rev 278) @@ -71,17 +71,16 @@ # table self.tablewidth=600 - self.epsgs = wx.ListCtrl(self, -1, - style=wx.LC_REPORT|wx.LC_HRULES, - size=(700,100)) - self.epsgs.InsertColumn(0, 'EPSG') - self.epsgs.InsertColumn(1, ' Description ') - self.epsgs.InsertColumn(2, ' Parameters ') + self.epsgs = wx.ListCtrl(self, id = wx.ID_ANY, + size=(750,200), + style=wx.LC_REPORT|wx.LC_HRULES|wx.EXPAND) + self.epsgs.InsertColumn(0, 'EPSG', wx.LIST_FORMAT_CENTRE) + self.epsgs.InsertColumn(1, 'Description', wx.LIST_FORMAT_LEFT) + self.epsgs.InsertColumn(2, 'Parameters', wx.LIST_FORMAT_LEFT) self.epsgs.SetColumnWidth(0, 50) - self.epsgs.SetColumnWidth(1, wx.LIST_AUTOSIZE_USEHEADER) - self.epsgs.SetColumnWidth(2, wx.LIST_AUTOSIZE_USEHEADER) + self.epsgs.SetColumnWidth(1, 300) + self.epsgs.SetColumnWidth(2, 400) - # layout self.sizer.Add(self.lname, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | @@ -128,7 +127,7 @@ self.sizer.Add(self.epanel4, 0, wx.ALIGN_LEFT, 1) self.vsizer.Add(self.sizer,0, wx.ADJUST_MINSIZE, 1) - self.vsizer.Add(self.epsgs, wx.ALIGN_LEFT|wx.EXPAND, 2) + self.vsizer.Add(self.epsgs, wx.ALIGN_LEFT|wx.EXPAND, 0) self.SetAutoLayout(True) self.SetSizer(self.vsizer) @@ -136,7 +135,6 @@ self.vsizer.SetSizeHints(self) self.Layout() - # events wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) wx.EVT_BUTTON(self, self.bcancel.GetId(), self.OnCancel) @@ -195,19 +193,24 @@ for par in line.split(" ")[1:]: params += par + " " code = code[1:-1] + if code == None: code = 'no code' + if descr == None: descr = 'no description' + if params == None: params = 'no parameters' if i%2 == 0: if search and descr.lower().find(search.lower()) > -1 or\ not search: - self.epsgs.InsertStringItem(j,str(code)) - self.epsgs.SetStringItem(j, 1, str(descr)) - self.epsgs.SetStringItem(j, 2, str(params)) + index = self.epsgs.InsertStringItem(j, code) + self.epsgs.SetStringItem(index, 1, descr) + self.epsgs.SetStringItem(index, 2, params) j += 1 # reset descr = None; code = None; params = "" - if i%2 == 0: - self.epsgs.SetItemBackgroundColour(i, "grey") +# if i%2 == 0: +# self.epsgs.SetItemBackgroundColour(i, "grey") i += 1 f.close() + self.epsgs.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.epsgs.SetColumnWidth(2, wx.LIST_AUTOSIZE) self.SendSizeEvent() except StandardError, e: dlg = wx.MessageDialog(self, "Could not read EPGS codes: %s " @@ -228,16 +231,16 @@ number = -1 try: - number = int(self.tcode.GetValue()) + code = self.tcode.GetValue() except: - dlg = wx.MessageDialog(self, "Could not create new location: '%s' not a number" % self.tcode.GetValue(), + dlg = wx.MessageDialog(self, "Could not create new location: '%s' is not a valid EPSG code" % code, "Can not create location", wx.OK|wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() return if os.path.isdir(os.path.join(self.parent.gisdbase,self.tname.GetValue())): - dlg = wx.MessageDialog(self, "Could not create new location: %s exists" + dlg = wx.MessageDialog(self, "Could not create new location: %s already exists" % os.path.join(self.parent.gisdbase,self.tname.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() @@ -247,18 +250,24 @@ # all credit to Michael Barton and his file_option.tcl and # Markus Neteler try: - # FIXME: this does not need to work on windows - os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) - datumtrans = os.popen(" g.proj epsg=%d datumtrans=-1 >&2" % (number)).readlines() + dtoptions = os.popen3(" g.proj epsg=%s datumtrans=-1" % (code))[1].read() + if dtoptions != None: + # open a dialog to select datum transform number + dtoptions = 'Select the number of a datum transformation to use: \n'+dtoptions + dlg = wx.TextEntryDialog(self, dtoptions) + dlg.SetValue('1') - if datumtrans: - #os.system(" g.proj epsg=%d datumtrans=%s >&2" % (number,datumtrans[0]).readlines() - pass + if dlg.ShowModal() == wx.ID_OK: + dtrans = dlg.GetValue() + + dlg.Destroy() + + cmd = os.system("g.proj -c epsg=%s location=%s datumtrans=%s" % (code, self.tname.GetValue(), dtrans)) else: - os.system("g.proj -c epsg=%d location=%s datumtrans=1" % (number, self.tname.GetValue())) + os.system("g.proj -c epsg=%s location=%s datumtrans=1" % (code, self.tname.GetValue())) - self.parent.OnSetDatabase(None) self.Destroy() + self.parent.OnSetDatabase(None) except StandardError, e: dlg = wx.MessageDialog(self, "Could not create new location: %s " @@ -267,7 +276,6 @@ dlg.Destroy() return - def OnDoubleClick(self, event): print self.epsgs.GetValue() pass From barton at grass.itc.it Sat Mar 24 17:34:33 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 24 17:34:35 2007 Subject: [grass-addons] r279 - trunk/grassaddons/gui/Gism Message-ID: <200703241634.l2OGYXFu028056@grass.itc.it> Author: barton Date: 2007-03-24 17:34:24 +0100 (Sat, 24 Mar 2007) New Revision: 279 Modified: trunk/grassaddons/gui/Gism/menuform.py Log: Better sizing of gui panels. Based on max x and max y of all tab sections. Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 16:00:17 UTC (rev 278) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 16:34:24 UTC (rev 279) @@ -434,13 +434,19 @@ self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) + xsizelist = [] + ysizelist = [] for section in sections: self.tabsizer[section].SetSizeHints( self.tab[section] ) self.tabsizer[section].Fit( self.tab[section] ) self.tab[section].SetAutoLayout(True) self.tab[section].SetSizer( self.tabsizer[section] ) self.tab[section].Layout() + xsizelist.append(self.tabsizer[section].GetMinSize()[0]) + ysizelist.append(self.tabsizer[section].GetMinSize()[1]) + maxminsize = (max(xsizelist),max(ysizelist)) + self.notebook.SetInitialSize(maxminsize) self.panelsizer.SetSizeHints( self.notebookpanel ) self.panelsizer.Fit( self.notebookpanel ) self.notebookpanel.SetSizer(self.panelsizer) @@ -448,6 +454,7 @@ self.notebookpanel.Layout() self.guisizer.SetSizeHints(self) +# self.guisizer.SetMinSize(maxminsize) self.SetAutoLayout(True) self.SetSizer(self.guisizer) self.Layout() From barton at grass.itc.it Sat Mar 24 17:38:55 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 24 17:38:57 2007 Subject: [grass-addons] r280 - trunk/grassaddons/gui/Gism Message-ID: <200703241638.l2OGctEW028087@grass.itc.it> Author: barton Date: 2007-03-24 17:38:47 +0100 (Sat, 24 Mar 2007) New Revision: 280 Modified: trunk/grassaddons/gui/Gism/gismutils.py Log: Double clicking on layer will open options dialog for new layer types. Modified: trunk/grassaddons/gui/Gism/gismutils.py =================================================================== --- trunk/grassaddons/gui/Gism/gismutils.py 2007-03-24 16:34:24 UTC (rev 279) +++ trunk/grassaddons/gui/Gism/gismutils.py 2007-03-24 16:38:47 UTC (rev 280) @@ -212,8 +212,18 @@ # When double clicked or first added, open options dialog if self.layertype[layer] == 'raster': menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif self.layertype[layer] == 'rgb': + menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif self.layertype[layer] == 'his': + menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif self.layertype[layer] == 'rastleg': + menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer), parentframe=self) elif self.layertype[layer] == 'vector': menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif self.layertype[layer] == 'thememap': + menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer), parentframe=self) + elif self.layertype[layer] == 'themechart': + menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer), parentframe=self) def onDeleteLayer(self, event): layer = event.GetItem() From barton at grass.itc.it Sat Mar 24 18:09:52 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 24 18:09:54 2007 Subject: [grass-addons] r281 - trunk/grassaddons/gui/Gism Message-ID: <200703241709.l2OH9q4a028218@grass.itc.it> Author: barton Date: 2007-03-24 18:09:42 +0100 (Sat, 24 Mar 2007) New Revision: 281 Modified: trunk/grassaddons/gui/Gism/gismutils.py trunk/grassaddons/gui/Gism/menuform.py Log: Set up structure to pass command parameters from an existing layer in the GIS Manager to the options dialog when it is opened. Need to parse existing d.* command in gismutils to do this (and of course debug in menuform). This will work much easier if a command is created as a list instead of a string. Modified: trunk/grassaddons/gui/Gism/gismutils.py =================================================================== --- trunk/grassaddons/gui/Gism/gismutils.py 2007-03-24 16:38:47 UTC (rev 280) +++ trunk/grassaddons/gui/Gism/gismutils.py 2007-03-24 17:09:42 UTC (rev 281) @@ -58,6 +58,7 @@ self.saveitem = {} # dictionary to preserve layer attributes for drag and drop self.first = True # indicates if a layer is just added or not self.drag = False # flag to indicate a drag event is in process + self.params = {} # dictionary of existing command parameters self.Map = disp.getRender() @@ -168,37 +169,37 @@ self.SetItemImage(layer, self.rast_icon) self.SetItemText(layer, 'raster (double click to set properties)') # launch the properties dialog - menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif type == 'rgb': self.SetItemImage(layer, self.rgb_icon) self.SetItemText(layer, 'RGB (double click to set properties)') # launch the properties dialog - menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif type == 'his': self.SetItemImage(layer, self.his_icon) self.SetItemText(layer, 'HIS (double click to set properties)') # launch the properties dialog - menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif type == 'rastleg': self.SetItemImage(layer, self.leg_icon) self.SetItemText(layer, 'legend (double click to set properties)') # launch the properties dialog - menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif type == 'vector': self.SetItemImage(layer, self.vect_icon) self.SetItemText(layer, 'vector (double click to set properties)') # launch the properties dialog - menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif type == 'thememap': self.SetItemImage(layer, self.theme_icon) self.SetItemText(layer, 'thematic map (double click to set properties)') # launch the properties dialog - menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif type == 'themechart': self.SetItemImage(layer, self.chart_icon) self.SetItemText(layer, 'thematic charts (double click to set properties)') # launch the properties dialog - menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif type == 'command': self.SetItemImage(layer, self.cmd_icon) self.first = False @@ -211,19 +212,19 @@ # When double clicked or first added, open options dialog if self.layertype[layer] == 'raster': - menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif self.layertype[layer] == 'rgb': - menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif self.layertype[layer] == 'his': - menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif self.layertype[layer] == 'rastleg': - menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif self.layertype[layer] == 'vector': - menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif self.layertype[layer] == 'thememap': - menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif self.layertype[layer] == 'themechart': - menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer), parentframe=self) + menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) def onDeleteLayer(self, event): layer = event.GetItem() Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 16:38:47 UTC (rev 280) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-24 17:09:42 UTC (rev 281) @@ -263,7 +263,7 @@ The dialog is organized in a notebook according to the guisections defined by each GRASS command.""" - def __init__(self, parent, ID, get_dcmd=None, layer=None): + def __init__(self, parent, ID, get_dcmd=None, layer=None, dcmd_params=None): wx.Frame.__init__(self, parent, ID, grass_task.name, wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) @@ -273,6 +273,7 @@ self.selection = '' #selection from GIS element selector self.paramdict = {} # dictionary of controls and their parameter values self.get_dcmd = get_dcmd + self.dcmd_params = dcmd_params #this should be passed from the layer tree eventually self.layer = layer menu = wx.Menu() @@ -328,6 +329,11 @@ if p['multiple'] == 'yes' and len( p['values'] ) == 0: title = "[multiple] " + title p['value'] = p['default'] + # inserting existing values from d.* command in layer tree + if self.dcmd_params != None: + for dparam in self.dcmd_params: + if p == dparam: + p['value'] = self.dcmd_params[dparam] if (len(p['values']) > 0): valuelist=map(str,p['values']) @@ -400,6 +406,7 @@ which_sizer.Add(btn_colour, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) self.paramdict[btn_colour] = ID_PARAM_START + p_count self.Bind(csel.EVT_COLOURSELECT, self.OnColorButton, btn_colour) + f_count = -1 for f in grass_task.flags: f_count += 1 From barton at grass.itc.it Sun Mar 25 03:21:39 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 03:21:40 2007 Subject: [grass-addons] r282 - trunk/grassaddons/gui/Gism Message-ID: <200703250121.l2P1LdV7031804@grass.itc.it> Author: barton Date: 2007-03-25 03:21:25 +0200 (Sun, 25 Mar 2007) New Revision: 282 Added: trunk/grassaddons/gui/Gism/grass.smlogo.gif trunk/grassaddons/gui/Gism/grasslogo_big.gif Log: GRASS logos to use in dialogs. Added: trunk/grassaddons/gui/Gism/grass.smlogo.gif =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/Gism/grass.smlogo.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/Gism/grasslogo_big.gif =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/Gism/grasslogo_big.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From barton at grass.itc.it Sun Mar 25 03:22:38 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 03:22:40 2007 Subject: [grass-addons] r283 - trunk/grassaddons/gui Message-ID: <200703250122.l2P1McTf031830@grass.itc.it> Author: barton Date: 2007-03-25 03:22:30 +0200 (Sun, 25 Mar 2007) New Revision: 283 Modified: trunk/grassaddons/gui/grass_wizard.py Log: Updating and polishing location wizard Modified: trunk/grassaddons/gui/grass_wizard.py =================================================================== --- trunk/grassaddons/gui/grass_wizard.py 2007-03-25 01:21:25 UTC (rev 282) +++ trunk/grassaddons/gui/grass_wizard.py 2007-03-25 01:22:30 UTC (rev 283) @@ -50,50 +50,93 @@ self.parent = parent # text input - self.tdatum = self.MakeTextCtrl("") - self.ttrans = self.MakeTextCtrl("") + self.tdatum = self.MakeTextCtrl("", size=(200,20)) + self.ttrans = self.MakeTextCtrl("", size=(200,20)) # search box - self.searchb = wx.SearchCtrl(self, size=(100,-1), style=wx.TE_PROCESS_ENTER) + self.searchb = wx.SearchCtrl(self, size=(200,20), + style=wx.TE_PROCESS_ENTER) # button self.bupdate = self.MakeButton("Update trans. parms.", - size=(150,25)) + size=(-1,-1)) # table - self.tablewidth=600 - self.datumlist = wx.ListCtrl(self, -1, style=wx.LC_REPORT | wx.LC_VRULES | wx.LC_HRULES, size=(700,100)) - self.datumlist.InsertColumn(0, 'Short Name ') - self.datumlist.InsertColumn(1, ' Full EPSG-style name ') + self.tablewidth=675 + + # create list control for datum/elipsoid list + self.datumlist = wx.ListCtrl(self, id=wx.ID_ANY, + size=(675,150), + style=wx.LC_REPORT | + wx.LC_VRULES | + wx.LC_HRULES | + wx.EXPAND) + self.datumlist.InsertColumn(0, 'Short Name') + self.datumlist.InsertColumn(1, 'Full EPSG-style name') self.datumlist.InsertColumn(2, 'Ellipsoid') - self.datumlist.InsertColumn(3, ' Parameters ') + self.datumlist.InsertColumn(3, 'Parameters') self.datumlist.SetColumnWidth(0, 100) - self.datumlist.SetColumnWidth(1, wx.LIST_AUTOSIZE_USEHEADER) - self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE_USEHEADER) - self.datumlist.SetColumnWidth(3, wx.LIST_AUTOSIZE_USEHEADER) + self.datumlist.SetColumnWidth(1, 225) + self.datumlist.SetColumnWidth(2, 100) + self.datumlist.SetColumnWidth(3, 250) - self.transformlist = wx.ListCtrl(self, -1, style=wx.LC_REPORT | wx.LC_VRULES | wx.LC_HRULES, size=(700,100)) - self.transformlist.InsertColumn(0, ' ID') - self.transformlist.InsertColumn(1, ' Country ') - self.transformlist.InsertColumn(2, ' Description ') - self.transformlist.InsertColumn(3, ' Params ') - self.transformlist.SetColumnWidth(0, 30) - self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE_USEHEADER) - self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE_USEHEADER) - self.transformlist.SetColumnWidth(3, wx.LIST_AUTOSIZE_USEHEADER) - + # create list control for datum transformation parameters list + self.transformlist = wx.ListCtrl(self, id=wx.ID_ANY, + size=(675,125), + style=wx.LC_REPORT | + wx.LC_VRULES | + wx.LC_HRULES | + wx.EXPAND) + self.transformlist.InsertColumn(0, 'ID') + self.transformlist.InsertColumn(1, 'Country') + self.transformlist.InsertColumn(2, 'Description ') + self.transformlist.InsertColumn(3, 'Parameters') + self.transformlist.SetColumnWidth(0, 50) + self.transformlist.SetColumnWidth(1, 125) + self.transformlist.SetColumnWidth(2, 250) + self.transformlist.SetColumnWidth(3, 250) + # laout - self.sizer.Add(self.MakeLabel("Geodetic datum:"), 1, col=1, row=1) - self.sizer.Add(self.tdatum, 0 , wx.ALIGN_LEFT, 1, row=1, col=2) - self.sizer.Add(self.bupdate, 0 , wx.ALIGN_CENTER_VERTICAL, 1, row=1, col=3) - self.sizer.Add(self.MakeLabel("Search in description:"), 1, col=1, row=2) - self.sizer.Add(self.searchb, 0 , wx.ALIGN_LEFT, 1, row=2, col=2) + self.sizer.Add(self.MakeLabel("Geodetic datum:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=1) + self.sizer.Add(self.tdatum, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.bupdate, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=3) + self.sizer.Add(self.MakeLabel("Search in description:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=2) + self.sizer.Add(self.searchb, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=2) - self.sizer.Add(self.datumlist, 0 , wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL, 1, row=3, col=1, colspan=5) - self.sizer.Add(self.MakeLabel("Transformation parameters:"), 1, col=1, row=5) - self.sizer.Add(self.ttrans, 0 , wx.ALIGN_LEFT, 1, row=5, col=2) - self.sizer.Add(self.transformlist, 0 , wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL, 1, row=6, col=1, colspan=5) + self.sizer.Add(self.datumlist, 0 , + wx.EXPAND | + wx.ALIGN_LEFT | + wx.ALL, 5, row=3, col=1, colspan=5) + self.sizer.Add(self.MakeLabel("Transformation parameters:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=5) + self.sizer.Add(self.ttrans, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=5, col=2) + + self.sizer.Add(self.transformlist, 0 , + wx.EXPAND | + wx.ALIGN_LEFT | + wx.ALL, 5, row=6, col=1, colspan=5) + # events #wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) #wx.EVT_BUTTON(self, self.bbcodes.GetId(), self.OnBrowseCodes) @@ -104,6 +147,10 @@ self.tdatum.Bind(wx.EVT_TEXT_ENTER, self._onBrowseParams, self.tdatum) self._onBrowseDatums(None,None) + self.datumlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) + self.datumlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) + self.datumlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) def OnDoSearch(self,event): str = self.searchb.GetValue() @@ -117,7 +164,7 @@ break self._onBrowseDatums(None,str) - + def OnTransformSelected(self,event): item = event.GetItem() self.ttrans.SetValue(str(item.GetText())) @@ -126,7 +173,7 @@ item = event.GetItem() self.tdatum.SetValue(str(item.GetText())) self._onBrowseParams() - + def _onBrowseParams(self, event=None): params = [["","Use whole region",""]] file = os.path.join(os.getenv("GISBASE"), "etc","datumtransform.table") @@ -149,10 +196,29 @@ self.transformlist.DeleteAllItems() for i in range(len(params)): - self.transformlist.InsertStringItem(i,str(i+1)) - self.transformlist.SetStringItem(i,1,params[i][1]) - self.transformlist.SetStringItem(i,2,params[i][2]) - self.transformlist.SetStringItem(i,3,params[i][0]) + # fill datum transformation parameters list control + index = self.transformlist.InsertStringItem(i,str(i+1)) + dtp1 = self.transformlist.SetStringItem(index,1,params[i][1]) + dtp2 = self.transformlist.SetStringItem(index,2,params[i][2]) + dtp3 = self.transformlist.SetStringItem(index,3,params[i][0]) + # format list control columns + if index != '': + self.transformlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) + else: + self.transformlist.SetColumnWidth(0, 30) + if dtp1 != '': + self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + else: + self.transformlist.SetColumnWidth(1, 150) + if dtp2 != '': + self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) + else: + self.transformlist.SetColumnWidth(2, 250) + if dtp3 != '': + self.transformlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) + else: + self.transformlist.SetColumnWidth(3, 320) + except IOError, e: self.transformlist.DeleteAllItems() dlg = wx.MessageDialog(self, "Could not read datum params: %s " @@ -179,10 +245,10 @@ ellps.lower().find(search.lower()) > -1 or\ epsgname.lower().find(search.lower()) > -1) or\ not search: - self.datumlist.InsertStringItem(j,shortname) - self.datumlist.SetStringItem(j,1,epsgname) - self.datumlist.SetStringItem(j,2,ellps) - self.datumlist.SetStringItem(j,3,params) + index = self.datumlist.InsertStringItem(j,shortname) + self.datumlist.SetStringItem(index,1,epsgname) + self.datumlist.SetStringItem(index,2,ellps) + self.datumlist.SetStringItem(index,3,params) j += 1 f.close() self.datumlist.SendSizeEvent() @@ -459,7 +525,7 @@ path = self.tdsn.GetValue() number="-?\d+\.\d+" line = "" - + #Extent: (-146.976217, -55.985484) - (72.774632, 80.594358) rex = re.compile("\((%s),\s*(%s)\)\s*-\s*\((%s),\s*(%s)\)" %(number, number, number, number)) cmd = os.popen("ogrinfo -so %s %s" % (path ,layer)) @@ -502,7 +568,7 @@ self.tbottom.SetValue(y) self.tright.SetValue(x) line = obj.readline() - return + return def OnStateText(self,event): item = self.llayers.FindString(event.GetString()) @@ -523,7 +589,7 @@ def OnItemSelected(self, event): item = self.cstate.GetSelection() w,s,e,n = self.coords[item] - # 4 + # 4 # 1 3 # 2 @@ -554,9 +620,9 @@ self.lmessage.SetLabel("Unable to calculate country extends:\n cs2cs +proj=latlong +datum=WGS84 +to %s"% to) self.ttop.SetValue( str(n) ) - self.tbottom.SetValue( str(s) ) + self.tbottom.SetValue( str(s) ) self.tright.SetValue( str(e) ) - self.tleft.SetValue( str(w) ) + self.tleft.SetValue( str(w) ) class ProjectionsPage(TitledPage): def __init__(self, wizard, parent): @@ -564,27 +630,48 @@ self.parent = parent # text input - self.tproj = self.MakeTextCtrl("") + self.tproj = self.MakeTextCtrl("", size=(200,20)) # search box - self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) + self.searchb = wx.SearchCtrl(self, size=(200,20), + style=wx.TE_PROCESS_ENTER) # table - self.tablewidth=600 - self.list = wx.ListCtrl(self, -1, style=wx.LC_REPORT| wx.LC_VRULES | wx.LC_HRULES, size=(700,100)) + self.tablewidth=675 + self.list = wx.ListCtrl(self, id=wx.ID_ANY, + size=(675,275), + style=wx.LC_REPORT | + wx.LC_VRULES | + wx.LC_HRULES | + wx.EXPAND) self.list.InsertColumn(0, 'Name') - self.list.InsertColumn(1, ' Description ') - self.list.SetColumnWidth(0, 50) - self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE_USEHEADER) + self.list.InsertColumn(1, 'Description') + self.list.SetColumnWidth(0, 100) + self.list.SetColumnWidth(1, 575) - # laout - self.sizer.Add(self.MakeLabel("Projection name:"), 0, row=1, col=2) - self.sizer.Add(self.tproj, 0, wx.ALIGN_LEFT, 1, row=1, col=3) + # layout + self.sizer.Add(self.MakeLabel("Projection name:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.tproj, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=3) - self.sizer.Add(self.MakeLabel("Search in projection description"), 0, 1, row=2, col=2) - self.sizer.Add(self.searchb, 0, wx.ALIGN_LEFT,1, row=2, col=3) + self.sizer.Add(self.MakeLabel("Search in projection description"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=2) + self.sizer.Add(self.searchb, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=3) - self.sizer.Add(self.list, wx.EXPAND, 1, row=3, col=1, colspan=5) + self.sizer.Add(self.list, + wx.EXPAND | + wx.ALIGN_LEFT | + wx.ALL, 5, row=3, col=1, colspan=4) # events self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) @@ -592,6 +679,9 @@ self._onBrowseDatums(None, None) + self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE) + self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE) + def OnDoSearch(self,event): str = self.searchb.GetValue() listItem = self.list.GetColumn(1) @@ -604,13 +694,13 @@ break self._onBrowseDatums(None,str) - + def OnItemSelected(self,event): item = event.GetItem() self.tproj.SetValue(str(item.GetText())) - + def _onBrowseDatums(self,event,search=None): try: self.list.DeleteAllItems() @@ -632,7 +722,7 @@ self.list.InsertStringItem(j,proj) self.list.SetStringItem(j,1,descr) j += 1 - # reset + # reset descr = None; proj = "" f.close() self.SendSizeEvent() @@ -649,20 +739,28 @@ class GeoreferencedFilePage(TitledPage): def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Choose projection name") + TitledPage.__init__(self, wizard, "Select georeferenced file") - self.tfile = self.MakeTextCtrl(size=(150,20)) - + # create controls + self.lfile= wx.StaticText(self, -1, "Georeferenced file: ", + style=wx.ALIGN_RIGHT) + self.tfile = wx.TextCtrl(self,-1, "", size=(150,20)) self.bbrowse = self.MakeButton("Browse ...") - self.sizer.Add(self.MakeLabel("Georeferenced file:"), 1, row=1, col=2) - self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT, 1, row=1, col=3) - self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT, 1, row=1, col=4) + # do layout + self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTRE_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTRE_VERTICAL | + wx.ALL, 5, row=1, col=3) + self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | + wx.ALL, 5, row=1, col=4) wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) - def OnBrowse(self, event): - + def OnBrowse(self, event): + dlg = wx.FileDialog(self, "Choose a georeferenced file:", os.getcwd(), "", "*.*", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() @@ -697,7 +795,7 @@ # # Markus Neteler # try: # # FIXME: this does not need to work on windows - # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) + # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) # self.parent.OnSetDatabase(None) # self.Destroy() @@ -712,42 +810,70 @@ def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Choose EPSG Code") + # labels + self.lfile= wx.StaticText(self, -1, "Path to the EPSG-codes file: ", + style=wx.ALIGN_RIGHT) + self.lcode= wx.StaticText(self, -1, "EPSG code: ", + style=wx.ALIGN_RIGHT) + self.lsearch= wx.StaticText(self, -1, "Search in code description: ", + style=wx.ALIGN_RIGHT) + # text input - self.tfile = self.MakeTextCtrl("/usr/share/proj/epsg", size=(150,20)) - self.tcode = self.MakeTextCtrl("") + epsgdir = os.path.join(os.environ["GRASS_PROJSHARE"], 'epsg') + self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,20)) + self.tcode = wx.TextCtrl(self,-1, "", size=(200,20)) # buttons - self.bbrowse = self.MakeButton("Browse ...") - self.bbcodes = self.MakeButton("Browse Codes") + self.bbrowse = wx.Button(self, -1, "Browse ...", size=(100,-1)) + self.bbcodes = wx.Button(self, -1, "Browse Codes") # search box self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) # table - self.tablewidth=600 - self.epsgs = wx.ListCtrl(self, -1, style=wx.LC_REPORT| wx.LC_VRULES | wx.LC_HRULES, - size=(700,100)) - self.epsgs.InsertColumn(0, 'EPSG') - self.epsgs.InsertColumn(1, ' Description ') - self.epsgs.InsertColumn(2, ' Parameters ') + self.tablewidth=675 + self.epsgs = wx.ListCtrl(self, id=wx.ID_ANY, + size=(675,275), + style=wx.LC_REPORT| + wx.LC_HRULES| + wx.EXPAND) + self.epsgs.InsertColumn(0, 'EPSG', wx.LIST_FORMAT_CENTRE) + self.epsgs.InsertColumn(1, 'Description', wx.LIST_FORMAT_LEFT) + self.epsgs.InsertColumn(2, 'Parameters', wx.LIST_FORMAT_LEFT) self.epsgs.SetColumnWidth(0, 50) - self.epsgs.SetColumnWidth(1, wx.LIST_AUTOSIZE_USEHEADER) - self.epsgs.SetColumnWidth(2, wx.LIST_AUTOSIZE_USEHEADER) - - # laout - self.sizer.Add(self.MakeLabel("Path to the EPSG-codes file:"), 1, col=1, row=1) - self.sizer.Add(self.tfile, 0 , wx.ALIGN_LEFT, 1, row=1, col=2) - self.sizer.Add(self.bbrowse, 0 , wx.ALIGN_CENTER_HORIZONTAL, 1, row=1, col=3) + self.epsgs.SetColumnWidth(1, 300) + self.epsgs.SetColumnWidth(2, 325) - self.sizer.Add(self.MakeLabel("EPSG code:"), 0, col=1, row=2) - self.sizer.Add(self.tcode, 0, wx.ALIGN_LEFT,1, row=2, col=2) + # layout + self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=1) + self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=3) - self.sizer.Add(self.MakeLabel("Search in code description:"), 0, col=1, row=3) - self.sizer.Add(self.searchb, 0, wx.ALIGN_LEFT,1, row=3, col=2) - self.sizer.Add(self.bbcodes, 0 , wx.ALIGN_CENTER_HORIZONTAL, row=3, col=3) + self.sizer.Add(self.lcode, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=2) + self.sizer.Add(self.tcode, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=2) - self.sizer.Add(self.epsgs, wx.EXPAND, 0, row=4, col=1, colspan=5) + self.sizer.Add(self.lsearch, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=3) + self.sizer.Add(self.searchb, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3, col=2) + self.sizer.Add(self.bbcodes, 0 , wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3, col=3) + self.sizer.Add(self.epsgs, wx.ALIGN_LEFT|wx.EXPAND, 0, row=4, col=1, colspan=5) + # events wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) wx.EVT_BUTTON(self, self.bbcodes.GetId(), self.OnBrowseCodes) @@ -766,10 +892,10 @@ break self.OnBrowseCodes(None,str) - - def OnBrowse(self, event): - + + def OnBrowse(self, event): + dlg = wx.FileDialog(self, "Choose a georeferenced file:", "/", "", "*.*", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: @@ -781,7 +907,7 @@ item = event.GetItem() self.tcode.SetValue(str(item.GetText())) - + def OnBrowseCodes(self,event,search=None): try: self.epsgs.DeleteAllItems() @@ -795,25 +921,30 @@ for line in f.readlines(): line = line.strip() if line.find("#") == 0: - descr= line[1:].strip() + descr = line[1:].strip() elif line.find("<") == 0: code = line.split(" ")[0] for par in line.split(" ")[1:]: params += par + " " code = code[1:-1] + if code == None: code = 'no code' + if descr == None: descr = 'no description' + if params == None: params = 'no parameters' if i%2 == 0: if search and descr.lower().find(search.lower()) > -1 or\ not search: - self.epsgs.InsertStringItem(j,str(code)) - self.epsgs.SetStringItem(j, 1, str(descr)) - self.epsgs.SetStringItem(j, 2, str(params)) + index = self.epsgs.InsertStringItem(j, code) + self.epsgs.SetStringItem(index, 1, descr) + self.epsgs.SetStringItem(index, 2, params) j += 1 - # reset + # reset descr = None; code = None; params = "" - if i%2 == 0: - self.epsgs.SetItemBackgroundColour(i, "grey") +# if i%2 == 0: +# self.epsgs.SetItemBackgroundColour(i, "grey") i += 1 f.close() + self.epsgs.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.epsgs.SetColumnWidth(2, wx.LIST_AUTOSIZE) self.SendSizeEvent() except StandardError, e: dlg = wx.MessageDialog(self, "Could not read EPGS codes: %s " @@ -831,7 +962,7 @@ # dlg.ShowModal() # dlg.Destroy() # return - # + # # number = -1 # try: # number = int(self.tcode.GetValue()) @@ -841,20 +972,20 @@ # dlg.ShowModal() # dlg.Destroy() # return - # + # # if os.path.isdir(os.path.join(self.parent.gisdbase,self.tname.GetValue())): # dlg = wx.MessageDialog(self, "Could not create new location: %s exists" # % os.path.join(self.parent.gisdbase,self.tname.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) # dlg.ShowModal() # dlg.Destroy() # return - # + # # # creating location # # all credit to Michael Barton and his file_option.tcl and # # Markus Neteler # try: # # FIXME: this does not need to work on windows - # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) + # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) # datumtrans = os.popen(" g.proj epsg=%d datumtrans=-1 >&2" % (number)).readlines() # if datumtrans: @@ -873,7 +1004,7 @@ # dlg.Destroy() # return - + def OnDoubleClick(self, event): print self.epsgs.GetValue() pass @@ -883,7 +1014,7 @@ def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Choose coordinate system for location") - self.parent = parent + self.parent = parent self.cs = "xy" # toggles @@ -901,7 +1032,7 @@ self.sizer.Add(self.radio4, 0, wx.ALIGN_LEFT, row=4, col=2) self.sizer.Add(self.radio5, 0, wx.ALIGN_LEFT, row=5, col=2) self.sizer.Add(self.radio6, 0, wx.ALIGN_LEFT, row=6, col=2) - + # bindings self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId()) self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId()) @@ -953,24 +1084,48 @@ TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name") # buttons - self.bbrowse = self.MakeButton("Browse ...") + self.bbrowse = self.MakeButton("Browse ...", size=wx.DefaultSize) # text controls self.tgisdbase = self.MakeTextCtrl(grassdatabase, size=(300, 20)) - self.tlocation = self.MakeTextCtrl("newLocation") - + self.tlocation = self.MakeTextCtrl("newLocation", size=(300, 20)) + # layout - self.sizer.Add(self.MakeLabel("GIS Data Directory:"), 0, wx.ALIGN_RIGHT, row=1, col=2) - self.sizer.Add(self.tgisdbase,0,wx.ALIGN_LEFT, row=1, col=3) - self.sizer.Add(self.bbrowse, 0, wx.ALIGN_CENTER_HORIZONTAL, row=1, col=4) + self.sizer.Add(self.MakeLabel("GIS Data Directory:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=1, col=2) + self.sizer.Add(self.tgisdbase,0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=1, col=3) + self.sizer.Add(self.bbrowse, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=1, col=4) # - self.sizer.Add(self.MakeLabel("Project Location\n(projection/coordinate system)"), 0, wx.ALIGN_RIGHT, row=2, col=2) - self.sizer.Add(self.tlocation,0,wx.ALIGN_LEFT, row=2, col=3) - + self.sizer.Add(self.MakeLabel("Project Location"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=2, col=2) + self.sizer.Add(self.tlocation,0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=2, col=3) + self.sizer.Add(self.MakeLabel("(projection/coordinate system)"), 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=2, col=4) + # bindings self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChanging) - def OnWizPageChanging(self,event=None): if os.path.isdir(os.path.join(self.tgisdbase.GetValue(),self.tlocation.GetValue())): dlg = wx.MessageDialog(self, "Could not create new location: <%s> directory exists "\ @@ -994,11 +1149,15 @@ def OnWizPageChange(self,event=None): self.grassdatabase = self.tgisdbase.GetValue() self.location = self.tlocation.GetValue() - + class GWizard: def __init__(self, parent, grassdatabase): - wizard = wiz.Wizard(parent, -1, "Define new Location") + wizbmp = wx.Image(os.path.join(os.getenv("GISBASE"),"etc","wx","Gism","grasslogo_small.gif"), wx.BITMAP_TYPE_GIF) + wizbmp.Rescale(50,60) + wizbmp = wizbmp.ConvertToBitmap() + wizard = wiz.Wizard(parent, -1, "Define new Location", + bitmap=wizbmp) self.startpage = DatabasePage(wizard, self, grassdatabase) self.csystemspage = CoordinateSystemPage(wizard, self) self.epsgpage = EPSGPage(wizard, self) @@ -1007,7 +1166,7 @@ self.projpage = ProjectionsPage(wizard, self) self.sumpage = SummaryPage(wizard, self) self.datumpage = DatumPage(wizard, self) - + # Set the initial order of the pages self.startpage.SetNext(self.csystemspage) @@ -1027,7 +1186,7 @@ self.bboxpage.SetPrev(self.csystemspage) self.bboxpage.SetNext(self.sumpage) - self.sumpage.SetPrev(self.bboxpage) + self.sumpage.SetPrev(self.bboxpage) wizard.FitToPage(self.bboxpage) wizard.RunWizard(self.startpage) From barton at grass.itc.it Sun Mar 25 07:16:21 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 07:16:23 2007 Subject: [grass-addons] r284 - trunk/grassaddons/gui Message-ID: <200703250516.l2P5GLU9020392@grass.itc.it> Author: barton Date: 2007-03-25 07:16:13 +0200 (Sun, 25 Mar 2007) New Revision: 284 Modified: trunk/grassaddons/gui/grass_wizard.py Log: Wizard is pretty much nicely formatted. But the location-creating code still doesn't work yet. Modified: trunk/grassaddons/gui/grass_wizard.py =================================================================== --- trunk/grassaddons/gui/grass_wizard.py 2007-03-25 01:22:30 UTC (rev 283) +++ trunk/grassaddons/gui/grass_wizard.py 2007-03-25 05:16:13 UTC (rev 284) @@ -34,7 +34,7 @@ pass return wx.StaticText(self, -1, text, style=wx.ALIGN_RIGHT) - def MakeTextCtrl(self,text='', size=(100,20)): + def MakeTextCtrl(self,text='', size=(100,-1)): return wx.TextCtrl(self,-1, text, size=size) def MakeButton(self,text, size=(75,25)): @@ -50,11 +50,11 @@ self.parent = parent # text input - self.tdatum = self.MakeTextCtrl("", size=(200,20)) - self.ttrans = self.MakeTextCtrl("", size=(200,20)) + self.tdatum = self.MakeTextCtrl("", size=(200,-1)) + self.ttrans = self.MakeTextCtrl("", size=(200,-1)) # search box - self.searchb = wx.SearchCtrl(self, size=(200,20), + self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) # button @@ -96,7 +96,7 @@ self.transformlist.SetColumnWidth(2, 250) self.transformlist.SetColumnWidth(3, 250) - # laout + # layout self.sizer.Add(self.MakeLabel("Geodetic datum:"), 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | @@ -356,26 +356,33 @@ class BBoxPage(TitledPage): def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Set default region") + TitledPage.__init__(self, wizard, "Set default region extents and resolution") self.parent = parent # inputs - self.ttop = self.MakeTextCtrl("1") - self.tbottom = self.MakeTextCtrl("0") - self.tleft = self.MakeTextCtrl("0") - self.tright = self.MakeTextCtrl("1") - self.tres = self.MakeTextCtrl("1") - self.tgdal = self.MakeTextCtrl("") - self.tdsn = self.MakeTextCtrl("") + self.ttop = self.MakeTextCtrl("1", size=(150, -1)) + self.tbottom = self.MakeTextCtrl("0", size=(150, -1)) + self.tleft = self.MakeTextCtrl("0", size=(150, -1)) + self.tright = self.MakeTextCtrl("1", size=(150, -1)) + self.tres = self.MakeTextCtrl("1", size=(150, -1)) + self.tgdal = self.MakeTextCtrl("", size=(250, -1)) + self.tdsn = self.MakeTextCtrl("", size=(250, -1)) + # list of layers + self.layers = [] + self.llayers = wx.ComboBox(self, -1, + choices=self.layers, + size=(250,-1), + style=wx.CB_DROPDOWN) + # labels - self.lmessage = wx.StaticText(self,-1, "", size=(200,50)) + self.lmessage = wx.StaticText(self,-1, "", size=(300,50)) # buttons - self.bbrowsegdal = self.MakeButton("Browse ...") - self.bbrowseogr = self.MakeButton("Browse ...") - self.bgetlayers = self.MakeButton("Get Layers") - self.bset = self.MakeButton("Set coordinates") + self.bbrowsegdal = self.MakeButton("Browse ...", size=(150,-1)) + self.bbrowseogr = self.MakeButton("Browse ...", size=(150,-1)) + self.bgetlayers = self.MakeButton("Get Layers", size=(150,-1)) + self.bset = self.MakeButton("Set coordinates", size=(150,-1)) # list of states self.states = [] @@ -399,60 +406,136 @@ # self.cstate = wx.combo.ComboCtrl(self, -1, pos=(50, 170), size=(150, -1), # style=wx.CB_READONLY) - self.cstate = wx.ComboBox(self, -1, pos=(50, 170), size=(150, -1), - choices=self.states, style=wx.CB_DROPDOWN) + self.cstate = wx.ComboBox(self, -1, + size=(250,-1), + choices=self.states, + style=wx.CB_DROPDOWN) - # list of layers - self.layers = [] - self.llayers = wx.ComboBox(self, -1, choices=self.layers, size=(100,-1), - style=wx.CB_DROPDOWN) + # layout + self.sizer.Add(self.MakeLabel("North"), 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 0, row=1,col=2) + self.sizer.Add(self.ttop, 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2,col=2) + self.sizer.Add(self.MakeLabel("West"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 0, row=3,col=0) + self.sizer.Add(self.tleft, 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3,col=1) - # layout - self.sizer.Add(self.MakeLabel("North"), 0, wx.ALIGN_RIGHT, row=1,col=2) - self.sizer.Add(self.ttop, 0, wx.ALIGN_LEFT, row=1,col=3) + self.sizer.Add(self.tright, 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3,col=3) + self.sizer.Add(self.MakeLabel("East"), 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 0, row=3,col=4) - self.sizer.Add(self.MakeLabel("West"), 0, wx.ALIGN_RIGHT, row=2,col=1) - self.sizer.Add(self.tleft, 0, wx.ALIGN_LEFT, row=2,col=2) - self.sizer.Add(self.MakeLabel("East"), 0, wx.ALIGN_RIGHT, row=2,col=4) - self.sizer.Add(self.tright, 0, wx.ALIGN_LEFT, row=2,col=5) + self.sizer.Add(self.tbottom, 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=4,col=2) + self.sizer.Add(self.MakeLabel("South"), 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 0, row=5,col=2) - self.sizer.Add(self.MakeLabel("South"), 0, wx.ALIGN_RIGHT, row=3,col=2) - self.sizer.Add(self.tbottom, 0, wx.ALIGN_LEFT, row=3,col=3) + self.sizer.Add(self.MakeLabel("Initial resolution"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=6,col=1) + self.sizer.Add(self.tres, 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=6,col=2) + self.sizer.Add(self.bset, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=6, col=3 ) - self.sizer.Add(self.MakeLabel("Initial resolution"), 0, wx.ALIGN_RIGHT, row=4,col=2) - self.sizer.Add(self.tres, 0, wx.ALIGN_LEFT, row=4,col=3) - self.sizer.Add(self.bset, 0, wx.ALIGN_CENTER_VERTICAL, row=4, col=5 ) + self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0, row=7, col=0, colspan=6) - self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0, row=5, col=0, colspan=6) - self.sizer.Add(self.MakeLabel("Use georeferenced raster file"), 3, wx.ALIGN_RIGHT, row=6,col=0, colspan=3) + self.sizer.Add(self.MakeLabel("Match extents of georeferenced raster map or image"), 3, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=8,col=0, colspan=3) - self.sizer.Add(self.MakeLabel("File name:"), 3, wx.ALIGN_RIGHT, row=7,col=2, colspan=1) - self.sizer.Add(self.tgdal, 0, wx.ALIGN_CENTER_VERTICAL, row=7,col=3) - self.sizer.Add(self.bbrowsegdal, 0, wx.ALIGN_LEFT, row=7,col=4) + self.sizer.Add(self.MakeLabel("File:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=9,col=0, colspan=1) + self.sizer.Add(self.tgdal, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=9,col=1, colspan=2) + self.sizer.Add(self.bbrowsegdal, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=9,col=3) - self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0, - row=8, col=2, colspan=3) + self.sizer.Add(wx.StaticLine(self, -1), 0, + wx.EXPAND|wx.ALL, 0, + row=10, col=0, colspan=6) - self.sizer.Add(self.MakeLabel("Use georeferenced vector layer"), 3, wx.ALIGN_RIGHT, row=9,col=0, colspan=3 ) + self.sizer.Add(self.MakeLabel("Match extents of georeferenced vector map"), 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=11,col=0, colspan=3 ) - self.sizer.Add(self.MakeLabel("Data source name:"), 3, wx.ALIGN_RIGHT, row=10,col=2, colspan=1) - self.sizer.Add(self.tdsn, 0, wx.ALIGN_CENTER_VERTICAL, row=10, col=3) - self.sizer.Add(self.bbrowseogr, 0, wx.ALIGN_LEFT, row=10,col=4) + self.sizer.Add(self.MakeLabel("Data source/directory:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=12,col=0, colspan=1) + self.sizer.Add(self.tdsn, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=12, col=1, colspan=2) + self.sizer.Add(self.bbrowseogr, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=12, col=3) - self.sizer.Add(self.MakeLabel("Layer name:"), 3, wx.ALIGN_RIGHT, row=12,col=2, colspan=1) - self.sizer.Add(self.llayers, 0, wx.ALIGN_CENTER_VERTICAL, row=12,col=3) - self.sizer.Add(self.bgetlayers, 0, wx.ALIGN_LEFT, row=12,col=4) + self.sizer.Add(self.MakeLabel("Layer/file:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=13,col=0, colspan=1) + self.sizer.Add(self.llayers, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=13,col=1, colspan=2) + self.sizer.Add(self.bgetlayers, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=13,col=3) - self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0, - row=13, col=0, colspan=6) - self.sizer.Add(self.MakeLabel("Set extent according to selected country"), 3, wx.ALIGN_RIGHT, row=14,col=2) - self.sizer.Add(self.cstate, 0, wx.ALIGN_LEFT, row=14,col=3) + self.sizer.Add(wx.StaticLine(self, -1), 0, + wx.EXPAND|wx.ALL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=14, col=0, colspan=6) + self.sizer.Add(self.MakeLabel("Match extents of selected country"), 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=15,col=0, colspan=3) + self.sizer.Add(self.cstate, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=16,col=1, colspan=2) - self.sizer.Add(self.lmessage, 0, wx.ALIGN_CENTER_VERTICAL, - row=15,col=3, colspan=3) + self.sizer.Add(self.lmessage, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=17,col=1, colspan=3) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChange) self.Bind(wx.EVT_COMBOBOX, self.OnItemSelected, self.cstate) self.Bind(wx.EVT_TEXT, self.OnStateText, self.cstate) @@ -526,6 +609,10 @@ number="-?\d+\.\d+" line = "" + #test values + self.ttop.SetValue(500) + self.tleft.SetValue(500) + #Extent: (-146.976217, -55.985484) - (72.774632, 80.594358) rex = re.compile("\((%s),\s*(%s)\)\s*-\s*\((%s),\s*(%s)\)" %(number, number, number, number)) cmd = os.popen("ogrinfo -so %s %s" % (path ,layer)) @@ -550,6 +637,10 @@ line = "" number="-?\d+\.\d+" + #test values + self.ttop.SetValue(500) + self.tleft.SetValue(500) + # Upper Left ( 0.0, 0.0) rex=re.compile("\(\s*(%s)\s*,\s*(%s)\)" % (number, number)) obj = os.popen("gdalinfo %s | grep \"Upper\|Lower\"" % path) @@ -630,10 +721,10 @@ self.parent = parent # text input - self.tproj = self.MakeTextCtrl("", size=(200,20)) + self.tproj = self.MakeTextCtrl("", size=(200,-1)) # search box - self.searchb = wx.SearchCtrl(self, size=(200,20), + self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) # table @@ -744,7 +835,7 @@ # create controls self.lfile= wx.StaticText(self, -1, "Georeferenced file: ", style=wx.ALIGN_RIGHT) - self.tfile = wx.TextCtrl(self,-1, "", size=(150,20)) + self.tfile = wx.TextCtrl(self,-1, "", size=(150,-1)) self.bbrowse = self.MakeButton("Browse ...") # do layout @@ -820,8 +911,8 @@ # text input epsgdir = os.path.join(os.environ["GRASS_PROJSHARE"], 'epsg') - self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,20)) - self.tcode = wx.TextCtrl(self,-1, "", size=(200,20)) + self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,-1)) + self.tcode = wx.TextCtrl(self,-1, "", size=(200,-1)) # buttons self.bbrowse = wx.Button(self, -1, "Browse ...", size=(100,-1)) @@ -1087,8 +1178,8 @@ self.bbrowse = self.MakeButton("Browse ...", size=wx.DefaultSize) # text controls - self.tgisdbase = self.MakeTextCtrl(grassdatabase, size=(300, 20)) - self.tlocation = self.MakeTextCtrl("newLocation", size=(300, 20)) + self.tgisdbase = self.MakeTextCtrl(grassdatabase, size=(300, -1)) + self.tlocation = self.MakeTextCtrl("newLocation", size=(300, -1)) # layout self.sizer.Add(self.MakeLabel("GIS Data Directory:"), 0, From barton at grass.itc.it Sun Mar 25 07:25:21 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 07:25:22 2007 Subject: [grass-addons] r285 - trunk/grassaddons/gui Message-ID: <200703250525.l2P5PLdW020450@grass.itc.it> Author: barton Date: 2007-03-25 07:25:13 +0200 (Sun, 25 Mar 2007) New Revision: 285 Modified: trunk/grassaddons/gui/gis_set.py Log: Minor code cleanup Modified: trunk/grassaddons/gui/gis_set.py =================================================================== --- trunk/grassaddons/gui/gis_set.py 2007-03-25 05:16:13 UTC (rev 284) +++ trunk/grassaddons/gui/gis_set.py 2007-03-25 05:25:13 UTC (rev 285) @@ -28,7 +28,6 @@ def __init__(self, parent, id, title, ): wx.Frame.__init__(self,parent, id , title, size=(50,600)) - self.parent = parent # sizers @@ -40,8 +39,6 @@ style=wx.ALIGN_RIGHT) self.lfile= wx.StaticText(self, -1, "Path to the EPSG-codes file: ", style=wx.ALIGN_RIGHT) - - self.lcode= wx.StaticText(self, -1, "EPSG code: ", style=wx.ALIGN_RIGHT) self.lsearch= wx.StaticText(self, -1, "Search in code description: ", @@ -71,9 +68,11 @@ # table self.tablewidth=600 - self.epsgs = wx.ListCtrl(self, id = wx.ID_ANY, + self.epsgs = wx.ListCtrl(self, id=wx.ID_ANY, size=(750,200), - style=wx.LC_REPORT|wx.LC_HRULES|wx.EXPAND) + style=wx.LC_REPORT| + wx.LC_HRULES| + wx.EXPAND) self.epsgs.InsertColumn(0, 'EPSG', wx.LIST_FORMAT_CENTRE) self.epsgs.InsertColumn(1, 'Description', wx.LIST_FORMAT_LEFT) self.epsgs.InsertColumn(2, 'Parameters', wx.LIST_FORMAT_LEFT) @@ -295,8 +294,8 @@ self.lfile= wx.StaticText(self, -1, "Georeferenced file: ", style=wx.ALIGN_RIGHT) - self.tname = wx.TextCtrl(self,-1, "newLocation", size=(150,20)) - self.tfile = wx.TextCtrl(self,-1, "", size=(150,20)) + self.tname = wx.TextCtrl(self,-1, "newLocation", size=(200,20)) + self.tfile = wx.TextCtrl(self,-1, "", size=(200,20)) self.bbrowse = wx.Button(self, -1, "Browse ...", size=(100,-1)) self.bcancel = wx.Button(self, -1, "Cancel", size=(100,-1)) From barton at grass.itc.it Sun Mar 25 07:53:16 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 07:53:18 2007 Subject: [grass-addons] r286 - trunk/grassaddons/gui Message-ID: <200703250553.l2P5rGcf021362@grass.itc.it> Author: barton Date: 2007-03-25 07:53:08 +0200 (Sun, 25 Mar 2007) New Revision: 286 Added: trunk/grassaddons/gui/images/ Log: New directory to hold images used specifically by wxgrass From barton at grass.itc.it Sun Mar 25 07:58:05 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 07:58:07 2007 Subject: [grass-addons] r287 - trunk/grassaddons/gui/images Message-ID: <200703250558.l2P5w5dn021383@grass.itc.it> Author: barton Date: 2007-03-25 07:57:52 +0200 (Sun, 25 Mar 2007) New Revision: 287 Added: trunk/grassaddons/gui/images/grass.smlogo.gif trunk/grassaddons/gui/images/grasslogo_big.gif Log: Moving grass logo images into wx/images directory Added: trunk/grassaddons/gui/images/grass.smlogo.gif =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/images/grass.smlogo.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/images/grasslogo_big.gif =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/images/grasslogo_big.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From barton at grass.itc.it Sun Mar 25 08:00:22 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:00:24 2007 Subject: [grass-addons] r288 - trunk/grassaddons/gui/Gism Message-ID: <200703250600.l2P60MSG021403@grass.itc.it> Author: barton Date: 2007-03-25 08:00:09 +0200 (Sun, 25 Mar 2007) New Revision: 288 Modified: trunk/grassaddons/gui/Gism/menudata.py trunk/grassaddons/gui/Gism/menuform.py trunk/grassaddons/gui/Gism/toolbars.py Log: Renamed Gism to gui_modules Modified: trunk/grassaddons/gui/Gism/menudata.py =================================================================== --- trunk/grassaddons/gui/Gism/menudata.py 2007-03-25 05:57:52 UTC (rev 287) +++ trunk/grassaddons/gui/Gism/menudata.py 2007-03-25 06:00:09 UTC (rev 288) @@ -1,5 +1,5 @@ class Data: - '''Data object that returns menu descriptions to be used in gism.py. + '''Data object that returns menu descriptions to be used in wxgui.py. Probably could be changed to XML or *.dtd file.''' def GetMenu(self): return [( @@ -7,7 +7,7 @@ ("Import", "Import files", "self.runMenuCmd", "r.in.gdal"), ("Export", "Export files", "self.runMenuCmd", "r.out.gdal"), ("","","", ""), - ("E&xit", "Exit from gism.py", "self.onCloseWindow", "") + ("E&xit", "Exit from wxgui.py", "self.onCloseWindow", "") )), ("Config", ( ("Region", "Set region", "self.runMenuCmd", "g.region"), Modified: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-25 05:57:52 UTC (rev 287) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-25 06:00:09 UTC (rev 288) @@ -558,13 +558,13 @@ cmd = self.createCmd() if cmd != None and cmd[0:2] != "d.": - # Send any non-display command to parent window (probably gism.py) + # Send any non-display command to parent window (probably wxgui.py) if self.parent > -1: # put to parents try: self.parent.goutput.runCmd(cmd) except AttributeError,e: - print >>sys.stderr, "%s: Propably not running in gism.py session?" % (e) + print >>sys.stderr, "%s: Propably not running in wxgui.py session?" % (e) print >>sys.stderr, "parent window is: %s" % (str(self.parent)) # Send any other command to the shell. else: @@ -622,7 +622,7 @@ class GUI: def __init__(self, parent=-1): '''Parses GRASS commands when module is imported and used - from gism.py''' + from wxgui.py''' self.parent = parent def parseCommand(self, cmd, gmpath, completed=None, parentframe=-1 ): @@ -662,6 +662,6 @@ app = GrassGUIApp(0) # Parsing if run from command line: find out the command to run gui = GUI(app.frame) - gui.parseCommand( sys.argv[1], os.getenv("GISBASE") + "/etc/wx/Gism") + gui.parseCommand( sys.argv[1], os.getenv("GISBASE") + "/etc/wx/gui_modules") app.MainLoop() Modified: trunk/grassaddons/gui/Gism/toolbars.py =================================================================== --- trunk/grassaddons/gui/Gism/toolbars.py 2007-03-25 05:57:52 UTC (rev 287) +++ trunk/grassaddons/gui/Gism/toolbars.py 2007-03-25 06:00:09 UTC (rev 288) @@ -6,11 +6,11 @@ """ import wx import os -import gismutils +import wxgui_utils import cmd -icons= os.path.split(gismutils.icons)[0] +icons= os.path.split(wxgui_utils.icons)[0] icons= os.path.split(icons)[0] icons= os.path.split(icons)[0] #print icons @@ -31,12 +31,12 @@ # Draw # self.displaymap = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="displaymap", - bitmap=wx.Bitmap(name=os.path.join(gismutils.icons,"gui-display.gif"), + bitmap=wx.Bitmap(name=os.path.join(wxgui_utils.icons,"gui-display.gif"), type=wx.BITMAP_TYPE_ANY), bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL, shortHelp="Display map", longHelp="") self.erase = self.toolbar.AddLabelTool(wx.ID_ANY, "erase", - wx.Bitmap(os.path.join(gismutils.icons,"gui-erase.gif"), + wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-erase.gif"), wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, "Erase display", "") self.toolbar.AddSeparator() @@ -45,22 +45,22 @@ # Zooming, etc. # self.pointer = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="pointer", - bitmap=wx.Bitmap(os.path.join(gismutils.icons,"gui-pointer.gif"), + bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-pointer.gif"), wx.BITMAP_TYPE_ANY), bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, shortHelp="Pointer", longHelp="") self.zoomin = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="zoom_in", - bitmap=wx.Bitmap(os.path.join(gismutils.icons,"gui-zoom_in.gif"), + bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-zoom_in.gif"), wx.BITMAP_TYPE_ANY), bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, shortHelp="Zoom in", longHelp="Drag or click mouse to zoom") self.zoomout = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="zoom_out", - bitmap=wx.Bitmap(os.path.join(gismutils.icons,"gui-zoom_out.gif"), + bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-zoom_out.gif"), wx.BITMAP_TYPE_ANY), bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, shortHelp="Zoom out", longHelp="Drag or click mouse to unzoom") self.pan = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="pan", - bitmap=wx.Bitmap(os.path.join(gismutils.icons,"gui-pan.gif"), + bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-pan.gif"), wx.BITMAP_TYPE_ANY), bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, shortHelp="Pan", longHelp="Drag with mouse to pan") @@ -70,7 +70,7 @@ # Misc # self.savefile = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="savefile", - #bitmap=wx.Bitmap(os.path.join(gismutils.icons,"file-save.gif"), + #bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"file-save.gif"), #wx.BITMAP_TYPE_ANY), # just testing wx.ArtProvider bitmap=wx.ArtProvider.GetBitmap(id=wx.ART_FILE_SAVE, client=wx.ART_BUTTON), From barton at grass.itc.it Sun Mar 25 08:04:57 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:04:58 2007 Subject: [grass-addons] r289 - trunk/grassaddons/gui Message-ID: <200703250604.l2P64v3K021438@grass.itc.it> Author: barton Date: 2007-03-25 08:04:49 +0200 (Sun, 25 Mar 2007) New Revision: 289 Modified: trunk/grassaddons/gui/gis_set.py trunk/grassaddons/gui/wxgrass Log: Modified for file name changes Modified: trunk/grassaddons/gui/gis_set.py =================================================================== --- trunk/grassaddons/gui/gis_set.py 2007-03-25 06:00:09 UTC (rev 288) +++ trunk/grassaddons/gui/gis_set.py 2007-03-25 06:04:49 UTC (rev 289) @@ -597,9 +597,9 @@ return None def OnWizard(self,event): - import grass_wizard - reload(grass_wizard) - gWizard = grass_wizard.GWizard(self, self.tgisdbase.GetValue()) + import location_wizard + reload(location_wizard) + gWizard = location_wizard.GWizard(self, self.tgisdbase.GetValue()) def UpdateLocations(self,dbase): Modified: trunk/grassaddons/gui/wxgrass =================================================================== --- trunk/grassaddons/gui/wxgrass 2007-03-25 06:00:09 UTC (rev 288) +++ trunk/grassaddons/gui/wxgrass 2007-03-25 06:04:49 UTC (rev 289) @@ -2,9 +2,9 @@ SYSTEM=`uname -s` if [ "$SYSTEM" = "Darwin" ] ; then - pythonw "$GISBASE/etc/wx/gism.py" -name gmism_py + pythonw "$GISBASE/etc/wx/wxgui.py" -name wxgui_py else - python "$GISBASE/etc/wx/gism.py" -name gmism_py + python "$GISBASE/etc/wx/wxgui.py" -name wxgui_py fi From barton at grass.itc.it Sun Mar 25 08:05:52 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:05:54 2007 Subject: [grass-addons] r290 - trunk/grassaddons/gui Message-ID: <200703250605.l2P65quH021462@grass.itc.it> Author: barton Date: 2007-03-25 08:05:44 +0200 (Sun, 25 Mar 2007) New Revision: 290 Added: trunk/grassaddons/gui/wxgui.py Log: Renamed gism.py to wxgui.py Added: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py (rev 0) +++ trunk/grassaddons/gui/wxgui.py 2007-03-25 06:05:44 UTC (rev 290) @@ -0,0 +1,565 @@ +#!/usr/bin/env python +""" +Classes: +* GRasterDialog +* GMFrame +* SetVal +* GMApp +""" +import sys +import os +import wx +import wx.combo +import wx.lib.customtreectrl as CT +import wx.lib.flatnotebook as FN +import wx.stc +import wx.richtext + +import sys, os, time, traceback, types + +import wx # This module uses the new wx namespace +import wx.html + +import images + +# try: +# import subprocess +#except: +# from compat import subprocess + +import gui_modules +gmpath = gui_modules.__path__[0] +sys.path.append(gmpath) + +import gui_modules.track as track +import gui_modules.wxgui_utils as wxgui_utils +import gui_modules.mapdisp as mapdisp +import gui_modules.render as render +import gui_modules.menudata as menudata +import gui_modules.menuform as menuform +import gui_modules.grassenv as grassevn + +"""Main Python app to set up GIS Manager window and trap commands +Only command console is working currently, but windows for +panels and layer tree done and demo tree items appear""" + +########################################################################## +# +# wxgui.py - wxPython prototype GUI for GRASS 6+ +# +# Authors: Michael Barton (Arizona State University) & +# Jachym Cepicky (Mendel University of Agriculture) +# +# August 2006 +# +# COPYRIGHT: (C) 1999 - 2006 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. +# +########################################################################## + +menucmd = {} + +class GRasterDialog(wx.Frame): + def __init__(self,parent,id=-1,title="Set raster layer"): + wx.Frame.__init__(self, parent, id , title, size=(50,600)) + + # sizers + sizer = wx.BoxSizer(wx.VERTICAL) + buttsizer = wx.BoxSizer(wx.HORIZONTAL) + + # 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") + + # checkboxes + cboverlay = wx.CheckBox(self, -1, "Overlay (non-null values)") + cboverlay.SetValue(True) + + # text entries + tmapname = wx.TextCtrl(self,-1,size=(-1,-1)) + tvalues = wx.TextCtrl(self,-1,size=(-1,-1)) + + # 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) + + 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() + + +class GMFrame(wx.Frame): + '''GIS Manager frame with notebook widget for controlling + 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, title): + self.parent = parent + wx.Frame.__init__(self, parent=parent, id=-1, title=title, style=wx.DEFAULT_FRAME_STYLE) + + # creating widgets + self.notebook = self.__createNoteBook() + self.cmdinput = self.__createCommandInput() + self.menubar = self.__createMenuBar() + toolbar = self.__createToolBar() + #self.panel = wx.Panel(self,-1, style= wx.EXPAND) + self.sizer= wx.BoxSizer(wx.VERTICAL) + self.cmdsizer = wx.BoxSizer(wx.HORIZONTAL) + + # do layout + self.SetTitle(_("GRASS GIS Manager - wxPython Prototype")) + self.SetMinSize((450, 450)) + # self.nb_panel = wx.Panel(self) + + # initialize variables + self.mapdisplays = {} #dictionary to index open map displays + self.disp_idx = 0 #index value for map displays and layer trees + self.maptree = {} #dictionary to index a layer tree to accompanying a map display + self.mapfocus = 0 #track which display currently has focus + + self.Bind(wx.EVT_CLOSE, self.onCloseWindow) + self.Bind(wx.EVT_LEFT_DOWN, self.addRaster) + + # item, proportion, flag, border, userData + self.sizer.Add(self.notebook, proportion=1, flag=wx.EXPAND, border=1) + self.sizer.Add(self.cmdinput, proportion=0, flag=wx.EXPAND, border=1) + self.SetSizer(self.sizer) + self.sizer.Fit(self) + self.Layout() + wx.CallAfter(self.notebook.SetSelection, 0) + + # start default initial display + self.newDisplay() + + def __createCommandInput(self): + """Creates command input area""" + #l = wx.StaticText(self, -1, "GRASS> ") + + self.cmdinput = wx.TextCtrl(self, id=wx.ID_ANY, value="", style=wx.HSCROLL|wx.TE_LINEWRAP| + wx.TE_PROCESS_ENTER) + + #self.cmdinput.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "Monospace")) + wx.CallAfter(self.cmdinput.SetInsertionPoint, 0) + + #self.cmdsizer.Add(l,0,wx.ADJUST_MINSIZE | wx.ALIGN_CENTER_VERTICAL, 1) + #self.cmdsizer.Add(self.cmdinput, 0, wx.EXPAND, 0) + + self.Bind(wx.EVT_TEXT_ENTER, self.runCmd, self.cmdinput) + + return self.cmdinput + + def __createMenuBar(self): + """Creates menubar""" + + self.menubar = wx.MenuBar() + menud = menudata.Data() + for eachMenuData in menud.GetMenu(): + for eachHeading in eachMenuData: + menuLabel = eachHeading[0] + menuItems = eachHeading[1] + self.menubar.Append(self.__createMenu(menuItems), menuLabel) + self.SetMenuBar(self.menubar) + + return self.menubar + + def __createMenu(self, menuData): + """Cretes menu""" + + menu = wx.Menu() + for eachItem in menuData: + if len(eachItem) == 2: + label = eachItem[0] + subMenu = self.__createMenu(eachItem[1]) + menu.AppendMenu(wx.NewId(), label, subMenu) + else: + self.__createMenuItem(menu, *eachItem) + return menu + + def __createMenuItem(self, menu, label, help, handler, gcmd, kind=wx.ITEM_NORMAL): + """Creates menu items""" + + if not label: + menu.AppendSeparator() + return + menuItem = menu.Append(-1, label, help, kind) + if label: + menucmd[label] = gcmd + rhandler = eval(handler) + self.Bind(wx.EVT_MENU, rhandler, menuItem) + + def __createNoteBook(self): + """Creates notebook widgets""" + + # create main notebook widget + #bookStyle=FN.FNB_DEFAULT_STYLE #| FN.FNB_FANCY_TABS + #bookStyle=FN.FNB_DEFAULT_STYLE|FN.FNB_BOTTOM|FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS + nbStyle=FN.FNB_FANCY_TABS|FN.FNB_BOTTOM|FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS + self.notebook = FN.FlatNotebook(self, id=wx.ID_ANY, style=nbStyle) + + # create displays notebook widget and add it to main notebook page + cbStyle=FN.FNB_VC8|FN.FNB_BACKGROUND_GRADIENT|FN.FNB_X_ON_TAB|FN.FNB_TABS_BORDER_SIMPLE + #self.cb_panel = wx.Panel(self,-1, style = wx.EXPAND) + self.gm_cb = FN.FlatNotebook(self, id=wx.ID_ANY, style=cbStyle) + self.gm_cb.SetTabAreaColour(wx.Colour(125,200,175)) + self.notebook.AddPage(self.gm_cb, text="Map layers for each display") + + # create command output text area and add it to main notebook page + #self.outpanel = wx.Panel(self,-1, style = wx.EXPAND) + self.goutput = wxgui_utils.GMConsole(self) + #self.goutput = wx.richtext.RichTextCtrl(self,style=wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER) + self.outpage = self.notebook.AddPage(self.goutput, text="Command output") + + self.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.onCBPageChanged, self.gm_cb) + self.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.onCBPageClosed, self.gm_cb) + + self.out_sizer = wx.BoxSizer(wx.VERTICAL) + self.out_sizer.Add(self.goutput, proportion=1, flag=wx.EXPAND, border=1) + self.SetSizer(self.out_sizer) + #self.out_sizer.Fit(self.outpage) + #self.outpage.Layout() + + self.Centre() + return self.notebook + + + # choicebook methods + def onCBPageChanged(self, event): + """Page in notebook changed""" + + old_pgnum = event.GetOldSelection() + new_pgnum = event.GetSelection() + curr_pg = self.gm_cb.GetCurrentPage() + sel_pgnum = self.gm_cb.GetSelection() + + # get ID of associated display if more than one + disp_idx = track.Track().GetDisp_idx(curr_pg) + if disp_idx != None: + #get associated display and make it active + newdisp = track.Track().GetCtrls(disp_idx, 0) + newdisp.SetFocus() + newdisp.Raise() + event.Skip() + + def onCBPageClosed(self, event): + """Page of notebook closed""" + + curr_pg = self.gm_cb.GetCurrentPage() + disp_idx = track.Track().GetDisp_idx(curr_pg) + if disp_idx != None: + #get associated display and make it active + disp = track.Track().GetCtrls(disp_idx, 0) + try: + if self.mapdisplays.has_key(disp_idx): + if self.mapdisplays[disp_idx].Close(False): + self.mapdisplays[disp_idx].Close(True) + except: + pass + + def runCmd(self,event): + """Run command""" + + #global gmpath + cmd = self.cmdinput.GetValue() + + self.goutput.runCmd(cmd) + #menuform.GUI().parseCommand(cmd, gmpath) + + def runMenuCmd(self, event): + """Run menu command""" + + menuitem = self.menubar.FindItemById(event.GetId()) + itemtext = menuitem.GetText() + cmd = menucmd[itemtext] + global gmpath + menuform.GUI().parseCommand(cmd,gmpath, parentframe=self) + + def __createToolBar(self): + """Creates toolbar""" + + toolbar = self.CreateToolBar() + for each in self.toolbarData(): + self.addToolbarButton(toolbar, *each) + toolbar.Realize() + + def addToolbarButton(self, toolbar, label, icon, help, handler): + """Adds button to the given toolbar""" + + if not label: + toolbar.AddSeparator() + return + tool = toolbar.AddLabelTool(id=wx.ID_ANY, label=label, bitmap=icon, shortHelp=help) + self.Bind(wx.EVT_TOOL, handler, tool) + + def toolbarData(self): + + return ( + ('newdisplay', wx.Bitmap(os.path.join(wxgui_utils.icons,'gui-startmon.gif'), wx.BITMAP_TYPE_ANY), 'Start new display', self.newDisplay), + ('', '', '', ''), + ('addrast', wx.Bitmap(os.path.join(wxgui_utils.icons,'element-cell.gif'), wx.BITMAP_TYPE_ANY), 'Add raster layer', self.onRaster), + ('addvect', wx.Bitmap(os.path.join(wxgui_utils.icons,'element-vector.gif'), wx.BITMAP_TYPE_ANY), 'Add vector layer', self.onVector), + ('addcmd', wx.Bitmap(os.path.join(wxgui_utils.icons,'gui-cmd.gif'), wx.BITMAP_TYPE_ANY), 'Add command layer', self.addCommand), + ('delcmd', wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_TOOLBAR, (16,16)), 'Delete selected layer', self.deleteLayer), + ) + + def addToolbarCombo(self, toolbar, indx, type): + tbcb = wx.combo.BitmapComboBox(toolbar, pos=(25,25), size=(100,-1), style=wx.TE_PROCESS_ENTER) + self.comboItems(tbcb, type) + toolbar.InsertControl(indx, tbcb) + toolbar.Realize() + + self.Bind(wx.EVT_COMBOBOX, self.onCombo, tbcb) + self.Bind(wx.EVT_TEXT_ENTER, self.onCombo, tbcb) + + def onCombo(self, event): + bcb = event.GetEventObject() + idx = event.GetInt() + st = bcb.GetString(idx) + cd = bcb.GetClientData(idx) + if 'Add raster map' in st: + self.addRaster() + elif 'Add RGB' in st: + self.addRGB() + elif 'Add raster legend' in st: + self.addRastLeg() + elif 'Add vector map' in st: + self.addVector() + elif 'Add thematic map' in st: + self.addThemeMap() + elif 'Add thematic chart' in st: + self.addThemeChart() + +# self.log.write("EVT_COMBOBOX: Id %d, string '%s', clientData '%s'" % (idx, st, cd)) + evt.Skip() + + + def newDisplay(self, event=None): + """Create new map display frame""" + + newdisp = self.mapdisplays[self.disp_idx] = mapdisp.MapFrame(self, + id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, + style=wx.DEFAULT_FRAME_STYLE, + cb=self.gm_cb, idx=self.disp_idx) + # title + newdisp.SetTitle(_("Map Display " + str(self.disp_idx))) + #self.maptree[self.disp_idx] = self.mapdisplays[self.disp_idx].getTree() + + #add notebook page to GIS Manager + + # make a new page in the bookcontrol for the layer tree (on page 0 of the notebook) + self.pg_panel = wx.Panel(self.gm_cb, id=wx.ID_ANY, style= wx.EXPAND) + self.gm_cb.AddPage(self.pg_panel, text="Display "+ str(self.disp_idx), select = True) + self.cb_page = self.gm_cb.GetCurrentPage() + + # create layer tree (tree control for managing GIS layers) and put on new notebook page + self.maptree = wxgui_utils.LayerTree(self.cb_page, id=wx.ID_ANY, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS + |wx.TR_LINES_AT_ROOT|wx.TR_EDIT_LABELS|wx.TR_HIDE_ROOT + |wx.TR_DEFAULT_STYLE|wx.NO_BORDER|wx.FULL_REPAINT_ON_RESIZE, + disp=newdisp) + + # layout for controls + cb_boxsizer = wx.BoxSizer(wx.VERTICAL) + cb_boxsizer.Add(self.maptree, proportion=1, flag=wx.EXPAND, border=1) + self.cb_page.SetSizer(cb_boxsizer) + cb_boxsizer.Fit(self.cb_page) + self.cb_page.Layout() + #self.cb_page.SetAutoLayout(True) + #self.Centre() + + # store information about display and associated controls in a dictionary in track.py + track.Track().SetDisp(self.disp_idx,self) + track.Track().SetCtrlDict(self.disp_idx, newdisp, self.cb_page, self.maptree) + + #show new display + self.mapdisplays[self.disp_idx].Show() + self.mapdisplays[self.disp_idx].Refresh() + self.mapdisplays[self.disp_idx].Update() + + self.disp_idx += 1 + + # toolBar button handlers + def onRaster(self, event): + """Add raster item menu""" + point = wx.GetMousePosition() + rastmenu = wx.Menu() + # Add items to the menu + addrast = wx.MenuItem(rastmenu, -1,'Add raster map layer') + bmp = wx.Image(os.path.join(wxgui_utils.icons,'element-cell.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addrast.SetBitmap(bmp) + rastmenu.AppendItem(addrast) + self.Bind(wx.EVT_MENU, self.addRaster, addrast) + + addrgb = wx.MenuItem(rastmenu, -1,'Add RGB layer') + bmp = wx.Image(os.path.join(wxgui_utils.icons,'module-d.rgb.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addrgb.SetBitmap(bmp) + rastmenu.AppendItem(addrgb) + self.Bind(wx.EVT_MENU, self.addRGB, addrgb) + + addhis = wx.MenuItem(rastmenu, -1,'Add HIS layer') + bmp = wx.Image(os.path.join(wxgui_utils.icons,'channel-his.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addhis.SetBitmap(bmp) + rastmenu.AppendItem(addhis) + self.Bind(wx.EVT_MENU, self.addHIS, addhis) + + addrleg = wx.MenuItem(rastmenu, -1,'Add raster legend layer') + bmp = wx.Image(os.path.join(wxgui_utils.icons,'module-d.legend.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addrleg.SetBitmap(bmp) + rastmenu.AppendItem(addrleg) + self.Bind(wx.EVT_MENU, self.addRastLeg, addrleg) + + # Popup the menu. If an item is selected then its handler + # will be called before PopupMenu returns. + self.PopupMenu(rastmenu) + rastmenu.Destroy() + + def onVector(self, event): + """Add raster item menu""" + point = wx.GetMousePosition() + vectmenu = wx.Menu() + + addvect = wx.MenuItem(vectmenu, -1,'Add vector map layer') + bmp = wx.Image(os.path.join(wxgui_utils.icons,'element-vector.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addvect.SetBitmap(bmp) + vectmenu.AppendItem(addvect) + self.Bind(wx.EVT_MENU, self.addVector, addvect) + + addtheme = wx.MenuItem(vectmenu, -1,'Add thematic map layer') + bmp = wx.Image(os.path.join(wxgui_utils.icons,'module-d.vect.thematic.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addtheme.SetBitmap(bmp) + vectmenu.AppendItem(addtheme) + self.Bind(wx.EVT_MENU, self.addThemeMap, addtheme) + + addchart = wx.MenuItem(vectmenu, -1,'Add thematic chart layer') + bmp = wx.Image(os.path.join(wxgui_utils.icons,'module-d.vect.chart.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addchart.SetBitmap(bmp) + vectmenu.AppendItem(addchart) + self.Bind(wx.EVT_MENU, self.addThemeChart, addchart) + # Popup the menu. If an item is selected then its handler + # will be called before PopupMenu returns. + self.PopupMenu(vectmenu) + vectmenu.Destroy() + + def addRaster(self, event): + self.SetTree('raster') + + def addRGB(self, event): + """Add RGB layer""" + self.SetTree('rgb') + + def addHIS(self, event): + """Add HIS layer""" + self.SetTree('his') + + def addRastLeg(self, event): + """Add raster legend""" + self.SetTree('rastleg') + + def addVector(self, event): + """Add vector layer""" + self.SetTree('vector') + + def addThemeMap(self, event): + """Add thematic map layer""" + self.SetTree('thememap') + + def addThemeChart(self, event): + """Add thematic chart layer""" + self.SetTree('themechart') + + def addCommand(self, event): + """Add command line layer""" + self.SetTree('command') + + def GetSelectedDisplay(self): + return self.notebook.GetSelection() + + def SetTree(self, layertype): + """ + Add map display layer in GIS Manager tree widget + """ + disp_idx = track.Track().GetDisp_idx(self.maptree) + if disp_idx != None: + self.maptree.AddLayer(disp_idx, layertype) + + def deleteLayer(self, event): + """ + Delete selected map display layer in GIS Manager tree widget + """ + self.maptree.Delete(self.maptree.GetSelection()) + + #Misc methods + def onCloseWindow(self, event): + '''Cleanup when wxgui.py is quit''' + mdlist = range(0, self.disp_idx+1) + try: + for md in mdlist: + if self.mapdisplays.has_key(md): + if self.mapdisplays[md].Close(False): + self.mapdisplays[md].Close(True) + except: + self.DestroyChildren() + self.Destroy() + + def Nomethod(self, event): + '''Stub for testing''' + pass + event.Skip() + +class GMApp(wx.App): + """ + GMApp class + """ + def OnInit(self): +## reexec_with_pythonw() + # initialize all available image handlers + wx.InitAllImageHandlers() + # create and show main frame + mainframe = GMFrame(None, -1, "") + self.SetTopWindow(mainframe) + mainframe.Show() + return 1 + +def reexec_with_pythonw(): + 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:]) + + +if __name__ == "__main__": + + reexec_with_pythonw() + + import gettext + gettext.install("GMApp") # replace with the appropriate catalog name + app = GMApp(0) + app.MainLoop() Property changes on: trunk/grassaddons/gui/wxgui.py ___________________________________________________________________ Name: svn:executable + * From barton at grass.itc.it Sun Mar 25 08:06:21 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:06:23 2007 Subject: [grass-addons] r291 - trunk/grassaddons/gui Message-ID: <200703250606.l2P66LpW021482@grass.itc.it> Author: barton Date: 2007-03-25 08:06:13 +0200 (Sun, 25 Mar 2007) New Revision: 291 Added: trunk/grassaddons/gui/location_wizard.py Log: Renamed grass_wizard.py to location_wizard.py Added: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py (rev 0) +++ trunk/grassaddons/gui/location_wizard.py 2007-03-25 06:06:13 UTC (rev 291) @@ -0,0 +1,1290 @@ +import wx +import wx.wizard as wiz +import wx.lib.rcsizer as rcs +from wx.lib.combotreebox import ComboTreeBox + +import os +import sys +import string +import re + + +class TitledPage(wiz.WizardPageSimple): + def __init__(self, parent, title): + wiz.WizardPageSimple.__init__(self, parent) + + self.title = wx.StaticText(self,-1,title) + self.title.SetFont(wx.Font(13, wx.SWISS, wx.NORMAL, wx.BOLD)) + + self.sizer = rcs.RowColSizer() + tmpsizer = wx.BoxSizer(wx.VERTICAL) + + tmpsizer.Add(self.title, 0, wx.ALIGN_CENTRE|wx.ALL, 5) + tmpsizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0) + tmpsizer.Add(self.sizer, wx.EXPAND) + + self.SetSizer(tmpsizer) + self.SetAutoLayout(True) + + def MakeLabel(self, text=""): + try: + if text[-1] != " ": + text += " " + except: + pass + return wx.StaticText(self, -1, text, style=wx.ALIGN_RIGHT) + + def MakeTextCtrl(self,text='', size=(100,-1)): + return wx.TextCtrl(self,-1, text, size=size) + + def MakeButton(self,text, size=(75,25)): + return wx.Button(self, -1, text, + style=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, + size=size) + + +class DatumPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Specify geodetic datum") + + self.parent = parent + + # text input + self.tdatum = self.MakeTextCtrl("", size=(200,-1)) + self.ttrans = self.MakeTextCtrl("", size=(200,-1)) + + # search box + self.searchb = wx.SearchCtrl(self, size=(200,-1), + style=wx.TE_PROCESS_ENTER) + + # button + self.bupdate = self.MakeButton("Update trans. parms.", + size=(-1,-1)) + + # table + self.tablewidth=675 + + # create list control for datum/elipsoid list + self.datumlist = wx.ListCtrl(self, id=wx.ID_ANY, + size=(675,150), + style=wx.LC_REPORT | + wx.LC_VRULES | + wx.LC_HRULES | + wx.EXPAND) + self.datumlist.InsertColumn(0, 'Short Name') + self.datumlist.InsertColumn(1, 'Full EPSG-style name') + self.datumlist.InsertColumn(2, 'Ellipsoid') + self.datumlist.InsertColumn(3, 'Parameters') + self.datumlist.SetColumnWidth(0, 100) + self.datumlist.SetColumnWidth(1, 225) + self.datumlist.SetColumnWidth(2, 100) + self.datumlist.SetColumnWidth(3, 250) + + # create list control for datum transformation parameters list + self.transformlist = wx.ListCtrl(self, id=wx.ID_ANY, + size=(675,125), + style=wx.LC_REPORT | + wx.LC_VRULES | + wx.LC_HRULES | + wx.EXPAND) + self.transformlist.InsertColumn(0, 'ID') + self.transformlist.InsertColumn(1, 'Country') + self.transformlist.InsertColumn(2, 'Description ') + self.transformlist.InsertColumn(3, 'Parameters') + self.transformlist.SetColumnWidth(0, 50) + self.transformlist.SetColumnWidth(1, 125) + self.transformlist.SetColumnWidth(2, 250) + self.transformlist.SetColumnWidth(3, 250) + + # layout + self.sizer.Add(self.MakeLabel("Geodetic datum:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=1) + self.sizer.Add(self.tdatum, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.bupdate, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=3) + self.sizer.Add(self.MakeLabel("Search in description:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=2) + self.sizer.Add(self.searchb, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=2) + + self.sizer.Add(self.datumlist, 0 , + wx.EXPAND | + wx.ALIGN_LEFT | + wx.ALL, 5, row=3, col=1, colspan=5) + + self.sizer.Add(self.MakeLabel("Transformation parameters:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=5) + self.sizer.Add(self.ttrans, 0 , + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=5, col=2) + + self.sizer.Add(self.transformlist, 0 , + wx.EXPAND | + wx.ALIGN_LEFT | + wx.ALL, 5, row=6, col=1, colspan=5) + + # events + #wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) + #wx.EVT_BUTTON(self, self.bbcodes.GetId(), self.OnBrowseCodes) + self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.datumlist) + self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTransformSelected, self.transformlist) + self.bupdate.Bind(wx.EVT_BUTTON, self._onBrowseParams) + self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) + self.tdatum.Bind(wx.EVT_TEXT_ENTER, self._onBrowseParams, self.tdatum) + + self._onBrowseDatums(None,None) + self.datumlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) + self.datumlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) + self.datumlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) + + def OnDoSearch(self,event): + str = self.searchb.GetValue() + listItem = self.datumlist.GetColumn(1) + + for i in range(self.datumlist.GetItemCount()): + listItem = self.datumlist.GetItem(i,1) + if listItem.GetText().find(str) > -1: + datumcode = self.datumlist.GetItem(i, 0) + self.tdatum.SetValue(datumcode.GetText()) + break + + self._onBrowseDatums(None,str) + + def OnTransformSelected(self,event): + item = event.GetItem() + self.ttrans.SetValue(str(item.GetText())) + + def OnItemSelected(self,event): + item = event.GetItem() + self.tdatum.SetValue(str(item.GetText())) + self._onBrowseParams() + + def _onBrowseParams(self, event=None): + params = [["","Use whole region",""]] + file = os.path.join(os.getenv("GISBASE"), "etc","datumtransform.table") + search = self.tdatum.GetValue() + + try: + f = open(file,"r") + rex=re.compile('^(.+)\s+"(.+)"\s+"(.+)"\s+"(.+)"') + for line in f.readlines(): + line = line.strip() + if line[0] == "#": continue + id,parm,country,descr = rex.findall(line)[0] + id=id.strip() + parm=parm.strip() + country = country.strip() + descr=descr.strip() + if id == search: + params.append([parm,country,descr]) + f.close() + + self.transformlist.DeleteAllItems() + for i in range(len(params)): + # fill datum transformation parameters list control + index = self.transformlist.InsertStringItem(i,str(i+1)) + dtp1 = self.transformlist.SetStringItem(index,1,params[i][1]) + dtp2 = self.transformlist.SetStringItem(index,2,params[i][2]) + dtp3 = self.transformlist.SetStringItem(index,3,params[i][0]) + # format list control columns + if index != '': + self.transformlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) + else: + self.transformlist.SetColumnWidth(0, 30) + if dtp1 != '': + self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) + else: + self.transformlist.SetColumnWidth(1, 150) + if dtp2 != '': + self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) + else: + self.transformlist.SetColumnWidth(2, 250) + if dtp3 != '': + self.transformlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) + else: + self.transformlist.SetColumnWidth(3, 320) + + except IOError, e: + self.transformlist.DeleteAllItems() + dlg = wx.MessageDialog(self, "Could not read datum params: %s " + % e,"Can not read file", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + + def _onBrowseDatums(self,event,search=None): + try: + self.datumlist.DeleteAllItems() + f = open(os.path.join(os.getenv("GISBASE"), "etc","datum.table"),"r") + # shortname "Full EPSG-style name" ellipsoid dx= dy= dz= + rex=re.compile('^(.+)\s+"(.+)"\s+(.+)\s+(dx=.+)') + j=0 + for line in f.readlines(): + line = line.strip() + if not line: continue + if line[0] == "#": continue + shortname, epsgname, ellps, params = rex.findall(line)[0] + params = params.strip() + ellps = ellps.strip() + if search and (shortname.lower().find(search.lower()) > -1 or\ + ellps.lower().find(search.lower()) > -1 or\ + epsgname.lower().find(search.lower()) > -1) or\ + not search: + index = self.datumlist.InsertStringItem(j,shortname) + self.datumlist.SetStringItem(index,1,epsgname) + self.datumlist.SetStringItem(index,2,ellps) + self.datumlist.SetStringItem(index,3,params) + j += 1 + f.close() + self.datumlist.SendSizeEvent() + except IOError, e: + dlg = wx.MessageDialog(self, "Could not read datums: %s " + % e,"Can not read file", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + def OnChange(self,event): + self.item = event.GetItem() + +class SummaryPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Summary") + + self.parent = parent + + self.sizer.Add(self.MakeLabel("GRASS database:"), 1, flag=wx.ALIGN_RIGHT, row=1, col=2) + self.sizer.Add(self.MakeLabel("Location name:"), 1, flag=wx.ALIGN_RIGHT, row=2, col=2) + self.sizer.Add((200,20), 1, flag=wx.ALIGN_CENTER_HORIZONTAL, row=4, col=2) + self.sizer.Add(self.MakeLabel("Projection:"), 1, flag=wx.ALIGN_RIGHT, row=5, col=2) + self.sizer.Add(self.MakeLabel("North:"), 1, flag=wx.ALIGN_RIGHT, row=6, col=2) + self.sizer.Add(self.MakeLabel("South:"), 1, flag=wx.ALIGN_RIGHT, row=7, col=2) + self.sizer.Add(self.MakeLabel("East:"), 1, flag=wx.ALIGN_RIGHT, row=8, col=2) + self.sizer.Add(self.MakeLabel("West:"), 1, flag=wx.ALIGN_RIGHT, row=9, col=2) + self.sizer.Add(self.MakeLabel("Resolution:"), 1, flag=wx.ALIGN_RIGHT, row=10, col=2) + self.sizer.Add(self.MakeLabel("Rows:"), 1, flag=wx.ALIGN_RIGHT, row=12, col=2) + self.sizer.Add(self.MakeLabel("Columns:"), 1, flag=wx.ALIGN_RIGHT, row=13, col=2) + self.sizer.Add(self.MakeLabel("Cells:"), 1, flag=wx.ALIGN_RIGHT, row=14, col=2) + + # labels + self.ldatabase = self.MakeLabel("") + self.llocation = self.MakeLabel("") + self.lprojection = self.MakeLabel("") + self.lnorth = self.MakeLabel("") + self.lsouth = self.MakeLabel("") + self.least = self.MakeLabel("") + self.lwest = self.MakeLabel("") + self.lres = self.MakeLabel("") + self.lrows = self.MakeLabel("") + self.lcols = self.MakeLabel("") + self.lcells = self.MakeLabel("") + + self.sizer.Add(self.ldatabase, 1, flag=wx.ALIGN_LEFT, row=1, col=3) + self.sizer.Add(self.llocation, 1, flag=wx.ALIGN_LEFT, row=4, col=3) + self.sizer.Add(self.lprojection, 1, flag=wx.ALIGN_LEFT, row=5, col=3) + self.sizer.Add(self.lnorth, 1, flag=wx.ALIGN_LEFT, row=6, col=3) + self.sizer.Add(self.lsouth, 1, flag=wx.ALIGN_LEFT, row=7, col=3) + self.sizer.Add(self.least, 1, flag=wx.ALIGN_LEFT, row=8, col=3) + self.sizer.Add(self.lwest, 1, flag=wx.ALIGN_LEFT, row=9, col=3) + self.sizer.Add(self.lres, 1, flag=wx.ALIGN_LEFT, row=10, col=3) + self.sizer.Add(self.lrows, 1, flag=wx.ALIGN_LEFT, row=12, col=3) + self.sizer.Add(self.lcols, 1, flag=wx.ALIGN_LEFT, row=13, col=3) + self.sizer.Add(self.lcells, 1, flag=wx.ALIGN_LEFT, row=14, col=3) + + def FillVars(self,event=None): + database = self.parent.startpage.tgisdbase.GetValue() + location = self.parent.startpage.tlocation.GetValue() + projection = self.parent.csystemspage.cs + #zoone = self.pages + north = self.parent.bboxpage.ttop.GetValue() + south = self.parent.bboxpage.tbottom.GetValue() + east = self.parent.bboxpage.tright.GetValue() + west = self.parent.bboxpage.tleft.GetValue() + res = self.parent.bboxpage.tres.GetValue() + #if projection != "latlong": + rows = int(round((float(north)-float(south))/float(res))) + cols = int(round((float(east)-float(west))/float(res))) + cells = int(rows*cols) + + self.ldatabase.SetLabel(database) + self.llocation.SetLabel(location) + self.lprojection.SetLabel(projection) + self.lnorth.SetLabel(north) + self.lsouth.SetLabel(south) + self.least.SetLabel(east) + self.lwest.SetLabel(west) + self.lres.SetLabel(res) + self.lrows.SetLabel(str(rows)) + self.lcols.SetLabel(str(cols)) + self.lcells.SetLabel(str(cells)) + + + +#projection: 99 (Other Projection) +#zone: 0 +# north: 344444 +# south: 3333 +# east: 3333333 +# west: 33333 +# +# e-w res: 30 +# n-s res: 30.00096746 (Changed to conform to grid) +# +#total rows: 11370 +#total cols: 110000 +#total cells: 1,250,700,000 +# +# +#Do you accept this region? (y/n) [n] > + + + # inputs + +class BBoxPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Set default region extents and resolution") + + self.parent = parent + # inputs + self.ttop = self.MakeTextCtrl("1", size=(150, -1)) + self.tbottom = self.MakeTextCtrl("0", size=(150, -1)) + self.tleft = self.MakeTextCtrl("0", size=(150, -1)) + self.tright = self.MakeTextCtrl("1", size=(150, -1)) + self.tres = self.MakeTextCtrl("1", size=(150, -1)) + + self.tgdal = self.MakeTextCtrl("", size=(250, -1)) + self.tdsn = self.MakeTextCtrl("", size=(250, -1)) + # list of layers + self.layers = [] + self.llayers = wx.ComboBox(self, -1, + choices=self.layers, + size=(250,-1), + style=wx.CB_DROPDOWN) + + # labels + self.lmessage = wx.StaticText(self,-1, "", size=(300,50)) + + # buttons + self.bbrowsegdal = self.MakeButton("Browse ...", size=(150,-1)) + self.bbrowseogr = self.MakeButton("Browse ...", size=(150,-1)) + self.bgetlayers = self.MakeButton("Get Layers", size=(150,-1)) + self.bset = self.MakeButton("Set coordinates", size=(150,-1)) + + # list of states + self.states = [] + self.coords = [] + try: + f = open(os.path.join(os.getenv("GISBASE"),"etc","wx","states.txt"),"r") + for line in f.readlines(): + if line[0] == "#": + continue + state,coord = line.split(";") + coord = coord.replace(","," ") + self.states.append(state) + self.coords.append(coord.split()) + f.close() + except: + pass + # NOTE: ComboCtcl should come here, but nobody knows, how to + # implement it + # self.stateslist = wx.ListCtrl(self, + # style=wx.LC_LIST|wx.LC_SINGLE_SEL|wx.SIMPLE_BORDER) + # self.cstate = wx.combo.ComboCtrl(self, -1, pos=(50, 170), size=(150, -1), + # style=wx.CB_READONLY) + + self.cstate = wx.ComboBox(self, -1, + size=(250,-1), + choices=self.states, + style=wx.CB_DROPDOWN) + + # layout + self.sizer.Add(self.MakeLabel("North"), 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 0, row=1,col=2) + self.sizer.Add(self.ttop, 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2,col=2) + + self.sizer.Add(self.MakeLabel("West"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 0, row=3,col=0) + self.sizer.Add(self.tleft, 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3,col=1) + + self.sizer.Add(self.tright, 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3,col=3) + self.sizer.Add(self.MakeLabel("East"), 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 0, row=3,col=4) + + self.sizer.Add(self.tbottom, 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=4,col=2) + self.sizer.Add(self.MakeLabel("South"), 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 0, row=5,col=2) + + self.sizer.Add(self.MakeLabel("Initial resolution"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=6,col=1) + self.sizer.Add(self.tres, 0, + wx.ALIGN_CENTER_HORIZONTAL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=6,col=2) + self.sizer.Add(self.bset, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=6, col=3 ) + + self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0, row=7, col=0, colspan=6) + + self.sizer.Add(self.MakeLabel("Match extents of georeferenced raster map or image"), 3, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=8,col=0, colspan=3) + + self.sizer.Add(self.MakeLabel("File:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=9,col=0, colspan=1) + self.sizer.Add(self.tgdal, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=9,col=1, colspan=2) + self.sizer.Add(self.bbrowsegdal, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=9,col=3) + + self.sizer.Add(wx.StaticLine(self, -1), 0, + wx.EXPAND|wx.ALL, 0, + row=10, col=0, colspan=6) + + self.sizer.Add(self.MakeLabel("Match extents of georeferenced vector map"), 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=11,col=0, colspan=3 ) + + self.sizer.Add(self.MakeLabel("Data source/directory:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=12,col=0, colspan=1) + self.sizer.Add(self.tdsn, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=12, col=1, colspan=2) + self.sizer.Add(self.bbrowseogr, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=12, col=3) + + self.sizer.Add(self.MakeLabel("Layer/file:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=13,col=0, colspan=1) + self.sizer.Add(self.llayers, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=13,col=1, colspan=2) + self.sizer.Add(self.bgetlayers, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=13,col=3) + + self.sizer.Add(wx.StaticLine(self, -1), 0, + wx.EXPAND|wx.ALL | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=14, col=0, colspan=6) + self.sizer.Add(self.MakeLabel("Match extents of selected country"), 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=15,col=0, colspan=3) + self.sizer.Add(self.cstate, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=16,col=1, colspan=2) + + self.sizer.Add(self.lmessage, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=17,col=1, colspan=3) + + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChange) + self.Bind(wx.EVT_COMBOBOX, self.OnItemSelected, self.cstate) + self.Bind(wx.EVT_TEXT, self.OnStateText, self.cstate) + self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset) + self.Bind(wx.EVT_BUTTON, self.OnBrowseGdal, self.bbrowsegdal) + self.Bind(wx.EVT_BUTTON, self.OnBrowseOGR, self.bbrowseogr) + self.Bind(wx.EVT_BUTTON, self.OnGetOGRLayers, self.bgetlayers) + + def OnBrowseGdal(self, event): + dlg = wx.FileDialog(self, "Choose a raster file:", os.getcwd(), "", "*.*", wx.OPEN) + path = "" + if dlg.ShowModal() == wx.ID_OK: + path = dlg.GetPath() + self.tgdal.SetValue(path) + dlg.Destroy() + + self.OnSetButton() + + def OnBrowseOGR(self, event): + dlg = wx.FileDialog(self, "Choose a data source name:", os.getcwd(), "", "*.*", wx.OPEN) + path = "" + if dlg.ShowModal() == wx.ID_OK: + path = dlg.GetPath() + self.tdsn.SetValue(path) + dlg.Destroy() + self.OnGetOGRLayers(None) + + def OnSetButton(self,event=None): + if self.tgdal.GetValue(): + self.__setGDAL() + if self.tdsn.GetValue() and self.llayers.GetSelection()>-1: + self.__setOGR() + elif self.cstate.GetSelection() > -1: + sys.stderr.write("##############"+str(self.cstate.GetSelection())+"\n") + self.OnItemSelected(None) + + def OnGetOGRLayers(self, event): + path = self.tdsn.GetValue() + line = "" + + sys.stderr.write(path+"####\n") + self.layers = [] + self.llayers.Clear() + cmd = os.popen("ogrinfo -so %s\n" % (path)) + line = cmd.readline() + # 1: cr (Polygon) + rex = re.compile("^(\d+):\s+(.+)\s+\(.*\)") + while 1: + if not line or line == "": + break + try: + sys.stderr.write("#####"+line+"####\n") + number, name = rex.findall(line)[0] + self.layers.append(name) + except: + pass + line = cmd.readline() + self.llayers.AppendItems(self.layers) + #sys.stderr.write(str( self.layers)+"\n") + #self.sizer.Remove(self.llayers) + #self.llayers = wx.ComboBox(self, -1, choices=self.layers, size=(100,-1), + # style=wx.CB_DROPDOWN) + #self.sizer.Add(self.llayers, 0, wx.ALIGN_CENTER_VERTICAL, row=12,col=3) + #self.sizer.ShowItems(True) + self.OnSetButton() + pass + + def __setOGR(self): + layer = self.layers[self.llayers.GetSelection()] + path = self.tdsn.GetValue() + number="-?\d+\.\d+" + line = "" + + #test values + self.ttop.SetValue(500) + self.tleft.SetValue(500) + + #Extent: (-146.976217, -55.985484) - (72.774632, 80.594358) + rex = re.compile("\((%s),\s*(%s)\)\s*-\s*\((%s),\s*(%s)\)" %(number, number, number, number)) + cmd = os.popen("ogrinfo -so %s %s" % (path ,layer)) + line = cmd.readline() + while 1: + if not line or line == "": + break + sys.stderr.write(line+"\n") + if line.find("Extent")>-1: + sys.stderr.write(line[0]+"#####\n") + x1,y1,x2,y2 = rex.findall(line)[0] + self.tbottom.SetValue(y1) + self.tleft.SetValue(x1) + self.ttop.SetValue(y2) + self.tright.SetValue(x2) + break + line = cmd.readline() + return + + def __setGDAL(self): + path = self.tgdal.GetValue() + line = "" + number="-?\d+\.\d+" + + #test values + self.ttop.SetValue(500) + self.tleft.SetValue(500) + + # Upper Left ( 0.0, 0.0) + rex=re.compile("\(\s*(%s)\s*,\s*(%s)\)" % (number, number)) + obj = os.popen("gdalinfo %s | grep \"Upper\|Lower\"" % path) + + line = obj.readline() + while 1: + sys.stderr.write(line+"\n") + if not line: + break + if line.find("Upper Left")>-1: + x,y = rex.findall(line)[0] + self.ttop.SetValue(y) + self.tleft.SetValue(x) + if line.find("Lower Right")>-1: + x,y = rex.findall(line)[0] + self.tbottom.SetValue(y) + self.tright.SetValue(x) + line = obj.readline() + return + + def OnStateText(self,event): + item = self.llayers.FindString(event.GetString()) + self.llayers.SetSelection(item) + self.llayers.SetValue(self.llayers.GetStringSelection()) + pass + #.log.WriteText('EvtTextEnter: %s' % event.GetString()) + #sys.stderr.write(event.GetString()+"\n") + #text=event.GetString().lower() + #for idx in range(len(self.states)): + # if self.states[idx].lower() == text: + # self.cstate.Select(idx) + # break + + def OnWizPageChange(self, event): + self.GetNext().FillVars() + + def OnItemSelected(self, event): + item = self.cstate.GetSelection() + w,s,e,n = self.coords[item] + # 4 + # 1 3 + # 2 + + if self.parent.csystemspage.cs == "latlong": + pass + if self.parent.csystemspage.cs == "xy": + pass + else: + if self.parent.csystemspage.cs == "epsg": + to="+init=epsg:%d" % (int(self.parent.epsgpage.tcode.GetValue())) + elif self.parent.csystemspage.cs == "custom": + to="+proj=%s" % (self.parent.projpage.tproj.GetValue()) + elif self.parent.csystemspage.cs == "utm": + to="+proj=utm" + else: + sys.stderr.write(self.parent.csystemspage.cs+"\n") + + try: + sin, sout = os.popen2("cs2cs +proj=latlong +datum=WGS84 +to %s" % (to)) + sin.write("%s %s\n" % (w,s)) + sin.write("%s %s\n" % (e,n)) + sin.close() + w,s,t = sout.readline().split() + e,n,t = sout.readline().split() + self.lmessage.SetLabel("") + except: + n = s = w = e="NULL" + self.lmessage.SetLabel("Unable to calculate country extends:\n cs2cs +proj=latlong +datum=WGS84 +to %s"% to) + + self.ttop.SetValue( str(n) ) + self.tbottom.SetValue( str(s) ) + self.tright.SetValue( str(e) ) + self.tleft.SetValue( str(w) ) + +class ProjectionsPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Choose projection name") + + self.parent = parent + # text input + self.tproj = self.MakeTextCtrl("", size=(200,-1)) + + # search box + self.searchb = wx.SearchCtrl(self, size=(200,-1), + style=wx.TE_PROCESS_ENTER) + + # table + self.tablewidth=675 + self.list = wx.ListCtrl(self, id=wx.ID_ANY, + size=(675,275), + style=wx.LC_REPORT | + wx.LC_VRULES | + wx.LC_HRULES | + wx.EXPAND) + self.list.InsertColumn(0, 'Name') + self.list.InsertColumn(1, 'Description') + self.list.SetColumnWidth(0, 100) + self.list.SetColumnWidth(1, 575) + + # layout + self.sizer.Add(self.MakeLabel("Projection name:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.tproj, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=3) + + self.sizer.Add(self.MakeLabel("Search in projection description"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=2) + self.sizer.Add(self.searchb, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=3) + + self.sizer.Add(self.list, + wx.EXPAND | + wx.ALIGN_LEFT | + wx.ALL, 5, row=3, col=1, colspan=4) + + # events + self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) + self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) + + self._onBrowseDatums(None, None) + + self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE) + self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE) + + def OnDoSearch(self,event): + str = self.searchb.GetValue() + listItem = self.list.GetColumn(1) + + for i in range(self.list.GetItemCount()): + listItem = self.list.GetItem(i,1) + if listItem.GetText().find(str) > -1: + datumcode = self.list.GetItem(i, 0) + self.tproj.SetValue(datumcode.GetText()) + break + + self._onBrowseDatums(None,str) + + + def OnItemSelected(self,event): + item = event.GetItem() + self.tproj.SetValue(str(item.GetText())) + + + def _onBrowseDatums(self,event,search=None): + try: + self.list.DeleteAllItems() + f = open(os.path.join(os.getenv("GISBASE"), "etc","projections"),"r") + i=1 + j = 0 + descr = None + proj = None + for line in f.readlines(): + line = line.strip() + if not line: + continue + if line[0] == "#": + continue + proj,descr = string.split(line, ":", maxsplit=1) + if search and (descr.lower().find(search.lower()) > -1 or\ + proj.lower().find(search.lower()) > -1) or\ + not search: + self.list.InsertStringItem(j,proj) + self.list.SetStringItem(j,1,descr) + j += 1 + # reset + descr = None; proj = "" + f.close() + self.SendSizeEvent() + except StandardError, e: + dlg = wx.MessageDialog(self, "Could not read datums: %s " + % e,"Can not read file", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + def OnChange(self,event): + self.item = event.GetItem() + + + +class GeoreferencedFilePage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Select georeferenced file") + + # create controls + self.lfile= wx.StaticText(self, -1, "Georeferenced file: ", + style=wx.ALIGN_RIGHT) + self.tfile = wx.TextCtrl(self,-1, "", size=(150,-1)) + self.bbrowse = self.MakeButton("Browse ...") + + # do layout + self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTRE_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTRE_VERTICAL | + wx.ALL, 5, row=1, col=3) + self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | + wx.ALL, 5, row=1, col=4) + + wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) + + def OnBrowse(self, event): + + dlg = wx.FileDialog(self, "Choose a georeferenced file:", os.getcwd(), "", "*.*", wx.OPEN) + if dlg.ShowModal() == wx.ID_OK: + path = dlg.GetPath() + self.tfile.SetValue(path) + dlg.Destroy() + + def OnCreate(self, event): + pass + # if not os.path.isfile(self.tfile.GetValue()): + # dlg = wx.MessageDialog(self, "Could not create new location: %s not file" + # % self.tfile.GetValue(),"Can not create location", wx.OK|wx.ICON_INFORMATION) + # dlg.ShowModal() + # dlg.Destroy() + # return + + # if not self.tname.GetValue(): + # dlg = wx.MessageDialog(self, "Could not create new location: name not set", + # "Can not create location", wx.OK|wx.ICON_INFORMATION) + # dlg.ShowModal() + # dlg.Destroy() + # return + + # if os.path.isdir(os.path.join(self.parent.gisdbase,self.tname.GetValue())): + # dlg = wx.MessageDialog(self, "Could not create new location: %s exists" + # % os.path.join(self.parent.gisdbase,self.tname.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) + # dlg.ShowModal() + # dlg.Destroy() + # return + + # # creating location + # # all credit to Michael Barton and his file_option.tcl and + # # Markus Neteler + # try: + # # FIXME: this does not need to work on windows + # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) + + # self.parent.OnSetDatabase(None) + # self.Destroy() + + # except StandardError, e: + # dlg = wx.MessageDialog(self, "Could not create new location: %s " + # % str(e),"Can not create location", wx.OK|wx.ICON_INFORMATION) + # dlg.ShowModal() + # dlg.Destroy() + +class EPSGPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Choose EPSG Code") + + # labels + self.lfile= wx.StaticText(self, -1, "Path to the EPSG-codes file: ", + style=wx.ALIGN_RIGHT) + self.lcode= wx.StaticText(self, -1, "EPSG code: ", + style=wx.ALIGN_RIGHT) + self.lsearch= wx.StaticText(self, -1, "Search in code description: ", + style=wx.ALIGN_RIGHT) + + # text input + epsgdir = os.path.join(os.environ["GRASS_PROJSHARE"], 'epsg') + self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,-1)) + self.tcode = wx.TextCtrl(self,-1, "", size=(200,-1)) + + # buttons + self.bbrowse = wx.Button(self, -1, "Browse ...", size=(100,-1)) + self.bbcodes = wx.Button(self, -1, "Browse Codes") + + # search box + self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) + + # table + self.tablewidth=675 + self.epsgs = wx.ListCtrl(self, id=wx.ID_ANY, + size=(675,275), + style=wx.LC_REPORT| + wx.LC_HRULES| + wx.EXPAND) + self.epsgs.InsertColumn(0, 'EPSG', wx.LIST_FORMAT_CENTRE) + self.epsgs.InsertColumn(1, 'Description', wx.LIST_FORMAT_LEFT) + self.epsgs.InsertColumn(2, 'Parameters', wx.LIST_FORMAT_LEFT) + self.epsgs.SetColumnWidth(0, 50) + self.epsgs.SetColumnWidth(1, 300) + self.epsgs.SetColumnWidth(2, 325) + + # layout + self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=1) + self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=2) + self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=1, col=3) + + self.sizer.Add(self.lcode, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=2) + self.sizer.Add(self.tcode, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=2, col=2) + + self.sizer.Add(self.lsearch, 0, wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, col=1, row=3) + self.sizer.Add(self.searchb, 0, wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3, col=2) + self.sizer.Add(self.bbcodes, 0 , wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, row=3, col=3) + + self.sizer.Add(self.epsgs, wx.ALIGN_LEFT|wx.EXPAND, 0, row=4, col=1, colspan=5) + + # events + wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) + wx.EVT_BUTTON(self, self.bbcodes.GetId(), self.OnBrowseCodes) + self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.epsgs) + self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) + + def OnDoSearch(self,event): + str = self.searchb.GetValue() + listItem = self.epsgs.GetColumn(1) + + for i in range(self.epsgs.GetItemCount()): + listItem = self.epsgs.GetItem(i,1) + if listItem.GetText().find(str) > -1: + epsgcode = self.epsgs.GetItem(i, 0) + self.tcode.SetValue(epsgcode.GetText()) + break + + self.OnBrowseCodes(None,str) + + + def OnBrowse(self, event): + + dlg = wx.FileDialog(self, "Choose a georeferenced file:", + "/", "", "*.*", wx.OPEN) + if dlg.ShowModal() == wx.ID_OK: + path = dlg.GetPath() + self.tfile.SetValue(path) + dlg.Destroy() + + def OnItemSelected(self,event): + item = event.GetItem() + self.tcode.SetValue(str(item.GetText())) + + + def OnBrowseCodes(self,event,search=None): + try: + self.epsgs.DeleteAllItems() + f = open(self.tfile.GetValue(),"r") + i=1 + j = 0 + descr = None + code = None + params = "" + #self.epsgs.ClearAll() + for line in f.readlines(): + line = line.strip() + if line.find("#") == 0: + descr = line[1:].strip() + elif line.find("<") == 0: + code = line.split(" ")[0] + for par in line.split(" ")[1:]: + params += par + " " + code = code[1:-1] + if code == None: code = 'no code' + if descr == None: descr = 'no description' + if params == None: params = 'no parameters' + if i%2 == 0: + if search and descr.lower().find(search.lower()) > -1 or\ + not search: + index = self.epsgs.InsertStringItem(j, code) + self.epsgs.SetStringItem(index, 1, descr) + self.epsgs.SetStringItem(index, 2, params) + j += 1 + # reset + descr = None; code = None; params = "" +# if i%2 == 0: +# self.epsgs.SetItemBackgroundColour(i, "grey") + i += 1 + f.close() + self.epsgs.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.epsgs.SetColumnWidth(2, wx.LIST_AUTOSIZE) + self.SendSizeEvent() + except StandardError, e: + dlg = wx.MessageDialog(self, "Could not read EPGS codes: %s " + % e,"Can not read file", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + def OnChange(self,event): + self.item = event.GetItem() + + #def OnCreate(self, event): + # if not self.tcode.GetValue(): + # dlg = wx.MessageDialog(self, "Could not create new location: EPSG Code value missing", + # "Can not create location", wx.OK|wx.ICON_INFORMATION) + # dlg.ShowModal() + # dlg.Destroy() + # return + # + # number = -1 + # try: + # number = int(self.tcode.GetValue()) + # except: + # dlg = wx.MessageDialog(self, "Could not create new location: '%s' not a number" % self.tcode.GetValue(), + # "Can not create location", wx.OK|wx.ICON_INFORMATION) + # dlg.ShowModal() + # dlg.Destroy() + # return + # + # if os.path.isdir(os.path.join(self.parent.gisdbase,self.tname.GetValue())): + # dlg = wx.MessageDialog(self, "Could not create new location: %s exists" + # % os.path.join(self.parent.gisdbase,self.tname.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) + # dlg.ShowModal() + # dlg.Destroy() + # return + # + # # creating location + # # all credit to Michael Barton and his file_option.tcl and + # # Markus Neteler + # try: + # # FIXME: this does not need to work on windows + # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) + # datumtrans = os.popen(" g.proj epsg=%d datumtrans=-1 >&2" % (number)).readlines() + + # if datumtrans: + # #os.system(" g.proj epsg=%d datumtrans=%s >&2" % (number,datumtrans[0]).readlines() + # pass + # else: + # os.system("g.proj -c epsg=%d location=%s datumtrans=1" % (number, self.tname.GetValue())) + + # self.parent.OnSetDatabase(None) + # self.Destroy() + + # except StandardError, e: + # dlg = wx.MessageDialog(self, "Could not create new location: %s " + # % str(e),"Can not create location", wx.OK|wx.ICON_INFORMATION) + # dlg.ShowModal() + # dlg.Destroy() + # return + + + def OnDoubleClick(self, event): + print self.epsgs.GetValue() + pass + + +class CoordinateSystemPage(TitledPage): + def __init__(self, wizard, parent): + TitledPage.__init__(self, wizard, "Choose coordinate system for location") + + self.parent = parent + self.cs = "xy" + + # toggles + self.radio1 = wx.RadioButton( self, -1, " XY ", style = wx.RB_GROUP ) + self.radio2 = wx.RadioButton( self, -1, " Lat/Long " ) + self.radio3 = wx.RadioButton( self, -1, " UTM " ) + self.radio4 = wx.RadioButton( self, -1, " Custom " ) + self.radio5 = wx.RadioButton( self, -1, " EPSG " ) + self.radio6 = wx.RadioButton( self, -1, " Based on Georeferenced file " ) + + # layout + self.sizer.Add(self.radio1, 0, wx.ALIGN_LEFT, row=1, col=2) + self.sizer.Add(self.radio2, 0, wx.ALIGN_LEFT, row=2, col=2) + self.sizer.Add(self.radio3, 0, wx.ALIGN_LEFT, row=3, col=2) + self.sizer.Add(self.radio4, 0, wx.ALIGN_LEFT, row=4, col=2) + self.sizer.Add(self.radio5, 0, wx.ALIGN_LEFT, row=5, col=2) + self.sizer.Add(self.radio6, 0, wx.ALIGN_LEFT, row=6, col=2) + + # bindings + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio3.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio4.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio5.GetId()) + self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio6.GetId()) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChange) + + def SetVal(self,event): + if event.GetId() == self.radio1.GetId(): + self.cs = "xy" + self.SetNext(self.parent.bboxpage) + self.parent.bboxpage.cstate.Enable(False) + elif event.GetId() == self.radio2.GetId(): + self.cs = "latlong" + self.SetNext(self.parent.datumpage) + self.parent.datumpage.SetPrev(self.parent.csystemspage) + self.parent.bboxpage.SetPrev(self.parent.datumpage) + elif event.GetId() == self.radio3.GetId(): + self.cs = "utm" + self.SetNext(self.parent.datumpage) + self.parent.datumpage.SetPrev(self.parent.csystemspage) + self.parent.bboxpage.SetPrev(self.parent.datumpage) + elif event.GetId() == self.radio4.GetId(): + self.cs = "custom" + self.SetNext(self.parent.projpage) + self.parent.datumpage.SetPrev(self.parent.projpage) + self.parent.bboxpage.SetPrev(self.parent.datumpage) + elif event.GetId() == self.radio5.GetId(): + self.cs = "epsg" + self.SetNext(self.parent.epsgpage) + self.parent.datumpage.SetPrev(self.parent.epsgpage) + self.parent.bboxpage.SetPrev(self.parent.datumpage) + elif event.GetId() == self.radio6.GetId(): + self.SetNext(self.parent.filepage) + self.cs = "file" + + def OnWizPageChange(self,event=None): + if self.cs == "xy": + self.parent.bboxpage.cstate.Enable(False) + else: + self.parent.bboxpage.cstate.Enable(True) + pass + + +class DatabasePage(TitledPage): + def __init__(self, wizard, parent, grassdatabase): + TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name") + + # buttons + self.bbrowse = self.MakeButton("Browse ...", size=wx.DefaultSize) + + # text controls + self.tgisdbase = self.MakeTextCtrl(grassdatabase, size=(300, -1)) + self.tlocation = self.MakeTextCtrl("newLocation", size=(300, -1)) + + # layout + self.sizer.Add(self.MakeLabel("GIS Data Directory:"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=1, col=2) + self.sizer.Add(self.tgisdbase,0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=1, col=3) + self.sizer.Add(self.bbrowse, 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=1, col=4) + # + self.sizer.Add(self.MakeLabel("Project Location"), 0, + wx.ALIGN_RIGHT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=2, col=2) + self.sizer.Add(self.tlocation,0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=2, col=3) + self.sizer.Add(self.MakeLabel("(projection/coordinate system)"), 0, + wx.ALIGN_LEFT | + wx.ALIGN_CENTER_VERTICAL | + wx.ALL, 5, + row=2, col=4) + + # bindings + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChanging) + + def OnWizPageChanging(self,event=None): + if os.path.isdir(os.path.join(self.tgisdbase.GetValue(),self.tlocation.GetValue())): + dlg = wx.MessageDialog(self, "Could not create new location: <%s> directory exists "\ + % str(self.tlocation.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + event.Veto() + return + + if not self.tlocation.GetValue(): + dlg = wx.MessageDialog(self, "Could not create new location: not set "\ + ,"Can not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + event.Veto() + return + + self.location = self.tlocation.GetValue() + self.grassdatabase = self.tgisdbase.GetValue() + + def OnWizPageChange(self,event=None): + self.grassdatabase = self.tgisdbase.GetValue() + self.location = self.tlocation.GetValue() + + +class GWizard: + def __init__(self, parent, grassdatabase): + wizbmp = wx.Image(os.path.join(os.getenv("GISBASE"),"etc","wx","images","grasslogo_small.gif"), wx.BITMAP_TYPE_GIF) + wizbmp.Rescale(50,60) + wizbmp = wizbmp.ConvertToBitmap() + wizard = wiz.Wizard(parent, -1, "Define new Location", + bitmap=wizbmp) + self.startpage = DatabasePage(wizard, self, grassdatabase) + self.csystemspage = CoordinateSystemPage(wizard, self) + self.epsgpage = EPSGPage(wizard, self) + self.bboxpage = BBoxPage(wizard, self) + self.filepage = GeoreferencedFilePage(wizard, self) + self.projpage = ProjectionsPage(wizard, self) + self.sumpage = SummaryPage(wizard, self) + self.datumpage = DatumPage(wizard, self) + + # Set the initial order of the pages + self.startpage.SetNext(self.csystemspage) + + self.csystemspage.SetPrev(self.startpage) + self.csystemspage.SetNext(self.bboxpage) + + self.epsgpage.SetNext(self.datumpage) + self.epsgpage.SetPrev(self.csystemspage) + + self.projpage.SetNext(self.datumpage) + self.projpage.SetPrev(self.csystemspage) + + self.filepage.SetPrev(self.csystemspage) + + self.datumpage.SetNext(self.bboxpage) + + self.bboxpage.SetPrev(self.csystemspage) + self.bboxpage.SetNext(self.sumpage) + + self.sumpage.SetPrev(self.bboxpage) + + wizard.FitToPage(self.bboxpage) + wizard.RunWizard(self.startpage) + wizard.Destroy() + +if __name__ == "__main__": + gWizard = GWizard(None, "") + GRASSStartUp = GWizard.StartUp(0) + GRASSStartUp.MainLoop() + #app.MainLoop() From barton at grass.itc.it Sun Mar 25 08:07:42 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:07:43 2007 Subject: [grass-addons] r292 - trunk/grassaddons/gui Message-ID: <200703250607.l2P67g1g021508@grass.itc.it> Author: barton Date: 2007-03-25 08:07:36 +0200 (Sun, 25 Mar 2007) New Revision: 292 Added: trunk/grassaddons/gui/gui_modules/ Log: Renamed wx/Gism to wx/gui_modules From barton at grass.itc.it Sun Mar 25 08:08:38 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:08:40 2007 Subject: [grass-addons] r293 - trunk/grassaddons/gui/Gism Message-ID: <200703250608.l2P68cQs021528@grass.itc.it> Author: barton Date: 2007-03-25 08:08:31 +0200 (Sun, 25 Mar 2007) New Revision: 293 Added: trunk/grassaddons/gui/Gism/wxgui_utils.py Log: Renamed gismutils.py to wxgui_utils.py Added: trunk/grassaddons/gui/Gism/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/Gism/wxgui_utils.py (rev 0) +++ trunk/grassaddons/gui/Gism/wxgui_utils.py 2007-03-25 06:08:31 UTC (rev 293) @@ -0,0 +1,747 @@ +import os,sys +import wx +import wx.lib.customtreectrl as CT +import wx.combo + +import track +import select +import menuform + +#FIXME?? +try: + import subprocess +except: + from compat import subprocess + + +gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules/" +sys.path.append(gmpath) + +icons = "" + +if not os.getenv("GRASS_ICONPATH"): + icons = os.getenv("GISBASE") + "/etc/gui/icons/" +else: + icons = os.environ["GRASS_ICONPATH"] + +class LayerTree(CT.CustomTreeCtrl): + """ + Creates layer tree structure + """ + # def __init__(self, parent, id, pos, size, style): + def __init__(self, parent, + id=wx.ID_ANY, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.SUNKEN_BORDER, + ctstyle=CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT | + CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT, + disp=None, log=None): + CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style,ctstyle) + + # we need this only for GIS Manager, but not for e.g. mapdisp + import menuform + + self.SetAutoLayout(True) + self.SetGradientStyle(1) + self.EnableSelectionGradient(True) + self.SetFirstGradientColour(wx.Colour(150, 150, 150)) + + self.Map = "" # instance of render.Map associated with display + self.root = "" # ID of layer tree root node + self.node = 0 # index value for layers + self.optpage = {} # dictionary of notebook option pages for each map layer + self.layer_selected = "" # ID of currently selected layer + self.layertype = {} # dictionary of layer types for each layer + self.layerctrl = {} # dictionary of layers indexed by special wind controls (spinctrl and textctrl) + self.saveitem = {} # dictionary to preserve layer attributes for drag and drop + self.first = True # indicates if a layer is just added or not + self.drag = False # flag to indicate a drag event is in process + self.params = {} # dictionary of existing command parameters + + self.Map = disp.getRender() + + self.root = self.AddRoot("Map Layers") + self.SetPyData(self.root, None) + + #create image list to use with layer tree + il = wx.ImageList(16, 16, False) + + trgif = wx.Image(icons + r'/element-cell.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.rast_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.rgb.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.rgb_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/channel-his.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.his_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.legend.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.leg_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/element-vector.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.vect_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.vect.thematic.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.theme_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.vect.chart.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.chart_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/gui-cmd.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.cmd_icon = il.Add(trgif) + + checksize = il.GetSize(0) + checkbmp = il.GetBitmap(0) + self.AssignImageList(il) + + # use when groups implemented + # self.tree.SetItemImage(self.root, fldridx, wx.TreeItemIcon_Normal) + # self.tree.SetItemImage(self.root, fldropenidx, wx.TreeItemIcon_Expanded) + + self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.onExpandNode) + self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.onCollapseNode) + self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.onActivateLayer) + self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onChangeSel) + self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.onLayerChecked) + self.Bind(wx.EVT_TREE_DELETE_ITEM, self.onDeleteLayer) + self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag) + self.Bind(wx.EVT_TREE_END_DRAG, self.onEndDrag) + + def AddLayer(self, idx, type): + self.first = True + if type == 'command': + # generic command layer + self.ctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='', + pos=wx.DefaultPosition, size=(250,40), + style=wx.TE_MULTILINE|wx.TE_WORDWRAP) + self.ctrl.Bind(wx.EVT_TEXT_ENTER, self.onCmdChanged) + self.ctrl.Bind(wx.EVT_TEXT, self.onCmdChanged) + else: + # all other layers + self.ctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50), + style=wx.SP_ARROW_KEYS) + self.ctrl.SetRange(1,100) + self.ctrl.SetValue(100) + self.ctrl.Bind(wx.EVT_TEXT, self.onOpacity) + + if self.layer_selected and self.layer_selected != self.GetRootItem(): + layer = self.InsertItem(self.root, self.GetPrevSibling(self.layer_selected), + '', ct_type=1, wnd=self.ctrl ) + else: + layer = self.PrependItem(self.root, '', ct_type=1, wnd=self.ctrl) + + self.SelectItem(layer) + + # add to layertype and layerctrl dictionaries + self.layertype[layer] = type + self.layerctrl[self.ctrl] = layer + + # add a data object to hold the layer's command (does not apply to generic command layers) + self.SetPyData(layer, None) + + #layer is initially unchecked as inactive + self.CheckItem(layer, checked=False) + + # add layer to layers list in render.Map + self.Map.addLayer(item=layer, command='', l_active=False, + l_hidden=False, l_opacity=1, l_render=False) + + # add text and icons for each layer type + if type == 'raster': + self.SetItemImage(layer, self.rast_icon) + self.SetItemText(layer, 'raster (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'rgb': + self.SetItemImage(layer, self.rgb_icon) + self.SetItemText(layer, 'RGB (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'his': + self.SetItemImage(layer, self.his_icon) + self.SetItemText(layer, 'HIS (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'rastleg': + self.SetItemImage(layer, self.leg_icon) + self.SetItemText(layer, 'legend (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'vector': + self.SetItemImage(layer, self.vect_icon) + self.SetItemText(layer, 'vector (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'thememap': + self.SetItemImage(layer, self.theme_icon) + self.SetItemText(layer, 'thematic map (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'themechart': + self.SetItemImage(layer, self.chart_icon) + self.SetItemText(layer, 'thematic charts (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'command': + self.SetItemImage(layer, self.cmd_icon) + self.first = False + + def onActivateLayer(self, event): + global gmpath + layer = event.GetItem() + self.layer_selected = layer + completed = '' + + # When double clicked or first added, open options dialog + if self.layertype[layer] == 'raster': + menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'rgb': + menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'his': + menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'rastleg': + menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'vector': + menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'thememap': + menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'themechart': + menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + + def onDeleteLayer(self, event): + layer = event.GetItem() + self.layertype.pop(layer) + + # delete layer in render.Map + self.Map.delLayer(item=layer) + + def onLayerChecked(self, event): + layer = event.GetItem() + checked = self.IsItemChecked(layer) + + if self.drag == False and self.first == False: + # change active parameter for item in layers list in render.Map + self.changeChecked(layer, checked) + + def onCmdChanged(self, event): + layer = self.layerctrl[event.GetEventObject()] + cmd = event.GetString() + + if self.drag == False: + # change parameters for item in layers list in render.Map + self.changeLayer(layer) + event.Skip() + + def onOpacity(self, event): + if 'Spin' in str(event.GetEventObject()): + layer = self.layerctrl[event.GetEventObject()] + else: + layer = self.layerctrl[event.GetEventObject().GetParent()] + opacity = float(event.GetString())/100 + + if self.drag == False: + # change opacity parameter for item in layers list in render.Map + self.changeOpacity(layer, opacity) + event.Skip() + + def onChangeSel(self, event): + layer = event.GetItem() + self.layer_selected = layer + + def onCollapseNode(self, event): + print 'group collapsed' + event.Skip() + + def onExpandNode(self, event): + self.layer_selected = event.GetItem() + print 'group expanded' + event.Skip() + + def onBeginDrag(self, event): + """ Drag and drop of single tree nodes + """ + self.drag = True + # node cannot be a parent + if self.GetChildrenCount(event.GetItem()) == 0: + event.Allow() + + # save everthing associated with item to drag + self.dragItem = event.GetItem() + self.saveitem['type'] = self.layertype[self.dragItem] + self.saveitem['check'] = self.IsItemChecked(self.dragItem) + self.saveitem['image'] = self.GetItemImage(self.dragItem, 0) + self.saveitem['text'] = self.GetItemText(self.dragItem) + self.saveitem['wind'] = self.GetItemWindow(self.dragItem) + self.saveitem['windval'] = self.GetItemWindow(self.dragItem).GetValue() + self.saveitem['data'] = self.GetPyData(self.dragItem) + else: + print ("Cant drag a node that has children") + + def onEndDrag(self, event): + """ + Insert copy of layer in new position and + delete original at old position + """ + + #If we dropped somewhere that isn't on top of an item, ignore the event + if not event.GetItem(): + return + + # Make sure this memeber exists. + try: + old = self.dragItem + except: + return + + # Get the other IDs that are involved + afteritem = event.GetItem() + parent = self.GetItemParent(afteritem) + if not parent: + return + + # recreate old layer at new position + if self.layertype[old] == 'command': + self.dragctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='', + pos=wx.DefaultPosition, size=(250,40), + style=wx.TE_MULTILINE|wx.TE_WORDWRAP) + self.dragctrl.Bind(wx.EVT_TEXT_ENTER, self.onCmdChanged) + else: + self.dragctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50), + style=wx.SP_ARROW_KEYS) + self.dragctrl.SetRange(1,100) + self.dragctrl.SetValue(100) + self.dragctrl.Bind(wx.EVT_SPINCTRL, self.onOpacity) + + new = self.InsertItem(parent, afteritem, text=self.saveitem['text'], \ + ct_type=1, wnd=self.dragctrl, image=self.saveitem['image'], \ + data=self.saveitem['data']) + self.layertype[new] = self.saveitem['type'] + self.CheckItem(new, checked=self.saveitem['check']) + self.GetItemWindow(new).SetValue(self.saveitem['windval']) + + # delete layer at original position + self.Delete(old) + + # update layers list in render.Map + if self.saveitem['type'] == 'command': + self.Map.addLayer(item=new, command=self.saveitem['windval'], l_active=self.saveitem['check'], + l_hidden=False, l_opacity=1, l_render=False) + else: + self.Map.addLayer(item=new, command=self.saveitem['data'], l_active=self.saveitem['check'], + l_hidden=False, l_opacity=self.saveitem['windval'], l_render=False) + + self.reorderLayers() + self.drag = False + + def getOptData(self, dcmd, layer): + for item in dcmd.split(' '): + if 'map=' in item: + mapname = item.split('=')[1] + elif 'red=' in item: + mapname = item.split('=')[1] + elif 'h_map=' in item: + mapname = item.split('=')[1] + + # set layer text to map name + self.SetItemText(layer, mapname) + + # add command to layer's data + self.SetPyData(layer, dcmd) + + # check layer as active + self.CheckItem(layer, checked=True) + + # change parameters for item in layers list in render.Map + self.changeLayer(layer) + + def writeDCommand(self, dcmd): + # echos d.* command to output console + global goutput + goutput.write(dcmd+"\n----------\n") + + def reorderLayers(self): + """ + add commands from data associated with + any valid and checked layers to layer list + """ + # first empty the list of old layers +# self.Map.Clean() + # make a list of visible layers + treelayers = [] + vislayer = self.GetFirstVisibleItem() + for item in range(0,self.GetCount()): + if self.IsItemChecked(vislayer): + treelayers.append(vislayer) + if self.GetNextVisible(vislayer) == None: + break + else: + vislayer = self.GetNextVisible(vislayer) + treelayers.reverse() + self.Map.reorderLayers(treelayers) + + def changeOpacity(self, layer, opacity): + self.Map.changeOpacity(layer, opacity) + + def changeChecked(self, layer, check): + self.Map.changeActive(layer, check) + + def changeLayer(self, layer): + if self.layertype[layer] == 'command': + if self.GetItemWindow(layer).GetValue() != None: + cmd = self.GetItemWindow(layer).GetValue() + opac = 1.0 + chk = self.IsItemChecked(layer) + hidden = not self.IsVisible(layer) + self.Map.changeLayer(item=layer, command=cmd, l_active=chk, + l_hidden=hidden, l_opacity=opac, l_render=False) + else: + if self.GetPyData(layer) != None: + cmd = self.GetPyData(layer) + opac = float(self.GetItemWindow(layer).GetValue())/100 + chk = self.IsItemChecked(layer) + hidden = not self.IsVisible(layer) + self.Map.changeLayer(item=layer, command=cmd, l_active=chk, + l_hidden=hidden, l_opacity=opac, l_render=False) + +class TreeCtrlComboPopup(wx.combo.ComboPopup): + """ + Create a tree ComboBox for selecting maps and other GIS elements + in accessible mapsets within the current location + """ + + # overridden ComboPopup methods + + def Init(self): + self.value = None + self.curitem = None + + + def Create(self, parent): + self.tree = wx.TreeCtrl(parent, style=wx.TR_HIDE_ROOT + |wx.TR_HAS_BUTTONS + |wx.TR_SINGLE + |wx.TR_LINES_AT_ROOT + |wx.SIMPLE_BORDER + |wx.TR_FULL_ROW_HIGHLIGHT) + self.tree.Bind(wx.EVT_MOTION, self.OnMotion) + self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) + + + def GetControl(self): + return self.tree + + + def GetStringValue(self): + if self.value: + return self.tree.GetItemText(self.value) + return "" + + + def OnPopup(self): + if self.value: + self.tree.EnsureVisible(self.value) + self.tree.SelectItem(self.value) + + + def SetStringValue(self, value): + # this assumes that item strings are unique... + root = self.tree.GetRootItem() + if not root: + return + found = self.FindItem(root, value) + if found: + self.value = found + self.tree.SelectItem(found) + + + def GetAdjustedSize(self, minWidth, prefHeight, maxHeight): + return wx.Size(minWidth, min(200, maxHeight)) + + + def getElementList(self, element): + """ + Get list of GIS elements in accessible mapsets and display as tree + with all relevant elements displayed beneath each mapset branch + """ + #set environmental variables + gisdbase = os.popen('g.gisenv get=GISDBASE', "r").read().strip() + location = os.popen('g.gisenv get=LOCATION_NAME', "r").read().strip() + curr_mapset = os.popen('g.gisenv get=MAPSET', "r").read().strip() + location_path = os.path.join (gisdbase,location) + windfile = os.path.join (location_path,'PERMANENT','WIND') + symbol_path = os.path.join (os.environ['GISBASE'],'etc','symbol') + + #valid location test if needed + if windfile != None: + pass + + #mapsets in current location + mapsets = os.popen('g.mapsets -p', "r").read().lstrip().rstrip().split(' ') + + #Get directory tree nodes + for dir in mapsets: + if dir == curr_mapset: + #TODO: make current mapset node expanded + dir_node = self.AddItem('Mapset: '+dir) + self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) + self.tree.Expand(dir_node) + elem_list = os.listdir(os.path.join (location_path, dir, element)) + #TODO: sort list items? + for elem in elem_list: + self.AddItem(elem, parent=dir_node) + else: + dir_node = self.AddItem('Mapset: '+dir) + self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) + elem_list = os.listdir(os.path.join (location_path, dir, element)) + #TODO: sort list items? + for elem in elem_list: + self.AddItem(elem+'@'+dir, parent=dir_node) + + # helpers + + def FindItem(self, parentItem, text): + item, cookie = self.tree.GetFirstChild(parentItem) + while item: + if self.tree.GetItemText(item) == text: + return item + if self.tree.ItemHasChildren(item): + item = self.FindItem(item, text) + item, cookie = self.tree.GetNextChild(parentItem, cookie) + return wx.TreeItemId(); + + + def AddItem(self, value, parent=None): + if not parent: + root = self.tree.GetRootItem() + if not root: + root = self.tree.AddRoot("") + parent = root + + item = self.tree.AppendItem(parent, value) + return item + + + def OnMotion(self, evt): + # have the selection follow the mouse, like in a real combobox + item, flags = self.tree.HitTest(evt.GetPosition()) + if item and flags & wx.TREE_HITTEST_ONITEMLABEL: + self.tree.SelectItem(item) + self.curitem = item + evt.Skip() + + + def OnLeftDown(self, evt): + # do the combobox selection + item, flags = self.tree.HitTest(evt.GetPosition()) + if item and flags & wx.TREE_HITTEST_ONITEMLABEL: + self.curitem = item + self.value = item + self.Dismiss() + evt.Skip() + + + +class GMConsole(wx.Panel): + """ + Create and manage output console for commands entered on the + GIS Manager command line. + """ + def __init__(self, parent, id=-1, + pos=wx.DefaultPosition, size=wx.DefaultSize, + style=wx.TAB_TRAVERSAL|wx.FULL_REPAINT_ON_RESIZE): + wx.Panel.__init__(self, parent, id, pos, size, style) + #initialize variables + + self.cmd_output = "" + self.console_command = "" + self.console_clear = "" + self.console_save = "" + self.gcmdlst = [] #list of commands in bin and scripts + + #text control for command output + self.cmd_output = wx.TextCtrl(self, -1, "", + style=wx.TE_MULTILINE| + wx.TE_READONLY) + + global goutput + goutput = self.cmd_output + self.console_clear = wx.Button(self, -1, _("Clear")) + self.console_save = wx.Button(self, -1, _("Save")) + + self.Bind(wx.EVT_BUTTON, self.clearHistory, self.console_clear) + self.Bind(wx.EVT_BUTTON, self.saveHistory, self.console_save) + + # output control layout + boxsizer1 = wx.BoxSizer(wx.VERTICAL) + gridsizer1 = wx.GridSizer(1, 2, 0, 0) + boxsizer1.Add(self.cmd_output, 1, + wx.EXPAND|wx.ADJUST_MINSIZE, 0) + gridsizer1.Add(self.console_clear, 0, + wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) + gridsizer1.Add(self.console_save, 0, + wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) + + boxsizer1.Add((0,5)) + boxsizer1.Add(gridsizer1, 0, wx.EXPAND|wx.ALIGN_CENTRE_VERTICAL) + boxsizer1.Add((0,5)) + boxsizer1.Fit(self) + boxsizer1.SetSizeHints(self) + self.SetAutoLayout(True) + self.SetSizer(boxsizer1) + + def getGRASSCmds(self): + ''' + Create list of all available GRASS commands to use when + parsing string from the command line + ''' + self.gcmdlst = [] + gisbase = os.environ['GISBASE'] + self.gcmdlst = os.listdir(gisbase+r'/bin') + self.gcmdlst = self.gcmdlst + os.listdir(gisbase+r'/scripts') + return self.gcmdlst + + def runCmd(self, cmd): + """ + Run in GUI or shell GRASS (or other) commands typed into + console command text widget, echo command to + output text widget, and send stdout output to output + text widget. + + TODO: Display commands (*.d) are captured and + processed separately by mapdisp.py. Display commands are + rendered in map display widget that currently has + the focus (as indicted by mdidx). + """ + + gcmdlst = self.getGRASSCmds() + cmdlst = [] +# cmd = self.console_command.GetLineText(0) + cmdlst = cmd.split(' ') + disp_idx = int(track.Track().GetDisp()[0]) + curr_disp = track.Track().GetDisp()[1] + + if len(cmdlst) == 1 and cmd in gcmdlst: + # Send GRASS command without arguments to GUI command interface + # except display commands (they are handled differently) + global gmpath + if cmd[0:2] == "d.": + if cmd == 'd.rast': + layertype = 'raster' + elif cmd == 'd.rgb': + layertype = 'rgb' + elif cmd == 'd.his': + layertype = 'his' + elif cmd == 'd.legend': + layertype = 'rastleg' + elif cmd == 'd.vect': + layertype = 'vector' + elif cmd == 'd.vect.thematic': + layertype = 'thememap' + elif cmd == 'd.vect.chart': + layertype = 'themechart' + else: + print 'Command type not yet implemented' + return + + if disp_idx != None: + # get layer tree for active display + layertree = track.Track().GetCtrls(disp_idx, 2) + # add layer + layertree.AddLayer(disp_idx, layertype) + + else: + menuform.GUI().parseCommand(cmd, gmpath) + self.cmd_output.write(cmdlst[0] + + "\n----------\n") + + elif cmd[0:2] == "d." and len(cmdlst) > 1 and cmdlst[0] in gcmdlst: + """ + Send GRASS display command(s)with arguments + to the display processor and echo to command output console. + Accepts a list of d.* commands separated by commas. + Display with focus receives display command(s). + """ + self.cmd_output.write(cmd + + "\n----------\n") + dcmds = cmd.split(',') + curr_disp.addMapsToList(type='command', map=dcmds, mset=None) + curr_disp.ReDrawCommand() + + else: + # Send any other command to the shell. Send output to + # console output window. + try: + retcode = subprocess.call(cmd, shell=True) + + if retcode < 0: + print >> sys.stderr, "Child was terminated by signal", retcode + elif retcode > 0: + print >> sys.stderr, "Child returned", retcode + except OSError, e: + print >> sys.stderr, "Execution failed:", e + + self.cmd_output.write(cmd+"\n----------\n") + #FIXME - why is PIPE not recognized? +# self.out = subprocess.Popen(cmd, shell=True, stdout=PIPE).stdout + self.out = os.popen(cmd, "r").read() + self.cmd_output.write(self.out+"\n") + + def clearHistory(self, event): + self.cmd_output.Clear() + + def saveHistory(self, event): + self.history = self.cmd_output.GetStringSelection() + if self.history == "": + self.cmd_output.SetSelection(-1,-1) + self.history = self.cmd_output.GetStringSelection() + + #Use a standard dialog for this + wildcard = "Text file (*.txt)|*.txt" + dlg = wx.FileDialog( + self, message="Save file as ...", defaultDir=os.getcwd(), + defaultFile="grass_cmd_history.txt", wildcard=wildcard, style=wx.SAVE|wx.FD_OVERWRITE_PROMPT + ) + + # Show the dialog and retrieve the user response. If it is the OK response, + # process the data. + if dlg.ShowModal() == wx.ID_OK: + path = dlg.GetPath() + + output = open(path,"w") + output.write(self.history) + output.close() + dlg.Destroy() + +def GetTempfile( pref=None): + """ + Creates GRASS temporary file using defined prefix. + + Returns: + Path to file name (string) or None + """ + + tempfile = os.popen("g.tempfile pid=%d" % + os.getpid()).readlines()[0].strip() + + if not tempfile: + return None + else: + path,file = os.path.split(tempfile) + if pref: + file = "%s%s" % (pref,file) + return os.path.join(path,file) From barton at grass.itc.it Sun Mar 25 08:09:30 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:09:33 2007 Subject: [grass-addons] r294 - trunk/grassaddons/gui/Gism Message-ID: <200703250609.l2P69UqC021554@grass.itc.it> Author: barton Date: 2007-03-25 08:09:22 +0200 (Sun, 25 Mar 2007) New Revision: 294 Removed: trunk/grassaddons/gui/Gism/gismutils.py trunk/grassaddons/gui/Gism/grass.smlogo.gif trunk/grassaddons/gui/Gism/grasslogo_big.gif Log: renamed gismutils.py and moved grass logo files to wx/images Deleted: trunk/grassaddons/gui/Gism/gismutils.py =================================================================== --- trunk/grassaddons/gui/Gism/gismutils.py 2007-03-25 06:08:31 UTC (rev 293) +++ trunk/grassaddons/gui/Gism/gismutils.py 2007-03-25 06:09:22 UTC (rev 294) @@ -1,750 +0,0 @@ -import os,sys -import wx -import wx.lib.customtreectrl as CT -import wx.combo - -import track -import select -import menuform -import optpanels.raster_prop as raster_prop -import optpanels.vectopt as vectopt -import optpanels.cmdopt as cmdopt - -#FIXME?? -try: - import subprocess -except: - from compat import subprocess - - -gmpath = os.getenv("GISBASE") + "/etc/wx/Gism/" -sys.path.append(gmpath) - -icons = "" - -if not os.getenv("GRASS_ICONPATH"): - icons = os.getenv("GISBASE") + "/etc/gui/icons/" -else: - icons = os.environ["GRASS_ICONPATH"] - -class LayerTree(CT.CustomTreeCtrl): - """ - Creates layer tree structure - """ - # def __init__(self, parent, id, pos, size, style): - def __init__(self, parent, - id=wx.ID_ANY, pos=wx.DefaultPosition, - size=wx.DefaultSize, style=wx.SUNKEN_BORDER, - ctstyle=CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT | - CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT, - disp=None, log=None): - CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style,ctstyle) - - # we need this only for GIS Manager, but not for e.g. mapdisp - import menuform - - self.SetAutoLayout(True) - self.SetGradientStyle(1) - self.EnableSelectionGradient(True) - self.SetFirstGradientColour(wx.Colour(150, 150, 150)) - - self.Map = "" # instance of render.Map associated with display - self.root = "" # ID of layer tree root node - self.node = 0 # index value for layers - self.optpage = {} # dictionary of notebook option pages for each map layer - self.layer_selected = "" # ID of currently selected layer - self.layertype = {} # dictionary of layer types for each layer - self.layerctrl = {} # dictionary of layers indexed by special wind controls (spinctrl and textctrl) - self.saveitem = {} # dictionary to preserve layer attributes for drag and drop - self.first = True # indicates if a layer is just added or not - self.drag = False # flag to indicate a drag event is in process - self.params = {} # dictionary of existing command parameters - - self.Map = disp.getRender() - - self.root = self.AddRoot("Map Layers") - self.SetPyData(self.root, None) - - #create image list to use with layer tree - il = wx.ImageList(16, 16, False) - - trgif = wx.Image(icons + r'/element-cell.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.rast_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/module-d.rgb.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.rgb_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/channel-his.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.his_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/module-d.legend.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.leg_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/element-vector.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.vect_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/module-d.vect.thematic.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.theme_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/module-d.vect.chart.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.chart_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/gui-cmd.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.cmd_icon = il.Add(trgif) - - checksize = il.GetSize(0) - checkbmp = il.GetBitmap(0) - self.AssignImageList(il) - - # use when groups implemented - # self.tree.SetItemImage(self.root, fldridx, wx.TreeItemIcon_Normal) - # self.tree.SetItemImage(self.root, fldropenidx, wx.TreeItemIcon_Expanded) - - self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.onExpandNode) - self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.onCollapseNode) - self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.onActivateLayer) - self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onChangeSel) - self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.onLayerChecked) - self.Bind(wx.EVT_TREE_DELETE_ITEM, self.onDeleteLayer) - self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag) - self.Bind(wx.EVT_TREE_END_DRAG, self.onEndDrag) - - def AddLayer(self, idx, type): - self.first = True - if type == 'command': - # generic command layer - self.ctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='', - pos=wx.DefaultPosition, size=(250,40), - style=wx.TE_MULTILINE|wx.TE_WORDWRAP) - self.ctrl.Bind(wx.EVT_TEXT_ENTER, self.onCmdChanged) - self.ctrl.Bind(wx.EVT_TEXT, self.onCmdChanged) - else: - # all other layers - self.ctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50), - style=wx.SP_ARROW_KEYS) - self.ctrl.SetRange(1,100) - self.ctrl.SetValue(100) - self.ctrl.Bind(wx.EVT_TEXT, self.onOpacity) - - if self.layer_selected and self.layer_selected != self.GetRootItem(): - layer = self.InsertItem(self.root, self.GetPrevSibling(self.layer_selected), - '', ct_type=1, wnd=self.ctrl ) - else: - layer = self.PrependItem(self.root, '', ct_type=1, wnd=self.ctrl) - - self.SelectItem(layer) - - # add to layertype and layerctrl dictionaries - self.layertype[layer] = type - self.layerctrl[self.ctrl] = layer - - # add a data object to hold the layer's command (does not apply to generic command layers) - self.SetPyData(layer, None) - - #layer is initially unchecked as inactive - self.CheckItem(layer, checked=False) - - # add layer to layers list in render.Map - self.Map.addLayer(item=layer, command='', l_active=False, - l_hidden=False, l_opacity=1, l_render=False) - - # add text and icons for each layer type - if type == 'raster': - self.SetItemImage(layer, self.rast_icon) - self.SetItemText(layer, 'raster (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'rgb': - self.SetItemImage(layer, self.rgb_icon) - self.SetItemText(layer, 'RGB (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'his': - self.SetItemImage(layer, self.his_icon) - self.SetItemText(layer, 'HIS (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'rastleg': - self.SetItemImage(layer, self.leg_icon) - self.SetItemText(layer, 'legend (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'vector': - self.SetItemImage(layer, self.vect_icon) - self.SetItemText(layer, 'vector (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'thememap': - self.SetItemImage(layer, self.theme_icon) - self.SetItemText(layer, 'thematic map (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'themechart': - self.SetItemImage(layer, self.chart_icon) - self.SetItemText(layer, 'thematic charts (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'command': - self.SetItemImage(layer, self.cmd_icon) - self.first = False - - def onActivateLayer(self, event): - global gmpath - layer = event.GetItem() - self.layer_selected = layer - completed = '' - - # When double clicked or first added, open options dialog - if self.layertype[layer] == 'raster': - menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'rgb': - menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'his': - menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'rastleg': - menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'vector': - menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'thememap': - menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'themechart': - menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - - def onDeleteLayer(self, event): - layer = event.GetItem() - self.layertype.pop(layer) - - # delete layer in render.Map - self.Map.delLayer(item=layer) - - def onLayerChecked(self, event): - layer = event.GetItem() - checked = self.IsItemChecked(layer) - - if self.drag == False and self.first == False: - # change active parameter for item in layers list in render.Map - self.changeChecked(layer, checked) - - def onCmdChanged(self, event): - layer = self.layerctrl[event.GetEventObject()] - cmd = event.GetString() - - if self.drag == False: - # change parameters for item in layers list in render.Map - self.changeLayer(layer) - event.Skip() - - def onOpacity(self, event): - if 'Spin' in str(event.GetEventObject()): - layer = self.layerctrl[event.GetEventObject()] - else: - layer = self.layerctrl[event.GetEventObject().GetParent()] - opacity = float(event.GetString())/100 - - if self.drag == False: - # change opacity parameter for item in layers list in render.Map - self.changeOpacity(layer, opacity) - event.Skip() - - def onChangeSel(self, event): - layer = event.GetItem() - self.layer_selected = layer - - def onCollapseNode(self, event): - print 'group collapsed' - event.Skip() - - def onExpandNode(self, event): - self.layer_selected = event.GetItem() - print 'group expanded' - event.Skip() - - def onBeginDrag(self, event): - """ Drag and drop of single tree nodes - """ - self.drag = True - # node cannot be a parent - if self.GetChildrenCount(event.GetItem()) == 0: - event.Allow() - - # save everthing associated with item to drag - self.dragItem = event.GetItem() - self.saveitem['type'] = self.layertype[self.dragItem] - self.saveitem['check'] = self.IsItemChecked(self.dragItem) - self.saveitem['image'] = self.GetItemImage(self.dragItem, 0) - self.saveitem['text'] = self.GetItemText(self.dragItem) - self.saveitem['wind'] = self.GetItemWindow(self.dragItem) - self.saveitem['windval'] = self.GetItemWindow(self.dragItem).GetValue() - self.saveitem['data'] = self.GetPyData(self.dragItem) - else: - print ("Cant drag a node that has children") - - def onEndDrag(self, event): - """ - Insert copy of layer in new position and - delete original at old position - """ - - #If we dropped somewhere that isn't on top of an item, ignore the event - if not event.GetItem(): - return - - # Make sure this memeber exists. - try: - old = self.dragItem - except: - return - - # Get the other IDs that are involved - afteritem = event.GetItem() - parent = self.GetItemParent(afteritem) - if not parent: - return - - # recreate old layer at new position - if self.layertype[old] == 'command': - self.dragctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='', - pos=wx.DefaultPosition, size=(250,40), - style=wx.TE_MULTILINE|wx.TE_WORDWRAP) - self.dragctrl.Bind(wx.EVT_TEXT_ENTER, self.onCmdChanged) - else: - self.dragctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50), - style=wx.SP_ARROW_KEYS) - self.dragctrl.SetRange(1,100) - self.dragctrl.SetValue(100) - self.dragctrl.Bind(wx.EVT_SPINCTRL, self.onOpacity) - - new = self.InsertItem(parent, afteritem, text=self.saveitem['text'], \ - ct_type=1, wnd=self.dragctrl, image=self.saveitem['image'], \ - data=self.saveitem['data']) - self.layertype[new] = self.saveitem['type'] - self.CheckItem(new, checked=self.saveitem['check']) - self.GetItemWindow(new).SetValue(self.saveitem['windval']) - - # delete layer at original position - self.Delete(old) - - # update layers list in render.Map - if self.saveitem['type'] == 'command': - self.Map.addLayer(item=new, command=self.saveitem['windval'], l_active=self.saveitem['check'], - l_hidden=False, l_opacity=1, l_render=False) - else: - self.Map.addLayer(item=new, command=self.saveitem['data'], l_active=self.saveitem['check'], - l_hidden=False, l_opacity=self.saveitem['windval'], l_render=False) - - self.reorderLayers() - self.drag = False - - def getOptData(self, dcmd, layer): - for item in dcmd.split(' '): - if 'map=' in item: - mapname = item.split('=')[1] - elif 'red=' in item: - mapname = item.split('=')[1] - elif 'h_map=' in item: - mapname = item.split('=')[1] - - # set layer text to map name - self.SetItemText(layer, mapname) - - # add command to layer's data - self.SetPyData(layer, dcmd) - - # check layer as active - self.CheckItem(layer, checked=True) - - # change parameters for item in layers list in render.Map - self.changeLayer(layer) - - def writeDCommand(self, dcmd): - # echos d.* command to output console - global goutput - goutput.write(dcmd+"\n----------\n") - - def reorderLayers(self): - """ - add commands from data associated with - any valid and checked layers to layer list - """ - # first empty the list of old layers -# self.Map.Clean() - # make a list of visible layers - treelayers = [] - vislayer = self.GetFirstVisibleItem() - for item in range(0,self.GetCount()): - if self.IsItemChecked(vislayer): - treelayers.append(vislayer) - if self.GetNextVisible(vislayer) == None: - break - else: - vislayer = self.GetNextVisible(vislayer) - treelayers.reverse() - self.Map.reorderLayers(treelayers) - - def changeOpacity(self, layer, opacity): - self.Map.changeOpacity(layer, opacity) - - def changeChecked(self, layer, check): - self.Map.changeActive(layer, check) - - def changeLayer(self, layer): - if self.layertype[layer] == 'command': - if self.GetItemWindow(layer).GetValue() != None: - cmd = self.GetItemWindow(layer).GetValue() - opac = 1.0 - chk = self.IsItemChecked(layer) - hidden = not self.IsVisible(layer) - self.Map.changeLayer(item=layer, command=cmd, l_active=chk, - l_hidden=hidden, l_opacity=opac, l_render=False) - else: - if self.GetPyData(layer) != None: - cmd = self.GetPyData(layer) - opac = float(self.GetItemWindow(layer).GetValue())/100 - chk = self.IsItemChecked(layer) - hidden = not self.IsVisible(layer) - self.Map.changeLayer(item=layer, command=cmd, l_active=chk, - l_hidden=hidden, l_opacity=opac, l_render=False) - -class TreeCtrlComboPopup(wx.combo.ComboPopup): - """ - Create a tree ComboBox for selecting maps and other GIS elements - in accessible mapsets within the current location - """ - - # overridden ComboPopup methods - - def Init(self): - self.value = None - self.curitem = None - - - def Create(self, parent): - self.tree = wx.TreeCtrl(parent, style=wx.TR_HIDE_ROOT - |wx.TR_HAS_BUTTONS - |wx.TR_SINGLE - |wx.TR_LINES_AT_ROOT - |wx.SIMPLE_BORDER - |wx.TR_FULL_ROW_HIGHLIGHT) - self.tree.Bind(wx.EVT_MOTION, self.OnMotion) - self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) - - - def GetControl(self): - return self.tree - - - def GetStringValue(self): - if self.value: - return self.tree.GetItemText(self.value) - return "" - - - def OnPopup(self): - if self.value: - self.tree.EnsureVisible(self.value) - self.tree.SelectItem(self.value) - - - def SetStringValue(self, value): - # this assumes that item strings are unique... - root = self.tree.GetRootItem() - if not root: - return - found = self.FindItem(root, value) - if found: - self.value = found - self.tree.SelectItem(found) - - - def GetAdjustedSize(self, minWidth, prefHeight, maxHeight): - return wx.Size(minWidth, min(200, maxHeight)) - - - def getElementList(self, element): - """ - Get list of GIS elements in accessible mapsets and display as tree - with all relevant elements displayed beneath each mapset branch - """ - #set environmental variables - gisdbase = os.popen('g.gisenv get=GISDBASE', "r").read().strip() - location = os.popen('g.gisenv get=LOCATION_NAME', "r").read().strip() - curr_mapset = os.popen('g.gisenv get=MAPSET', "r").read().strip() - location_path = os.path.join (gisdbase,location) - windfile = os.path.join (location_path,'PERMANENT','WIND') - symbol_path = os.path.join (os.environ['GISBASE'],'etc','symbol') - - #valid location test if needed - if windfile != None: - pass - - #mapsets in current location - mapsets = os.popen('g.mapsets -p', "r").read().lstrip().rstrip().split(' ') - - #Get directory tree nodes - for dir in mapsets: - if dir == curr_mapset: - #TODO: make current mapset node expanded - dir_node = self.AddItem('Mapset: '+dir) - self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) - self.tree.Expand(dir_node) - elem_list = os.listdir(os.path.join (location_path, dir, element)) - #TODO: sort list items? - for elem in elem_list: - self.AddItem(elem, parent=dir_node) - else: - dir_node = self.AddItem('Mapset: '+dir) - self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) - elem_list = os.listdir(os.path.join (location_path, dir, element)) - #TODO: sort list items? - for elem in elem_list: - self.AddItem(elem+'@'+dir, parent=dir_node) - - # helpers - - def FindItem(self, parentItem, text): - item, cookie = self.tree.GetFirstChild(parentItem) - while item: - if self.tree.GetItemText(item) == text: - return item - if self.tree.ItemHasChildren(item): - item = self.FindItem(item, text) - item, cookie = self.tree.GetNextChild(parentItem, cookie) - return wx.TreeItemId(); - - - def AddItem(self, value, parent=None): - if not parent: - root = self.tree.GetRootItem() - if not root: - root = self.tree.AddRoot("") - parent = root - - item = self.tree.AppendItem(parent, value) - return item - - - def OnMotion(self, evt): - # have the selection follow the mouse, like in a real combobox - item, flags = self.tree.HitTest(evt.GetPosition()) - if item and flags & wx.TREE_HITTEST_ONITEMLABEL: - self.tree.SelectItem(item) - self.curitem = item - evt.Skip() - - - def OnLeftDown(self, evt): - # do the combobox selection - item, flags = self.tree.HitTest(evt.GetPosition()) - if item and flags & wx.TREE_HITTEST_ONITEMLABEL: - self.curitem = item - self.value = item - self.Dismiss() - evt.Skip() - - - -class GMConsole(wx.Panel): - """ - Create and manage output console for commands entered on the - GIS Manager command line. - """ - def __init__(self, parent, id=-1, - pos=wx.DefaultPosition, size=wx.DefaultSize, - style=wx.TAB_TRAVERSAL|wx.FULL_REPAINT_ON_RESIZE): - wx.Panel.__init__(self, parent, id, pos, size, style) - #initialize variables - - self.cmd_output = "" - self.console_command = "" - self.console_clear = "" - self.console_save = "" - self.gcmdlst = [] #list of commands in bin and scripts - - #text control for command output - self.cmd_output = wx.TextCtrl(self, -1, "", - style=wx.TE_MULTILINE| - wx.TE_READONLY) - - global goutput - goutput = self.cmd_output - self.console_clear = wx.Button(self, -1, _("Clear")) - self.console_save = wx.Button(self, -1, _("Save")) - - self.Bind(wx.EVT_BUTTON, self.clearHistory, self.console_clear) - self.Bind(wx.EVT_BUTTON, self.saveHistory, self.console_save) - - # output control layout - boxsizer1 = wx.BoxSizer(wx.VERTICAL) - gridsizer1 = wx.GridSizer(1, 2, 0, 0) - boxsizer1.Add(self.cmd_output, 1, - wx.EXPAND|wx.ADJUST_MINSIZE, 0) - gridsizer1.Add(self.console_clear, 0, - wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) - gridsizer1.Add(self.console_save, 0, - wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) - - boxsizer1.Add((0,5)) - boxsizer1.Add(gridsizer1, 0, wx.EXPAND|wx.ALIGN_CENTRE_VERTICAL) - boxsizer1.Add((0,5)) - boxsizer1.Fit(self) - boxsizer1.SetSizeHints(self) - self.SetAutoLayout(True) - self.SetSizer(boxsizer1) - - def getGRASSCmds(self): - ''' - Create list of all available GRASS commands to use when - parsing string from the command line - ''' - self.gcmdlst = [] - gisbase = os.environ['GISBASE'] - self.gcmdlst = os.listdir(gisbase+r'/bin') - self.gcmdlst = self.gcmdlst + os.listdir(gisbase+r'/scripts') - return self.gcmdlst - - def runCmd(self, cmd): - """ - Run in GUI or shell GRASS (or other) commands typed into - console command text widget, echo command to - output text widget, and send stdout output to output - text widget. - - TODO: Display commands (*.d) are captured and - processed separately by mapdisp.py. Display commands are - rendered in map display widget that currently has - the focus (as indicted by mdidx). - """ - - gcmdlst = self.getGRASSCmds() - cmdlst = [] -# cmd = self.console_command.GetLineText(0) - cmdlst = cmd.split(' ') - disp_idx = int(track.Track().GetDisp()[0]) - curr_disp = track.Track().GetDisp()[1] - - if len(cmdlst) == 1 and cmd in gcmdlst: - # Send GRASS command without arguments to GUI command interface - # except display commands (they are handled differently) - global gmpath - if cmd[0:2] == "d.": - if cmd == 'd.rast': - layertype = 'raster' - elif cmd == 'd.rgb': - layertype = 'rgb' - elif cmd == 'd.his': - layertype = 'his' - elif cmd == 'd.legend': - layertype = 'rastleg' - elif cmd == 'd.vect': - layertype = 'vector' - elif cmd == 'd.vect.thematic': - layertype = 'thememap' - elif cmd == 'd.vect.chart': - layertype = 'themechart' - else: - print 'Command type not yet implemented' - return - - if disp_idx != None: - # get layer tree for active display - layertree = track.Track().GetCtrls(disp_idx, 2) - # add layer - layertree.AddLayer(disp_idx, layertype) - - else: - menuform.GUI().parseCommand(cmd, gmpath) - self.cmd_output.write(cmdlst[0] + - "\n----------\n") - - elif cmd[0:2] == "d." and len(cmdlst) > 1 and cmdlst[0] in gcmdlst: - """ - Send GRASS display command(s)with arguments - to the display processor and echo to command output console. - Accepts a list of d.* commands separated by commas. - Display with focus receives display command(s). - """ - self.cmd_output.write(cmd + - "\n----------\n") - dcmds = cmd.split(',') - curr_disp.addMapsToList(type='command', map=dcmds, mset=None) - curr_disp.ReDrawCommand() - - else: - # Send any other command to the shell. Send output to - # console output window. - try: - retcode = subprocess.call(cmd, shell=True) - - if retcode < 0: - print >> sys.stderr, "Child was terminated by signal", retcode - elif retcode > 0: - print >> sys.stderr, "Child returned", retcode - except OSError, e: - print >> sys.stderr, "Execution failed:", e - - self.cmd_output.write(cmd+"\n----------\n") - #FIXME - why is PIPE not recognized? -# self.out = subprocess.Popen(cmd, shell=True, stdout=PIPE).stdout - self.out = os.popen(cmd, "r").read() - self.cmd_output.write(self.out+"\n") - - def clearHistory(self, event): - self.cmd_output.Clear() - - def saveHistory(self, event): - self.history = self.cmd_output.GetStringSelection() - if self.history == "": - self.cmd_output.SetSelection(-1,-1) - self.history = self.cmd_output.GetStringSelection() - - #Use a standard dialog for this - wildcard = "Text file (*.txt)|*.txt" - dlg = wx.FileDialog( - self, message="Save file as ...", defaultDir=os.getcwd(), - defaultFile="grass_cmd_history.txt", wildcard=wildcard, style=wx.SAVE|wx.FD_OVERWRITE_PROMPT - ) - - # Show the dialog and retrieve the user response. If it is the OK response, - # process the data. - if dlg.ShowModal() == wx.ID_OK: - path = dlg.GetPath() - - output = open(path,"w") - output.write(self.history) - output.close() - dlg.Destroy() - -def GetTempfile( pref=None): - """ - Creates GRASS temporary file using defined prefix. - - Returns: - Path to file name (string) or None - """ - - tempfile = os.popen("g.tempfile pid=%d" % - os.getpid()).readlines()[0].strip() - - if not tempfile: - return None - else: - path,file = os.path.split(tempfile) - if pref: - file = "%s%s" % (pref,file) - return os.path.join(path,file) Deleted: trunk/grassaddons/gui/Gism/grass.smlogo.gif =================================================================== (Binary files differ) Deleted: trunk/grassaddons/gui/Gism/grasslogo_big.gif =================================================================== (Binary files differ) From barton at grass.itc.it Sun Mar 25 08:10:23 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:10:25 2007 Subject: [grass-addons] r295 - trunk/grassaddons/gui Message-ID: <200703250610.l2P6ANJV021580@grass.itc.it> Author: barton Date: 2007-03-25 08:10:16 +0200 (Sun, 25 Mar 2007) New Revision: 295 Removed: trunk/grassaddons/gui/gism.py trunk/grassaddons/gui/grass_wizard.py Log: renamed gism.py to wxgui.py and grass_wizard.py to location_wizard.py Deleted: trunk/grassaddons/gui/gism.py =================================================================== --- trunk/grassaddons/gui/gism.py 2007-03-25 06:09:22 UTC (rev 294) +++ trunk/grassaddons/gui/gism.py 2007-03-25 06:10:16 UTC (rev 295) @@ -1,565 +0,0 @@ -#!/usr/bin/env python -""" -Classes: -* GRasterDialog -* GMFrame -* SetVal -* GMApp -""" -import sys -import os -import wx -import wx.combo -import wx.lib.customtreectrl as CT -import wx.lib.flatnotebook as FN -import wx.stc -import wx.richtext - -import sys, os, time, traceback, types - -import wx # This module uses the new wx namespace -import wx.html - -import images - -# try: -# import subprocess -#except: -# from compat import subprocess - -import Gism -gmpath = Gism.__path__[0] -sys.path.append(gmpath) - -import Gism.track as track -import Gism.gismutils as gismutils -import Gism.mapdisp as mapdisp -import Gism.render as render -import Gism.menudata as menudata -import Gism.menuform as menuform -import Gism.grassenv as grassevn - -"""Main Python app to set up GIS Manager window and trap commands -Only command console is working currently, but windows for -panels and layer tree done and demo tree items appear""" - -########################################################################## -# -# gism.py - wxPython prototype GUI for GRASS 6+ -# -# Authors: Michael Barton (Arizona State University) & -# Jachym Cepicky (Mendel University of Agriculture) -# -# August 2006 -# -# COPYRIGHT: (C) 1999 - 2006 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. -# -########################################################################## - -menucmd = {} - -class GRasterDialog(wx.Frame): - def __init__(self,parent,id=-1,title="Set raster layer"): - wx.Frame.__init__(self, parent, id , title, size=(50,600)) - - # sizers - sizer = wx.BoxSizer(wx.VERTICAL) - buttsizer = wx.BoxSizer(wx.HORIZONTAL) - - # 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") - - # checkboxes - cboverlay = wx.CheckBox(self, -1, "Overlay (non-null values)") - cboverlay.SetValue(True) - - # text entries - tmapname = wx.TextCtrl(self,-1,size=(-1,-1)) - tvalues = wx.TextCtrl(self,-1,size=(-1,-1)) - - # 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) - - 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() - - -class GMFrame(wx.Frame): - '''GIS Manager frame with notebook widget for controlling - 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, title): - self.parent = parent - wx.Frame.__init__(self, parent=parent, id=-1, title=title, style=wx.DEFAULT_FRAME_STYLE) - - # creating widgets - self.notebook = self.__createNoteBook() - self.cmdinput = self.__createCommandInput() - self.menubar = self.__createMenuBar() - toolbar = self.__createToolBar() - #self.panel = wx.Panel(self,-1, style= wx.EXPAND) - self.sizer= wx.BoxSizer(wx.VERTICAL) - self.cmdsizer = wx.BoxSizer(wx.HORIZONTAL) - - # do layout - self.SetTitle(_("GRASS GIS Manager - wxPython Prototype")) - self.SetMinSize((450, 450)) - # self.nb_panel = wx.Panel(self) - - # initialize variables - self.mapdisplays = {} #dictionary to index open map displays - self.disp_idx = 0 #index value for map displays and layer trees - self.maptree = {} #dictionary to index a layer tree to accompanying a map display - self.mapfocus = 0 #track which display currently has focus - - self.Bind(wx.EVT_CLOSE, self.onCloseWindow) - self.Bind(wx.EVT_LEFT_DOWN, self.addRaster) - - # item, proportion, flag, border, userData - self.sizer.Add(self.notebook, proportion=1, flag=wx.EXPAND, border=1) - self.sizer.Add(self.cmdinput, proportion=0, flag=wx.EXPAND, border=1) - self.SetSizer(self.sizer) - self.sizer.Fit(self) - self.Layout() - wx.CallAfter(self.notebook.SetSelection, 0) - - # start default initial display - self.newDisplay() - - def __createCommandInput(self): - """Creates command input area""" - #l = wx.StaticText(self, -1, "GRASS> ") - - self.cmdinput = wx.TextCtrl(self, id=wx.ID_ANY, value="", style=wx.HSCROLL|wx.TE_LINEWRAP| - wx.TE_PROCESS_ENTER) - - #self.cmdinput.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "Monospace")) - wx.CallAfter(self.cmdinput.SetInsertionPoint, 0) - - #self.cmdsizer.Add(l,0,wx.ADJUST_MINSIZE | wx.ALIGN_CENTER_VERTICAL, 1) - #self.cmdsizer.Add(self.cmdinput, 0, wx.EXPAND, 0) - - self.Bind(wx.EVT_TEXT_ENTER, self.runCmd, self.cmdinput) - - return self.cmdinput - - def __createMenuBar(self): - """Creates menubar""" - - self.menubar = wx.MenuBar() - menud = menudata.Data() - for eachMenuData in menud.GetMenu(): - for eachHeading in eachMenuData: - menuLabel = eachHeading[0] - menuItems = eachHeading[1] - self.menubar.Append(self.__createMenu(menuItems), menuLabel) - self.SetMenuBar(self.menubar) - - return self.menubar - - def __createMenu(self, menuData): - """Cretes menu""" - - menu = wx.Menu() - for eachItem in menuData: - if len(eachItem) == 2: - label = eachItem[0] - subMenu = self.__createMenu(eachItem[1]) - menu.AppendMenu(wx.NewId(), label, subMenu) - else: - self.__createMenuItem(menu, *eachItem) - return menu - - def __createMenuItem(self, menu, label, help, handler, gcmd, kind=wx.ITEM_NORMAL): - """Creates menu items""" - - if not label: - menu.AppendSeparator() - return - menuItem = menu.Append(-1, label, help, kind) - if label: - menucmd[label] = gcmd - rhandler = eval(handler) - self.Bind(wx.EVT_MENU, rhandler, menuItem) - - def __createNoteBook(self): - """Creates notebook widgets""" - - # create main notebook widget - #bookStyle=FN.FNB_DEFAULT_STYLE #| FN.FNB_FANCY_TABS - #bookStyle=FN.FNB_DEFAULT_STYLE|FN.FNB_BOTTOM|FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS - nbStyle=FN.FNB_FANCY_TABS|FN.FNB_BOTTOM|FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS - self.notebook = FN.FlatNotebook(self, id=wx.ID_ANY, style=nbStyle) - - # create displays notebook widget and add it to main notebook page - cbStyle=FN.FNB_VC8|FN.FNB_BACKGROUND_GRADIENT|FN.FNB_X_ON_TAB|FN.FNB_TABS_BORDER_SIMPLE - #self.cb_panel = wx.Panel(self,-1, style = wx.EXPAND) - self.gm_cb = FN.FlatNotebook(self, id=wx.ID_ANY, style=cbStyle) - self.gm_cb.SetTabAreaColour(wx.Colour(125,200,175)) - self.notebook.AddPage(self.gm_cb, text="Map layers for each display") - - # create command output text area and add it to main notebook page - #self.outpanel = wx.Panel(self,-1, style = wx.EXPAND) - self.goutput = gismutils.GMConsole(self) - #self.goutput = wx.richtext.RichTextCtrl(self,style=wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER) - self.outpage = self.notebook.AddPage(self.goutput, text="Command output") - - self.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.onCBPageChanged, self.gm_cb) - self.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.onCBPageClosed, self.gm_cb) - - self.out_sizer = wx.BoxSizer(wx.VERTICAL) - self.out_sizer.Add(self.goutput, proportion=1, flag=wx.EXPAND, border=1) - self.SetSizer(self.out_sizer) - #self.out_sizer.Fit(self.outpage) - #self.outpage.Layout() - - self.Centre() - return self.notebook - - - # choicebook methods - def onCBPageChanged(self, event): - """Page in notebook changed""" - - old_pgnum = event.GetOldSelection() - new_pgnum = event.GetSelection() - curr_pg = self.gm_cb.GetCurrentPage() - sel_pgnum = self.gm_cb.GetSelection() - - # get ID of associated display if more than one - disp_idx = track.Track().GetDisp_idx(curr_pg) - if disp_idx != None: - #get associated display and make it active - newdisp = track.Track().GetCtrls(disp_idx, 0) - newdisp.SetFocus() - newdisp.Raise() - event.Skip() - - def onCBPageClosed(self, event): - """Page of notebook closed""" - - curr_pg = self.gm_cb.GetCurrentPage() - disp_idx = track.Track().GetDisp_idx(curr_pg) - if disp_idx != None: - #get associated display and make it active - disp = track.Track().GetCtrls(disp_idx, 0) - try: - if self.mapdisplays.has_key(disp_idx): - if self.mapdisplays[disp_idx].Close(False): - self.mapdisplays[disp_idx].Close(True) - except: - pass - - def runCmd(self,event): - """Run command""" - - #global gmpath - cmd = self.cmdinput.GetValue() - - self.goutput.runCmd(cmd) - #menuform.GUI().parseCommand(cmd, gmpath) - - def runMenuCmd(self, event): - """Run menu command""" - - menuitem = self.menubar.FindItemById(event.GetId()) - itemtext = menuitem.GetText() - cmd = menucmd[itemtext] - global gmpath - menuform.GUI().parseCommand(cmd,gmpath, parentframe=self) - - def __createToolBar(self): - """Creates toolbar""" - - toolbar = self.CreateToolBar() - for each in self.toolbarData(): - self.addToolbarButton(toolbar, *each) - toolbar.Realize() - - def addToolbarButton(self, toolbar, label, icon, help, handler): - """Adds button to the given toolbar""" - - if not label: - toolbar.AddSeparator() - return - tool = toolbar.AddLabelTool(id=wx.ID_ANY, label=label, bitmap=icon, shortHelp=help) - self.Bind(wx.EVT_TOOL, handler, tool) - - def toolbarData(self): - - return ( - ('newdisplay', wx.Bitmap(os.path.join(gismutils.icons,'gui-startmon.gif'), wx.BITMAP_TYPE_ANY), 'Start new display', self.newDisplay), - ('', '', '', ''), - ('addrast', wx.Bitmap(os.path.join(gismutils.icons,'element-cell.gif'), wx.BITMAP_TYPE_ANY), 'Add raster layer', self.onRaster), - ('addvect', wx.Bitmap(os.path.join(gismutils.icons,'element-vector.gif'), wx.BITMAP_TYPE_ANY), 'Add vector layer', self.onVector), - ('addcmd', wx.Bitmap(os.path.join(gismutils.icons,'gui-cmd.gif'), wx.BITMAP_TYPE_ANY), 'Add command layer', self.addCommand), - ('delcmd', wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_TOOLBAR, (16,16)), 'Delete selected layer', self.deleteLayer), - ) - - def addToolbarCombo(self, toolbar, indx, type): - tbcb = wx.combo.BitmapComboBox(toolbar, pos=(25,25), size=(100,-1), style=wx.TE_PROCESS_ENTER) - self.comboItems(tbcb, type) - toolbar.InsertControl(indx, tbcb) - toolbar.Realize() - - self.Bind(wx.EVT_COMBOBOX, self.onCombo, tbcb) - self.Bind(wx.EVT_TEXT_ENTER, self.onCombo, tbcb) - - def onCombo(self, event): - bcb = event.GetEventObject() - idx = event.GetInt() - st = bcb.GetString(idx) - cd = bcb.GetClientData(idx) - if 'Add raster map' in st: - self.addRaster() - elif 'Add RGB' in st: - self.addRGB() - elif 'Add raster legend' in st: - self.addRastLeg() - elif 'Add vector map' in st: - self.addVector() - elif 'Add thematic map' in st: - self.addThemeMap() - elif 'Add thematic chart' in st: - self.addThemeChart() - -# self.log.write("EVT_COMBOBOX: Id %d, string '%s', clientData '%s'" % (idx, st, cd)) - evt.Skip() - - - def newDisplay(self, event=None): - """Create new map display frame""" - - newdisp = self.mapdisplays[self.disp_idx] = mapdisp.MapFrame(self, - id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, - style=wx.DEFAULT_FRAME_STYLE, - cb=self.gm_cb, idx=self.disp_idx) - # title - newdisp.SetTitle(_("Map Display " + str(self.disp_idx))) - #self.maptree[self.disp_idx] = self.mapdisplays[self.disp_idx].getTree() - - #add notebook page to GIS Manager - - # make a new page in the bookcontrol for the layer tree (on page 0 of the notebook) - self.pg_panel = wx.Panel(self.gm_cb, id=wx.ID_ANY, style= wx.EXPAND) - self.gm_cb.AddPage(self.pg_panel, text="Display "+ str(self.disp_idx), select = True) - self.cb_page = self.gm_cb.GetCurrentPage() - - # create layer tree (tree control for managing GIS layers) and put on new notebook page - self.maptree = gismutils.LayerTree(self.cb_page, id=wx.ID_ANY, pos=wx.DefaultPosition, - size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS - |wx.TR_LINES_AT_ROOT|wx.TR_EDIT_LABELS|wx.TR_HIDE_ROOT - |wx.TR_DEFAULT_STYLE|wx.NO_BORDER|wx.FULL_REPAINT_ON_RESIZE, - disp=newdisp) - - # layout for controls - cb_boxsizer = wx.BoxSizer(wx.VERTICAL) - cb_boxsizer.Add(self.maptree, proportion=1, flag=wx.EXPAND, border=1) - self.cb_page.SetSizer(cb_boxsizer) - cb_boxsizer.Fit(self.cb_page) - self.cb_page.Layout() - #self.cb_page.SetAutoLayout(True) - #self.Centre() - - # store information about display and associated controls in a dictionary in track.py - track.Track().SetDisp(self.disp_idx,self) - track.Track().SetCtrlDict(self.disp_idx, newdisp, self.cb_page, self.maptree) - - #show new display - self.mapdisplays[self.disp_idx].Show() - self.mapdisplays[self.disp_idx].Refresh() - self.mapdisplays[self.disp_idx].Update() - - self.disp_idx += 1 - - # toolBar button handlers - def onRaster(self, event): - """Add raster item menu""" - point = wx.GetMousePosition() - rastmenu = wx.Menu() - # Add items to the menu - addrast = wx.MenuItem(rastmenu, -1,'Add raster map layer') - bmp = wx.Image(os.path.join(gismutils.icons,'element-cell.gif'), wx.BITMAP_TYPE_GIF) - bmp.Rescale(16, 16) - bmp = bmp.ConvertToBitmap() - addrast.SetBitmap(bmp) - rastmenu.AppendItem(addrast) - self.Bind(wx.EVT_MENU, self.addRaster, addrast) - - addrgb = wx.MenuItem(rastmenu, -1,'Add RGB layer') - bmp = wx.Image(os.path.join(gismutils.icons,'module-d.rgb.gif'), wx.BITMAP_TYPE_GIF) - bmp.Rescale(16, 16) - bmp = bmp.ConvertToBitmap() - addrgb.SetBitmap(bmp) - rastmenu.AppendItem(addrgb) - self.Bind(wx.EVT_MENU, self.addRGB, addrgb) - - addhis = wx.MenuItem(rastmenu, -1,'Add HIS layer') - bmp = wx.Image(os.path.join(gismutils.icons,'channel-his.gif'), wx.BITMAP_TYPE_GIF) - bmp.Rescale(16, 16) - bmp = bmp.ConvertToBitmap() - addhis.SetBitmap(bmp) - rastmenu.AppendItem(addhis) - self.Bind(wx.EVT_MENU, self.addHIS, addhis) - - addrleg = wx.MenuItem(rastmenu, -1,'Add raster legend layer') - bmp = wx.Image(os.path.join(gismutils.icons,'module-d.legend.gif'), wx.BITMAP_TYPE_GIF) - bmp.Rescale(16, 16) - bmp = bmp.ConvertToBitmap() - addrleg.SetBitmap(bmp) - rastmenu.AppendItem(addrleg) - self.Bind(wx.EVT_MENU, self.addRastLeg, addrleg) - - # Popup the menu. If an item is selected then its handler - # will be called before PopupMenu returns. - self.PopupMenu(rastmenu) - rastmenu.Destroy() - - def onVector(self, event): - """Add raster item menu""" - point = wx.GetMousePosition() - vectmenu = wx.Menu() - - addvect = wx.MenuItem(vectmenu, -1,'Add vector map layer') - bmp = wx.Image(os.path.join(gismutils.icons,'element-vector.gif'), wx.BITMAP_TYPE_GIF) - bmp.Rescale(16, 16) - bmp = bmp.ConvertToBitmap() - addvect.SetBitmap(bmp) - vectmenu.AppendItem(addvect) - self.Bind(wx.EVT_MENU, self.addVector, addvect) - - addtheme = wx.MenuItem(vectmenu, -1,'Add thematic map layer') - bmp = wx.Image(os.path.join(gismutils.icons,'module-d.vect.thematic.gif'), wx.BITMAP_TYPE_GIF) - bmp.Rescale(16, 16) - bmp = bmp.ConvertToBitmap() - addtheme.SetBitmap(bmp) - vectmenu.AppendItem(addtheme) - self.Bind(wx.EVT_MENU, self.addThemeMap, addtheme) - - addchart = wx.MenuItem(vectmenu, -1,'Add thematic chart layer') - bmp = wx.Image(os.path.join(gismutils.icons,'module-d.vect.chart.gif'), wx.BITMAP_TYPE_GIF) - bmp.Rescale(16, 16) - bmp = bmp.ConvertToBitmap() - addchart.SetBitmap(bmp) - vectmenu.AppendItem(addchart) - self.Bind(wx.EVT_MENU, self.addThemeChart, addchart) - # Popup the menu. If an item is selected then its handler - # will be called before PopupMenu returns. - self.PopupMenu(vectmenu) - vectmenu.Destroy() - - def addRaster(self, event): - self.SetTree('raster') - - def addRGB(self, event): - """Add RGB layer""" - self.SetTree('rgb') - - def addHIS(self, event): - """Add HIS layer""" - self.SetTree('his') - - def addRastLeg(self, event): - """Add raster legend""" - self.SetTree('rastleg') - - def addVector(self, event): - """Add vector layer""" - self.SetTree('vector') - - def addThemeMap(self, event): - """Add thematic map layer""" - self.SetTree('thememap') - - def addThemeChart(self, event): - """Add thematic chart layer""" - self.SetTree('themechart') - - def addCommand(self, event): - """Add command line layer""" - self.SetTree('command') - - def GetSelectedDisplay(self): - return self.notebook.GetSelection() - - def SetTree(self, layertype): - """ - Add map display layer in GIS Manager tree widget - """ - disp_idx = track.Track().GetDisp_idx(self.maptree) - if disp_idx != None: - self.maptree.AddLayer(disp_idx, layertype) - - def deleteLayer(self, event): - """ - Delete selected map display layer in GIS Manager tree widget - """ - self.maptree.Delete(self.maptree.GetSelection()) - - #Misc methods - def onCloseWindow(self, event): - '''Cleanup when gism.py is quit''' - mdlist = range(0, self.disp_idx+1) - try: - for md in mdlist: - if self.mapdisplays.has_key(md): - if self.mapdisplays[md].Close(False): - self.mapdisplays[md].Close(True) - except: - self.DestroyChildren() - self.Destroy() - - def Nomethod(self, event): - '''Stub for testing''' - pass - event.Skip() - -class GMApp(wx.App): - """ - GMApp class - """ - def OnInit(self): -## reexec_with_pythonw() - # initialize all available image handlers - wx.InitAllImageHandlers() - # create and show main frame - mainframe = GMFrame(None, -1, "") - self.SetTopWindow(mainframe) - mainframe.Show() - return 1 - -def reexec_with_pythonw(): - 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:]) - - -if __name__ == "__main__": - - reexec_with_pythonw() - - import gettext - gettext.install("GMApp") # replace with the appropriate catalog name - app = GMApp(0) - app.MainLoop() Deleted: trunk/grassaddons/gui/grass_wizard.py =================================================================== --- trunk/grassaddons/gui/grass_wizard.py 2007-03-25 06:09:22 UTC (rev 294) +++ trunk/grassaddons/gui/grass_wizard.py 2007-03-25 06:10:16 UTC (rev 295) @@ -1,1290 +0,0 @@ -import wx -import wx.wizard as wiz -import wx.lib.rcsizer as rcs -from wx.lib.combotreebox import ComboTreeBox - -import os -import sys -import string -import re - - -class TitledPage(wiz.WizardPageSimple): - def __init__(self, parent, title): - wiz.WizardPageSimple.__init__(self, parent) - - self.title = wx.StaticText(self,-1,title) - self.title.SetFont(wx.Font(13, wx.SWISS, wx.NORMAL, wx.BOLD)) - - self.sizer = rcs.RowColSizer() - tmpsizer = wx.BoxSizer(wx.VERTICAL) - - tmpsizer.Add(self.title, 0, wx.ALIGN_CENTRE|wx.ALL, 5) - tmpsizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0) - tmpsizer.Add(self.sizer, wx.EXPAND) - - self.SetSizer(tmpsizer) - self.SetAutoLayout(True) - - def MakeLabel(self, text=""): - try: - if text[-1] != " ": - text += " " - except: - pass - return wx.StaticText(self, -1, text, style=wx.ALIGN_RIGHT) - - def MakeTextCtrl(self,text='', size=(100,-1)): - return wx.TextCtrl(self,-1, text, size=size) - - def MakeButton(self,text, size=(75,25)): - return wx.Button(self, -1, text, - style=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, - size=size) - - -class DatumPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Specify geodetic datum") - - self.parent = parent - - # text input - self.tdatum = self.MakeTextCtrl("", size=(200,-1)) - self.ttrans = self.MakeTextCtrl("", size=(200,-1)) - - # search box - self.searchb = wx.SearchCtrl(self, size=(200,-1), - style=wx.TE_PROCESS_ENTER) - - # button - self.bupdate = self.MakeButton("Update trans. parms.", - size=(-1,-1)) - - # table - self.tablewidth=675 - - # create list control for datum/elipsoid list - self.datumlist = wx.ListCtrl(self, id=wx.ID_ANY, - size=(675,150), - style=wx.LC_REPORT | - wx.LC_VRULES | - wx.LC_HRULES | - wx.EXPAND) - self.datumlist.InsertColumn(0, 'Short Name') - self.datumlist.InsertColumn(1, 'Full EPSG-style name') - self.datumlist.InsertColumn(2, 'Ellipsoid') - self.datumlist.InsertColumn(3, 'Parameters') - self.datumlist.SetColumnWidth(0, 100) - self.datumlist.SetColumnWidth(1, 225) - self.datumlist.SetColumnWidth(2, 100) - self.datumlist.SetColumnWidth(3, 250) - - # create list control for datum transformation parameters list - self.transformlist = wx.ListCtrl(self, id=wx.ID_ANY, - size=(675,125), - style=wx.LC_REPORT | - wx.LC_VRULES | - wx.LC_HRULES | - wx.EXPAND) - self.transformlist.InsertColumn(0, 'ID') - self.transformlist.InsertColumn(1, 'Country') - self.transformlist.InsertColumn(2, 'Description ') - self.transformlist.InsertColumn(3, 'Parameters') - self.transformlist.SetColumnWidth(0, 50) - self.transformlist.SetColumnWidth(1, 125) - self.transformlist.SetColumnWidth(2, 250) - self.transformlist.SetColumnWidth(3, 250) - - # layout - self.sizer.Add(self.MakeLabel("Geodetic datum:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, col=1, row=1) - self.sizer.Add(self.tdatum, 0 , - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=2) - self.sizer.Add(self.bupdate, 0 , - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=3) - self.sizer.Add(self.MakeLabel("Search in description:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, col=1, row=2) - self.sizer.Add(self.searchb, 0 , - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=2, col=2) - - self.sizer.Add(self.datumlist, 0 , - wx.EXPAND | - wx.ALIGN_LEFT | - wx.ALL, 5, row=3, col=1, colspan=5) - - self.sizer.Add(self.MakeLabel("Transformation parameters:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, col=1, row=5) - self.sizer.Add(self.ttrans, 0 , - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=5, col=2) - - self.sizer.Add(self.transformlist, 0 , - wx.EXPAND | - wx.ALIGN_LEFT | - wx.ALL, 5, row=6, col=1, colspan=5) - - # events - #wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) - #wx.EVT_BUTTON(self, self.bbcodes.GetId(), self.OnBrowseCodes) - self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.datumlist) - self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTransformSelected, self.transformlist) - self.bupdate.Bind(wx.EVT_BUTTON, self._onBrowseParams) - self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) - self.tdatum.Bind(wx.EVT_TEXT_ENTER, self._onBrowseParams, self.tdatum) - - self._onBrowseDatums(None,None) - self.datumlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) - self.datumlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) - self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) - self.datumlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) - - def OnDoSearch(self,event): - str = self.searchb.GetValue() - listItem = self.datumlist.GetColumn(1) - - for i in range(self.datumlist.GetItemCount()): - listItem = self.datumlist.GetItem(i,1) - if listItem.GetText().find(str) > -1: - datumcode = self.datumlist.GetItem(i, 0) - self.tdatum.SetValue(datumcode.GetText()) - break - - self._onBrowseDatums(None,str) - - def OnTransformSelected(self,event): - item = event.GetItem() - self.ttrans.SetValue(str(item.GetText())) - - def OnItemSelected(self,event): - item = event.GetItem() - self.tdatum.SetValue(str(item.GetText())) - self._onBrowseParams() - - def _onBrowseParams(self, event=None): - params = [["","Use whole region",""]] - file = os.path.join(os.getenv("GISBASE"), "etc","datumtransform.table") - search = self.tdatum.GetValue() - - try: - f = open(file,"r") - rex=re.compile('^(.+)\s+"(.+)"\s+"(.+)"\s+"(.+)"') - for line in f.readlines(): - line = line.strip() - if line[0] == "#": continue - id,parm,country,descr = rex.findall(line)[0] - id=id.strip() - parm=parm.strip() - country = country.strip() - descr=descr.strip() - if id == search: - params.append([parm,country,descr]) - f.close() - - self.transformlist.DeleteAllItems() - for i in range(len(params)): - # fill datum transformation parameters list control - index = self.transformlist.InsertStringItem(i,str(i+1)) - dtp1 = self.transformlist.SetStringItem(index,1,params[i][1]) - dtp2 = self.transformlist.SetStringItem(index,2,params[i][2]) - dtp3 = self.transformlist.SetStringItem(index,3,params[i][0]) - # format list control columns - if index != '': - self.transformlist.SetColumnWidth(0, wx.LIST_AUTOSIZE) - else: - self.transformlist.SetColumnWidth(0, 30) - if dtp1 != '': - self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE) - else: - self.transformlist.SetColumnWidth(1, 150) - if dtp2 != '': - self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) - else: - self.transformlist.SetColumnWidth(2, 250) - if dtp3 != '': - self.transformlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) - else: - self.transformlist.SetColumnWidth(3, 320) - - except IOError, e: - self.transformlist.DeleteAllItems() - dlg = wx.MessageDialog(self, "Could not read datum params: %s " - % e,"Can not read file", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - - - def _onBrowseDatums(self,event,search=None): - try: - self.datumlist.DeleteAllItems() - f = open(os.path.join(os.getenv("GISBASE"), "etc","datum.table"),"r") - # shortname "Full EPSG-style name" ellipsoid dx= dy= dz= - rex=re.compile('^(.+)\s+"(.+)"\s+(.+)\s+(dx=.+)') - j=0 - for line in f.readlines(): - line = line.strip() - if not line: continue - if line[0] == "#": continue - shortname, epsgname, ellps, params = rex.findall(line)[0] - params = params.strip() - ellps = ellps.strip() - if search and (shortname.lower().find(search.lower()) > -1 or\ - ellps.lower().find(search.lower()) > -1 or\ - epsgname.lower().find(search.lower()) > -1) or\ - not search: - index = self.datumlist.InsertStringItem(j,shortname) - self.datumlist.SetStringItem(index,1,epsgname) - self.datumlist.SetStringItem(index,2,ellps) - self.datumlist.SetStringItem(index,3,params) - j += 1 - f.close() - self.datumlist.SendSizeEvent() - except IOError, e: - dlg = wx.MessageDialog(self, "Could not read datums: %s " - % e,"Can not read file", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - - def OnChange(self,event): - self.item = event.GetItem() - -class SummaryPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Summary") - - self.parent = parent - - self.sizer.Add(self.MakeLabel("GRASS database:"), 1, flag=wx.ALIGN_RIGHT, row=1, col=2) - self.sizer.Add(self.MakeLabel("Location name:"), 1, flag=wx.ALIGN_RIGHT, row=2, col=2) - self.sizer.Add((200,20), 1, flag=wx.ALIGN_CENTER_HORIZONTAL, row=4, col=2) - self.sizer.Add(self.MakeLabel("Projection:"), 1, flag=wx.ALIGN_RIGHT, row=5, col=2) - self.sizer.Add(self.MakeLabel("North:"), 1, flag=wx.ALIGN_RIGHT, row=6, col=2) - self.sizer.Add(self.MakeLabel("South:"), 1, flag=wx.ALIGN_RIGHT, row=7, col=2) - self.sizer.Add(self.MakeLabel("East:"), 1, flag=wx.ALIGN_RIGHT, row=8, col=2) - self.sizer.Add(self.MakeLabel("West:"), 1, flag=wx.ALIGN_RIGHT, row=9, col=2) - self.sizer.Add(self.MakeLabel("Resolution:"), 1, flag=wx.ALIGN_RIGHT, row=10, col=2) - self.sizer.Add(self.MakeLabel("Rows:"), 1, flag=wx.ALIGN_RIGHT, row=12, col=2) - self.sizer.Add(self.MakeLabel("Columns:"), 1, flag=wx.ALIGN_RIGHT, row=13, col=2) - self.sizer.Add(self.MakeLabel("Cells:"), 1, flag=wx.ALIGN_RIGHT, row=14, col=2) - - # labels - self.ldatabase = self.MakeLabel("") - self.llocation = self.MakeLabel("") - self.lprojection = self.MakeLabel("") - self.lnorth = self.MakeLabel("") - self.lsouth = self.MakeLabel("") - self.least = self.MakeLabel("") - self.lwest = self.MakeLabel("") - self.lres = self.MakeLabel("") - self.lrows = self.MakeLabel("") - self.lcols = self.MakeLabel("") - self.lcells = self.MakeLabel("") - - self.sizer.Add(self.ldatabase, 1, flag=wx.ALIGN_LEFT, row=1, col=3) - self.sizer.Add(self.llocation, 1, flag=wx.ALIGN_LEFT, row=4, col=3) - self.sizer.Add(self.lprojection, 1, flag=wx.ALIGN_LEFT, row=5, col=3) - self.sizer.Add(self.lnorth, 1, flag=wx.ALIGN_LEFT, row=6, col=3) - self.sizer.Add(self.lsouth, 1, flag=wx.ALIGN_LEFT, row=7, col=3) - self.sizer.Add(self.least, 1, flag=wx.ALIGN_LEFT, row=8, col=3) - self.sizer.Add(self.lwest, 1, flag=wx.ALIGN_LEFT, row=9, col=3) - self.sizer.Add(self.lres, 1, flag=wx.ALIGN_LEFT, row=10, col=3) - self.sizer.Add(self.lrows, 1, flag=wx.ALIGN_LEFT, row=12, col=3) - self.sizer.Add(self.lcols, 1, flag=wx.ALIGN_LEFT, row=13, col=3) - self.sizer.Add(self.lcells, 1, flag=wx.ALIGN_LEFT, row=14, col=3) - - def FillVars(self,event=None): - database = self.parent.startpage.tgisdbase.GetValue() - location = self.parent.startpage.tlocation.GetValue() - projection = self.parent.csystemspage.cs - #zoone = self.pages - north = self.parent.bboxpage.ttop.GetValue() - south = self.parent.bboxpage.tbottom.GetValue() - east = self.parent.bboxpage.tright.GetValue() - west = self.parent.bboxpage.tleft.GetValue() - res = self.parent.bboxpage.tres.GetValue() - #if projection != "latlong": - rows = int(round((float(north)-float(south))/float(res))) - cols = int(round((float(east)-float(west))/float(res))) - cells = int(rows*cols) - - self.ldatabase.SetLabel(database) - self.llocation.SetLabel(location) - self.lprojection.SetLabel(projection) - self.lnorth.SetLabel(north) - self.lsouth.SetLabel(south) - self.least.SetLabel(east) - self.lwest.SetLabel(west) - self.lres.SetLabel(res) - self.lrows.SetLabel(str(rows)) - self.lcols.SetLabel(str(cols)) - self.lcells.SetLabel(str(cells)) - - - -#projection: 99 (Other Projection) -#zone: 0 -# north: 344444 -# south: 3333 -# east: 3333333 -# west: 33333 -# -# e-w res: 30 -# n-s res: 30.00096746 (Changed to conform to grid) -# -#total rows: 11370 -#total cols: 110000 -#total cells: 1,250,700,000 -# -# -#Do you accept this region? (y/n) [n] > - - - # inputs - -class BBoxPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Set default region extents and resolution") - - self.parent = parent - # inputs - self.ttop = self.MakeTextCtrl("1", size=(150, -1)) - self.tbottom = self.MakeTextCtrl("0", size=(150, -1)) - self.tleft = self.MakeTextCtrl("0", size=(150, -1)) - self.tright = self.MakeTextCtrl("1", size=(150, -1)) - self.tres = self.MakeTextCtrl("1", size=(150, -1)) - - self.tgdal = self.MakeTextCtrl("", size=(250, -1)) - self.tdsn = self.MakeTextCtrl("", size=(250, -1)) - # list of layers - self.layers = [] - self.llayers = wx.ComboBox(self, -1, - choices=self.layers, - size=(250,-1), - style=wx.CB_DROPDOWN) - - # labels - self.lmessage = wx.StaticText(self,-1, "", size=(300,50)) - - # buttons - self.bbrowsegdal = self.MakeButton("Browse ...", size=(150,-1)) - self.bbrowseogr = self.MakeButton("Browse ...", size=(150,-1)) - self.bgetlayers = self.MakeButton("Get Layers", size=(150,-1)) - self.bset = self.MakeButton("Set coordinates", size=(150,-1)) - - # list of states - self.states = [] - self.coords = [] - try: - f = open(os.path.join(os.getenv("GISBASE"),"etc","wx","states.txt"),"r") - for line in f.readlines(): - if line[0] == "#": - continue - state,coord = line.split(";") - coord = coord.replace(","," ") - self.states.append(state) - self.coords.append(coord.split()) - f.close() - except: - pass - # NOTE: ComboCtcl should come here, but nobody knows, how to - # implement it - # self.stateslist = wx.ListCtrl(self, - # style=wx.LC_LIST|wx.LC_SINGLE_SEL|wx.SIMPLE_BORDER) - # self.cstate = wx.combo.ComboCtrl(self, -1, pos=(50, 170), size=(150, -1), - # style=wx.CB_READONLY) - - self.cstate = wx.ComboBox(self, -1, - size=(250,-1), - choices=self.states, - style=wx.CB_DROPDOWN) - - # layout - self.sizer.Add(self.MakeLabel("North"), 0, - wx.ALIGN_CENTER_HORIZONTAL | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 0, row=1,col=2) - self.sizer.Add(self.ttop, 0, - wx.ALIGN_CENTER_HORIZONTAL | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=2,col=2) - - self.sizer.Add(self.MakeLabel("West"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 0, row=3,col=0) - self.sizer.Add(self.tleft, 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=3,col=1) - - self.sizer.Add(self.tright, 0, - wx.ALIGN_CENTER_HORIZONTAL | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=3,col=3) - self.sizer.Add(self.MakeLabel("East"), 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 0, row=3,col=4) - - self.sizer.Add(self.tbottom, 0, - wx.ALIGN_CENTER_HORIZONTAL | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=4,col=2) - self.sizer.Add(self.MakeLabel("South"), 0, - wx.ALIGN_CENTER_HORIZONTAL | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 0, row=5,col=2) - - self.sizer.Add(self.MakeLabel("Initial resolution"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=6,col=1) - self.sizer.Add(self.tres, 0, - wx.ALIGN_CENTER_HORIZONTAL | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=6,col=2) - self.sizer.Add(self.bset, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=6, col=3 ) - - self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0, row=7, col=0, colspan=6) - - self.sizer.Add(self.MakeLabel("Match extents of georeferenced raster map or image"), 3, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=8,col=0, colspan=3) - - self.sizer.Add(self.MakeLabel("File:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=9,col=0, colspan=1) - self.sizer.Add(self.tgdal, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=9,col=1, colspan=2) - self.sizer.Add(self.bbrowsegdal, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=9,col=3) - - self.sizer.Add(wx.StaticLine(self, -1), 0, - wx.EXPAND|wx.ALL, 0, - row=10, col=0, colspan=6) - - self.sizer.Add(self.MakeLabel("Match extents of georeferenced vector map"), 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=11,col=0, colspan=3 ) - - self.sizer.Add(self.MakeLabel("Data source/directory:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=12,col=0, colspan=1) - self.sizer.Add(self.tdsn, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=12, col=1, colspan=2) - self.sizer.Add(self.bbrowseogr, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=12, col=3) - - self.sizer.Add(self.MakeLabel("Layer/file:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=13,col=0, colspan=1) - self.sizer.Add(self.llayers, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=13,col=1, colspan=2) - self.sizer.Add(self.bgetlayers, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=13,col=3) - - self.sizer.Add(wx.StaticLine(self, -1), 0, - wx.EXPAND|wx.ALL | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=14, col=0, colspan=6) - self.sizer.Add(self.MakeLabel("Match extents of selected country"), 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=15,col=0, colspan=3) - self.sizer.Add(self.cstate, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=16,col=1, colspan=2) - - self.sizer.Add(self.lmessage, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=17,col=1, colspan=3) - - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChange) - self.Bind(wx.EVT_COMBOBOX, self.OnItemSelected, self.cstate) - self.Bind(wx.EVT_TEXT, self.OnStateText, self.cstate) - self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset) - self.Bind(wx.EVT_BUTTON, self.OnBrowseGdal, self.bbrowsegdal) - self.Bind(wx.EVT_BUTTON, self.OnBrowseOGR, self.bbrowseogr) - self.Bind(wx.EVT_BUTTON, self.OnGetOGRLayers, self.bgetlayers) - - def OnBrowseGdal(self, event): - dlg = wx.FileDialog(self, "Choose a raster file:", os.getcwd(), "", "*.*", wx.OPEN) - path = "" - if dlg.ShowModal() == wx.ID_OK: - path = dlg.GetPath() - self.tgdal.SetValue(path) - dlg.Destroy() - - self.OnSetButton() - - def OnBrowseOGR(self, event): - dlg = wx.FileDialog(self, "Choose a data source name:", os.getcwd(), "", "*.*", wx.OPEN) - path = "" - if dlg.ShowModal() == wx.ID_OK: - path = dlg.GetPath() - self.tdsn.SetValue(path) - dlg.Destroy() - self.OnGetOGRLayers(None) - - def OnSetButton(self,event=None): - if self.tgdal.GetValue(): - self.__setGDAL() - if self.tdsn.GetValue() and self.llayers.GetSelection()>-1: - self.__setOGR() - elif self.cstate.GetSelection() > -1: - sys.stderr.write("##############"+str(self.cstate.GetSelection())+"\n") - self.OnItemSelected(None) - - def OnGetOGRLayers(self, event): - path = self.tdsn.GetValue() - line = "" - - sys.stderr.write(path+"####\n") - self.layers = [] - self.llayers.Clear() - cmd = os.popen("ogrinfo -so %s\n" % (path)) - line = cmd.readline() - # 1: cr (Polygon) - rex = re.compile("^(\d+):\s+(.+)\s+\(.*\)") - while 1: - if not line or line == "": - break - try: - sys.stderr.write("#####"+line+"####\n") - number, name = rex.findall(line)[0] - self.layers.append(name) - except: - pass - line = cmd.readline() - self.llayers.AppendItems(self.layers) - #sys.stderr.write(str( self.layers)+"\n") - #self.sizer.Remove(self.llayers) - #self.llayers = wx.ComboBox(self, -1, choices=self.layers, size=(100,-1), - # style=wx.CB_DROPDOWN) - #self.sizer.Add(self.llayers, 0, wx.ALIGN_CENTER_VERTICAL, row=12,col=3) - #self.sizer.ShowItems(True) - self.OnSetButton() - pass - - def __setOGR(self): - layer = self.layers[self.llayers.GetSelection()] - path = self.tdsn.GetValue() - number="-?\d+\.\d+" - line = "" - - #test values - self.ttop.SetValue(500) - self.tleft.SetValue(500) - - #Extent: (-146.976217, -55.985484) - (72.774632, 80.594358) - rex = re.compile("\((%s),\s*(%s)\)\s*-\s*\((%s),\s*(%s)\)" %(number, number, number, number)) - cmd = os.popen("ogrinfo -so %s %s" % (path ,layer)) - line = cmd.readline() - while 1: - if not line or line == "": - break - sys.stderr.write(line+"\n") - if line.find("Extent")>-1: - sys.stderr.write(line[0]+"#####\n") - x1,y1,x2,y2 = rex.findall(line)[0] - self.tbottom.SetValue(y1) - self.tleft.SetValue(x1) - self.ttop.SetValue(y2) - self.tright.SetValue(x2) - break - line = cmd.readline() - return - - def __setGDAL(self): - path = self.tgdal.GetValue() - line = "" - number="-?\d+\.\d+" - - #test values - self.ttop.SetValue(500) - self.tleft.SetValue(500) - - # Upper Left ( 0.0, 0.0) - rex=re.compile("\(\s*(%s)\s*,\s*(%s)\)" % (number, number)) - obj = os.popen("gdalinfo %s | grep \"Upper\|Lower\"" % path) - - line = obj.readline() - while 1: - sys.stderr.write(line+"\n") - if not line: - break - if line.find("Upper Left")>-1: - x,y = rex.findall(line)[0] - self.ttop.SetValue(y) - self.tleft.SetValue(x) - if line.find("Lower Right")>-1: - x,y = rex.findall(line)[0] - self.tbottom.SetValue(y) - self.tright.SetValue(x) - line = obj.readline() - return - - def OnStateText(self,event): - item = self.llayers.FindString(event.GetString()) - self.llayers.SetSelection(item) - self.llayers.SetValue(self.llayers.GetStringSelection()) - pass - #.log.WriteText('EvtTextEnter: %s' % event.GetString()) - #sys.stderr.write(event.GetString()+"\n") - #text=event.GetString().lower() - #for idx in range(len(self.states)): - # if self.states[idx].lower() == text: - # self.cstate.Select(idx) - # break - - def OnWizPageChange(self, event): - self.GetNext().FillVars() - - def OnItemSelected(self, event): - item = self.cstate.GetSelection() - w,s,e,n = self.coords[item] - # 4 - # 1 3 - # 2 - - if self.parent.csystemspage.cs == "latlong": - pass - if self.parent.csystemspage.cs == "xy": - pass - else: - if self.parent.csystemspage.cs == "epsg": - to="+init=epsg:%d" % (int(self.parent.epsgpage.tcode.GetValue())) - elif self.parent.csystemspage.cs == "custom": - to="+proj=%s" % (self.parent.projpage.tproj.GetValue()) - elif self.parent.csystemspage.cs == "utm": - to="+proj=utm" - else: - sys.stderr.write(self.parent.csystemspage.cs+"\n") - - try: - sin, sout = os.popen2("cs2cs +proj=latlong +datum=WGS84 +to %s" % (to)) - sin.write("%s %s\n" % (w,s)) - sin.write("%s %s\n" % (e,n)) - sin.close() - w,s,t = sout.readline().split() - e,n,t = sout.readline().split() - self.lmessage.SetLabel("") - except: - n = s = w = e="NULL" - self.lmessage.SetLabel("Unable to calculate country extends:\n cs2cs +proj=latlong +datum=WGS84 +to %s"% to) - - self.ttop.SetValue( str(n) ) - self.tbottom.SetValue( str(s) ) - self.tright.SetValue( str(e) ) - self.tleft.SetValue( str(w) ) - -class ProjectionsPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Choose projection name") - - self.parent = parent - # text input - self.tproj = self.MakeTextCtrl("", size=(200,-1)) - - # search box - self.searchb = wx.SearchCtrl(self, size=(200,-1), - style=wx.TE_PROCESS_ENTER) - - # table - self.tablewidth=675 - self.list = wx.ListCtrl(self, id=wx.ID_ANY, - size=(675,275), - style=wx.LC_REPORT | - wx.LC_VRULES | - wx.LC_HRULES | - wx.EXPAND) - self.list.InsertColumn(0, 'Name') - self.list.InsertColumn(1, 'Description') - self.list.SetColumnWidth(0, 100) - self.list.SetColumnWidth(1, 575) - - # layout - self.sizer.Add(self.MakeLabel("Projection name:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=2) - self.sizer.Add(self.tproj, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=3) - - self.sizer.Add(self.MakeLabel("Search in projection description"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=2, col=2) - self.sizer.Add(self.searchb, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=2, col=3) - - self.sizer.Add(self.list, - wx.EXPAND | - wx.ALIGN_LEFT | - wx.ALL, 5, row=3, col=1, colspan=4) - - # events - self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) - self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) - - self._onBrowseDatums(None, None) - - self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE) - self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE) - - def OnDoSearch(self,event): - str = self.searchb.GetValue() - listItem = self.list.GetColumn(1) - - for i in range(self.list.GetItemCount()): - listItem = self.list.GetItem(i,1) - if listItem.GetText().find(str) > -1: - datumcode = self.list.GetItem(i, 0) - self.tproj.SetValue(datumcode.GetText()) - break - - self._onBrowseDatums(None,str) - - - def OnItemSelected(self,event): - item = event.GetItem() - self.tproj.SetValue(str(item.GetText())) - - - def _onBrowseDatums(self,event,search=None): - try: - self.list.DeleteAllItems() - f = open(os.path.join(os.getenv("GISBASE"), "etc","projections"),"r") - i=1 - j = 0 - descr = None - proj = None - for line in f.readlines(): - line = line.strip() - if not line: - continue - if line[0] == "#": - continue - proj,descr = string.split(line, ":", maxsplit=1) - if search and (descr.lower().find(search.lower()) > -1 or\ - proj.lower().find(search.lower()) > -1) or\ - not search: - self.list.InsertStringItem(j,proj) - self.list.SetStringItem(j,1,descr) - j += 1 - # reset - descr = None; proj = "" - f.close() - self.SendSizeEvent() - except StandardError, e: - dlg = wx.MessageDialog(self, "Could not read datums: %s " - % e,"Can not read file", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - - def OnChange(self,event): - self.item = event.GetItem() - - - -class GeoreferencedFilePage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Select georeferenced file") - - # create controls - self.lfile= wx.StaticText(self, -1, "Georeferenced file: ", - style=wx.ALIGN_RIGHT) - self.tfile = wx.TextCtrl(self,-1, "", size=(150,-1)) - self.bbrowse = self.MakeButton("Browse ...") - - # do layout - self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | - wx.ALIGN_CENTRE_VERTICAL | - wx.ALL, 5, row=1, col=2) - self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTRE_VERTICAL | - wx.ALL, 5, row=1, col=3) - self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | - wx.ALL, 5, row=1, col=4) - - wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) - - def OnBrowse(self, event): - - dlg = wx.FileDialog(self, "Choose a georeferenced file:", os.getcwd(), "", "*.*", wx.OPEN) - if dlg.ShowModal() == wx.ID_OK: - path = dlg.GetPath() - self.tfile.SetValue(path) - dlg.Destroy() - - def OnCreate(self, event): - pass - # if not os.path.isfile(self.tfile.GetValue()): - # dlg = wx.MessageDialog(self, "Could not create new location: %s not file" - # % self.tfile.GetValue(),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - - # if not self.tname.GetValue(): - # dlg = wx.MessageDialog(self, "Could not create new location: name not set", - # "Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - - # if os.path.isdir(os.path.join(self.parent.gisdbase,self.tname.GetValue())): - # dlg = wx.MessageDialog(self, "Could not create new location: %s exists" - # % os.path.join(self.parent.gisdbase,self.tname.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - - # # creating location - # # all credit to Michael Barton and his file_option.tcl and - # # Markus Neteler - # try: - # # FIXME: this does not need to work on windows - # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) - - # self.parent.OnSetDatabase(None) - # self.Destroy() - - # except StandardError, e: - # dlg = wx.MessageDialog(self, "Could not create new location: %s " - # % str(e),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - -class EPSGPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Choose EPSG Code") - - # labels - self.lfile= wx.StaticText(self, -1, "Path to the EPSG-codes file: ", - style=wx.ALIGN_RIGHT) - self.lcode= wx.StaticText(self, -1, "EPSG code: ", - style=wx.ALIGN_RIGHT) - self.lsearch= wx.StaticText(self, -1, "Search in code description: ", - style=wx.ALIGN_RIGHT) - - # text input - epsgdir = os.path.join(os.environ["GRASS_PROJSHARE"], 'epsg') - self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,-1)) - self.tcode = wx.TextCtrl(self,-1, "", size=(200,-1)) - - # buttons - self.bbrowse = wx.Button(self, -1, "Browse ...", size=(100,-1)) - self.bbcodes = wx.Button(self, -1, "Browse Codes") - - # search box - self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) - - # table - self.tablewidth=675 - self.epsgs = wx.ListCtrl(self, id=wx.ID_ANY, - size=(675,275), - style=wx.LC_REPORT| - wx.LC_HRULES| - wx.EXPAND) - self.epsgs.InsertColumn(0, 'EPSG', wx.LIST_FORMAT_CENTRE) - self.epsgs.InsertColumn(1, 'Description', wx.LIST_FORMAT_LEFT) - self.epsgs.InsertColumn(2, 'Parameters', wx.LIST_FORMAT_LEFT) - self.epsgs.SetColumnWidth(0, 50) - self.epsgs.SetColumnWidth(1, 300) - self.epsgs.SetColumnWidth(2, 325) - - # layout - self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, col=1, row=1) - self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=2) - self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=1, col=3) - - self.sizer.Add(self.lcode, 0, wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, col=1, row=2) - self.sizer.Add(self.tcode, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=2, col=2) - - self.sizer.Add(self.lsearch, 0, wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, col=1, row=3) - self.sizer.Add(self.searchb, 0, wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=3, col=2) - self.sizer.Add(self.bbcodes, 0 , wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, row=3, col=3) - - self.sizer.Add(self.epsgs, wx.ALIGN_LEFT|wx.EXPAND, 0, row=4, col=1, colspan=5) - - # events - wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) - wx.EVT_BUTTON(self, self.bbcodes.GetId(), self.OnBrowseCodes) - self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.epsgs) - self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) - - def OnDoSearch(self,event): - str = self.searchb.GetValue() - listItem = self.epsgs.GetColumn(1) - - for i in range(self.epsgs.GetItemCount()): - listItem = self.epsgs.GetItem(i,1) - if listItem.GetText().find(str) > -1: - epsgcode = self.epsgs.GetItem(i, 0) - self.tcode.SetValue(epsgcode.GetText()) - break - - self.OnBrowseCodes(None,str) - - - def OnBrowse(self, event): - - dlg = wx.FileDialog(self, "Choose a georeferenced file:", - "/", "", "*.*", wx.OPEN) - if dlg.ShowModal() == wx.ID_OK: - path = dlg.GetPath() - self.tfile.SetValue(path) - dlg.Destroy() - - def OnItemSelected(self,event): - item = event.GetItem() - self.tcode.SetValue(str(item.GetText())) - - - def OnBrowseCodes(self,event,search=None): - try: - self.epsgs.DeleteAllItems() - f = open(self.tfile.GetValue(),"r") - i=1 - j = 0 - descr = None - code = None - params = "" - #self.epsgs.ClearAll() - for line in f.readlines(): - line = line.strip() - if line.find("#") == 0: - descr = line[1:].strip() - elif line.find("<") == 0: - code = line.split(" ")[0] - for par in line.split(" ")[1:]: - params += par + " " - code = code[1:-1] - if code == None: code = 'no code' - if descr == None: descr = 'no description' - if params == None: params = 'no parameters' - if i%2 == 0: - if search and descr.lower().find(search.lower()) > -1 or\ - not search: - index = self.epsgs.InsertStringItem(j, code) - self.epsgs.SetStringItem(index, 1, descr) - self.epsgs.SetStringItem(index, 2, params) - j += 1 - # reset - descr = None; code = None; params = "" -# if i%2 == 0: -# self.epsgs.SetItemBackgroundColour(i, "grey") - i += 1 - f.close() - self.epsgs.SetColumnWidth(1, wx.LIST_AUTOSIZE) - self.epsgs.SetColumnWidth(2, wx.LIST_AUTOSIZE) - self.SendSizeEvent() - except StandardError, e: - dlg = wx.MessageDialog(self, "Could not read EPGS codes: %s " - % e,"Can not read file", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - - def OnChange(self,event): - self.item = event.GetItem() - - #def OnCreate(self, event): - # if not self.tcode.GetValue(): - # dlg = wx.MessageDialog(self, "Could not create new location: EPSG Code value missing", - # "Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - # - # number = -1 - # try: - # number = int(self.tcode.GetValue()) - # except: - # dlg = wx.MessageDialog(self, "Could not create new location: '%s' not a number" % self.tcode.GetValue(), - # "Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - # - # if os.path.isdir(os.path.join(self.parent.gisdbase,self.tname.GetValue())): - # dlg = wx.MessageDialog(self, "Could not create new location: %s exists" - # % os.path.join(self.parent.gisdbase,self.tname.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - # - # # creating location - # # all credit to Michael Barton and his file_option.tcl and - # # Markus Neteler - # try: - # # FIXME: this does not need to work on windows - # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) - # datumtrans = os.popen(" g.proj epsg=%d datumtrans=-1 >&2" % (number)).readlines() - - # if datumtrans: - # #os.system(" g.proj epsg=%d datumtrans=%s >&2" % (number,datumtrans[0]).readlines() - # pass - # else: - # os.system("g.proj -c epsg=%d location=%s datumtrans=1" % (number, self.tname.GetValue())) - - # self.parent.OnSetDatabase(None) - # self.Destroy() - - # except StandardError, e: - # dlg = wx.MessageDialog(self, "Could not create new location: %s " - # % str(e),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - - - def OnDoubleClick(self, event): - print self.epsgs.GetValue() - pass - - -class CoordinateSystemPage(TitledPage): - def __init__(self, wizard, parent): - TitledPage.__init__(self, wizard, "Choose coordinate system for location") - - self.parent = parent - self.cs = "xy" - - # toggles - self.radio1 = wx.RadioButton( self, -1, " XY ", style = wx.RB_GROUP ) - self.radio2 = wx.RadioButton( self, -1, " Lat/Long " ) - self.radio3 = wx.RadioButton( self, -1, " UTM " ) - self.radio4 = wx.RadioButton( self, -1, " Custom " ) - self.radio5 = wx.RadioButton( self, -1, " EPSG " ) - self.radio6 = wx.RadioButton( self, -1, " Based on Georeferenced file " ) - - # layout - self.sizer.Add(self.radio1, 0, wx.ALIGN_LEFT, row=1, col=2) - self.sizer.Add(self.radio2, 0, wx.ALIGN_LEFT, row=2, col=2) - self.sizer.Add(self.radio3, 0, wx.ALIGN_LEFT, row=3, col=2) - self.sizer.Add(self.radio4, 0, wx.ALIGN_LEFT, row=4, col=2) - self.sizer.Add(self.radio5, 0, wx.ALIGN_LEFT, row=5, col=2) - self.sizer.Add(self.radio6, 0, wx.ALIGN_LEFT, row=6, col=2) - - # bindings - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio3.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio4.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio5.GetId()) - self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio6.GetId()) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChange) - - def SetVal(self,event): - if event.GetId() == self.radio1.GetId(): - self.cs = "xy" - self.SetNext(self.parent.bboxpage) - self.parent.bboxpage.cstate.Enable(False) - elif event.GetId() == self.radio2.GetId(): - self.cs = "latlong" - self.SetNext(self.parent.datumpage) - self.parent.datumpage.SetPrev(self.parent.csystemspage) - self.parent.bboxpage.SetPrev(self.parent.datumpage) - elif event.GetId() == self.radio3.GetId(): - self.cs = "utm" - self.SetNext(self.parent.datumpage) - self.parent.datumpage.SetPrev(self.parent.csystemspage) - self.parent.bboxpage.SetPrev(self.parent.datumpage) - elif event.GetId() == self.radio4.GetId(): - self.cs = "custom" - self.SetNext(self.parent.projpage) - self.parent.datumpage.SetPrev(self.parent.projpage) - self.parent.bboxpage.SetPrev(self.parent.datumpage) - elif event.GetId() == self.radio5.GetId(): - self.cs = "epsg" - self.SetNext(self.parent.epsgpage) - self.parent.datumpage.SetPrev(self.parent.epsgpage) - self.parent.bboxpage.SetPrev(self.parent.datumpage) - elif event.GetId() == self.radio6.GetId(): - self.SetNext(self.parent.filepage) - self.cs = "file" - - def OnWizPageChange(self,event=None): - if self.cs == "xy": - self.parent.bboxpage.cstate.Enable(False) - else: - self.parent.bboxpage.cstate.Enable(True) - pass - - -class DatabasePage(TitledPage): - def __init__(self, wizard, parent, grassdatabase): - TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name") - - # buttons - self.bbrowse = self.MakeButton("Browse ...", size=wx.DefaultSize) - - # text controls - self.tgisdbase = self.MakeTextCtrl(grassdatabase, size=(300, -1)) - self.tlocation = self.MakeTextCtrl("newLocation", size=(300, -1)) - - # layout - self.sizer.Add(self.MakeLabel("GIS Data Directory:"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=1, col=2) - self.sizer.Add(self.tgisdbase,0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=1, col=3) - self.sizer.Add(self.bbrowse, 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=1, col=4) - # - self.sizer.Add(self.MakeLabel("Project Location"), 0, - wx.ALIGN_RIGHT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=2, col=2) - self.sizer.Add(self.tlocation,0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=2, col=3) - self.sizer.Add(self.MakeLabel("(projection/coordinate system)"), 0, - wx.ALIGN_LEFT | - wx.ALIGN_CENTER_VERTICAL | - wx.ALL, 5, - row=2, col=4) - - # bindings - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChanging) - - def OnWizPageChanging(self,event=None): - if os.path.isdir(os.path.join(self.tgisdbase.GetValue(),self.tlocation.GetValue())): - dlg = wx.MessageDialog(self, "Could not create new location: <%s> directory exists "\ - % str(self.tlocation.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - event.Veto() - return - - if not self.tlocation.GetValue(): - dlg = wx.MessageDialog(self, "Could not create new location: not set "\ - ,"Can not create location", wx.OK|wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - event.Veto() - return - - self.location = self.tlocation.GetValue() - self.grassdatabase = self.tgisdbase.GetValue() - - def OnWizPageChange(self,event=None): - self.grassdatabase = self.tgisdbase.GetValue() - self.location = self.tlocation.GetValue() - - -class GWizard: - def __init__(self, parent, grassdatabase): - wizbmp = wx.Image(os.path.join(os.getenv("GISBASE"),"etc","wx","Gism","grasslogo_small.gif"), wx.BITMAP_TYPE_GIF) - wizbmp.Rescale(50,60) - wizbmp = wizbmp.ConvertToBitmap() - wizard = wiz.Wizard(parent, -1, "Define new Location", - bitmap=wizbmp) - self.startpage = DatabasePage(wizard, self, grassdatabase) - self.csystemspage = CoordinateSystemPage(wizard, self) - self.epsgpage = EPSGPage(wizard, self) - self.bboxpage = BBoxPage(wizard, self) - self.filepage = GeoreferencedFilePage(wizard, self) - self.projpage = ProjectionsPage(wizard, self) - self.sumpage = SummaryPage(wizard, self) - self.datumpage = DatumPage(wizard, self) - - # Set the initial order of the pages - self.startpage.SetNext(self.csystemspage) - - self.csystemspage.SetPrev(self.startpage) - self.csystemspage.SetNext(self.bboxpage) - - self.epsgpage.SetNext(self.datumpage) - self.epsgpage.SetPrev(self.csystemspage) - - self.projpage.SetNext(self.datumpage) - self.projpage.SetPrev(self.csystemspage) - - self.filepage.SetPrev(self.csystemspage) - - self.datumpage.SetNext(self.bboxpage) - - self.bboxpage.SetPrev(self.csystemspage) - self.bboxpage.SetNext(self.sumpage) - - self.sumpage.SetPrev(self.bboxpage) - - wizard.FitToPage(self.bboxpage) - wizard.RunWizard(self.startpage) - wizard.Destroy() - -if __name__ == "__main__": - gWizard = GWizard(None, "") - GRASSStartUp = GWizard.StartUp(0) - GRASSStartUp.MainLoop() - #app.MainLoop() From barton at grass.itc.it Sun Mar 25 08:16:21 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:16:22 2007 Subject: [grass-addons] r296 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250616.l2P6GLCC021606@grass.itc.it> Author: barton Date: 2007-03-25 08:16:07 +0200 (Sun, 25 Mar 2007) New Revision: 296 Added: trunk/grassaddons/gui/gui_modules/__init__.py Removed: trunk/grassaddons/gui/Gism/__init__.py Log: Moving things from wx/Gism to wx/gui_modules Deleted: trunk/grassaddons/gui/Gism/__init__.py =================================================================== --- trunk/grassaddons/gui/Gism/__init__.py 2007-03-25 06:10:16 UTC (rev 295) +++ trunk/grassaddons/gui/Gism/__init__.py 2007-03-25 06:16:07 UTC (rev 296) @@ -1,7 +0,0 @@ -all = ["gismutils", - "mapdisp", - "render", - "menudata", - "menuform", - "select", - ] Copied: trunk/grassaddons/gui/gui_modules/__init__.py (from rev 295, trunk/grassaddons/gui/Gism/__init__.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/__init__.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/__init__.py 2007-03-25 06:16:07 UTC (rev 296) @@ -0,0 +1,7 @@ +all = ["gismutils", + "mapdisp", + "render", + "menudata", + "menuform", + "select", + ] From barton at grass.itc.it Sun Mar 25 08:24:47 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:24:48 2007 Subject: [grass-addons] r297 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250624.l2P6OlFc021654@grass.itc.it> Author: barton Date: 2007-03-25 08:24:33 +0200 (Sun, 25 Mar 2007) New Revision: 297 Added: trunk/grassaddons/gui/gui_modules/cmd.py Removed: trunk/grassaddons/gui/Gism/cmd.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/cmd.py =================================================================== --- trunk/grassaddons/gui/Gism/cmd.py 2007-03-25 06:16:07 UTC (rev 296) +++ trunk/grassaddons/gui/Gism/cmd.py 2007-03-25 06:24:33 UTC (rev 297) @@ -1,101 +0,0 @@ -import grassenv -import os -class EndOfCommand(Exception): - def __str__(self): - return "End of command" - -class Command: - def __init__ (self,cmd,stdin=None,verbose=False): - self.module_stdout = None - self.module_stdin = None - self.cmd = cmd - self.line = None - - - os.environ["GRASS_MESSAGE_FORMAT"] = "gui" - (self.module_stdin, self.module_stdout, self.module_stderr) = os.popen3(self.cmd) - os.environ["GRASS_MESSAGE_FORMAT"] = "text" - - if stdin: - self.module_stdin.write(stdin) - self.module_stdin.close() - - if not verbose: - self.RunS() - - def Run(self): - """ - run command verbosely - - Returns: (msgtype, content) - - Usage: - cmd = Command("d.rast elevation.dem") - try: - (msgtype,content) = cmd.RunV() - while 1: - if msgtype == "GRASS_INFO_PERCENT": - print "Percent done: %d" % (int(content)) - else: - print "General message:", content - (msgtype,content) = cmd.RunV() - except EndOfCommand: - print "end" - """ - msgtype = None - cont = None - line = None - - line = self.module_stderr.readline() - while 1: - if not line: - raise EndOfCommand() - if line.find(':') > -1: - break - line = self.module_stderr.readline() - msgtype, cont = line.split(":") - - cont=cont.strip() - return (msgtype,cont.strip()) - - def RunS(self): - """ - run command silently - - Returns: - None if OK - Usage: - cmd = Command("d.rast elevation.dem") - if cmd.RunS(): - print "ERRRROR" - - FIXME: maybe use os.system instead? - """ - - line = self.module_stderr.readline() - while 1: - if not line: - break - line =self.module_stderr.readline() - return - -if __name__ == "__main__": - print "Running d.rast" - cmd=Command("d.rast elevation.dem") - try: - (msgtype,content) = cmd.RunV() - while 1: - if msgtype == "GRASS_INFO_PERCENT": - print "Percent done: %d" % (int(content)) - else: - print "General message:", content - (msgtype,content) = cmd.RunV() - except EndOfCommand: - print "konec" - - print "Running v.net.path for 0 593527.6875 4925297.0625 602083.875 4917545.8125" - cmd=Command("v.net.path in=roads out=tmp --o", "0 593527.6875 4925297.0625 602083.875 4917545.8125") - cmd.RunS() - print "Running d.vect tmp" - cmd = Command("d.vect tmp") - cmd.RunS() Copied: trunk/grassaddons/gui/gui_modules/cmd.py (from rev 296, trunk/grassaddons/gui/Gism/cmd.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/cmd.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/cmd.py 2007-03-25 06:24:33 UTC (rev 297) @@ -0,0 +1,101 @@ +import grassenv +import os +class EndOfCommand(Exception): + def __str__(self): + return "End of command" + +class Command: + def __init__ (self,cmd,stdin=None,verbose=False): + self.module_stdout = None + self.module_stdin = None + self.cmd = cmd + self.line = None + + + os.environ["GRASS_MESSAGE_FORMAT"] = "gui" + (self.module_stdin, self.module_stdout, self.module_stderr) = os.popen3(self.cmd) + os.environ["GRASS_MESSAGE_FORMAT"] = "text" + + if stdin: + self.module_stdin.write(stdin) + self.module_stdin.close() + + if not verbose: + self.RunS() + + def Run(self): + """ + run command verbosely + + Returns: (msgtype, content) + + Usage: + cmd = Command("d.rast elevation.dem") + try: + (msgtype,content) = cmd.RunV() + while 1: + if msgtype == "GRASS_INFO_PERCENT": + print "Percent done: %d" % (int(content)) + else: + print "General message:", content + (msgtype,content) = cmd.RunV() + except EndOfCommand: + print "end" + """ + msgtype = None + cont = None + line = None + + line = self.module_stderr.readline() + while 1: + if not line: + raise EndOfCommand() + if line.find(':') > -1: + break + line = self.module_stderr.readline() + msgtype, cont = line.split(":") + + cont=cont.strip() + return (msgtype,cont.strip()) + + def RunS(self): + """ + run command silently + + Returns: + None if OK + Usage: + cmd = Command("d.rast elevation.dem") + if cmd.RunS(): + print "ERRRROR" + + FIXME: maybe use os.system instead? + """ + + line = self.module_stderr.readline() + while 1: + if not line: + break + line =self.module_stderr.readline() + return + +if __name__ == "__main__": + print "Running d.rast" + cmd=Command("d.rast elevation.dem") + try: + (msgtype,content) = cmd.RunV() + while 1: + if msgtype == "GRASS_INFO_PERCENT": + print "Percent done: %d" % (int(content)) + else: + print "General message:", content + (msgtype,content) = cmd.RunV() + except EndOfCommand: + print "konec" + + print "Running v.net.path for 0 593527.6875 4925297.0625 602083.875 4917545.8125" + cmd=Command("v.net.path in=roads out=tmp --o", "0 593527.6875 4925297.0625 602083.875 4917545.8125") + cmd.RunS() + print "Running d.vect tmp" + cmd = Command("d.vect tmp") + cmd.RunS() From barton at grass.itc.it Sun Mar 25 08:25:28 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:25:29 2007 Subject: [grass-addons] r298 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250625.l2P6PSb5021675@grass.itc.it> Author: barton Date: 2007-03-25 08:25:14 +0200 (Sun, 25 Mar 2007) New Revision: 298 Added: trunk/grassaddons/gui/gui_modules/grass-interface.dtd Removed: trunk/grassaddons/gui/Gism/grass-interface.dtd Log: Moving items Deleted: trunk/grassaddons/gui/Gism/grass-interface.dtd =================================================================== --- trunk/grassaddons/gui/Gism/grass-interface.dtd 2007-03-25 06:24:33 UTC (rev 297) +++ trunk/grassaddons/gui/Gism/grass-interface.dtd 2007-03-25 06:25:14 UTC (rev 298) @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Copied: trunk/grassaddons/gui/gui_modules/grass-interface.dtd (from rev 297, trunk/grassaddons/gui/Gism/grass-interface.dtd) =================================================================== --- trunk/grassaddons/gui/gui_modules/grass-interface.dtd (rev 0) +++ trunk/grassaddons/gui/gui_modules/grass-interface.dtd 2007-03-25 06:25:14 UTC (rev 298) @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From barton at grass.itc.it Sun Mar 25 08:25:54 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:25:55 2007 Subject: [grass-addons] r299 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250625.l2P6PsKT021695@grass.itc.it> Author: barton Date: 2007-03-25 08:25:39 +0200 (Sun, 25 Mar 2007) New Revision: 299 Added: trunk/grassaddons/gui/gui_modules/grassenv.py Removed: trunk/grassaddons/gui/Gism/grassenv.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/grassenv.py =================================================================== --- trunk/grassaddons/gui/Gism/grassenv.py 2007-03-25 06:25:14 UTC (rev 298) +++ trunk/grassaddons/gui/Gism/grassenv.py 2007-03-25 06:25:39 UTC (rev 299) @@ -1,43 +0,0 @@ -import os - -env={} - -class NotInGRASSSession(Exception): - def __str__(self): - return "You must be in running GRASS session" - -class CouldNotStartMonitor(Exception): - def __init__(self,monitor): - self.monitor = monitor - - def __str__(self): - return "Could not start GRASS monitor <%s>" % self.monitor - -class CouldNotStopMonitor(Exception): - def __init__(self,monitor): - self.monitor = monitor - - def __str__(self): - return "Could not start GRASS monitor <%s>" % self.monitor - -class CouldNotExecute(Exception): - def __init__(self,command): - self.command = command - def __str__(self): - return "Could not execute GRASS command: %s" % self.command - - -if not os.getenv("GISBASE"): - raise NotInGRASSSession() -else: - env["GISBASE"] = os.getenv("GISBASE") - env["GIS_LOCK"] = os.getenv("GIS_LOCK") - env["GISRC"] = os.getenv("GISRC") - -for key in os.environ.keys(): - if key.find("GRASS") > -1: - env[key] = os.getenv(key) - -for line in os.popen("g.gisenv").readlines(): - key,val = line.strip().split("=") - env[key] = val Copied: trunk/grassaddons/gui/gui_modules/grassenv.py (from rev 298, trunk/grassaddons/gui/Gism/grassenv.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/grassenv.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/grassenv.py 2007-03-25 06:25:39 UTC (rev 299) @@ -0,0 +1,43 @@ +import os + +env={} + +class NotInGRASSSession(Exception): + def __str__(self): + return "You must be in running GRASS session" + +class CouldNotStartMonitor(Exception): + def __init__(self,monitor): + self.monitor = monitor + + def __str__(self): + return "Could not start GRASS monitor <%s>" % self.monitor + +class CouldNotStopMonitor(Exception): + def __init__(self,monitor): + self.monitor = monitor + + def __str__(self): + return "Could not start GRASS monitor <%s>" % self.monitor + +class CouldNotExecute(Exception): + def __init__(self,command): + self.command = command + def __str__(self): + return "Could not execute GRASS command: %s" % self.command + + +if not os.getenv("GISBASE"): + raise NotInGRASSSession() +else: + env["GISBASE"] = os.getenv("GISBASE") + env["GIS_LOCK"] = os.getenv("GIS_LOCK") + env["GISRC"] = os.getenv("GISRC") + +for key in os.environ.keys(): + if key.find("GRASS") > -1: + env[key] = os.getenv(key) + +for line in os.popen("g.gisenv").readlines(): + key,val = line.strip().split("=") + env[key] = val From barton at grass.itc.it Sun Mar 25 08:26:28 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:26:30 2007 Subject: [grass-addons] r300 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250626.l2P6QSoT021715@grass.itc.it> Author: barton Date: 2007-03-25 08:26:05 +0200 (Sun, 25 Mar 2007) New Revision: 300 Added: trunk/grassaddons/gui/gui_modules/mapdisp.py Removed: trunk/grassaddons/gui/Gism/mapdisp.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/mapdisp.py =================================================================== --- trunk/grassaddons/gui/Gism/mapdisp.py 2007-03-25 06:25:39 UTC (rev 299) +++ trunk/grassaddons/gui/Gism/mapdisp.py 2007-03-25 06:26:05 UTC (rev 300) @@ -1,804 +0,0 @@ -""" -To be used either from GIS Manager or as p.mon backend - -Usage: - mapdisp.py /path/to/command/file - -mapdisp Package - -Classes: -* BufferedWindow -* DrawWindow -* MapFrame -* MapApp -""" - - -# Authors: Michael Barton and Jachym Cepicky -# COPYRIGHT: (C) 1999 - 2006 by the GRASS Development Team -# Double buffered drawing concepts from the wxPython Cookbook - -import wx -import wx.aui -import os, sys, time, glob - -import render -import toolbars -import grassenv -import track - -Map = render.Map() # instance of Map class to render GRASS display output to PPM file -DEBUG = False - -# for cmdline -from threading import Thread -import time -cmdfilename = None - -class Command(Thread): - """ - Creates thread, which will observe the command file and see, if there - is new command to be executed - """ - def __init__ (self,parent,Map): - Thread.__init__(self) - - global cmdfilename - - self.parent = parent - self.map = Map # - self.cmdfile = open(cmdfilename,"r") - - def run(self): - """ - Run this in thread - """ - dispcmd = [] - while 1: - self.parent.redraw = False - line = self.cmdfile.readline().strip() - if line == "quit": - break - - if line: - try: - #oper, lname, mapset, catlist, vallist, invert, opacity - # 0 1 2 3 4 5 6 - dispcmd = list(line.strip().split()) - #print dispcmd - if dispcmd[0]=="addraster": - try: mapset = eval(dispcmd[2]) - except: pass - try: catlist = eval(dispcmd[3]) - except: pass - try: vallist = eval(dispcmd[4]) - except: pass - try: invert = eval(dispcmd[5]) - except: pass - opacity = float(dispcmd[6]) - - self.map.AddRasterLayer(name="%s" % (dispcmd[1]), - mapset=dispcmd[2], vallist=vallist, - l_opacity=opacity) - - if dispcmd[0]=="addvector": - self.map.AddVectorLayer(name="%s" % (dispcmd[1]), - mapset=dispcmd[2]) - self.parent.redraw =True - except Exception, e: - print "Command Thread: ",e - pass - - time.sleep(0.1) - - sys.exit() - -class BufferedWindow(wx.Window): - """ - A Buffered window class. - - To use it, subclass it and define a Draw(DC) method that takes a DC - to draw to. In that method, put the code needed to draw the picture - you want. The window will automatically be double buffered, and the - screen will be automatically updated when a Paint event is received. - - When the drawing needs to change, you app needs to call the - UpdateMap() method. Since the drawing is stored in a bitmap, you - can also save the drawing to file by calling the - SaveToFile(self,file_name,file_type) method. - """ - - def __init__(self, parent, id, - pos = wx.DefaultPosition, - size = wx.DefaultSize, - style=wx.NO_FULL_REPAINT_ON_RESIZE): - - wx.Window.__init__(self, parent, id, pos, size, style) - self.parent = parent - - # - # Flags - # - self.render = True # re-render the map from GRASS or just redraw image - self.resize = False # indicates whether or not a resize event has taken place - self.dragimg = None # initialize variable for map panning - self.pen = None # pen for drawing zoom boxes, etc. - - # - # Event bindings - # - self.Bind(wx.EVT_PAINT, self.OnPaint) - self.Bind(wx.EVT_SIZE, self.OnSize) - self.Bind(wx.EVT_IDLE, self.OnIdle) - self.Bind(wx.EVT_MOTION, self.MouseActions) - self.Bind(wx.EVT_MOUSE_EVENTS, self.MouseActions) - - # - # Render output objects - # - self.mapfile = None # image file to be rendered - self.Img = "" # wx.Image object (self.mapfile) - - # - # mouse attributes like currently pressed buttons, position on - # the screen, begin and end of dragging, and type of drawing - # - self.mouse = { - 'l': False, - 'r': False, - 'm': False, - 'pos': [None, None], - 'begin': [0, 0], - 'end': [0, 0], - 'box': "point" - } - self.zoomtype = 1 # 1 zoom in, 0 no zoom, -1 zoom out - - # OnSize called to make sure the buffer is initialized. - # This might result in OnSize getting called twice on some - # platforms at initialization, but little harm done. - #!!! self.OnSize(None) - - def Draw(self, dc, img=None, dctype='image', coords='0,0'): - """ - Just here as a place holder. - This method should be over-ridden when sub-classed - """ - pass - - def OnPaint(self, event): - """ - All that is needed here is to draw the buffer to screen - """ - dc = wx.BufferedPaintDC(self, self._Buffer) - - def OnSize(self, event): - """ - The Buffer init is done here, to make sure the buffer is always - the same size as the Window - """ - - # set size of the input image - Map.width, Map.height = self.GetClientSize() - - # Make new off screen bitmap: this bitmap will always have the - # current drawing in it, so it can be used to save the image to - # a file, or whatever. - self._Buffer = wx.EmptyBitmap(Map.width, Map.height) - - # get the image to be rendered - self.Img = self.GetImage() - - # update map display - if self.Img and Map.width + Map.height > 0: # scale image during resize - self.Img = self.Img.Scale(Map.width, Map.height) - self.render = False - self.UpdateMap() - - # re-render image on idle - self.resize = True - - def OnIdle(self, event): - """ - Only re-render a compsite map image from GRASS during - idle time instead of multiple times during resizing. - """ - - if self.resize: - self.render = True - self.UpdateMap() - event.Skip() - - def SaveToFile(self, FileName, FileType): - """ - This will save the contents of the buffer - to the specified file. See the wx.Windows docs for - wx.Bitmap::SaveFile for the details - """ - self._Buffer.SaveFile(FileName, FileType) - - def UpdateMap(self, img=None): - """ - This would get called if the drawing needed to change, for whatever reason. - - The idea here is that the drawing is based on some data generated - elsewhere in the system. IF that data changes, the drawing needs to - be updated. - - """ - if self.render: - Map.width, Map.height = self.GetClientSize() - self.mapfile = Map.Render(force=self.render) - self.Img = self.GetImage() - self.resize = False - if not self.Img: return - dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - self.Draw(dc, self.Img) - else: - if not self.Img: return - dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - self.Draw(dc, self.Img) - self.resize = False - - def EraseMap(self): - """ - Erase the map display - """ - dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - self.Draw(dc, dctype='clear') - - def DragMap(self, moveto): - """ - Drag a bitmap image for panning. - """ - - dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - dc.SetBackground(wx.Brush("White")) - bitmap = wx.BitmapFromImage(self.Img) - self.dragimg = wx.DragImage(bitmap) - self.dragimg.BeginDrag((0, 0), self) - self.dragimg.GetImageRect(moveto) - self.dragimg.Move(moveto) - dc.Clear() - self.dragimg.DoDrawImage(dc, moveto) - self.dragimg.EndDrag() - ## self.dragimg.UpdateBackingFromWindow(dc, memdc, sourcerect,destrect) - - def MouseDraw(self): - """ - Mouse zoom rectangles and lines - """ - img = self.Img # composite map in background - dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - if self.mouse['box'] == "box": - mousecoords = [self.mouse['begin'][0], self.mouse['begin'][1], \ - self.mouse['end'][0] - self.mouse['begin'][0], \ - self.mouse['end'][1] - self.mouse['begin'][1]] - self.Draw(dc, img, dctype='box', coords=mousecoords) - elif self.mouse['box'] == "line": - mousecoords = [self.mouse['begin'][0], self.mouse['begin'][1], \ - self.mouse['end'][0] - self.mouse['begin'][0], \ - self.mouse['end'][1] - self.mouse['begin'][1]] - self.Draw(dc, img, dctype='line', coords=mousecoords) - - def MouseActions(self, event): - """ - Mouse motion and button click notifier - """ - wheel = event.GetWheelRotation() # +- int - # left mouse button pressed - if event.LeftDown(): - # start point of zoom box or drag - self.mouse['begin'] = event.GetPositionTuple()[:] - - # left mouse button released and not just a pointer - elif event.LeftUp(): - if self.mouse['box'] != "point": - # end point of zoom box or drag - self.mouse['end'] = event.GetPositionTuple()[:] - - # set region in zoom or pan - self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype) - - else: - # digitizing - if self.parent.digittoolbar: - if self.parent.digittoolbar.digitize == "point": - east,north= self.Pixel2Cell(self.mouse['end'][0],self.mouse['end'][1]) - self.parent.digittoolbar.AddPoint(east,north) - # redraw map - self.render=True - self.UpdateMap() - - # dragging or drawing box with left button - elif event.Dragging() and event.LeftIsDown: - currpos = event.GetPositionTuple()[:] - end = (currpos[0]-self.mouse['begin'][0], \ - currpos[1]-self.mouse['begin'][1]) - if self.mouse['box'] == 'drag': - self.DragMap(end) - else: - self.mouse['end'] = event.GetPositionTuple()[:] - self.MouseDraw() - - # zoom on mouse wheel - elif wheel != 0: - - # zoom 1/2 of the screen - begin = [Map.width/4, Map.height/4] - end = [Map.width - Map.width/4, - Map.height - Map.height/4] - - # store current mouse position - self.mouse['pos'] = event.GetPositionTuple()[:] - - def GetImage(self): - """ - Converts files to wx.Image - """ - if Map.mapfile and os.path.isfile(Map.mapfile) and \ - os.path.getsize(Map.mapfile): - self.Img = wx.Image(Map.mapfile, wx.BITMAP_TYPE_ANY) - else: - self.Img = None - return self.Img - - def Pixel2Cell(self, x, y): - """ - Calculates real word coordinates to image coordinates - - Input : x, y - Output: int x, int y - """ - newx = Map.region['w'] + x * Map.region["ewres"] - newy = Map.region['n'] - y * Map.region["nsres"] - return newx, newy - - - def Zoom(self, begin, end, zoomtype): - """ - Calculates new region while (un)zoom/pan-ing - """ - x1, y1, x2, y2 = begin[0], begin[1], end[0], end[1] - newreg = {} - - # threshold - too small squares do not make sense - # can only zoom to windows of > 10x10 screen pixels - if x2 > 10 and y2 > 10 and zoomtype != 0: - - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - # zoom in - if zoomtype > 0: - newreg['w'], newreg['n'] = self.Pixel2Cell(x1, y1) - newreg['e'], newreg['s'] = self.Pixel2Cell(x2, y2) - - # zoom out - elif zoomtype < 0: - newreg['w'], newreg['n'] = self.Pixel2Cell( - -x1*2, - -y1*2) - newreg['e'], newreg['s'] = self.Pixel2Cell( - Map.width+2*(Map.width-x2), - Map.height+2*(Map.height-y2)) - # pan - elif zoomtype == 0: - newreg['w'], newreg['n'] = self.Pixel2Cell( - x1-x2, - y1-y2) - newreg['e'], newreg['s'] = self.Pixel2Cell( - Map.width+x1-x2, - Map.height+y1-y2) - - # if new region has been calculated, set the values - if newreg : - Map.region['n'] = newreg['n'] - Map.region['s'] = newreg['s'] - Map.region['e'] = newreg['e'] - Map.region['w'] = newreg['w'] - -class DrawWindow(BufferedWindow): - """ - Drawing routine for double buffered drawing. Overwrites Draw method - in the BufferedWindow class - """ - def __init__(self, parent, id = wx.ID_ANY): - """ - """ - ## Any data the Draw() function needs must be initialized before - ## calling BufferedWindow.__init__, as it will call the Draw - ## function. - self.dcmd_list = [] # list of display commands to process - BufferedWindow.__init__(self, parent, id) - - def Draw(self, dc, img=None, dctype='image', coords=[0, 0]): - """ - Draws image, box and line in the background - """ - dc.BeginDrawing() - dc.SetBackground(wx.Brush(self.GetBackgroundColour())) - dc.Clear() # make sure you clear the bitmap! - - if dctype == 'clear': # erase the display - dc.EndDrawing() - return - bitmap = wx.BitmapFromImage(img) - dc.DrawBitmap(bitmap, 0, 0) # draw the composite map - - if dctype == 'box': # draw a box on top of the map - dc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) - dc.SetPen(self.pen) - dc.DrawRectangle(coords[0], coords[1], coords[2], coords[3]) - elif dctype == 'line': # draw a line on top of the map - dc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) - dc.SetPen(self.pen) - dc.DrawLine(coords[0], coords[1], coords[2], coords[3]) - - dc.EndDrawing() - -class MapFrame(wx.Frame): - """ - Main frame for map display window. Drawing takes place in child double buffered - drawing window. - """ - - def __init__(self, parent=None, id = wx.ID_ANY, title="Map display", - pos=wx.DefaultPosition, size=wx.DefaultSize, - style=wx.DEFAULT_FRAME_STYLE, toolbars=["map"], cb=None, idx=-1): - -# style=wx.DEFAULT_FRAME_STYLE, toolbars=["map"]): - - """ - Main map display window with toolbars, statusbar and - DrawWindow - - Parameters: - parent -- parent window, None, wx.Window() - id -- window ID, int, wx.NewId() - title -- window title, string - pos -- where to place it, tupple, wx.Position - size -- window size, tupple, wx.Size - style -- window style - toolbars-- array of default toolbars, which should appear - map, digit - """ - - wx.Frame.__init__(self, parent, id, title, pos, size, style) - - # - # Set the size - # - self.SetClientSize((600, 475)) - - # Set variables to associate display with GIS Manager page - self.ctrlbk = cb - self.disp_idx = idx - - # - # Fancy gui - # - self._mgr = wx.aui.AuiManager(self) - - # - # Add toolbars - # - self.maptoolbar = None - self.digittoolbar = None - for toolb in toolbars: - self.AddToolbar(toolb) - - # - # Add statusbar - # - self.statusbar = self.CreateStatusBar(number=2, style=0) - self.statusbar.SetStatusWidths([-2, -1]) - map_frame_statusbar_fields = ["Extent: %d,%d : %d,%d" % - (Map.region["n"], Map.region["s"], - Map.region["w"], Map.region["e"]), - "%s,%s" %(None, None)] - for i in range(len(map_frame_statusbar_fields)): - self.statusbar.SetStatusText(map_frame_statusbar_fields[i], i) - - - # - # Init map display - # - self.InitDisplay() # initialize region values - self.MapWindow = DrawWindow(self) # initialize buffered DC - self.MapWindow.Bind(wx.EVT_MOTION, self.OnMotion) - - - # - # Bind various events - # ONLY if we are running from GIS manager - # - if self.disp_idx > -1: - self.Bind(wx.EVT_ACTIVATE, self.OnFocus) - self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) - - # - # Update fancy gui style - # - self._mgr.AddPane(self.MapWindow, wx.CENTER) - self._mgr.Update() - - # - # Create dictionary of available cursors - # - self.cursors = { - "default" : wx.StockCursor (wx.CURSOR_DEFAULT), - "cross" : wx.StockCursor (wx.CURSOR_CROSS), - "hand" : wx.StockCursor (wx.CURSOR_HAND) - } - - def AddToolbar(self, name): - """ - Add defined toolbar to the window - - Currently known toolbars are: - * map - * digit - """ - if name == "map": - self.maptoolbar = toolbars.MapToolbar(self, Map) - self._mgr.AddPane(self.maptoolbar.toolbar, wx.aui.AuiPaneInfo(). - Name("maptoolbar").Caption("Map Toolbar"). - ToolbarPane().Top().LeftDockable(False).RightDockable(False). - BottomDockable(True).CloseButton(False)) - - if name == "digit": - self.digittoolbar = toolbars.DigitToolbar(self,Map) - self._mgr.AddPane(self.digittoolbar.toolbar, wx.aui.AuiPaneInfo(). - Name("digittoolbar").Caption("Digit Toolbar"). - ToolbarPane().Top().LeftDockable(False).RightDockable(False). - BottomDockable(True).CloseButton(False)) - self._mgr.Update() - - def InitDisplay(self): - """ - Initialize map display, set dimensions and map region - """ - self.width, self.height = self.GetClientSize() - Map.geom = self.width, self.height - Map.GetRegion() - #FIXME - #This was Map.getResolution(). - #I'm guessing at the moment that this is replaced by Map.SetRegion() - Map.SetRegion() - - def OnFocus(self, event): - """ - Store information about active display - in tracking variables and change choicebook - page to match display - """ - #get index number of active display - self.disp_idx = int(track.Track().GetDisp_idx(self)) - - #set active display tuple in track - track.Track().SetDisp(self.disp_idx, self) - - # change bookcontrol page to page associted with display if > 1 display - pg = track.Track().GetCtrls(self.disp_idx, 1) - pg_count = self.ctrlbk.GetPageCount() - pgnum = '0' - if pg_count > 0: - for x in range(0,pg_count): - if self.ctrlbk.GetPage(x) == pg: - pgnum = x - break - - self.ctrlbk.SetSelection(pgnum) - event.Skip() - - def SetDcommandList(self, clst): - self.MapWindow.dcmd_list = clst - self.MapWindow.ProcessDcommand() - self.MapWindow.UpdateMap() - - def OnMotion(self, event): - """ - Mouse moved - Track mouse motion and update status bar - """ - # store current mouse position - posx, posy = event.GetPositionTuple() - - - # upsdate coordinates - x, y = self.MapWindow.Pixel2Cell(posx, posy) - self.statusbar.SetStatusText("%d,%d" % (x, y), 1) - - event.Skip() - - def ReDraw(self, event): - """ - Redraw button clicked - """ - self.MapWindow.UpdateMap() - - def ReDrawCommand(self): - """ - d.* command on command line and enter pressed. - """ - self.MapWindow.UpdateMap() - - def Pointer(self, event): - """Pointer button clicled""" - self.MapWindow.mouse['box'] = "point" - - # change the cursor - self.MapWindow.SetCursor (self.cursors["default"]) - - def OnZoomIn(self, event): - """ - Zoom in the map. - Set mouse pointer and zoom direction - """ - self.MapWindow.mouse['box'] = "box" - self.MapWindow.zoomtype = 1 - self.MapWindow.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH) - - # change the cursor - self.MapWindow.SetCursor (self.cursors["cross"]) - - def OnZoomOut(self, event): - """ - Zoom out the map. - Set mouse pointer and zoom direction - """ - self.MapWindow.mouse['box'] = "box" - self.MapWindow.zoomtype = -1 - self.MapWindow.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH) - - # change the cursor - self.MapWindow.SetCursor (self.cursors["cross"]) - - def OnZoomBack(self, event): - """ - Zoom last (previously stored position) - """ - # FIXME - pass - - def OnPan(self, event): - """ - Panning, set mouse to drag - """ - self.MapWindow.mouse['box'] = "drag" - self.MapWindow.zoomtype = 0 - event.Skip() - - # change the cursor - self.MapWindow.SetCursor (self.cursors["hand"]) - - def OnErase(self, event): - """ - Erase the canvas - """ - self.MapWindow.EraseMap() - - def OnZoomRegion(self, event): - """ - Zoom to region - """ - Map.getRegion() - Map.getResolution() - self.draw(dc) - event.Skip() - - def OnAlignRegion(self, event): - """ - Align region - """ - if not Map.alignRegion: - Map.alignRegion = True - else: - Map.alignRegion = False - event.Skip() - - def SaveToFile(self, event): - """ - Save to file - """ - dlg = wx.FileDialog(self, "Choose a file name to save the image as a PNG to", - defaultDir = "", - defaultFile = "", - wildcard = "*.png", - style=wx.SAVE) - if dlg.ShowModal() == wx.ID_OK: - self.MapWindow.SaveToFile(dlg.GetPath(), wx.BITMAP_TYPE_PNG) - dlg.Destroy() - - def OnCloseWindow(self, event): - """ - Window closed - """ - Map.Clean() - self.Destroy() - - #close associated controls book page - #get index number of active display - self.disp_idx = track.Track().GetDisp_idx(self) - - # delete associated bookcontrol page if it exists - if self.disp_idx != None: - pg = track.Track().GetCtrls(self.disp_idx, 1) - pg_count = self.ctrlbk.GetPageCount() - pgnum = '0' - if pg_count > 0: - for x in range(0,pg_count): - if self.ctrlbk.GetPage(x) == pg: - pgnum = x - track.Track().popCtrl(self.disp_idx) - self.ctrlbk.DeletePage(pgnum) - - def getRender(self): - """ - returns the current instance of render.Map() - """ - return Map - -# end of class MapFrame - -class MapApp(wx.App): - """ - MapApp class - """ - - def OnInit(self): - wx.InitAllImageHandlers() - self.Mapfrm = MapFrame(parent=None, id=wx.ID_ANY) - #self.SetTopWindow(Map) - self.Mapfrm.Show() - - # only for testing purpose - if __name__ == "__main__": - - # redraw map, if new command appears - self.redraw = False - status = Command(self,Map) - status.start() - self.timer = wx.PyTimer(self.watcher) - # chec each 0.1s - self.timer.Start(100) - - - return 1 - - def watcher(self): - """Redraw, if new layer appears""" - if self.redraw: - self.Mapfrm.ReDraw(None) - self.redraw = False - return - - -# end of class MapApp - -if __name__ == "__main__": - - ###### SET command variable - if len(sys.argv) != 2: - print __doc__ - sys.exit() - - cmdfilename = sys.argv[1] - - import gettext - gettext.install("gm_map") # replace with the appropriate catalog name - - - if not os.getenv("GRASS_ICONPATH"): - os.environ["GRASS_ICONPATH"]=os.getenv("GISBASE")+"/etc/gui/icons/" - - gm_map = MapApp(0) - gm_map.MainLoop() - if grassenv.env.has_key("MONITOR"): - os.system("d.mon sel=%s" % grassenv.env["MONITOR"]) - - os.remove(cmdfilename) - os.system("""g.gisenv set="GRASS_PYCMDFILE" """) - Copied: trunk/grassaddons/gui/gui_modules/mapdisp.py (from rev 299, trunk/grassaddons/gui/Gism/mapdisp.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-25 06:26:05 UTC (rev 300) @@ -0,0 +1,804 @@ +""" +To be used either from GIS Manager or as p.mon backend + +Usage: + mapdisp.py /path/to/command/file + +mapdisp Package + +Classes: +* BufferedWindow +* DrawWindow +* MapFrame +* MapApp +""" + + +# Authors: Michael Barton and Jachym Cepicky +# COPYRIGHT: (C) 1999 - 2006 by the GRASS Development Team +# Double buffered drawing concepts from the wxPython Cookbook + +import wx +import wx.aui +import os, sys, time, glob + +import render +import toolbars +import grassenv +import track + +Map = render.Map() # instance of Map class to render GRASS display output to PPM file +DEBUG = False + +# for cmdline +from threading import Thread +import time +cmdfilename = None + +class Command(Thread): + """ + Creates thread, which will observe the command file and see, if there + is new command to be executed + """ + def __init__ (self,parent,Map): + Thread.__init__(self) + + global cmdfilename + + self.parent = parent + self.map = Map # + self.cmdfile = open(cmdfilename,"r") + + def run(self): + """ + Run this in thread + """ + dispcmd = [] + while 1: + self.parent.redraw = False + line = self.cmdfile.readline().strip() + if line == "quit": + break + + if line: + try: + #oper, lname, mapset, catlist, vallist, invert, opacity + # 0 1 2 3 4 5 6 + dispcmd = list(line.strip().split()) + #print dispcmd + if dispcmd[0]=="addraster": + try: mapset = eval(dispcmd[2]) + except: pass + try: catlist = eval(dispcmd[3]) + except: pass + try: vallist = eval(dispcmd[4]) + except: pass + try: invert = eval(dispcmd[5]) + except: pass + opacity = float(dispcmd[6]) + + self.map.AddRasterLayer(name="%s" % (dispcmd[1]), + mapset=dispcmd[2], vallist=vallist, + l_opacity=opacity) + + if dispcmd[0]=="addvector": + self.map.AddVectorLayer(name="%s" % (dispcmd[1]), + mapset=dispcmd[2]) + self.parent.redraw =True + except Exception, e: + print "Command Thread: ",e + pass + + time.sleep(0.1) + + sys.exit() + +class BufferedWindow(wx.Window): + """ + A Buffered window class. + + To use it, subclass it and define a Draw(DC) method that takes a DC + to draw to. In that method, put the code needed to draw the picture + you want. The window will automatically be double buffered, and the + screen will be automatically updated when a Paint event is received. + + When the drawing needs to change, you app needs to call the + UpdateMap() method. Since the drawing is stored in a bitmap, you + can also save the drawing to file by calling the + SaveToFile(self,file_name,file_type) method. + """ + + def __init__(self, parent, id, + pos = wx.DefaultPosition, + size = wx.DefaultSize, + style=wx.NO_FULL_REPAINT_ON_RESIZE): + + wx.Window.__init__(self, parent, id, pos, size, style) + self.parent = parent + + # + # Flags + # + self.render = True # re-render the map from GRASS or just redraw image + self.resize = False # indicates whether or not a resize event has taken place + self.dragimg = None # initialize variable for map panning + self.pen = None # pen for drawing zoom boxes, etc. + + # + # Event bindings + # + self.Bind(wx.EVT_PAINT, self.OnPaint) + self.Bind(wx.EVT_SIZE, self.OnSize) + self.Bind(wx.EVT_IDLE, self.OnIdle) + self.Bind(wx.EVT_MOTION, self.MouseActions) + self.Bind(wx.EVT_MOUSE_EVENTS, self.MouseActions) + + # + # Render output objects + # + self.mapfile = None # image file to be rendered + self.Img = "" # wx.Image object (self.mapfile) + + # + # mouse attributes like currently pressed buttons, position on + # the screen, begin and end of dragging, and type of drawing + # + self.mouse = { + 'l': False, + 'r': False, + 'm': False, + 'pos': [None, None], + 'begin': [0, 0], + 'end': [0, 0], + 'box': "point" + } + self.zoomtype = 1 # 1 zoom in, 0 no zoom, -1 zoom out + + # OnSize called to make sure the buffer is initialized. + # This might result in OnSize getting called twice on some + # platforms at initialization, but little harm done. + #!!! self.OnSize(None) + + def Draw(self, dc, img=None, dctype='image', coords='0,0'): + """ + Just here as a place holder. + This method should be over-ridden when sub-classed + """ + pass + + def OnPaint(self, event): + """ + All that is needed here is to draw the buffer to screen + """ + dc = wx.BufferedPaintDC(self, self._Buffer) + + def OnSize(self, event): + """ + The Buffer init is done here, to make sure the buffer is always + the same size as the Window + """ + + # set size of the input image + Map.width, Map.height = self.GetClientSize() + + # Make new off screen bitmap: this bitmap will always have the + # current drawing in it, so it can be used to save the image to + # a file, or whatever. + self._Buffer = wx.EmptyBitmap(Map.width, Map.height) + + # get the image to be rendered + self.Img = self.GetImage() + + # update map display + if self.Img and Map.width + Map.height > 0: # scale image during resize + self.Img = self.Img.Scale(Map.width, Map.height) + self.render = False + self.UpdateMap() + + # re-render image on idle + self.resize = True + + def OnIdle(self, event): + """ + Only re-render a compsite map image from GRASS during + idle time instead of multiple times during resizing. + """ + + if self.resize: + self.render = True + self.UpdateMap() + event.Skip() + + def SaveToFile(self, FileName, FileType): + """ + This will save the contents of the buffer + to the specified file. See the wx.Windows docs for + wx.Bitmap::SaveFile for the details + """ + self._Buffer.SaveFile(FileName, FileType) + + def UpdateMap(self, img=None): + """ + This would get called if the drawing needed to change, for whatever reason. + + The idea here is that the drawing is based on some data generated + elsewhere in the system. IF that data changes, the drawing needs to + be updated. + + """ + if self.render: + Map.width, Map.height = self.GetClientSize() + self.mapfile = Map.Render(force=self.render) + self.Img = self.GetImage() + self.resize = False + if not self.Img: return + dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) + self.Draw(dc, self.Img) + else: + if not self.Img: return + dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) + self.Draw(dc, self.Img) + self.resize = False + + def EraseMap(self): + """ + Erase the map display + """ + dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) + self.Draw(dc, dctype='clear') + + def DragMap(self, moveto): + """ + Drag a bitmap image for panning. + """ + + dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) + dc.SetBackground(wx.Brush("White")) + bitmap = wx.BitmapFromImage(self.Img) + self.dragimg = wx.DragImage(bitmap) + self.dragimg.BeginDrag((0, 0), self) + self.dragimg.GetImageRect(moveto) + self.dragimg.Move(moveto) + dc.Clear() + self.dragimg.DoDrawImage(dc, moveto) + self.dragimg.EndDrag() + ## self.dragimg.UpdateBackingFromWindow(dc, memdc, sourcerect,destrect) + + def MouseDraw(self): + """ + Mouse zoom rectangles and lines + """ + img = self.Img # composite map in background + dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) + if self.mouse['box'] == "box": + mousecoords = [self.mouse['begin'][0], self.mouse['begin'][1], \ + self.mouse['end'][0] - self.mouse['begin'][0], \ + self.mouse['end'][1] - self.mouse['begin'][1]] + self.Draw(dc, img, dctype='box', coords=mousecoords) + elif self.mouse['box'] == "line": + mousecoords = [self.mouse['begin'][0], self.mouse['begin'][1], \ + self.mouse['end'][0] - self.mouse['begin'][0], \ + self.mouse['end'][1] - self.mouse['begin'][1]] + self.Draw(dc, img, dctype='line', coords=mousecoords) + + def MouseActions(self, event): + """ + Mouse motion and button click notifier + """ + wheel = event.GetWheelRotation() # +- int + # left mouse button pressed + if event.LeftDown(): + # start point of zoom box or drag + self.mouse['begin'] = event.GetPositionTuple()[:] + + # left mouse button released and not just a pointer + elif event.LeftUp(): + if self.mouse['box'] != "point": + # end point of zoom box or drag + self.mouse['end'] = event.GetPositionTuple()[:] + + # set region in zoom or pan + self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype) + + else: + # digitizing + if self.parent.digittoolbar: + if self.parent.digittoolbar.digitize == "point": + east,north= self.Pixel2Cell(self.mouse['end'][0],self.mouse['end'][1]) + self.parent.digittoolbar.AddPoint(east,north) + # redraw map + self.render=True + self.UpdateMap() + + # dragging or drawing box with left button + elif event.Dragging() and event.LeftIsDown: + currpos = event.GetPositionTuple()[:] + end = (currpos[0]-self.mouse['begin'][0], \ + currpos[1]-self.mouse['begin'][1]) + if self.mouse['box'] == 'drag': + self.DragMap(end) + else: + self.mouse['end'] = event.GetPositionTuple()[:] + self.MouseDraw() + + # zoom on mouse wheel + elif wheel != 0: + + # zoom 1/2 of the screen + begin = [Map.width/4, Map.height/4] + end = [Map.width - Map.width/4, + Map.height - Map.height/4] + + # store current mouse position + self.mouse['pos'] = event.GetPositionTuple()[:] + + def GetImage(self): + """ + Converts files to wx.Image + """ + if Map.mapfile and os.path.isfile(Map.mapfile) and \ + os.path.getsize(Map.mapfile): + self.Img = wx.Image(Map.mapfile, wx.BITMAP_TYPE_ANY) + else: + self.Img = None + return self.Img + + def Pixel2Cell(self, x, y): + """ + Calculates real word coordinates to image coordinates + + Input : x, y + Output: int x, int y + """ + newx = Map.region['w'] + x * Map.region["ewres"] + newy = Map.region['n'] - y * Map.region["nsres"] + return newx, newy + + + def Zoom(self, begin, end, zoomtype): + """ + Calculates new region while (un)zoom/pan-ing + """ + x1, y1, x2, y2 = begin[0], begin[1], end[0], end[1] + newreg = {} + + # threshold - too small squares do not make sense + # can only zoom to windows of > 10x10 screen pixels + if x2 > 10 and y2 > 10 and zoomtype != 0: + + if x1 > x2: + x1, x2 = x2, x1 + if y1 > y2: + y1, y2 = y2, y1 + # zoom in + if zoomtype > 0: + newreg['w'], newreg['n'] = self.Pixel2Cell(x1, y1) + newreg['e'], newreg['s'] = self.Pixel2Cell(x2, y2) + + # zoom out + elif zoomtype < 0: + newreg['w'], newreg['n'] = self.Pixel2Cell( + -x1*2, + -y1*2) + newreg['e'], newreg['s'] = self.Pixel2Cell( + Map.width+2*(Map.width-x2), + Map.height+2*(Map.height-y2)) + # pan + elif zoomtype == 0: + newreg['w'], newreg['n'] = self.Pixel2Cell( + x1-x2, + y1-y2) + newreg['e'], newreg['s'] = self.Pixel2Cell( + Map.width+x1-x2, + Map.height+y1-y2) + + # if new region has been calculated, set the values + if newreg : + Map.region['n'] = newreg['n'] + Map.region['s'] = newreg['s'] + Map.region['e'] = newreg['e'] + Map.region['w'] = newreg['w'] + +class DrawWindow(BufferedWindow): + """ + Drawing routine for double buffered drawing. Overwrites Draw method + in the BufferedWindow class + """ + def __init__(self, parent, id = wx.ID_ANY): + """ + """ + ## Any data the Draw() function needs must be initialized before + ## calling BufferedWindow.__init__, as it will call the Draw + ## function. + self.dcmd_list = [] # list of display commands to process + BufferedWindow.__init__(self, parent, id) + + def Draw(self, dc, img=None, dctype='image', coords=[0, 0]): + """ + Draws image, box and line in the background + """ + dc.BeginDrawing() + dc.SetBackground(wx.Brush(self.GetBackgroundColour())) + dc.Clear() # make sure you clear the bitmap! + + if dctype == 'clear': # erase the display + dc.EndDrawing() + return + bitmap = wx.BitmapFromImage(img) + dc.DrawBitmap(bitmap, 0, 0) # draw the composite map + + if dctype == 'box': # draw a box on top of the map + dc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) + dc.SetPen(self.pen) + dc.DrawRectangle(coords[0], coords[1], coords[2], coords[3]) + elif dctype == 'line': # draw a line on top of the map + dc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) + dc.SetPen(self.pen) + dc.DrawLine(coords[0], coords[1], coords[2], coords[3]) + + dc.EndDrawing() + +class MapFrame(wx.Frame): + """ + Main frame for map display window. Drawing takes place in child double buffered + drawing window. + """ + + def __init__(self, parent=None, id = wx.ID_ANY, title="Map display", + pos=wx.DefaultPosition, size=wx.DefaultSize, + style=wx.DEFAULT_FRAME_STYLE, toolbars=["map"], cb=None, idx=-1): + +# style=wx.DEFAULT_FRAME_STYLE, toolbars=["map"]): + + """ + Main map display window with toolbars, statusbar and + DrawWindow + + Parameters: + parent -- parent window, None, wx.Window() + id -- window ID, int, wx.NewId() + title -- window title, string + pos -- where to place it, tupple, wx.Position + size -- window size, tupple, wx.Size + style -- window style + toolbars-- array of default toolbars, which should appear + map, digit + """ + + wx.Frame.__init__(self, parent, id, title, pos, size, style) + + # + # Set the size + # + self.SetClientSize((600, 475)) + + # Set variables to associate display with GIS Manager page + self.ctrlbk = cb + self.disp_idx = idx + + # + # Fancy gui + # + self._mgr = wx.aui.AuiManager(self) + + # + # Add toolbars + # + self.maptoolbar = None + self.digittoolbar = None + for toolb in toolbars: + self.AddToolbar(toolb) + + # + # Add statusbar + # + self.statusbar = self.CreateStatusBar(number=2, style=0) + self.statusbar.SetStatusWidths([-2, -1]) + map_frame_statusbar_fields = ["Extent: %d,%d : %d,%d" % + (Map.region["n"], Map.region["s"], + Map.region["w"], Map.region["e"]), + "%s,%s" %(None, None)] + for i in range(len(map_frame_statusbar_fields)): + self.statusbar.SetStatusText(map_frame_statusbar_fields[i], i) + + + # + # Init map display + # + self.InitDisplay() # initialize region values + self.MapWindow = DrawWindow(self) # initialize buffered DC + self.MapWindow.Bind(wx.EVT_MOTION, self.OnMotion) + + + # + # Bind various events + # ONLY if we are running from GIS manager + # + if self.disp_idx > -1: + self.Bind(wx.EVT_ACTIVATE, self.OnFocus) + self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) + + # + # Update fancy gui style + # + self._mgr.AddPane(self.MapWindow, wx.CENTER) + self._mgr.Update() + + # + # Create dictionary of available cursors + # + self.cursors = { + "default" : wx.StockCursor (wx.CURSOR_DEFAULT), + "cross" : wx.StockCursor (wx.CURSOR_CROSS), + "hand" : wx.StockCursor (wx.CURSOR_HAND) + } + + def AddToolbar(self, name): + """ + Add defined toolbar to the window + + Currently known toolbars are: + * map + * digit + """ + if name == "map": + self.maptoolbar = toolbars.MapToolbar(self, Map) + self._mgr.AddPane(self.maptoolbar.toolbar, wx.aui.AuiPaneInfo(). + Name("maptoolbar").Caption("Map Toolbar"). + ToolbarPane().Top().LeftDockable(False).RightDockable(False). + BottomDockable(True).CloseButton(False)) + + if name == "digit": + self.digittoolbar = toolbars.DigitToolbar(self,Map) + self._mgr.AddPane(self.digittoolbar.toolbar, wx.aui.AuiPaneInfo(). + Name("digittoolbar").Caption("Digit Toolbar"). + ToolbarPane().Top().LeftDockable(False).RightDockable(False). + BottomDockable(True).CloseButton(False)) + self._mgr.Update() + + def InitDisplay(self): + """ + Initialize map display, set dimensions and map region + """ + self.width, self.height = self.GetClientSize() + Map.geom = self.width, self.height + Map.GetRegion() + #FIXME + #This was Map.getResolution(). + #I'm guessing at the moment that this is replaced by Map.SetRegion() + Map.SetRegion() + + def OnFocus(self, event): + """ + Store information about active display + in tracking variables and change choicebook + page to match display + """ + #get index number of active display + self.disp_idx = int(track.Track().GetDisp_idx(self)) + + #set active display tuple in track + track.Track().SetDisp(self.disp_idx, self) + + # change bookcontrol page to page associted with display if > 1 display + pg = track.Track().GetCtrls(self.disp_idx, 1) + pg_count = self.ctrlbk.GetPageCount() + pgnum = '0' + if pg_count > 0: + for x in range(0,pg_count): + if self.ctrlbk.GetPage(x) == pg: + pgnum = x + break + + self.ctrlbk.SetSelection(pgnum) + event.Skip() + + def SetDcommandList(self, clst): + self.MapWindow.dcmd_list = clst + self.MapWindow.ProcessDcommand() + self.MapWindow.UpdateMap() + + def OnMotion(self, event): + """ + Mouse moved + Track mouse motion and update status bar + """ + # store current mouse position + posx, posy = event.GetPositionTuple() + + + # upsdate coordinates + x, y = self.MapWindow.Pixel2Cell(posx, posy) + self.statusbar.SetStatusText("%d,%d" % (x, y), 1) + + event.Skip() + + def ReDraw(self, event): + """ + Redraw button clicked + """ + self.MapWindow.UpdateMap() + + def ReDrawCommand(self): + """ + d.* command on command line and enter pressed. + """ + self.MapWindow.UpdateMap() + + def Pointer(self, event): + """Pointer button clicled""" + self.MapWindow.mouse['box'] = "point" + + # change the cursor + self.MapWindow.SetCursor (self.cursors["default"]) + + def OnZoomIn(self, event): + """ + Zoom in the map. + Set mouse pointer and zoom direction + """ + self.MapWindow.mouse['box'] = "box" + self.MapWindow.zoomtype = 1 + self.MapWindow.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH) + + # change the cursor + self.MapWindow.SetCursor (self.cursors["cross"]) + + def OnZoomOut(self, event): + """ + Zoom out the map. + Set mouse pointer and zoom direction + """ + self.MapWindow.mouse['box'] = "box" + self.MapWindow.zoomtype = -1 + self.MapWindow.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH) + + # change the cursor + self.MapWindow.SetCursor (self.cursors["cross"]) + + def OnZoomBack(self, event): + """ + Zoom last (previously stored position) + """ + # FIXME + pass + + def OnPan(self, event): + """ + Panning, set mouse to drag + """ + self.MapWindow.mouse['box'] = "drag" + self.MapWindow.zoomtype = 0 + event.Skip() + + # change the cursor + self.MapWindow.SetCursor (self.cursors["hand"]) + + def OnErase(self, event): + """ + Erase the canvas + """ + self.MapWindow.EraseMap() + + def OnZoomRegion(self, event): + """ + Zoom to region + """ + Map.getRegion() + Map.getResolution() + self.draw(dc) + event.Skip() + + def OnAlignRegion(self, event): + """ + Align region + """ + if not Map.alignRegion: + Map.alignRegion = True + else: + Map.alignRegion = False + event.Skip() + + def SaveToFile(self, event): + """ + Save to file + """ + dlg = wx.FileDialog(self, "Choose a file name to save the image as a PNG to", + defaultDir = "", + defaultFile = "", + wildcard = "*.png", + style=wx.SAVE) + if dlg.ShowModal() == wx.ID_OK: + self.MapWindow.SaveToFile(dlg.GetPath(), wx.BITMAP_TYPE_PNG) + dlg.Destroy() + + def OnCloseWindow(self, event): + """ + Window closed + """ + Map.Clean() + self.Destroy() + + #close associated controls book page + #get index number of active display + self.disp_idx = track.Track().GetDisp_idx(self) + + # delete associated bookcontrol page if it exists + if self.disp_idx != None: + pg = track.Track().GetCtrls(self.disp_idx, 1) + pg_count = self.ctrlbk.GetPageCount() + pgnum = '0' + if pg_count > 0: + for x in range(0,pg_count): + if self.ctrlbk.GetPage(x) == pg: + pgnum = x + track.Track().popCtrl(self.disp_idx) + self.ctrlbk.DeletePage(pgnum) + + def getRender(self): + """ + returns the current instance of render.Map() + """ + return Map + +# end of class MapFrame + +class MapApp(wx.App): + """ + MapApp class + """ + + def OnInit(self): + wx.InitAllImageHandlers() + self.Mapfrm = MapFrame(parent=None, id=wx.ID_ANY) + #self.SetTopWindow(Map) + self.Mapfrm.Show() + + # only for testing purpose + if __name__ == "__main__": + + # redraw map, if new command appears + self.redraw = False + status = Command(self,Map) + status.start() + self.timer = wx.PyTimer(self.watcher) + # chec each 0.1s + self.timer.Start(100) + + + return 1 + + def watcher(self): + """Redraw, if new layer appears""" + if self.redraw: + self.Mapfrm.ReDraw(None) + self.redraw = False + return + + +# end of class MapApp + +if __name__ == "__main__": + + ###### SET command variable + if len(sys.argv) != 2: + print __doc__ + sys.exit() + + cmdfilename = sys.argv[1] + + import gettext + gettext.install("gm_map") # replace with the appropriate catalog name + + + if not os.getenv("GRASS_ICONPATH"): + os.environ["GRASS_ICONPATH"]=os.getenv("GISBASE")+"/etc/gui/icons/" + + gm_map = MapApp(0) + gm_map.MainLoop() + if grassenv.env.has_key("MONITOR"): + os.system("d.mon sel=%s" % grassenv.env["MONITOR"]) + + os.remove(cmdfilename) + os.system("""g.gisenv set="GRASS_PYCMDFILE" """) + From barton at grass.itc.it Sun Mar 25 08:28:36 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:28:38 2007 Subject: [grass-addons] r301 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250628.l2P6Salx021741@grass.itc.it> Author: barton Date: 2007-03-25 08:28:21 +0200 (Sun, 25 Mar 2007) New Revision: 301 Added: trunk/grassaddons/gui/gui_modules/menudata.py Removed: trunk/grassaddons/gui/Gism/menudata.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/menudata.py =================================================================== --- trunk/grassaddons/gui/Gism/menudata.py 2007-03-25 06:26:05 UTC (rev 300) +++ trunk/grassaddons/gui/Gism/menudata.py 2007-03-25 06:28:21 UTC (rev 301) @@ -1,327 +0,0 @@ -class Data: - '''Data object that returns menu descriptions to be used in wxgui.py. - Probably could be changed to XML or *.dtd file.''' - def GetMenu(self): - return [( - ("Files", ( - ("Import", "Import files", "self.runMenuCmd", "r.in.gdal"), - ("Export", "Export files", "self.runMenuCmd", "r.out.gdal"), - ("","","", ""), - ("E&xit", "Exit from wxgui.py", "self.onCloseWindow", "") - )), - ("Config", ( - ("Region", "Set region", "self.runMenuCmd", "g.region"), - ("","","", "") - )), - ("Raster", ( - ("Develop map", ( - ("Digitize raster", "Digitize raster", "self.runMenuCmd", "r.digit"), - ("","","", ""), - ("Compress/decompress raster file", "Compress/decompress raster file", "self.runMenuCmd", "r.compress"), - ("Manage boundary definition (WHICH COMMAND?)", "Manage boundary definition", "self.runMenuCmd", "r.region"), - ("Manage null values", "Manage null values", "self.runMenuCmd", "r.null"), - ("Manage timestamp for files", "Manage timestamp for files", "self.runMenuCmd", "r.timestamp"), - ("Quantization for floating-point maps", "Quantization for floating-point maps", "self.runMenuCmd", "r.quant"), - ("Resample (change resolution) using nearest neighbor method", "Resample (change resolution) using nearest neighbor method", "self.runMenuCmd", "r.resample"), - ("Resample (change resolution) using regularized spline tension", "Resample (change resolution) using regularized spline tension", "self.runMenuCmd", "r.resamp.rst"), - ("Support file creation and maintenance", "Support file creation and maintenance", "self.runMenuCmd", "r.support.sh"), - ("","","", ""), - ("Reproject raster from other location", "Reproject raster from other location", "self.runMenuCmd", "r.proj"), - ("Generate tiling for other projection", "Generate tiling for other projection", "self.runMenuCmd", "r.tileset"), - )), - ("Manage map colors", ( - ("Set colors to predefined color tables", "Set colors to predefined color tables", "self.runMenuCmd", "r.colors"), - ("Set colors using color rules", "Set colors using color rules", "self.runMenuCmd", "r.colors.rules"), - ("","","", ""), - ("Blend 2 color maps to produce 3 RGB files", "Blend 2 color maps to produce 3 RGB files", "self.runMenuCmd", "r.blend"), - ("Create color image from RGB files", "Create color image from RGB files", "self.runMenuCmd", "r.composite"), - ("Create 3 RGB (red, green, blue) maps from 3 HIS (hue, intensity, saturation) maps", "Create 3 RGB (red, green, blue) maps from 3 HIS (hue, intensity, saturation) maps", "self.runMenuCmd", "r.his"), - )), - ("Query by coordinates", "Query by coordinates", "self.runMenuCmd", "r.what"), - ("","","", ""), - ("Create raster buffers", "Develop raster buffer", "self.runMenuCmd", "r.buffer"), - ("Create raster MASK", "Develop raster mask", "self.runMenuCmd", "r.mask"), - ("Locate closest points between areas in 2 raster maps", "r.distance", "self.runMenuCmd", "r.distance"), - ("Map calculator", "Map calculator", "self.runMenuCmd", "scripts/mapcalc_gparser.sh"), - ("Neighborhood analysis", ( - ("Moving window analysis of raster cells", "Moving window analysis of raster cells", "self.runMenuCmd", "r.neighbors"), - ("Analyze vector points in neighborhood of raster cells", "Analyze vector points in neighborhood of raster cells", "self.runMenuCmd", "v.neighbors"), - )), - ("Overlay maps", ( - ("Cross product", "Cross product", "self.runMenuCmd", "r.cross"), - ("Function of map series (time series)", "Function of map series (time series)", "self.runMenuCmd", "r.series"), - ("Patch maps", "Patch maps", "self.runMenuCmd", "r.patch"), - ("","","", ""), - ("Statistical calculations for cover map over base map", "Statistical calculations for cover map over base map", "self.runMenuCmd", "r.statistics"), - )), - ("Solar radiance and shadows", ( - ("Solar irradiance and daily irradiation", "Solar irradiance and daily irradiation", "self.runMenuCmd", "r.sun"), - ("Shadow map for sun position or date/time", "Shadow map for sun position or date/time", "self.runMenuCmd", "r.sunmask"), - )), - ("Terrain analysis", ( - ("Calculate cumulative movement costs between locales", "Calculate cumulative movement costs between locales", "self.runMenuCmd", "r.walk"), - ("cost surface", "cost surface", "self.runMenuCmd", "r.cost"), - ("Least cost route or flow", "Least cost route or flow", "self.runMenuCmd", "r.drain"), - ("Profile analysis", "Profile analysis", "self.runMenuCmd", "d.profile"), - ("Shaded relief map", "Shaded relief map", "self.runMenuCmd", "r.shaded.relief"), - ("Slope and aspect", "Slope and aspect", "self.runMenuCmd", "r.slope.aspect"), - ("Terrain parameters", "Terrain parameters", "self.runMenuCmd", "r.param.scale"), - ("Textural features", "Textural features", "self.runMenuCmd", "r.texture"), - ("Visibility/Line of sight", "Visibility/Line of sight", "self.runMenuCmd", "r.los"), - )), - ("Transform features", ( - ("Clump small areas (statistics calculated by r.volume)", "Clump small areas (statistics calculated by r.volume)", "self.runMenuCmd", "r.clump"), - ("Grow areas", "Grow areas", "self.runMenuCmd", "r.grow"), - ("Thin linear features", "Thin linear features", "self.runMenuCmd", "r.thin"), - )), - ("","","", ""), - ("Hydrologic modeling", ( - ("Carve stream channels into elevation map using vector streams map", "Carve stream channels into elevation map using vector streams map", "self.runMenuCmd", "r.carve"), - ("Depressionless elevation map and flowline map", "Depressionless elevation map and flowline map", "self.runMenuCmd", "r.fill.dir"), - ("Fill lake from seed point to specified level", "Fill lake from seed point to specified level", "self.runMenuCmd", "r.lake"), - ("Flow accumulation for massive grids (WHICH COMMAND?)", "Flow accumulation for massive grids", "self.runMenuCmd", "r.flow"), - ("Generate flow lines for raster map (WHICH COMMAND?)", "Generate flow lines for raster map", "self.runMenuCmd", "r.flow"), - ("SIMWE overland flow modeling (WHICH COMMAND?)", "SIMWE overland flow modeling", "self.runMenuCmd", "r.simwe"), - ("SIMWE sediment erosion, transport, deposition modeling (WHICH COMMAND?)", "SIMWE sediment erosion, transport, deposition modeling", "self.runMenuCmd", "r.simwe"), - ("Topographic index map", "Topographic index map", "self.runMenuCmd", "r.topidx"), - ("TOPMODEL simulation", "TOPMODEL simulation", "self.runMenuCmd", "r.topmodel"), - ("Watershed subbasins", "Watershed subbasins", "self.runMenuCmd", "r.basins.fill"), - ("Watershed analysis", "Watershed analysis", "self.runMenuCmd", "r.watershed"), - ("Watershed basin creation", "Watershed basin creation", "self.runMenuCmd", "r.water.outlet"), - )), - ("Landscape structure modeling", ( - ("Set up sampling and analysis framework", "Set up sampling and analysis framework", "self.runMenuCmd", "r.le.setup"), - ("","","", ""), - ("Analyze landscape characteristics", "Analyze landscape characteristics", "self.runMenuCmd", "r.le.pixel"), - ("Analyze landscape patch characteristics", "Analyze landscape patch characteristics", "self.runMenuCmd", "r.le.patch"), - ("Output landscape patch information", "Output landscape patch information", "self.runMenuCmd", "r.le.trace"), - )), - ("Wildfire modeling", ( - ("Generate rate of spread (ROS) maps", "Generate rate of spread (ROS) maps", "self.runMenuCmd", "r.ros"), - ("Generate least-cost spread paths", "Generate least-cost spread paths", "self.runMenuCmd", "r.spreadpath"), - ("Simulate anisotropic spread phenomena", "Simulate anisotropic spread phenomena", "self.runMenuCmd", "r.spread"), - )), - ("","","", ""), - ("Change category values and labels", ( - ("Edit category values of individual cells for displayed raster map", "Edit category values of individual cells for displayed raster map", "self.runMenuCmd", "d.rast.edit"), - ("","","", ""), - ("Reclassify categories for areas of specified sizes", "Reclassify categories for areas of specified sizes", "self.runMenuCmd", "r.reclass.area"), - ("Reclassify categories using rules", "Reclassify categories using rules", "self.runMenuCmd", "r.reclass.rules"), - ("Reclassify categories using rules file", "Reclassify categories using rules file", "self.runMenuCmd", "r.reclass.file"), - ("","","", ""), - ("Recode categories using rules (create new map)", "Recode categories using rules (create new map)", "self.runMenuCmd", "r.recode.rules"), - ("Recode categories using rules file (create new map)", "Recode categories using rules file (create new map)", "self.runMenuCmd", "r.recode.file"), - ("","","", ""), - ("Rescale categories (create new map)", "Rescale categories (create new map)", "self.runMenuCmd", "r.rescale"), - ("Rescale categories with equalized histogram (create new map)", "Rescale categories with equalized histogram (create new map)", "self.runMenuCmd", "r.rescale.eq"), - )), - ("","","", ""), - ("Generate concentric circles around points", "Generate concentric circles around points", "self.runMenuCmd", "r.circle"), - ("Generate random raster cells", ( - ("Generate random cells", "Generate random cells", "self.runMenuCmd", "r.random.cells"), - ("Generate random cells and vector points from raster map", "Generate random cells and vector points from raster map", "self.runMenuCmd", "r.random"), - )), - ("Generate surfaces", ( - ("Generate density surface using moving Gaussian kernel", "Generate density surface using moving Gaussian kernel", "self.runMenuCmd", "v.kernel"), - ("Generate fractal surface", "Generate fractal surface", "self.runMenuCmd", "r.surf.fractal"), - ("Generate gaussian deviates surface", "Generate gaussian deviates surface", "self.runMenuCmd", "r.surf.gauss"), - ("Generate plane", "Generate plane", "self.runMenuCmd", "r.plane"), - ("Generate random deviates surface", "Generate random deviates surface", "self.runMenuCmd", "r.surf.random"), - ("Generate random surface with spatial dependence", "Generate random surface with spatial dependence", "self.runMenuCmd", "r.random.surface"), - )), - ("Generate vector contour lines", "Generate vector contour lines", "self.runMenuCmd", "r.contour"), - ("Interpolate surfaces", ( - ("Bilinear interpolation from raster points", "Bilinear interpolation from raster points", "self.runMenuCmd", "r.bilinear"), - ("Inverse distance weighted interpolation from raster points", "Inverse distance weighted interpolation from raster points", "self.runMenuCmd", "r.surf.idw"), - ("Interpolation from raster contour", "Interpolation from raster contour", "self.runMenuCmd", "r.surf.contour"), - ("","","", ""), - ("Inverse distance weighted interpolation from vector points", "Inverse distance weighted interpolation from vector points", "self.runMenuCmd", "v.surf.idw"), - ("Regularized spline tension interpolation from vector points or contours (WHICH COMMAND ?)", "Regularized spline tension interpolation from vector points or contours", "self.runMenuCmd", "v.surf.rst"), - ("","","", ""), - ("Fill NULL cells by interpolation using regularized spline tension", "Fill NULL cells by interpolation using regularized spline tension", "self.runMenuCmd", "r.fillnulls"), - )), - ("","","", ""), - ("Report and statistics", ( - ("Report basic file information", "Report basic file information", "self.runMenuCmd", "r.info"), - ("Report category labels and values", "Report category labels and values", "self.runMenuCmd", "r.cats"), - ("","","", ""), - ("General statistics", "General statistics", "self.runMenuCmd", "r.stats"), - ("Range of all category values", "Range of all category values", "self.runMenuCmd", "r.describe"), - ("Sum all cell category values", "Sum all cell category values", "self.runMenuCmd", "r.sum"), - ("Sum area by map and category", "Sum area by map and category", "self.runMenuCmd", "r.report"), - ("Summary statistics for clumped cells (work with r.clump)", "Summary statistics for clumped cells (work with r.clump)", "self.runMenuCmd", "r.volume"), - ("Total surface area corrected for topography", "Total surface area corrected for topography", "self.runMenuCmd", "r.surf.area"), - ("Univariate statistics", "Univariate statistics", "self.runMenuCmd", "r.univar"), - ("Univariate statistics (script version)", "Univariate statistics (script version)", "self.runMenuCmd", "r.univar.sh"), - ("","","", ""), - ("Sample values along transects", "Sample values along transects", "self.runMenuCmd", "r.profile"), - ("Sample values along transects (use azimuth, distance)", "Sample values along transects (use azimuth, distance)", "self.runMenuCmd", "r.transect"), - ("","","", ""), - ("Covariance/correlation", "Covariance/correlation", "self.runMenuCmd", "r.covar"), - ("Linear regression between 2 maps", "Linear regression between 2 maps", "self.runMenuCmd", "r.regression.line"), - ("Mutual category occurrences (coincidence)", "Mutual category occurrences (coincidence)", "self.runMenuCmd", "r.coin"), - )), - ("","","", "") - )), - ("Vector", ( - ("Develop map", ( - ("Digitize", "Digitize vector", "self.runMenuCmd", "v.digit"), - ("","","", ""), - ("Create/Rebuild topology", "Create/Rebuild topology", "self.runMenuCmd", "v.build"), - ("Clean vector files", "clean vector files", "self.runMenuCmd", "v.clean"), - ("","","", ""), - ("Break lines at intersections", "Break lines at intersections", "self.runMenuCmd", "v.topo.check"), - ("Build polylines from adjacent segments", "Build polylines from adjacent segments", "self.runMenuCmd", "v.build.polylines"), - ("Split polylines into segments", "Split polylines into segments", "self.runMenuCmd", "v.segment"), - ("Create lines parallel to existing lines", "Create lines parallel to existing lines", "self.runMenuCmd", "v.parallel"), - ("","","", ""), - ("Convert vector feature types", "Convert vector feature types", "self.runMenuCmd", "v.type"), - ("Convert 2D vector to 3D by sampling raster", "Convert 2D vector to 3D by sampling raster", "self.runMenuCmd", "v.drape"), - ("Extrude 2D vector into 3D vector", "Extrude 2D vector into 3D vector", "self.runMenuCmd", "v.extrude"), - ("","","", ""), - ("Create text label file for vector features", "Create text label file for vector features", "self.runMenuCmd", "v.label"), - ("","","", ""), - ("Reproject vector from other location", "Reproject vector from other location", "self.runMenuCmd", "v.proj"), - ("","","", "") - )), - ("","","", ""), - ("vector<->database connections", ( - ("Create new vector as link to external OGR layer", "Create new vector as link to external OGR layer", "self.runMenuCmd", "v.external"), - ("Set database connection for vector attributes", "Set database connection for vector attributes", "self.runMenuCmd", "v.db.connect"), - )), - ("Query by attributes", "Query by attributes", "self.runMenuCmd", "v.extract"), - ("Query by coordinate(s)", "Query by coordinate(s)", "self.runMenuCmd", "v.what"), - ("Query by map features", "Query by map features", "self.runMenuCmd", "v.select"), - ("","","", ""), - ("Create vector buffers", "Create vector buffers", "self.runMenuCmd", "v.buffer"), - ("Linear referencing for vectors", ( - ("Create linear reference system", "Create linear reference system", "self.runMenuCmd", "v.lrs.create"), - ("Create stationing from input lines, and linear reference system", "Create stationing from input lines, and linear reference system", "self.runMenuCmd", "v.lrs.label"), - ("Create points/segments from input lines, linear reference system and positions read from stdin", "Create points/segments from input lines, linear reference system and positions read from stdin", "self.runMenuCmd", "v.lrs.segment"), - ("Find line id and real km+offset for given points in vector map using linear reference system", "Find line id and real km+offset for given points in vector map using linear reference system", "self.runMenuCmd", "v.lrs.where"), - )), - ("Neighborhood analysis", ( - ("Locate nearest feature to points or centroids", "Locate nearest feature to points or centroids", "self.runMenuCmd", "v.distance"), - ("Generate Thiessen polygons around points (Voronoi diagram)", "Generate Thiessen polygons around points (Voronoi diagram)", "self.runMenuCmd", "v.voronoi"), - ("Connect points to create Delaunay triangles", "Connect points to create Delaunay triangles", "self.runMenuCmd", "v.delaunay"), - )), - ("Network analysis", ( - ("Allocate subnets", "Allocate subnets", "self.runMenuCmd", "v.net.alloc"), - ("Network maintenance", "Network maintenance", "self.runMenuCmd", "v.net"), - ("Shortest route", "Shortest route", "self.runMenuCmd", "v.net.path"), - ("Shortest route (visualization only)", "Shortest route (visualization only)", "self.runMenuCmd", "d.path"), - ("Split net to bands between cost isolines", "Split net to bands between cost isolines", "self.runMenuCmd", "v.net.iso"), - ("Steiner tree", "Steiner tree", "self.runMenuCmd", "v.net.steiner"), - ("Traveling salesman analysis", "Traveling salesman analysis", "self.runMenuCmd", "v.net.salesman"), - )), - ("Overlay maps", ( - ("Overlay/combine 2 vector maps", "Overlay/combine 2 vector maps", "self.runMenuCmd", "v.overlay"), - ("Patch multiple maps (combine)", "Patch multiple maps (combine)", "self.runMenuCmd", "v.patch"), - )), - ("Generate area feature for extent of current region", "Generate area feature for extent of current region", "self.runMenuCmd", "v.in.region"), - ("Generate rectangular vector grid", "Generate rectangular vector grid", "self.runMenuCmd", "v.mkgrid"), - ("","","", ""), - ("Change attributes", ( - ("Attach/delete, or report categories", "Attach/delete, or report categories", "self.runMenuCmd", "v.category"), - ("Reclassify features using rules file", "Reclassify features using rules file", "self.runMenuCmd", "v.reclass"), - )), - ("","","", ""), - ("Work with vector points", ( - ("Generate points", ( - ("Generate points from database", "Generate points from database", "self.runMenuCmd", "v.in.db"), - ("Generate random points", "Generate random points", "self.runMenuCmd", "v.random"), - ("Random location perturbations of points", "Random location perturbations of points", "self.runMenuCmd", "v.perturb"), - )), - ("Generate areas from points", ( - ("Generate convex hull for point set", "Generate convex hull for point set", "self.runMenuCmd", "v.hull"), - ("Generate Delaunay triangles for point set", "Generate Delaunay triangles for point set", "self.runMenuCmd", "v.delaunay"), - ("Generate Voronoi diagram/Thiessen polygons for point set", "Generate Voronoi diagram/Thiessen polygons for point set", "self.runMenuCmd", "v.voronoi"), - )), - ("Sample raster maps", ( - ("Calculate statistics for raster map overlain by vector map", "Calculate statistics for raster map overlain by vector map", "self.runMenuCmd", "v.rast.stats"), - ("Sample raster maps at point locations", "Sample raster maps at point locations", "self.runMenuCmd", "v.what.rast"), - ("Sample raster neighborhood around points", "Sample raster neighborhood around points", "self.runMenuCmd", "v.sample"), - )), - ("Partition points into test/training sets for k-fold cross validation", "Partition points into test/training sets for k-fold cross validation", "self.runMenuCmd", "v.kcv"), - ("Transfer attribute data from queried vector map to points", "Transfer attribute data from queried vector map to points", "self.runMenuCmd", "v.what.vect"), - )), - ("","","", ""), - ("Reports and statistics", ( - ("Basic information", "Basic information", "self.runMenuCmd", "v.info"), - ("Load vector attributes to database or create reports", "Load vector attributes to database or create reports", "self.runMenuCmd", "v.to.db"), - ("Report areas for vector attribute categories", "Report areas for vector attribute categories", "self.runMenuCmd", "v.report"), - ("Univariate statistics", "Univariate statistics", "self.runMenuCmd", "v.univar"), - ("","","", ""), - ("Test normality of point distribution", "Test normality of point distribution", "self.runMenuCmd", "v.normal"), - ("Calculate stats for raster map underlying vector objects", "Calculate stats for raster map underlying vector objects", "self.runMenuCmd", "v.rast.stats"), - ("Indices of point counts in quadrats", "Indices of point counts in quadrats", "self.runMenuCmd", "v.qcount"), - )), - ("","","", "") - )), - ("Image", ( - ("Develop images and groups", ( - ("Create/edit imagery group", "Create/edit imagery group", "self.runMenuCmd", "i.group"), - ("Target imagery group", "Target imagery group", "self.runMenuCmd", "i.target"), - ("","","", ""), - ("Mosaic up to 4 adjacent images", "Mosaic up to 4 adjacent images", "self.runMenuCmd", "i.image.mosaic"), - )), - ("Manage image colors", ( - ("Color balance and enhance color tables of multiband imagery for rgb display", "Color balance and enhance color tables of multiband imagery for rgb display", "self.runMenuCmd", "i.landsat.rgb"), - ("Transform HIS (Hue/Intensity/Saturation) color image to RGB (Red/Green/Blue)", "Transform HIS (Hue/Intensity/Saturation) color image to RGB (Red/Green/Blue)", "self.runMenuCmd", "i.his.rgb"), - ("Transform RGB (Red/Green/Blue) color image to HIS (Hue/Intensity/Saturation)", "Transform RGB (Red/Green/Blue) color image to HIS (Hue/Intensity/Saturation)", "self.runMenuCmd", "i.rgb.his"), - )), - ("Rectify and georeference image group", ( - ("Set ground control points (GCP's) from raster map or keyboard entry", "Set ground control points (GCP's) from raster map or keyboard entry", "self.runMenuCmd", "i.points"), - ("Set ground control points (GCP's) from vector map or keyboard entry", "Set ground control points (GCP's) from vector map or keyboard entry", "self.runMenuCmd", "i.vpoints"), - ("Affine and Polynomial rectification (rubber sheet)", "Affine and Polynomial rectification (rubber sheet)", "self.runMenuCmd", "i.rectify"), - ("Ortho Photo rectification", "Ortho Photo rectification", "self.runMenuCmd", "i.ortho.photo"), - )), - ("","","", ""), - ("Brovey transformation and pan sharpening", "Brovey transformation and pan sharpening", "self.runMenuCmd", "i.fusion.brovey"), - ("Classify image", ( - ("Clustering input for unsupervised classification", "Clustering input for unsupervised classification", "self.runMenuCmd", "i.cluster"), - ("","","", ""), - ("Maximum likelihood Classification (MLC)", "Maximum likelihood Classification (MLC)", "self.runMenuCmd", "i.maxlik"), - ("Sequential maximum a posteriori classification (SMAP)", "Sequential maximum a posteriori classification (SMAP)", "self.runMenuCmd", "i.smap"), - ("","","", ""), - ("Interactive input for supervised classification", "Interactive input for supervised classification", "self.runMenuCmd", "i.class"), - ("Non-interactive input for supervised classification (MLC)", "Non-interactive input for supervised classification (MLC)", "self.runMenuCmd", "i.gensig"), - ("Non-interactive input for supervised classification (SMAP)", "Non-interactive input for supervised classification (SMAP)", "self.runMenuCmd", "i.gensigset"), - )), - ("Filter image", ( - ("Zero edge crossing detection", "Zero edge crossing detection", "self.runMenuCmd", "i.zc"), - ("User defined matrix/convolving filter", "User defined matrix/convolving filter", "self.runMenuCmd", "r.mfilter"), - )), - ("Spectral response", "Spectral response", "self.runMenuCmd", "i.spectral"), - ("Tasseled cap vegetation index", "Tasseled cap vegetation index", "self.runMenuCmd", "i.tasscap"), - ("Transform image", ( - ("Canonical component", "Canonical component", "self.runMenuCmd", "i.cca"), - ("Principal component", "Principal component", "self.runMenuCmd", "i.pca"), - ("Fast Fourier Transform", "Fast Fourier Transform", "self.runMenuCmd", "i.fft"), - ("Inverse Fast Fourier Transform", "Inverse Fast Fourier Transform", "self.runMenuCmd", "i.ifft"), - )), - ("","","", ""), - ("Report and statistics", ( - ("Report basic file information", "Report basic file information", "self.runMenuCmd", "r.info"), - ("Range of image values", "Range of image values", "self.runMenuCmd", "r.describe"), - ("","","", ""), - ("Bit pattern comparison for ID of low quality pixels", "Bit pattern comparison for ID of low quality pixels", "self.runMenuCmd", "r.bitpattern"), - ("Kappa classification accuracy assessment", "Kappa classification accuracy assessment", "self.runMenuCmd", "r.kappa"), - ("Optimum index factor for LandSat TM", "Optimum index factor for LandSat TM", "self.runMenuCmd", "i.oif"), - )), - ("","","", "") - )), - ("Database", ( - ("Query", "Query database", "self.Nomethod", ""), - ("","","", "") - )))] - - - - - - - - - - Copied: trunk/grassaddons/gui/gui_modules/menudata.py (from rev 300, trunk/grassaddons/gui/Gism/menudata.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/menudata.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/menudata.py 2007-03-25 06:28:21 UTC (rev 301) @@ -0,0 +1,327 @@ +class Data: + '''Data object that returns menu descriptions to be used in wxgui.py. + Probably could be changed to XML or *.dtd file.''' + def GetMenu(self): + return [( + ("Files", ( + ("Import", "Import files", "self.runMenuCmd", "r.in.gdal"), + ("Export", "Export files", "self.runMenuCmd", "r.out.gdal"), + ("","","", ""), + ("E&xit", "Exit from wxgui.py", "self.onCloseWindow", "") + )), + ("Config", ( + ("Region", "Set region", "self.runMenuCmd", "g.region"), + ("","","", "") + )), + ("Raster", ( + ("Develop map", ( + ("Digitize raster", "Digitize raster", "self.runMenuCmd", "r.digit"), + ("","","", ""), + ("Compress/decompress raster file", "Compress/decompress raster file", "self.runMenuCmd", "r.compress"), + ("Manage boundary definition (WHICH COMMAND?)", "Manage boundary definition", "self.runMenuCmd", "r.region"), + ("Manage null values", "Manage null values", "self.runMenuCmd", "r.null"), + ("Manage timestamp for files", "Manage timestamp for files", "self.runMenuCmd", "r.timestamp"), + ("Quantization for floating-point maps", "Quantization for floating-point maps", "self.runMenuCmd", "r.quant"), + ("Resample (change resolution) using nearest neighbor method", "Resample (change resolution) using nearest neighbor method", "self.runMenuCmd", "r.resample"), + ("Resample (change resolution) using regularized spline tension", "Resample (change resolution) using regularized spline tension", "self.runMenuCmd", "r.resamp.rst"), + ("Support file creation and maintenance", "Support file creation and maintenance", "self.runMenuCmd", "r.support.sh"), + ("","","", ""), + ("Reproject raster from other location", "Reproject raster from other location", "self.runMenuCmd", "r.proj"), + ("Generate tiling for other projection", "Generate tiling for other projection", "self.runMenuCmd", "r.tileset"), + )), + ("Manage map colors", ( + ("Set colors to predefined color tables", "Set colors to predefined color tables", "self.runMenuCmd", "r.colors"), + ("Set colors using color rules", "Set colors using color rules", "self.runMenuCmd", "r.colors.rules"), + ("","","", ""), + ("Blend 2 color maps to produce 3 RGB files", "Blend 2 color maps to produce 3 RGB files", "self.runMenuCmd", "r.blend"), + ("Create color image from RGB files", "Create color image from RGB files", "self.runMenuCmd", "r.composite"), + ("Create 3 RGB (red, green, blue) maps from 3 HIS (hue, intensity, saturation) maps", "Create 3 RGB (red, green, blue) maps from 3 HIS (hue, intensity, saturation) maps", "self.runMenuCmd", "r.his"), + )), + ("Query by coordinates", "Query by coordinates", "self.runMenuCmd", "r.what"), + ("","","", ""), + ("Create raster buffers", "Develop raster buffer", "self.runMenuCmd", "r.buffer"), + ("Create raster MASK", "Develop raster mask", "self.runMenuCmd", "r.mask"), + ("Locate closest points between areas in 2 raster maps", "r.distance", "self.runMenuCmd", "r.distance"), + ("Map calculator", "Map calculator", "self.runMenuCmd", "scripts/mapcalc_gparser.sh"), + ("Neighborhood analysis", ( + ("Moving window analysis of raster cells", "Moving window analysis of raster cells", "self.runMenuCmd", "r.neighbors"), + ("Analyze vector points in neighborhood of raster cells", "Analyze vector points in neighborhood of raster cells", "self.runMenuCmd", "v.neighbors"), + )), + ("Overlay maps", ( + ("Cross product", "Cross product", "self.runMenuCmd", "r.cross"), + ("Function of map series (time series)", "Function of map series (time series)", "self.runMenuCmd", "r.series"), + ("Patch maps", "Patch maps", "self.runMenuCmd", "r.patch"), + ("","","", ""), + ("Statistical calculations for cover map over base map", "Statistical calculations for cover map over base map", "self.runMenuCmd", "r.statistics"), + )), + ("Solar radiance and shadows", ( + ("Solar irradiance and daily irradiation", "Solar irradiance and daily irradiation", "self.runMenuCmd", "r.sun"), + ("Shadow map for sun position or date/time", "Shadow map for sun position or date/time", "self.runMenuCmd", "r.sunmask"), + )), + ("Terrain analysis", ( + ("Calculate cumulative movement costs between locales", "Calculate cumulative movement costs between locales", "self.runMenuCmd", "r.walk"), + ("cost surface", "cost surface", "self.runMenuCmd", "r.cost"), + ("Least cost route or flow", "Least cost route or flow", "self.runMenuCmd", "r.drain"), + ("Profile analysis", "Profile analysis", "self.runMenuCmd", "d.profile"), + ("Shaded relief map", "Shaded relief map", "self.runMenuCmd", "r.shaded.relief"), + ("Slope and aspect", "Slope and aspect", "self.runMenuCmd", "r.slope.aspect"), + ("Terrain parameters", "Terrain parameters", "self.runMenuCmd", "r.param.scale"), + ("Textural features", "Textural features", "self.runMenuCmd", "r.texture"), + ("Visibility/Line of sight", "Visibility/Line of sight", "self.runMenuCmd", "r.los"), + )), + ("Transform features", ( + ("Clump small areas (statistics calculated by r.volume)", "Clump small areas (statistics calculated by r.volume)", "self.runMenuCmd", "r.clump"), + ("Grow areas", "Grow areas", "self.runMenuCmd", "r.grow"), + ("Thin linear features", "Thin linear features", "self.runMenuCmd", "r.thin"), + )), + ("","","", ""), + ("Hydrologic modeling", ( + ("Carve stream channels into elevation map using vector streams map", "Carve stream channels into elevation map using vector streams map", "self.runMenuCmd", "r.carve"), + ("Depressionless elevation map and flowline map", "Depressionless elevation map and flowline map", "self.runMenuCmd", "r.fill.dir"), + ("Fill lake from seed point to specified level", "Fill lake from seed point to specified level", "self.runMenuCmd", "r.lake"), + ("Flow accumulation for massive grids (WHICH COMMAND?)", "Flow accumulation for massive grids", "self.runMenuCmd", "r.flow"), + ("Generate flow lines for raster map (WHICH COMMAND?)", "Generate flow lines for raster map", "self.runMenuCmd", "r.flow"), + ("SIMWE overland flow modeling (WHICH COMMAND?)", "SIMWE overland flow modeling", "self.runMenuCmd", "r.simwe"), + ("SIMWE sediment erosion, transport, deposition modeling (WHICH COMMAND?)", "SIMWE sediment erosion, transport, deposition modeling", "self.runMenuCmd", "r.simwe"), + ("Topographic index map", "Topographic index map", "self.runMenuCmd", "r.topidx"), + ("TOPMODEL simulation", "TOPMODEL simulation", "self.runMenuCmd", "r.topmodel"), + ("Watershed subbasins", "Watershed subbasins", "self.runMenuCmd", "r.basins.fill"), + ("Watershed analysis", "Watershed analysis", "self.runMenuCmd", "r.watershed"), + ("Watershed basin creation", "Watershed basin creation", "self.runMenuCmd", "r.water.outlet"), + )), + ("Landscape structure modeling", ( + ("Set up sampling and analysis framework", "Set up sampling and analysis framework", "self.runMenuCmd", "r.le.setup"), + ("","","", ""), + ("Analyze landscape characteristics", "Analyze landscape characteristics", "self.runMenuCmd", "r.le.pixel"), + ("Analyze landscape patch characteristics", "Analyze landscape patch characteristics", "self.runMenuCmd", "r.le.patch"), + ("Output landscape patch information", "Output landscape patch information", "self.runMenuCmd", "r.le.trace"), + )), + ("Wildfire modeling", ( + ("Generate rate of spread (ROS) maps", "Generate rate of spread (ROS) maps", "self.runMenuCmd", "r.ros"), + ("Generate least-cost spread paths", "Generate least-cost spread paths", "self.runMenuCmd", "r.spreadpath"), + ("Simulate anisotropic spread phenomena", "Simulate anisotropic spread phenomena", "self.runMenuCmd", "r.spread"), + )), + ("","","", ""), + ("Change category values and labels", ( + ("Edit category values of individual cells for displayed raster map", "Edit category values of individual cells for displayed raster map", "self.runMenuCmd", "d.rast.edit"), + ("","","", ""), + ("Reclassify categories for areas of specified sizes", "Reclassify categories for areas of specified sizes", "self.runMenuCmd", "r.reclass.area"), + ("Reclassify categories using rules", "Reclassify categories using rules", "self.runMenuCmd", "r.reclass.rules"), + ("Reclassify categories using rules file", "Reclassify categories using rules file", "self.runMenuCmd", "r.reclass.file"), + ("","","", ""), + ("Recode categories using rules (create new map)", "Recode categories using rules (create new map)", "self.runMenuCmd", "r.recode.rules"), + ("Recode categories using rules file (create new map)", "Recode categories using rules file (create new map)", "self.runMenuCmd", "r.recode.file"), + ("","","", ""), + ("Rescale categories (create new map)", "Rescale categories (create new map)", "self.runMenuCmd", "r.rescale"), + ("Rescale categories with equalized histogram (create new map)", "Rescale categories with equalized histogram (create new map)", "self.runMenuCmd", "r.rescale.eq"), + )), + ("","","", ""), + ("Generate concentric circles around points", "Generate concentric circles around points", "self.runMenuCmd", "r.circle"), + ("Generate random raster cells", ( + ("Generate random cells", "Generate random cells", "self.runMenuCmd", "r.random.cells"), + ("Generate random cells and vector points from raster map", "Generate random cells and vector points from raster map", "self.runMenuCmd", "r.random"), + )), + ("Generate surfaces", ( + ("Generate density surface using moving Gaussian kernel", "Generate density surface using moving Gaussian kernel", "self.runMenuCmd", "v.kernel"), + ("Generate fractal surface", "Generate fractal surface", "self.runMenuCmd", "r.surf.fractal"), + ("Generate gaussian deviates surface", "Generate gaussian deviates surface", "self.runMenuCmd", "r.surf.gauss"), + ("Generate plane", "Generate plane", "self.runMenuCmd", "r.plane"), + ("Generate random deviates surface", "Generate random deviates surface", "self.runMenuCmd", "r.surf.random"), + ("Generate random surface with spatial dependence", "Generate random surface with spatial dependence", "self.runMenuCmd", "r.random.surface"), + )), + ("Generate vector contour lines", "Generate vector contour lines", "self.runMenuCmd", "r.contour"), + ("Interpolate surfaces", ( + ("Bilinear interpolation from raster points", "Bilinear interpolation from raster points", "self.runMenuCmd", "r.bilinear"), + ("Inverse distance weighted interpolation from raster points", "Inverse distance weighted interpolation from raster points", "self.runMenuCmd", "r.surf.idw"), + ("Interpolation from raster contour", "Interpolation from raster contour", "self.runMenuCmd", "r.surf.contour"), + ("","","", ""), + ("Inverse distance weighted interpolation from vector points", "Inverse distance weighted interpolation from vector points", "self.runMenuCmd", "v.surf.idw"), + ("Regularized spline tension interpolation from vector points or contours (WHICH COMMAND ?)", "Regularized spline tension interpolation from vector points or contours", "self.runMenuCmd", "v.surf.rst"), + ("","","", ""), + ("Fill NULL cells by interpolation using regularized spline tension", "Fill NULL cells by interpolation using regularized spline tension", "self.runMenuCmd", "r.fillnulls"), + )), + ("","","", ""), + ("Report and statistics", ( + ("Report basic file information", "Report basic file information", "self.runMenuCmd", "r.info"), + ("Report category labels and values", "Report category labels and values", "self.runMenuCmd", "r.cats"), + ("","","", ""), + ("General statistics", "General statistics", "self.runMenuCmd", "r.stats"), + ("Range of all category values", "Range of all category values", "self.runMenuCmd", "r.describe"), + ("Sum all cell category values", "Sum all cell category values", "self.runMenuCmd", "r.sum"), + ("Sum area by map and category", "Sum area by map and category", "self.runMenuCmd", "r.report"), + ("Summary statistics for clumped cells (work with r.clump)", "Summary statistics for clumped cells (work with r.clump)", "self.runMenuCmd", "r.volume"), + ("Total surface area corrected for topography", "Total surface area corrected for topography", "self.runMenuCmd", "r.surf.area"), + ("Univariate statistics", "Univariate statistics", "self.runMenuCmd", "r.univar"), + ("Univariate statistics (script version)", "Univariate statistics (script version)", "self.runMenuCmd", "r.univar.sh"), + ("","","", ""), + ("Sample values along transects", "Sample values along transects", "self.runMenuCmd", "r.profile"), + ("Sample values along transects (use azimuth, distance)", "Sample values along transects (use azimuth, distance)", "self.runMenuCmd", "r.transect"), + ("","","", ""), + ("Covariance/correlation", "Covariance/correlation", "self.runMenuCmd", "r.covar"), + ("Linear regression between 2 maps", "Linear regression between 2 maps", "self.runMenuCmd", "r.regression.line"), + ("Mutual category occurrences (coincidence)", "Mutual category occurrences (coincidence)", "self.runMenuCmd", "r.coin"), + )), + ("","","", "") + )), + ("Vector", ( + ("Develop map", ( + ("Digitize", "Digitize vector", "self.runMenuCmd", "v.digit"), + ("","","", ""), + ("Create/Rebuild topology", "Create/Rebuild topology", "self.runMenuCmd", "v.build"), + ("Clean vector files", "clean vector files", "self.runMenuCmd", "v.clean"), + ("","","", ""), + ("Break lines at intersections", "Break lines at intersections", "self.runMenuCmd", "v.topo.check"), + ("Build polylines from adjacent segments", "Build polylines from adjacent segments", "self.runMenuCmd", "v.build.polylines"), + ("Split polylines into segments", "Split polylines into segments", "self.runMenuCmd", "v.segment"), + ("Create lines parallel to existing lines", "Create lines parallel to existing lines", "self.runMenuCmd", "v.parallel"), + ("","","", ""), + ("Convert vector feature types", "Convert vector feature types", "self.runMenuCmd", "v.type"), + ("Convert 2D vector to 3D by sampling raster", "Convert 2D vector to 3D by sampling raster", "self.runMenuCmd", "v.drape"), + ("Extrude 2D vector into 3D vector", "Extrude 2D vector into 3D vector", "self.runMenuCmd", "v.extrude"), + ("","","", ""), + ("Create text label file for vector features", "Create text label file for vector features", "self.runMenuCmd", "v.label"), + ("","","", ""), + ("Reproject vector from other location", "Reproject vector from other location", "self.runMenuCmd", "v.proj"), + ("","","", "") + )), + ("","","", ""), + ("vector<->database connections", ( + ("Create new vector as link to external OGR layer", "Create new vector as link to external OGR layer", "self.runMenuCmd", "v.external"), + ("Set database connection for vector attributes", "Set database connection for vector attributes", "self.runMenuCmd", "v.db.connect"), + )), + ("Query by attributes", "Query by attributes", "self.runMenuCmd", "v.extract"), + ("Query by coordinate(s)", "Query by coordinate(s)", "self.runMenuCmd", "v.what"), + ("Query by map features", "Query by map features", "self.runMenuCmd", "v.select"), + ("","","", ""), + ("Create vector buffers", "Create vector buffers", "self.runMenuCmd", "v.buffer"), + ("Linear referencing for vectors", ( + ("Create linear reference system", "Create linear reference system", "self.runMenuCmd", "v.lrs.create"), + ("Create stationing from input lines, and linear reference system", "Create stationing from input lines, and linear reference system", "self.runMenuCmd", "v.lrs.label"), + ("Create points/segments from input lines, linear reference system and positions read from stdin", "Create points/segments from input lines, linear reference system and positions read from stdin", "self.runMenuCmd", "v.lrs.segment"), + ("Find line id and real km+offset for given points in vector map using linear reference system", "Find line id and real km+offset for given points in vector map using linear reference system", "self.runMenuCmd", "v.lrs.where"), + )), + ("Neighborhood analysis", ( + ("Locate nearest feature to points or centroids", "Locate nearest feature to points or centroids", "self.runMenuCmd", "v.distance"), + ("Generate Thiessen polygons around points (Voronoi diagram)", "Generate Thiessen polygons around points (Voronoi diagram)", "self.runMenuCmd", "v.voronoi"), + ("Connect points to create Delaunay triangles", "Connect points to create Delaunay triangles", "self.runMenuCmd", "v.delaunay"), + )), + ("Network analysis", ( + ("Allocate subnets", "Allocate subnets", "self.runMenuCmd", "v.net.alloc"), + ("Network maintenance", "Network maintenance", "self.runMenuCmd", "v.net"), + ("Shortest route", "Shortest route", "self.runMenuCmd", "v.net.path"), + ("Shortest route (visualization only)", "Shortest route (visualization only)", "self.runMenuCmd", "d.path"), + ("Split net to bands between cost isolines", "Split net to bands between cost isolines", "self.runMenuCmd", "v.net.iso"), + ("Steiner tree", "Steiner tree", "self.runMenuCmd", "v.net.steiner"), + ("Traveling salesman analysis", "Traveling salesman analysis", "self.runMenuCmd", "v.net.salesman"), + )), + ("Overlay maps", ( + ("Overlay/combine 2 vector maps", "Overlay/combine 2 vector maps", "self.runMenuCmd", "v.overlay"), + ("Patch multiple maps (combine)", "Patch multiple maps (combine)", "self.runMenuCmd", "v.patch"), + )), + ("Generate area feature for extent of current region", "Generate area feature for extent of current region", "self.runMenuCmd", "v.in.region"), + ("Generate rectangular vector grid", "Generate rectangular vector grid", "self.runMenuCmd", "v.mkgrid"), + ("","","", ""), + ("Change attributes", ( + ("Attach/delete, or report categories", "Attach/delete, or report categories", "self.runMenuCmd", "v.category"), + ("Reclassify features using rules file", "Reclassify features using rules file", "self.runMenuCmd", "v.reclass"), + )), + ("","","", ""), + ("Work with vector points", ( + ("Generate points", ( + ("Generate points from database", "Generate points from database", "self.runMenuCmd", "v.in.db"), + ("Generate random points", "Generate random points", "self.runMenuCmd", "v.random"), + ("Random location perturbations of points", "Random location perturbations of points", "self.runMenuCmd", "v.perturb"), + )), + ("Generate areas from points", ( + ("Generate convex hull for point set", "Generate convex hull for point set", "self.runMenuCmd", "v.hull"), + ("Generate Delaunay triangles for point set", "Generate Delaunay triangles for point set", "self.runMenuCmd", "v.delaunay"), + ("Generate Voronoi diagram/Thiessen polygons for point set", "Generate Voronoi diagram/Thiessen polygons for point set", "self.runMenuCmd", "v.voronoi"), + )), + ("Sample raster maps", ( + ("Calculate statistics for raster map overlain by vector map", "Calculate statistics for raster map overlain by vector map", "self.runMenuCmd", "v.rast.stats"), + ("Sample raster maps at point locations", "Sample raster maps at point locations", "self.runMenuCmd", "v.what.rast"), + ("Sample raster neighborhood around points", "Sample raster neighborhood around points", "self.runMenuCmd", "v.sample"), + )), + ("Partition points into test/training sets for k-fold cross validation", "Partition points into test/training sets for k-fold cross validation", "self.runMenuCmd", "v.kcv"), + ("Transfer attribute data from queried vector map to points", "Transfer attribute data from queried vector map to points", "self.runMenuCmd", "v.what.vect"), + )), + ("","","", ""), + ("Reports and statistics", ( + ("Basic information", "Basic information", "self.runMenuCmd", "v.info"), + ("Load vector attributes to database or create reports", "Load vector attributes to database or create reports", "self.runMenuCmd", "v.to.db"), + ("Report areas for vector attribute categories", "Report areas for vector attribute categories", "self.runMenuCmd", "v.report"), + ("Univariate statistics", "Univariate statistics", "self.runMenuCmd", "v.univar"), + ("","","", ""), + ("Test normality of point distribution", "Test normality of point distribution", "self.runMenuCmd", "v.normal"), + ("Calculate stats for raster map underlying vector objects", "Calculate stats for raster map underlying vector objects", "self.runMenuCmd", "v.rast.stats"), + ("Indices of point counts in quadrats", "Indices of point counts in quadrats", "self.runMenuCmd", "v.qcount"), + )), + ("","","", "") + )), + ("Image", ( + ("Develop images and groups", ( + ("Create/edit imagery group", "Create/edit imagery group", "self.runMenuCmd", "i.group"), + ("Target imagery group", "Target imagery group", "self.runMenuCmd", "i.target"), + ("","","", ""), + ("Mosaic up to 4 adjacent images", "Mosaic up to 4 adjacent images", "self.runMenuCmd", "i.image.mosaic"), + )), + ("Manage image colors", ( + ("Color balance and enhance color tables of multiband imagery for rgb display", "Color balance and enhance color tables of multiband imagery for rgb display", "self.runMenuCmd", "i.landsat.rgb"), + ("Transform HIS (Hue/Intensity/Saturation) color image to RGB (Red/Green/Blue)", "Transform HIS (Hue/Intensity/Saturation) color image to RGB (Red/Green/Blue)", "self.runMenuCmd", "i.his.rgb"), + ("Transform RGB (Red/Green/Blue) color image to HIS (Hue/Intensity/Saturation)", "Transform RGB (Red/Green/Blue) color image to HIS (Hue/Intensity/Saturation)", "self.runMenuCmd", "i.rgb.his"), + )), + ("Rectify and georeference image group", ( + ("Set ground control points (GCP's) from raster map or keyboard entry", "Set ground control points (GCP's) from raster map or keyboard entry", "self.runMenuCmd", "i.points"), + ("Set ground control points (GCP's) from vector map or keyboard entry", "Set ground control points (GCP's) from vector map or keyboard entry", "self.runMenuCmd", "i.vpoints"), + ("Affine and Polynomial rectification (rubber sheet)", "Affine and Polynomial rectification (rubber sheet)", "self.runMenuCmd", "i.rectify"), + ("Ortho Photo rectification", "Ortho Photo rectification", "self.runMenuCmd", "i.ortho.photo"), + )), + ("","","", ""), + ("Brovey transformation and pan sharpening", "Brovey transformation and pan sharpening", "self.runMenuCmd", "i.fusion.brovey"), + ("Classify image", ( + ("Clustering input for unsupervised classification", "Clustering input for unsupervised classification", "self.runMenuCmd", "i.cluster"), + ("","","", ""), + ("Maximum likelihood Classification (MLC)", "Maximum likelihood Classification (MLC)", "self.runMenuCmd", "i.maxlik"), + ("Sequential maximum a posteriori classification (SMAP)", "Sequential maximum a posteriori classification (SMAP)", "self.runMenuCmd", "i.smap"), + ("","","", ""), + ("Interactive input for supervised classification", "Interactive input for supervised classification", "self.runMenuCmd", "i.class"), + ("Non-interactive input for supervised classification (MLC)", "Non-interactive input for supervised classification (MLC)", "self.runMenuCmd", "i.gensig"), + ("Non-interactive input for supervised classification (SMAP)", "Non-interactive input for supervised classification (SMAP)", "self.runMenuCmd", "i.gensigset"), + )), + ("Filter image", ( + ("Zero edge crossing detection", "Zero edge crossing detection", "self.runMenuCmd", "i.zc"), + ("User defined matrix/convolving filter", "User defined matrix/convolving filter", "self.runMenuCmd", "r.mfilter"), + )), + ("Spectral response", "Spectral response", "self.runMenuCmd", "i.spectral"), + ("Tasseled cap vegetation index", "Tasseled cap vegetation index", "self.runMenuCmd", "i.tasscap"), + ("Transform image", ( + ("Canonical component", "Canonical component", "self.runMenuCmd", "i.cca"), + ("Principal component", "Principal component", "self.runMenuCmd", "i.pca"), + ("Fast Fourier Transform", "Fast Fourier Transform", "self.runMenuCmd", "i.fft"), + ("Inverse Fast Fourier Transform", "Inverse Fast Fourier Transform", "self.runMenuCmd", "i.ifft"), + )), + ("","","", ""), + ("Report and statistics", ( + ("Report basic file information", "Report basic file information", "self.runMenuCmd", "r.info"), + ("Range of image values", "Range of image values", "self.runMenuCmd", "r.describe"), + ("","","", ""), + ("Bit pattern comparison for ID of low quality pixels", "Bit pattern comparison for ID of low quality pixels", "self.runMenuCmd", "r.bitpattern"), + ("Kappa classification accuracy assessment", "Kappa classification accuracy assessment", "self.runMenuCmd", "r.kappa"), + ("Optimum index factor for LandSat TM", "Optimum index factor for LandSat TM", "self.runMenuCmd", "i.oif"), + )), + ("","","", "") + )), + ("Database", ( + ("Query", "Query database", "self.Nomethod", ""), + ("","","", "") + )))] + + + + + + + + + + From barton at grass.itc.it Sun Mar 25 08:30:32 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:30:34 2007 Subject: [grass-addons] r302 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250630.l2P6UWoq021767@grass.itc.it> Author: barton Date: 2007-03-25 08:30:17 +0200 (Sun, 25 Mar 2007) New Revision: 302 Added: trunk/grassaddons/gui/gui_modules/menuform.py Removed: trunk/grassaddons/gui/Gism/menuform.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/menuform.py =================================================================== --- trunk/grassaddons/gui/Gism/menuform.py 2007-03-25 06:28:21 UTC (rev 301) +++ trunk/grassaddons/gui/Gism/menuform.py 2007-03-25 06:30:17 UTC (rev 302) @@ -1,667 +0,0 @@ -#! /usr/bin/python -""" Construct simple wx.Python GUI from a GRASS command interface description. - -# Copyright (C) 2000-2007 by the GRASS Development Team -# Author: Jan-Oliver Wagner -# improved by: Bernhard Reiter -# Improved by: Michael Barton, Arizona State University -# Improved by: Daniel Calvelo -# -# This program is free software under the GPL (>=v2) -# Read the file COPYING coming with GRASS for details. - -# This program is just a coarse approach to -# automatically build a GUI from a xml-based -# GRASS user interface description. -# -# You need to have Python 2.4, wx.Python 2.6 and python-xml. -# -# The XML stream is read from stdin, thus you -# may call it for instance this way: -# r.basins.fill --interface-description | python grassgui.py -# or -# r.basins.fill --interface-description | ./grassgui.py -# -# Or you set an alias or wrap the call up in a nice -# shell script, GUI environment ... please contribute your idea. -# -# Updated to wxPython 2.6 syntax. Methods added to make it callable by gui. -# Method added to automatically re-run with pythonw on a Mac. -""" -__version__ ="$Date: 2006/08/06 21:21:01 $" - -import wx -import sys -import string -import select -import wx.lib.flatnotebook as FN -import wx.lib.colourselect as csel - -# Do the python 2.0 standard xml thing and map it on the old names -import xml.sax -import xml.sax.handler -HandlerBase=xml.sax.handler.ContentHandler -from xml.sax import make_parser - -import os -from os import system -try: - import subprocess -except: - from compat import subprocess -import re - - -def reexec_with_pythonw(): - 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:]) - -reexec_with_pythonw() - -ID_PARAM_START = 800 -ID_FLAG_START = 900 -ID_MULTI_START = 1000 - -ID_ABOUT_COMMAND = 102 - -VSPACE = 4 -HSPACE = 4 -MENU_HEIGHT = 30 -STATUSBAR_HEIGHT = 30 -ENTRY_HEIGHT = 20 -STRING_ENTRY_WIDTH = 300 -BUTTON_HEIGHT = 44 -BUTTON_WIDTH = 100 - -t_colors = "red,orange,yellow,green,blue,indigo,violet,white,black,gray,brown,magenta,aqua,grey,cyan,purple" -t_rgb = ( # From lib/gis/col_str.c - (255, 0, 0), - (255,128, 0), - (255,255, 0), - ( 0,255, 0), - ( 0, 0,255), - ( 0,128,255), - (128, 0,255), - (255,255,255), - ( 0, 0, 0), - (128,128,128), - (180, 77, 25), - (255, 0,255), - (100,128,255), - (128,128,128), - ( 0,255,255), - (128, 0,128) -) -t_color = t_colors.split(',') -color_str2rgb = {} -color_rgb2str = {} -for c in range(0,len(t_rgb)): - color_str2rgb[ t_color[c] ] = t_rgb[ c ] - color_rgb2str[ t_rgb[ c ] ] = t_color[ c ] - - -def normalize_whitespace(text): - "Remove redundant whitespace from a string" - return string.join( string.split(text), ' ') - -def escape_ampersand(text): - "Escapes ampersands with additional ampersand for GUI" - return string.replace(text, "&", "&&") - -class testSAXContentHandler(HandlerBase): -# SAX compliant - def characters(self, ch, start, length): - pass - -def test_for_broken_SAX(): - ch=testSAXContentHandler() - try: - xml.sax.parseString(""" - Text goes here - """,ch) - except TypeError: - return 1 - return 0 - -class grass_task: - pass - -def grass_task_init(): - grass_task.name = 'unknown' - grass_task.params = [] - grass_task.description = '' - grass_task.flags = [] -grass_task_init() - -class processTask(HandlerBase): - def __init__(self): - self.inDescriptionContent = 0 - self.inDefaultContent = 0 - self.inValueContent = 0 - self.inParameter = 0 - self.inFlag = 0 - self.inGispromptContent = 0 - self.inGuisection = 0 - - def startElement(self, name, attrs): - - if name == 'task': - grass_task.name = attrs.get('name', None) - - if name == 'parameter': - self.inParameter = 1; - self.param_description = '' - self.param_default = '' - self.param_values = [] - self.param_gisprompt = False - self.param_age = '' - self.param_element = '' - self.param_prompt = '' - self.param_guisection = '' - # Look for the parameter name, type, requiredness - self.param_name = attrs.get('name', None) - self.param_type = attrs.get('type', None) - self.param_required = attrs.get('required', None) - self.param_multiple = attrs.get('multiple', None) - - if name == 'flag': - self.inFlag = 1; - self.flag_description = '' - self.flag_default = '' - self.flag_values = [] - # Look for the flag name - self.flag_name = attrs.get('name', None) - - if name == 'description': - self.inDescriptionContent = 1 - self.description = '' - - if name == 'default': - self.inDefaultContent = 1 - self.param_default = '' - - if name == 'value': - self.inValueContent = 1 - self.value_tmp = '' - - if name == 'gisprompt': - self.param_gisprompt = True - self.param_age = attrs.get('age', None) - self.param_element = attrs.get('element', None) - self.param_prompt = attrs.get('prompt', None) - - if name == 'guisection': - self.inGuisection = 1 - self.param_guisection = '' - - # works with python 2.0, but is not SAX compliant - def characters(self, ch): - self.my_characters(ch) - - def my_characters(self, ch): - if self.inDescriptionContent: - self.description = self.description + ch - if self.inDefaultContent: - self.param_default = self.param_default + ch - if self.inValueContent: - self.value_tmp = self.value_tmp + ch - if self.inGuisection: - self.param_guisection = self.param_guisection + ch - - def endElement(self, name): - # If it's not a parameter element, ignore it - if name == 'parameter': - self.inParameter = 0; - grass_task.params.append({ - "name" : self.param_name, - "type" : self.param_type, - "required" : self.param_required, - "multiple" : self.param_multiple, - "description" : self.param_description, - 'gisprompt' : self.param_gisprompt, - 'age' : self.param_age, - 'element' :self.param_element, - 'prompt' : self.param_prompt, - "guisection" : self.param_guisection, - "default" : self.param_default, - "values" : self.param_values, - "value" : '' }) - - if name == 'flag': - self.inFlag = 0; - grass_task.flags.append({ - "name" : self.flag_name, - "description" : self.flag_description } ) - - if name == 'description': - if self.inParameter: - self.param_description = normalize_whitespace(self.description) - elif self.inFlag: - self.flag_description = normalize_whitespace(self.description) - else: - grass_task.description = normalize_whitespace(self.description) - self.inDescriptionContent = 0 - - if name == 'default': - self.param_default = normalize_whitespace(self.param_default) - self.inDefaultContent = 0 - - if name == 'value': - v = normalize_whitespace(self.value_tmp) - self.param_values = self.param_values + [ normalize_whitespace(self.value_tmp) ] - self.inValueContent = 0 - - if name == 'guisection': - self.param_guisection = normalize_whitespace(self.param_guisection) - self.inGuisection = 0 - - -class mainFrame(wx.Frame): - """This is the Frame containing the dialog for options input. - - The dialog is organized in a notebook according to the guisections - defined by each GRASS command.""" - def __init__(self, parent, ID, get_dcmd=None, layer=None, dcmd_params=None): - wx.Frame.__init__(self, parent, ID, grass_task.name, - wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) - - self.CreateStatusBar() - self.SetStatusText("Enter parameters for " + grass_task.name) - self.parent = parent - self.selection = '' #selection from GIS element selector - self.paramdict = {} # dictionary of controls and their parameter values - self.get_dcmd = get_dcmd - self.dcmd_params = dcmd_params #this should be passed from the layer tree eventually - self.layer = layer - - menu = wx.Menu() - menu.Append(wx.ID_ABOUT, "&About GrassGUI", - "Information about GrassGUI") - menu.Append(ID_ABOUT_COMMAND, "&About " + grass_task.name, - "Short descripton of GRASS command " + grass_task.name) - menu.AppendSeparator() - menu.Append(wx.ID_EXIT, "E&xit", "Terminate the program") - - menuBar = wx.MenuBar() - menuBar.Append(menu, "&File"); - - self.SetMenuBar(menuBar) - self.guisizer = wx.BoxSizer(wx.VERTICAL) - - sections = [] - is_section = {} - for task in grass_task.params + grass_task.flags: - if not task.has_key('guisection') or task['guisection']=='': - task['guisection'] = 'Options' - if not is_section.has_key(task['guisection']): - is_section[task['guisection']] = 1 - sections.append( task['guisection'] ) - - self.notebookpanel = wx.ScrolledWindow( self, id=wx.ID_ANY ) - self.notebookpanel.SetScrollRate(10,10) - self.panelsizer = wx.BoxSizer(wx.VERTICAL) - - nbStyle=FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS|FN.FNB_VC8|FN.FNB_BACKGROUND_GRADIENT - self.notebook = FN.FlatNotebook(self.notebookpanel, id=wx.ID_ANY, style=nbStyle) - self.notebook.SetTabAreaColour(wx.Colour(125,200,175)) - self.tab = {} - self.tabsizer = {} - is_first = True - for section in sections: - self.tab[section] = wx.Panel(self.notebook, id = wx.ID_ANY ) - self.tabsizer[section] = wx.BoxSizer(wx.VERTICAL) - self.notebook.AddPage( self.tab[section], text = section, select = is_first ) - is_first = False - - self.panelsizer.Add( self.notebook, flag=wx.EXPAND ) - self.guisizer.Add( self.notebookpanel, flag = wx.EXPAND ) - - p_count = -1 - for p in grass_task.params: - p_count += 1 # Needed for checkboxes hack - which_sizer = self.tabsizer[ p['guisection'] ] - which_panel = self.tab[ p['guisection'] ] - title = escape_ampersand(p['description']) - if p['required'] == 'no': - title = "[optional] " + title - if p['multiple'] == 'yes' and len( p['values'] ) == 0: - title = "[multiple] " + title - p['value'] = p['default'] - # inserting existing values from d.* command in layer tree - if self.dcmd_params != None: - for dparam in self.dcmd_params: - if p == dparam: - p['value'] = self.dcmd_params[dparam] - if (len(p['values']) > 0): - - valuelist=map(str,p['values']) - if p['multiple'] == 'yes': - hSizer=wx.StaticBoxSizer( wx.StaticBox(which_panel,0,title+":"), - wx.HORIZONTAL ) - v_count = 0 - isDefault = {} - for defval in p['value'].split(','): - isDefault[ defval ] = 'yes' - for val in valuelist: - # This is the checkboxes hack - idForWX = ID_MULTI_START + p_count*20 + v_count - chkbox = wx.CheckBox( which_panel, idForWX, val+" " ) - if isDefault.has_key(val): chkbox.SetValue( True ) - hSizer.Add( chkbox,0,wx.ADJUST_MINSIZE,0 ) - self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBoxMulti) - v_count += 1 - which_sizer.Add( hSizer, 0, wx.ADJUST_MINSIZE, 5) - else: - txt1 = wx.StaticText(which_panel, label = title + ':' ) - which_sizer.Add(txt1, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) - self.cb = wx.ComboBox(which_panel, -1, p['default'], - wx.Point(-1, -1), wx.Size(STRING_ENTRY_WIDTH, -1), - valuelist, wx.CB_DROPDOWN) - which_sizer.Add(self.cb, 0, wx.ADJUST_MINSIZE, 5) - self.paramdict[self.cb] = ID_PARAM_START + p_count - self.cb.Bind( wx.EVT_COMBOBOX, self.EvtComboBox) - - if (p['type'] in ('string','integer','float') - and len(p['values']) == 0 - and p['gisprompt'] == False - and p['prompt'] != 'color'): - - txt2 = wx.StaticText(which_panel, label = title + ':' ) - which_sizer.Add(txt2, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) - - self.txt3 = wx.TextCtrl(which_panel, value = p['default'], - size = (STRING_ENTRY_WIDTH, ENTRY_HEIGHT)) - which_sizer.Add(self.txt3, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) - self.paramdict[self.txt3] = ID_PARAM_START + p_count - self.txt3.Bind(wx.EVT_TEXT, self.EvtText) - - if p['type'] == 'string' and p['gisprompt'] == True: - txt4 = wx.StaticText(which_panel, label = title + ':') - which_sizer.Add(txt4, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) - if p['prompt'] != 'color': - self.selection = select.Select(which_panel, id=wx.ID_ANY, size=(250,-1), - type=p['element']) - which_sizer.Add(self.selection, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) - self.paramdict[self.selection] = ID_PARAM_START + p_count - self.selection.Bind(wx.EVT_TEXT, self.EvtText) - elif p['prompt'] == 'color': - if p['default'] != '': - if p['default'][0] in "0123456789": - default_color = tuple(map(int,p['default'].split( ':' ))) - label_color = p['default'] - else: - # Convert color names to RGB - try: - default_color = color_str2rgb[ p['default'] ] - label_color = p['default'] - except KeyError: - default_color = (200,200,200) - label_color = 'Select Color' - else: - default_color = (200,200,200) - label_color = 'Select Color' - btn_colour = csel.ColourSelect(which_panel, -1, label_color, default_color, wx.DefaultPosition, (150,-1) ) - which_sizer.Add(btn_colour, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) - self.paramdict[btn_colour] = ID_PARAM_START + p_count - self.Bind(csel.EVT_COLOURSELECT, self.OnColorButton, btn_colour) - - f_count = -1 - for f in grass_task.flags: - f_count += 1 - which_sizer = self.tabsizer[ f['guisection'] ] - which_panel = self.tab[ f['guisection'] ] - title = escape_ampersand(f['description']) - self.chk = wx.CheckBox(which_panel,-1, label = title, style = wx.NO_BORDER) - which_sizer.Add(self.chk, 0, wx.EXPAND| wx.ALL, 5) - self.paramdict[self.chk] = ID_FLAG_START + f_count - self.chk.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox) - - btnsizer = wx.BoxSizer(wx.HORIZONTAL) - self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "Cancel") - btnsizer.Add(self.btn_cancel, 0, wx.ALL| wx.ALIGN_CENTER, 10) - if self.get_dcmd is not None: # A callback has been set up - self.btn_apply = wx.Button(self, wx.ID_APPLY, "Apply") - btnsizer.Add(self.btn_apply, 0, wx.ALL| wx.ALIGN_CENTER, 10) - self.btn_ok = wx.Button(self, wx.ID_OK, "OK") - btnsizer.Add(self.btn_ok, 0, wx.ALL| wx.ALIGN_CENTER, 10) - self.btn_ok.SetDefault() - self.btn_apply.Bind(wx.EVT_BUTTON, self.OnApply) - self.btn_ok.Bind(wx.EVT_BUTTON, self.OnOK) - else: # We're standalone - self.btn_run = wx.Button(self, wx.ID_OK, "Run") - btnsizer.Add(self.btn_run, 0, wx.ALL| wx.ALIGN_CENTER, 10) - self.btn_run.SetDefault() - self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun) - self.guisizer.Add(btnsizer, 0, wx.EXPAND) - wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout) - wx.EVT_MENU(self, ID_ABOUT_COMMAND, self.OnAboutCommand) - wx.EVT_MENU(self, wx.ID_EXIT, self.OnCancel) - self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) - self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) - - xsizelist = [] - ysizelist = [] - for section in sections: - self.tabsizer[section].SetSizeHints( self.tab[section] ) - self.tabsizer[section].Fit( self.tab[section] ) - self.tab[section].SetAutoLayout(True) - self.tab[section].SetSizer( self.tabsizer[section] ) - self.tab[section].Layout() - xsizelist.append(self.tabsizer[section].GetMinSize()[0]) - ysizelist.append(self.tabsizer[section].GetMinSize()[1]) - - maxminsize = (max(xsizelist),max(ysizelist)) - self.notebook.SetInitialSize(maxminsize) - self.panelsizer.SetSizeHints( self.notebookpanel ) - self.panelsizer.Fit( self.notebookpanel ) - self.notebookpanel.SetSizer(self.panelsizer) - self.notebookpanel.SetAutoLayout(True) - self.notebookpanel.Layout() - - self.guisizer.SetSizeHints(self) -# self.guisizer.SetMinSize(maxminsize) - self.SetAutoLayout(True) - self.SetSizer(self.guisizer) - self.Layout() - - - def OnColorButton(self, event): - colorchooser = wx.FindWindowById( event.GetId() ) - new_color = colorchooser.GetValue() - # This is weird: new_color is a 4-tuple and new_color[:] is a 3-tuple - # under wx2.8.1 - new_label = color_rgb2str.get( new_color[:], ':'.join(map(str,new_color)) ) - colorchooser.SetLabel( new_label ) - colorchooser.SetColour( new_color ) - colorchooser.Refresh() - self.getValues() - - def getValues(self): - for item in self.paramdict.items(): - param_num = item[1] - if 'CheckBox' in str(item[0]): - tasktype = grass_task.flags - num = param_num-ID_FLAG_START - param_val = item[0].GetValue() - else: - tasktype = grass_task.params - num = param_num-ID_PARAM_START - if 'ColourSelect' in str(item[0]): - data = item[0].GetValue() - param_val = str(data[0])+':'+str(data[1])+':'+str(data[2]) - else: - param_val = item[0].GetValue() - tasktype[num]['value'] = param_val - - def EvtText(self, event): - self.getValues() - - def EvtCheckBox(self, event): - self.getValues() - - def EvtComboBox(self, event): - self.getValues() - - def EvtCheckBoxMulti(self, event): - """Fill the values ,-separated string according to current status of the checkboxes.""" - theParamId = (event.GetId()-ID_MULTI_START ) / 20 - theCheckedId = (event.GetId()-ID_MULTI_START ) % 20 - # Unpack current value list - currentValues={} - for isThere in grass_task.params[theParamId]['value'].split(','): - currentValues[isThere] = 1 - theValue = grass_task.params[theParamId]['values'][theCheckedId] - if event.Checked(): - currentValues[ theValue ] = 1 - else: - del currentValues[ theValue ] - # Pack it back - grass_task.params[theParamId]['value'] = ','.join( currentValues.keys() ) - - def createCmd(self): - """Produce a command line string for feeding into GRASS.""" - cmd = grass_task.name - errors = 0 - errStr = "" - for flag in grass_task.flags: - if 'value' in flag and flag['value']: - cmd += ' -' + flag['name'] - for p in grass_task.params: - if p['value'] == '' and p['required'] != 'no': - errStr += "Parameter " + p['name'] + "(" + p['description'] + ") is missing\n" - errors += 1 - if p['value'] != '' and p['value'] != p['default'] : - cmd += ' ' + p['name'] + '=' + p['value'] - if errors: - self.OnError(errStr) - return None - return cmd - - def OnOK(self, event): - cmd = self.OnApply(event) - if cmd is not None and self.get_dcmd is not None: - self.OnCancel(event) - - def OnApply(self, event): - cmd = self.createCmd() - - if cmd is not None and self.get_dcmd is not None: - # return d.* command to layer tree for rendering - self.get_dcmd(cmd, self.layer) - # echo d.* command to output console - self.parent.writeDCommand(cmd) - return cmd - - def OnRun(self, event): - cmd = self.createCmd() - - if cmd != None and cmd[0:2] != "d.": - # Send any non-display command to parent window (probably wxgui.py) - if self.parent > -1: - # put to parents - try: - self.parent.goutput.runCmd(cmd) - except AttributeError,e: - print >>sys.stderr, "%s: Propably not running in wxgui.py session?" % (e) - print >>sys.stderr, "parent window is: %s" % (str(self.parent)) - # Send any other command to the shell. - else: - try: - retcode = subprocess.call(cmd, shell=True) - if retcode < 0: - print >>sys.stderr, "Child was terminated by signal", -retcode - elif retcode > 0: - print >>sys.stderr, "Child returned", retcode - except OSError, e: - print >>sys.stderr, "Execution failed:", e - - def OnError(self, errMsg): - dlg = wx.MessageDialog(self, errMsg, "Error", wx.OK | wx.ICON_ERROR) - dlg.ShowModal() - dlg.Destroy() - - def OnCancel(self, event): - self.Close(True) - for t in self.tab.values(): t = None - for t in self.tabsizer.values(): t.Clear(True) - self.notebook.Destroy() - self.guisizer.Clear(True) - grass_task_init() - self.Destroy() - - def OnCloseWindow(self, event): - grass_task_init() - self.Destroy() - - def OnAbout(self, event): - dlg = wx.MessageDialog(self, "This is a sample program for\n" - "GRASS command interface parsing\n" - "and automatic GUI building. \n%s" %(__version__), - "About GrassGUI", wx.OK | wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - - def OnAboutCommand(self, event): - dlg = wx.MessageDialog(self, - grass_task.name+": "+grass_task.description, - "About " + grass_task.name, - wx.OK | wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - - -class GrassGUIApp(wx.App): - def OnInit(self): - self.frame = mainFrame(None, -1) - self.frame.Show(True) - self.SetTopWindow(self.frame) - return True - -class GUI: - def __init__(self, parent=-1): - '''Parses GRASS commands when module is imported and used - from wxgui.py''' - self.parent = parent - - def parseCommand(self, cmd, gmpath, completed=None, parentframe=-1 ): - if completed == None: - self.get_dcmd = None - layer = None - else: - self.get_dcmd = completed[0] - layer = completed[1] - cmdlst = [] - cmdlst = cmd.split(' ') - - if parentframe > -1: - self.parent = parentframe - - if len(cmdlst) > 1: - print "usage: %s " % cmdlst[0] - else: - # parse the interface decription - cmd = cmd + r' --interface-description' - cmdout = os.popen(cmd, "r").read() - p = re.compile( '(grass-interface.dtd)') - cmdout2 = p.sub( gmpath+r'/grass-interface.dtd', cmdout) - handler = processTask() - xml.sax.parseString(cmdout2, handler) - - mf = mainFrame(self.parent ,-1, self.get_dcmd, layer) - mf.Show(True) - -if __name__ == "__main__": - # Just for testing purposes - - # Create the application - if len(sys.argv) != 2: - print "Usage: %s " % sys.argv[0] - sys.exit() - app = GrassGUIApp(0) - # Parsing if run from command line: find out the command to run - gui = GUI(app.frame) - gui.parseCommand( sys.argv[1], os.getenv("GISBASE") + "/etc/wx/gui_modules") - app.MainLoop() - Copied: trunk/grassaddons/gui/gui_modules/menuform.py (from rev 301, trunk/grassaddons/gui/Gism/menuform.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-25 06:30:17 UTC (rev 302) @@ -0,0 +1,667 @@ +#! /usr/bin/python +""" Construct simple wx.Python GUI from a GRASS command interface description. + +# Copyright (C) 2000-2007 by the GRASS Development Team +# Author: Jan-Oliver Wagner +# improved by: Bernhard Reiter +# Improved by: Michael Barton, Arizona State University +# Improved by: Daniel Calvelo +# +# This program is free software under the GPL (>=v2) +# Read the file COPYING coming with GRASS for details. + +# This program is just a coarse approach to +# automatically build a GUI from a xml-based +# GRASS user interface description. +# +# You need to have Python 2.4, wx.Python 2.6 and python-xml. +# +# The XML stream is read from stdin, thus you +# may call it for instance this way: +# r.basins.fill --interface-description | python grassgui.py +# or +# r.basins.fill --interface-description | ./grassgui.py +# +# Or you set an alias or wrap the call up in a nice +# shell script, GUI environment ... please contribute your idea. +# +# Updated to wxPython 2.6 syntax. Methods added to make it callable by gui. +# Method added to automatically re-run with pythonw on a Mac. +""" +__version__ ="$Date: 2006/08/06 21:21:01 $" + +import wx +import sys +import string +import select +import wx.lib.flatnotebook as FN +import wx.lib.colourselect as csel + +# Do the python 2.0 standard xml thing and map it on the old names +import xml.sax +import xml.sax.handler +HandlerBase=xml.sax.handler.ContentHandler +from xml.sax import make_parser + +import os +from os import system +try: + import subprocess +except: + from compat import subprocess +import re + + +def reexec_with_pythonw(): + 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:]) + +reexec_with_pythonw() + +ID_PARAM_START = 800 +ID_FLAG_START = 900 +ID_MULTI_START = 1000 + +ID_ABOUT_COMMAND = 102 + +VSPACE = 4 +HSPACE = 4 +MENU_HEIGHT = 30 +STATUSBAR_HEIGHT = 30 +ENTRY_HEIGHT = 20 +STRING_ENTRY_WIDTH = 300 +BUTTON_HEIGHT = 44 +BUTTON_WIDTH = 100 + +t_colors = "red,orange,yellow,green,blue,indigo,violet,white,black,gray,brown,magenta,aqua,grey,cyan,purple" +t_rgb = ( # From lib/gis/col_str.c + (255, 0, 0), + (255,128, 0), + (255,255, 0), + ( 0,255, 0), + ( 0, 0,255), + ( 0,128,255), + (128, 0,255), + (255,255,255), + ( 0, 0, 0), + (128,128,128), + (180, 77, 25), + (255, 0,255), + (100,128,255), + (128,128,128), + ( 0,255,255), + (128, 0,128) +) +t_color = t_colors.split(',') +color_str2rgb = {} +color_rgb2str = {} +for c in range(0,len(t_rgb)): + color_str2rgb[ t_color[c] ] = t_rgb[ c ] + color_rgb2str[ t_rgb[ c ] ] = t_color[ c ] + + +def normalize_whitespace(text): + "Remove redundant whitespace from a string" + return string.join( string.split(text), ' ') + +def escape_ampersand(text): + "Escapes ampersands with additional ampersand for GUI" + return string.replace(text, "&", "&&") + +class testSAXContentHandler(HandlerBase): +# SAX compliant + def characters(self, ch, start, length): + pass + +def test_for_broken_SAX(): + ch=testSAXContentHandler() + try: + xml.sax.parseString(""" + Text goes here + """,ch) + except TypeError: + return 1 + return 0 + +class grass_task: + pass + +def grass_task_init(): + grass_task.name = 'unknown' + grass_task.params = [] + grass_task.description = '' + grass_task.flags = [] +grass_task_init() + +class processTask(HandlerBase): + def __init__(self): + self.inDescriptionContent = 0 + self.inDefaultContent = 0 + self.inValueContent = 0 + self.inParameter = 0 + self.inFlag = 0 + self.inGispromptContent = 0 + self.inGuisection = 0 + + def startElement(self, name, attrs): + + if name == 'task': + grass_task.name = attrs.get('name', None) + + if name == 'parameter': + self.inParameter = 1; + self.param_description = '' + self.param_default = '' + self.param_values = [] + self.param_gisprompt = False + self.param_age = '' + self.param_element = '' + self.param_prompt = '' + self.param_guisection = '' + # Look for the parameter name, type, requiredness + self.param_name = attrs.get('name', None) + self.param_type = attrs.get('type', None) + self.param_required = attrs.get('required', None) + self.param_multiple = attrs.get('multiple', None) + + if name == 'flag': + self.inFlag = 1; + self.flag_description = '' + self.flag_default = '' + self.flag_values = [] + # Look for the flag name + self.flag_name = attrs.get('name', None) + + if name == 'description': + self.inDescriptionContent = 1 + self.description = '' + + if name == 'default': + self.inDefaultContent = 1 + self.param_default = '' + + if name == 'value': + self.inValueContent = 1 + self.value_tmp = '' + + if name == 'gisprompt': + self.param_gisprompt = True + self.param_age = attrs.get('age', None) + self.param_element = attrs.get('element', None) + self.param_prompt = attrs.get('prompt', None) + + if name == 'guisection': + self.inGuisection = 1 + self.param_guisection = '' + + # works with python 2.0, but is not SAX compliant + def characters(self, ch): + self.my_characters(ch) + + def my_characters(self, ch): + if self.inDescriptionContent: + self.description = self.description + ch + if self.inDefaultContent: + self.param_default = self.param_default + ch + if self.inValueContent: + self.value_tmp = self.value_tmp + ch + if self.inGuisection: + self.param_guisection = self.param_guisection + ch + + def endElement(self, name): + # If it's not a parameter element, ignore it + if name == 'parameter': + self.inParameter = 0; + grass_task.params.append({ + "name" : self.param_name, + "type" : self.param_type, + "required" : self.param_required, + "multiple" : self.param_multiple, + "description" : self.param_description, + 'gisprompt' : self.param_gisprompt, + 'age' : self.param_age, + 'element' :self.param_element, + 'prompt' : self.param_prompt, + "guisection" : self.param_guisection, + "default" : self.param_default, + "values" : self.param_values, + "value" : '' }) + + if name == 'flag': + self.inFlag = 0; + grass_task.flags.append({ + "name" : self.flag_name, + "description" : self.flag_description } ) + + if name == 'description': + if self.inParameter: + self.param_description = normalize_whitespace(self.description) + elif self.inFlag: + self.flag_description = normalize_whitespace(self.description) + else: + grass_task.description = normalize_whitespace(self.description) + self.inDescriptionContent = 0 + + if name == 'default': + self.param_default = normalize_whitespace(self.param_default) + self.inDefaultContent = 0 + + if name == 'value': + v = normalize_whitespace(self.value_tmp) + self.param_values = self.param_values + [ normalize_whitespace(self.value_tmp) ] + self.inValueContent = 0 + + if name == 'guisection': + self.param_guisection = normalize_whitespace(self.param_guisection) + self.inGuisection = 0 + + +class mainFrame(wx.Frame): + """This is the Frame containing the dialog for options input. + + The dialog is organized in a notebook according to the guisections + defined by each GRASS command.""" + def __init__(self, parent, ID, get_dcmd=None, layer=None, dcmd_params=None): + wx.Frame.__init__(self, parent, ID, grass_task.name, + wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) + + self.CreateStatusBar() + self.SetStatusText("Enter parameters for " + grass_task.name) + self.parent = parent + self.selection = '' #selection from GIS element selector + self.paramdict = {} # dictionary of controls and their parameter values + self.get_dcmd = get_dcmd + self.dcmd_params = dcmd_params #this should be passed from the layer tree eventually + self.layer = layer + + menu = wx.Menu() + menu.Append(wx.ID_ABOUT, "&About GrassGUI", + "Information about GrassGUI") + menu.Append(ID_ABOUT_COMMAND, "&About " + grass_task.name, + "Short descripton of GRASS command " + grass_task.name) + menu.AppendSeparator() + menu.Append(wx.ID_EXIT, "E&xit", "Terminate the program") + + menuBar = wx.MenuBar() + menuBar.Append(menu, "&File"); + + self.SetMenuBar(menuBar) + self.guisizer = wx.BoxSizer(wx.VERTICAL) + + sections = [] + is_section = {} + for task in grass_task.params + grass_task.flags: + if not task.has_key('guisection') or task['guisection']=='': + task['guisection'] = 'Options' + if not is_section.has_key(task['guisection']): + is_section[task['guisection']] = 1 + sections.append( task['guisection'] ) + + self.notebookpanel = wx.ScrolledWindow( self, id=wx.ID_ANY ) + self.notebookpanel.SetScrollRate(10,10) + self.panelsizer = wx.BoxSizer(wx.VERTICAL) + + nbStyle=FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS|FN.FNB_VC8|FN.FNB_BACKGROUND_GRADIENT + self.notebook = FN.FlatNotebook(self.notebookpanel, id=wx.ID_ANY, style=nbStyle) + self.notebook.SetTabAreaColour(wx.Colour(125,200,175)) + self.tab = {} + self.tabsizer = {} + is_first = True + for section in sections: + self.tab[section] = wx.Panel(self.notebook, id = wx.ID_ANY ) + self.tabsizer[section] = wx.BoxSizer(wx.VERTICAL) + self.notebook.AddPage( self.tab[section], text = section, select = is_first ) + is_first = False + + self.panelsizer.Add( self.notebook, flag=wx.EXPAND ) + self.guisizer.Add( self.notebookpanel, flag = wx.EXPAND ) + + p_count = -1 + for p in grass_task.params: + p_count += 1 # Needed for checkboxes hack + which_sizer = self.tabsizer[ p['guisection'] ] + which_panel = self.tab[ p['guisection'] ] + title = escape_ampersand(p['description']) + if p['required'] == 'no': + title = "[optional] " + title + if p['multiple'] == 'yes' and len( p['values'] ) == 0: + title = "[multiple] " + title + p['value'] = p['default'] + # inserting existing values from d.* command in layer tree + if self.dcmd_params != None: + for dparam in self.dcmd_params: + if p == dparam: + p['value'] = self.dcmd_params[dparam] + if (len(p['values']) > 0): + + valuelist=map(str,p['values']) + if p['multiple'] == 'yes': + hSizer=wx.StaticBoxSizer( wx.StaticBox(which_panel,0,title+":"), + wx.HORIZONTAL ) + v_count = 0 + isDefault = {} + for defval in p['value'].split(','): + isDefault[ defval ] = 'yes' + for val in valuelist: + # This is the checkboxes hack + idForWX = ID_MULTI_START + p_count*20 + v_count + chkbox = wx.CheckBox( which_panel, idForWX, val+" " ) + if isDefault.has_key(val): chkbox.SetValue( True ) + hSizer.Add( chkbox,0,wx.ADJUST_MINSIZE,0 ) + self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBoxMulti) + v_count += 1 + which_sizer.Add( hSizer, 0, wx.ADJUST_MINSIZE, 5) + else: + txt1 = wx.StaticText(which_panel, label = title + ':' ) + which_sizer.Add(txt1, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) + self.cb = wx.ComboBox(which_panel, -1, p['default'], + wx.Point(-1, -1), wx.Size(STRING_ENTRY_WIDTH, -1), + valuelist, wx.CB_DROPDOWN) + which_sizer.Add(self.cb, 0, wx.ADJUST_MINSIZE, 5) + self.paramdict[self.cb] = ID_PARAM_START + p_count + self.cb.Bind( wx.EVT_COMBOBOX, self.EvtComboBox) + + if (p['type'] in ('string','integer','float') + and len(p['values']) == 0 + and p['gisprompt'] == False + and p['prompt'] != 'color'): + + txt2 = wx.StaticText(which_panel, label = title + ':' ) + which_sizer.Add(txt2, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) + + self.txt3 = wx.TextCtrl(which_panel, value = p['default'], + size = (STRING_ENTRY_WIDTH, ENTRY_HEIGHT)) + which_sizer.Add(self.txt3, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) + self.paramdict[self.txt3] = ID_PARAM_START + p_count + self.txt3.Bind(wx.EVT_TEXT, self.EvtText) + + if p['type'] == 'string' and p['gisprompt'] == True: + txt4 = wx.StaticText(which_panel, label = title + ':') + which_sizer.Add(txt4, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) + if p['prompt'] != 'color': + self.selection = select.Select(which_panel, id=wx.ID_ANY, size=(250,-1), + type=p['element']) + which_sizer.Add(self.selection, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) + self.paramdict[self.selection] = ID_PARAM_START + p_count + self.selection.Bind(wx.EVT_TEXT, self.EvtText) + elif p['prompt'] == 'color': + if p['default'] != '': + if p['default'][0] in "0123456789": + default_color = tuple(map(int,p['default'].split( ':' ))) + label_color = p['default'] + else: + # Convert color names to RGB + try: + default_color = color_str2rgb[ p['default'] ] + label_color = p['default'] + except KeyError: + default_color = (200,200,200) + label_color = 'Select Color' + else: + default_color = (200,200,200) + label_color = 'Select Color' + btn_colour = csel.ColourSelect(which_panel, -1, label_color, default_color, wx.DefaultPosition, (150,-1) ) + which_sizer.Add(btn_colour, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) + self.paramdict[btn_colour] = ID_PARAM_START + p_count + self.Bind(csel.EVT_COLOURSELECT, self.OnColorButton, btn_colour) + + f_count = -1 + for f in grass_task.flags: + f_count += 1 + which_sizer = self.tabsizer[ f['guisection'] ] + which_panel = self.tab[ f['guisection'] ] + title = escape_ampersand(f['description']) + self.chk = wx.CheckBox(which_panel,-1, label = title, style = wx.NO_BORDER) + which_sizer.Add(self.chk, 0, wx.EXPAND| wx.ALL, 5) + self.paramdict[self.chk] = ID_FLAG_START + f_count + self.chk.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox) + + btnsizer = wx.BoxSizer(wx.HORIZONTAL) + self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "Cancel") + btnsizer.Add(self.btn_cancel, 0, wx.ALL| wx.ALIGN_CENTER, 10) + if self.get_dcmd is not None: # A callback has been set up + self.btn_apply = wx.Button(self, wx.ID_APPLY, "Apply") + btnsizer.Add(self.btn_apply, 0, wx.ALL| wx.ALIGN_CENTER, 10) + self.btn_ok = wx.Button(self, wx.ID_OK, "OK") + btnsizer.Add(self.btn_ok, 0, wx.ALL| wx.ALIGN_CENTER, 10) + self.btn_ok.SetDefault() + self.btn_apply.Bind(wx.EVT_BUTTON, self.OnApply) + self.btn_ok.Bind(wx.EVT_BUTTON, self.OnOK) + else: # We're standalone + self.btn_run = wx.Button(self, wx.ID_OK, "Run") + btnsizer.Add(self.btn_run, 0, wx.ALL| wx.ALIGN_CENTER, 10) + self.btn_run.SetDefault() + self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun) + self.guisizer.Add(btnsizer, 0, wx.EXPAND) + wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout) + wx.EVT_MENU(self, ID_ABOUT_COMMAND, self.OnAboutCommand) + wx.EVT_MENU(self, wx.ID_EXIT, self.OnCancel) + self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) + self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) + + xsizelist = [] + ysizelist = [] + for section in sections: + self.tabsizer[section].SetSizeHints( self.tab[section] ) + self.tabsizer[section].Fit( self.tab[section] ) + self.tab[section].SetAutoLayout(True) + self.tab[section].SetSizer( self.tabsizer[section] ) + self.tab[section].Layout() + xsizelist.append(self.tabsizer[section].GetMinSize()[0]) + ysizelist.append(self.tabsizer[section].GetMinSize()[1]) + + maxminsize = (max(xsizelist),max(ysizelist)) + self.notebook.SetInitialSize(maxminsize) + self.panelsizer.SetSizeHints( self.notebookpanel ) + self.panelsizer.Fit( self.notebookpanel ) + self.notebookpanel.SetSizer(self.panelsizer) + self.notebookpanel.SetAutoLayout(True) + self.notebookpanel.Layout() + + self.guisizer.SetSizeHints(self) +# self.guisizer.SetMinSize(maxminsize) + self.SetAutoLayout(True) + self.SetSizer(self.guisizer) + self.Layout() + + + def OnColorButton(self, event): + colorchooser = wx.FindWindowById( event.GetId() ) + new_color = colorchooser.GetValue() + # This is weird: new_color is a 4-tuple and new_color[:] is a 3-tuple + # under wx2.8.1 + new_label = color_rgb2str.get( new_color[:], ':'.join(map(str,new_color)) ) + colorchooser.SetLabel( new_label ) + colorchooser.SetColour( new_color ) + colorchooser.Refresh() + self.getValues() + + def getValues(self): + for item in self.paramdict.items(): + param_num = item[1] + if 'CheckBox' in str(item[0]): + tasktype = grass_task.flags + num = param_num-ID_FLAG_START + param_val = item[0].GetValue() + else: + tasktype = grass_task.params + num = param_num-ID_PARAM_START + if 'ColourSelect' in str(item[0]): + data = item[0].GetValue() + param_val = str(data[0])+':'+str(data[1])+':'+str(data[2]) + else: + param_val = item[0].GetValue() + tasktype[num]['value'] = param_val + + def EvtText(self, event): + self.getValues() + + def EvtCheckBox(self, event): + self.getValues() + + def EvtComboBox(self, event): + self.getValues() + + def EvtCheckBoxMulti(self, event): + """Fill the values ,-separated string according to current status of the checkboxes.""" + theParamId = (event.GetId()-ID_MULTI_START ) / 20 + theCheckedId = (event.GetId()-ID_MULTI_START ) % 20 + # Unpack current value list + currentValues={} + for isThere in grass_task.params[theParamId]['value'].split(','): + currentValues[isThere] = 1 + theValue = grass_task.params[theParamId]['values'][theCheckedId] + if event.Checked(): + currentValues[ theValue ] = 1 + else: + del currentValues[ theValue ] + # Pack it back + grass_task.params[theParamId]['value'] = ','.join( currentValues.keys() ) + + def createCmd(self): + """Produce a command line string for feeding into GRASS.""" + cmd = grass_task.name + errors = 0 + errStr = "" + for flag in grass_task.flags: + if 'value' in flag and flag['value']: + cmd += ' -' + flag['name'] + for p in grass_task.params: + if p['value'] == '' and p['required'] != 'no': + errStr += "Parameter " + p['name'] + "(" + p['description'] + ") is missing\n" + errors += 1 + if p['value'] != '' and p['value'] != p['default'] : + cmd += ' ' + p['name'] + '=' + p['value'] + if errors: + self.OnError(errStr) + return None + return cmd + + def OnOK(self, event): + cmd = self.OnApply(event) + if cmd is not None and self.get_dcmd is not None: + self.OnCancel(event) + + def OnApply(self, event): + cmd = self.createCmd() + + if cmd is not None and self.get_dcmd is not None: + # return d.* command to layer tree for rendering + self.get_dcmd(cmd, self.layer) + # echo d.* command to output console + self.parent.writeDCommand(cmd) + return cmd + + def OnRun(self, event): + cmd = self.createCmd() + + if cmd != None and cmd[0:2] != "d.": + # Send any non-display command to parent window (probably wxgui.py) + if self.parent > -1: + # put to parents + try: + self.parent.goutput.runCmd(cmd) + except AttributeError,e: + print >>sys.stderr, "%s: Propably not running in wxgui.py session?" % (e) + print >>sys.stderr, "parent window is: %s" % (str(self.parent)) + # Send any other command to the shell. + else: + try: + retcode = subprocess.call(cmd, shell=True) + if retcode < 0: + print >>sys.stderr, "Child was terminated by signal", -retcode + elif retcode > 0: + print >>sys.stderr, "Child returned", retcode + except OSError, e: + print >>sys.stderr, "Execution failed:", e + + def OnError(self, errMsg): + dlg = wx.MessageDialog(self, errMsg, "Error", wx.OK | wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + + def OnCancel(self, event): + self.Close(True) + for t in self.tab.values(): t = None + for t in self.tabsizer.values(): t.Clear(True) + self.notebook.Destroy() + self.guisizer.Clear(True) + grass_task_init() + self.Destroy() + + def OnCloseWindow(self, event): + grass_task_init() + self.Destroy() + + def OnAbout(self, event): + dlg = wx.MessageDialog(self, "This is a sample program for\n" + "GRASS command interface parsing\n" + "and automatic GUI building. \n%s" %(__version__), + "About GrassGUI", wx.OK | wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + def OnAboutCommand(self, event): + dlg = wx.MessageDialog(self, + grass_task.name+": "+grass_task.description, + "About " + grass_task.name, + wx.OK | wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + +class GrassGUIApp(wx.App): + def OnInit(self): + self.frame = mainFrame(None, -1) + self.frame.Show(True) + self.SetTopWindow(self.frame) + return True + +class GUI: + def __init__(self, parent=-1): + '''Parses GRASS commands when module is imported and used + from wxgui.py''' + self.parent = parent + + def parseCommand(self, cmd, gmpath, completed=None, parentframe=-1 ): + if completed == None: + self.get_dcmd = None + layer = None + else: + self.get_dcmd = completed[0] + layer = completed[1] + cmdlst = [] + cmdlst = cmd.split(' ') + + if parentframe > -1: + self.parent = parentframe + + if len(cmdlst) > 1: + print "usage: %s " % cmdlst[0] + else: + # parse the interface decription + cmd = cmd + r' --interface-description' + cmdout = os.popen(cmd, "r").read() + p = re.compile( '(grass-interface.dtd)') + cmdout2 = p.sub( gmpath+r'/grass-interface.dtd', cmdout) + handler = processTask() + xml.sax.parseString(cmdout2, handler) + + mf = mainFrame(self.parent ,-1, self.get_dcmd, layer) + mf.Show(True) + +if __name__ == "__main__": + # Just for testing purposes + + # Create the application + if len(sys.argv) != 2: + print "Usage: %s " % sys.argv[0] + sys.exit() + app = GrassGUIApp(0) + # Parsing if run from command line: find out the command to run + gui = GUI(app.frame) + gui.parseCommand( sys.argv[1], os.getenv("GISBASE") + "/etc/wx/gui_modules") + app.MainLoop() + From barton at grass.itc.it Sun Mar 25 08:31:10 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:31:12 2007 Subject: [grass-addons] r303 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250631.l2P6VATm021793@grass.itc.it> Author: barton Date: 2007-03-25 08:30:56 +0200 (Sun, 25 Mar 2007) New Revision: 303 Added: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Removed: trunk/grassaddons/gui/Gism/wxgui_utils.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/Gism/wxgui_utils.py 2007-03-25 06:30:17 UTC (rev 302) +++ trunk/grassaddons/gui/Gism/wxgui_utils.py 2007-03-25 06:30:56 UTC (rev 303) @@ -1,747 +0,0 @@ -import os,sys -import wx -import wx.lib.customtreectrl as CT -import wx.combo - -import track -import select -import menuform - -#FIXME?? -try: - import subprocess -except: - from compat import subprocess - - -gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules/" -sys.path.append(gmpath) - -icons = "" - -if not os.getenv("GRASS_ICONPATH"): - icons = os.getenv("GISBASE") + "/etc/gui/icons/" -else: - icons = os.environ["GRASS_ICONPATH"] - -class LayerTree(CT.CustomTreeCtrl): - """ - Creates layer tree structure - """ - # def __init__(self, parent, id, pos, size, style): - def __init__(self, parent, - id=wx.ID_ANY, pos=wx.DefaultPosition, - size=wx.DefaultSize, style=wx.SUNKEN_BORDER, - ctstyle=CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT | - CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT, - disp=None, log=None): - CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style,ctstyle) - - # we need this only for GIS Manager, but not for e.g. mapdisp - import menuform - - self.SetAutoLayout(True) - self.SetGradientStyle(1) - self.EnableSelectionGradient(True) - self.SetFirstGradientColour(wx.Colour(150, 150, 150)) - - self.Map = "" # instance of render.Map associated with display - self.root = "" # ID of layer tree root node - self.node = 0 # index value for layers - self.optpage = {} # dictionary of notebook option pages for each map layer - self.layer_selected = "" # ID of currently selected layer - self.layertype = {} # dictionary of layer types for each layer - self.layerctrl = {} # dictionary of layers indexed by special wind controls (spinctrl and textctrl) - self.saveitem = {} # dictionary to preserve layer attributes for drag and drop - self.first = True # indicates if a layer is just added or not - self.drag = False # flag to indicate a drag event is in process - self.params = {} # dictionary of existing command parameters - - self.Map = disp.getRender() - - self.root = self.AddRoot("Map Layers") - self.SetPyData(self.root, None) - - #create image list to use with layer tree - il = wx.ImageList(16, 16, False) - - trgif = wx.Image(icons + r'/element-cell.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.rast_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/module-d.rgb.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.rgb_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/channel-his.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.his_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/module-d.legend.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.leg_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/element-vector.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.vect_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/module-d.vect.thematic.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.theme_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/module-d.vect.chart.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.chart_icon = il.Add(trgif) - - trgif = wx.Image(icons + r'/gui-cmd.gif', wx.BITMAP_TYPE_GIF) - trgif.Rescale(16, 16) - trgif = trgif.ConvertToBitmap() - self.cmd_icon = il.Add(trgif) - - checksize = il.GetSize(0) - checkbmp = il.GetBitmap(0) - self.AssignImageList(il) - - # use when groups implemented - # self.tree.SetItemImage(self.root, fldridx, wx.TreeItemIcon_Normal) - # self.tree.SetItemImage(self.root, fldropenidx, wx.TreeItemIcon_Expanded) - - self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.onExpandNode) - self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.onCollapseNode) - self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.onActivateLayer) - self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onChangeSel) - self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.onLayerChecked) - self.Bind(wx.EVT_TREE_DELETE_ITEM, self.onDeleteLayer) - self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag) - self.Bind(wx.EVT_TREE_END_DRAG, self.onEndDrag) - - def AddLayer(self, idx, type): - self.first = True - if type == 'command': - # generic command layer - self.ctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='', - pos=wx.DefaultPosition, size=(250,40), - style=wx.TE_MULTILINE|wx.TE_WORDWRAP) - self.ctrl.Bind(wx.EVT_TEXT_ENTER, self.onCmdChanged) - self.ctrl.Bind(wx.EVT_TEXT, self.onCmdChanged) - else: - # all other layers - self.ctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50), - style=wx.SP_ARROW_KEYS) - self.ctrl.SetRange(1,100) - self.ctrl.SetValue(100) - self.ctrl.Bind(wx.EVT_TEXT, self.onOpacity) - - if self.layer_selected and self.layer_selected != self.GetRootItem(): - layer = self.InsertItem(self.root, self.GetPrevSibling(self.layer_selected), - '', ct_type=1, wnd=self.ctrl ) - else: - layer = self.PrependItem(self.root, '', ct_type=1, wnd=self.ctrl) - - self.SelectItem(layer) - - # add to layertype and layerctrl dictionaries - self.layertype[layer] = type - self.layerctrl[self.ctrl] = layer - - # add a data object to hold the layer's command (does not apply to generic command layers) - self.SetPyData(layer, None) - - #layer is initially unchecked as inactive - self.CheckItem(layer, checked=False) - - # add layer to layers list in render.Map - self.Map.addLayer(item=layer, command='', l_active=False, - l_hidden=False, l_opacity=1, l_render=False) - - # add text and icons for each layer type - if type == 'raster': - self.SetItemImage(layer, self.rast_icon) - self.SetItemText(layer, 'raster (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'rgb': - self.SetItemImage(layer, self.rgb_icon) - self.SetItemText(layer, 'RGB (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'his': - self.SetItemImage(layer, self.his_icon) - self.SetItemText(layer, 'HIS (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'rastleg': - self.SetItemImage(layer, self.leg_icon) - self.SetItemText(layer, 'legend (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'vector': - self.SetItemImage(layer, self.vect_icon) - self.SetItemText(layer, 'vector (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'thememap': - self.SetItemImage(layer, self.theme_icon) - self.SetItemText(layer, 'thematic map (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'themechart': - self.SetItemImage(layer, self.chart_icon) - self.SetItemText(layer, 'thematic charts (double click to set properties)') - # launch the properties dialog - menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif type == 'command': - self.SetItemImage(layer, self.cmd_icon) - self.first = False - - def onActivateLayer(self, event): - global gmpath - layer = event.GetItem() - self.layer_selected = layer - completed = '' - - # When double clicked or first added, open options dialog - if self.layertype[layer] == 'raster': - menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'rgb': - menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'his': - menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'rastleg': - menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'vector': - menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'thememap': - menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - elif self.layertype[layer] == 'themechart': - menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) - - def onDeleteLayer(self, event): - layer = event.GetItem() - self.layertype.pop(layer) - - # delete layer in render.Map - self.Map.delLayer(item=layer) - - def onLayerChecked(self, event): - layer = event.GetItem() - checked = self.IsItemChecked(layer) - - if self.drag == False and self.first == False: - # change active parameter for item in layers list in render.Map - self.changeChecked(layer, checked) - - def onCmdChanged(self, event): - layer = self.layerctrl[event.GetEventObject()] - cmd = event.GetString() - - if self.drag == False: - # change parameters for item in layers list in render.Map - self.changeLayer(layer) - event.Skip() - - def onOpacity(self, event): - if 'Spin' in str(event.GetEventObject()): - layer = self.layerctrl[event.GetEventObject()] - else: - layer = self.layerctrl[event.GetEventObject().GetParent()] - opacity = float(event.GetString())/100 - - if self.drag == False: - # change opacity parameter for item in layers list in render.Map - self.changeOpacity(layer, opacity) - event.Skip() - - def onChangeSel(self, event): - layer = event.GetItem() - self.layer_selected = layer - - def onCollapseNode(self, event): - print 'group collapsed' - event.Skip() - - def onExpandNode(self, event): - self.layer_selected = event.GetItem() - print 'group expanded' - event.Skip() - - def onBeginDrag(self, event): - """ Drag and drop of single tree nodes - """ - self.drag = True - # node cannot be a parent - if self.GetChildrenCount(event.GetItem()) == 0: - event.Allow() - - # save everthing associated with item to drag - self.dragItem = event.GetItem() - self.saveitem['type'] = self.layertype[self.dragItem] - self.saveitem['check'] = self.IsItemChecked(self.dragItem) - self.saveitem['image'] = self.GetItemImage(self.dragItem, 0) - self.saveitem['text'] = self.GetItemText(self.dragItem) - self.saveitem['wind'] = self.GetItemWindow(self.dragItem) - self.saveitem['windval'] = self.GetItemWindow(self.dragItem).GetValue() - self.saveitem['data'] = self.GetPyData(self.dragItem) - else: - print ("Cant drag a node that has children") - - def onEndDrag(self, event): - """ - Insert copy of layer in new position and - delete original at old position - """ - - #If we dropped somewhere that isn't on top of an item, ignore the event - if not event.GetItem(): - return - - # Make sure this memeber exists. - try: - old = self.dragItem - except: - return - - # Get the other IDs that are involved - afteritem = event.GetItem() - parent = self.GetItemParent(afteritem) - if not parent: - return - - # recreate old layer at new position - if self.layertype[old] == 'command': - self.dragctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='', - pos=wx.DefaultPosition, size=(250,40), - style=wx.TE_MULTILINE|wx.TE_WORDWRAP) - self.dragctrl.Bind(wx.EVT_TEXT_ENTER, self.onCmdChanged) - else: - self.dragctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50), - style=wx.SP_ARROW_KEYS) - self.dragctrl.SetRange(1,100) - self.dragctrl.SetValue(100) - self.dragctrl.Bind(wx.EVT_SPINCTRL, self.onOpacity) - - new = self.InsertItem(parent, afteritem, text=self.saveitem['text'], \ - ct_type=1, wnd=self.dragctrl, image=self.saveitem['image'], \ - data=self.saveitem['data']) - self.layertype[new] = self.saveitem['type'] - self.CheckItem(new, checked=self.saveitem['check']) - self.GetItemWindow(new).SetValue(self.saveitem['windval']) - - # delete layer at original position - self.Delete(old) - - # update layers list in render.Map - if self.saveitem['type'] == 'command': - self.Map.addLayer(item=new, command=self.saveitem['windval'], l_active=self.saveitem['check'], - l_hidden=False, l_opacity=1, l_render=False) - else: - self.Map.addLayer(item=new, command=self.saveitem['data'], l_active=self.saveitem['check'], - l_hidden=False, l_opacity=self.saveitem['windval'], l_render=False) - - self.reorderLayers() - self.drag = False - - def getOptData(self, dcmd, layer): - for item in dcmd.split(' '): - if 'map=' in item: - mapname = item.split('=')[1] - elif 'red=' in item: - mapname = item.split('=')[1] - elif 'h_map=' in item: - mapname = item.split('=')[1] - - # set layer text to map name - self.SetItemText(layer, mapname) - - # add command to layer's data - self.SetPyData(layer, dcmd) - - # check layer as active - self.CheckItem(layer, checked=True) - - # change parameters for item in layers list in render.Map - self.changeLayer(layer) - - def writeDCommand(self, dcmd): - # echos d.* command to output console - global goutput - goutput.write(dcmd+"\n----------\n") - - def reorderLayers(self): - """ - add commands from data associated with - any valid and checked layers to layer list - """ - # first empty the list of old layers -# self.Map.Clean() - # make a list of visible layers - treelayers = [] - vislayer = self.GetFirstVisibleItem() - for item in range(0,self.GetCount()): - if self.IsItemChecked(vislayer): - treelayers.append(vislayer) - if self.GetNextVisible(vislayer) == None: - break - else: - vislayer = self.GetNextVisible(vislayer) - treelayers.reverse() - self.Map.reorderLayers(treelayers) - - def changeOpacity(self, layer, opacity): - self.Map.changeOpacity(layer, opacity) - - def changeChecked(self, layer, check): - self.Map.changeActive(layer, check) - - def changeLayer(self, layer): - if self.layertype[layer] == 'command': - if self.GetItemWindow(layer).GetValue() != None: - cmd = self.GetItemWindow(layer).GetValue() - opac = 1.0 - chk = self.IsItemChecked(layer) - hidden = not self.IsVisible(layer) - self.Map.changeLayer(item=layer, command=cmd, l_active=chk, - l_hidden=hidden, l_opacity=opac, l_render=False) - else: - if self.GetPyData(layer) != None: - cmd = self.GetPyData(layer) - opac = float(self.GetItemWindow(layer).GetValue())/100 - chk = self.IsItemChecked(layer) - hidden = not self.IsVisible(layer) - self.Map.changeLayer(item=layer, command=cmd, l_active=chk, - l_hidden=hidden, l_opacity=opac, l_render=False) - -class TreeCtrlComboPopup(wx.combo.ComboPopup): - """ - Create a tree ComboBox for selecting maps and other GIS elements - in accessible mapsets within the current location - """ - - # overridden ComboPopup methods - - def Init(self): - self.value = None - self.curitem = None - - - def Create(self, parent): - self.tree = wx.TreeCtrl(parent, style=wx.TR_HIDE_ROOT - |wx.TR_HAS_BUTTONS - |wx.TR_SINGLE - |wx.TR_LINES_AT_ROOT - |wx.SIMPLE_BORDER - |wx.TR_FULL_ROW_HIGHLIGHT) - self.tree.Bind(wx.EVT_MOTION, self.OnMotion) - self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) - - - def GetControl(self): - return self.tree - - - def GetStringValue(self): - if self.value: - return self.tree.GetItemText(self.value) - return "" - - - def OnPopup(self): - if self.value: - self.tree.EnsureVisible(self.value) - self.tree.SelectItem(self.value) - - - def SetStringValue(self, value): - # this assumes that item strings are unique... - root = self.tree.GetRootItem() - if not root: - return - found = self.FindItem(root, value) - if found: - self.value = found - self.tree.SelectItem(found) - - - def GetAdjustedSize(self, minWidth, prefHeight, maxHeight): - return wx.Size(minWidth, min(200, maxHeight)) - - - def getElementList(self, element): - """ - Get list of GIS elements in accessible mapsets and display as tree - with all relevant elements displayed beneath each mapset branch - """ - #set environmental variables - gisdbase = os.popen('g.gisenv get=GISDBASE', "r").read().strip() - location = os.popen('g.gisenv get=LOCATION_NAME', "r").read().strip() - curr_mapset = os.popen('g.gisenv get=MAPSET', "r").read().strip() - location_path = os.path.join (gisdbase,location) - windfile = os.path.join (location_path,'PERMANENT','WIND') - symbol_path = os.path.join (os.environ['GISBASE'],'etc','symbol') - - #valid location test if needed - if windfile != None: - pass - - #mapsets in current location - mapsets = os.popen('g.mapsets -p', "r").read().lstrip().rstrip().split(' ') - - #Get directory tree nodes - for dir in mapsets: - if dir == curr_mapset: - #TODO: make current mapset node expanded - dir_node = self.AddItem('Mapset: '+dir) - self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) - self.tree.Expand(dir_node) - elem_list = os.listdir(os.path.join (location_path, dir, element)) - #TODO: sort list items? - for elem in elem_list: - self.AddItem(elem, parent=dir_node) - else: - dir_node = self.AddItem('Mapset: '+dir) - self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) - elem_list = os.listdir(os.path.join (location_path, dir, element)) - #TODO: sort list items? - for elem in elem_list: - self.AddItem(elem+'@'+dir, parent=dir_node) - - # helpers - - def FindItem(self, parentItem, text): - item, cookie = self.tree.GetFirstChild(parentItem) - while item: - if self.tree.GetItemText(item) == text: - return item - if self.tree.ItemHasChildren(item): - item = self.FindItem(item, text) - item, cookie = self.tree.GetNextChild(parentItem, cookie) - return wx.TreeItemId(); - - - def AddItem(self, value, parent=None): - if not parent: - root = self.tree.GetRootItem() - if not root: - root = self.tree.AddRoot("") - parent = root - - item = self.tree.AppendItem(parent, value) - return item - - - def OnMotion(self, evt): - # have the selection follow the mouse, like in a real combobox - item, flags = self.tree.HitTest(evt.GetPosition()) - if item and flags & wx.TREE_HITTEST_ONITEMLABEL: - self.tree.SelectItem(item) - self.curitem = item - evt.Skip() - - - def OnLeftDown(self, evt): - # do the combobox selection - item, flags = self.tree.HitTest(evt.GetPosition()) - if item and flags & wx.TREE_HITTEST_ONITEMLABEL: - self.curitem = item - self.value = item - self.Dismiss() - evt.Skip() - - - -class GMConsole(wx.Panel): - """ - Create and manage output console for commands entered on the - GIS Manager command line. - """ - def __init__(self, parent, id=-1, - pos=wx.DefaultPosition, size=wx.DefaultSize, - style=wx.TAB_TRAVERSAL|wx.FULL_REPAINT_ON_RESIZE): - wx.Panel.__init__(self, parent, id, pos, size, style) - #initialize variables - - self.cmd_output = "" - self.console_command = "" - self.console_clear = "" - self.console_save = "" - self.gcmdlst = [] #list of commands in bin and scripts - - #text control for command output - self.cmd_output = wx.TextCtrl(self, -1, "", - style=wx.TE_MULTILINE| - wx.TE_READONLY) - - global goutput - goutput = self.cmd_output - self.console_clear = wx.Button(self, -1, _("Clear")) - self.console_save = wx.Button(self, -1, _("Save")) - - self.Bind(wx.EVT_BUTTON, self.clearHistory, self.console_clear) - self.Bind(wx.EVT_BUTTON, self.saveHistory, self.console_save) - - # output control layout - boxsizer1 = wx.BoxSizer(wx.VERTICAL) - gridsizer1 = wx.GridSizer(1, 2, 0, 0) - boxsizer1.Add(self.cmd_output, 1, - wx.EXPAND|wx.ADJUST_MINSIZE, 0) - gridsizer1.Add(self.console_clear, 0, - wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) - gridsizer1.Add(self.console_save, 0, - wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) - - boxsizer1.Add((0,5)) - boxsizer1.Add(gridsizer1, 0, wx.EXPAND|wx.ALIGN_CENTRE_VERTICAL) - boxsizer1.Add((0,5)) - boxsizer1.Fit(self) - boxsizer1.SetSizeHints(self) - self.SetAutoLayout(True) - self.SetSizer(boxsizer1) - - def getGRASSCmds(self): - ''' - Create list of all available GRASS commands to use when - parsing string from the command line - ''' - self.gcmdlst = [] - gisbase = os.environ['GISBASE'] - self.gcmdlst = os.listdir(gisbase+r'/bin') - self.gcmdlst = self.gcmdlst + os.listdir(gisbase+r'/scripts') - return self.gcmdlst - - def runCmd(self, cmd): - """ - Run in GUI or shell GRASS (or other) commands typed into - console command text widget, echo command to - output text widget, and send stdout output to output - text widget. - - TODO: Display commands (*.d) are captured and - processed separately by mapdisp.py. Display commands are - rendered in map display widget that currently has - the focus (as indicted by mdidx). - """ - - gcmdlst = self.getGRASSCmds() - cmdlst = [] -# cmd = self.console_command.GetLineText(0) - cmdlst = cmd.split(' ') - disp_idx = int(track.Track().GetDisp()[0]) - curr_disp = track.Track().GetDisp()[1] - - if len(cmdlst) == 1 and cmd in gcmdlst: - # Send GRASS command without arguments to GUI command interface - # except display commands (they are handled differently) - global gmpath - if cmd[0:2] == "d.": - if cmd == 'd.rast': - layertype = 'raster' - elif cmd == 'd.rgb': - layertype = 'rgb' - elif cmd == 'd.his': - layertype = 'his' - elif cmd == 'd.legend': - layertype = 'rastleg' - elif cmd == 'd.vect': - layertype = 'vector' - elif cmd == 'd.vect.thematic': - layertype = 'thememap' - elif cmd == 'd.vect.chart': - layertype = 'themechart' - else: - print 'Command type not yet implemented' - return - - if disp_idx != None: - # get layer tree for active display - layertree = track.Track().GetCtrls(disp_idx, 2) - # add layer - layertree.AddLayer(disp_idx, layertype) - - else: - menuform.GUI().parseCommand(cmd, gmpath) - self.cmd_output.write(cmdlst[0] + - "\n----------\n") - - elif cmd[0:2] == "d." and len(cmdlst) > 1 and cmdlst[0] in gcmdlst: - """ - Send GRASS display command(s)with arguments - to the display processor and echo to command output console. - Accepts a list of d.* commands separated by commas. - Display with focus receives display command(s). - """ - self.cmd_output.write(cmd + - "\n----------\n") - dcmds = cmd.split(',') - curr_disp.addMapsToList(type='command', map=dcmds, mset=None) - curr_disp.ReDrawCommand() - - else: - # Send any other command to the shell. Send output to - # console output window. - try: - retcode = subprocess.call(cmd, shell=True) - - if retcode < 0: - print >> sys.stderr, "Child was terminated by signal", retcode - elif retcode > 0: - print >> sys.stderr, "Child returned", retcode - except OSError, e: - print >> sys.stderr, "Execution failed:", e - - self.cmd_output.write(cmd+"\n----------\n") - #FIXME - why is PIPE not recognized? -# self.out = subprocess.Popen(cmd, shell=True, stdout=PIPE).stdout - self.out = os.popen(cmd, "r").read() - self.cmd_output.write(self.out+"\n") - - def clearHistory(self, event): - self.cmd_output.Clear() - - def saveHistory(self, event): - self.history = self.cmd_output.GetStringSelection() - if self.history == "": - self.cmd_output.SetSelection(-1,-1) - self.history = self.cmd_output.GetStringSelection() - - #Use a standard dialog for this - wildcard = "Text file (*.txt)|*.txt" - dlg = wx.FileDialog( - self, message="Save file as ...", defaultDir=os.getcwd(), - defaultFile="grass_cmd_history.txt", wildcard=wildcard, style=wx.SAVE|wx.FD_OVERWRITE_PROMPT - ) - - # Show the dialog and retrieve the user response. If it is the OK response, - # process the data. - if dlg.ShowModal() == wx.ID_OK: - path = dlg.GetPath() - - output = open(path,"w") - output.write(self.history) - output.close() - dlg.Destroy() - -def GetTempfile( pref=None): - """ - Creates GRASS temporary file using defined prefix. - - Returns: - Path to file name (string) or None - """ - - tempfile = os.popen("g.tempfile pid=%d" % - os.getpid()).readlines()[0].strip() - - if not tempfile: - return None - else: - path,file = os.path.split(tempfile) - if pref: - file = "%s%s" % (pref,file) - return os.path.join(path,file) Copied: trunk/grassaddons/gui/gui_modules/wxgui_utils.py (from rev 302, trunk/grassaddons/gui/Gism/wxgui_utils.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-25 06:30:56 UTC (rev 303) @@ -0,0 +1,747 @@ +import os,sys +import wx +import wx.lib.customtreectrl as CT +import wx.combo + +import track +import select +import menuform + +#FIXME?? +try: + import subprocess +except: + from compat import subprocess + + +gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules/" +sys.path.append(gmpath) + +icons = "" + +if not os.getenv("GRASS_ICONPATH"): + icons = os.getenv("GISBASE") + "/etc/gui/icons/" +else: + icons = os.environ["GRASS_ICONPATH"] + +class LayerTree(CT.CustomTreeCtrl): + """ + Creates layer tree structure + """ + # def __init__(self, parent, id, pos, size, style): + def __init__(self, parent, + id=wx.ID_ANY, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.SUNKEN_BORDER, + ctstyle=CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT | + CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT, + disp=None, log=None): + CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style,ctstyle) + + # we need this only for GIS Manager, but not for e.g. mapdisp + import menuform + + self.SetAutoLayout(True) + self.SetGradientStyle(1) + self.EnableSelectionGradient(True) + self.SetFirstGradientColour(wx.Colour(150, 150, 150)) + + self.Map = "" # instance of render.Map associated with display + self.root = "" # ID of layer tree root node + self.node = 0 # index value for layers + self.optpage = {} # dictionary of notebook option pages for each map layer + self.layer_selected = "" # ID of currently selected layer + self.layertype = {} # dictionary of layer types for each layer + self.layerctrl = {} # dictionary of layers indexed by special wind controls (spinctrl and textctrl) + self.saveitem = {} # dictionary to preserve layer attributes for drag and drop + self.first = True # indicates if a layer is just added or not + self.drag = False # flag to indicate a drag event is in process + self.params = {} # dictionary of existing command parameters + + self.Map = disp.getRender() + + self.root = self.AddRoot("Map Layers") + self.SetPyData(self.root, None) + + #create image list to use with layer tree + il = wx.ImageList(16, 16, False) + + trgif = wx.Image(icons + r'/element-cell.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.rast_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.rgb.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.rgb_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/channel-his.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.his_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.legend.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.leg_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/element-vector.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.vect_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.vect.thematic.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.theme_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.vect.chart.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.chart_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/gui-cmd.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.cmd_icon = il.Add(trgif) + + checksize = il.GetSize(0) + checkbmp = il.GetBitmap(0) + self.AssignImageList(il) + + # use when groups implemented + # self.tree.SetItemImage(self.root, fldridx, wx.TreeItemIcon_Normal) + # self.tree.SetItemImage(self.root, fldropenidx, wx.TreeItemIcon_Expanded) + + self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.onExpandNode) + self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.onCollapseNode) + self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.onActivateLayer) + self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onChangeSel) + self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.onLayerChecked) + self.Bind(wx.EVT_TREE_DELETE_ITEM, self.onDeleteLayer) + self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag) + self.Bind(wx.EVT_TREE_END_DRAG, self.onEndDrag) + + def AddLayer(self, idx, type): + self.first = True + if type == 'command': + # generic command layer + self.ctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='', + pos=wx.DefaultPosition, size=(250,40), + style=wx.TE_MULTILINE|wx.TE_WORDWRAP) + self.ctrl.Bind(wx.EVT_TEXT_ENTER, self.onCmdChanged) + self.ctrl.Bind(wx.EVT_TEXT, self.onCmdChanged) + else: + # all other layers + self.ctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50), + style=wx.SP_ARROW_KEYS) + self.ctrl.SetRange(1,100) + self.ctrl.SetValue(100) + self.ctrl.Bind(wx.EVT_TEXT, self.onOpacity) + + if self.layer_selected and self.layer_selected != self.GetRootItem(): + layer = self.InsertItem(self.root, self.GetPrevSibling(self.layer_selected), + '', ct_type=1, wnd=self.ctrl ) + else: + layer = self.PrependItem(self.root, '', ct_type=1, wnd=self.ctrl) + + self.SelectItem(layer) + + # add to layertype and layerctrl dictionaries + self.layertype[layer] = type + self.layerctrl[self.ctrl] = layer + + # add a data object to hold the layer's command (does not apply to generic command layers) + self.SetPyData(layer, None) + + #layer is initially unchecked as inactive + self.CheckItem(layer, checked=False) + + # add layer to layers list in render.Map + self.Map.addLayer(item=layer, command='', l_active=False, + l_hidden=False, l_opacity=1, l_render=False) + + # add text and icons for each layer type + if type == 'raster': + self.SetItemImage(layer, self.rast_icon) + self.SetItemText(layer, 'raster (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'rgb': + self.SetItemImage(layer, self.rgb_icon) + self.SetItemText(layer, 'RGB (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'his': + self.SetItemImage(layer, self.his_icon) + self.SetItemText(layer, 'HIS (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'rastleg': + self.SetItemImage(layer, self.leg_icon) + self.SetItemText(layer, 'legend (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'vector': + self.SetItemImage(layer, self.vect_icon) + self.SetItemText(layer, 'vector (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'thememap': + self.SetItemImage(layer, self.theme_icon) + self.SetItemText(layer, 'thematic map (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'themechart': + self.SetItemImage(layer, self.chart_icon) + self.SetItemText(layer, 'thematic charts (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'command': + self.SetItemImage(layer, self.cmd_icon) + self.first = False + + def onActivateLayer(self, event): + global gmpath + layer = event.GetItem() + self.layer_selected = layer + completed = '' + + # When double clicked or first added, open options dialog + if self.layertype[layer] == 'raster': + menuform.GUI().parseCommand('d.rast', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'rgb': + menuform.GUI().parseCommand('d.rgb', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'his': + menuform.GUI().parseCommand('d.his', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'rastleg': + menuform.GUI().parseCommand('d.legend', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'vector': + menuform.GUI().parseCommand('d.vect', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'thememap': + menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'themechart': + menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + + def onDeleteLayer(self, event): + layer = event.GetItem() + self.layertype.pop(layer) + + # delete layer in render.Map + self.Map.delLayer(item=layer) + + def onLayerChecked(self, event): + layer = event.GetItem() + checked = self.IsItemChecked(layer) + + if self.drag == False and self.first == False: + # change active parameter for item in layers list in render.Map + self.changeChecked(layer, checked) + + def onCmdChanged(self, event): + layer = self.layerctrl[event.GetEventObject()] + cmd = event.GetString() + + if self.drag == False: + # change parameters for item in layers list in render.Map + self.changeLayer(layer) + event.Skip() + + def onOpacity(self, event): + if 'Spin' in str(event.GetEventObject()): + layer = self.layerctrl[event.GetEventObject()] + else: + layer = self.layerctrl[event.GetEventObject().GetParent()] + opacity = float(event.GetString())/100 + + if self.drag == False: + # change opacity parameter for item in layers list in render.Map + self.changeOpacity(layer, opacity) + event.Skip() + + def onChangeSel(self, event): + layer = event.GetItem() + self.layer_selected = layer + + def onCollapseNode(self, event): + print 'group collapsed' + event.Skip() + + def onExpandNode(self, event): + self.layer_selected = event.GetItem() + print 'group expanded' + event.Skip() + + def onBeginDrag(self, event): + """ Drag and drop of single tree nodes + """ + self.drag = True + # node cannot be a parent + if self.GetChildrenCount(event.GetItem()) == 0: + event.Allow() + + # save everthing associated with item to drag + self.dragItem = event.GetItem() + self.saveitem['type'] = self.layertype[self.dragItem] + self.saveitem['check'] = self.IsItemChecked(self.dragItem) + self.saveitem['image'] = self.GetItemImage(self.dragItem, 0) + self.saveitem['text'] = self.GetItemText(self.dragItem) + self.saveitem['wind'] = self.GetItemWindow(self.dragItem) + self.saveitem['windval'] = self.GetItemWindow(self.dragItem).GetValue() + self.saveitem['data'] = self.GetPyData(self.dragItem) + else: + print ("Cant drag a node that has children") + + def onEndDrag(self, event): + """ + Insert copy of layer in new position and + delete original at old position + """ + + #If we dropped somewhere that isn't on top of an item, ignore the event + if not event.GetItem(): + return + + # Make sure this memeber exists. + try: + old = self.dragItem + except: + return + + # Get the other IDs that are involved + afteritem = event.GetItem() + parent = self.GetItemParent(afteritem) + if not parent: + return + + # recreate old layer at new position + if self.layertype[old] == 'command': + self.dragctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='', + pos=wx.DefaultPosition, size=(250,40), + style=wx.TE_MULTILINE|wx.TE_WORDWRAP) + self.dragctrl.Bind(wx.EVT_TEXT_ENTER, self.onCmdChanged) + else: + self.dragctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50), + style=wx.SP_ARROW_KEYS) + self.dragctrl.SetRange(1,100) + self.dragctrl.SetValue(100) + self.dragctrl.Bind(wx.EVT_SPINCTRL, self.onOpacity) + + new = self.InsertItem(parent, afteritem, text=self.saveitem['text'], \ + ct_type=1, wnd=self.dragctrl, image=self.saveitem['image'], \ + data=self.saveitem['data']) + self.layertype[new] = self.saveitem['type'] + self.CheckItem(new, checked=self.saveitem['check']) + self.GetItemWindow(new).SetValue(self.saveitem['windval']) + + # delete layer at original position + self.Delete(old) + + # update layers list in render.Map + if self.saveitem['type'] == 'command': + self.Map.addLayer(item=new, command=self.saveitem['windval'], l_active=self.saveitem['check'], + l_hidden=False, l_opacity=1, l_render=False) + else: + self.Map.addLayer(item=new, command=self.saveitem['data'], l_active=self.saveitem['check'], + l_hidden=False, l_opacity=self.saveitem['windval'], l_render=False) + + self.reorderLayers() + self.drag = False + + def getOptData(self, dcmd, layer): + for item in dcmd.split(' '): + if 'map=' in item: + mapname = item.split('=')[1] + elif 'red=' in item: + mapname = item.split('=')[1] + elif 'h_map=' in item: + mapname = item.split('=')[1] + + # set layer text to map name + self.SetItemText(layer, mapname) + + # add command to layer's data + self.SetPyData(layer, dcmd) + + # check layer as active + self.CheckItem(layer, checked=True) + + # change parameters for item in layers list in render.Map + self.changeLayer(layer) + + def writeDCommand(self, dcmd): + # echos d.* command to output console + global goutput + goutput.write(dcmd+"\n----------\n") + + def reorderLayers(self): + """ + add commands from data associated with + any valid and checked layers to layer list + """ + # first empty the list of old layers +# self.Map.Clean() + # make a list of visible layers + treelayers = [] + vislayer = self.GetFirstVisibleItem() + for item in range(0,self.GetCount()): + if self.IsItemChecked(vislayer): + treelayers.append(vislayer) + if self.GetNextVisible(vislayer) == None: + break + else: + vislayer = self.GetNextVisible(vislayer) + treelayers.reverse() + self.Map.reorderLayers(treelayers) + + def changeOpacity(self, layer, opacity): + self.Map.changeOpacity(layer, opacity) + + def changeChecked(self, layer, check): + self.Map.changeActive(layer, check) + + def changeLayer(self, layer): + if self.layertype[layer] == 'command': + if self.GetItemWindow(layer).GetValue() != None: + cmd = self.GetItemWindow(layer).GetValue() + opac = 1.0 + chk = self.IsItemChecked(layer) + hidden = not self.IsVisible(layer) + self.Map.changeLayer(item=layer, command=cmd, l_active=chk, + l_hidden=hidden, l_opacity=opac, l_render=False) + else: + if self.GetPyData(layer) != None: + cmd = self.GetPyData(layer) + opac = float(self.GetItemWindow(layer).GetValue())/100 + chk = self.IsItemChecked(layer) + hidden = not self.IsVisible(layer) + self.Map.changeLayer(item=layer, command=cmd, l_active=chk, + l_hidden=hidden, l_opacity=opac, l_render=False) + +class TreeCtrlComboPopup(wx.combo.ComboPopup): + """ + Create a tree ComboBox for selecting maps and other GIS elements + in accessible mapsets within the current location + """ + + # overridden ComboPopup methods + + def Init(self): + self.value = None + self.curitem = None + + + def Create(self, parent): + self.tree = wx.TreeCtrl(parent, style=wx.TR_HIDE_ROOT + |wx.TR_HAS_BUTTONS + |wx.TR_SINGLE + |wx.TR_LINES_AT_ROOT + |wx.SIMPLE_BORDER + |wx.TR_FULL_ROW_HIGHLIGHT) + self.tree.Bind(wx.EVT_MOTION, self.OnMotion) + self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) + + + def GetControl(self): + return self.tree + + + def GetStringValue(self): + if self.value: + return self.tree.GetItemText(self.value) + return "" + + + def OnPopup(self): + if self.value: + self.tree.EnsureVisible(self.value) + self.tree.SelectItem(self.value) + + + def SetStringValue(self, value): + # this assumes that item strings are unique... + root = self.tree.GetRootItem() + if not root: + return + found = self.FindItem(root, value) + if found: + self.value = found + self.tree.SelectItem(found) + + + def GetAdjustedSize(self, minWidth, prefHeight, maxHeight): + return wx.Size(minWidth, min(200, maxHeight)) + + + def getElementList(self, element): + """ + Get list of GIS elements in accessible mapsets and display as tree + with all relevant elements displayed beneath each mapset branch + """ + #set environmental variables + gisdbase = os.popen('g.gisenv get=GISDBASE', "r").read().strip() + location = os.popen('g.gisenv get=LOCATION_NAME', "r").read().strip() + curr_mapset = os.popen('g.gisenv get=MAPSET', "r").read().strip() + location_path = os.path.join (gisdbase,location) + windfile = os.path.join (location_path,'PERMANENT','WIND') + symbol_path = os.path.join (os.environ['GISBASE'],'etc','symbol') + + #valid location test if needed + if windfile != None: + pass + + #mapsets in current location + mapsets = os.popen('g.mapsets -p', "r").read().lstrip().rstrip().split(' ') + + #Get directory tree nodes + for dir in mapsets: + if dir == curr_mapset: + #TODO: make current mapset node expanded + dir_node = self.AddItem('Mapset: '+dir) + self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) + self.tree.Expand(dir_node) + elem_list = os.listdir(os.path.join (location_path, dir, element)) + #TODO: sort list items? + for elem in elem_list: + self.AddItem(elem, parent=dir_node) + else: + dir_node = self.AddItem('Mapset: '+dir) + self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) + elem_list = os.listdir(os.path.join (location_path, dir, element)) + #TODO: sort list items? + for elem in elem_list: + self.AddItem(elem+'@'+dir, parent=dir_node) + + # helpers + + def FindItem(self, parentItem, text): + item, cookie = self.tree.GetFirstChild(parentItem) + while item: + if self.tree.GetItemText(item) == text: + return item + if self.tree.ItemHasChildren(item): + item = self.FindItem(item, text) + item, cookie = self.tree.GetNextChild(parentItem, cookie) + return wx.TreeItemId(); + + + def AddItem(self, value, parent=None): + if not parent: + root = self.tree.GetRootItem() + if not root: + root = self.tree.AddRoot("") + parent = root + + item = self.tree.AppendItem(parent, value) + return item + + + def OnMotion(self, evt): + # have the selection follow the mouse, like in a real combobox + item, flags = self.tree.HitTest(evt.GetPosition()) + if item and flags & wx.TREE_HITTEST_ONITEMLABEL: + self.tree.SelectItem(item) + self.curitem = item + evt.Skip() + + + def OnLeftDown(self, evt): + # do the combobox selection + item, flags = self.tree.HitTest(evt.GetPosition()) + if item and flags & wx.TREE_HITTEST_ONITEMLABEL: + self.curitem = item + self.value = item + self.Dismiss() + evt.Skip() + + + +class GMConsole(wx.Panel): + """ + Create and manage output console for commands entered on the + GIS Manager command line. + """ + def __init__(self, parent, id=-1, + pos=wx.DefaultPosition, size=wx.DefaultSize, + style=wx.TAB_TRAVERSAL|wx.FULL_REPAINT_ON_RESIZE): + wx.Panel.__init__(self, parent, id, pos, size, style) + #initialize variables + + self.cmd_output = "" + self.console_command = "" + self.console_clear = "" + self.console_save = "" + self.gcmdlst = [] #list of commands in bin and scripts + + #text control for command output + self.cmd_output = wx.TextCtrl(self, -1, "", + style=wx.TE_MULTILINE| + wx.TE_READONLY) + + global goutput + goutput = self.cmd_output + self.console_clear = wx.Button(self, -1, _("Clear")) + self.console_save = wx.Button(self, -1, _("Save")) + + self.Bind(wx.EVT_BUTTON, self.clearHistory, self.console_clear) + self.Bind(wx.EVT_BUTTON, self.saveHistory, self.console_save) + + # output control layout + boxsizer1 = wx.BoxSizer(wx.VERTICAL) + gridsizer1 = wx.GridSizer(1, 2, 0, 0) + boxsizer1.Add(self.cmd_output, 1, + wx.EXPAND|wx.ADJUST_MINSIZE, 0) + gridsizer1.Add(self.console_clear, 0, + wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) + gridsizer1.Add(self.console_save, 0, + wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) + + boxsizer1.Add((0,5)) + boxsizer1.Add(gridsizer1, 0, wx.EXPAND|wx.ALIGN_CENTRE_VERTICAL) + boxsizer1.Add((0,5)) + boxsizer1.Fit(self) + boxsizer1.SetSizeHints(self) + self.SetAutoLayout(True) + self.SetSizer(boxsizer1) + + def getGRASSCmds(self): + ''' + Create list of all available GRASS commands to use when + parsing string from the command line + ''' + self.gcmdlst = [] + gisbase = os.environ['GISBASE'] + self.gcmdlst = os.listdir(gisbase+r'/bin') + self.gcmdlst = self.gcmdlst + os.listdir(gisbase+r'/scripts') + return self.gcmdlst + + def runCmd(self, cmd): + """ + Run in GUI or shell GRASS (or other) commands typed into + console command text widget, echo command to + output text widget, and send stdout output to output + text widget. + + TODO: Display commands (*.d) are captured and + processed separately by mapdisp.py. Display commands are + rendered in map display widget that currently has + the focus (as indicted by mdidx). + """ + + gcmdlst = self.getGRASSCmds() + cmdlst = [] +# cmd = self.console_command.GetLineText(0) + cmdlst = cmd.split(' ') + disp_idx = int(track.Track().GetDisp()[0]) + curr_disp = track.Track().GetDisp()[1] + + if len(cmdlst) == 1 and cmd in gcmdlst: + # Send GRASS command without arguments to GUI command interface + # except display commands (they are handled differently) + global gmpath + if cmd[0:2] == "d.": + if cmd == 'd.rast': + layertype = 'raster' + elif cmd == 'd.rgb': + layertype = 'rgb' + elif cmd == 'd.his': + layertype = 'his' + elif cmd == 'd.legend': + layertype = 'rastleg' + elif cmd == 'd.vect': + layertype = 'vector' + elif cmd == 'd.vect.thematic': + layertype = 'thememap' + elif cmd == 'd.vect.chart': + layertype = 'themechart' + else: + print 'Command type not yet implemented' + return + + if disp_idx != None: + # get layer tree for active display + layertree = track.Track().GetCtrls(disp_idx, 2) + # add layer + layertree.AddLayer(disp_idx, layertype) + + else: + menuform.GUI().parseCommand(cmd, gmpath) + self.cmd_output.write(cmdlst[0] + + "\n----------\n") + + elif cmd[0:2] == "d." and len(cmdlst) > 1 and cmdlst[0] in gcmdlst: + """ + Send GRASS display command(s)with arguments + to the display processor and echo to command output console. + Accepts a list of d.* commands separated by commas. + Display with focus receives display command(s). + """ + self.cmd_output.write(cmd + + "\n----------\n") + dcmds = cmd.split(',') + curr_disp.addMapsToList(type='command', map=dcmds, mset=None) + curr_disp.ReDrawCommand() + + else: + # Send any other command to the shell. Send output to + # console output window. + try: + retcode = subprocess.call(cmd, shell=True) + + if retcode < 0: + print >> sys.stderr, "Child was terminated by signal", retcode + elif retcode > 0: + print >> sys.stderr, "Child returned", retcode + except OSError, e: + print >> sys.stderr, "Execution failed:", e + + self.cmd_output.write(cmd+"\n----------\n") + #FIXME - why is PIPE not recognized? +# self.out = subprocess.Popen(cmd, shell=True, stdout=PIPE).stdout + self.out = os.popen(cmd, "r").read() + self.cmd_output.write(self.out+"\n") + + def clearHistory(self, event): + self.cmd_output.Clear() + + def saveHistory(self, event): + self.history = self.cmd_output.GetStringSelection() + if self.history == "": + self.cmd_output.SetSelection(-1,-1) + self.history = self.cmd_output.GetStringSelection() + + #Use a standard dialog for this + wildcard = "Text file (*.txt)|*.txt" + dlg = wx.FileDialog( + self, message="Save file as ...", defaultDir=os.getcwd(), + defaultFile="grass_cmd_history.txt", wildcard=wildcard, style=wx.SAVE|wx.FD_OVERWRITE_PROMPT + ) + + # Show the dialog and retrieve the user response. If it is the OK response, + # process the data. + if dlg.ShowModal() == wx.ID_OK: + path = dlg.GetPath() + + output = open(path,"w") + output.write(self.history) + output.close() + dlg.Destroy() + +def GetTempfile( pref=None): + """ + Creates GRASS temporary file using defined prefix. + + Returns: + Path to file name (string) or None + """ + + tempfile = os.popen("g.tempfile pid=%d" % + os.getpid()).readlines()[0].strip() + + if not tempfile: + return None + else: + path,file = os.path.split(tempfile) + if pref: + file = "%s%s" % (pref,file) + return os.path.join(path,file) From barton at grass.itc.it Sun Mar 25 08:31:43 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:31:44 2007 Subject: [grass-addons] r304 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250631.l2P6Vh3h021819@grass.itc.it> Author: barton Date: 2007-03-25 08:31:29 +0200 (Sun, 25 Mar 2007) New Revision: 304 Added: trunk/grassaddons/gui/gui_modules/utils.py Removed: trunk/grassaddons/gui/Gism/utils.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/utils.py =================================================================== --- trunk/grassaddons/gui/Gism/utils.py 2007-03-25 06:30:56 UTC (rev 303) +++ trunk/grassaddons/gui/Gism/utils.py 2007-03-25 06:31:29 UTC (rev 304) @@ -1,22 +0,0 @@ -import os - -def GetTempfile( pref=None): - """ - Creates GRASS temporary file using defined prefix. - - Returns: - Path to file name (string) or None - """ - - tempfile = os.popen("g.tempfile pid=%d" % - os.getpid()).readlines()[0].strip() - - if not tempfile: - return None - else: - path,file = os.path.split(tempfile) - if pref: - file = "%s%s" % (pref,file) - return os.path.join(path,file) - - Copied: trunk/grassaddons/gui/gui_modules/utils.py (from rev 303, trunk/grassaddons/gui/Gism/utils.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/utils.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/utils.py 2007-03-25 06:31:29 UTC (rev 304) @@ -0,0 +1,22 @@ +import os + +def GetTempfile( pref=None): + """ + Creates GRASS temporary file using defined prefix. + + Returns: + Path to file name (string) or None + """ + + tempfile = os.popen("g.tempfile pid=%d" % + os.getpid()).readlines()[0].strip() + + if not tempfile: + return None + else: + path,file = os.path.split(tempfile) + if pref: + file = "%s%s" % (pref,file) + return os.path.join(path,file) + + From barton at grass.itc.it Sun Mar 25 08:32:22 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:32:23 2007 Subject: [grass-addons] r305 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250632.l2P6WMYW021839@grass.itc.it> Author: barton Date: 2007-03-25 08:32:08 +0200 (Sun, 25 Mar 2007) New Revision: 305 Added: trunk/grassaddons/gui/gui_modules/track.py Removed: trunk/grassaddons/gui/Gism/track.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/track.py =================================================================== --- trunk/grassaddons/gui/Gism/track.py 2007-03-25 06:31:29 UTC (rev 304) +++ trunk/grassaddons/gui/Gism/track.py 2007-03-25 06:32:08 UTC (rev 305) @@ -1,69 +0,0 @@ -""" -Variables set at initialization -""" -global curr_disp -curr_disp="" -global ctrl_dict -ctrl_dict={} - -class Track: - """ - This class has functions and variables for tracking map display, - associated notebook pages, and other index values. - """ - - def SetCtrlDict(self, idx, disp, page, tree): - """ - This method stores the associated display index, display ID, - controls book page ID, and map layer tree ID in a dictionary - """ - global ctrl_dict - ctrl_dict[idx]=[disp, page, tree] - return ctrl_dict - - def GetCtrls(self, idx, num): - """ - Returns widget ID for map display (num=0), controls book page - (num=1), or map layer tree (num=2) for a given map display - index (idx) - """ - global ctrl_dict - ctrls = ctrl_dict[idx][num] - return ctrls - - def popCtrl(self, idx): - """ - Removes entry from display and control dictionary. - Used when display is closed - """ - global ctrl_dict - if ctrl_dict != "": - ctrl_dict.pop(idx) - - def GetDisp_idx(self, ctrl_id): - """ - Returns the display index for the display/controls dictionary entry - given the widget ID of the control (ctrl_id) - """ - global ctrl_dict - for idx,ctrl in ctrl_dict.items(): - if ctrl_id in ctrl: - return idx - - def SetDisp(self, disp_idx, disp_id): - """ - Creates a tuple of the currently active display index and its corresponding - map display frame ID. - """ - global curr_disp - curr_disp = (disp_idx, disp_id) - return curr_disp - - def GetDisp(self): - """ - Returns the (display index, display ID) tuple of the currently - active display - """ - global curr_disp - return curr_disp - Copied: trunk/grassaddons/gui/gui_modules/track.py (from rev 304, trunk/grassaddons/gui/Gism/track.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/track.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/track.py 2007-03-25 06:32:08 UTC (rev 305) @@ -0,0 +1,69 @@ +""" +Variables set at initialization +""" +global curr_disp +curr_disp="" +global ctrl_dict +ctrl_dict={} + +class Track: + """ + This class has functions and variables for tracking map display, + associated notebook pages, and other index values. + """ + + def SetCtrlDict(self, idx, disp, page, tree): + """ + This method stores the associated display index, display ID, + controls book page ID, and map layer tree ID in a dictionary + """ + global ctrl_dict + ctrl_dict[idx]=[disp, page, tree] + return ctrl_dict + + def GetCtrls(self, idx, num): + """ + Returns widget ID for map display (num=0), controls book page + (num=1), or map layer tree (num=2) for a given map display + index (idx) + """ + global ctrl_dict + ctrls = ctrl_dict[idx][num] + return ctrls + + def popCtrl(self, idx): + """ + Removes entry from display and control dictionary. + Used when display is closed + """ + global ctrl_dict + if ctrl_dict != "": + ctrl_dict.pop(idx) + + def GetDisp_idx(self, ctrl_id): + """ + Returns the display index for the display/controls dictionary entry + given the widget ID of the control (ctrl_id) + """ + global ctrl_dict + for idx,ctrl in ctrl_dict.items(): + if ctrl_id in ctrl: + return idx + + def SetDisp(self, disp_idx, disp_id): + """ + Creates a tuple of the currently active display index and its corresponding + map display frame ID. + """ + global curr_disp + curr_disp = (disp_idx, disp_id) + return curr_disp + + def GetDisp(self): + """ + Returns the (display index, display ID) tuple of the currently + active display + """ + global curr_disp + return curr_disp + From barton at grass.itc.it Sun Mar 25 08:32:53 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:32:55 2007 Subject: [grass-addons] r306 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250632.l2P6Wr6p021865@grass.itc.it> Author: barton Date: 2007-03-25 08:32:39 +0200 (Sun, 25 Mar 2007) New Revision: 306 Added: trunk/grassaddons/gui/gui_modules/toolbars.py Removed: trunk/grassaddons/gui/Gism/toolbars.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/toolbars.py =================================================================== --- trunk/grassaddons/gui/Gism/toolbars.py 2007-03-25 06:32:08 UTC (rev 305) +++ trunk/grassaddons/gui/Gism/toolbars.py 2007-03-25 06:32:39 UTC (rev 306) @@ -1,192 +0,0 @@ -""" -toolbars package - -class: -* MapToolbar -""" -import wx -import os -import wxgui_utils - -import cmd - -icons= os.path.split(wxgui_utils.icons)[0] -icons= os.path.split(icons)[0] -icons= os.path.split(icons)[0] -#print icons - -class MapToolbar: - """ - Main Map Display toolbar - """ - def __init__(self, mapdisplay, map): - global icons - self.mapcontent = map - self.mapdisplay = mapdisplay - - self.toolbar = wx.ToolBar(parent=self.mapdisplay, id=wx.ID_ANY, size=(5,100)) - #self.SetToolBar(self.toolbar) - self.toolbar.SetToolBitmapSize(wx.Size(24,24)) - # - # Draw - # - self.displaymap = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="displaymap", - bitmap=wx.Bitmap(name=os.path.join(wxgui_utils.icons,"gui-display.gif"), - type=wx.BITMAP_TYPE_ANY), - bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL, - shortHelp="Display map", longHelp="") - self.erase = self.toolbar.AddLabelTool(wx.ID_ANY, "erase", - wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-erase.gif"), - wx.BITMAP_TYPE_ANY), - wx.NullBitmap, wx.ITEM_NORMAL, "Erase display", "") - self.toolbar.AddSeparator() - - # - # Zooming, etc. - # - self.pointer = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="pointer", - bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-pointer.gif"), - wx.BITMAP_TYPE_ANY), - bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, - shortHelp="Pointer", longHelp="") - self.zoomin = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="zoom_in", - bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-zoom_in.gif"), - wx.BITMAP_TYPE_ANY), - bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, - shortHelp="Zoom in", longHelp="Drag or click mouse to zoom") - self.zoomout = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="zoom_out", - bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-zoom_out.gif"), - wx.BITMAP_TYPE_ANY), - bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, - shortHelp="Zoom out", longHelp="Drag or click mouse to unzoom") - self.pan = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="pan", - bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-pan.gif"), - wx.BITMAP_TYPE_ANY), - bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, - shortHelp="Pan", longHelp="Drag with mouse to pan") - self.toolbar.AddSeparator() - - # - # Misc - # - self.savefile = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="savefile", - #bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"file-save.gif"), - #wx.BITMAP_TYPE_ANY), - # just testing wx.ArtProvider - bitmap=wx.ArtProvider.GetBitmap(id=wx.ART_FILE_SAVE, client=wx.ART_BUTTON), - bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL, - shortHelp="Save display to PNG file", longHelp="") - - self.toolbar.AddSeparator() - - # - # Optional toolbars - # - cb = wx.ComboBox(self.toolbar, id=wx.ID_ANY, value='', - choices=['Digitize'], size=(-1, -1), style=wx.CB_READONLY , name='Tools') - self.combo = self.toolbar.AddControl(cb) - - self.toolbar.Realize() - - self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.ReDraw, self.displaymap) - self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.Pointer, self.pointer) - self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnZoomIn, self.zoomin) - self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnZoomOut, self.zoomout) - self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnPan, self.pan) - self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnErase, self.erase) - self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.SaveToFile, self.savefile) - self.mapdisplay.Bind(wx.EVT_COMBOBOX, self.OnSelect, self.combo) - - def OnSelect(self,event): - tool = event.GetString() - - if tool == "Digitize" and not self.mapdisplay.digittoolbar: - self.mapdisplay.AddToolbar("digit") - -class DigitToolbar: - def __init__(self,parent,map): - - global icons - - self.mapcontent = map - self.digitize=None - self.parent=parent - self.toolbar = wx.ToolBar(self.parent, wx.ID_ANY) - icons = os.path.join(icons,"v.digit") - - self.addString = "" - - self.layers = self._getListOfLayers() - - self.initToolbar() - - def initToolbar(self): - self.combo = wx.ComboBox(self.toolbar, 4, 'Select vector map', - choices=self.layers, size=(120, 10)) - - self.comboid = self.toolbar.AddControl(self.combo) - - self.toolbar.AddSeparator() - - self.point = self.toolbar.AddLabelTool(wx.ID_ANY, "point", - wx.Bitmap(os.path.join(icons,"new.point.gif"), - wx.BITMAP_TYPE_ANY), - wx.NullBitmap, wx.ITEM_RADIO, "Digitize new point", "") - self.line = self.toolbar.AddLabelTool(wx.ID_ANY, "line", - wx.Bitmap(os.path.join(icons,"new.line.gif"), - wx.BITMAP_TYPE_ANY), - wx.NullBitmap, wx.ITEM_RADIO, "Digitize new line", - "") - self.boundary = self.toolbar.AddLabelTool(wx.ID_ANY, "boundary", - wx.Bitmap(os.path.join(icons,"new.boundary.gif"), - wx.BITMAP_TYPE_ANY), - wx.NullBitmap, wx.ITEM_RADIO, "Digitize new boundary", "") - self.centroid = self.toolbar.AddLabelTool(wx.ID_ANY, "centroid", - wx.Bitmap(os.path.join(icons,"new.centroid.gif"), - wx.BITMAP_TYPE_ANY), - wx.NullBitmap, wx.ITEM_RADIO, "Digitize new centroid", "") - - self.parent.Bind(wx.EVT_TOOL, self.OnPoint, self.point) - - def OnPoint(self,event): - - self.digitize="point" - #self.parent.MapWindow.mouse['box'] = "point" - - def AddPoint(self,x,y): - #east,north = self.parent.Pixel2Cell(x,y) - selectedmap=self.combo.GetCurrentSelection() - if selectedmap < 1: - print "you have to select map" - return - - addstring="""P 1 - %f %f - """ % (x,y) - command = """v.edit -n map="%s" tool=add""" % (self.combo.GetValue()) - #print addstring, command - vedit=cmd.Command(command,stdin=addstring) - #try: - # kye,val = vedit.RunV() - # while 1: - # print key,val - # key,val = vedit.RunV() - #except: - # pass - - - def _getListOfLayers(self): - layers =[""] - for layer in self.mapcontent.GetListOfLayers(l_type="vector"): - layers.append( layer.name) - return layers - -#class pokus: -# def __init__(self): -# global icons -# print icons -# -#if __name__=="__main__": -# p = pokus() - - Copied: trunk/grassaddons/gui/gui_modules/toolbars.py (from rev 305, trunk/grassaddons/gui/Gism/toolbars.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-03-25 06:32:39 UTC (rev 306) @@ -0,0 +1,192 @@ +""" +toolbars package + +class: +* MapToolbar +""" +import wx +import os +import wxgui_utils + +import cmd + +icons= os.path.split(wxgui_utils.icons)[0] +icons= os.path.split(icons)[0] +icons= os.path.split(icons)[0] +#print icons + +class MapToolbar: + """ + Main Map Display toolbar + """ + def __init__(self, mapdisplay, map): + global icons + self.mapcontent = map + self.mapdisplay = mapdisplay + + self.toolbar = wx.ToolBar(parent=self.mapdisplay, id=wx.ID_ANY, size=(5,100)) + #self.SetToolBar(self.toolbar) + self.toolbar.SetToolBitmapSize(wx.Size(24,24)) + # + # Draw + # + self.displaymap = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="displaymap", + bitmap=wx.Bitmap(name=os.path.join(wxgui_utils.icons,"gui-display.gif"), + type=wx.BITMAP_TYPE_ANY), + bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL, + shortHelp="Display map", longHelp="") + self.erase = self.toolbar.AddLabelTool(wx.ID_ANY, "erase", + wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-erase.gif"), + wx.BITMAP_TYPE_ANY), + wx.NullBitmap, wx.ITEM_NORMAL, "Erase display", "") + self.toolbar.AddSeparator() + + # + # Zooming, etc. + # + self.pointer = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="pointer", + bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-pointer.gif"), + wx.BITMAP_TYPE_ANY), + bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, + shortHelp="Pointer", longHelp="") + self.zoomin = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="zoom_in", + bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-zoom_in.gif"), + wx.BITMAP_TYPE_ANY), + bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, + shortHelp="Zoom in", longHelp="Drag or click mouse to zoom") + self.zoomout = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="zoom_out", + bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-zoom_out.gif"), + wx.BITMAP_TYPE_ANY), + bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, + shortHelp="Zoom out", longHelp="Drag or click mouse to unzoom") + self.pan = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="pan", + bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"gui-pan.gif"), + wx.BITMAP_TYPE_ANY), + bmpDisabled=wx.NullBitmap, kind=wx.ITEM_RADIO, + shortHelp="Pan", longHelp="Drag with mouse to pan") + self.toolbar.AddSeparator() + + # + # Misc + # + self.savefile = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="savefile", + #bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"file-save.gif"), + #wx.BITMAP_TYPE_ANY), + # just testing wx.ArtProvider + bitmap=wx.ArtProvider.GetBitmap(id=wx.ART_FILE_SAVE, client=wx.ART_BUTTON), + bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL, + shortHelp="Save display to PNG file", longHelp="") + + self.toolbar.AddSeparator() + + # + # Optional toolbars + # + cb = wx.ComboBox(self.toolbar, id=wx.ID_ANY, value='', + choices=['Digitize'], size=(-1, -1), style=wx.CB_READONLY , name='Tools') + self.combo = self.toolbar.AddControl(cb) + + self.toolbar.Realize() + + self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.ReDraw, self.displaymap) + self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.Pointer, self.pointer) + self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnZoomIn, self.zoomin) + self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnZoomOut, self.zoomout) + self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnPan, self.pan) + self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnErase, self.erase) + self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.SaveToFile, self.savefile) + self.mapdisplay.Bind(wx.EVT_COMBOBOX, self.OnSelect, self.combo) + + def OnSelect(self,event): + tool = event.GetString() + + if tool == "Digitize" and not self.mapdisplay.digittoolbar: + self.mapdisplay.AddToolbar("digit") + +class DigitToolbar: + def __init__(self,parent,map): + + global icons + + self.mapcontent = map + self.digitize=None + self.parent=parent + self.toolbar = wx.ToolBar(self.parent, wx.ID_ANY) + icons = os.path.join(icons,"v.digit") + + self.addString = "" + + self.layers = self._getListOfLayers() + + self.initToolbar() + + def initToolbar(self): + self.combo = wx.ComboBox(self.toolbar, 4, 'Select vector map', + choices=self.layers, size=(120, 10)) + + self.comboid = self.toolbar.AddControl(self.combo) + + self.toolbar.AddSeparator() + + self.point = self.toolbar.AddLabelTool(wx.ID_ANY, "point", + wx.Bitmap(os.path.join(icons,"new.point.gif"), + wx.BITMAP_TYPE_ANY), + wx.NullBitmap, wx.ITEM_RADIO, "Digitize new point", "") + self.line = self.toolbar.AddLabelTool(wx.ID_ANY, "line", + wx.Bitmap(os.path.join(icons,"new.line.gif"), + wx.BITMAP_TYPE_ANY), + wx.NullBitmap, wx.ITEM_RADIO, "Digitize new line", + "") + self.boundary = self.toolbar.AddLabelTool(wx.ID_ANY, "boundary", + wx.Bitmap(os.path.join(icons,"new.boundary.gif"), + wx.BITMAP_TYPE_ANY), + wx.NullBitmap, wx.ITEM_RADIO, "Digitize new boundary", "") + self.centroid = self.toolbar.AddLabelTool(wx.ID_ANY, "centroid", + wx.Bitmap(os.path.join(icons,"new.centroid.gif"), + wx.BITMAP_TYPE_ANY), + wx.NullBitmap, wx.ITEM_RADIO, "Digitize new centroid", "") + + self.parent.Bind(wx.EVT_TOOL, self.OnPoint, self.point) + + def OnPoint(self,event): + + self.digitize="point" + #self.parent.MapWindow.mouse['box'] = "point" + + def AddPoint(self,x,y): + #east,north = self.parent.Pixel2Cell(x,y) + selectedmap=self.combo.GetCurrentSelection() + if selectedmap < 1: + print "you have to select map" + return + + addstring="""P 1 + %f %f + """ % (x,y) + command = """v.edit -n map="%s" tool=add""" % (self.combo.GetValue()) + #print addstring, command + vedit=cmd.Command(command,stdin=addstring) + #try: + # kye,val = vedit.RunV() + # while 1: + # print key,val + # key,val = vedit.RunV() + #except: + # pass + + + def _getListOfLayers(self): + layers =[""] + for layer in self.mapcontent.GetListOfLayers(l_type="vector"): + layers.append( layer.name) + return layers + +#class pokus: +# def __init__(self): +# global icons +# print icons +# +#if __name__=="__main__": +# p = pokus() + + From barton at grass.itc.it Sun Mar 25 08:34:23 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:34:24 2007 Subject: [grass-addons] r307 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250634.l2P6YNgK021890@grass.itc.it> Author: barton Date: 2007-03-25 08:34:08 +0200 (Sun, 25 Mar 2007) New Revision: 307 Added: trunk/grassaddons/gui/gui_modules/select.py Removed: trunk/grassaddons/gui/Gism/select.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/select.py =================================================================== --- trunk/grassaddons/gui/Gism/select.py 2007-03-25 06:32:39 UTC (rev 306) +++ trunk/grassaddons/gui/Gism/select.py 2007-03-25 06:34:08 UTC (rev 307) @@ -1,169 +0,0 @@ -import os -import wx -import wx.combo - -class Select(wx.combo.ComboCtrl): - def __init__(self, parent, id, size, type): - """ - Custom control to create a ComboBox with a tree control - to display GIS elements within acessible mapsets. - Elements can be selected with mouse. - """ - wx.combo.ComboCtrl.__init__(self, parent=parent, id=id, size=size) - tcp = TreeCtrlComboPopup() - self.SetPopupControl(tcp) - tcp.getElementList(type) - -class TreeCtrlComboPopup(wx.combo.ComboPopup): - """ - Create a tree ComboBox for selecting maps and other GIS elements - in accessible mapsets within the current location - """ - - # overridden ComboPopup methods - - def Init(self): - self.value = None - self.curitem = None - - - def Create(self, parent): - self.tree = wx.TreeCtrl(parent, style=wx.TR_HIDE_ROOT - |wx.TR_HAS_BUTTONS - |wx.TR_SINGLE - |wx.TR_LINES_AT_ROOT - |wx.SIMPLE_BORDER - |wx.TR_FULL_ROW_HIGHLIGHT) - self.tree.Bind(wx.EVT_MOTION, self.OnMotion) - self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) - - - def GetControl(self): - return self.tree - - - def GetStringValue(self): - if self.value: - return self.tree.GetItemText(self.value) - return "" - - - def OnPopup(self): - if self.value: - self.tree.EnsureVisible(self.value) - self.tree.SelectItem(self.value) - - def SetStringValue(self, value): - # this assumes that item strings are unique... - root = self.tree.GetRootItem() - if not root: - return - found = self.FindItem(root, value) - if found: - self.value = found - self.tree.SelectItem(found) - - def GetAdjustedSize(self, minWidth, prefHeight, maxHeight): - return wx.Size(minWidth, min(200, maxHeight)) - - def getElementList(self, element): - """ - Get list of GIS elements in accessible mapsets and display as tree - with all relevant elements displayed beneath each mapset branch - """ - #set environmental variables - gisdbase = os.popen('g.gisenv get=GISDBASE', "r").read().strip() - location = os.popen('g.gisenv get=LOCATION_NAME', "r").read().strip() - curr_mapset = os.popen('g.gisenv get=MAPSET', "r").read().strip() - location_path = os.path.join (gisdbase,location) - windfile = os.path.join (location_path,'PERMANENT','WIND') - symbol_path = os.path.join (os.environ['GISBASE'],'etc','symbol') - - #valid location test if needed - if windfile != None: - pass - - #mapsets in current location - mapsets = os.popen('g.mapsets -p', "r").read().lstrip().rstrip().split(' ') - - elementlist = ['cell', - 'grid3d', - 'vector', - 'dig', - 'dig_ascii', - 'icons', - 'paint/labels', - 'site_lists', - 'windows', - 'windows3d', - 'group', - '3d.view'] - - if element not in elementlist: - self.AddItem('Not selectable element') - return - - #Get directory tree nodes - for dir in mapsets: - if dir == curr_mapset: - #TODO: make current mapset node expanded - dir_node = self.AddItem('Mapset: '+dir) - self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) - try: - elem_list = os.listdir(os.path.join (location_path, dir, element)) - for elem in elem_list: - self.AddItem(elem+'@'+dir, parent=dir_node) - except: - continue - self.tree.Expand(dir_node) - else: - dir_node = self.AddItem('Mapset: '+dir) - self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) - try: - elem_list = os.listdir(os.path.join (location_path, dir, element)) - for elem in elem_list: - self.AddItem(elem+'@'+dir, parent=dir_node) - except: - continue - - # helpers - def FindItem(self, parentItem, text): - item, cookie = self.tree.GetFirstChild(parentItem) - while item: - if self.tree.GetItemText(item) == text: - return item - if self.tree.ItemHasChildren(item): - item = self.FindItem(item, text) - item, cookie = self.tree.GetNextChild(parentItem, cookie) - return wx.TreeItemId(); - - - def AddItem(self, value, parent=None): - if not parent: - root = self.tree.GetRootItem() - if not root: - root = self.tree.AddRoot("") - parent = root - - item = self.tree.AppendItem(parent, value) - return item - - def OnMotion(self, evt): - # have the selection follow the mouse, like in a real combobox - item, flags = self.tree.HitTest(evt.GetPosition()) - if item and flags & wx.TREE_HITTEST_ONITEMLABEL: - self.tree.SelectItem(item) - self.curitem = item - evt.Skip() - - def OnLeftDown(self, evt): - # do the combobox selection - item, flags = self.tree.HitTest(evt.GetPosition()) - if item and flags & wx.TREE_HITTEST_ONITEMLABEL: - self.curitem = item - self.value = item - self.Dismiss() - evt.Skip() - - - Copied: trunk/grassaddons/gui/gui_modules/select.py (from rev 306, trunk/grassaddons/gui/Gism/select.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/select.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/select.py 2007-03-25 06:34:08 UTC (rev 307) @@ -0,0 +1,169 @@ +import os +import wx +import wx.combo + +class Select(wx.combo.ComboCtrl): + def __init__(self, parent, id, size, type): + """ + Custom control to create a ComboBox with a tree control + to display GIS elements within acessible mapsets. + Elements can be selected with mouse. + """ + wx.combo.ComboCtrl.__init__(self, parent=parent, id=id, size=size) + tcp = TreeCtrlComboPopup() + self.SetPopupControl(tcp) + tcp.getElementList(type) + +class TreeCtrlComboPopup(wx.combo.ComboPopup): + """ + Create a tree ComboBox for selecting maps and other GIS elements + in accessible mapsets within the current location + """ + + # overridden ComboPopup methods + + def Init(self): + self.value = None + self.curitem = None + + + def Create(self, parent): + self.tree = wx.TreeCtrl(parent, style=wx.TR_HIDE_ROOT + |wx.TR_HAS_BUTTONS + |wx.TR_SINGLE + |wx.TR_LINES_AT_ROOT + |wx.SIMPLE_BORDER + |wx.TR_FULL_ROW_HIGHLIGHT) + self.tree.Bind(wx.EVT_MOTION, self.OnMotion) + self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) + + + def GetControl(self): + return self.tree + + + def GetStringValue(self): + if self.value: + return self.tree.GetItemText(self.value) + return "" + + + def OnPopup(self): + if self.value: + self.tree.EnsureVisible(self.value) + self.tree.SelectItem(self.value) + + def SetStringValue(self, value): + # this assumes that item strings are unique... + root = self.tree.GetRootItem() + if not root: + return + found = self.FindItem(root, value) + if found: + self.value = found + self.tree.SelectItem(found) + + def GetAdjustedSize(self, minWidth, prefHeight, maxHeight): + return wx.Size(minWidth, min(200, maxHeight)) + + def getElementList(self, element): + """ + Get list of GIS elements in accessible mapsets and display as tree + with all relevant elements displayed beneath each mapset branch + """ + #set environmental variables + gisdbase = os.popen('g.gisenv get=GISDBASE', "r").read().strip() + location = os.popen('g.gisenv get=LOCATION_NAME', "r").read().strip() + curr_mapset = os.popen('g.gisenv get=MAPSET', "r").read().strip() + location_path = os.path.join (gisdbase,location) + windfile = os.path.join (location_path,'PERMANENT','WIND') + symbol_path = os.path.join (os.environ['GISBASE'],'etc','symbol') + + #valid location test if needed + if windfile != None: + pass + + #mapsets in current location + mapsets = os.popen('g.mapsets -p', "r").read().lstrip().rstrip().split(' ') + + elementlist = ['cell', + 'grid3d', + 'vector', + 'dig', + 'dig_ascii', + 'icons', + 'paint/labels', + 'site_lists', + 'windows', + 'windows3d', + 'group', + '3d.view'] + + if element not in elementlist: + self.AddItem('Not selectable element') + return + + #Get directory tree nodes + for dir in mapsets: + if dir == curr_mapset: + #TODO: make current mapset node expanded + dir_node = self.AddItem('Mapset: '+dir) + self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) + try: + elem_list = os.listdir(os.path.join (location_path, dir, element)) + for elem in elem_list: + self.AddItem(elem+'@'+dir, parent=dir_node) + except: + continue + self.tree.Expand(dir_node) + else: + dir_node = self.AddItem('Mapset: '+dir) + self.tree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) + try: + elem_list = os.listdir(os.path.join (location_path, dir, element)) + for elem in elem_list: + self.AddItem(elem+'@'+dir, parent=dir_node) + except: + continue + + # helpers + def FindItem(self, parentItem, text): + item, cookie = self.tree.GetFirstChild(parentItem) + while item: + if self.tree.GetItemText(item) == text: + return item + if self.tree.ItemHasChildren(item): + item = self.FindItem(item, text) + item, cookie = self.tree.GetNextChild(parentItem, cookie) + return wx.TreeItemId(); + + + def AddItem(self, value, parent=None): + if not parent: + root = self.tree.GetRootItem() + if not root: + root = self.tree.AddRoot("") + parent = root + + item = self.tree.AppendItem(parent, value) + return item + + def OnMotion(self, evt): + # have the selection follow the mouse, like in a real combobox + item, flags = self.tree.HitTest(evt.GetPosition()) + if item and flags & wx.TREE_HITTEST_ONITEMLABEL: + self.tree.SelectItem(item) + self.curitem = item + evt.Skip() + + def OnLeftDown(self, evt): + # do the combobox selection + item, flags = self.tree.HitTest(evt.GetPosition()) + if item and flags & wx.TREE_HITTEST_ONITEMLABEL: + self.curitem = item + self.value = item + self.Dismiss() + evt.Skip() + + + From barton at grass.itc.it Sun Mar 25 08:36:20 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:36:22 2007 Subject: [grass-addons] r308 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250636.l2P6aKrM021916@grass.itc.it> Author: barton Date: 2007-03-25 08:36:06 +0200 (Sun, 25 Mar 2007) New Revision: 308 Added: trunk/grassaddons/gui/gui_modules/render.py Removed: trunk/grassaddons/gui/Gism/render.py Log: Moving items Deleted: trunk/grassaddons/gui/Gism/render.py =================================================================== --- trunk/grassaddons/gui/Gism/render.py 2007-03-25 06:34:08 UTC (rev 307) +++ trunk/grassaddons/gui/Gism/render.py 2007-03-25 06:36:06 UTC (rev 308) @@ -1,1054 +0,0 @@ -""" -class GRASSLayer -class MapLayer -class Map -""" - -import os,sys,glob -import utils - -# Authors : Michael Barton, Jachym Cepicky, Martin Landa -# -# COPYRIGHT:(C) 1999 - 2007 by the GRASS Development Team - -DEBUG = False - -class GRASSLayer: - """ - This class stores GRASS layer metainformation - (command line parameters and flags) needed for creating - MapLayer instance - - Attributes: - params - based on a given GRASS layer (raster, vector, graph, etc.) - """ - - def __init__(self, parameters): - self.params = parameters - -class MapLayer: - """ - This class serves for storing map layers to be displayed - - Common layer attributes: - name - layer name - mapset - mapset name - type - layer type - - active - layer is active, will be rendered only if True - hidden - layer is hidden, won't be listed in GIS Manager if True - opacity - layer opacity [0-1] - - mapfile - file name of rendered layer - maskfile - mask name of rendered layer - """ - - def __init__(self, type, name, mapset, - active, hidden, opacity, - **parameters): - self.name = name - self.mapset = mapset - - self.type = type - self.active = active - self.hidden = hidden - self.opacity = opacity - - self.grassLayer = GRASSLayer(parameters) - - gtemp = utils.GetTempfile() - self.maskfile = gtemp + ".pgm" - self.mapfile = gtemp + ".ppm" - - def __renderRasterLayer(self): - """ - Stores d.rast command with all parameters in the self.cmd variable - """ - - try: - self.cmd = "d.rast -o map=%s@%s" % (self.name, self.mapset) - - for key in self.grassLayer.params.keys(): - value = self.grassLayer.params[key] - - if self.grassLayer.params[key]: - ##FIXME: test data type not strlen - if type(value) == type(""): - self.cmd += " %s=%s" % \ - (key, value) - else: - self.cmd += " -%s" % key - - except StandardError, e: - sys.stderr.write("Could not render raster layer <%s>: %s\n" %\ - (self.name, str(e))) - self.cmd = None - - def __renderVectorLayer(self): - """ - Stores d.vect command with all parameters in the self.cmd variable - """ - - try: - self.cmd = "d.vect map=%s@%s" % (self.name, self.mapset) - - for key in self.grassLayer.params: - if self.grassLayer.params[key]: - ##FIXME: test data type not strlen - if len(key) > 1: - self.cmd += " %s=%s" % \ - (key, self.grassLayer.params[key]) - else: - self.cmd += " -%s" % key - - except StandardError, e: - sys.stderr.write("Could not render vector layer <%s>: %s\n" %\ - (self.name, str(e))) - self.cmd = None - - def __renderCommandLayer(self): - """ - Stores generic command with all parameters in the self.cmd variable - """ - - try: - self.cmd = self.name + " --q" - - except StandardError, e: - sys.stderr.write("Could not render command layer <%s>: %s\n" %\ - (self.name, str(e))) - self.cmd = None - - def Render(self): - """ - Runs all d.* commands. - - Returns: - Name of file with rendered image or None - """ - - # - # create command variable - # - self.cmd = "" - - # - # to be sure, set temporary file with layer and mask - # - if not self.mapfile: - gtemp = utils.GetTempfile() - self.maskfile = gtemp + ".pgm" - self.mapfile = gtemp + ".ppm" - - - # - # prepare command for each layer - # - if self.type == "raster": - self.__renderRasterLayer() - - elif self.type == "vector": - self.__renderVectorLayer() - - elif self.type == "command": - self.__renderCommandLayer() - - elif self.type == "wms": - print "Type wms is not supported yet" - else: - print "Type <%s> of layer <%s> is not supported yet" % \ - (self.type, self.name) - - # - # Start monitor - # - os.environ["GRASS_PNGFILE"] = self.mapfile - os.environ["GRASS_RENDER_IMMEDIATE"] = "TRUE" - - # - # execute command - # - if not self.cmd: - sys.stderr.write("Could not render layer <%s> with command: #%s#" %\ - (self.name, self.cmd)) - return None - - if os.system(self.cmd): - print "Could not execute '%s'" % (self.cmd) - self.mapfile = None - self.maskfile = None - return None - - # - # Stop monitor - # - os.unsetenv("GRASS_PNGFILE") - os.unsetenv("GRASS_RENDER_IMMEDIATE") - - return self.mapfile - -class Map: - """ - This class serves for rendering of output images. - - Attributes: - env - for some environment variables - verbosity - verbosity level - width - width of the map in pixels - height - height of the map in pixels - windfile - content of WIND file for temporary region - settings - n-s resol: 30; - e-w resol: 30; - ... - region - g.region -gp output - "n":1000, - "s":0, - "e":1000, - "w":0, - ... - layers - list of all available layers - renderRegion - dictionary: - "color" : "RRR:GGG:BBB", - "width" : 3, - "render": True/False - mapfile - rendered final image filename - """ - - def __init__(self): - """ - While initalization, necessary variables are set, monitor size is - determined and - """ - - self.wind = {} # WIND settings - self.region = {} # region settings - self.width = 300 # map width - self.height = 400 # map height - - self.layers = [] # stack of available layer - self.lookup = {} # lookup dictionary for tree items and layers - self.env = {} # enviroment variables, like MAPSET, LOCATION_NAME, etc. - self.verbosity = 0 - self.mapfile = utils.GetTempfile() - -# self.renderRegion = { -# "render" : True, # should the region be displayed? -# "color" :"255:0:0", -# "width" : 3 -# } - - # setting some initial env. variables - self.__initEnv() - self.__initRegion() - os.environ["GRASS_TRANSPARENT"] = "TRUE" - os.environ["GRASS_BACKGROUNDCOLOR"] = "ffffff" - os.environ["GRASS_HEIGHT"] = str(self.height) - os.environ["GRASS_WIDTH"] = str(self.width) - os.environ["GRASS_MESSAGE_FORMAT"] = "gui" - os.environ["GRASS_PNG_AUTO_WRITE"] = "TRUE" - os.environ["GRASS_TRUECOLOR"] = "TRUE" - os.environ["GRASS_COMPRESSION"] = "0" - os.environ["GRASS_VERBOSE"] = str(self.verbosity) - - def __initRegion(self): - """ - Reads current region settings from g.region command - """ - - # - # setting region - # - self.region = self.GetRegion() - - # - # setting WIND - # - # FIXME: duplicated region WIND == g.region (at least some values) - # FIXME: cannot open WIND file -> raise exception - windfile = os.path.join (self.env['GISDBASE'], - self.env['LOCATION_NAME'], - self.env['MAPSET'], - "WIND") - - try: - windfile = open (windfile, "r") - except StandardError, e : - sys.stderr.write("Could open file <%s>: %s\n" % \ - (windfile,e)) - sys.exit(1) - - for line in windfile.readlines(): - line = line.strip() - key, value = line.split(":",1) - key = key.strip() - value = value.strip() - self.wind[key] = value - - self.__adjustRegion() - - windfile.close() - - - - # - # setting resolution - # - # self.region['ewres'] = self.region['nsres'] = abs(float(self.region['e']) - # - float(self.region['w']))/self.width - - def __initMonSize(self): - """ - Reads current GRASS monitor dimensions from env or - use the default values [640x480] - """ - - try: - self.width = int (os.getenv("GRASS_WIDTH")) - except: - self.width = 640 - - try: - self.height = int(os.getenv("GRASS_HEIGHT")) - - except: - self.height = 480 - - - def __initEnv(self): - """ - Stores environment variables to self.env variable - """ - - if not os.getenv("GISBASE"): - sys.stderr.write("GISBASE not set, you must be " - "in GRASS GIS to run this program\n") - sys.exit(1) - - #os.system("d.mon --quiet stop=gism") - - for line in os.popen("g.gisenv").readlines(): - line = line.strip() - key, val = line.split("=") - val = val.replace(";","") - val = val.replace("'","") - self.env[key] = val - - def __adjustRegion(self): - """ - Adjust region according to monitor size - """ - - # adjusting region to monitor size - if self.width > self.height and \ - self.region["w"] - self.region["e"] > \ - self.region['n'] - self.region['s']: - - # changing e-w region - self.region["ewres"] = self.region["nsres"] = \ - (self.region['n'] - self.region['s']) / self.height - - center = self.region['w'] + \ - (self.region['e'] - self.region['w']) / 2 - - self.region['w'] = center - self.width / 2 * \ - self.region["nsres"] - - self.region['e'] = center + self.width / 2 * \ - self.region["nsres"] - - self.region['rows'] = self.width - self.region['cols'] = self.height - - else: - # changing n-s region - self.region["ewres"] = self.region["nsres"] = \ - (self.region['e'] - self.region['w']) / self.width - - center = self.region['s'] + \ - (self.region['n'] - self.region['s']) / 2 - - self.region['s'] = center - self.height / 2 * \ - self.region["ewres"] - - self.region['n'] = center + self.height / 2 * \ - self.region["ewres"] - - self.region['rows'] = self.width - self.region['cols'] = self.height - - - def GetRegion(self): - """ - Returns dictionary with output from g.region -gp - - Example: - {"n":"4928010", "s":"4913700", "w":"589980",...} - """ - - region = {} - - tmpreg = os.getenv("GRASS_REGION") - os.unsetenv("GRASS_REGION") - - for reg in os.popen("g.region -gp").readlines(): - reg = reg.strip() - key, val = reg.split("=",1) - try: - region[key] = float(val) - except ValueError: - region[key] = val - - if tmpreg: - os.environ["GRASS_REGION"] = tmpreg - - return region - - def SetRegion(self): - """ - Render string for GRASS_REGION env. variable, so that the images will be rendred - from desired zoom level. - - Returns: - string usable for GRASS_REGION variable or None - """ - - grass_region = "" - - self.__adjustRegion() - - try: - for key in self.wind.keys(): - if key == 'north': - grass_region += "north: %s; " % \ - (self.region['n']) - continue - elif key == "south": - grass_region += "south: %s; " % \ - (self.region['s']) - continue - elif key == "east": - grass_region += "east: %s; " % \ - (self.region['e']) - continue - elif key == "west": - grass_region += "west: %s; " % \ - (self.region['w']) - continue - elif key == "e-w resol": - grass_region += "e-w resol: %f; " % \ - (self.region['ewres']) - continue - elif key == "n-s resol": - grass_region += "n-s resol: %f; " % \ - (self.region['nsres']) - continue - elif key == "cols": - grass_region += 'cols: %d; ' % \ - (self.width) - continue - elif key == "rows": - grass_region += 'rows: %d; ' % \ - (self.height) - continue - else: - grass_region += key + ": " + self.wind[key] + "; " - - return grass_region - - except: - return None - - def GetListOfLayers(self, l_type=None, l_active=None, l_hidden=None): - """ - Returns list of layers of selected type or list of all layers. It - is also possible to get list of active or hidden layers. - - Parameters: - l_type - layer type. raster/vector/wms/... - l_active - only layers with "active" attribute set to True or False - l_hidden - only layers with "hidden" attribute set to True or False - - Returns: - List of selected layers or None - """ - - selected = [] - - # ["raster", "vector", "wms", ... ] - - for layer in self.layers: - - # specified type only - if l_type != None and layer.type != l_type: - continue - - # hidden and active layers - if l_active != None and \ - l_hidden != None: - if layer.active == l_active and \ - layer.hidden == l_hidden: - selected.append(layer) - - # active layers - elif l_active != None: - if layer.active == l_active: - selected.append(layer) - - # hidden layers - elif l_hidden != None: - if layer.hidden == l_hidden: - selected.append(layer) - - # all layers - else: - selected.append(layer) - - if len(selected) > 0: - return selected - else: - return None - - def Render(self, force=False): - """ - Creates final image composite - - NOTE: This function should be done by high-level tools, which - should be avaliable in wxPython library - - Returns: - Name of file with rendered image or None - """ - - ## FIXME: not needed? - maps = [] - masks =[] - opacities = [] - - tmp_region = os.getenv("GRASS_REGION") - os.environ["GRASS_REGION"] = self.SetRegion() - os.environ["GRASS_WIDTH"] = str(self.width) - os.environ["GRASS_HEIGHT"] = str(self.height) - - if DEBUG: - print ("mapimg.py: Map: Render: force=%s" % (force)) - try: - for layer in self.layers: - # skip if hidden or not active - if layer.active == False or layer.hidden == True: - continue - - # render if there is no mapfile - if layer.mapfile == None: - layer.Render() - - # redraw layer content - if force: - if not layer.Render(): - continue - - # add image to compositing list - maps.append(layer.mapfile) - masks.append(layer.maskfile) - opacities.append(str(layer.opacity)) - - # make arrays to strings - mapstr = ",".join(maps) - maskstr = ",".join(masks) - opacstr = repr(",".join(opacities)) - - # compose command - compcmd = "g.pnmcomp in=" + mapstr + \ - " mask=" + maskstr + \ - " opacity=" + opacstr + \ - " background=255:255:255" + \ - " width=" + str(self.width) + \ - " height=" + str(self.height) + \ - " output=" + self.mapfile - - # run g.composite to get composite image - if os.system(compcmd): - sys.stderr.write("Could not run g.pnmcomp\n") - raise Exception (compcmd) - - os.unsetenv("GRASS_REGION") - - if tmp_region: - os.environ["GRASS_REGION"] = tmp_region - - return self.mapfile - except Exception, e: - os.unsetenv("GRASS_REGION") - - if tmp_region: - os.environ["GRASS_REGION"] = tmp_region - return None - - def AddRasterLayer(self, name, mapset=None, catlist=None, - vallist=None, invertCats=False, l_active=True, l_hidden=False, - l_opacity=1, l_render=False): - """ - Adds raster layer to list of layers - - Layer Attributes: - name - raster layer name - mapset - mapset name, default: current - catlist - list of categories - vallist - list of values - invertCats - invert catlist, True/False - - l_active - see MapLayer class - l_hidden - l_opacity - l_render - render an image - - Returns: - Added layer on success or None - - """ - - if not mapset: - mapset = self.env["MAPSET"] - - # l_opacity must be <0;1> - if l_opacity < 0: l_opacity = 0 - elif l_opacity > 1: l_opacity = 1 - - layer = MapLayer("raster", name, mapset, - l_active, l_hidden, l_opacity, - catlist = catlist, - vallist = vallist, - i = invertCats) - - # add maplayer to the list of layers - self.layers.append(layer) - - if l_render: - if not layer.Render(): - sys.stderr.write("Could not render layer <%s@%s>\n" % \ - (name,mapset)) - - return self.layers[-1] - - def AddGraphLayer(self, name, graph=None, color="255:0:0", - coordsinmapunits=False, - l_active=True, l_hidden=True, l_opacity=1, l_render=False): - """ - Adds graph layer to list of layers (for d.graph definition) - - Layer attributes: - name - graphics name - graph - graphics definition (string) - color - color triplet - - coordsinmapunits - coordinates are given in map units - - l_active - see MapLayer class - l_hidden - l_opacity - l_render - render an image - - Returns: - Added layer on success or None - """ - - # l_opacity must be <0;1> - if l_opacity < 0: l_opacity = 0 - elif l_opacity > 1: l_opacity = 1 - - layer = MapLayer("graph", name, "", # current mapset - l_active, l_hidden, l_opacity, - color = color, - coordsinmapunits = coordsinmapunits) - - self.layers.append(layer) - - if l_render: - if not layer.Render(): - sys.stderr.write ("Could not render layer <%s>\n" % \ - (name)) - - return self.layers[-1] - - def AddVectorLayer(self, name, mapset=None, - type = "point,line,boundary,centroid,area,face", - display= "shape", attrcol= None, icon = "basic/circle", - size = 8, layer = 1, cats = None, where = None, width = 1, - wcolumn = None, wscale = 1, color = "000:000:000", - fcolor = "200:200:200", rgb_column = "GRASSRGB", llayer = 1, - lcolor = "256:000:000", bgcolor = None, bcolor = None, - lsize = 8, font = None, xref = "left", yref = "center", - minreg = None, maxreg = None, colorfromtable=False, - randomcolor=False, catsasid=False, l_active=True, - l_hidden=False, l_opacity=1, l_render=False): - """ - Adds vector layer to list of layers - - Layer attributes: - name - raster layer name - mapset - mapset name, default: current - type - feature type - display - display - attrcol - name of column to be displayed - icon - point and centroid symbol - size - symbol size - layer - layer number - cats - category values - where - WHERE conditions of SQL statement - width - line width - wcolumn - name of column for line widths - wscale - scale factor for wcolumn - color - line color - fcolor - area fill color - rgb_column - name of color definition column - llayer - layer number - lcolor - label color - bgcolor - lable border color - lsize - label size - font - font name - xref - label horizontal justification, default: left - yref - label horizontal justification, default: center - minreg - minimum region size when map is displayed - maxreg - maximum region size when map is displayed - - colorfromtable - get colors from map table column - randomcolor - random colors according to category number - catsasid - use values from 'cats' option as line id - - l_active - see MapLayer class - l_hidden - l_opacity - l_render - render an image - - Returns: - Added layer if succeeded or None - """ - - if not mapset: - mapset = self.env["MAPSET"] - - # l_opacity must be <0;1> - if l_opacity < 0: l_opacity = 0 - elif l_opacity > 1: l_opacity = 1 - - - maplayer = MapLayer("vector", name, mapset, - l_active, l_hidden, l_opacity, - display = display, - attrcol = attrcol, - icon = icon, - size = size, - layer = layer, - cats = cats, - where = where, - width = width, - wcolumn = wcolumn, - wscale = wscale, - color = color, - fcolor = fcolor, - rgb_column = rgb_column, - llayer = llayer, - lcolor = lcolor, - bgcolor = bgcolor, - bcolor = bcolor, - lsize = lsize, - font = font, - xref = xref, - yref = yref, - minreg = minreg, - maxreg = maxreg, - colorfromtable = colorfromtable, - randomcolor = randomcolor, - catsasid = catsasid) - - self.layers.append(maplayer) - - if l_render: - if not maplayer.Render(): - sys.stderr.write("Could not render layer <%s@%s>\n" % \ - (name,mapset)) - - return self.layers[-1] - - def AddCommandLayer(self, name, mapset=None, l_active=True, l_hidden=False, - l_opacity=1, l_render=False): - """ - Adds generic layer to list of layers - - Layer Attributes: - name - raster layer name - mapset - mapset name, default: current - - l_active - see MapLayer class - l_hidden - l_opacity - l_render - render an image - - Returns: - Added layer on success or None - - """ - if not mapset: - mapset = self.env["MAPSET"] - - # l_opacity must be <0;1> - if l_opacity < 0: l_opacity = 0 - elif l_opacity > 1: l_opacity = 1 - # the following won't work in all situations. What - # if opacity had somehow been set to 1000? -# l_opacity = float(l_opacity) / 100 - - layer = MapLayer("command", name, mapset, - l_active, l_hidden, l_opacity) - - # add maplayer to the list of layers - self.layers.append(layer) - - if l_render: - if not layer.Render(): - sys.stderr.write("Could not render layer <%s@%s>\n" % \ - (name, mapset)) - - return self.layers[-1] - - def addLayer(self, item, command, mapset=None, l_active=True, l_hidden=False, - l_opacity=1, l_render=False): - """ - Adds generic layer to list of layers - - Layer Attributes: - name - display command - mapset - mapset name, default: current - - l_active - see MapLayer class - l_hidden - l_opacity - l_render - render an image - - Returns: - Added layer on success or None - - """ - if not mapset: - mapset = self.env["MAPSET"] - - # l_opacity must be <0;1> - if l_opacity < 0: l_opacity = 0 - elif l_opacity > 1: l_opacity = 1 - - layer = MapLayer("command", command, mapset, - l_active, l_hidden, l_opacity) - - # add maplayer to the list of layers - self.layers.append(layer) - # add item and layer to lookup dictionary - self.lookup[item] = layer - - if l_render: - if not layer.Render(): - sys.stderr.write("Could not render layer <%s@%s>\n" % \ - (name, mapset)) - - return self.layers[-1] - - def delLayer(self, item): - """ - Removes layer from list of layers, defined by name@mapset or id - - Parameters: - name - map name - mapset - mapset name, default: current - id - index of the layer in layer list - - Returns: - Removed layer on success or None - """ - layer = self.lookup[item] - - if layer in self.layers: - if layer.mapfile: - base = os.path.split(layer.mapfile)[0] - mapfile = os.path.split(layer.mapfile)[1] - tempbase = mapfile.split('.')[0] - basefile = os.path.join(base,tempbase)+r'.*' - for f in glob.glob(basefile): - os.remove(f) - self.layers.remove(layer) - del self.lookup[item] - return layer - - return None - - def reorderLayers(self, item_list): - - # make a new reordered list - temp = [] - - for item in item_list: - temp.append(self.lookup[item]) - - # replace original layers list with reordered one - self.layers = temp - - - def changeLayer(self, item, command, mapset=None, l_active=True, l_hidden=False, - l_opacity=1, l_render=False): - - if not mapset: - mapset = self.env["MAPSET"] - - # l_opacity must be <0;1> - if l_opacity < 0: l_opacity = 0 - elif l_opacity > 1: l_opacity = 1 - - newlayer = MapLayer("command", command, mapset, - l_active, l_hidden, l_opacity) - - oldlayer = self.lookup[item] - oldlayerindex = self.layers.index(oldlayer) - - # add maplayer to the list of layers - if self.lookup[item]: - del self.layers[oldlayerindex] - del self.lookup[item] - if oldlayerindex == 0: - self.layers.append(newlayer) - else: - self.layers.insert(oldlayerindex, newlayer) - self.lookup[item] = newlayer - - - if l_render: - if not layer.Render(): - sys.stderr.write("Could not render layer <%s@%s>\n" % \ - (name, mapset)) - - return self.layers[-1] - - def changeOpacity(self, item, l_opacity): - # l_opacity must be <0;1> - if l_opacity < 0: l_opacity = 0 - elif l_opacity > 1: l_opacity = 1 - layer = self.lookup[item] - layer.opacity = l_opacity - - def changeActive(self, item, activ): - layer = self.lookup[item] - layer.active = activ - - def RemoveLayer(self, name=None, mapset=None, id=None): - """ - Removes layer from list of layers, defined by name@mapset or id - - Parameters: - name - map name - mapset - mapset name, default: current - id - index of the layer in layer list - - Returns: - Removed layer on success or None - """ - - # get mapset name - if not mapset: - mapset = self.env['MAPSET'] - - # del by name - if name: - retlayer = None - for layer in self.layers: - if layer.name == name and layer.mapset == mapset: - retlayer = layer - os.remove(layer.mapfile) - os.remove(layer.maskfile) - self.layers.remove(layer) - return layer - # del by id - elif id != None: - return self.layers.pop(id) - - return None - - def GetLayerIndex(self, name, mapset=None): - """ - Returns index of layer in layer list - - Parameters: - name - map name - mapset - mapset name, default: current - - Returns: - Integer or None - """ - - if not mapset: - mapset = self.env['MAPSET'] - - for i in range(0, len(self.layers)): - if self.layers[i].name == name and \ - self.layers[i].mapset == mapset: - return i - - return None - - def Clean(self): - """ - Go trough all layers and remove them from layer list - Removes also l_mapfile and l_maskfile - - Returns 1 if failed or None if ok" - """ - try: - for layer in self.layers: - if layer.mapfile: - base = os.path.split(layer.mapfile)[0] - mapfile = os.path.split(layer.mapfile)[1] - tempbase = mapfile.split('.')[0] - basefile = os.path.join(base,tempbase)+r'.*' - for f in glob.glob(basefile): - os.remove(f) -# if layer.maskfile: os.remove(layer.maskfile) - self.layers.remove(layer) - return None - except: - return 1 - self.layers = [] - - -if __name__ == "__main__": - print """ - Test of Display class. - Usage: display=Render() - """ - - print "Initializing..." - os.system("g.region -d") - - map = Map() - map.width = 300 - map.height = 400 - - map.AddRasterLayer("elevation.dem", mapset="PERMANENT", catlist="1000-1500", invertCats=True) - - map.AddVectorLayer("roads", color="red", width=3, mapset="PERMANENT", - l_opacity=50) - - image = map.Render(force=True) - - if image: - os.system("display %s" % image) - - #image = map.Render() - #os.system("display %s" % image) - - #print "Rendering only vector layer, and region, on shifted region" - #map.region["n"] ="4937550" - #map.region["s"] ="4904160" - #map.region["w"] ="577290" - #map.Region["e"] ="621690" - #map.RemoveLayer("elevation.dem", mapset="PERMANENT") - #layer = map.GetLayerIndex("roads", mapset="PERMANENT") - #map.layers[layer].color = "green" - ##map.renderRegion["render"] = True - #image = map.Render(force=True) - #os.system("display %s" % image) Copied: trunk/grassaddons/gui/gui_modules/render.py (from rev 307, trunk/grassaddons/gui/Gism/render.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-03-25 06:36:06 UTC (rev 308) @@ -0,0 +1,1054 @@ +""" +class GRASSLayer +class MapLayer +class Map +""" + +import os,sys,glob +import utils + +# Authors : Michael Barton, Jachym Cepicky, Martin Landa +# +# COPYRIGHT:(C) 1999 - 2007 by the GRASS Development Team + +DEBUG = False + +class GRASSLayer: + """ + This class stores GRASS layer metainformation + (command line parameters and flags) needed for creating + MapLayer instance + + Attributes: + params - based on a given GRASS layer (raster, vector, graph, etc.) + """ + + def __init__(self, parameters): + self.params = parameters + +class MapLayer: + """ + This class serves for storing map layers to be displayed + + Common layer attributes: + name - layer name + mapset - mapset name + type - layer type + + active - layer is active, will be rendered only if True + hidden - layer is hidden, won't be listed in GIS Manager if True + opacity - layer opacity [0-1] + + mapfile - file name of rendered layer + maskfile - mask name of rendered layer + """ + + def __init__(self, type, name, mapset, + active, hidden, opacity, + **parameters): + self.name = name + self.mapset = mapset + + self.type = type + self.active = active + self.hidden = hidden + self.opacity = opacity + + self.grassLayer = GRASSLayer(parameters) + + gtemp = utils.GetTempfile() + self.maskfile = gtemp + ".pgm" + self.mapfile = gtemp + ".ppm" + + def __renderRasterLayer(self): + """ + Stores d.rast command with all parameters in the self.cmd variable + """ + + try: + self.cmd = "d.rast -o map=%s@%s" % (self.name, self.mapset) + + for key in self.grassLayer.params.keys(): + value = self.grassLayer.params[key] + + if self.grassLayer.params[key]: + ##FIXME: test data type not strlen + if type(value) == type(""): + self.cmd += " %s=%s" % \ + (key, value) + else: + self.cmd += " -%s" % key + + except StandardError, e: + sys.stderr.write("Could not render raster layer <%s>: %s\n" %\ + (self.name, str(e))) + self.cmd = None + + def __renderVectorLayer(self): + """ + Stores d.vect command with all parameters in the self.cmd variable + """ + + try: + self.cmd = "d.vect map=%s@%s" % (self.name, self.mapset) + + for key in self.grassLayer.params: + if self.grassLayer.params[key]: + ##FIXME: test data type not strlen + if len(key) > 1: + self.cmd += " %s=%s" % \ + (key, self.grassLayer.params[key]) + else: + self.cmd += " -%s" % key + + except StandardError, e: + sys.stderr.write("Could not render vector layer <%s>: %s\n" %\ + (self.name, str(e))) + self.cmd = None + + def __renderCommandLayer(self): + """ + Stores generic command with all parameters in the self.cmd variable + """ + + try: + self.cmd = self.name + " --q" + + except StandardError, e: + sys.stderr.write("Could not render command layer <%s>: %s\n" %\ + (self.name, str(e))) + self.cmd = None + + def Render(self): + """ + Runs all d.* commands. + + Returns: + Name of file with rendered image or None + """ + + # + # create command variable + # + self.cmd = "" + + # + # to be sure, set temporary file with layer and mask + # + if not self.mapfile: + gtemp = utils.GetTempfile() + self.maskfile = gtemp + ".pgm" + self.mapfile = gtemp + ".ppm" + + + # + # prepare command for each layer + # + if self.type == "raster": + self.__renderRasterLayer() + + elif self.type == "vector": + self.__renderVectorLayer() + + elif self.type == "command": + self.__renderCommandLayer() + + elif self.type == "wms": + print "Type wms is not supported yet" + else: + print "Type <%s> of layer <%s> is not supported yet" % \ + (self.type, self.name) + + # + # Start monitor + # + os.environ["GRASS_PNGFILE"] = self.mapfile + os.environ["GRASS_RENDER_IMMEDIATE"] = "TRUE" + + # + # execute command + # + if not self.cmd: + sys.stderr.write("Could not render layer <%s> with command: #%s#" %\ + (self.name, self.cmd)) + return None + + if os.system(self.cmd): + print "Could not execute '%s'" % (self.cmd) + self.mapfile = None + self.maskfile = None + return None + + # + # Stop monitor + # + os.unsetenv("GRASS_PNGFILE") + os.unsetenv("GRASS_RENDER_IMMEDIATE") + + return self.mapfile + +class Map: + """ + This class serves for rendering of output images. + + Attributes: + env - for some environment variables + verbosity - verbosity level + width - width of the map in pixels + height - height of the map in pixels + windfile - content of WIND file for temporary region + settings + n-s resol: 30; + e-w resol: 30; + ... + region - g.region -gp output + "n":1000, + "s":0, + "e":1000, + "w":0, + ... + layers - list of all available layers + renderRegion - dictionary: + "color" : "RRR:GGG:BBB", + "width" : 3, + "render": True/False + mapfile - rendered final image filename + """ + + def __init__(self): + """ + While initalization, necessary variables are set, monitor size is + determined and + """ + + self.wind = {} # WIND settings + self.region = {} # region settings + self.width = 300 # map width + self.height = 400 # map height + + self.layers = [] # stack of available layer + self.lookup = {} # lookup dictionary for tree items and layers + self.env = {} # enviroment variables, like MAPSET, LOCATION_NAME, etc. + self.verbosity = 0 + self.mapfile = utils.GetTempfile() + +# self.renderRegion = { +# "render" : True, # should the region be displayed? +# "color" :"255:0:0", +# "width" : 3 +# } + + # setting some initial env. variables + self.__initEnv() + self.__initRegion() + os.environ["GRASS_TRANSPARENT"] = "TRUE" + os.environ["GRASS_BACKGROUNDCOLOR"] = "ffffff" + os.environ["GRASS_HEIGHT"] = str(self.height) + os.environ["GRASS_WIDTH"] = str(self.width) + os.environ["GRASS_MESSAGE_FORMAT"] = "gui" + os.environ["GRASS_PNG_AUTO_WRITE"] = "TRUE" + os.environ["GRASS_TRUECOLOR"] = "TRUE" + os.environ["GRASS_COMPRESSION"] = "0" + os.environ["GRASS_VERBOSE"] = str(self.verbosity) + + def __initRegion(self): + """ + Reads current region settings from g.region command + """ + + # + # setting region + # + self.region = self.GetRegion() + + # + # setting WIND + # + # FIXME: duplicated region WIND == g.region (at least some values) + # FIXME: cannot open WIND file -> raise exception + windfile = os.path.join (self.env['GISDBASE'], + self.env['LOCATION_NAME'], + self.env['MAPSET'], + "WIND") + + try: + windfile = open (windfile, "r") + except StandardError, e : + sys.stderr.write("Could open file <%s>: %s\n" % \ + (windfile,e)) + sys.exit(1) + + for line in windfile.readlines(): + line = line.strip() + key, value = line.split(":",1) + key = key.strip() + value = value.strip() + self.wind[key] = value + + self.__adjustRegion() + + windfile.close() + + + + # + # setting resolution + # + # self.region['ewres'] = self.region['nsres'] = abs(float(self.region['e']) + # - float(self.region['w']))/self.width + + def __initMonSize(self): + """ + Reads current GRASS monitor dimensions from env or + use the default values [640x480] + """ + + try: + self.width = int (os.getenv("GRASS_WIDTH")) + except: + self.width = 640 + + try: + self.height = int(os.getenv("GRASS_HEIGHT")) + + except: + self.height = 480 + + + def __initEnv(self): + """ + Stores environment variables to self.env variable + """ + + if not os.getenv("GISBASE"): + sys.stderr.write("GISBASE not set, you must be " + "in GRASS GIS to run this program\n") + sys.exit(1) + + #os.system("d.mon --quiet stop=gism") + + for line in os.popen("g.gisenv").readlines(): + line = line.strip() + key, val = line.split("=") + val = val.replace(";","") + val = val.replace("'","") + self.env[key] = val + + def __adjustRegion(self): + """ + Adjust region according to monitor size + """ + + # adjusting region to monitor size + if self.width > self.height and \ + self.region["w"] - self.region["e"] > \ + self.region['n'] - self.region['s']: + + # changing e-w region + self.region["ewres"] = self.region["nsres"] = \ + (self.region['n'] - self.region['s']) / self.height + + center = self.region['w'] + \ + (self.region['e'] - self.region['w']) / 2 + + self.region['w'] = center - self.width / 2 * \ + self.region["nsres"] + + self.region['e'] = center + self.width / 2 * \ + self.region["nsres"] + + self.region['rows'] = self.width + self.region['cols'] = self.height + + else: + # changing n-s region + self.region["ewres"] = self.region["nsres"] = \ + (self.region['e'] - self.region['w']) / self.width + + center = self.region['s'] + \ + (self.region['n'] - self.region['s']) / 2 + + self.region['s'] = center - self.height / 2 * \ + self.region["ewres"] + + self.region['n'] = center + self.height / 2 * \ + self.region["ewres"] + + self.region['rows'] = self.width + self.region['cols'] = self.height + + + def GetRegion(self): + """ + Returns dictionary with output from g.region -gp + + Example: + {"n":"4928010", "s":"4913700", "w":"589980",...} + """ + + region = {} + + tmpreg = os.getenv("GRASS_REGION") + os.unsetenv("GRASS_REGION") + + for reg in os.popen("g.region -gp").readlines(): + reg = reg.strip() + key, val = reg.split("=",1) + try: + region[key] = float(val) + except ValueError: + region[key] = val + + if tmpreg: + os.environ["GRASS_REGION"] = tmpreg + + return region + + def SetRegion(self): + """ + Render string for GRASS_REGION env. variable, so that the images will be rendred + from desired zoom level. + + Returns: + string usable for GRASS_REGION variable or None + """ + + grass_region = "" + + self.__adjustRegion() + + try: + for key in self.wind.keys(): + if key == 'north': + grass_region += "north: %s; " % \ + (self.region['n']) + continue + elif key == "south": + grass_region += "south: %s; " % \ + (self.region['s']) + continue + elif key == "east": + grass_region += "east: %s; " % \ + (self.region['e']) + continue + elif key == "west": + grass_region += "west: %s; " % \ + (self.region['w']) + continue + elif key == "e-w resol": + grass_region += "e-w resol: %f; " % \ + (self.region['ewres']) + continue + elif key == "n-s resol": + grass_region += "n-s resol: %f; " % \ + (self.region['nsres']) + continue + elif key == "cols": + grass_region += 'cols: %d; ' % \ + (self.width) + continue + elif key == "rows": + grass_region += 'rows: %d; ' % \ + (self.height) + continue + else: + grass_region += key + ": " + self.wind[key] + "; " + + return grass_region + + except: + return None + + def GetListOfLayers(self, l_type=None, l_active=None, l_hidden=None): + """ + Returns list of layers of selected type or list of all layers. It + is also possible to get list of active or hidden layers. + + Parameters: + l_type - layer type. raster/vector/wms/... + l_active - only layers with "active" attribute set to True or False + l_hidden - only layers with "hidden" attribute set to True or False + + Returns: + List of selected layers or None + """ + + selected = [] + + # ["raster", "vector", "wms", ... ] + + for layer in self.layers: + + # specified type only + if l_type != None and layer.type != l_type: + continue + + # hidden and active layers + if l_active != None and \ + l_hidden != None: + if layer.active == l_active and \ + layer.hidden == l_hidden: + selected.append(layer) + + # active layers + elif l_active != None: + if layer.active == l_active: + selected.append(layer) + + # hidden layers + elif l_hidden != None: + if layer.hidden == l_hidden: + selected.append(layer) + + # all layers + else: + selected.append(layer) + + if len(selected) > 0: + return selected + else: + return None + + def Render(self, force=False): + """ + Creates final image composite + + NOTE: This function should be done by high-level tools, which + should be avaliable in wxPython library + + Returns: + Name of file with rendered image or None + """ + + ## FIXME: not needed? + maps = [] + masks =[] + opacities = [] + + tmp_region = os.getenv("GRASS_REGION") + os.environ["GRASS_REGION"] = self.SetRegion() + os.environ["GRASS_WIDTH"] = str(self.width) + os.environ["GRASS_HEIGHT"] = str(self.height) + + if DEBUG: + print ("mapimg.py: Map: Render: force=%s" % (force)) + try: + for layer in self.layers: + # skip if hidden or not active + if layer.active == False or layer.hidden == True: + continue + + # render if there is no mapfile + if layer.mapfile == None: + layer.Render() + + # redraw layer content + if force: + if not layer.Render(): + continue + + # add image to compositing list + maps.append(layer.mapfile) + masks.append(layer.maskfile) + opacities.append(str(layer.opacity)) + + # make arrays to strings + mapstr = ",".join(maps) + maskstr = ",".join(masks) + opacstr = repr(",".join(opacities)) + + # compose command + compcmd = "g.pnmcomp in=" + mapstr + \ + " mask=" + maskstr + \ + " opacity=" + opacstr + \ + " background=255:255:255" + \ + " width=" + str(self.width) + \ + " height=" + str(self.height) + \ + " output=" + self.mapfile + + # run g.composite to get composite image + if os.system(compcmd): + sys.stderr.write("Could not run g.pnmcomp\n") + raise Exception (compcmd) + + os.unsetenv("GRASS_REGION") + + if tmp_region: + os.environ["GRASS_REGION"] = tmp_region + + return self.mapfile + except Exception, e: + os.unsetenv("GRASS_REGION") + + if tmp_region: + os.environ["GRASS_REGION"] = tmp_region + return None + + def AddRasterLayer(self, name, mapset=None, catlist=None, + vallist=None, invertCats=False, l_active=True, l_hidden=False, + l_opacity=1, l_render=False): + """ + Adds raster layer to list of layers + + Layer Attributes: + name - raster layer name + mapset - mapset name, default: current + catlist - list of categories + vallist - list of values + invertCats - invert catlist, True/False + + l_active - see MapLayer class + l_hidden + l_opacity + l_render - render an image + + Returns: + Added layer on success or None + + """ + + if not mapset: + mapset = self.env["MAPSET"] + + # l_opacity must be <0;1> + if l_opacity < 0: l_opacity = 0 + elif l_opacity > 1: l_opacity = 1 + + layer = MapLayer("raster", name, mapset, + l_active, l_hidden, l_opacity, + catlist = catlist, + vallist = vallist, + i = invertCats) + + # add maplayer to the list of layers + self.layers.append(layer) + + if l_render: + if not layer.Render(): + sys.stderr.write("Could not render layer <%s@%s>\n" % \ + (name,mapset)) + + return self.layers[-1] + + def AddGraphLayer(self, name, graph=None, color="255:0:0", + coordsinmapunits=False, + l_active=True, l_hidden=True, l_opacity=1, l_render=False): + """ + Adds graph layer to list of layers (for d.graph definition) + + Layer attributes: + name - graphics name + graph - graphics definition (string) + color - color triplet + + coordsinmapunits - coordinates are given in map units + + l_active - see MapLayer class + l_hidden + l_opacity + l_render - render an image + + Returns: + Added layer on success or None + """ + + # l_opacity must be <0;1> + if l_opacity < 0: l_opacity = 0 + elif l_opacity > 1: l_opacity = 1 + + layer = MapLayer("graph", name, "", # current mapset + l_active, l_hidden, l_opacity, + color = color, + coordsinmapunits = coordsinmapunits) + + self.layers.append(layer) + + if l_render: + if not layer.Render(): + sys.stderr.write ("Could not render layer <%s>\n" % \ + (name)) + + return self.layers[-1] + + def AddVectorLayer(self, name, mapset=None, + type = "point,line,boundary,centroid,area,face", + display= "shape", attrcol= None, icon = "basic/circle", + size = 8, layer = 1, cats = None, where = None, width = 1, + wcolumn = None, wscale = 1, color = "000:000:000", + fcolor = "200:200:200", rgb_column = "GRASSRGB", llayer = 1, + lcolor = "256:000:000", bgcolor = None, bcolor = None, + lsize = 8, font = None, xref = "left", yref = "center", + minreg = None, maxreg = None, colorfromtable=False, + randomcolor=False, catsasid=False, l_active=True, + l_hidden=False, l_opacity=1, l_render=False): + """ + Adds vector layer to list of layers + + Layer attributes: + name - raster layer name + mapset - mapset name, default: current + type - feature type + display - display + attrcol - name of column to be displayed + icon - point and centroid symbol + size - symbol size + layer - layer number + cats - category values + where - WHERE conditions of SQL statement + width - line width + wcolumn - name of column for line widths + wscale - scale factor for wcolumn + color - line color + fcolor - area fill color + rgb_column - name of color definition column + llayer - layer number + lcolor - label color + bgcolor - lable border color + lsize - label size + font - font name + xref - label horizontal justification, default: left + yref - label horizontal justification, default: center + minreg - minimum region size when map is displayed + maxreg - maximum region size when map is displayed + + colorfromtable - get colors from map table column + randomcolor - random colors according to category number + catsasid - use values from 'cats' option as line id + + l_active - see MapLayer class + l_hidden + l_opacity + l_render - render an image + + Returns: + Added layer if succeeded or None + """ + + if not mapset: + mapset = self.env["MAPSET"] + + # l_opacity must be <0;1> + if l_opacity < 0: l_opacity = 0 + elif l_opacity > 1: l_opacity = 1 + + + maplayer = MapLayer("vector", name, mapset, + l_active, l_hidden, l_opacity, + display = display, + attrcol = attrcol, + icon = icon, + size = size, + layer = layer, + cats = cats, + where = where, + width = width, + wcolumn = wcolumn, + wscale = wscale, + color = color, + fcolor = fcolor, + rgb_column = rgb_column, + llayer = llayer, + lcolor = lcolor, + bgcolor = bgcolor, + bcolor = bcolor, + lsize = lsize, + font = font, + xref = xref, + yref = yref, + minreg = minreg, + maxreg = maxreg, + colorfromtable = colorfromtable, + randomcolor = randomcolor, + catsasid = catsasid) + + self.layers.append(maplayer) + + if l_render: + if not maplayer.Render(): + sys.stderr.write("Could not render layer <%s@%s>\n" % \ + (name,mapset)) + + return self.layers[-1] + + def AddCommandLayer(self, name, mapset=None, l_active=True, l_hidden=False, + l_opacity=1, l_render=False): + """ + Adds generic layer to list of layers + + Layer Attributes: + name - raster layer name + mapset - mapset name, default: current + + l_active - see MapLayer class + l_hidden + l_opacity + l_render - render an image + + Returns: + Added layer on success or None + + """ + if not mapset: + mapset = self.env["MAPSET"] + + # l_opacity must be <0;1> + if l_opacity < 0: l_opacity = 0 + elif l_opacity > 1: l_opacity = 1 + # the following won't work in all situations. What + # if opacity had somehow been set to 1000? +# l_opacity = float(l_opacity) / 100 + + layer = MapLayer("command", name, mapset, + l_active, l_hidden, l_opacity) + + # add maplayer to the list of layers + self.layers.append(layer) + + if l_render: + if not layer.Render(): + sys.stderr.write("Could not render layer <%s@%s>\n" % \ + (name, mapset)) + + return self.layers[-1] + + def addLayer(self, item, command, mapset=None, l_active=True, l_hidden=False, + l_opacity=1, l_render=False): + """ + Adds generic layer to list of layers + + Layer Attributes: + name - display command + mapset - mapset name, default: current + + l_active - see MapLayer class + l_hidden + l_opacity + l_render - render an image + + Returns: + Added layer on success or None + + """ + if not mapset: + mapset = self.env["MAPSET"] + + # l_opacity must be <0;1> + if l_opacity < 0: l_opacity = 0 + elif l_opacity > 1: l_opacity = 1 + + layer = MapLayer("command", command, mapset, + l_active, l_hidden, l_opacity) + + # add maplayer to the list of layers + self.layers.append(layer) + # add item and layer to lookup dictionary + self.lookup[item] = layer + + if l_render: + if not layer.Render(): + sys.stderr.write("Could not render layer <%s@%s>\n" % \ + (name, mapset)) + + return self.layers[-1] + + def delLayer(self, item): + """ + Removes layer from list of layers, defined by name@mapset or id + + Parameters: + name - map name + mapset - mapset name, default: current + id - index of the layer in layer list + + Returns: + Removed layer on success or None + """ + layer = self.lookup[item] + + if layer in self.layers: + if layer.mapfile: + base = os.path.split(layer.mapfile)[0] + mapfile = os.path.split(layer.mapfile)[1] + tempbase = mapfile.split('.')[0] + basefile = os.path.join(base,tempbase)+r'.*' + for f in glob.glob(basefile): + os.remove(f) + self.layers.remove(layer) + del self.lookup[item] + return layer + + return None + + def reorderLayers(self, item_list): + + # make a new reordered list + temp = [] + + for item in item_list: + temp.append(self.lookup[item]) + + # replace original layers list with reordered one + self.layers = temp + + + def changeLayer(self, item, command, mapset=None, l_active=True, l_hidden=False, + l_opacity=1, l_render=False): + + if not mapset: + mapset = self.env["MAPSET"] + + # l_opacity must be <0;1> + if l_opacity < 0: l_opacity = 0 + elif l_opacity > 1: l_opacity = 1 + + newlayer = MapLayer("command", command, mapset, + l_active, l_hidden, l_opacity) + + oldlayer = self.lookup[item] + oldlayerindex = self.layers.index(oldlayer) + + # add maplayer to the list of layers + if self.lookup[item]: + del self.layers[oldlayerindex] + del self.lookup[item] + if oldlayerindex == 0: + self.layers.append(newlayer) + else: + self.layers.insert(oldlayerindex, newlayer) + self.lookup[item] = newlayer + + + if l_render: + if not layer.Render(): + sys.stderr.write("Could not render layer <%s@%s>\n" % \ + (name, mapset)) + + return self.layers[-1] + + def changeOpacity(self, item, l_opacity): + # l_opacity must be <0;1> + if l_opacity < 0: l_opacity = 0 + elif l_opacity > 1: l_opacity = 1 + layer = self.lookup[item] + layer.opacity = l_opacity + + def changeActive(self, item, activ): + layer = self.lookup[item] + layer.active = activ + + def RemoveLayer(self, name=None, mapset=None, id=None): + """ + Removes layer from list of layers, defined by name@mapset or id + + Parameters: + name - map name + mapset - mapset name, default: current + id - index of the layer in layer list + + Returns: + Removed layer on success or None + """ + + # get mapset name + if not mapset: + mapset = self.env['MAPSET'] + + # del by name + if name: + retlayer = None + for layer in self.layers: + if layer.name == name and layer.mapset == mapset: + retlayer = layer + os.remove(layer.mapfile) + os.remove(layer.maskfile) + self.layers.remove(layer) + return layer + # del by id + elif id != None: + return self.layers.pop(id) + + return None + + def GetLayerIndex(self, name, mapset=None): + """ + Returns index of layer in layer list + + Parameters: + name - map name + mapset - mapset name, default: current + + Returns: + Integer or None + """ + + if not mapset: + mapset = self.env['MAPSET'] + + for i in range(0, len(self.layers)): + if self.layers[i].name == name and \ + self.layers[i].mapset == mapset: + return i + + return None + + def Clean(self): + """ + Go trough all layers and remove them from layer list + Removes also l_mapfile and l_maskfile + + Returns 1 if failed or None if ok" + """ + try: + for layer in self.layers: + if layer.mapfile: + base = os.path.split(layer.mapfile)[0] + mapfile = os.path.split(layer.mapfile)[1] + tempbase = mapfile.split('.')[0] + basefile = os.path.join(base,tempbase)+r'.*' + for f in glob.glob(basefile): + os.remove(f) +# if layer.maskfile: os.remove(layer.maskfile) + self.layers.remove(layer) + return None + except: + return 1 + self.layers = [] + + +if __name__ == "__main__": + print """ + Test of Display class. + Usage: display=Render() + """ + + print "Initializing..." + os.system("g.region -d") + + map = Map() + map.width = 300 + map.height = 400 + + map.AddRasterLayer("elevation.dem", mapset="PERMANENT", catlist="1000-1500", invertCats=True) + + map.AddVectorLayer("roads", color="red", width=3, mapset="PERMANENT", + l_opacity=50) + + image = map.Render(force=True) + + if image: + os.system("display %s" % image) + + #image = map.Render() + #os.system("display %s" % image) + + #print "Rendering only vector layer, and region, on shifted region" + #map.region["n"] ="4937550" + #map.region["s"] ="4904160" + #map.region["w"] ="577290" + #map.Region["e"] ="621690" + #map.RemoveLayer("elevation.dem", mapset="PERMANENT") + #layer = map.GetLayerIndex("roads", mapset="PERMANENT") + #map.layers[layer].color = "green" + ##map.renderRegion["render"] = True + #image = map.Render(force=True) + #os.system("display %s" % image) From barton at grass.itc.it Sun Mar 25 08:37:21 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:37:23 2007 Subject: [grass-addons] r309 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250637.l2P6bLqp021942@grass.itc.it> Author: barton Date: 2007-03-25 08:37:07 +0200 (Sun, 25 Mar 2007) New Revision: 309 Added: trunk/grassaddons/gui/gui_modules/packages-uml.svg Removed: trunk/grassaddons/gui/Gism/packages-uml.svg Log: Moving items Deleted: trunk/grassaddons/gui/Gism/packages-uml.svg =================================================================== --- trunk/grassaddons/gui/Gism/packages-uml.svg 2007-03-25 06:36:06 UTC (rev 308) +++ trunk/grassaddons/gui/Gism/packages-uml.svg 2007-03-25 06:37:07 UTC (rev 309) @@ -1,218 +0,0 @@ - - - - - - - - gismutils - - - - - render - - - MapLayer - - - +cmd: string - +name: string - +mapset: string - +type: string - +active: boolean - +hidden: boolean - +opacity: integer - +mapfile: string - +maskfile: string - - - -init(type:string,name:string,mapset:string, - active:boolean,hidden:boolean,opacity:boolean, - parameters:dictionary) - -renderRasterLayer() - -renderVectorLayer() - +Render(): name of rendered image or None - - - - - - layer - 0..* - 1 - - - <<wx.lib.customtreectrl.CustomTreeCtrl>> - LayerTree - - - - - -init(...) - +AddLayer(idx:integer,layertype:string) - +onCollapseNode() - +onExpandNone() - +onActiveLayer() - +onChangeSel() - - - Map - - - +env: dictionary - +verbosity: integer - +width: integer - +height: integer - +windfile: string - +region: dictionary - +layer: list - +renderRegion: dictionary - +mapfile: string - - - -init() - -initRegion() - -initMonSize() - -initEnv() - -adjustRegion() - +GetRegion(): region - +SetRegion(): GRASS_REGION or string - +GetListOfLayers(type:string=None,active:boolean=None, - hidden:boolean=None): list of layers - +Render(force:boolean=None): rendered image filename - +AddRasterLayer(name:string,mapset:string=None, - catlist:string=None,vallist:string=None, - l_active:boolean=True,l_hidden:boolean=False, - l_opacity:integer=1,l_render:boolean=False): added layer - +AddGraphLayer(name:string,graph:string=None, - color:string=255:0:0,coordsinmapunits:boolean=False, - l_active:boolean=True,l_hidden:boolean=False, - l_opacity:integer=1,l_render:boolean=False): added layer - +AddVectorLayer(name:string,mapset:string=None, - type:string,display:string=shape, - attrcol:string=None,icon:string=basic/circle, - size:integer=8,layer:integer=1, - cats:string=None,where:string=None, - width:integer=1,wcolumn:string=None, - wscale:inreger=1,color:string=000:000:000, - fcolor:string=200:200:200, - rgb_column:string=GRASSRBG, - llayer:integer=1,lcolor:string=256:000:000, - bgcolor:string=None,bcolor:string=None, - lsize:integer=8,font:string=None, - xref:string=left,yref:string=center, - minreg:string=None,maxreg:string=None, - colorfromtable:boolean=False, - randomcolor:boolean=False, - catasid:boolean=False,l_active:boolean=True, - l_hidden:boolean=False,l_opacity:boolean=1, - l_render:boolean=False): added layer - +PopLayer(name:string=None,mapset:string=None, - id:integer=None): Layer - +GetLayerIndex(name:string,mapset:string=None): index or None - +Clean() - - - <<wx.Panel>> - GMConsole - - - - - -init() - +getGRASSCmd() - +runCmd(event) - +clearHistory(event) - +saveHistory(event) - - - - - GetTempFile (pref=None) - - - - - toolbars - - - MapToolBar - - - - - -init(mapdisplay,map) - +onSelect(event) - - - DigitToolbar - - - - - -init(parent,map) - +initToolbar() - +onPoint(event) - +AddPoint(x,y) - +getListOfLayers() - - - - - grassenv - - - <<Exception>> - NotInGRASSSession - - - - - - - <<Exception>> - CouldNotStartMonitor - - - - - - - <<Exception>> - CouldNotExecute - - - - - - - <<Exception>> - CouldNotStopMonitor - - - - - - - - - env - - - GRASSLayer - - - +params: dictionary - - - -init(parameters:dictionary) - - - - - - 1 - grassLayer - 1 - Copied: trunk/grassaddons/gui/gui_modules/packages-uml.svg (from rev 308, trunk/grassaddons/gui/Gism/packages-uml.svg) =================================================================== --- trunk/grassaddons/gui/gui_modules/packages-uml.svg (rev 0) +++ trunk/grassaddons/gui/gui_modules/packages-uml.svg 2007-03-25 06:37:07 UTC (rev 309) @@ -0,0 +1,218 @@ + + + + + + + + gismutils + + + + + render + + + MapLayer + + + +cmd: string + +name: string + +mapset: string + +type: string + +active: boolean + +hidden: boolean + +opacity: integer + +mapfile: string + +maskfile: string + + + -init(type:string,name:string,mapset:string, + active:boolean,hidden:boolean,opacity:boolean, + parameters:dictionary) + -renderRasterLayer() + -renderVectorLayer() + +Render(): name of rendered image or None + + + + + + layer + 0..* + 1 + + + <<wx.lib.customtreectrl.CustomTreeCtrl>> + LayerTree + + + + + -init(...) + +AddLayer(idx:integer,layertype:string) + +onCollapseNode() + +onExpandNone() + +onActiveLayer() + +onChangeSel() + + + Map + + + +env: dictionary + +verbosity: integer + +width: integer + +height: integer + +windfile: string + +region: dictionary + +layer: list + +renderRegion: dictionary + +mapfile: string + + + -init() + -initRegion() + -initMonSize() + -initEnv() + -adjustRegion() + +GetRegion(): region + +SetRegion(): GRASS_REGION or string + +GetListOfLayers(type:string=None,active:boolean=None, + hidden:boolean=None): list of layers + +Render(force:boolean=None): rendered image filename + +AddRasterLayer(name:string,mapset:string=None, + catlist:string=None,vallist:string=None, + l_active:boolean=True,l_hidden:boolean=False, + l_opacity:integer=1,l_render:boolean=False): added layer + +AddGraphLayer(name:string,graph:string=None, + color:string=255:0:0,coordsinmapunits:boolean=False, + l_active:boolean=True,l_hidden:boolean=False, + l_opacity:integer=1,l_render:boolean=False): added layer + +AddVectorLayer(name:string,mapset:string=None, + type:string,display:string=shape, + attrcol:string=None,icon:string=basic/circle, + size:integer=8,layer:integer=1, + cats:string=None,where:string=None, + width:integer=1,wcolumn:string=None, + wscale:inreger=1,color:string=000:000:000, + fcolor:string=200:200:200, + rgb_column:string=GRASSRBG, + llayer:integer=1,lcolor:string=256:000:000, + bgcolor:string=None,bcolor:string=None, + lsize:integer=8,font:string=None, + xref:string=left,yref:string=center, + minreg:string=None,maxreg:string=None, + colorfromtable:boolean=False, + randomcolor:boolean=False, + catasid:boolean=False,l_active:boolean=True, + l_hidden:boolean=False,l_opacity:boolean=1, + l_render:boolean=False): added layer + +PopLayer(name:string=None,mapset:string=None, + id:integer=None): Layer + +GetLayerIndex(name:string,mapset:string=None): index or None + +Clean() + + + <<wx.Panel>> + GMConsole + + + + + -init() + +getGRASSCmd() + +runCmd(event) + +clearHistory(event) + +saveHistory(event) + + + + + GetTempFile (pref=None) + + + + + toolbars + + + MapToolBar + + + + + -init(mapdisplay,map) + +onSelect(event) + + + DigitToolbar + + + + + -init(parent,map) + +initToolbar() + +onPoint(event) + +AddPoint(x,y) + +getListOfLayers() + + + + + grassenv + + + <<Exception>> + NotInGRASSSession + + + + + + + <<Exception>> + CouldNotStartMonitor + + + + + + + <<Exception>> + CouldNotExecute + + + + + + + <<Exception>> + CouldNotStopMonitor + + + + + + + + + env + + + GRASSLayer + + + +params: dictionary + + + -init(parameters:dictionary) + + + + + + 1 + grassLayer + 1 + From barton at grass.itc.it Sun Mar 25 08:40:31 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:40:32 2007 Subject: [grass-addons] r311 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250640.l2P6eVQv021988@grass.itc.it> Author: barton Date: 2007-03-25 08:40:17 +0200 (Sun, 25 Mar 2007) New Revision: 311 Added: trunk/grassaddons/gui/gui_modules/optpanels/ Removed: trunk/grassaddons/gui/Gism/optpanels/ Log: Moving items Copied: trunk/grassaddons/gui/gui_modules/optpanels (from rev 310, trunk/grassaddons/gui/Gism/optpanels) From barton at grass.itc.it Sun Mar 25 08:42:41 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:42:42 2007 Subject: [grass-addons] r312 - trunk/grassaddons/gui Message-ID: <200703250642.l2P6gfNg022020@grass.itc.it> Author: barton Date: 2007-03-25 08:42:35 +0200 (Sun, 25 Mar 2007) New Revision: 312 Removed: trunk/grassaddons/gui/Gism/ Log: replaced by gui_modules From barton at grass.itc.it Sun Mar 25 08:54:59 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 08:55:00 2007 Subject: [grass-addons] r313 - trunk/grassaddons/gui/scripts Message-ID: <200703250654.l2P6sxjK022453@grass.itc.it> Author: barton Date: 2007-03-25 08:54:51 +0200 (Sun, 25 Mar 2007) New Revision: 313 Modified: trunk/grassaddons/gui/scripts/p.mon Log: Updated to use new names (gui_modules) Modified: trunk/grassaddons/gui/scripts/p.mon =================================================================== --- trunk/grassaddons/gui/scripts/p.mon 2007-03-25 06:42:35 UTC (rev 312) +++ trunk/grassaddons/gui/scripts/p.mon 2007-03-25 06:54:51 UTC (rev 313) @@ -68,4 +68,4 @@ command_file="`g.tempfile pid=$$`" g.gisenv set=GRASS_PYCMDFILE=${command_file} -python Gism/mapdisp.py ${command_file} & +python gui_modules/mapdisp.py ${command_file} & From barton at grass.itc.it Sun Mar 25 21:12:35 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 21:12:36 2007 Subject: [grass-addons] r314 - trunk/grassaddons/gui/gui_modules Message-ID: <200703251912.l2PJCZRJ027922@grass.itc.it> Author: barton Date: 2007-03-25 21:12:26 +0200 (Sun, 25 Mar 2007) New Revision: 314 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: Using subprocess.Popen for command output now. Also fixed command fonts to use monospaced font family for better display. Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-25 06:54:51 UTC (rev 313) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-25 19:12:26 UTC (rev 314) @@ -9,11 +9,11 @@ #FIXME?? try: - import subprocess + from subprocess import * except: from compat import subprocess + from subprocess import * - gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules/" sys.path.append(gmpath) @@ -577,6 +577,7 @@ self.cmd_output = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE| wx.TE_READONLY) + self.cmd_output.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, '')) global goutput goutput = self.cmd_output @@ -686,20 +687,17 @@ # Send any other command to the shell. Send output to # console output window. try: - retcode = subprocess.call(cmd, shell=True) + self.cmd_output.write(cmd+"\n----------\n") + self.out = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).communicate()[0] + self.cmd_output.write(self.out+"\n") - if retcode < 0: - print >> sys.stderr, "Child was terminated by signal", retcode - elif retcode > 0: - print >> sys.stderr, "Child returned", retcode + if self.out < 0: + print >> sys.stderr, "Child was terminated by signal", self.out + elif self.out > 0: + print >> sys.stderr, "Child returned", self.out except OSError, e: print >> sys.stderr, "Execution failed:", e - self.cmd_output.write(cmd+"\n----------\n") - #FIXME - why is PIPE not recognized? -# self.out = subprocess.Popen(cmd, shell=True, stdout=PIPE).stdout - self.out = os.popen(cmd, "r").read() - self.cmd_output.write(self.out+"\n") def clearHistory(self, event): self.cmd_output.Clear() From barton at grass.itc.it Sun Mar 25 21:20:10 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 21:20:10 2007 Subject: [grass-addons] r315 - trunk/grassaddons/gui Message-ID: <200703251920.l2PJK98S028373@grass.itc.it> Author: barton Date: 2007-03-25 21:20:01 +0200 (Sun, 25 Mar 2007) New Revision: 315 Modified: trunk/grassaddons/gui/wxgui.py Log: Fixed font specification for command line. Modified: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py 2007-03-25 19:12:26 UTC (rev 314) +++ trunk/grassaddons/gui/wxgui.py 2007-03-25 19:20:01 UTC (rev 315) @@ -153,12 +153,9 @@ self.cmdinput = wx.TextCtrl(self, id=wx.ID_ANY, value="", style=wx.HSCROLL|wx.TE_LINEWRAP| wx.TE_PROCESS_ENTER) - #self.cmdinput.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "Monospace")) + self.cmdinput.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, '')) wx.CallAfter(self.cmdinput.SetInsertionPoint, 0) - #self.cmdsizer.Add(l,0,wx.ADJUST_MINSIZE | wx.ALIGN_CENTER_VERTICAL, 1) - #self.cmdsizer.Add(self.cmdinput, 0, wx.EXPAND, 0) - self.Bind(wx.EVT_TEXT_ENTER, self.runCmd, self.cmdinput) return self.cmdinput @@ -543,7 +540,7 @@ # initialize all available image handlers wx.InitAllImageHandlers() # create and show main frame - mainframe = GMFrame(None, -1, "") + mainframe = GMFrame(None, -1, "" ) self.SetTopWindow(mainframe) mainframe.Show() return 1 From calvelo at grass.itc.it Sun Mar 25 23:03:48 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Sun Mar 25 23:03:49 2007 Subject: [grass-addons] r316 - trunk/grassaddons/gui/gui_modules Message-ID: <200703252103.l2PL3mwV029308@grass.itc.it> Author: calvelo Date: 2007-03-25 23:03:34 +0200 (Sun, 25 Mar 2007) New Revision: 316 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - Highlight compulsory parameters; should we drop '[optional]'? Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-25 19:20:01 UTC (rev 315) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-25 21:03:34 UTC (rev 316) @@ -144,6 +144,7 @@ self.inFlag = 0 self.inGispromptContent = 0 self.inGuisection = 0 + grass_task_init() def startElement(self, name, attrs): @@ -324,8 +325,11 @@ which_sizer = self.tabsizer[ p['guisection'] ] which_panel = self.tab[ p['guisection'] ] title = escape_ampersand(p['description']) + text_style = wx.FONTWEIGHT_BOLD + txt = None if p['required'] == 'no': title = "[optional] " + title + text_style = wx.FONTWEIGHT_NORMAL if p['multiple'] == 'yes' and len( p['values'] ) == 0: title = "[multiple] " + title p['value'] = p['default'] @@ -334,12 +338,13 @@ for dparam in self.dcmd_params: if p == dparam: p['value'] = self.dcmd_params[dparam] + if (len(p['values']) > 0): valuelist=map(str,p['values']) if p['multiple'] == 'yes': - hSizer=wx.StaticBoxSizer( wx.StaticBox(which_panel,0,title+":"), - wx.HORIZONTAL ) + txt = wx.StaticBox(which_panel,0,title+":") + hSizer=wx.StaticBoxSizer( txt, wx.HORIZONTAL ) v_count = 0 isDefault = {} for defval in p['value'].split(','): @@ -354,8 +359,8 @@ v_count += 1 which_sizer.Add( hSizer, 0, wx.ADJUST_MINSIZE, 5) else: - txt1 = wx.StaticText(which_panel, label = title + ':' ) - which_sizer.Add(txt1, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) + txt = wx.StaticText(which_panel, label = title + ':' ) + which_sizer.Add(txt, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) self.cb = wx.ComboBox(which_panel, -1, p['default'], wx.Point(-1, -1), wx.Size(STRING_ENTRY_WIDTH, -1), valuelist, wx.CB_DROPDOWN) @@ -368,8 +373,8 @@ and p['gisprompt'] == False and p['prompt'] != 'color'): - txt2 = wx.StaticText(which_panel, label = title + ':' ) - which_sizer.Add(txt2, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) + txt = wx.StaticText(which_panel, label = title + ':' ) + which_sizer.Add(txt, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) self.txt3 = wx.TextCtrl(which_panel, value = p['default'], size = (STRING_ENTRY_WIDTH, ENTRY_HEIGHT)) @@ -378,8 +383,8 @@ self.txt3.Bind(wx.EVT_TEXT, self.EvtText) if p['type'] == 'string' and p['gisprompt'] == True: - txt4 = wx.StaticText(which_panel, label = title + ':') - which_sizer.Add(txt4, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) + txt = wx.StaticText(which_panel, label = title + ':') + which_sizer.Add(txt, 0, wx.ADJUST_MINSIZE | wx.ALL, 5) if p['prompt'] != 'color': self.selection = select.Select(which_panel, id=wx.ID_ANY, size=(250,-1), type=p['element']) @@ -406,6 +411,8 @@ which_sizer.Add(btn_colour, 0, wx.ADJUST_MINSIZE| wx.ALL, 5) self.paramdict[btn_colour] = ID_PARAM_START + p_count self.Bind(csel.EVT_COLOURSELECT, self.OnColorButton, btn_colour) + if txt is not None: + txt.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, '')) f_count = -1 for f in grass_task.flags: @@ -417,6 +424,7 @@ which_sizer.Add(self.chk, 0, wx.EXPAND| wx.ALL, 5) self.paramdict[self.chk] = ID_FLAG_START + f_count self.chk.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox) + btnsizer = wx.BoxSizer(wx.HORIZONTAL) self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "Cancel") @@ -452,7 +460,10 @@ xsizelist.append(self.tabsizer[section].GetMinSize()[0]) ysizelist.append(self.tabsizer[section].GetMinSize()[1]) - maxminsize = (max(xsizelist),max(ysizelist)) + if xsizelist != []: + maxminsize = (max(xsizelist),max(ysizelist)) + else: + maxminsize = (0,0) self.notebook.SetInitialSize(maxminsize) self.panelsizer.SetSizeHints( self.notebookpanel ) self.panelsizer.Fit( self.notebookpanel ) @@ -588,11 +599,9 @@ for t in self.tabsizer.values(): t.Clear(True) self.notebook.Destroy() self.guisizer.Clear(True) - grass_task_init() self.Destroy() def OnCloseWindow(self, event): - grass_task_init() self.Destroy() def OnAbout(self, event): From barton at grass.itc.it Sun Mar 25 23:10:20 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 23:10:22 2007 Subject: [grass-addons] r317 - trunk/grassaddons/gui Message-ID: <200703252110.l2PLAK4n029347@grass.itc.it> Author: barton Date: 2007-03-25 23:10:11 +0200 (Sun, 25 Mar 2007) New Revision: 317 Modified: trunk/grassaddons/gui/README Log: Added simple installation and startup instructions. Modified: trunk/grassaddons/gui/README =================================================================== --- trunk/grassaddons/gui/README 2007-03-25 21:03:34 UTC (rev 316) +++ trunk/grassaddons/gui/README 2007-03-25 21:10:11 UTC (rev 317) @@ -2,11 +2,11 @@ ============================== AUTHORS: Jachym, Michael -LAST CHANGE: 2007-3-19 +LAST CHANGE: 2007-3-25 --------------------------------------------------------------------- Requirements: - Python >=2.3 and wxPython 2.8.1.1 + Python >=2.4 and wxPython 2.8.1.1 --------------------------------------------------------------------- How to start: @@ -24,9 +24,29 @@ $~ cd grassaddons/gui -1 - CLI MapDisplay +1 - INSTALLATION + +Put everthing from gui into a new directory $GISBASE/etc/wx. + +Move the script "wxgrass" into $GISBASE/scripts + + +2 - STARTUP WITH GRASS INITIALIZATION + +If you want to start the wxgrass GUI automatically when you start GRASS, replace your $GRASS/etc/init.sh with the one that accompanies wxgrass. Rename your original init.sh to avoid overwriting it. + +***NOTE*** +You may need to edit init.sh to match your settings for LD_DISPLAY + + +3 - STARTUP FROM GRASS TERMINAL + +Do not use the wxgrass init.sh. Simply type wxgrass& from the GRASS terminal to start the GUI using the wxgrass script. + + +4 - CLI MapDisplay scripts ------------------ -This is going to be replacement for command line tools like d.rast and d.vect +This is going to be replacement for command line tools like d.rast and d.vect Now add directory "scripts" in gui directory to your $PATH. This small programms should later go to GRASS Scripts directory or became Python @@ -65,10 +85,4 @@ displayed. You should be also able to store the display content as well as clear the display and start from scratch. -2 - GIS Manager ---------------- -This is a bit tricky -3 - Start-up screen with Location wizard ----------------------------------------- -This is even more complicated :-) From barton at grass.itc.it Sun Mar 25 23:19:33 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sun Mar 25 23:19:34 2007 Subject: [grass-addons] r318 - trunk/grassaddons/gui Message-ID: <200703252119.l2PLJX1t029384@grass.itc.it> Author: barton Date: 2007-03-25 23:19:25 +0200 (Sun, 25 Mar 2007) New Revision: 318 Modified: trunk/grassaddons/gui/README Log: Another startup instruction added Modified: trunk/grassaddons/gui/README =================================================================== --- trunk/grassaddons/gui/README 2007-03-25 21:10:11 UTC (rev 317) +++ trunk/grassaddons/gui/README 2007-03-25 21:19:25 UTC (rev 318) @@ -35,6 +35,14 @@ If you want to start the wxgrass GUI automatically when you start GRASS, replace your $GRASS/etc/init.sh with the one that accompanies wxgrass. Rename your original init.sh to avoid overwriting it. +Edit your .grassrc6 file to replace... + +GRASS_GUI: tcktk (or whatever you have here) + +...with... + +GRASS_GUI: wx + ***NOTE*** You may need to edit init.sh to match your settings for LD_DISPLAY From barton at grass.itc.it Mon Mar 26 03:59:40 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Mar 26 03:59:41 2007 Subject: [grass-addons] r319 - trunk/grassaddons/gui Message-ID: <200703260159.l2Q1xeRV030879@grass.itc.it> Author: barton Date: 2007-03-26 03:59:31 +0200 (Mon, 26 Mar 2007) New Revision: 319 Modified: trunk/grassaddons/gui/wxgui.py Log: Remove import images used for testing Modified: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py 2007-03-25 21:19:25 UTC (rev 318) +++ trunk/grassaddons/gui/wxgui.py 2007-03-26 01:59:31 UTC (rev 319) @@ -20,7 +20,6 @@ import wx # This module uses the new wx namespace import wx.html -import images # try: # import subprocess From barton at grass.itc.it Mon Mar 26 04:45:20 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Mar 26 04:45:21 2007 Subject: [grass-addons] r320 - trunk/grassaddons/gui/gui_modules Message-ID: <200703260245.l2Q2jK9s031475@grass.itc.it> Author: barton Date: 2007-03-26 04:45:12 +0200 (Mon, 26 Mar 2007) New Revision: 320 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: Fixed bug in trying to launch menuform dialog from command line. Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-26 01:59:31 UTC (rev 319) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-26 02:45:12 UTC (rev 320) @@ -666,7 +666,7 @@ layertree.AddLayer(disp_idx, layertype) else: - menuform.GUI().parseCommand(cmd, gmpath) + menuform.GUI().parseCommand(cmd, gmpath, parentframe=self) self.cmd_output.write(cmdlst[0] + "\n----------\n") From barton at grass.itc.it Mon Mar 26 09:05:30 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Mar 26 09:05:32 2007 Subject: [grass-addons] r321 - trunk/grassaddons/gui/gui_modules Message-ID: <200703260705.l2Q75UkS002842@grass.itc.it> Author: barton Date: 2007-03-26 09:05:21 +0200 (Mon, 26 Mar 2007) New Revision: 321 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: Flag font matches parameter font. Added hint (bold=required)in status bar and removed string "[optional]" Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 02:45:12 UTC (rev 320) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 07:05:21 UTC (rev 321) @@ -269,7 +269,7 @@ wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.CreateStatusBar() - self.SetStatusText("Enter parameters for " + grass_task.name) + self.SetStatusText("Enter parameters for " + grass_task.name + " (bold=required)") self.parent = parent self.selection = '' #selection from GIS element selector self.paramdict = {} # dictionary of controls and their parameter values @@ -325,11 +325,11 @@ which_sizer = self.tabsizer[ p['guisection'] ] which_panel = self.tab[ p['guisection'] ] title = escape_ampersand(p['description']) - text_style = wx.FONTWEIGHT_BOLD - txt = None + text_style = wx.FONTWEIGHT_BOLD + txt = None if p['required'] == 'no': - title = "[optional] " + title - text_style = wx.FONTWEIGHT_NORMAL +# title = "[optional] " + title + text_style = wx.FONTWEIGHT_NORMAL if p['multiple'] == 'yes' and len( p['values'] ) == 0: title = "[multiple] " + title p['value'] = p['default'] @@ -412,7 +412,7 @@ self.paramdict[btn_colour] = ID_PARAM_START + p_count self.Bind(csel.EVT_COLOURSELECT, self.OnColorButton, btn_colour) if txt is not None: - txt.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, '')) + txt.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, '')) f_count = -1 for f in grass_task.flags: @@ -421,11 +421,12 @@ which_panel = self.tab[ f['guisection'] ] title = escape_ampersand(f['description']) self.chk = wx.CheckBox(which_panel,-1, label = title, style = wx.NO_BORDER) + self.chk.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, '')) which_sizer.Add(self.chk, 0, wx.EXPAND| wx.ALL, 5) self.paramdict[self.chk] = ID_FLAG_START + f_count self.chk.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox) - + btnsizer = wx.BoxSizer(wx.HORIZONTAL) self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "Cancel") btnsizer.Add(self.btn_cancel, 0, wx.ALL| wx.ALIGN_CENTER, 10) From calvelo at grass.itc.it Mon Mar 26 09:10:07 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Mon Mar 26 09:10:09 2007 Subject: [grass-addons] r322 - trunk/grassaddons/gui/gui_modules Message-ID: <200703260710.l2Q7A7pI002868@grass.itc.it> Author: calvelo Date: 2007-03-26 09:09:59 +0200 (Mon, 26 Mar 2007) New Revision: 322 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - Better resizing overall - 'Main' tab now holds compulsory parameters, so everything else is optional Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 07:05:21 UTC (rev 321) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 07:09:59 UTC (rev 322) @@ -291,7 +291,7 @@ self.SetMenuBar(menuBar) self.guisizer = wx.BoxSizer(wx.VERTICAL) - sections = [] + sections = ['Main'] is_section = {} for task in grass_task.params + grass_task.flags: if not task.has_key('guisection') or task['guisection']=='': @@ -299,7 +299,15 @@ if not is_section.has_key(task['guisection']): is_section[task['guisection']] = 1 sections.append( task['guisection'] ) + there_is_main = False + for i in grass_task.params+grass_task.flags: + if i.has_key('required') and i['required'] == 'yes': + i['guisection'] = 'Main' + there_is_main = True + if not there_is_main: + sections = sections[1:] + self.notebookpanel = wx.ScrolledWindow( self, id=wx.ID_ANY ) self.notebookpanel.SetScrollRate(10,10) self.panelsizer = wx.BoxSizer(wx.VERTICAL) @@ -307,6 +315,7 @@ nbStyle=FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS|FN.FNB_VC8|FN.FNB_BACKGROUND_GRADIENT self.notebook = FN.FlatNotebook(self.notebookpanel, id=wx.ID_ANY, style=nbStyle) self.notebook.SetTabAreaColour(wx.Colour(125,200,175)) + self.notebook.Bind( FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChange ) self.tab = {} self.tabsizer = {} is_first = True @@ -328,7 +337,6 @@ text_style = wx.FONTWEIGHT_BOLD txt = None if p['required'] == 'no': -# title = "[optional] " + title text_style = wx.FONTWEIGHT_NORMAL if p['multiple'] == 'yes' and len( p['values'] ) == 0: title = "[multiple] " + title @@ -354,7 +362,7 @@ idForWX = ID_MULTI_START + p_count*20 + v_count chkbox = wx.CheckBox( which_panel, idForWX, val+" " ) if isDefault.has_key(val): chkbox.SetValue( True ) - hSizer.Add( chkbox,0,wx.ADJUST_MINSIZE,0 ) + hSizer.Add( chkbox,0,wx.ADJUST_MINSIZE,5 ) self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBoxMulti) v_count += 1 which_sizer.Add( hSizer, 0, wx.ADJUST_MINSIZE, 5) @@ -443,42 +451,35 @@ btnsizer.Add(self.btn_run, 0, wx.ALL| wx.ALIGN_CENTER, 10) self.btn_run.SetDefault() self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun) - self.guisizer.Add(btnsizer, 0, wx.EXPAND) + self.guisizer.Add(btnsizer, 0, wx.ALIGN_BOTTOM) wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout) wx.EVT_MENU(self, ID_ABOUT_COMMAND, self.OnAboutCommand) wx.EVT_MENU(self, wx.ID_EXIT, self.OnCancel) self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) - xsizelist = [] - ysizelist = [] + maxsizes = (0,0) for section in sections: self.tabsizer[section].SetSizeHints( self.tab[section] ) self.tabsizer[section].Fit( self.tab[section] ) self.tab[section].SetAutoLayout(True) self.tab[section].SetSizer( self.tabsizer[section] ) self.tab[section].Layout() - xsizelist.append(self.tabsizer[section].GetMinSize()[0]) - ysizelist.append(self.tabsizer[section].GetMinSize()[1]) + minsecsizes = self.tabsizer[section].GetMinSize() + maxsizes = map( lambda x: max( maxsizes[x], minsecsizes[x] ), (0,1) ) - if xsizelist != []: - maxminsize = (max(xsizelist),max(ysizelist)) - else: - maxminsize = (0,0) - self.notebook.SetInitialSize(maxminsize) - self.panelsizer.SetSizeHints( self.notebookpanel ) - self.panelsizer.Fit( self.notebookpanel ) + self.notebookpanel.SetSize( (min(600, maxsizes[0]), min(600, maxsizes[1]) ) ) self.notebookpanel.SetSizer(self.panelsizer) - self.notebookpanel.SetAutoLayout(True) - self.notebookpanel.Layout() - + self.guisizer.SetSizeHints(self) -# self.guisizer.SetMinSize(maxminsize) self.SetAutoLayout(True) self.SetSizer(self.guisizer) self.Layout() + def OnPageChange(self, event): + self.Layout() + def OnColorButton(self, event): colorchooser = wx.FindWindowById( event.GetId() ) new_color = colorchooser.GetValue() From calvelo at grass.itc.it Mon Mar 26 09:40:17 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Mon Mar 26 09:40:19 2007 Subject: [grass-addons] r323 - trunk/grassaddons/gui/gui_modules Message-ID: <200703260740.l2Q7eHSF002944@grass.itc.it> Author: calvelo Date: 2007-03-26 09:40:08 +0200 (Mon, 26 Mar 2007) New Revision: 323 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - StatusBar gives the current command being built. It may become too large, however... Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 07:09:59 UTC (rev 322) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 07:40:08 UTC (rev 323) @@ -269,7 +269,7 @@ wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.CreateStatusBar() - self.SetStatusText("Enter parameters for " + grass_task.name + " (bold=required)") + self.SetStatusText("Enter parameters for " + grass_task.name + " (those in Main are required)") self.parent = parent self.selection = '' #selection from GIS element selector self.paramdict = {} # dictionary of controls and their parameter values @@ -468,7 +468,7 @@ minsecsizes = self.tabsizer[section].GetMinSize() maxsizes = map( lambda x: max( maxsizes[x], minsecsizes[x] ), (0,1) ) - self.notebookpanel.SetSize( (min(600, maxsizes[0]), min(600, maxsizes[1]) ) ) + self.notebookpanel.SetSize( (min(600, maxsizes[0]), min(600, maxsizes[1]+60) ) ) # 60 takes the tabbar into account self.notebookpanel.SetSizer(self.panelsizer) self.guisizer.SetSizeHints(self) @@ -491,6 +491,9 @@ colorchooser.Refresh() self.getValues() + def updateStatusLine(self): + self.SetStatusText( self.createCmd(ignoreErrors = True) ) + def getValues(self): for item in self.paramdict.items(): param_num = item[1] @@ -507,7 +510,8 @@ else: param_val = item[0].GetValue() tasktype[num]['value'] = param_val - + self.updateStatusLine() + def EvtText(self, event): self.getValues() @@ -532,8 +536,9 @@ del currentValues[ theValue ] # Pack it back grass_task.params[theParamId]['value'] = ','.join( currentValues.keys() ) + self.updateStatusLine() - def createCmd(self): + def createCmd(self, ignoreErrors = False): """Produce a command line string for feeding into GRASS.""" cmd = grass_task.name errors = 0 @@ -543,11 +548,12 @@ cmd += ' -' + flag['name'] for p in grass_task.params: if p['value'] == '' and p['required'] != 'no': + cmd += ' ' + p['name'] + '=' + '' errStr += "Parameter " + p['name'] + "(" + p['description'] + ") is missing\n" errors += 1 if p['value'] != '' and p['value'] != p['default'] : cmd += ' ' + p['name'] + '=' + p['value'] - if errors: + if errors and not ignoreErrors: self.OnError(errStr) return None return cmd From calvelo at grass.itc.it Mon Mar 26 10:19:52 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Mon Mar 26 10:19:54 2007 Subject: [grass-addons] r324 - trunk/grassaddons/gui/gui_modules Message-ID: <200703260819.l2Q8JqRf003045@grass.itc.it> Author: calvelo Date: 2007-03-26 10:19:44 +0200 (Mon, 26 Mar 2007) New Revision: 324 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - Better handling of default values, particularly colour Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 07:40:08 UTC (rev 323) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 08:19:44 UTC (rev 324) @@ -482,10 +482,10 @@ def OnColorButton(self, event): colorchooser = wx.FindWindowById( event.GetId() ) - new_color = colorchooser.GetValue() + new_color = colorchooser.GetValue()[:] # This is weird: new_color is a 4-tuple and new_color[:] is a 3-tuple # under wx2.8.1 - new_label = color_rgb2str.get( new_color[:], ':'.join(map(str,new_color)) ) + new_label = color_rgb2str.get( new_color, ':'.join(map(str,new_color)) ) colorchooser.SetLabel( new_label ) colorchooser.SetColour( new_color ) colorchooser.Refresh() @@ -495,20 +495,22 @@ self.SetStatusText( self.createCmd(ignoreErrors = True) ) def getValues(self): - for item in self.paramdict.items(): - param_num = item[1] - if 'CheckBox' in str(item[0]): + for (gui_object,param_num) in self.paramdict.items(): + if 'CheckBox' in str( gui_object ): tasktype = grass_task.flags num = param_num-ID_FLAG_START - param_val = item[0].GetValue() + param_val = gui_object.GetValue() else: tasktype = grass_task.params num = param_num-ID_PARAM_START - if 'ColourSelect' in str(item[0]): - data = item[0].GetValue() - param_val = str(data[0])+':'+str(data[1])+':'+str(data[2]) + if 'ColourSelect' in str( gui_object ): + if 'Select' in gui_object.GetLabel(): + param_val = '' + else: + data = gui_object.GetValue()[:] + param_val = color_rgb2str.get( data , ':'.join( map(str, data) ) ) else: - param_val = item[0].GetValue() + param_val = gui_object.GetValue() tasktype[num]['value'] = param_val self.updateStatusLine() @@ -534,8 +536,12 @@ currentValues[ theValue ] = 1 else: del currentValues[ theValue ] + currentValueList=[] # Keep the original order, so that some defaults may be recovered + for v in grass_task.params[theParamId]['values']: + if currentValues.has_key(v): + currentValueList.append( v ) # Pack it back - grass_task.params[theParamId]['value'] = ','.join( currentValues.keys() ) + grass_task.params[theParamId]['value'] = ','.join( currentValueList ) self.updateStatusLine() def createCmd(self, ignoreErrors = False): From cepicky at grass.itc.it Mon Mar 26 11:02:53 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Mon Mar 26 11:02:55 2007 Subject: [grass-addons] r325 - trunk/grassaddons/gui/gui_modules Message-ID: <200703260902.l2Q92rPP004336@grass.itc.it> Author: cepicky Date: 2007-03-26 11:02:53 +0200 (Mon, 26 Mar 2007) New Revision: 325 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: fixed the import statement Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-26 08:19:44 UTC (rev 324) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-26 09:02:53 UTC (rev 325) @@ -12,7 +12,7 @@ from subprocess import * except: from compat import subprocess - from subprocess import * + from compat.subprocess import * gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules/" sys.path.append(gmpath) From cepicky at grass.itc.it Mon Mar 26 14:20:54 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Mon Mar 26 14:20:57 2007 Subject: [grass-addons] r326 - in trunk/grassaddons/gui: . gui_modules Message-ID: <200703261220.l2QCKsNB006754@grass.itc.it> Author: cepicky Date: 2007-03-26 14:20:53 +0200 (Mon, 26 Mar 2007) New Revision: 326 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/menuform.py trunk/grassaddons/gui/wxgui.py Log: window icons added for better orientetation Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-26 09:02:53 UTC (rev 325) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-26 12:20:53 UTC (rev 326) @@ -480,6 +480,7 @@ # Fancy gui # self._mgr = wx.aui.AuiManager(self) + self.SetIcon(wx.Icon(os.path.join("images",'grass.map.gif'), wx.BITMAP_TYPE_ANY)) # # Add toolbars Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 09:02:53 UTC (rev 325) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 12:20:53 UTC (rev 326) @@ -276,6 +276,7 @@ self.get_dcmd = get_dcmd self.dcmd_params = dcmd_params #this should be passed from the layer tree eventually self.layer = layer + self.SetIcon(wx.Icon(os.path.join("images",'grass.form.gif'), wx.BITMAP_TYPE_ANY)) menu = wx.Menu() menu.Append(wx.ID_ABOUT, "&About GrassGUI", Modified: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py 2007-03-26 09:02:53 UTC (rev 325) +++ trunk/grassaddons/gui/wxgui.py 2007-03-26 12:20:53 UTC (rev 326) @@ -123,6 +123,7 @@ # do layout self.SetTitle(_("GRASS GIS Manager - wxPython Prototype")) self.SetMinSize((450, 450)) + self.SetIcon(wx.Icon(os.path.join("images",'grass.smlogo.gif'), wx.BITMAP_TYPE_ANY)) # self.nb_panel = wx.Panel(self) # initialize variables From cepicky at grass.itc.it Mon Mar 26 14:23:51 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Mon Mar 26 14:23:52 2007 Subject: [grass-addons] r327 - trunk/grassaddons/gui/images Message-ID: <200703261223.l2QCNpD4006774@grass.itc.it> Author: cepicky Date: 2007-03-26 14:23:51 +0200 (Mon, 26 Mar 2007) New Revision: 327 Added: trunk/grassaddons/gui/images/grass.form.gif trunk/grassaddons/gui/images/grass.map.gif Log: window icons added for better orientation Added: trunk/grassaddons/gui/images/grass.form.gif =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/images/grass.form.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/images/grass.map.gif =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/images/grass.map.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From cepicky at grass.itc.it Mon Mar 26 15:02:48 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Mon Mar 26 15:02:49 2007 Subject: [grass-addons] r328 - trunk/grassaddons/gui/gui_modules Message-ID: <200703261302.l2QD2mkb007265@grass.itc.it> Author: cepicky Date: 2007-03-26 15:02:48 +0200 (Mon, 26 Mar 2007) New Revision: 328 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: long texts for some inputs wrapped Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 12:23:51 UTC (rev 327) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 13:02:48 UTC (rev 328) @@ -33,6 +33,7 @@ import wx import sys import string +import textwrap import select import wx.lib.flatnotebook as FN import wx.lib.colourselect as csel @@ -353,15 +354,21 @@ valuelist=map(str,p['values']) if p['multiple'] == 'yes': txt = wx.StaticBox(which_panel,0,title+":") - hSizer=wx.StaticBoxSizer( txt, wx.HORIZONTAL ) + hSizer=wx.StaticBoxSizer( txt, wx.VERTICAL ) v_count = 0 isDefault = {} for defval in p['value'].split(','): isDefault[ defval ] = 'yes' for val in valuelist: + # make some descriptions short: + nval = "" + for lval in textwrap.wrap(val, 60): + nval += lval+"\n" + nval = nval[:-1] + # This is the checkboxes hack idForWX = ID_MULTI_START + p_count*20 + v_count - chkbox = wx.CheckBox( which_panel, idForWX, val+" " ) + chkbox = wx.CheckBox( which_panel, idForWX, nval+" " ) if isDefault.has_key(val): chkbox.SetValue( True ) hSizer.Add( chkbox,0,wx.ADJUST_MINSIZE,5 ) self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBoxMulti) From cepicky at grass.itc.it Mon Mar 26 15:51:57 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Mon Mar 26 15:51:58 2007 Subject: [grass-addons] r329 - trunk/grassaddons/gui/gui_modules Message-ID: <200703261351.l2QDpv23007605@grass.itc.it> Author: cepicky Date: 2007-03-26 15:51:57 +0200 (Mon, 26 Mar 2007) New Revision: 329 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: first steps towards progress bar Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-26 13:02:48 UTC (rev 328) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-26 13:51:57 UTC (rev 329) @@ -688,13 +688,26 @@ # console output window. try: self.cmd_output.write(cmd+"\n----------\n") - self.out = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).communicate()[0] + # self.out = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).communicate()[0] + p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) + (child_stdin, child_stdout, child_stderr) = (p.stdin, p.stdout, p.stderr) + + oline = child_stderr.readline() + while 1: + if oline == '': + break + print >>sys.stderr, "MSG: ",oline + oline = child_stderr.readline() + self.out=p.communicate()[0] self.cmd_output.write(self.out+"\n") + child_stderr.close() + child_stdout.close() + child_stdin.close() if self.out < 0: print >> sys.stderr, "Child was terminated by signal", self.out elif self.out > 0: - print >> sys.stderr, "Child returned", self.out + print >> sys.stderr, self.out except OSError, e: print >> sys.stderr, "Execution failed:", e From cepicky at grass.itc.it Mon Mar 26 16:35:19 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Mon Mar 26 16:35:20 2007 Subject: [grass-addons] r330 - trunk/grassaddons/gui/gui_modules Message-ID: <200703261435.l2QEZJT5007832@grass.itc.it> Author: cepicky Date: 2007-03-26 16:35:19 +0200 (Mon, 26 Mar 2007) New Revision: 330 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: command can be copied to clipboard and pasted with mouse somewhere else now Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 13:51:57 UTC (rev 329) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 14:35:19 UTC (rev 330) @@ -459,6 +459,9 @@ btnsizer.Add(self.btn_run, 0, wx.ALL| wx.ALIGN_CENTER, 10) self.btn_run.SetDefault() self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun) + self.btn_clipboard = wx.Button(self, wx.ID_OK, "Copy") + btnsizer.Add(self.btn_clipboard, 0, wx.ALL| wx.ALIGN_CENTER, 10) + self.btn_clipboard.Bind(wx.EVT_BUTTON, self.OnCopy) self.guisizer.Add(btnsizer, 0, wx.ALIGN_BOTTOM) wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout) wx.EVT_MENU(self, ID_ABOUT_COMMAND, self.OnAboutCommand) @@ -610,6 +613,16 @@ except OSError, e: print >>sys.stderr, "Execution failed:", e + def OnCopy(self, event): + cmddata = wx.TextDataObject() + cmddata.SetText(self.createCmd(ignoreErrors=True)) + if wx.TheClipboard.Open(): + wx.TheClipboard.UsePrimarySelection(True) + wx.TheClipboard.SetData(cmddata) + wx.TheClipboard.Close() + self.SetStatusText("'%s' copied to clipboard" %\ + (self.createCmd(ignoreErrors=True))) + def OnError(self, errMsg): dlg = wx.MessageDialog(self, errMsg, "Error", wx.OK | wx.ICON_ERROR) dlg.ShowModal() From barton at grass.itc.it Mon Mar 26 17:17:47 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Mar 26 17:17:48 2007 Subject: [grass-addons] r331 - in trunk/grassaddons/gui: . gui_modules images Message-ID: <200703261517.l2QFHloh008867@grass.itc.it> Author: barton Date: 2007-03-26 17:17:29 +0200 (Mon, 26 Mar 2007) New Revision: 331 Added: trunk/grassaddons/gui/images/__init__.py Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/menuform.py trunk/grassaddons/gui/wxgui.py Log: Added import code so that images can be found. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-26 14:35:19 UTC (rev 330) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-26 15:17:29 UTC (rev 331) @@ -27,6 +27,11 @@ import grassenv import track +import images +imagepath = images.__path__[0] +sys.path.append(imagepath) + + Map = render.Map() # instance of Map class to render GRASS display output to PPM file DEBUG = False @@ -480,7 +485,7 @@ # Fancy gui # self._mgr = wx.aui.AuiManager(self) - self.SetIcon(wx.Icon(os.path.join("images",'grass.map.gif'), wx.BITMAP_TYPE_ANY)) + self.SetIcon(wx.Icon(os.path.join(imagepath,'grass.map.gif'), wx.BITMAP_TYPE_ANY)) # # Add toolbars Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 14:35:19 UTC (rev 330) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 15:17:29 UTC (rev 331) @@ -52,7 +52,11 @@ from compat import subprocess import re +import images +imagepath = images.__path__[0] +sys.path.append(imagepath) + def reexec_with_pythonw(): if sys.platform == 'darwin' and\ not sys.executable.endswith('MacOS/Python'): @@ -277,7 +281,7 @@ self.get_dcmd = get_dcmd self.dcmd_params = dcmd_params #this should be passed from the layer tree eventually self.layer = layer - self.SetIcon(wx.Icon(os.path.join("images",'grass.form.gif'), wx.BITMAP_TYPE_ANY)) + self.SetIcon(wx.Icon(os.path.join(imagepath,'grass.form.gif'), wx.BITMAP_TYPE_ANY)) menu = wx.Menu() menu.Append(wx.ID_ABOUT, "&About GrassGUI", @@ -481,7 +485,7 @@ self.notebookpanel.SetSize( (min(600, maxsizes[0]), min(600, maxsizes[1]+60) ) ) # 60 takes the tabbar into account self.notebookpanel.SetSizer(self.panelsizer) - + self.guisizer.SetSizeHints(self) self.SetAutoLayout(True) self.SetSizer(self.guisizer) @@ -524,7 +528,7 @@ param_val = gui_object.GetValue() tasktype[num]['value'] = param_val self.updateStatusLine() - + def EvtText(self, event): self.getValues() Added: trunk/grassaddons/gui/images/__init__.py =================================================================== --- trunk/grassaddons/gui/images/__init__.py (rev 0) +++ trunk/grassaddons/gui/images/__init__.py 2007-03-26 15:17:29 UTC (rev 331) @@ -0,0 +1,5 @@ +all = ["grass.form.gif", + "grass.map.gif", + "grass.smlogo.gif", + "grasslogo_big.gif", + ] Modified: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py 2007-03-26 14:35:19 UTC (rev 330) +++ trunk/grassaddons/gui/wxgui.py 2007-03-26 15:17:29 UTC (rev 331) @@ -30,6 +30,11 @@ gmpath = gui_modules.__path__[0] sys.path.append(gmpath) +import images +imagepath = images.__path__[0] +sys.path.append(imagepath) + + import gui_modules.track as track import gui_modules.wxgui_utils as wxgui_utils import gui_modules.mapdisp as mapdisp @@ -123,7 +128,7 @@ # do layout self.SetTitle(_("GRASS GIS Manager - wxPython Prototype")) self.SetMinSize((450, 450)) - self.SetIcon(wx.Icon(os.path.join("images",'grass.smlogo.gif'), wx.BITMAP_TYPE_ANY)) + self.SetIcon(wx.Icon(os.path.join(imagepath,'grass.smlogo.gif'), wx.BITMAP_TYPE_ANY)) # self.nb_panel = wx.Panel(self) # initialize variables From barton at grass.itc.it Mon Mar 26 17:43:16 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Mar 26 17:43:18 2007 Subject: [grass-addons] r332 - trunk/grassaddons/gui/gui_modules Message-ID: <200703261543.l2QFhGV3008975@grass.itc.it> Author: barton Date: 2007-03-26 17:43:08 +0200 (Mon, 26 Mar 2007) New Revision: 332 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: Added self.notebookpanel.Layout() statements so that all notebook pages display properly when selected. Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 15:17:29 UTC (rev 331) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 15:43:08 UTC (rev 332) @@ -485,6 +485,7 @@ self.notebookpanel.SetSize( (min(600, maxsizes[0]), min(600, maxsizes[1]+60) ) ) # 60 takes the tabbar into account self.notebookpanel.SetSizer(self.panelsizer) + self.notebookpanel.Layout() self.guisizer.SetSizeHints(self) self.SetAutoLayout(True) @@ -493,7 +494,7 @@ def OnPageChange(self, event): - self.Layout() + self.notebookpanel.Layout() def OnColorButton(self, event): colorchooser = wx.FindWindowById( event.GetId() ) From calvelo at grass.itc.it Mon Mar 26 23:11:58 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Mon Mar 26 23:12:00 2007 Subject: [grass-addons] r333 - trunk/grassaddons/gui/gui_modules Message-ID: <200703262111.l2QLBwiB014479@grass.itc.it> Author: calvelo Date: 2007-03-26 23:11:50 +0200 (Mon, 26 Mar 2007) New Revision: 333 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - Added HTML manual tab - Overhauled sizer and scrollbar handling; should be smoother now Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 15:43:08 UTC (rev 332) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 21:11:50 UTC (rev 333) @@ -37,6 +37,7 @@ import select import wx.lib.flatnotebook as FN import wx.lib.colourselect as csel +import wx.html # Do the python 2.0 standard xml thing and map it on the old names import xml.sax @@ -54,6 +55,7 @@ import images imagepath = images.__path__[0] +#imagepath = os.sep.join( os.getcwd().split(os.sep) [:-1] + ['images'] ) sys.path.append(imagepath) @@ -134,7 +136,7 @@ pass def grass_task_init(): - grass_task.name = 'unknown' + grass_task.name = 'index' grass_task.params = [] grass_task.description = '' grass_task.flags = [] @@ -264,6 +266,35 @@ self.inGuisection = 0 +class helpPanel(wx.html.HtmlWindow): + """This panel holds the text from GRASS docs.""" + def __init__(self, parent, id, grass_command = "index"): + wx.html.HtmlWindow.__init__(self, parent, id) + self.fspath = os.getenv( "GISBASE" ) + "/docs/html/" + self.fillContentsFromFile( self.fspath + grass_command + ".html" ) + + def fillContentsFromFile( self, htmlFile ): + aLink = re.compile( r'()', re.IGNORECASE ) + try: + contents = [ '' % self.fspath ] + dont_skip = True + for l in file( htmlFile, "rb" ).readlines(): + if "DESCRIPTION" in l: dont_skip = True + if dont_skip: + if "SYNOPSIS" in l: dont_skip = False # do skip the options description + else: + findLink = aLink.search( l ) + if findLink is not None: + contents.append( aLink.sub(findLink.group(1)+self.fspath+findLink.group(2),l) ) + else: + contents.append( l ) + self.SetPage( "".join( contents ) ) + self.Ok = True + except: + raise + self.Ok = False + + class mainFrame(wx.Frame): """This is the Frame containing the dialog for options input. @@ -314,8 +345,7 @@ sections = sections[1:] - self.notebookpanel = wx.ScrolledWindow( self, id=wx.ID_ANY ) - self.notebookpanel.SetScrollRate(10,10) + self.notebookpanel = wx.Panel( self, id=wx.ID_ANY ) self.panelsizer = wx.BoxSizer(wx.VERTICAL) nbStyle=FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS|FN.FNB_VC8|FN.FNB_BACKGROUND_GRADIENT @@ -326,11 +356,16 @@ self.tabsizer = {} is_first = True for section in sections: - self.tab[section] = wx.Panel(self.notebook, id = wx.ID_ANY ) + self.tab[section] = wx.ScrolledWindow(self.notebook, id = wx.ID_ANY ) + self.tab[section].SetScrollRate(10,10) self.tabsizer[section] = wx.BoxSizer(wx.VERTICAL) self.notebook.AddPage( self.tab[section], text = section, select = is_first ) is_first = False + manual_tab = helpPanel( self.notebook, id = wx.ID_ANY, grass_command = grass_task.name) + if manual_tab.Ok: + self.notebook.AddPage( manual_tab, text = "Manual" ) + self.panelsizer.Add( self.notebook, flag=wx.EXPAND ) self.guisizer.Add( self.notebookpanel, flag = wx.EXPAND ) @@ -483,7 +518,13 @@ minsecsizes = self.tabsizer[section].GetMinSize() maxsizes = map( lambda x: max( maxsizes[x], minsecsizes[x] ), (0,1) ) - self.notebookpanel.SetSize( (min(600, maxsizes[0]), min(600, maxsizes[1]+60) ) ) # 60 takes the tabbar into account + constrained_size = (min(600, maxsizes[0]), min(600, maxsizes[1]) ) + for section in sections: + self.tab[section].SetMinSize( constrained_size ) + if manual_tab.Ok: + manual_tab.SetMinSize( constrained_size ) + + self.notebookpanel.SetSize( (constrained_size[0],constrained_size[1]+80) ) # 80 takes the tabbar into account self.notebookpanel.SetSizer(self.panelsizer) self.notebookpanel.Layout() From barton at grass.itc.it Mon Mar 26 23:18:23 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Mar 26 23:18:25 2007 Subject: [grass-addons] r334 - in trunk/grassaddons/gui: . gui_modules Message-ID: <200703262118.l2QLINJZ014768@grass.itc.it> Author: barton Date: 2007-03-26 23:18:11 +0200 (Mon, 26 Mar 2007) New Revision: 334 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py trunk/grassaddons/gui/wxgui.py Log: Added groups and improved drag and drop in the layer tree. Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-26 21:11:50 UTC (rev 333) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-26 21:18:11 UTC (rev 334) @@ -47,7 +47,7 @@ self.Map = "" # instance of render.Map associated with display self.root = "" # ID of layer tree root node - self.node = 0 # index value for layers + self.groupnode = 0 # index value for layers self.optpage = {} # dictionary of notebook option pages for each map layer self.layer_selected = "" # ID of currently selected layer self.layertype = {} # dictionary of layer types for each layer @@ -65,6 +65,11 @@ #create image list to use with layer tree il = wx.ImageList(16, 16, False) + trart = wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_OTHER, (16,16)) + self.folder_open = il.Add(trart) + trart = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)) + self.folder = il.Add(trart) + trgif = wx.Image(icons + r'/element-cell.gif', wx.BITMAP_TYPE_GIF) trgif.Rescale(16, 16) trgif = trgif.ConvertToBitmap() @@ -131,6 +136,10 @@ style=wx.TE_MULTILINE|wx.TE_WORDWRAP) self.ctrl.Bind(wx.EVT_TEXT_ENTER, self.onCmdChanged) self.ctrl.Bind(wx.EVT_TEXT, self.onCmdChanged) + elif type == 'group': + self.ctrl = None + grouptext = 'Layer group:'+str(self.groupnode) + self.groupnode += 1 else: # all other layers self.ctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50), @@ -139,9 +148,16 @@ self.ctrl.SetValue(100) self.ctrl.Bind(wx.EVT_TEXT, self.onOpacity) - if self.layer_selected and self.layer_selected != self.GetRootItem(): - layer = self.InsertItem(self.root, self.GetPrevSibling(self.layer_selected), + if (self.layer_selected and self.layer_selected != self.GetRootItem() and + self.layertype[self.layer_selected] != 'group'): + parent = self.GetItemParent(self.layer_selected) + layer = self.InsertItem(parent, self.GetPrevSibling(self.layer_selected), '', ct_type=1, wnd=self.ctrl ) + elif (self.layer_selected and self.layer_selected != self.GetRootItem() and + self.layertype[self.layer_selected] == 'group'): + layer = self.InsertItem(self.layer_selected, self.GetPrevSibling(self.layer_selected), + '', ct_type=1, wnd=self.ctrl ) + self.Expand(self.layer_selected) else: layer = self.PrependItem(self.root, '', ct_type=1, wnd=self.ctrl) @@ -199,6 +215,11 @@ menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif type == 'command': self.SetItemImage(layer, self.cmd_icon) + elif type == 'group': + self.SetItemImage(layer, self.folder) + self.SetItemText(layer, grouptext) + self.CheckItem(layer, checked=True) + self.first = False def onActivateLayer(self, event): @@ -222,6 +243,11 @@ menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif self.layertype[layer] == 'themechart': menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'group': + if self.IsExpanded(layer): + self.Collapse(layer) + else: + self.Expand(layer) def onDeleteLayer(self, event): layer = event.GetItem() @@ -232,12 +258,25 @@ def onLayerChecked(self, event): layer = event.GetItem() - checked = self.IsItemChecked(layer) + checked = layer.IsChecked() if self.drag == False and self.first == False: # change active parameter for item in layers list in render.Map - self.changeChecked(layer, checked) + if self.layertype[layer] == 'group': + childitem = self.GetFirstChild(layer) + child = childitem[0] + cookie = childitem[1] + for n in range(0,self.GetChildrenCount(layer)): + if checked == False: + childchecked = False + else: + childchecked = child.IsChecked() + self.changeChecked(child, childchecked) + child = self.GetNextChild(layer, cookie)[0] + else: + self.changeChecked(layer, checked) + def onCmdChanged(self, event): layer = self.layerctrl[event.GetEventObject()] cmd = event.GetString() @@ -264,13 +303,13 @@ self.layer_selected = layer def onCollapseNode(self, event): - print 'group collapsed' - event.Skip() + if self.layertype[self.layer_selected] == 'group': + self.SetItemImage(self.layer_selected, self.folder) def onExpandNode(self, event): self.layer_selected = event.GetItem() - print 'group expanded' - event.Skip() + if self.layertype[self.layer_selected] == 'group': + self.SetItemImage(self.layer_selected, self.folder_open) def onBeginDrag(self, event): """ Drag and drop of single tree nodes @@ -298,9 +337,6 @@ delete original at old position """ - #If we dropped somewhere that isn't on top of an item, ignore the event - if not event.GetItem(): - return # Make sure this memeber exists. try: @@ -308,12 +344,6 @@ except: return - # Get the other IDs that are involved - afteritem = event.GetItem() - parent = self.GetItemParent(afteritem) - if not parent: - return - # recreate old layer at new position if self.layertype[old] == 'command': self.dragctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='', @@ -327,9 +357,31 @@ self.dragctrl.SetValue(100) self.dragctrl.Bind(wx.EVT_SPINCTRL, self.onOpacity) - new = self.InsertItem(parent, afteritem, text=self.saveitem['text'], \ + + #If we dropped somewhere that isn't on top of an item, ignore the event + flag = self.HitTest(event.GetPoint())[1] + + if flag & wx.TREE_HITTEST_ABOVE: + new = self.PrependItem(self.root, text=self.saveitem['text'], \ ct_type=1, wnd=self.dragctrl, image=self.saveitem['image'], \ data=self.saveitem['data']) + elif (flag & wx.TREE_HITTEST_BELOW) or (flag & wx.TREE_HITTEST_NOWHERE): + new = self.AppendItem(self.root, text=self.saveitem['text'], \ + ct_type=1, wnd=self.dragctrl, image=self.saveitem['image'], \ + data=self.saveitem['data']) + else: + if not event.GetItem(): + return + else: + afteritem = event.GetItem() + parent = self.GetItemParent(afteritem) + new = self.InsertItem(parent, afteritem, text=self.saveitem['text'], \ + ct_type=1, wnd=self.dragctrl, image=self.saveitem['image'], \ + data=self.saveitem['data']) + + + + self.layertype[new] = self.saveitem['type'] self.CheckItem(new, checked=self.saveitem['check']) self.GetItemWindow(new).SetValue(self.saveitem['windval']) @@ -691,7 +743,7 @@ # self.out = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).communicate()[0] p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) (child_stdin, child_stdout, child_stderr) = (p.stdin, p.stdout, p.stderr) - + oline = child_stderr.readline() while 1: if oline == '': Modified: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py 2007-03-26 21:11:50 UTC (rev 333) +++ trunk/grassaddons/gui/wxgui.py 2007-03-26 21:18:11 UTC (rev 334) @@ -315,47 +315,17 @@ ('addrast', wx.Bitmap(os.path.join(wxgui_utils.icons,'element-cell.gif'), wx.BITMAP_TYPE_ANY), 'Add raster layer', self.onRaster), ('addvect', wx.Bitmap(os.path.join(wxgui_utils.icons,'element-vector.gif'), wx.BITMAP_TYPE_ANY), 'Add vector layer', self.onVector), ('addcmd', wx.Bitmap(os.path.join(wxgui_utils.icons,'gui-cmd.gif'), wx.BITMAP_TYPE_ANY), 'Add command layer', self.addCommand), + ('addgrp', wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_TOOLBAR, (16,16)), 'Add layer group', self.addGroup), ('delcmd', wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_TOOLBAR, (16,16)), 'Delete selected layer', self.deleteLayer), ) - def addToolbarCombo(self, toolbar, indx, type): - tbcb = wx.combo.BitmapComboBox(toolbar, pos=(25,25), size=(100,-1), style=wx.TE_PROCESS_ENTER) - self.comboItems(tbcb, type) - toolbar.InsertControl(indx, tbcb) - toolbar.Realize() - - self.Bind(wx.EVT_COMBOBOX, self.onCombo, tbcb) - self.Bind(wx.EVT_TEXT_ENTER, self.onCombo, tbcb) - - def onCombo(self, event): - bcb = event.GetEventObject() - idx = event.GetInt() - st = bcb.GetString(idx) - cd = bcb.GetClientData(idx) - if 'Add raster map' in st: - self.addRaster() - elif 'Add RGB' in st: - self.addRGB() - elif 'Add raster legend' in st: - self.addRastLeg() - elif 'Add vector map' in st: - self.addVector() - elif 'Add thematic map' in st: - self.addThemeMap() - elif 'Add thematic chart' in st: - self.addThemeChart() - -# self.log.write("EVT_COMBOBOX: Id %d, string '%s', clientData '%s'" % (idx, st, cd)) - evt.Skip() - - def newDisplay(self, event=None): """Create new map display frame""" newdisp = self.mapdisplays[self.disp_idx] = mapdisp.MapFrame(self, - id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, - style=wx.DEFAULT_FRAME_STYLE, - cb=self.gm_cb, idx=self.disp_idx) + id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, + style=wx.DEFAULT_FRAME_STYLE, + cb=self.gm_cb, idx=self.disp_idx) # title newdisp.SetTitle(_("Map Display " + str(self.disp_idx))) #self.maptree[self.disp_idx] = self.mapdisplays[self.disp_idx].getTree() @@ -501,6 +471,10 @@ """Add command line layer""" self.SetTree('command') + def addGroup(self, event): + """Add layer group""" + self.SetTree('group') + def GetSelectedDisplay(self): return self.notebook.GetSelection() From calvelo at grass.itc.it Mon Mar 26 23:41:33 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Mon Mar 26 23:41:35 2007 Subject: [grass-addons] r335 - trunk/grassaddons/gui/gui_modules Message-ID: <200703262141.l2QLfXdg015560@grass.itc.it> Author: calvelo Date: 2007-03-26 23:41:25 +0200 (Mon, 26 Mar 2007) New Revision: 335 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - Minor tweaks: font size in manual page, default focus to Main; the grass icon won't appear at first, but then browsing around and back, it does >:/ Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 21:18:11 UTC (rev 334) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 21:41:25 UTC (rev 335) @@ -53,8 +53,7 @@ from compat import subprocess import re -import images -imagepath = images.__path__[0] +imagepath = os.getenv("GISBASE") + "/etc/wx/images/" #imagepath = os.sep.join( os.getcwd().split(os.sep) [:-1] + ['images'] ) sys.path.append(imagepath) @@ -271,6 +270,7 @@ def __init__(self, parent, id, grass_command = "index"): wx.html.HtmlWindow.__init__(self, parent, id) self.fspath = os.getenv( "GISBASE" ) + "/docs/html/" + self.SetStandardFonts( size = 8 ) self.fillContentsFromFile( self.fspath + grass_command + ".html" ) def fillContentsFromFile( self, htmlFile ): @@ -364,7 +364,7 @@ manual_tab = helpPanel( self.notebook, id = wx.ID_ANY, grass_command = grass_task.name) if manual_tab.Ok: - self.notebook.AddPage( manual_tab, text = "Manual" ) + self.notebook.AddPage( manual_tab, text = "Manual" , select = False ) self.panelsizer.Add( self.notebook, flag=wx.EXPAND ) self.guisizer.Add( self.notebookpanel, flag = wx.EXPAND ) From barton at grass.itc.it Tue Mar 27 02:03:06 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Mar 27 02:03:07 2007 Subject: [grass-addons] r336 - trunk/grassaddons/gui/gui_modules Message-ID: <200703270003.l2R036cM021279@grass.itc.it> Author: barton Date: 2007-03-27 02:02:57 +0200 (Tue, 27 Mar 2007) New Revision: 336 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: Fixed manual page sizing so that it expands if you expand the window. Also increased manual font size a bit--I just can't be satisfied ;-) Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-26 21:41:25 UTC (rev 335) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-27 00:02:57 UTC (rev 336) @@ -270,7 +270,7 @@ def __init__(self, parent, id, grass_command = "index"): wx.html.HtmlWindow.__init__(self, parent, id) self.fspath = os.getenv( "GISBASE" ) + "/docs/html/" - self.SetStandardFonts( size = 8 ) + self.SetStandardFonts( size = 11 ) self.fillContentsFromFile( self.fspath + grass_command + ".html" ) def fillContentsFromFile( self, htmlFile ): @@ -364,10 +364,11 @@ manual_tab = helpPanel( self.notebook, id = wx.ID_ANY, grass_command = grass_task.name) if manual_tab.Ok: + manual_tabsizer = wx.BoxSizer(wx.VERTICAL) self.notebook.AddPage( manual_tab, text = "Manual" , select = False ) - self.panelsizer.Add( self.notebook, flag=wx.EXPAND ) - self.guisizer.Add( self.notebookpanel, flag = wx.EXPAND ) + self.panelsizer.Add( self.notebook, 1, flag=wx.EXPAND ) + self.guisizer.Add( self.notebookpanel, 1, flag = wx.EXPAND ) p_count = -1 for p in grass_task.params: From calvelo at grass.itc.it Tue Mar 27 04:50:18 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Tue Mar 27 04:50:22 2007 Subject: [grass-addons] r337 - trunk/grassaddons/gui/gui_modules Message-ID: <200703270250.l2R2oIMF023173@grass.itc.it> Author: calvelo Date: 2007-03-27 04:50:12 +0200 (Tue, 27 Mar 2007) New Revision: 337 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - Beginning refactoring the thing to isolate frames, panels and no globals Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-27 00:02:57 UTC (rev 336) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-27 02:50:12 UTC (rev 337) @@ -16,12 +16,11 @@ # # You need to have Python 2.4, wx.Python 2.6 and python-xml. # -# The XML stream is read from stdin, thus you -# may call it for instance this way: -# r.basins.fill --interface-description | python grassgui.py -# or -# r.basins.fill --interface-description | ./grassgui.py +# The XML stream is read from executing the command given in the +# command line, thus you may call it for instance this way: # +# python r.basins.fill +# # Or you set an alias or wrap the call up in a nice # shell script, GUI environment ... please contribute your idea. # @@ -131,18 +130,15 @@ return 1 return 0 -class grass_task: - pass +class grassTask: + def __init__(self): + self.name = 'index' + self.params = [] + self.description = '' + self.flags = [] -def grass_task_init(): - grass_task.name = 'index' - grass_task.params = [] - grass_task.description = '' - grass_task.flags = [] -grass_task_init() - class processTask(HandlerBase): - def __init__(self): + def __init__(self, task_description): self.inDescriptionContent = 0 self.inDefaultContent = 0 self.inValueContent = 0 @@ -150,12 +146,12 @@ self.inFlag = 0 self.inGispromptContent = 0 self.inGuisection = 0 - grass_task_init() + self.task = task_description def startElement(self, name, attrs): if name == 'task': - grass_task.name = attrs.get('name', None) + self.task.name = attrs.get('name', None) if name == 'parameter': self.inParameter = 1; @@ -221,7 +217,7 @@ # If it's not a parameter element, ignore it if name == 'parameter': self.inParameter = 0; - grass_task.params.append({ + self.task.params.append({ "name" : self.param_name, "type" : self.param_type, "required" : self.param_required, @@ -238,7 +234,7 @@ if name == 'flag': self.inFlag = 0; - grass_task.flags.append({ + self.task.flags.append({ "name" : self.flag_name, "description" : self.flag_description } ) @@ -248,7 +244,7 @@ elif self.inFlag: self.flag_description = normalize_whitespace(self.description) else: - grass_task.description = normalize_whitespace(self.description) + self.task.description = normalize_whitespace(self.description) self.inDescriptionContent = 0 if name == 'default': @@ -300,12 +296,15 @@ The dialog is organized in a notebook according to the guisections defined by each GRASS command.""" - def __init__(self, parent, ID, get_dcmd=None, layer=None, dcmd_params=None): - wx.Frame.__init__(self, parent, ID, grass_task.name, + def __init__(self, parent, ID, task_description, get_dcmd=None, layer=None, dcmd_params=None): + + self.task = task_description + + wx.Frame.__init__(self, parent, ID, self.task.name, wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.CreateStatusBar() - self.SetStatusText("Enter parameters for " + grass_task.name + " (those in Main are required)") + self.SetStatusText("Enter parameters for " + self.task.name + " (those in Main are required)") self.parent = parent self.selection = '' #selection from GIS element selector self.paramdict = {} # dictionary of controls and their parameter values @@ -317,8 +316,8 @@ menu = wx.Menu() menu.Append(wx.ID_ABOUT, "&About GrassGUI", "Information about GrassGUI") - menu.Append(ID_ABOUT_COMMAND, "&About " + grass_task.name, - "Short descripton of GRASS command " + grass_task.name) + menu.Append(ID_ABOUT_COMMAND, "&About " + self.task.name, + "Short descripton of GRASS command " + self.task.name) menu.AppendSeparator() menu.Append(wx.ID_EXIT, "E&xit", "Terminate the program") @@ -330,14 +329,14 @@ sections = ['Main'] is_section = {} - for task in grass_task.params + grass_task.flags: + for task in self.task.params + self.task.flags: if not task.has_key('guisection') or task['guisection']=='': task['guisection'] = 'Options' if not is_section.has_key(task['guisection']): is_section[task['guisection']] = 1 sections.append( task['guisection'] ) there_is_main = False - for i in grass_task.params+grass_task.flags: + for i in self.task.params+self.task.flags: if i.has_key('required') and i['required'] == 'yes': i['guisection'] = 'Main' there_is_main = True @@ -362,7 +361,7 @@ self.notebook.AddPage( self.tab[section], text = section, select = is_first ) is_first = False - manual_tab = helpPanel( self.notebook, id = wx.ID_ANY, grass_command = grass_task.name) + manual_tab = helpPanel( self.notebook, id = wx.ID_ANY, grass_command = self.task.name) if manual_tab.Ok: manual_tabsizer = wx.BoxSizer(wx.VERTICAL) self.notebook.AddPage( manual_tab, text = "Manual" , select = False ) @@ -371,7 +370,7 @@ self.guisizer.Add( self.notebookpanel, 1, flag = wx.EXPAND ) p_count = -1 - for p in grass_task.params: + for p in self.task.params: p_count += 1 # Needed for checkboxes hack which_sizer = self.tabsizer[ p['guisection'] ] which_panel = self.tab[ p['guisection'] ] @@ -471,7 +470,7 @@ txt.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, '')) f_count = -1 - for f in grass_task.flags: + for f in self.task.flags: f_count += 1 which_sizer = self.tabsizer[ f['guisection'] ] which_panel = self.tab[ f['guisection'] ] @@ -555,11 +554,11 @@ def getValues(self): for (gui_object,param_num) in self.paramdict.items(): if 'CheckBox' in str( gui_object ): - tasktype = grass_task.flags + tasktype = self.task.flags num = param_num-ID_FLAG_START param_val = gui_object.GetValue() else: - tasktype = grass_task.params + tasktype = self.task.params num = param_num-ID_PARAM_START if 'ColourSelect' in str( gui_object ): if 'Select' in gui_object.GetLabel(): @@ -587,30 +586,30 @@ theCheckedId = (event.GetId()-ID_MULTI_START ) % 20 # Unpack current value list currentValues={} - for isThere in grass_task.params[theParamId]['value'].split(','): + for isThere in self.task.params[theParamId]['value'].split(','): currentValues[isThere] = 1 - theValue = grass_task.params[theParamId]['values'][theCheckedId] + theValue = self.task.params[theParamId]['values'][theCheckedId] if event.Checked(): currentValues[ theValue ] = 1 else: del currentValues[ theValue ] currentValueList=[] # Keep the original order, so that some defaults may be recovered - for v in grass_task.params[theParamId]['values']: + for v in self.task.params[theParamId]['values']: if currentValues.has_key(v): currentValueList.append( v ) # Pack it back - grass_task.params[theParamId]['value'] = ','.join( currentValueList ) + self.task.params[theParamId]['value'] = ','.join( currentValueList ) self.updateStatusLine() def createCmd(self, ignoreErrors = False): """Produce a command line string for feeding into GRASS.""" - cmd = grass_task.name + cmd = self.task.name errors = 0 errStr = "" - for flag in grass_task.flags: + for flag in self.task.flags: if 'value' in flag and flag['value']: cmd += ' -' + flag['name'] - for p in grass_task.params: + for p in self.task.params: if p['value'] == '' and p['required'] != 'no': cmd += ' ' + p['name'] + '=' + '' errStr += "Parameter " + p['name'] + "(" + p['description'] + ") is missing\n" @@ -696,8 +695,8 @@ def OnAboutCommand(self, event): dlg = wx.MessageDialog(self, - grass_task.name+": "+grass_task.description, - "About " + grass_task.name, + self.task.name+": "+self.task.description, + "About " + self.task.name, wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() @@ -705,7 +704,7 @@ class GrassGUIApp(wx.App): def OnInit(self): - self.frame = mainFrame(None, -1) + self.frame = mainFrame(None, -1, grassTask() ) self.frame.Show(True) self.SetTopWindow(self.frame) return True @@ -726,7 +725,7 @@ cmdlst = [] cmdlst = cmd.split(' ') - if parentframe > -1: + if parentframe != -1: self.parent = parentframe if len(cmdlst) > 1: @@ -737,22 +736,24 @@ cmdout = os.popen(cmd, "r").read() p = re.compile( '(grass-interface.dtd)') cmdout2 = p.sub( gmpath+r'/grass-interface.dtd', cmdout) - handler = processTask() + grass_task = grassTask() + handler = processTask(grass_task) xml.sax.parseString(cmdout2, handler) - mf = mainFrame(self.parent ,-1, self.get_dcmd, layer) - mf.Show(True) + self.mf = mainFrame(self.parent ,-1, grass_task, self.get_dcmd, layer) + self.mf.Show(True) if __name__ == "__main__": # Just for testing purposes # Create the application - if len(sys.argv) != 2: + if len(sys.argv) == 1: print "Usage: %s " % sys.argv[0] sys.exit() app = GrassGUIApp(0) # Parsing if run from command line: find out the command to run gui = GUI(app.frame) gui.parseCommand( sys.argv[1], os.getenv("GISBASE") + "/etc/wx/gui_modules") + app.SetTopWindow( gui.mf ) app.MainLoop() From barton at grass.itc.it Tue Mar 27 08:45:26 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Mar 27 08:45:27 2007 Subject: [grass-addons] r338 - trunk/grassaddons/gui Message-ID: <200703270645.l2R6jQoN025769@grass.itc.it> Author: barton Date: 2007-03-27 08:45:17 +0200 (Tue, 27 Mar 2007) New Revision: 338 Modified: trunk/grassaddons/gui/location_wizard.py Log: Working on location setting code. Not there yet, but closer. Is it even possible to set a location with datum/tranform parameters? Modified: trunk/grassaddons/gui/location_wizard.py =================================================================== --- trunk/grassaddons/gui/location_wizard.py 2007-03-27 02:50:12 UTC (rev 337) +++ trunk/grassaddons/gui/location_wizard.py 2007-03-27 06:45:17 UTC (rev 338) @@ -8,7 +8,30 @@ import string import re +global coordsys +global epsgcode +global georeffile +global datum +global transform +global projection +global north +global south +global east +global west +global resolution +coordsys = '' +epsgcode = '' +georeffile = '' +datum = '' +transform = '' +projection = '' +north = '' +south = '' +east = '' +west = '' +resolution = '' + class TitledPage(wiz.WizardPageSimple): def __init__(self, parent, title): wiz.WizardPageSimple.__init__(self, parent) @@ -142,6 +165,7 @@ #wx.EVT_BUTTON(self, self.bbcodes.GetId(), self.OnBrowseCodes) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.datumlist) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTransformSelected, self.transformlist) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) self.bupdate.Bind(wx.EVT_BUTTON, self._onBrowseParams) self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) self.tdatum.Bind(wx.EVT_TEXT_ENTER, self._onBrowseParams, self.tdatum) @@ -152,6 +176,12 @@ self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE) self.datumlist.SetColumnWidth(3, wx.LIST_AUTOSIZE) + def onPageChange(self,event): + global datum + datum = self.tdatum.GetValue() + global transform + transform = self.ttrans.GetValue() + def OnDoSearch(self,event): str = self.searchb.GetValue() listItem = self.datumlist.GetColumn(1) @@ -258,8 +288,6 @@ dlg.ShowModal() dlg.Destroy() - def OnChange(self,event): - self.item = event.GetItem() class SummaryPage(TitledPage): def __init__(self, wizard, parent): @@ -308,52 +336,32 @@ def FillVars(self,event=None): database = self.parent.startpage.tgisdbase.GetValue() location = self.parent.startpage.tlocation.GetValue() - projection = self.parent.csystemspage.cs - #zoone = self.pages - north = self.parent.bboxpage.ttop.GetValue() - south = self.parent.bboxpage.tbottom.GetValue() - east = self.parent.bboxpage.tright.GetValue() - west = self.parent.bboxpage.tleft.GetValue() - res = self.parent.bboxpage.tres.GetValue() + global coordsys + global north + global south + global east + global west + global resolution + + #if projection != "latlong": - rows = int(round((float(north)-float(south))/float(res))) - cols = int(round((float(east)-float(west))/float(res))) + rows = int(round((float(north)-float(south))/float(resolution))) + cols = int(round((float(east)-float(west))/float(resolution))) cells = int(rows*cols) self.ldatabase.SetLabel(database) self.llocation.SetLabel(location) - self.lprojection.SetLabel(projection) + self.lprojection.SetLabel(coordsys) self.lnorth.SetLabel(north) self.lsouth.SetLabel(south) self.least.SetLabel(east) self.lwest.SetLabel(west) - self.lres.SetLabel(res) + self.lres.SetLabel(resolution) self.lrows.SetLabel(str(rows)) self.lcols.SetLabel(str(cols)) self.lcells.SetLabel(str(cells)) - -#projection: 99 (Other Projection) -#zone: 0 -# north: 344444 -# south: 3333 -# east: 3333333 -# west: 33333 -# -# e-w res: 30 -# n-s res: 30.00096746 (Changed to conform to grid) -# -#total rows: 11370 -#total cols: 110000 -#total cells: 1,250,700,000 -# -# -#Do you accept this region? (y/n) [n] > - - - # inputs - class BBoxPage(TitledPage): def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Set default region extents and resolution") @@ -536,7 +544,7 @@ wx.ALL, 5, row=17,col=1, colspan=3) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChange) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) self.Bind(wx.EVT_COMBOBOX, self.OnItemSelected, self.cstate) self.Bind(wx.EVT_TEXT, self.OnStateText, self.cstate) self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset) @@ -674,9 +682,20 @@ # self.cstate.Select(idx) # break - def OnWizPageChange(self, event): + def onPageChange(self, event): self.GetNext().FillVars() + global north + north = self.ttop.GetValue() + global south + south = self.tbottom.GetValue() + global east + east = self.tright.GetValue() + global west + west = self.tleft.GetValue() + global resolution + resolution = self.tres.GetValue() + def OnItemSelected(self, event): item = self.cstate.GetSelection() w,s,e,n = self.coords[item] @@ -767,6 +786,7 @@ # events self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) self._onBrowseDatums(None, None) @@ -823,11 +843,10 @@ dlg.ShowModal() dlg.Destroy() - def OnChange(self,event): - self.item = event.GetItem() + def onPageChange(self,event): + global projection + projection = self.tproj - - class GeoreferencedFilePage(TitledPage): def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Select georeferenced file") @@ -849,7 +868,12 @@ wx.ALL, 5, row=1, col=4) wx.EVT_BUTTON(self, self.bbrowse.GetId(), self.OnBrowse) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) + def onPageChange(self, event): + global georeffile + georeffile = self.tfile + def OnBrowse(self, event): dlg = wx.FileDialog(self, "Choose a georeferenced file:", os.getcwd(), "", "*.*", wx.OPEN) @@ -860,46 +884,11 @@ def OnCreate(self, event): pass - # if not os.path.isfile(self.tfile.GetValue()): - # dlg = wx.MessageDialog(self, "Could not create new location: %s not file" - # % self.tfile.GetValue(),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - # if not self.tname.GetValue(): - # dlg = wx.MessageDialog(self, "Could not create new location: name not set", - # "Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - - # if os.path.isdir(os.path.join(self.parent.gisdbase,self.tname.GetValue())): - # dlg = wx.MessageDialog(self, "Could not create new location: %s exists" - # % os.path.join(self.parent.gisdbase,self.tname.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - - # # creating location - # # all credit to Michael Barton and his file_option.tcl and - # # Markus Neteler - # try: - # # FIXME: this does not need to work on windows - # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) - - # self.parent.OnSetDatabase(None) - # self.Destroy() - - # except StandardError, e: - # dlg = wx.MessageDialog(self, "Could not create new location: %s " - # % str(e),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - class EPSGPage(TitledPage): def __init__(self, wizard, parent): TitledPage.__init__(self, wizard, "Choose EPSG Code") + wx.MessageBox("in epsgpage") # labels self.lfile= wx.StaticText(self, -1, "Path to the EPSG-codes file: ", @@ -970,7 +959,13 @@ wx.EVT_BUTTON(self, self.bbcodes.GetId(), self.OnBrowseCodes) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.epsgs) self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) + def onPageChange(self, event): + global epsgcode + epsgcode = self.tcode + wx.MessageBox("setting epsgcode to %" % (epsgcode)) + def OnDoSearch(self,event): str = self.searchb.GetValue() listItem = self.epsgs.GetColumn(1) @@ -998,7 +993,6 @@ item = event.GetItem() self.tcode.SetValue(str(item.GetText())) - def OnBrowseCodes(self,event,search=None): try: self.epsgs.DeleteAllItems() @@ -1046,56 +1040,6 @@ def OnChange(self,event): self.item = event.GetItem() - #def OnCreate(self, event): - # if not self.tcode.GetValue(): - # dlg = wx.MessageDialog(self, "Could not create new location: EPSG Code value missing", - # "Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - # - # number = -1 - # try: - # number = int(self.tcode.GetValue()) - # except: - # dlg = wx.MessageDialog(self, "Could not create new location: '%s' not a number" % self.tcode.GetValue(), - # "Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - # - # if os.path.isdir(os.path.join(self.parent.gisdbase,self.tname.GetValue())): - # dlg = wx.MessageDialog(self, "Could not create new location: %s exists" - # % os.path.join(self.parent.gisdbase,self.tname.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - # - # # creating location - # # all credit to Michael Barton and his file_option.tcl and - # # Markus Neteler - # try: - # # FIXME: this does not need to work on windows - # os.system("g.proj -c georef=%s location=%s >&2" % (self.tfile.GetValue(), self.tname.GetValue())) - # datumtrans = os.popen(" g.proj epsg=%d datumtrans=-1 >&2" % (number)).readlines() - - # if datumtrans: - # #os.system(" g.proj epsg=%d datumtrans=%s >&2" % (number,datumtrans[0]).readlines() - # pass - # else: - # os.system("g.proj -c epsg=%d location=%s datumtrans=1" % (number, self.tname.GetValue())) - - # self.parent.OnSetDatabase(None) - # self.Destroy() - - # except StandardError, e: - # dlg = wx.MessageDialog(self, "Could not create new location: %s " - # % str(e),"Can not create location", wx.OK|wx.ICON_INFORMATION) - # dlg.ShowModal() - # dlg.Destroy() - # return - - def OnDoubleClick(self, event): print self.epsgs.GetValue() pass @@ -1131,45 +1075,44 @@ self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio4.GetId()) self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio5.GetId()) self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio6.GetId()) - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChange) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChange) def SetVal(self,event): + global coordsys if event.GetId() == self.radio1.GetId(): - self.cs = "xy" + coordsys = "xy" self.SetNext(self.parent.bboxpage) self.parent.bboxpage.cstate.Enable(False) elif event.GetId() == self.radio2.GetId(): - self.cs = "latlong" + coordsys = "latlong" self.SetNext(self.parent.datumpage) self.parent.datumpage.SetPrev(self.parent.csystemspage) self.parent.bboxpage.SetPrev(self.parent.datumpage) elif event.GetId() == self.radio3.GetId(): - self.cs = "utm" + coordsys = "utm" self.SetNext(self.parent.datumpage) self.parent.datumpage.SetPrev(self.parent.csystemspage) self.parent.bboxpage.SetPrev(self.parent.datumpage) elif event.GetId() == self.radio4.GetId(): - self.cs = "custom" + coordsys = "custom" self.SetNext(self.parent.projpage) - self.parent.datumpage.SetPrev(self.parent.projpage) - self.parent.bboxpage.SetPrev(self.parent.datumpage) + self.parent.bboxpage.SetPrev(self.parent.projpage) elif event.GetId() == self.radio5.GetId(): - self.cs = "epsg" + coordsys = "epsg" self.SetNext(self.parent.epsgpage) - self.parent.datumpage.SetPrev(self.parent.epsgpage) - self.parent.bboxpage.SetPrev(self.parent.datumpage) + self.parent.sumpage.SetPrev(self.parent.epsgpage) elif event.GetId() == self.radio6.GetId(): + coordsys = "file" self.SetNext(self.parent.filepage) - self.cs = "file" + self.parent.sumpage.SetPrev(self.parent.filepage) - def OnWizPageChange(self,event=None): - if self.cs == "xy": + def onPageChange(self,event=None): + global coordsys + if coordsys == "xy": self.parent.bboxpage.cstate.Enable(False) else: self.parent.bboxpage.cstate.Enable(True) - pass - class DatabasePage(TitledPage): def __init__(self, wizard, parent, grassdatabase): TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name") @@ -1215,9 +1158,11 @@ row=2, col=4) # bindings - self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnWizPageChanging) + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChanging) - def OnWizPageChanging(self,event=None): + self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.onPageChanged) + + def onPageChanging(self,event=None): if os.path.isdir(os.path.join(self.tgisdbase.GetValue(),self.tlocation.GetValue())): dlg = wx.MessageDialog(self, "Could not create new location: <%s> directory exists "\ % str(self.tlocation.GetValue()),"Can not create location", wx.OK|wx.ICON_INFORMATION) @@ -1237,7 +1182,7 @@ self.location = self.tlocation.GetValue() self.grassdatabase = self.tgisdbase.GetValue() - def OnWizPageChange(self,event=None): + def onPageChanged(self,event=None): self.grassdatabase = self.tgisdbase.GetValue() self.location = self.tlocation.GetValue() @@ -1264,13 +1209,14 @@ self.csystemspage.SetPrev(self.startpage) self.csystemspage.SetNext(self.bboxpage) - self.epsgpage.SetNext(self.datumpage) self.epsgpage.SetPrev(self.csystemspage) + self.epsgpage.SetNext(self.sumpage) + self.projpage.SetPrev(self.csystemspage) self.projpage.SetNext(self.datumpage) - self.projpage.SetPrev(self.csystemspage) self.filepage.SetPrev(self.csystemspage) + self.filepage.SetNext(self.sumpage) self.datumpage.SetNext(self.bboxpage) @@ -1280,9 +1226,144 @@ self.sumpage.SetPrev(self.bboxpage) wizard.FitToPage(self.bboxpage) - wizard.RunWizard(self.startpage) + if wizard.RunWizard(self.startpage): + self.onWizFinished() + wx.MessageBox("New location created.") + else: + wx.MessageBox("Location wizard canceled. New location not created.") + wizard.Destroy() + def onWizFinished(self): + database = self.startpage.tgisdbase.GetValue() + location = self.startpage.tlocation.GetValue() + global coordsys + + wx.MessageBox("finished database: %s, location: %s, coordsys: %s" % (database, location, coordsys)) + if os.path.isdir(os.path.join(database,location)): + dlg = wx.MessageDialog(self, "Could not create new location: %s already exists" + % os.path.join(self.parent.gisdbase,location),"Can not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + return + + if coordsys == "xy": + self.xyCreate + elif coordsys == "latlong": + rows = int(round((float(north)-float(south))/float(resolution))) + cols = int(round((float(east)-float(west))/float(resolution))) + cells = int(rows*cols) + self.latlongCreate + elif coordsys == "utm": + self.utmCreate + elif coordsys == "custom": + self.customCreate + elif coordsys == "epsg": + self.epsgCreate + elif "file": + self.fileCreate + + def xyCreate(self): + """ + Create an XY location + """ + pass + + def latlongCreate(self): + """ + Create a new Lat/Long location + """ + pass + + def utmCreate(self): + """ + Create a new UTM location + """ + pass + + def customCreate(self): + """ + Create a new custom-defined location + """ + pass + + def epsgCreate(self): + """ + Create a new location from an EPSG code. + """ + global epsgcode + global database + global location + + wx.MessageBox("Database: %s, Location: %s, EPSG code: %s" % (database, location, epsgcode)) + + if not epsgcode: + dlg = wx.MessageDialog(self, "Could not create new location: EPSG Code value missing", + "Can not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + return + + # creating location + # all credit to Michael Barton and his file_option.tcl and + # Markus Neteler + try: + dtoptions = os.popen3(" g.proj epsg=%s datumtrans=-1" % (epsgcode))[1].read() + if dtoptions != None: + # open a dialog to select datum transform number + dtoptions = 'Select the number of a datum transformation to use: \n'+dtoptions + dlg = wx.TextEntryDialog(self, dtoptions) + dlg.SetValue('1') + + if dlg.ShowModal() == wx.ID_OK: + dtrans = dlg.GetValue() + + dlg.Destroy() + + cmd = os.system("g.proj -c epsg=%s location=%s datumtrans=%s" % (epsgcode, location, dtrans)) + else: + os.system("g.proj -c epsg=%s location=%s datumtrans=1" % (epsgcode, location)) + + except StandardError, e: + dlg = wx.MessageDialog(self, "Could not create new location: %s " + % str(e),"Can not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + def FileCreate(self): + """ + Create a new location from a georeferenced file + """ + global georeffile + global database + global location + if not os.path.isfile(georeffile): + dlg = wx.MessageDialog(self, "Could not create new location: %s not file" + % georeffile,"Can not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + return + + if not sgeoreffile: + dlg = wx.MessageDialog(self, "Could not create new location: name not set", + "Can not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + return + + # creating location + # all credit to Michael Barton and his file_option.tcl and + # Markus Neteler + try: + # FIXME: this does not need to work on windows + os.system("g.proj -c georef=%s location=%s >&2" % (georeffile, location)) + + except StandardError, e: + dlg = wx.MessageDialog(self, "Could not create new location: %s " + % str(e),"Can not create location", wx.OK|wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + if __name__ == "__main__": gWizard = GWizard(None, "") GRASSStartUp = GWizard.StartUp(0) From barton at grass.itc.it Tue Mar 27 16:21:54 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Mar 27 16:21:55 2007 Subject: [grass-addons] r339 - trunk/grassaddons/gui/gui_modules Message-ID: <200703271421.l2RELst6029330@grass.itc.it> Author: barton Date: 2007-03-27 16:21:42 +0200 (Tue, 27 Mar 2007) New Revision: 339 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/toolbars.py Log: Started developing place to add decorations to maps. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-27 06:45:17 UTC (rev 338) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-27 14:21:42 UTC (rev 339) @@ -31,7 +31,13 @@ imagepath = images.__path__[0] sys.path.append(imagepath) +icons = "" +if not os.getenv("GRASS_ICONPATH"): + icons = os.getenv("GISBASE") + "/etc/gui/icons/" +else: + icons = os.environ["GRASS_ICONPATH"] + Map = render.Map() # instance of Map class to render GRASS display output to PPM file DEBUG = False @@ -695,6 +701,41 @@ self.draw(dc) event.Skip() + # toolBar button handlers + def onDecoration(self, event): + """Add decorations item menu""" + point = wx.GetMousePosition() + decmenu = wx.Menu() + # Add items to the menu + addscale = wx.MenuItem(decmenu, -1,'Add scalebar and north arrow') + bmp = wx.Image(os.path.join(icons,'module-d.barscale.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addscale.SetBitmap(bmp) + decmenu.AppendItem(addscale) + self.Bind(wx.EVT_MENU, self.addBarscale, addscale) + + addgrid = wx.MenuItem(decmenu, -1,'Add grid') + bmp = wx.Image(os.path.join(icons,'module-d.grid.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addgrid.SetBitmap(bmp) + decmenu.AppendItem(addgrid) + self.Bind(wx.EVT_MENU, self.addGrid, addgrid) + + # Popup the menu. If an item is selected then its handler + # will be called before PopupMenu returns. + self.PopupMenu(decmenu) + decmenu.Destroy() + + def addBarscale(self): + # need to run d.barscale options and then add the command + #to the top (last rendered) of the command stack + pass + + def addGrid(self): + pass + def OnAlignRegion(self, event): """ Align region Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-03-27 06:45:17 UTC (rev 338) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-03-27 14:21:42 UTC (rev 339) @@ -66,6 +66,15 @@ shortHelp="Pan", longHelp="Drag with mouse to pan") self.toolbar.AddSeparator() + self.dec = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="dec", + bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"module-d.barscale.gif"), + wx.BITMAP_TYPE_ANY), + bmpDisabled=wx.NullBitmap, + shortHelp="Decoration", longHelp="Add graphic overlays to map") + + + self.toolbar.AddSeparator() + # # Misc # @@ -93,6 +102,7 @@ self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnZoomIn, self.zoomin) self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnZoomOut, self.zoomout) self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnPan, self.pan) + self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.onDecoration, self.dec) self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.OnErase, self.erase) self.mapdisplay.Bind(wx.EVT_TOOL, self.mapdisplay.SaveToFile, self.savefile) self.mapdisplay.Bind(wx.EVT_COMBOBOX, self.OnSelect, self.combo) From barton at grass.itc.it Tue Mar 27 16:27:08 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Mar 27 16:27:09 2007 Subject: [grass-addons] r340 - trunk/grassaddons/gui/gui_modules Message-ID: <200703271427.l2RER8ve029356@grass.itc.it> Author: barton Date: 2007-03-27 16:26:59 +0200 (Tue, 27 Mar 2007) New Revision: 340 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: Added backslash for if clauses in () that break across lines. This seems to be a problem with some systems and we may need to alter all code in this way. Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-27 14:21:42 UTC (rev 339) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-27 14:26:59 UTC (rev 340) @@ -148,12 +148,12 @@ self.ctrl.SetValue(100) self.ctrl.Bind(wx.EVT_TEXT, self.onOpacity) - if (self.layer_selected and self.layer_selected != self.GetRootItem() and + if (self.layer_selected and self.layer_selected != self.GetRootItem() and \ self.layertype[self.layer_selected] != 'group'): parent = self.GetItemParent(self.layer_selected) layer = self.InsertItem(parent, self.GetPrevSibling(self.layer_selected), '', ct_type=1, wnd=self.ctrl ) - elif (self.layer_selected and self.layer_selected != self.GetRootItem() and + elif (self.layer_selected and self.layer_selected != self.GetRootItem() and \ self.layertype[self.layer_selected] == 'group'): layer = self.InsertItem(self.layer_selected, self.GetPrevSibling(self.layer_selected), '', ct_type=1, wnd=self.ctrl ) From cepicky at grass.itc.it Tue Mar 27 17:16:42 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Tue Mar 27 17:16:44 2007 Subject: [grass-addons] r341 - trunk/grassaddons/gui/gui_modules Message-ID: <200703271516.l2RFGgnw031197@grass.itc.it> Author: cepicky Date: 2007-03-27 17:16:42 +0200 (Tue, 27 Mar 2007) New Revision: 341 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: progress bar (wxGauge) added, but not working yet Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-27 14:26:59 UTC (rev 340) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-27 15:16:42 UTC (rev 341) @@ -619,6 +619,7 @@ wx.Panel.__init__(self, parent, id, pos, size, style) #initialize variables + self.parent = parent self.cmd_output = "" self.console_command = "" self.console_clear = "" @@ -636,6 +637,8 @@ self.console_clear = wx.Button(self, -1, _("Clear")) self.console_save = wx.Button(self, -1, _("Save")) + self.console_progressbar = wx.Gauge(self, -1, 100, (110, 50), (250, 25)) + self.Bind(wx.EVT_BUTTON, self.clearHistory, self.console_clear) self.Bind(wx.EVT_BUTTON, self.saveHistory, self.console_save) @@ -649,9 +652,12 @@ gridsizer1.Add(self.console_save, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) + boxsizer1.Add((0,5)) boxsizer1.Add(gridsizer1, 0, wx.EXPAND|wx.ALIGN_CENTRE_VERTICAL) boxsizer1.Add((0,5)) + boxsizer1.Add(self.console_progressbar, 0, + wx.EXPAND|wx.ADJUST_MINSIZE, 0) boxsizer1.Fit(self) boxsizer1.SetSizeHints(self) self.SetAutoLayout(True) @@ -739,27 +745,28 @@ # Send any other command to the shell. Send output to # console output window. try: + os.environ["GRASS_MESSAGE_FORMAT"] = "gui" + os.system("g.gisenv set=GRASS_MESSAGE_FORMAT=gui") self.cmd_output.write(cmd+"\n----------\n") - # self.out = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).communicate()[0] p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) - (child_stdin, child_stdout, child_stderr) = (p.stdin, p.stdout, p.stderr) - oline = child_stderr.readline() - while 1: - if oline == '': - break - print >>sys.stderr, "MSG: ",oline - oline = child_stderr.readline() - self.out=p.communicate()[0] - self.cmd_output.write(self.out+"\n") - child_stderr.close() - child_stdout.close() - child_stdin.close() + oline = p.stderr.readline() + while oline: + oline = oline.strip() + print "MSG: ", oline + oline = p.stderr.readline() - if self.out < 0: - print >> sys.stderr, "Child was terminated by signal", self.out - elif self.out > 0: - print >> sys.stderr, self.out + oline = p.stdout.readline() + while oline: + oline = oline.strip() + self.cmd_output.write(oline+"\n") + print >> sys.stderr, oline + oline = p.stdout.readline() + + if p.stdout < 0: + print >> sys.stderr, "Child was terminated by signal", p.stdout + elif p.stdout > 0: + print >> sys.stderr, p.stdout except OSError, e: print >> sys.stderr, "Execution failed:", e From cepicky at grass.itc.it Tue Mar 27 17:39:08 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Tue Mar 27 17:39:09 2007 Subject: [grass-addons] r342 - trunk/grassaddons/gui/gui_modules Message-ID: <200703271539.l2RFd8iv031343@grass.itc.it> Author: cepicky Date: 2007-03-27 17:39:08 +0200 (Tue, 27 Mar 2007) New Revision: 342 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: progress bar should work now Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-27 15:16:42 UTC (rev 341) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-27 15:39:08 UTC (rev 342) @@ -746,7 +746,6 @@ # console output window. try: os.environ["GRASS_MESSAGE_FORMAT"] = "gui" - os.system("g.gisenv set=GRASS_MESSAGE_FORMAT=gui") self.cmd_output.write(cmd+"\n----------\n") p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) @@ -754,8 +753,14 @@ while oline: oline = oline.strip() print "MSG: ", oline + print >> sys.stderr, oline+"#####" oline = p.stderr.readline() + # make some progress + #GRASS_INFO_PERCENT: 100 + if oline.find("GRASS_INFO_PERCENT")>-1: + self.console_progressbar.SetValue(int(oline.split()[1])) + oline = p.stdout.readline() while oline: oline = oline.strip() @@ -766,7 +771,8 @@ if p.stdout < 0: print >> sys.stderr, "Child was terminated by signal", p.stdout elif p.stdout > 0: - print >> sys.stderr, p.stdout + #print >> sys.stderr, p.stdout + pass except OSError, e: print >> sys.stderr, "Execution failed:", e From barton at grass.itc.it Tue Mar 27 17:51:18 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Mar 27 17:51:19 2007 Subject: [grass-addons] r343 - trunk/grassaddons/gui Message-ID: <200703271551.l2RFpIhl031432@grass.itc.it> Author: barton Date: 2007-03-27 17:51:09 +0200 (Tue, 27 Mar 2007) New Revision: 343 Modified: trunk/grassaddons/gui/gis_set.py Log: Fixed bug with new mapset not copying WIND file from PERMANENT. ****Please check to see if permissions need to be set (I just copied the WIND file permissions). Line 674 has a chmod statement, but I don't know what to set it to (needs set of numbers for u+rw,go+r I think). Modified: trunk/grassaddons/gui/gis_set.py =================================================================== --- trunk/grassaddons/gui/gis_set.py 2007-03-27 15:39:08 UTC (rev 342) +++ trunk/grassaddons/gui/gis_set.py 2007-03-27 15:51:09 UTC (rev 343) @@ -662,13 +662,16 @@ event.Skip() def OnCreateMapset(self,event): + database = self.tgisdbase.GetValue() + location = self.listOfLocations[self.lblocations.GetSelection()] try: mapset = self.tnewmapset.GetValue() - os.mkdir(os.path.join( - self.tgisdbase.GetValue(), - self.listOfLocations[self.lblocations.GetSelection()], - mapset)) + os.mkdir(os.path.join(database,location,mapset)) + # copy WIND file and its permissions from PERMANENT and set permissions to u+rw,go+r + shutil.copy(os.path.join(database,location,'PERMANENT','WIND'), + os.path.join(database,location,mapset)) +# os.chmod(os.path.join(database,location,mapset,'WIND'), ?????) self.OnSelectLocation(None) self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset)) except StandardError, e: From calvelo at grass.itc.it Wed Mar 28 01:35:59 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Wed Mar 28 01:36:01 2007 Subject: [grass-addons] r344 - trunk/grassaddons/gui/gui_modules Message-ID: <200703272335.l2RNZxmV005160@grass.itc.it> Author: calvelo Date: 2007-03-28 01:35:45 +0200 (Wed, 28 Mar 2007) New Revision: 344 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - Make standalone operation in one Frame; had to duplicate code: this is temporary Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-27 15:51:09 UTC (rev 343) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-27 23:35:45 UTC (rev 344) @@ -703,10 +703,22 @@ class GrassGUIApp(wx.App): + def __init__(self, cmd): + gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules" + cmd = cmd + r' --interface-description' + cmdout = os.popen(cmd, "r").read() + p = re.compile( '(grass-interface.dtd)') + p.search( cmdout ) + cmdout2 = p.sub( gmpath+r'/grass-interface.dtd', cmdout) + self.grass_task = grassTask() + handler = processTask(self.grass_task) + xml.sax.parseString(cmdout2, handler) + wx.App.__init__(self) + def OnInit(self): - self.frame = mainFrame(None, -1, grassTask() ) - self.frame.Show(True) - self.SetTopWindow(self.frame) + self.mf = mainFrame(None ,-1, self.grass_task ) + self.mf.Show(True) + self.SetTopWindow(self.mf) return True class GUI: @@ -722,7 +734,6 @@ else: self.get_dcmd = completed[0] layer = completed[1] - cmdlst = [] cmdlst = cmd.split(' ') if parentframe != -1: @@ -735,6 +746,7 @@ cmd = cmd + r' --interface-description' cmdout = os.popen(cmd, "r").read() p = re.compile( '(grass-interface.dtd)') + p.search( cmdout ) cmdout2 = p.sub( gmpath+r'/grass-interface.dtd', cmdout) grass_task = grassTask() handler = processTask(grass_task) @@ -750,10 +762,6 @@ if len(sys.argv) == 1: print "Usage: %s " % sys.argv[0] sys.exit() - app = GrassGUIApp(0) - # Parsing if run from command line: find out the command to run - gui = GUI(app.frame) - gui.parseCommand( sys.argv[1], os.getenv("GISBASE") + "/etc/wx/gui_modules") - app.SetTopWindow( gui.mf ) + app = GrassGUIApp(sys.argv[1]) app.MainLoop() From calvelo at grass.itc.it Wed Mar 28 02:55:11 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Wed Mar 28 02:55:13 2007 Subject: [grass-addons] r345 - trunk/grassaddons/gui/gui_modules Message-ID: <200703280055.l2S0tBq9006326@grass.itc.it> Author: calvelo Date: 2007-03-28 02:55:06 +0200 (Wed, 28 Mar 2007) New Revision: 345 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - more refactoring: the options notebook is now an independent Panel, except for the statusline callback, which is try:except:-ed Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-27 23:35:45 UTC (rev 344) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 00:55:06 UTC (rev 345) @@ -298,7 +298,16 @@ defined by each GRASS command.""" def __init__(self, parent, ID, task_description, get_dcmd=None, layer=None, dcmd_params=None): + self.get_dcmd = get_dcmd + self.dcmd_params = dcmd_params #this should be passed from the layer tree eventually + self.layer = layer self.task = task_description + # inserting existing values from d.* command in layer tree + for p in self.task.params: + if self.dcmd_params != None: + for dparam in self.dcmd_params: + if p == dparam: + p['value'] = self.dcmd_params[dparam] wx.Frame.__init__(self, parent, ID, self.task.name, wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) @@ -306,11 +315,6 @@ self.CreateStatusBar() self.SetStatusText("Enter parameters for " + self.task.name + " (those in Main are required)") self.parent = parent - self.selection = '' #selection from GIS element selector - self.paramdict = {} # dictionary of controls and their parameter values - self.get_dcmd = get_dcmd - self.dcmd_params = dcmd_params #this should be passed from the layer tree eventually - self.layer = layer self.SetIcon(wx.Icon(os.path.join(imagepath,'grass.form.gif'), wx.BITMAP_TYPE_ANY)) menu = wx.Menu() @@ -326,7 +330,134 @@ self.SetMenuBar(menuBar) self.guisizer = wx.BoxSizer(wx.VERTICAL) + + self.notebookpanel = cmdPanel( self, self.task ) + self.guisizer.Add( self.notebookpanel, 1, flag = wx.EXPAND ) + + btnsizer = wx.BoxSizer(wx.HORIZONTAL) + self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "Cancel") + btnsizer.Add(self.btn_cancel, 0, wx.ALL| wx.ALIGN_CENTER, 10) + if self.get_dcmd is not None: # A callback has been set up + self.btn_apply = wx.Button(self, wx.ID_APPLY, "Apply") + btnsizer.Add(self.btn_apply, 0, wx.ALL| wx.ALIGN_CENTER, 10) + self.btn_ok = wx.Button(self, wx.ID_OK, "OK") + btnsizer.Add(self.btn_ok, 0, wx.ALL| wx.ALIGN_CENTER, 10) + self.btn_ok.SetDefault() + self.btn_apply.Bind(wx.EVT_BUTTON, self.OnApply) + self.btn_ok.Bind(wx.EVT_BUTTON, self.OnOK) + else: # We're standalone + self.btn_run = wx.Button(self, wx.ID_OK, "Run") + btnsizer.Add(self.btn_run, 0, wx.ALL| wx.ALIGN_CENTER, 10) + self.btn_run.SetDefault() + self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun) + self.btn_clipboard = wx.Button(self, wx.ID_OK, "Copy") + btnsizer.Add(self.btn_clipboard, 0, wx.ALL| wx.ALIGN_CENTER, 10) + self.btn_clipboard.Bind(wx.EVT_BUTTON, self.OnCopy) + self.guisizer.Add(btnsizer, 0, wx.ALIGN_BOTTOM) + wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout) + wx.EVT_MENU(self, ID_ABOUT_COMMAND, self.OnAboutCommand) + wx.EVT_MENU(self, wx.ID_EXIT, self.OnCancel) + self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) + self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) + constrained_size = self.notebookpanel.GetSize() + self.notebookpanel.SetSize( (constrained_size[0],constrained_size[1]+80) ) # 80 takes the tabbar into account + self.notebookpanel.SetSizer( self.notebookpanel.panelsizer ) + self.notebookpanel.Layout() + + self.guisizer.SetSizeHints(self) + self.SetAutoLayout(True) + self.SetSizer(self.guisizer) + self.Layout() + + + def OnOK(self, event): + cmd = self.OnApply(event) + if cmd is not None and self.get_dcmd is not None: + self.OnCancel(event) + + def OnApply(self, event): + cmd = self.createCmd() + + if cmd is not None and self.get_dcmd is not None: + # return d.* command to layer tree for rendering + self.get_dcmd(cmd, self.layer) + # echo d.* command to output console + self.parent.writeDCommand(cmd) + return cmd + + def OnRun(self, event): + cmd = self.createCmd() + + if cmd != None and cmd[0:2] != "d.": + # Send any non-display command to parent window (probably wxgui.py) + if self.parent > -1: + # put to parents + try: + self.parent.goutput.runCmd(cmd) + except AttributeError,e: + print >>sys.stderr, "%s: Propably not running in wxgui.py session?" % (e) + print >>sys.stderr, "parent window is: %s" % (str(self.parent)) + # Send any other command to the shell. + else: + try: + retcode = subprocess.call(cmd, shell=True) + if retcode < 0: + print >>sys.stderr, "Child was terminated by signal", -retcode + elif retcode > 0: + print >>sys.stderr, "Child returned", retcode + except OSError, e: + print >>sys.stderr, "Execution failed:", e + + def OnCopy(self, event): + cmddata = wx.TextDataObject() + cmddata.SetText(self.createCmd(ignoreErrors=True)) + if wx.TheClipboard.Open(): + wx.TheClipboard.UsePrimarySelection(True) + wx.TheClipboard.SetData(cmddata) + wx.TheClipboard.Close() + self.SetStatusText("'%s' copied to clipboard" %\ + (self.createCmd(ignoreErrors=True))) + + def OnError(self, errMsg): + dlg = wx.MessageDialog(self, errMsg, "Error", wx.OK | wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + + def OnCancel(self, event): + self.Destroy() + + def OnCloseWindow(self, event): + self.Destroy() + + def OnAbout(self, event): + dlg = wx.MessageDialog(self, "This is a sample program for\n" + "GRASS command interface parsing\n" + "and automatic GUI building. \n%s" %(__version__), + "About GrassGUI", wx.OK | wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + def OnAboutCommand(self, event): + dlg = wx.MessageDialog(self, + self.task.name+": "+self.task.description, + "About " + self.task.name, + wx.OK | wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + def createCmd(self, ignoreErrors = False): + return self.notebookpanel.createCmd(ignoreErrors=ignoreErrors) + + +class cmdPanel(wx.Panel): + def __init__( self, parent, task, *args, **kwargs ): + wx.Panel.__init__( self, parent, *args, **kwargs ) + + self.task = task + self.selection = '' #selection from GIS element selector + self.paramdict = {} # dictionary of controls and their parameter values + sections = ['Main'] is_section = {} for task in self.task.params + self.task.flags: @@ -343,12 +474,10 @@ if not there_is_main: sections = sections[1:] - - self.notebookpanel = wx.Panel( self, id=wx.ID_ANY ) self.panelsizer = wx.BoxSizer(wx.VERTICAL) nbStyle=FN.FNB_NO_X_BUTTON|FN.FNB_NO_NAV_BUTTONS|FN.FNB_VC8|FN.FNB_BACKGROUND_GRADIENT - self.notebook = FN.FlatNotebook(self.notebookpanel, id=wx.ID_ANY, style=nbStyle) + self.notebook = FN.FlatNotebook( self, id=wx.ID_ANY, style=nbStyle) self.notebook.SetTabAreaColour(wx.Colour(125,200,175)) self.notebook.Bind( FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChange ) self.tab = {} @@ -367,7 +496,6 @@ self.notebook.AddPage( manual_tab, text = "Manual" , select = False ) self.panelsizer.Add( self.notebook, 1, flag=wx.EXPAND ) - self.guisizer.Add( self.notebookpanel, 1, flag = wx.EXPAND ) p_count = -1 for p in self.task.params: @@ -381,13 +509,8 @@ text_style = wx.FONTWEIGHT_NORMAL if p['multiple'] == 'yes' and len( p['values'] ) == 0: title = "[multiple] " + title - p['value'] = p['default'] - # inserting existing values from d.* command in layer tree - if self.dcmd_params != None: - for dparam in self.dcmd_params: - if p == dparam: - p['value'] = self.dcmd_params[dparam] - + if p[ 'value'] == '' : + p['value'] = p['default'] if (len(p['values']) > 0): valuelist=map(str,p['values']) @@ -481,33 +604,6 @@ self.paramdict[self.chk] = ID_FLAG_START + f_count self.chk.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox) - - btnsizer = wx.BoxSizer(wx.HORIZONTAL) - self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "Cancel") - btnsizer.Add(self.btn_cancel, 0, wx.ALL| wx.ALIGN_CENTER, 10) - if self.get_dcmd is not None: # A callback has been set up - self.btn_apply = wx.Button(self, wx.ID_APPLY, "Apply") - btnsizer.Add(self.btn_apply, 0, wx.ALL| wx.ALIGN_CENTER, 10) - self.btn_ok = wx.Button(self, wx.ID_OK, "OK") - btnsizer.Add(self.btn_ok, 0, wx.ALL| wx.ALIGN_CENTER, 10) - self.btn_ok.SetDefault() - self.btn_apply.Bind(wx.EVT_BUTTON, self.OnApply) - self.btn_ok.Bind(wx.EVT_BUTTON, self.OnOK) - else: # We're standalone - self.btn_run = wx.Button(self, wx.ID_OK, "Run") - btnsizer.Add(self.btn_run, 0, wx.ALL| wx.ALIGN_CENTER, 10) - self.btn_run.SetDefault() - self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun) - self.btn_clipboard = wx.Button(self, wx.ID_OK, "Copy") - btnsizer.Add(self.btn_clipboard, 0, wx.ALL| wx.ALIGN_CENTER, 10) - self.btn_clipboard.Bind(wx.EVT_BUTTON, self.OnCopy) - self.guisizer.Add(btnsizer, 0, wx.ALIGN_BOTTOM) - wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout) - wx.EVT_MENU(self, ID_ABOUT_COMMAND, self.OnAboutCommand) - wx.EVT_MENU(self, wx.ID_EXIT, self.OnCancel) - self.btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel) - self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) - maxsizes = (0,0) for section in sections: self.tabsizer[section].SetSizeHints( self.tab[section] ) @@ -524,19 +620,10 @@ if manual_tab.Ok: manual_tab.SetMinSize( constrained_size ) - self.notebookpanel.SetSize( (constrained_size[0],constrained_size[1]+80) ) # 80 takes the tabbar into account - self.notebookpanel.SetSizer(self.panelsizer) - self.notebookpanel.Layout() - self.guisizer.SetSizeHints(self) - self.SetAutoLayout(True) - self.SetSizer(self.guisizer) + def OnPageChange(self, event): self.Layout() - - def OnPageChange(self, event): - self.notebookpanel.Layout() - def OnColorButton(self, event): colorchooser = wx.FindWindowById( event.GetId() ) new_color = colorchooser.GetValue()[:] @@ -549,7 +636,10 @@ self.getValues() def updateStatusLine(self): - self.SetStatusText( self.createCmd(ignoreErrors = True) ) + try: + self.GetParent().SetStatusText( self.createCmd(ignoreErrors = True) ) + except: + pass def getValues(self): for (gui_object,param_num) in self.paramdict.items(): @@ -621,98 +711,20 @@ return None return cmd - def OnOK(self, event): - cmd = self.OnApply(event) - if cmd is not None and self.get_dcmd is not None: - self.OnCancel(event) +def getInterfaceDescription( cmd ): + gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules" + cmd = cmd + r' --interface-description' + cmdout = os.popen(cmd, "r").read() + p = re.compile( '(grass-interface.dtd)') + p.search( cmdout ) + cmdout = p.sub( gmpath+r'/grass-interface.dtd', cmdout) + return cmdout - def OnApply(self, event): - cmd = self.createCmd() - - if cmd is not None and self.get_dcmd is not None: - # return d.* command to layer tree for rendering - self.get_dcmd(cmd, self.layer) - # echo d.* command to output console - self.parent.writeDCommand(cmd) - return cmd - - def OnRun(self, event): - cmd = self.createCmd() - - if cmd != None and cmd[0:2] != "d.": - # Send any non-display command to parent window (probably wxgui.py) - if self.parent > -1: - # put to parents - try: - self.parent.goutput.runCmd(cmd) - except AttributeError,e: - print >>sys.stderr, "%s: Propably not running in wxgui.py session?" % (e) - print >>sys.stderr, "parent window is: %s" % (str(self.parent)) - # Send any other command to the shell. - else: - try: - retcode = subprocess.call(cmd, shell=True) - if retcode < 0: - print >>sys.stderr, "Child was terminated by signal", -retcode - elif retcode > 0: - print >>sys.stderr, "Child returned", retcode - except OSError, e: - print >>sys.stderr, "Execution failed:", e - - def OnCopy(self, event): - cmddata = wx.TextDataObject() - cmddata.SetText(self.createCmd(ignoreErrors=True)) - if wx.TheClipboard.Open(): - wx.TheClipboard.UsePrimarySelection(True) - wx.TheClipboard.SetData(cmddata) - wx.TheClipboard.Close() - self.SetStatusText("'%s' copied to clipboard" %\ - (self.createCmd(ignoreErrors=True))) - - def OnError(self, errMsg): - dlg = wx.MessageDialog(self, errMsg, "Error", wx.OK | wx.ICON_ERROR) - dlg.ShowModal() - dlg.Destroy() - - def OnCancel(self, event): - self.Close(True) - for t in self.tab.values(): t = None - for t in self.tabsizer.values(): t.Clear(True) - self.notebook.Destroy() - self.guisizer.Clear(True) - self.Destroy() - - def OnCloseWindow(self, event): - self.Destroy() - - def OnAbout(self, event): - dlg = wx.MessageDialog(self, "This is a sample program for\n" - "GRASS command interface parsing\n" - "and automatic GUI building. \n%s" %(__version__), - "About GrassGUI", wx.OK | wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - - def OnAboutCommand(self, event): - dlg = wx.MessageDialog(self, - self.task.name+": "+self.task.description, - "About " + self.task.name, - wx.OK | wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - - class GrassGUIApp(wx.App): def __init__(self, cmd): - gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules" - cmd = cmd + r' --interface-description' - cmdout = os.popen(cmd, "r").read() - p = re.compile( '(grass-interface.dtd)') - p.search( cmdout ) - cmdout2 = p.sub( gmpath+r'/grass-interface.dtd', cmdout) self.grass_task = grassTask() handler = processTask(self.grass_task) - xml.sax.parseString(cmdout2, handler) + xml.sax.parseString( getInterfaceDescription( cmd ) , handler ) wx.App.__init__(self) def OnInit(self): @@ -743,22 +755,15 @@ print "usage: %s " % cmdlst[0] else: # parse the interface decription - cmd = cmd + r' --interface-description' - cmdout = os.popen(cmd, "r").read() - p = re.compile( '(grass-interface.dtd)') - p.search( cmdout ) - cmdout2 = p.sub( gmpath+r'/grass-interface.dtd', cmdout) - grass_task = grassTask() - handler = processTask(grass_task) - xml.sax.parseString(cmdout2, handler) + self.grass_task = grassTask() + handler = processTask(self.grass_task) + xml.sax.parseString( getInterfaceDescription( cmd ) , handler ) - self.mf = mainFrame(self.parent ,-1, grass_task, self.get_dcmd, layer) - self.mf.Show(True) + self.mf = mainFrame(self.parent ,-1, grass_task, self.get_dcmd, layer) + self.mf.Show(True) if __name__ == "__main__": - # Just for testing purposes - # Create the application if len(sys.argv) == 1: print "Usage: %s " % sys.argv[0] sys.exit() From calvelo at grass.itc.it Wed Mar 28 03:32:08 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Wed Mar 28 03:32:19 2007 Subject: [grass-addons] r346 - trunk/grassaddons/gui/gui_modules Message-ID: <200703280132.l2S1W8NI006431@grass.itc.it> Author: calvelo Date: 2007-03-28 03:31:50 +0200 (Wed, 28 Mar 2007) New Revision: 346 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: - some code cleanup and docstringing Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 00:55:06 UTC (rev 345) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 01:31:50 UTC (rev 346) @@ -26,6 +26,11 @@ # # Updated to wxPython 2.6 syntax. Methods added to make it callable by gui. # Method added to automatically re-run with pythonw on a Mac. +# +# TODO: +# +# - verify option value types +# - add tooltips """ __version__ ="$Date: 2006/08/06 21:21:01 $" @@ -111,6 +116,12 @@ "Remove redundant whitespace from a string" return string.join( string.split(text), ' ') +def text_beautify( someString ): + "Make really long texts shorter" + # TODO: remove magic number (calculate a correct value from + # pixelSize of text and the magic number for maximum size + return escape_ampersand( "\n".join( textwrap.wrap( normalize_whitespace(someString), 72 ) ) ) + def escape_ampersand(text): "Escapes ampersands with additional ampersand for GUI" return string.replace(text, "&", "&&") @@ -131,13 +142,18 @@ return 0 class grassTask: + """This class holds the structures needed for both filling by the parser and + use by the interface constructor.""" def __init__(self): - self.name = 'index' + self.name = 'unknown' self.params = [] self.description = '' self.flags = [] class processTask(HandlerBase): + """A SAX handler for the --interface-description output, as + defined in grass-interface.dtd. Extend or modify this and the + DTD if the XML output of GRASS' parser is extended or modified.""" def __init__(self, task_description): self.inDescriptionContent = 0 self.inDefaultContent = 0 @@ -262,7 +278,11 @@ class helpPanel(wx.html.HtmlWindow): - """This panel holds the text from GRASS docs.""" + """This panel holds the text from GRASS docs. + + GISBASE must be set in the environment to find the html docs dir. + The SYNOPSIS section is skipped, since this Panel is supposed to + be integrated into the cmdPanel.""" def __init__(self, parent, id, grass_command = "index"): wx.html.HtmlWindow.__init__(self, parent, id) self.fspath = os.getenv( "GISBASE" ) + "/docs/html/" @@ -295,7 +315,14 @@ """This is the Frame containing the dialog for options input. The dialog is organized in a notebook according to the guisections - defined by each GRASS command.""" + defined by each GRASS command. + + If run with a parent, it may Apply, Ok or Cancel; the latter two close the dialog. + The former two trigger a callback. + + If run standalone, it will allow execution of the command. + + The command is checked and sent to the clipboard when clicking "Copy". """ def __init__(self, parent, ID, task_description, get_dcmd=None, layer=None, dcmd_params=None): self.get_dcmd = get_dcmd @@ -313,7 +340,6 @@ wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.CreateStatusBar() - self.SetStatusText("Enter parameters for " + self.task.name + " (those in Main are required)") self.parent = parent self.SetIcon(wx.Icon(os.path.join(imagepath,'grass.form.gif'), wx.BITMAP_TYPE_ANY)) @@ -333,7 +359,14 @@ self.notebookpanel = cmdPanel( self, self.task ) self.guisizer.Add( self.notebookpanel, 1, flag = wx.EXPAND ) - + + status_text = "Enter parameters for " + self.task.name + if self.notebookpanel.tab.has_key('Main'): + # We have to wait for the notebookpanel to be filled in order + # to know if there actually is a Main tab + status_text += " (those of Main in bold typeface are required)" + self.SetStatusText( status_text ) + btnsizer = wx.BoxSizer(wx.HORIZONTAL) self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "Cancel") btnsizer.Add(self.btn_cancel, 0, wx.ALL| wx.ALIGN_CENTER, 10) @@ -451,6 +484,7 @@ class cmdPanel(wx.Panel): + """A panel containing a notebook dividing in tabs the different guisections of the GRASS cmd.""" def __init__( self, parent, task, *args, **kwargs ): wx.Panel.__init__( self, parent, *args, **kwargs ) @@ -502,7 +536,7 @@ p_count += 1 # Needed for checkboxes hack which_sizer = self.tabsizer[ p['guisection'] ] which_panel = self.tab[ p['guisection'] ] - title = escape_ampersand(p['description']) + title = text_beautify(p['description']) text_style = wx.FONTWEIGHT_BOLD txt = None if p['required'] == 'no': @@ -522,15 +556,9 @@ for defval in p['value'].split(','): isDefault[ defval ] = 'yes' for val in valuelist: - # make some descriptions short: - nval = "" - for lval in textwrap.wrap(val, 60): - nval += lval+"\n" - nval = nval[:-1] - # This is the checkboxes hack idForWX = ID_MULTI_START + p_count*20 + v_count - chkbox = wx.CheckBox( which_panel, idForWX, nval+" " ) + chkbox = wx.CheckBox( which_panel, idForWX, text_beautify(val) ) if isDefault.has_key(val): chkbox.SetValue( True ) hSizer.Add( chkbox,0,wx.ADJUST_MINSIZE,5 ) self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBoxMulti) @@ -597,7 +625,7 @@ f_count += 1 which_sizer = self.tabsizer[ f['guisection'] ] which_panel = self.tab[ f['guisection'] ] - title = escape_ampersand(f['description']) + title = text_beautify(f['description']) self.chk = wx.CheckBox(which_panel,-1, label = title, style = wx.NO_BORDER) self.chk.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, '')) which_sizer.Add(self.chk, 0, wx.EXPAND| wx.ALL, 5) @@ -614,6 +642,7 @@ minsecsizes = self.tabsizer[section].GetMinSize() maxsizes = map( lambda x: max( maxsizes[x], minsecsizes[x] ), (0,1) ) + # TODO: be less arbitrary with these 600 constrained_size = (min(600, maxsizes[0]), min(600, maxsizes[1]) ) for section in sections: self.tab[section].SetMinSize( constrained_size ) @@ -636,6 +665,8 @@ self.getValues() def updateStatusLine(self): + """If we were part of a richer interface, report back the current command being built.""" + # TODO: don't tie this to a StatusLine try: self.GetParent().SetStatusText( self.createCmd(ignoreErrors = True) ) except: @@ -692,7 +723,11 @@ self.updateStatusLine() def createCmd(self, ignoreErrors = False): - """Produce a command line string for feeding into GRASS.""" + """Produce a command line string for feeding into GRASS. + + If ignoreErrors==True then it will return whatever has been + built so far, even though it would not be a correct command + for GRASS.""" cmd = self.task.name errors = 0 errStr = "" @@ -712,6 +747,10 @@ return cmd def getInterfaceDescription( cmd ): + """Returns the XML description for the GRASS cmd. + + The DTD must be located in $GISBASE/etx/wx/gui_modules/grass-interface.dtd, + otherwise the parser will not succeed.""" gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules" cmd = cmd + r' --interface-description' cmdout = os.popen(cmd, "r").read() @@ -721,6 +760,7 @@ return cmdout class GrassGUIApp(wx.App): + """Stand-alone GRASS command GUI""" def __init__(self, cmd): self.grass_task = grassTask() handler = processTask(self.grass_task) From cepicky at grass.itc.it Wed Mar 28 09:33:39 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Wed Mar 28 09:33:49 2007 Subject: [grass-addons] r347 - trunk/grassaddons/gui/gui_modules Message-ID: <200703280733.l2S7XdIO012439@grass.itc.it> Author: cepicky Date: 2007-03-28 09:33:05 +0200 (Wed, 28 Mar 2007) New Revision: 347 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: reodreding order of imports and paths Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 01:31:50 UTC (rev 346) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 07:33:05 UTC (rev 347) @@ -51,9 +51,11 @@ import os from os import system + try: import subprocess except: + sys.path.append(os.path.join(os.getenv("GISBASE"),"etc","wx")) from compat import subprocess import re From landa at grass.itc.it Wed Mar 28 09:50:50 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Mar 28 09:51:00 2007 Subject: [grass-addons] r348 - trunk/grassaddons/gui Message-ID: <200703280750.l2S7ooC5013775@grass.itc.it> Author: landa Date: 2007-03-28 09:49:33 +0200 (Wed, 28 Mar 2007) New Revision: 348 Modified: trunk/grassaddons/gui/wxgrass Log: check if GRASS is running Modified: trunk/grassaddons/gui/wxgrass =================================================================== --- trunk/grassaddons/gui/wxgrass 2007-03-28 07:33:05 UTC (rev 347) +++ trunk/grassaddons/gui/wxgrass 2007-03-28 07:49:33 UTC (rev 348) @@ -1,14 +1,16 @@ #!/bin/sh +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." 1>&2 + exit 1 +fi + SYSTEM=`uname -s` + if [ "$SYSTEM" = "Darwin" ] ; then pythonw "$GISBASE/etc/wx/wxgui.py" -name wxgui_py else python "$GISBASE/etc/wx/wxgui.py" -name wxgui_py fi - - - - - +exit 0 From cepicky at grass.itc.it Wed Mar 28 10:18:19 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Wed Mar 28 10:18:23 2007 Subject: [grass-addons] r349 - trunk/grassaddons/gui/gui_modules Message-ID: <200703280818.l2S8IJYb013894@grass.itc.it> Author: cepicky Date: 2007-03-28 10:18:10 +0200 (Wed, 28 Mar 2007) New Revision: 349 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: reodreding order of imports and paths Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 07:49:33 UTC (rev 348) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 08:18:10 UTC (rev 349) @@ -326,6 +326,7 @@ The command is checked and sent to the clipboard when clicking "Copy". """ def __init__(self, parent, ID, task_description, get_dcmd=None, layer=None, dcmd_params=None): + print parent self.get_dcmd = get_dcmd self.dcmd_params = dcmd_params #this should be passed from the layer tree eventually From cepicky at grass.itc.it Wed Mar 28 10:19:40 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Wed Mar 28 10:19:43 2007 Subject: [grass-addons] r350 - trunk/grassaddons/gui/gui_modules Message-ID: <200703280819.l2S8JeiZ013914@grass.itc.it> Author: cepicky Date: 2007-03-28 10:19:39 +0200 (Wed, 28 Mar 2007) New Revision: 350 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: small bug fixed Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 08:18:10 UTC (rev 349) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 08:19:39 UTC (rev 350) @@ -326,7 +326,6 @@ The command is checked and sent to the clipboard when clicking "Copy". """ def __init__(self, parent, ID, task_description, get_dcmd=None, layer=None, dcmd_params=None): - print parent self.get_dcmd = get_dcmd self.dcmd_params = dcmd_params #this should be passed from the layer tree eventually @@ -802,7 +801,7 @@ handler = processTask(self.grass_task) xml.sax.parseString( getInterfaceDescription( cmd ) , handler ) - self.mf = mainFrame(self.parent ,-1, grass_task, self.get_dcmd, layer) + self.mf = mainFrame(self.parent ,-1, self.grass_task, self.get_dcmd, layer) self.mf.Show(True) if __name__ == "__main__": From cepicky at grass.itc.it Wed Mar 28 10:37:28 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Wed Mar 28 10:37:37 2007 Subject: [grass-addons] r351 - trunk/grassaddons/gui/gui_modules Message-ID: <200703280837.l2S8bS6B014391@grass.itc.it> Author: cepicky Date: 2007-03-28 10:36:10 +0200 (Wed, 28 Mar 2007) New Revision: 351 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: removed _("text") from GMConsole. How is this supposed to work? Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-28 08:19:39 UTC (rev 350) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-28 08:36:10 UTC (rev 351) @@ -37,9 +37,6 @@ disp=None, log=None): CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style,ctstyle) - # we need this only for GIS Manager, but not for e.g. mapdisp - import menuform - self.SetAutoLayout(True) self.SetGradientStyle(1) self.EnableSelectionGradient(True) @@ -634,8 +631,8 @@ global goutput goutput = self.cmd_output - self.console_clear = wx.Button(self, -1, _("Clear")) - self.console_save = wx.Button(self, -1, _("Save")) + self.console_clear = wx.Button(self, -1, "Clear") + self.console_save = wx.Button(self, -1, "Save") self.console_progressbar = wx.Gauge(self, -1, 100, (110, 50), (250, 25)) From cepicky at grass.itc.it Wed Mar 28 11:09:19 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Wed Mar 28 11:09:29 2007 Subject: [grass-addons] r352 - trunk/grassaddons/gui/gui_modules Message-ID: <200703280909.l2S99Jpb015737@grass.itc.it> Author: cepicky Date: 2007-03-28 11:07:43 +0200 (Wed, 28 Mar 2007) New Revision: 352 Modified: trunk/grassaddons/gui/gui_modules/menuform.py trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: menuform should now work completely as stand-alone gui Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 08:36:10 UTC (rev 351) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 09:07:43 UTC (rev 352) @@ -278,7 +278,6 @@ self.param_guisection = normalize_whitespace(self.param_guisection) self.inGuisection = 0 - class helpPanel(wx.html.HtmlWindow): """This panel holds the text from GRASS docs. @@ -359,7 +358,16 @@ self.SetMenuBar(menuBar) self.guisizer = wx.BoxSizer(wx.VERTICAL) - self.notebookpanel = cmdPanel( self, self.task ) + # set apropriate output window + if self.parent: + standalone=False + self.goutput = self.parent.goutput + else: + standalone=True + self.notebookpanel = cmdPanel( self, self.task, standalone) + if standalone: + self.goutput = self.notebookpanel.goutput + self.guisizer.Add( self.notebookpanel, 1, flag = wx.EXPAND ) status_text = "Enter parameters for " + self.task.name @@ -425,24 +433,23 @@ cmd = self.createCmd() if cmd != None and cmd[0:2] != "d.": - # Send any non-display command to parent window (probably wxgui.py) - if self.parent > -1: - # put to parents - try: - self.parent.goutput.runCmd(cmd) - except AttributeError,e: - print >>sys.stderr, "%s: Propably not running in wxgui.py session?" % (e) - print >>sys.stderr, "parent window is: %s" % (str(self.parent)) + # Send any non-display command to parent window (probably wxgui.py) + # put to parents + try: + self.goutput.runCmd(cmd) + except AttributeError,e: + print >>sys.stderr, "%s: Propably not running in wxgui.py session?" % (e) + print >>sys.stderr, "parent window is: %s" % (str(self.parent)) # Send any other command to the shell. - else: - try: - retcode = subprocess.call(cmd, shell=True) - if retcode < 0: - print >>sys.stderr, "Child was terminated by signal", -retcode - elif retcode > 0: - print >>sys.stderr, "Child returned", retcode - except OSError, e: - print >>sys.stderr, "Execution failed:", e + else: + try: + retcode = subprocess.call(cmd, shell=True) + if retcode < 0: + print >>sys.stderr, "Child was terminated by signal", -retcode + elif retcode > 0: + print >>sys.stderr, "Child returned", retcode + except OSError, e: + print >>sys.stderr, "Execution failed:", e def OnCopy(self, event): cmddata = wx.TextDataObject() @@ -487,7 +494,7 @@ class cmdPanel(wx.Panel): """A panel containing a notebook dividing in tabs the different guisections of the GRASS cmd.""" - def __init__( self, parent, task, *args, **kwargs ): + def __init__( self, parent, task, standalone, *args, **kwargs ): wx.Panel.__init__( self, parent, *args, **kwargs ) self.task = task @@ -526,11 +533,18 @@ self.notebook.AddPage( self.tab[section], text = section, select = is_first ) is_first = False + # are we running from command line? + if standalone: + from gui_modules import wxgui_utils + self.goutput = wxgui_utils.GMConsole(self) + self.outpage = self.notebook.AddPage(self.goutput, text="Command output") + manual_tab = helpPanel( self.notebook, id = wx.ID_ANY, grass_command = self.task.name) if manual_tab.Ok: manual_tabsizer = wx.BoxSizer(wx.VERTICAL) self.notebook.AddPage( manual_tab, text = "Manual" , select = False ) + self.notebook.SetSelection(0) self.panelsizer.Add( self.notebook, 1, flag=wx.EXPAND ) p_count = -1 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-28 08:36:10 UTC (rev 351) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-28 09:07:43 UTC (rev 352) @@ -688,8 +688,12 @@ cmdlst = [] # cmd = self.console_command.GetLineText(0) cmdlst = cmd.split(' ') - disp_idx = int(track.Track().GetDisp()[0]) - curr_disp = track.Track().GetDisp()[1] + try: + disp_idx = int(track.Track().GetDisp()[0]) + curr_disp = track.Track().GetDisp()[1] + except: + disp_idx = None + curr_disp = None if len(cmdlst) == 1 and cmd in gcmdlst: # Send GRASS command without arguments to GUI command interface From cepicky at grass.itc.it Wed Mar 28 11:39:59 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Wed Mar 28 11:40:01 2007 Subject: [grass-addons] r353 - trunk/grassaddons/gui/gui_modules Message-ID: <200703280939.l2S9dxm3015803@grass.itc.it> Author: cepicky Date: 2007-03-28 11:39:59 +0200 (Wed, 28 Mar 2007) New Revision: 353 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: progress bar now moving, messages written to output Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-28 09:07:43 UTC (rev 352) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-28 09:39:59 UTC (rev 353) @@ -2,6 +2,7 @@ import wx import wx.lib.customtreectrl as CT import wx.combo +import string import track import select @@ -748,18 +749,22 @@ try: os.environ["GRASS_MESSAGE_FORMAT"] = "gui" self.cmd_output.write(cmd+"\n----------\n") - p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) + p = Popen(cmd +" --verbose", shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) oline = p.stderr.readline() while oline: oline = oline.strip() - print "MSG: ", oline - print >> sys.stderr, oline+"#####" oline = p.stderr.readline() # make some progress #GRASS_INFO_PERCENT: 100 if oline.find("GRASS_INFO_PERCENT")>-1: self.console_progressbar.SetValue(int(oline.split()[1])) + elif oline.find("GRASS_INFO_MESSAGE")>-1: + self.cmd_output.write(string.split(oline,maxsplit=1)[1]+"\n") + elif oline.find("GRASS_INFO_WARNING")>-1: + self.cmd_output.write("WARNING: "+string.split(oline,maxsplit=1)[1]+"\n") + elif oline.find("GRASS_INFO_ERROR")>-1: + self.cmd_output.write("ERROR: "+string.split(oline,maxsplit=1)[1]+"\n") oline = p.stdout.readline() @@ -780,6 +785,7 @@ def clearHistory(self, event): self.cmd_output.Clear() + self.console_progressbar.SetValue(0) def saveHistory(self, event): self.history = self.cmd_output.GetStringSelection() From chemin at grass.itc.it Wed Mar 28 13:59:01 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Wed Mar 28 13:59:03 2007 Subject: [grass-addons] r354 - trunk/grassaddons/gipe Message-ID: <200703281159.l2SBx1Zo017805@grass.itc.it> Author: chemin Date: 2007-03-28 13:58:56 +0200 (Wed, 28 Mar 2007) New Revision: 354 Modified: trunk/grassaddons/gipe/gmmenu.tcl Log: Updated tcltk menu with r.evapo.PT Modified: trunk/grassaddons/gipe/gmmenu.tcl =================================================================== --- trunk/grassaddons/gipe/gmmenu.tcl 2007-03-28 09:39:59 UTC (rev 353) +++ trunk/grassaddons/gipe/gmmenu.tcl 2007-03-28 11:58:56 UTC (rev 354) @@ -394,7 +394,7 @@ } {[G_msg "&Vector"]} all options $tmenu { {cascad {[G_msg "Develop map"]} {} "" $tmenu { - {command {[G_msg "Digitize"]} {} "v.digit" {} -command {guarantee_xmon; execute v.digit }} + {command {[G_msg "Digitize"]} {} "v.digit" {} -command {execute v.digit }} {separator} {command {[G_msg "Create/rebuild topology"]} {} "v.build" {} -command {execute v.build }} {command {[G_msg "Clean vector files"]} {} "v.clean" {} -command {execute v.clean }} @@ -409,17 +409,12 @@ {command {[G_msg "Convert 2D vector to 3D by sampling raster"]} {} "v.drape" {} -command {execute v.drape }} {command {[G_msg "Extrude 2D vector into 3D vector"]} {} "v.extrude" {} -command {execute v.extrude }} {separator} + {command {[G_msg "Create new vector as link to external OGR layer"]} {} "v.external" {} -command {execute v.external }} + {separator} {command {[G_msg "Create text label file for vector features"]} {} "v.label" {} -command {execute v.label }} {separator} {command {[G_msg "Reproject vector from other location"]} {} "v.proj" {} -command {execute v.proj }} }} - {cascad {[G_msg "Vector<->database connections"]} {} "" $tmenu { - {command {[G_msg "Create and add new attribute table to vector map"]} {} "v.db.addtable" {} -command {execute v.db.addtable }} - {command {[G_msg "Create new vector as link to external OGR layer"]} {} "v.external" {} -command {execute v.external }} - {command {[G_msg "Reconnect vector map to attribute database"]} {} "v.db.reconnect.all" {} -command {execute v.db.reconnect.all }} - {command {[G_msg "Remove existing table for vector map"]} {} "v.db.droptable" {} -command {execute v.db.droptable }} - {command {[G_msg "Set database connection for vector attributes"]} {} "v.db.connect" {} -command {execute v.db.connect }} - }} {command {[G_msg "Rectify and georeference vector map"]} {} "v.transform" {} -command {execute v.transform }} {separator} {command {[G_msg "Query by attributes"]} {} "v.extract" {} -command {execute v.extract }} @@ -441,13 +436,13 @@ {cascad {[G_msg "Neighborhood analysis"]} {} "" $tmenu { {command {[G_msg "Locate nearest features to points or centroids"]} {} "v.distance" {} -command {execute v.distance }} {command {[G_msg "Generate Thiessen polygons around points (Voronoi diagram)"]} {} "v.voronoi" {} -command {execute v.voronoi }} - {command {[G_msg "Connect points to create Delaunay triangles"]} {} "v.delauney" {} -command {execute v.delaunay }} + {command {[G_msg "Connect points to create Delaunay triangles"]} {} "v.delaunay" {} -command {execute v.delaunay }} }} {cascad {[G_msg "Network analysis"]} {} "" $tmenu { {command {[G_msg "Allocate subnets"]} {} "v.net.alloc" {} -command {execute v.net.alloc }} {command {[G_msg "Network maintenance"]} {} "v.net" {} -command {execute v.net }} {command {[G_msg "Shortest route"]} {} "v.net.path" {} -command {execute v.net.path }} - {command {[G_msg "Shortest route (visualization only)"]} {} "d.path" {} -command {guarantee_xmon; execute d.path }} + {command {[G_msg "Shortest route (visualization only)"]} {} "d.path" {} -command {guarantee_xmon; spawn d.path.sh -b --ui }} {command {[G_msg "Split net to bands between cost isolines"]} {} "v.net.iso" {} -command {execute v.net.iso }} {command {[G_msg "Steiner tree"]} {} "v.net.steiner" {} -command {execute v.net.steiner }} {command {[G_msg "Traveling salesman analysis"]} {} "v.net.salesman" {} -command {execute v.net.salesman }} @@ -568,9 +563,12 @@ {command {[G_msg "Connect to database"]} {} "db.connect" {} -command {execute db.connect }} {command {[G_msg "Login to database"]} {} "db.login" {} -command {execute db.login }} {separator} + {command {[G_msg "Create and add new attribute table to vector map"]} {} "v.db.addtable" {} -command {execute v.db.addtable }} {command {[G_msg "Copy table"]} {} "db.copy" {} -command {execute db.copy }} {command {[G_msg "Add columns to table"]} {} "v.db.addcol" {} -command {execute v.db.addcol }} {command {[G_msg "Change values in a column"]} {} "v.db.update" {} -command {execute v.db.update }} + {command {[G_msg "Remove existing table for vector map"]} {} "v.db.droptable" {} -command {execute v.db.droptable }} + {separator} {command {[G_msg "Test database"]} {} "db.test" {} -command {execute db.test }} }} {cascad {[G_msg "Database information"]} {} "" $tmenu { @@ -581,9 +579,14 @@ }} {separator} {cascad {[G_msg "Query"]} {} "" $tmenu { - {command {[G_msg "Query data (SQL select)"]} {} "db.select" {} -command {execute db.select }} + {command {[G_msg "Query data in any table"]} {} "db.select" {} -command {execute db.select }} + {command {[G_msg "Query vector attribute data"]} {} "db.select" {} -command {execute v.db.select }} {command {[G_msg "Execute SQL statement"]} {} "db.execute" {} -command {execute db.execute }} }} + {cascad {[G_msg "Vector<->database connections"]} {} "" $tmenu { + {command {[G_msg "Reconnect vector map to attribute database"]} {} "v.db.reconnect.all" {} -command {execute v.db.reconnect.all }} + {command {[G_msg "Set database connection for vector attributes"]} {} "v.db.connect" {} -command {execute v.db.connect }} + }} } {[G_msg "&USLE"]} all options $tmenu { {command {[G_msg "USLE R"]} {} "r.usler" {} -command {execute r.usler }} @@ -609,10 +612,11 @@ {command {[G_msg "Satellite overpass time"]} {} "r.sattime" {} -command {execute r.sattime }} }} {separator} - {cascad {[G_msg "ETP & ETa"]} {} "" $tmenu { + {cascad {[G_msg "ETP and ETa"]} {} "" $tmenu { {command {[G_msg "Potential ET (Radiative)"]} {} "r.evapo.potrad" {} -command {execute r.evapo.potrad }} {command {[G_msg "Potential ET (Radiative) from L7DN (.met)"]} {} "r.dn2potrad.l7" {} -command {execute r.dn2potrad.l7 }} {command {[G_msg "Potential ET (Penman-Monteith)"]} {} "r.evapo.PM" {} -command {execute r.evapo.PM }} + {command {[G_msg "Potential ET (Prestley and Taylor)"]} {} "r.evapo.PT" {} -command {execute r.evapo.PT }} {separator} {command {[G_msg "Actual ET (SEBAL)"]} {} "r.eb.eta" {} -command {execute r.eb.eta }} {command {[G_msg "Actual ET (TSA)"]} {} "r.evapo.TSA" {} -command {execute r.evapo.TSA }} From landa at grass.itc.it Wed Mar 28 16:52:34 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Mar 28 16:52:35 2007 Subject: [grass-addons] r355 - trunk/grassaddons/gui/scripts Message-ID: <200703281452.l2SEqYCo020417@grass.itc.it> Author: landa Date: 2007-03-28 16:52:15 +0200 (Wed, 28 Mar 2007) New Revision: 355 Modified: trunk/grassaddons/gui/scripts/p.mon Log: export PYTHONPATH Modified: trunk/grassaddons/gui/scripts/p.mon =================================================================== --- trunk/grassaddons/gui/scripts/p.mon 2007-03-28 11:58:56 UTC (rev 354) +++ trunk/grassaddons/gui/scripts/p.mon 2007-03-28 14:52:15 UTC (rev 355) @@ -64,8 +64,14 @@ # CODE GOES HERE +PYTHONPATH="$GISBASE/etc/wx" + +export PYTHONPATH + # create the command file command_file="`g.tempfile pid=$$`" g.gisenv set=GRASS_PYCMDFILE=${command_file} -python gui_modules/mapdisp.py ${command_file} & +python $PYTHONPATH/gui_modules/mapdisp.py ${command_file} & + +exit 0 From landa at grass.itc.it Wed Mar 28 20:28:02 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Mar 28 20:28:03 2007 Subject: [grass-addons] r356 - trunk/grassaddons/gui/scripts Message-ID: <200703281828.l2SIS2Dv021805@grass.itc.it> Author: landa Date: 2007-03-28 20:27:45 +0200 (Wed, 28 Mar 2007) New Revision: 356 Modified: trunk/grassaddons/gui/scripts/p.mon Log: only start= implemented Modified: trunk/grassaddons/gui/scripts/p.mon =================================================================== --- trunk/grassaddons/gui/scripts/p.mon 2007-03-28 14:52:15 UTC (rev 355) +++ trunk/grassaddons/gui/scripts/p.mon 2007-03-28 18:27:45 UTC (rev 356) @@ -29,7 +29,7 @@ #% type: string #% required: no #% multiple: no -#% description: Name of graphics monitor to start (p0-pX) +#% description: Name of graphics monitor to start (p0-p9) #%End #%Option #% key: stop @@ -68,10 +68,21 @@ export PYTHONPATH +start="$GIS_OPT_START" +select="$GIS_OPT_SELECT" +stop="$GIS_OPT_STOP" +unlock="$GIS_OPT_UNLOCK" + # create the command file command_file="`g.tempfile pid=$$`" g.gisenv set=GRASS_PYCMDFILE=${command_file} -python $PYTHONPATH/gui_modules/mapdisp.py ${command_file} & +if [ -n "$start" ] ; then + python $PYTHONPATH/gui_modules/mapdisp.py "$start" ${command_file} & +fi +if [[ -n "$stop" || -n "$select" || -n "$unlock" ]] ; then + g.message -w "Not implemented yet" +fi + exit 0 From landa at grass.itc.it Wed Mar 28 20:29:20 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Mar 28 20:29:22 2007 Subject: [grass-addons] r357 - trunk/grassaddons/gui/gui_modules Message-ID: <200703281829.l2SITKkh021830@grass.itc.it> Author: landa Date: 2007-03-28 20:29:00 +0200 (Wed, 28 Mar 2007) New Revision: 357 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: monitor-identifier added (see p.mon) Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-28 18:27:45 UTC (rev 356) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-28 18:29:00 UTC (rev 357) @@ -2,7 +2,7 @@ To be used either from GIS Manager or as p.mon backend Usage: - mapdisp.py /path/to/command/file + python mapdisp.py monitor-identifier /path/to/command/file mapdisp Package @@ -797,28 +797,16 @@ def OnInit(self): wx.InitAllImageHandlers() - self.Mapfrm = MapFrame(parent=None, id=wx.ID_ANY) + self.mapFrm = MapFrame(parent=None, id=wx.ID_ANY) #self.SetTopWindow(Map) - self.Mapfrm.Show() + self.mapFrm.Show() - # only for testing purpose - if __name__ == "__main__": - - # redraw map, if new command appears - self.redraw = False - status = Command(self,Map) - status.start() - self.timer = wx.PyTimer(self.watcher) - # chec each 0.1s - self.timer.Start(100) - - return 1 def watcher(self): """Redraw, if new layer appears""" if self.redraw: - self.Mapfrm.ReDraw(None) + self.mapFrm.ReDraw(None) self.redraw = False return @@ -828,11 +816,12 @@ if __name__ == "__main__": ###### SET command variable - if len(sys.argv) != 2: + if len(sys.argv) != 3: print __doc__ sys.exit() - cmdfilename = sys.argv[1] + title = sys.argv[1] + cmdfilename = sys.argv[2] import gettext gettext.install("gm_map") # replace with the appropriate catalog name @@ -841,11 +830,19 @@ if not os.getenv("GRASS_ICONPATH"): os.environ["GRASS_ICONPATH"]=os.getenv("GISBASE")+"/etc/gui/icons/" + print "Starting monitor <%s>" % (title) + gm_map = MapApp(0) + # set title + gm_map.mapFrm.SetTitle ("Map display " + title) gm_map.MainLoop() + if grassenv.env.has_key("MONITOR"): os.system("d.mon sel=%s" % grassenv.env["MONITOR"]) os.remove(cmdfilename) os.system("""g.gisenv set="GRASS_PYCMDFILE" """) + print "Stoping monitor <%s>" % (title) + + sys.exit() From barton at grass.itc.it Wed Mar 28 20:55:06 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Wed Mar 28 20:55:07 2007 Subject: [grass-addons] r358 - trunk/grassaddons/gui/gui_modules Message-ID: <200703281855.l2SIt6XW021883@grass.itc.it> Author: barton Date: 2007-03-28 20:54:59 +0200 (Wed, 28 Mar 2007) New Revision: 358 Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: Typing a command on the GIS Manager command line with no arguments will launch the command module in standalone mode (unless it is a d.* command). Commands with arguments will be processed and output will go to the GIS Manager output console. Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-28 18:29:00 UTC (rev 357) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-28 18:54:59 UTC (rev 358) @@ -726,7 +726,7 @@ layertree.AddLayer(disp_idx, layertype) else: - menuform.GUI().parseCommand(cmd, gmpath, parentframe=self) + menuform.GUI().parseCommand(cmd, gmpath, parentframe=None) self.cmd_output.write(cmdlst[0] + "\n----------\n") From landa at grass.itc.it Wed Mar 28 21:15:16 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Mar 28 21:15:18 2007 Subject: [grass-addons] r359 - in trunk/grassaddons/gui: gui_modules scripts Message-ID: <200703281915.l2SJFG9a021920@grass.itc.it> Author: landa Date: 2007-03-28 21:14:54 +0200 (Wed, 28 Mar 2007) New Revision: 359 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/scripts/p.rast Log: revert, terminate thread when OnExit() is called Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-28 18:54:59 UTC (rev 358) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-28 19:14:54 UTC (rev 359) @@ -41,10 +41,11 @@ Map = render.Map() # instance of Map class to render GRASS display output to PPM file DEBUG = False -# for cmdline -from threading import Thread -import time -cmdfilename = None +# for cmdlinef +if __name__ == "__main__": + from threading import Thread + import time + cmdfilename = None class Command(Thread): """ @@ -801,8 +802,24 @@ #self.SetTopWindow(Map) self.mapFrm.Show() + if __name__ == "__main__": + # redraw map, if new command appears + self.redraw = False + status = Command(self, Map) + status.start() + self.timer = wx.PyTimer(self.watcher) + # check each 0.1s + self.timer.Start(100) + return 1 + def OnExit(self): + if __name__ == "__main__": + # stop the timer + self.timer.Stop() + # terminate thread (a bit ugly) + os.system("""echo "quit" >> %s""" % (cmdfilename)) + def watcher(self): """Redraw, if new layer appears""" if self.redraw: Modified: trunk/grassaddons/gui/scripts/p.rast =================================================================== --- trunk/grassaddons/gui/scripts/p.rast 2007-03-28 18:54:59 UTC (rev 358) +++ trunk/grassaddons/gui/scripts/p.rast 2007-03-28 19:14:54 UTC (rev 359) @@ -58,7 +58,7 @@ if [ -e ${cmdfile} ] && [ -n "${cmdfile}" ]; then echo -n else - echo "WARNING: GRASS_PYCMDFILE File not existing. Run p.mon" >&2 + g.message -e "GRASS_PYCMDFILE File not found. Run p.mon" exit 1 fi From landa at grass.itc.it Wed Mar 28 21:38:35 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Mar 28 21:38:37 2007 Subject: [grass-addons] r360 - trunk/grassaddons/gui/gui_modules Message-ID: <200703281938.l2SJcZqs021969@grass.itc.it> Author: landa Date: 2007-03-28 21:38:23 +0200 (Wed, 28 Mar 2007) New Revision: 360 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: import threading moved, broken wxgrass Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-28 19:14:54 UTC (rev 359) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-28 19:38:23 UTC (rev 360) @@ -31,6 +31,8 @@ imagepath = images.__path__[0] sys.path.append(imagepath) +from threading import Thread + icons = "" if not os.getenv("GRASS_ICONPATH"): @@ -43,7 +45,7 @@ # for cmdlinef if __name__ == "__main__": - from threading import Thread + import time cmdfilename = None @@ -89,9 +91,13 @@ except: pass opacity = float(dispcmd[6]) + print "# %s" % dispcmd[3] + self.map.AddRasterLayer(name="%s" % (dispcmd[1]), - mapset=dispcmd[2], vallist=vallist, - l_opacity=opacity) + mapset=dispcmd[2], + catlist=1, + vallist=vallist, + l_opacity=opacity) if dispcmd[0]=="addvector": self.map.AddVectorLayer(name="%s" % (dispcmd[1]), From landa at grass.itc.it Wed Mar 28 21:44:47 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Mar 28 21:44:47 2007 Subject: [grass-addons] r361 - trunk/grassaddons/gui/gui_modules Message-ID: <200703281944.l2SJilcd022012@grass.itc.it> Author: landa Date: 2007-03-28 21:44:33 +0200 (Wed, 28 Mar 2007) New Revision: 361 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: time package already imported Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-28 19:38:23 UTC (rev 360) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-28 19:44:33 UTC (rev 361) @@ -44,11 +44,8 @@ DEBUG = False # for cmdlinef -if __name__ == "__main__": +cmdfilename = None - import time - cmdfilename = None - class Command(Thread): """ Creates thread, which will observe the command file and see, if there From barton at grass.itc.it Wed Mar 28 22:48:48 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Wed Mar 28 22:48:49 2007 Subject: [grass-addons] r362 - trunk/grassaddons/gui Message-ID: <200703282048.l2SKmmve022154@grass.itc.it> Author: barton Date: 2007-03-28 22:48:41 +0200 (Wed, 28 Mar 2007) New Revision: 362 Modified: trunk/grassaddons/gui/gis_set.py Log: Multiple bug fixes: creating new mapset correctly sets permissions (I hope). Location and mapset windows update properly now. GIS Database selection now works properly. Modified: trunk/grassaddons/gui/gis_set.py =================================================================== --- trunk/grassaddons/gui/gis_set.py 2007-03-28 19:44:33 UTC (rev 361) +++ trunk/grassaddons/gui/gis_set.py 2007-03-28 20:48:41 UTC (rev 362) @@ -450,14 +450,15 @@ # Locations self.lpanel = wx.Panel(self,-1) self.lblocations = wx.ListBox(self.lpanel, - 26, wx.DefaultPosition, (150, 200), self.listOfLocations, wx.LB_SINGLE) + id=26, pos=wx.DefaultPosition, size=(150, 200), + choices=self.listOfLocations, style=wx.LB_SINGLE) # Mapsets self.mpanel = wx.Panel(self,-1) self.lbmapsets = wx.ListBox(self.mpanel, - 26, wx.DefaultPosition, (150, 200), self.listOfMapsets, wx.LB_SINGLE) + id=26, pos=wx.DefaultPosition, size=(150, 200), + choices=self.listOfMapsets, style=wx.LB_SINGLE) - # layout & properties self.__set_properties() self.__do_layout() @@ -489,20 +490,25 @@ #self.bmapset.Enable(False) # set database - if not self.gisdbase: self.gisdbase = os.getenv("HOME") + if not self.gisdbase: + # sets an initial path for gisdbase if nothing in GISRC + if os.path.isdir(os.getenv("HOME")): + self.gisdbase = os.getenv("HOME") + else: + self.gisdbase = os.getcwd() self.tgisdbase.SetValue(self.gisdbase) - # list of locations - self.UpdateLocations(self.tgisdbase.GetValue()) self.OnSetDatabase(None) location = self._getRCValue("LOCATION_NAME") if location == "": location = None if location: + # list of locations + self.UpdateLocations(self.gisdbase) self.lblocations.SetSelection(self.listOfLocations.index(location)) # list of mapsets - self.UpdateMapsets(os.path.join(self.tgisdbase.GetValue(),self.listOfLocations[0])) + self.UpdateMapsets(os.path.join(self.gisdbase,location)) mapset =self._getRCValue("MAPSET") if mapset: self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset)) @@ -607,11 +613,12 @@ self.listOfLocations = [] for location in glob.glob(os.path.join(dbase,"*")): try: - glob.glob(os.path.join(location,"*")).index(os.path.join(location,"PERMANENT")) - self.listOfLocations.append(os.path.basename(location)) + if os.path.join(location,"PERMANENT") in glob.glob(os.path.join(location,"*")): + self.listOfLocations.append(os.path.basename(location)) except: pass - self.listOfLocations + self.lblocations.Clear() + self.lblocations.InsertItems(self.listOfLocations,0) return self.listOfLocations def UpdateMapsets(self,location): @@ -620,12 +627,14 @@ for mapset in glob.glob(os.path.join(location,"*")): if os.path.isdir(mapset): self.listOfMapsets.append(os.path.basename(mapset)) + self.lbmapsets.Clear() + self.lbmapsets.InsertItems(self.listOfMapsets,0) return self.listOfMapsets def OnSelectLocation(self,event): if self.lblocations.GetSelection() > -1: self.UpdateMapsets(os.path.join( - self.tgisdbase.GetValue(),self.listOfLocations[self.lblocations.GetSelection()])) + self.gisbase,self.listOfLocations[self.lblocations.GetSelection()])) else: self.listOfMapsets = [] self.lbmapsets.Clear() @@ -636,10 +645,11 @@ pass def OnSetDatabase(self,event): - self.UpdateLocations(self.tgisdbase.GetValue()) + self.gisbase = self.tgisdbase.GetValue() + self.UpdateLocations(self.gisbase) self.lblocations.Clear() self.lblocations.InsertItems(self.listOfLocations,0) - self.lblocations.SetSelection(0) + if self.listOfLocations != []: self.lblocations.SetSelection(0) self.OnSelectLocation(event) def OnBrowse(self, event): @@ -649,8 +659,8 @@ dlg = wx.DirDialog(self, "Choose a GRASS directory:", style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON) if dlg.ShowModal() == wx.ID_OK: - grassdata = dlg.GetDirectory() - self.tgisdbase.SetValue(grassdata) + self.gisbase = dlg.GetPath() + self.tgisdbase.SetValue(self.gisbase) dlg.Destroy() self.OnSetDatabase(event) @@ -662,16 +672,16 @@ event.Skip() def OnCreateMapset(self,event): - database = self.tgisdbase.GetValue() + self.gisbase = self.tgisdbase.GetValue() location = self.listOfLocations[self.lblocations.GetSelection()] try: mapset = self.tnewmapset.GetValue() - os.mkdir(os.path.join(database,location,mapset)) + os.mkdir(os.path.join(self.gisbase,location,mapset)) # copy WIND file and its permissions from PERMANENT and set permissions to u+rw,go+r - shutil.copy(os.path.join(database,location,'PERMANENT','WIND'), - os.path.join(database,location,mapset)) -# os.chmod(os.path.join(database,location,mapset,'WIND'), ?????) + shutil.copy(os.path.join(self.gisbase,location,'PERMANENT','WIND'), + os.path.join(self.gisbase,location,mapset)) +# os.chmod(os.path.join(database,location,mapset,'WIND'), 0644) self.OnSelectLocation(None) self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset)) except StandardError, e: From barton at grass.itc.it Wed Mar 28 23:53:11 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Wed Mar 28 23:53:12 2007 Subject: [grass-addons] r363 - trunk/grassaddons/gui Message-ID: <200703282153.l2SLrBMA023185@grass.itc.it> Author: barton Date: 2007-03-28 23:53:04 +0200 (Wed, 28 Mar 2007) New Revision: 363 Modified: trunk/grassaddons/gui/wxgrass Log: Starting non-modally Modified: trunk/grassaddons/gui/wxgrass =================================================================== --- trunk/grassaddons/gui/wxgrass 2007-03-28 20:48:41 UTC (rev 362) +++ trunk/grassaddons/gui/wxgrass 2007-03-28 21:53:04 UTC (rev 363) @@ -8,9 +8,9 @@ SYSTEM=`uname -s` if [ "$SYSTEM" = "Darwin" ] ; then - pythonw "$GISBASE/etc/wx/wxgui.py" -name wxgui_py + pythonw "$GISBASE/etc/wx/wxgui.py" -name wxgui_py & else - python "$GISBASE/etc/wx/wxgui.py" -name wxgui_py + python "$GISBASE/etc/wx/wxgui.py" -name wxgui_py & fi exit 0 From barton at grass.itc.it Thu Mar 29 08:29:10 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Thu Mar 29 08:29:11 2007 Subject: [grass-addons] r364 - trunk/grassaddons/gui/gui_modules Message-ID: <200703290629.l2T6TA9m027645@grass.itc.it> Author: barton Date: 2007-03-29 08:29:01 +0200 (Thu, 29 Mar 2007) New Revision: 364 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: Update in prep for creating overlays (grids, scalebars, etc.) Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-28 21:53:04 UTC (rev 363) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-03-29 06:29:01 UTC (rev 364) @@ -357,13 +357,13 @@ self.SetMenuBar(menuBar) self.guisizer = wx.BoxSizer(wx.VERTICAL) - + # set apropriate output window - if self.parent: - standalone=False - self.goutput = self.parent.goutput - else: - standalone=True +# if self.parent: +# standalone=False +# self.goutput = self.parent.goutput +# else: + standalone=True self.notebookpanel = cmdPanel( self, self.task, standalone) if standalone: self.goutput = self.notebookpanel.goutput @@ -426,7 +426,7 @@ # return d.* command to layer tree for rendering self.get_dcmd(cmd, self.layer) # echo d.* command to output console - self.parent.writeDCommand(cmd) +# self.parent.writeDCommand(cmd) return cmd def OnRun(self, event): @@ -782,7 +782,7 @@ handler = processTask(self.grass_task) xml.sax.parseString( getInterfaceDescription( cmd ) , handler ) wx.App.__init__(self) - + def OnInit(self): self.mf = mainFrame(None ,-1, self.grass_task ) self.mf.Show(True) From barton at grass.itc.it Thu Mar 29 08:30:58 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Thu Mar 29 08:31:00 2007 Subject: [grass-addons] r365 - trunk/grassaddons/gui/gui_modules Message-ID: <200703290630.l2T6UwgK027669@grass.itc.it> Author: barton Date: 2007-03-29 08:30:44 +0200 (Thu, 29 Mar 2007) New Revision: 365 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/render.py trunk/grassaddons/gui/gui_modules/toolbars.py Log: Initial go at creating overlays to maps: grids, scalebars, etc. Works, but clunky. Also need to get the overlay png to have a transparent background. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-29 06:29:01 UTC (rev 364) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-29 06:30:44 UTC (rev 365) @@ -26,6 +26,7 @@ import toolbars import grassenv import track +import menuform import images imagepath = images.__path__[0] @@ -33,6 +34,9 @@ from threading import Thread +gmpath = os.getenv("GISBASE") + "/etc/wx/gui_modules/" +sys.path.append(gmpath) + icons = "" if not os.getenv("GRASS_ICONPATH"): @@ -153,6 +157,7 @@ # self.mapfile = None # image file to be rendered self.Img = "" # wx.Image object (self.mapfile) + self.ovlist = [] # list of images for overlays # # mouse attributes like currently pressed buttons, position on @@ -203,6 +208,7 @@ # get the image to be rendered self.Img = self.GetImage() + self.ovlist = self.GetOverlay() # update map display if self.Img and Map.width + Map.height > 0: # scale image during resize @@ -247,12 +253,20 @@ self.Img = self.GetImage() self.resize = False if not self.Img: return + self.ovlist = self.GetOverlay() dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) self.Draw(dc, self.Img) + if self.ovlist != []: + for overlay in self.ovlist: + self.Draw(dc, overlay) else: if not self.Img: return + self.ovlist = self.GetOverlay() dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) self.Draw(dc, self.Img) + if self.ovlist != []: + for overlay in self.ovlist: + self.Draw(dc, overlay) self.resize = False def EraseMap(self): @@ -347,16 +361,29 @@ # store current mouse position self.mouse['pos'] = event.GetPositionTuple()[:] + def GetOverlay(self): + """ + Converts overlay files to wx.Image + """ + ovlist = [] + if Map.ovlist: + for ovlfile in Map.ovlist: + if os.path.isfile(ovlfile) and os.path.getsize(ovlfile): + ovlist.append(wx.Image(ovlfile, wx.BITMAP_TYPE_ANY)) + + return ovlist + + def GetImage(self): """ Converts files to wx.Image """ if Map.mapfile and os.path.isfile(Map.mapfile) and \ os.path.getsize(Map.mapfile): - self.Img = wx.Image(Map.mapfile, wx.BITMAP_TYPE_ANY) + img = wx.Image(Map.mapfile, wx.BITMAP_TYPE_ANY) else: - self.Img = None - return self.Img + img = None + return img def Pixel2Cell(self, x, y): """ @@ -440,7 +467,7 @@ dc.EndDrawing() return bitmap = wx.BitmapFromImage(img) - dc.DrawBitmap(bitmap, 0, 0) # draw the composite map + dc.DrawBitmap(bitmap, 0, 0, True) # draw the composite map if dctype == 'box': # draw a box on top of the map dc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) @@ -517,6 +544,8 @@ for i in range(len(map_frame_statusbar_fields)): self.statusbar.SetStatusText(map_frame_statusbar_fields[i], i) + self.decmenu = '' #decorations menu + self.ovlchk = False # # Init map display @@ -709,37 +738,66 @@ def onDecoration(self, event): """Add decorations item menu""" point = wx.GetMousePosition() - decmenu = wx.Menu() + self.decmenu = wx.Menu() # Add items to the menu - addscale = wx.MenuItem(decmenu, -1,'Add scalebar and north arrow') - bmp = wx.Image(os.path.join(icons,'module-d.barscale.gif'), wx.BITMAP_TYPE_GIF) - bmp.Rescale(16, 16) - bmp = bmp.ConvertToBitmap() + addscale = wx.MenuItem(self.decmenu, -1,'Add scalebar and north arrow') +# bmp = wx.Image(os.path.join(icons,'module-d.barscale.gif'), wx.BITMAP_TYPE_GIF) +# bmp.Rescale(16, 16) +# bmp = bmp.ConvertToBitmap() + bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) addscale.SetBitmap(bmp) - decmenu.AppendItem(addscale) + self.decmenu.AppendItem(addscale) + Map.addOverlay(type=0, command='', l_active=False, l_render=True) self.Bind(wx.EVT_MENU, self.addBarscale, addscale) - addgrid = wx.MenuItem(decmenu, -1,'Add grid') - bmp = wx.Image(os.path.join(icons,'module-d.grid.gif'), wx.BITMAP_TYPE_GIF) - bmp.Rescale(16, 16) - bmp = bmp.ConvertToBitmap() + addgrid = wx.MenuItem(self.decmenu, -1,'Add grid') +# bmp = wx.Image(os.path.join(icons,'module-d.grid.gif'), wx.BITMAP_TYPE_GIF) +# bmp.Rescale(16, 16) +# bmp = bmp.ConvertToBitmap() + bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) addgrid.SetBitmap(bmp) - decmenu.AppendItem(addgrid) + self.decmenu.AppendItem(addgrid) + Map.addOverlay(type=1, command='', l_active=False, l_render=True) self.Bind(wx.EVT_MENU, self.addGrid, addgrid) # Popup the menu. If an item is selected then its handler # will be called before PopupMenu returns. - self.PopupMenu(decmenu) - decmenu.Destroy() + self.PopupMenu(self.decmenu,point) + self.decmenu.Destroy() - def addBarscale(self): - # need to run d.barscale options and then add the command - #to the top (last rendered) of the command stack + def addBarscale(self, event): + self.params = [] + layer = 0 + if self.ovlchk == True: + self.ovlchk = False + bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) + else: + self.ovlchk = True + bmp = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_OTHER, (16,16)) + menuform.GUI().parseCommand('d.barscale', gmpath, completed=(self.getOptData,layer,self.params), parentframe=None) pass - def addGrid(self): + def addGrid(self, event): + self.params = [] + layer = 1 + if self.ovlchk == True: + self.ovlchk = False + bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_TOOLBAR, (16,16)) + else: + self.ovlchk = True + bmp = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_TOOLBAR, (16,16)) + menuform.GUI().parseCommand('d.grid', gmpath, completed=(self.getOptData,layer,self.params), parentframe=None) + pass + def getOptData(self, dcmd, layer): + + print 'dcmd: ', dcmd + print 'layer: ', layer + print 'check: ', self.ovlchk + + Map.changeOverlay(type=layer, command=dcmd, l_active=self.ovlchk, l_render=False) + def OnAlignRegion(self, event): """ Align region Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-03-29 06:29:01 UTC (rev 364) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-03-29 06:30:44 UTC (rev 365) @@ -59,6 +59,7 @@ gtemp = utils.GetTempfile() self.maskfile = gtemp + ".pgm" self.mapfile = gtemp + ".ppm" + self.ovlfile = gtemp + ".png" def __renderRasterLayer(self): """ @@ -119,6 +120,19 @@ (self.name, str(e))) self.cmd = None + def __renderOverlay(self): + """ + Stores overlay command with all parameters in the self.cmd variable + """ + + try: + self.cmd = self.name + " --q" + + except StandardError, e: + sys.stderr.write("Could not render command layer <%s>: %s\n" %\ + (self.name, str(e))) + self.cmd = None + def Render(self): """ Runs all d.* commands. @@ -135,12 +149,18 @@ # # to be sure, set temporary file with layer and mask # - if not self.mapfile: - gtemp = utils.GetTempfile() - self.maskfile = gtemp + ".pgm" - self.mapfile = gtemp + ".ppm" + if self.type == 'overlay': + if not self.ovlfile: + gtemp = utils.GetTempfile() + self.ovlfile = gtemp + ".png" + else: + if not self.mapfile: + gtemp = utils.GetTempfile() + self.maskfile = gtemp + ".pgm" + self.mapfile = gtemp + ".ppm" + # # prepare command for each layer # @@ -153,6 +173,9 @@ elif self.type == "command": self.__renderCommandLayer() + elif self.type == "overlay": + self.__renderOverlay() + elif self.type == "wms": print "Type wms is not supported yet" else: @@ -162,7 +185,10 @@ # # Start monitor # - os.environ["GRASS_PNGFILE"] = self.mapfile + if self.type == 'overlay': + os.environ["GRASS_PNGFILE"] = self.ovlfile + else: + os.environ["GRASS_PNGFILE"] = self.mapfile os.environ["GRASS_RENDER_IMMEDIATE"] = "TRUE" # @@ -185,7 +211,11 @@ os.unsetenv("GRASS_PNGFILE") os.unsetenv("GRASS_RENDER_IMMEDIATE") - return self.mapfile + if self.type == 'overlay': + pass + return self.ovlfile + else: + return self.mapfile class Map: """ @@ -227,10 +257,12 @@ self.height = 400 # map height self.layers = [] # stack of available layer - self.lookup = {} # lookup dictionary for tree items and layers + self.overlays = [] + self.lookup = {} # lookup dictionary for tree items and layers self.env = {} # enviroment variables, like MAPSET, LOCATION_NAME, etc. self.verbosity = 0 self.mapfile = utils.GetTempfile() + self.ovlist = [] # self.renderRegion = { # "render" : True, # should the region be displayed? @@ -397,7 +429,7 @@ try: region[key] = float(val) except ValueError: - region[key] = val + region[key] = val if tmpreg: os.environ["GRASS_REGION"] = tmpreg @@ -533,6 +565,23 @@ if DEBUG: print ("mapimg.py: Map: Render: force=%s" % (force)) try: + # render overlays + self.ovlist = [] + for overlay in self.overlays: + if overlay == None or overlay.active == False: + continue + + # render if there is no mapfile + if overlay.ovlfile == None: + overlay.Render() + + # redraw layer content + if force: + if not overlay.Render(): + continue + self.ovlist.append(overlay.ovlfile) + + # render map layers for layer in self.layers: # skip if hidden or not active if layer.active == False or layer.hidden == True: @@ -566,17 +615,20 @@ " height=" + str(self.height) + \ " output=" + self.mapfile + # render overlays + + os.unsetenv("GRASS_REGION") + + if tmp_region: + os.environ["GRASS_REGION"] = tmp_region + # run g.composite to get composite image if os.system(compcmd): sys.stderr.write("Could not run g.pnmcomp\n") raise Exception (compcmd) - os.unsetenv("GRASS_REGION") + return self.mapfile, self.ovlist - if tmp_region: - os.environ["GRASS_REGION"] = tmp_region - - return self.mapfile except Exception, e: os.unsetenv("GRASS_REGION") @@ -817,7 +869,7 @@ Adds generic layer to list of layers Layer Attributes: - name - display command + command - display command mapset - mapset name, default: current l_active - see MapLayer class @@ -904,17 +956,11 @@ newlayer = MapLayer("command", command, mapset, l_active, l_hidden, l_opacity) - oldlayer = self.lookup[item] - oldlayerindex = self.layers.index(oldlayer) + oldlayerindex = self.layers.index(self.lookup[item]) # add maplayer to the list of layers if self.lookup[item]: - del self.layers[oldlayerindex] - del self.lookup[item] - if oldlayerindex == 0: - self.layers.append(newlayer) - else: - self.layers.insert(oldlayerindex, newlayer) + self.layers[oldlayerindex] = newlayer self.lookup[item] = newlayer @@ -991,6 +1037,53 @@ return None + def addOverlay(self, type, command, mapset=None, l_active=True, + l_hidden=False, l_opacity=1, l_render=False): + + """ + Adds overlay (grid, barscale, others?) to list of overlays + + Overlay Attributes: + command - display command + l_active - see MapLayer class + l_render - render an image + + Returns: + Added layer on success or None + + """ + + overlay = MapLayer("overlay", command, mapset, + l_active, l_hidden, l_opacity) + + + # add maplayer to the list of layers + self.overlays.append(overlay) + # add item and layer to lookup dictionary + + if l_render: + if not overlay.Render(): + sys.stderr.write("Could not render overlay <%s>\n" % (command)) + + return self.overlays[-1] + + def changeOverlay(self, type, command, mapset=None, l_active=True, + l_hidden=False, l_opacity=1, l_render=False): + + overlay = MapLayer('overlay', command, mapset, + l_active, l_hidden, l_opacity) + + # add maplayer to the list of layers + self.overlays[type] = overlay + + if l_render: + if not overlay.Render(): + sys.stderr.write("Could not render overlay <%s>\n" % (command)) + + return self.overlays[-1] + + + def Clean(self): """ Go trough all layers and remove them from layer list @@ -1007,8 +1100,16 @@ basefile = os.path.join(base,tempbase)+r'.*' for f in glob.glob(basefile): os.remove(f) -# if layer.maskfile: os.remove(layer.maskfile) self.layers.remove(layer) + for overlay in self.overlays: + if overlay.ovlfile: + base = os.path.split(overlay.ovlfile)[0] + mapfile = os.path.split(overlay.ovlfile)[1] + tempbase = mapfile.split('.')[0] + basefile = os.path.join(base,tempbase)+r'.*' + for f in glob.glob(basefile): + os.remove(f) + self.overlays.remove(overlay) return None except: return 1 Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-03-29 06:29:01 UTC (rev 364) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-03-29 06:30:44 UTC (rev 365) @@ -66,6 +66,7 @@ shortHelp="Pan", longHelp="Drag with mouse to pan") self.toolbar.AddSeparator() + self.dec = self.toolbar.AddLabelTool(id=wx.ID_ANY, label="dec", bitmap=wx.Bitmap(os.path.join(wxgui_utils.icons,"module-d.barscale.gif"), wx.BITMAP_TYPE_ANY), From barton at grass.itc.it Thu Mar 29 08:53:39 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Thu Mar 29 08:53:41 2007 Subject: [grass-addons] r366 - trunk/grassaddons/gui/gui_modules Message-ID: <200703290653.l2T6rdu1028531@grass.itc.it> Author: barton Date: 2007-03-29 08:53:29 +0200 (Thu, 29 Mar 2007) New Revision: 366 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/render.py Log: Improvements to menu appearance and rendering. But still not transparent. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-29 06:30:44 UTC (rev 365) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-29 06:53:29 UTC (rev 366) @@ -544,8 +544,15 @@ for i in range(len(map_frame_statusbar_fields)): self.statusbar.SetStatusText(map_frame_statusbar_fields[i], i) + # variables for overlay menu self.decmenu = '' #decorations menu + self.addscale = '' #barscale overlay menu item + self.addgrid = '' #grid overlay menu item self.ovlchk = False + self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) + self.bmpgrid = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) + Map.addOverlay(type=0, command='', l_active=False, l_render=True) + Map.addOverlay(type=1, command='', l_active=False, l_render=True) # # Init map display @@ -740,25 +747,21 @@ point = wx.GetMousePosition() self.decmenu = wx.Menu() # Add items to the menu - addscale = wx.MenuItem(self.decmenu, -1,'Add scalebar and north arrow') + self.addscale = wx.MenuItem(self.decmenu, -1,'Add scalebar and north arrow') # bmp = wx.Image(os.path.join(icons,'module-d.barscale.gif'), wx.BITMAP_TYPE_GIF) # bmp.Rescale(16, 16) # bmp = bmp.ConvertToBitmap() - bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) - addscale.SetBitmap(bmp) - self.decmenu.AppendItem(addscale) - Map.addOverlay(type=0, command='', l_active=False, l_render=True) - self.Bind(wx.EVT_MENU, self.addBarscale, addscale) + self.addscale.SetBitmap(self.bmpscale) + self.decmenu.AppendItem(self.addscale) + self.Bind(wx.EVT_MENU, self.addBarscale, self.addscale) - addgrid = wx.MenuItem(self.decmenu, -1,'Add grid') + self.addgrid = wx.MenuItem(self.decmenu, -1,'Add grid') # bmp = wx.Image(os.path.join(icons,'module-d.grid.gif'), wx.BITMAP_TYPE_GIF) # bmp.Rescale(16, 16) # bmp = bmp.ConvertToBitmap() - bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) - addgrid.SetBitmap(bmp) - self.decmenu.AppendItem(addgrid) - Map.addOverlay(type=1, command='', l_active=False, l_render=True) - self.Bind(wx.EVT_MENU, self.addGrid, addgrid) + self.addgrid.SetBitmap(self.bmpgrid) + self.decmenu.AppendItem(self.addgrid) + self.Bind(wx.EVT_MENU, self.addGrid, self.addgrid) # Popup the menu. If an item is selected then its handler # will be called before PopupMenu returns. @@ -770,10 +773,10 @@ layer = 0 if self.ovlchk == True: self.ovlchk = False - bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) + self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) else: self.ovlchk = True - bmp = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_OTHER, (16,16)) + self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_OTHER, (16,16)) menuform.GUI().parseCommand('d.barscale', gmpath, completed=(self.getOptData,layer,self.params), parentframe=None) pass @@ -782,20 +785,16 @@ layer = 1 if self.ovlchk == True: self.ovlchk = False - bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_TOOLBAR, (16,16)) + self.bmpgrid = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_TOOLBAR, (16,16)) else: self.ovlchk = True - bmp = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_TOOLBAR, (16,16)) + self.bmpgrid = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_TOOLBAR, (16,16)) menuform.GUI().parseCommand('d.grid', gmpath, completed=(self.getOptData,layer,self.params), parentframe=None) pass def getOptData(self, dcmd, layer): - print 'dcmd: ', dcmd - print 'layer: ', layer - print 'check: ', self.ovlchk - Map.changeOverlay(type=layer, command=dcmd, l_active=self.ovlchk, l_render=False) def OnAlignRegion(self, event): Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-03-29 06:30:44 UTC (rev 365) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-03-29 06:53:29 UTC (rev 366) @@ -126,10 +126,13 @@ """ try: - self.cmd = self.name + " --q" + if self.name != '': + self.cmd = self.name + " --q" + else: + self.cmd = None except StandardError, e: - sys.stderr.write("Could not render command layer <%s>: %s\n" %\ + sys.stderr.write("Could not render overlay <%s>: %s\n" %\ (self.name, str(e))) self.cmd = None @@ -1061,7 +1064,7 @@ self.overlays.append(overlay) # add item and layer to lookup dictionary - if l_render: + if l_render and command != '': if not overlay.Render(): sys.stderr.write("Could not render overlay <%s>\n" % (command)) @@ -1076,7 +1079,7 @@ # add maplayer to the list of layers self.overlays[type] = overlay - if l_render: + if l_render and command != '': if not overlay.Render(): sys.stderr.write("Could not render overlay <%s>\n" % (command)) From barton at grass.itc.it Thu Mar 29 08:56:21 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Thu Mar 29 08:56:22 2007 Subject: [grass-addons] r367 - trunk/grassaddons/gui/gui_modules Message-ID: <200703290656.l2T6uLlJ028551@grass.itc.it> Author: barton Date: 2007-03-29 08:56:12 +0200 (Thu, 29 Mar 2007) New Revision: 367 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Popup menu stays with button Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-29 06:53:29 UTC (rev 366) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-29 06:56:12 UTC (rev 367) @@ -765,7 +765,7 @@ # Popup the menu. If an item is selected then its handler # will be called before PopupMenu returns. - self.PopupMenu(self.decmenu,point) + self.PopupMenu(self.decmenu) self.decmenu.Destroy() def addBarscale(self, event): From chemin at grass.itc.it Thu Mar 29 14:32:37 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Thu Mar 29 14:32:38 2007 Subject: [grass-addons] r368 - in trunk/grassaddons/gipe: r.eb.g0 r.evapo.PT Message-ID: <200703291232.l2TCWbMV001530@grass.itc.it> Author: chemin Date: 2007-03-29 14:32:30 +0200 (Thu, 29 Mar 2007) New Revision: 368 Modified: trunk/grassaddons/gipe/r.eb.g0/main.c trunk/grassaddons/gipe/r.evapo.PT/main.c trunk/grassaddons/gipe/r.evapo.PT/pt_daily_et.c Log: Debugged r.evapo.PT, still debugging r.eb.g0 Modified: trunk/grassaddons/gipe/r.eb.g0/main.c =================================================================== --- trunk/grassaddons/gipe/r.eb.g0/main.c 2007-03-29 06:56:12 UTC (rev 367) +++ trunk/grassaddons/gipe/r.eb.g0/main.c 2007-03-29 12:32:30 UTC (rev 368) @@ -1,12 +1,12 @@ /**************************************************************************** * * MODULE: r.eb.g0 - * AUTHOR(S): Yann Chemin - ychemin@gmail.com + * AUTHOR(S): Yann Chemin - yann.chemin@gmail.com * PURPOSE: Calculates an approximation of soil heat flux * as seen in Bastiaanssen (1995) using time of * satellite overpass. * - * COPYRIGHT: (C) 2002-2006 by the GRASS Development Team + * COPYRIGHT: (C) 2006-2007 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 @@ -52,6 +52,7 @@ void *inrast_albedo, *inrast_ndvi, *inrast_tempk, *inrast_rnet, *inrast_time; unsigned char *outrast; + RASTER_MAP_TYPE data_type_output=DCELL_TYPE; RASTER_MAP_TYPE data_type_albedo; RASTER_MAP_TYPE data_type_ndvi; RASTER_MAP_TYPE data_type_tempk; @@ -194,9 +195,9 @@ G_debug(3, "number of rows %d",cellhd.rows); nrows = G_window_rows(); ncols = G_window_cols(); - outrast = G_allocate_raster_buf(data_type_albedo); + outrast = G_allocate_raster_buf(data_type_output); /* Create New raster files */ - if ( (outfd = G_open_raster_new (result,data_type_albedo)) < 0) + if ( (outfd = G_open_raster_new (result,data_type_output)) < 0) G_fatal_error(_("Could not open <%s>"),result); /* Process pixels */ for (row = 0; row < nrows; row++) @@ -224,17 +225,61 @@ /*process the data */ for (col=0; col < ncols; col++) { - // printf("col=%i/%i ",col,ncols); - d_albedo = ((DCELL *) inrast_albedo)[col]; - // printf("albedo = %5.3f", d_albedo); - d_ndvi = ((DCELL *) inrast_ndvi)[col]; - // printf(" ndvi = %5.3f", d_ndvi); - d_tempk = ((DCELL *) inrast_tempk)[col]; - // printf(" tempk = %5.3f", d_tempk); - d_rnet = ((DCELL *) inrast_rnet)[col]; - // printf("inrast_rnet = %f\n", d_rnet); - d_time = ((DCELL *) inrast_time)[col]; - // printf("inrast_time = %f\n", d_time); + switch(data_type_albedo){ + case CELL_TYPE: + d_albedo = (double) ((CELL *) inrast_albedo)[col]; + break; + case FCELL_TYPE: + d_albedo = (double) ((FCELL *) inrast_albedo)[col]; + break; + case DCELL_TYPE: + d_albedo = ((DCELL *) inrast_albedo)[col]; + break; + } + switch(data_type_ndvi){ + case CELL_TYPE: + d_ndvi = (double) ((CELL *) inrast_ndvi)[col]; + break; + case FCELL_TYPE: + d_ndvi = (double) ((FCELL *) inrast_ndvi)[col]; + break; + case DCELL_TYPE: + d_ndvi = ((DCELL *) inrast_ndvi)[col]; + break; + } + switch(data_type_tempk){ + case CELL_TYPE: + d_tempk = (double) ((CELL *) inrast_tempk)[col]; + break; + case FCELL_TYPE: + d_tempk = (double) ((FCELL *) inrast_tempk)[col]; + break; + case DCELL_TYPE: + d_tempk = ((DCELL *) inrast_tempk)[col]; + break; + } + switch(data_type_rnet){ + case CELL_TYPE: + d_rnet = (double) ((CELL *) inrast_rnet)[col]; + break; + case FCELL_TYPE: + d_rnet = (double) ((FCELL *) inrast_rnet)[col]; + break; + case DCELL_TYPE: + d_rnet = ((DCELL *) inrast_rnet)[col]; + break; + } + switch(data_type_time){ + case CELL_TYPE: + d_time = (double) ((CELL *) inrast_time)[col]; + break; + case FCELL_TYPE: + d_time = (double) ((FCELL *) inrast_time)[col]; + break; + case DCELL_TYPE: + d_time = ((DCELL *) inrast_time)[col]; + break; + } if(G_is_d_null_value(&d_albedo)){ ((DCELL *) outrast)[col] = -999.99; }else if(G_is_d_null_value(&d_ndvi)){ @@ -257,7 +302,7 @@ // exit(EXIT_SUCCESS); // } } - if (G_put_raster_row (outfd, outrast, data_type_albedo) < 0) + if (G_put_raster_row (outfd, outrast, data_type_output) < 0) G_fatal_error(_("Cannot write to output raster file")); } Modified: trunk/grassaddons/gipe/r.evapo.PT/main.c =================================================================== --- trunk/grassaddons/gipe/r.evapo.PT/main.c 2007-03-29 06:56:12 UTC (rev 367) +++ trunk/grassaddons/gipe/r.evapo.PT/main.c 2007-03-29 12:32:30 UTC (rev 368) @@ -64,7 +64,7 @@ /* parser stuctures definition */ struct GModule *module; - struct Option *input_RNET,*input_TEMPKA, *input_PATM, *input_G0; + struct Option *input_RNET,*input_TEMPKA, *input_PATM, *input_G0, *input_PT; struct Option *output; struct Flag *flag1, *zero; struct Colors color; @@ -118,6 +118,15 @@ input_PATM->gisprompt = "old,cell,raster"; input_PATM->description = _("Name of Atmospheric Pressure raster map"); + input_PT = G_define_option(); + input_PT->key = "PT"; + input_PT->key_desc = "[-]"; + input_PT->type = TYPE_DOUBLE; + input_PT->required = YES; + input_PT->gisprompt = "old,cell,raster"; + input_PT->description = _("Prestley-Taylor Coefficient"); + input_PT->answer = "1.26"; + output = G_define_option() ; output->key = "output"; output->key_desc = "[mm/d]"; @@ -143,6 +152,7 @@ TEMPKA = input_TEMPKA->answer; PATM = input_PATM->answer; G0 = input_G0->answer; + d_pt_alpha = atof(input_PT->answer); ETa = output->answer; Modified: trunk/grassaddons/gipe/r.evapo.PT/pt_daily_et.c =================================================================== --- trunk/grassaddons/gipe/r.evapo.PT/pt_daily_et.c 2007-03-29 06:56:12 UTC (rev 367) +++ trunk/grassaddons/gipe/r.evapo.PT/pt_daily_et.c 2007-03-29 12:32:30 UTC (rev 368) @@ -8,7 +8,7 @@ { double result; - result = alpha_pt * ( delta_pt / ( delta_pt + ghamma_pt ) ) * ( rnet - g0 ) ; + result = (alpha_pt/28.588) * ( delta_pt / ( delta_pt + ghamma_pt ) ) * ( rnet - g0 ) ; return result; } From chemin at grass.itc.it Thu Mar 29 18:42:09 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Thu Mar 29 18:42:09 2007 Subject: [grass-addons] r369 - in trunk/grassaddons/gipe: . r.emissivity Message-ID: <200703291642.l2TGg9U4004879@grass.itc.it> Author: chemin Date: 2007-03-29 18:41:57 +0200 (Thu, 29 Mar 2007) New Revision: 369 Added: trunk/grassaddons/gipe/r.emissivity/ trunk/grassaddons/gipe/r.emissivity/Makefile trunk/grassaddons/gipe/r.emissivity/description.html trunk/grassaddons/gipe/r.emissivity/emissivity_generic.c trunk/grassaddons/gipe/r.emissivity/main.c Modified: trunk/grassaddons/gipe/Makefile Log: added r.emissivity Modified: trunk/grassaddons/gipe/Makefile =================================================================== --- trunk/grassaddons/gipe/Makefile 2007-03-29 12:32:30 UTC (rev 368) +++ trunk/grassaddons/gipe/Makefile 2007-03-29 16:41:57 UTC (rev 369) @@ -44,9 +44,11 @@ r.eb.ublend \ r.eb.ustar \ r.eb.z0m \ + r.emissivity \ r.evapo.potrad \ r.evapo.PM \ r.evapo.PT \ + r.evapo.TSA \ r.fill.dir \ r.flow \ r.gaswap.serial \ Added: trunk/grassaddons/gipe/r.emissivity/Makefile =================================================================== --- trunk/grassaddons/gipe/r.emissivity/Makefile (rev 0) +++ trunk/grassaddons/gipe/r.emissivity/Makefile 2007-03-29 16:41:57 UTC (rev 369) @@ -0,0 +1,10 @@ +MODULE_TOPDIR = ../.. + +PGM = r.emissivity + +LIBES = $(GISLIB) +DEPENDENCIES = $(GISDEP) + +include $(MODULE_TOPDIR)/include/Make/Module.make + +default: cmd Added: trunk/grassaddons/gipe/r.emissivity/description.html =================================================================== --- trunk/grassaddons/gipe/r.emissivity/description.html (rev 0) +++ trunk/grassaddons/gipe/r.emissivity/description.html 2007-03-29 16:41:57 UTC (rev 369) @@ -0,0 +1,25 @@ +

DESCRIPTION

+ +r.emissivity calculates the emissivity in the longwave radiation spectrum, according to the semi-empirical equation related to NDVI by Caselles and Colles (1997), valid in the NDVI range of 0.16 to 0.74. + +Estimation in the 8-14 micrometers range for sparse canopy + +

NOTES

+ + +

TODO

+ + +

SEE ALSO

+ + +
r.eb.netrad
+
+ + +

AUTHORS

+Yann Chemin, GRASS Development Team
+ + +

+Last changed: $Date: 2007/03/29 22:19:55 $ Added: trunk/grassaddons/gipe/r.emissivity/emissivity_generic.c =================================================================== --- trunk/grassaddons/gipe/r.emissivity/emissivity_generic.c (rev 0) +++ trunk/grassaddons/gipe/r.emissivity/emissivity_generic.c 2007-03-29 16:41:57 UTC (rev 369) @@ -0,0 +1,23 @@ +#include +#include +#include + +// Emissivity Generic mode (Reads directly from NDVI) +// Estimation in the 8-14 micrometers range for sparse canopy +// yann.chemin@gmail.com LGPL, Copylefted, 2004. + +double emissivity_generic( double ndvi ) +{ + double result; + + if(ndvi < 0.16){ + result = 1.0; + } else if(ndvi > 0.74){ + result = 0.9; + } else { + result = 1.009 + 0.047*log(ndvi); + } + + return result; +} + Added: trunk/grassaddons/gipe/r.emissivity/main.c =================================================================== --- trunk/grassaddons/gipe/r.emissivity/main.c (rev 0) +++ trunk/grassaddons/gipe/r.emissivity/main.c 2007-03-29 16:41:57 UTC (rev 369) @@ -0,0 +1,162 @@ +/**************************************************************************** + * + * MODULE: r.emissivity + * AUTHOR(S): Yann Chemin - yann.chemin@gmail.com + * PURPOSE: Calculates the emissivity from NDVI (empirical) + * as seen in Caselles and Colles (1997). + * + * COPYRIGHT: (C) 2007 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. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include + + +double emissivity_generic( double ndvi ); + +int main(int argc, char *argv[]) +{ + struct Cell_head cellhd; //region+header info + char *mapset; // mapset name + int nrows, ncols; + int row,col; + + int verbose=1; + struct GModule *module; + struct Option *input1, *output1; + + struct Flag *flag1, *flag2; + struct History history; //metadata + + /************************************/ + /* FMEO Declarations*****************/ + char *name; // input raster name + char *result1; //output raster name + //File Descriptors + int infd_ndvi; + int outfd1; + + char *ndvi; + char *emissivity; + int i=0,j=0; + + void *inrast_ndvi; + unsigned char *outrast1; + RASTER_MAP_TYPE data_type_output=DCELL_TYPE; + RASTER_MAP_TYPE data_type_ndvi; + /************************************/ + G_gisinit(argv[0]); + + module = G_define_module(); + module->keywords = _("emissivity, land flux, energy balance"); + module->description = _("Emissivity from NDVI, generic method for spares land."); + + /* Define the different options */ + input1 = G_define_option() ; + input1->key = _("ndvi"); + input1->type = TYPE_STRING; + input1->required = YES; + input1->gisprompt =_("old,cell,raster") ; + input1->description=_("Name of the NDVI map [-]"); + input1->answer =_("ndvi"); + + output1 = G_define_option() ; + output1->key =_("emissivity"); + output1->type = TYPE_STRING; + output1->required = YES; + output1->gisprompt =_("new,cell,raster"); + output1->description=_("Name of the output emissivity layer"); + output1->answer =_("e0"); + + + flag1 = G_define_flag(); + flag1->key = 'q'; + flag1->description = _("Quiet"); + + /********************/ + if (G_parser(argc, argv)) + exit (EXIT_FAILURE); + + ndvi = input1->answer; + + result1 = output1->answer; + verbose = (!flag1->answer); + /***************************************************/ + mapset = G_find_cell2(ndvi, ""); + if (mapset == NULL) { + G_fatal_error(_("cell file [%s] not found"), ndvi); + } + data_type_ndvi = G_raster_map_type(ndvi,mapset); + if ( (infd_ndvi = G_open_cell_old (ndvi,mapset)) < 0) + G_fatal_error (_("Cannot open cell file [%s]"), ndvi); + if (G_get_cellhd (ndvi, mapset, &cellhd) < 0) + G_fatal_error (_("Cannot read file header of [%s])"), ndvi); + inrast_ndvi = G_allocate_raster_buf(data_type_ndvi); + /***************************************************/ + G_debug(3, "number of rows %d",cellhd.rows); + nrows = G_window_rows(); + ncols = G_window_cols(); + outrast1 = G_allocate_raster_buf(data_type_output); + /* Create New raster files */ + if ( (outfd1 = G_open_raster_new (result1,data_type_output)) < 0) + G_fatal_error(_("Could not open <%s>"),result1); + /* Process pixels */ + for (row = 0; row < nrows; row++) + { + DCELL d; + DCELL d_ndvi; + if(verbose) + G_percent(row,nrows,2); +// printf("row = %i/%i\n",row,nrows); + /* read soil input maps */ + if(G_get_raster_row(infd_ndvi,inrast_ndvi,row,data_type_ndvi)<0) + G_fatal_error(_("Could not read from <%s>"),ndvi); + /*process the data */ + for (col=0; col < ncols; col++) + { + switch(data_type_ndvi){ + case CELL_TYPE: + d_ndvi = (double) ((CELL *) inrast_ndvi)[col]; + break; + case FCELL_TYPE: + d_ndvi = (double) ((FCELL *) inrast_ndvi)[col]; + break; + case DCELL_TYPE: + d_ndvi = ((DCELL *) inrast_ndvi)[col]; + break; + } + if(G_is_d_null_value(&d_ndvi)){ + ((DCELL *) outrast1)[col] = -999.99; + } else { + /****************************/ + /* calculate emissivity */ + d = emissivity_generic(d_ndvi); + + ((DCELL *) outrast1)[col] = d; + } + } + if (G_put_raster_row (outfd1, outrast1, data_type_output) < 0) + G_fatal_error(_("Cannot write to output raster file")); + } + + G_free (inrast_ndvi); + G_close_cell (infd_ndvi); + + G_free (outrast1); + G_close_cell (outfd1); + + G_short_history(result1, "raster", &history); + G_command_history(&history); + G_write_history(result1,&history); + + exit(EXIT_SUCCESS); +} + From cepicky at grass.itc.it Thu Mar 29 19:14:43 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Thu Mar 29 19:14:45 2007 Subject: [grass-addons] r370 - in trunk/grassaddons/gui: gui_modules images scripts Message-ID: <200703291714.l2THEhhv005560@grass.itc.it> Author: cepicky Date: 2007-03-29 19:14:43 +0200 (Thu, 29 Mar 2007) New Revision: 370 Added: trunk/grassaddons/gui/gui_modules/dbm.py trunk/grassaddons/gui/scripts/p.db Modified: trunk/grassaddons/gui/images/grass.smlogo.gif Log: starting to work on attribute table manager Added: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-03-29 17:14:43 UTC (rev 370) @@ -0,0 +1,195 @@ +#!/usr/bin/python +""" +Database browser for GRASS GIS >= 7 + +This program is based on FileHunter, publicated in "The wxPython Linux +Tutorial" on wxPython WIKI pages. + +Usage: + dbm.py table_name + +""" +############################################################################ +# +# MODULE: dbm.py +# AUTHOR(S): Jachym Cepicky jachym les-ejk cz +# PURPOSE: Database manager for vector attribute tables stored in +# GRASS GIS +# COPYRIGHT: (C) 2007 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. +# +############################################################################ + +# discussion: +# using database drivers is IMHO impossible +# so, first step: parsing output form db.* commands and using SQL for +# manipulation + +import wx +import os,sys +import time + +import grassenv +import images +imagepath = images.__path__[0] +sys.path.append(imagepath) + +ID_BUTTON=100 +ID_EXIT=200 + +class MyListCtrl(wx.ListCtrl): + def __init__(self, parent, id, tablename=None): + wx.ListCtrl.__init__(self, parent, id, style=wx.LC_REPORT, ) + + lengths =[] + # FIXME: subprocess.Popen should be used + # FIXME: Maximal number of columns, when the GUI is still usable + i = 0 + for column in os.popen("db.columns table=%s" % + (tablename)).readlines(): + + column = column.strip() + self.InsertColumn(i, column) + self.SetColumnWidth(i, 5) + i += 1 + lengths.append(1) # + + + # FIXME: subprocess.Popen should be used + # FIXME: Max. number of rows, while the GUI is still usable + j = 0 + for line in os.popen("""db.select -c sql="SELECT * FROM %s" """ % tablename): + attributes = line.strip().split("|") + + k = 0 + for attribute in attributes: + if len(attribute) > lengths[k]: + lengths[k] = len(attribute) + if k == 0: + self.InsertStringItem(j, attribute) + else: + self.SetStringItem(j, k, attribute) + k += 1 + + if (j % 2) == 0: + self.SetItemBackgroundColour(j, '#e6f1f5') + j = j + 1 + + # setting column widths + i = 0 + for length in lengths: + self.SetColumnWidth(i, (length+5)*12) + i += 1 + + +class DBHunter(wx.Frame): + def __init__(self, parent, id, title, tablename): + wx.Frame.__init__(self, parent, -1, title) + + global imagepath + self.tablename = tablename + self.SetIcon(wx.Icon(os.path.join(imagepath,'grass_db.png'), wx.BITMAP_TYPE_ANY)) + + + self.table = MyListCtrl(self, -1, self.tablename) + + + self.Bind(wx.EVT_SIZE, self.OnSize) + + filemenu= wx.Menu() + filemenu.Append(ID_EXIT,"E&xit"," Terminate the program") + editmenu = wx.Menu() + netmenu = wx.Menu() + showmenu = wx.Menu() + configmenu = wx.Menu() + helpmenu = wx.Menu() + + menuBar = wx.MenuBar() + menuBar.Append(filemenu,"&File") + menuBar.Append(editmenu, "&Edit") + menuBar.Append(netmenu, "&Net") + menuBar.Append(showmenu, "&Show") + menuBar.Append(configmenu, "&Config") + menuBar.Append(helpmenu, "&Help") + self.SetMenuBar(menuBar) + self.Bind(wx.EVT_MENU, self.OnExit, id=ID_EXIT) + + tb = self.CreateToolBar( wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT | wx.TB_TEXT) + tb.AddSimpleTool(10, wx.Bitmap('images/db_open_table.png'), 'Open table') + #tb.AddSimpleTool(20, wx.Bitmap('images/up.png'), 'Up one directory') + #tb.AddSimpleTool(30, wx.Bitmap('images/home.png'), 'Home') + #tb.AddSimpleTool(40, wx.Bitmap('images/refresh.png'), 'Refresh') + #tb.AddSeparator() + #tb.AddSimpleTool(50, wx.Bitmap('images/write.png'), 'Editor') + #tb.AddSimpleTool(60, wx.Bitmap('images/terminal.png'), 'Terminal') + #tb.AddSeparator() + #tb.AddSimpleTool(70, wx.Bitmap('images/help.png'), 'Help') + tb.Realize() + + #self.sizer2 = wx.BoxSizer(wx.HORIZONTAL) + + #button1 = wx.Button(self, ID_BUTTON + 1, "F3 View") + #button2 = wx.Button(self, ID_BUTTON + 2, "F4 Edit") + #button3 = wx.Button(self, ID_BUTTON + 3, "F5 Copy") + #button4 = wx.Button(self, ID_BUTTON + 4, "F6 Move") + #button5 = wx.Button(self, ID_BUTTON + 5, "F7 Mkdir") + #button6 = wx.Button(self, ID_BUTTON + 6, "F8 Delete") + #button7 = wx.Button(self, ID_BUTTON + 7, "F9 Rename") + #button8 = wx.Button(self, ID_EXIT, "F10 Quit") + + # self.sizer2.Add(button1, 1, wx.EXPAND) + # self.sizer2.Add(button2, 1, wx.EXPAND) + # self.sizer2.Add(button3, 1, wx.EXPAND) + # self.sizer2.Add(button4, 1, wx.EXPAND) + # self.sizer2.Add(button5, 1, wx.EXPAND) + # self.sizer2.Add(button6, 1, wx.EXPAND) + # self.sizer2.Add(button7, 1, wx.EXPAND) + # self.sizer2.Add(button8, 1, wx.EXPAND) + + self.Bind(wx.EVT_BUTTON, self.OnExit, id=ID_EXIT) + + self.sizer = wx.BoxSizer(wx.VERTICAL) + #self.sizer.Add(self.splitter,1,wx.EXPAND) + self.sizer.Add(self.table,1, wx.EXPAND | wx.ALL, 3) + #self.sizer.Add(self.sizer2,0,wx.EXPAND) + self.SetSizer(self.sizer) + + size = wx.DisplaySize() + self.SetSize(size) + + self.sb = self.CreateStatusBar() + self.dbcon = "table: %s; " % self.tablename + for line in os.popen("db.connect -p").readlines(): + self.dbcon += line.strip() +"; " + self.sb.SetStatusText(self.dbcon) + self.Center() + self.Show(True) + + + def OnExit(self,e): + self.Close(True) + + def OnSize(self, event): + size = self.GetSize() + #self.splitter.SetSashPosition(size.x / 2) + self.sb.SetStatusText(self.dbcon) + event.Skip() + + + def OnDoubleClick(self, event): + size = self.GetSize() + #self.splitter.SetSashPosition(size.x / 2) + +if __name__ == "__main__": + + if len(sys.argv) != 2: + print >>sys.stderr, __doc__ + sys.exit() + + app = wx.App(0) + dbmanager = DBHunter(None, -1, 'GRASS Attribute Table Manager',sys.argv[1]) + app.MainLoop() + Property changes on: trunk/grassaddons/gui/gui_modules/dbm.py ___________________________________________________________________ Name: svn:executable + * Modified: trunk/grassaddons/gui/images/grass.smlogo.gif =================================================================== (Binary files differ) Added: trunk/grassaddons/gui/scripts/p.db =================================================================== --- trunk/grassaddons/gui/scripts/p.db (rev 0) +++ trunk/grassaddons/gui/scripts/p.db 2007-03-29 17:14:43 UTC (rev 370) @@ -0,0 +1,32 @@ +#!/bin/sh + +#%Module +#% description: Start stand-alone attribute table manager +#% keywords: database +#%End +#%Option +#% key: table +#% type: string +#% required: yes +#% multiple: no +#% description: Table name +#%End + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." 1>&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +# CODE GOES HERE + +PYTHONPATH="$GISBASE/etc/wx" + +export PYTHONPATH + +python $PYTHONPATH/gui_modules/dbm.py $GIS_OPT_TABLE + +exit 0 Property changes on: trunk/grassaddons/gui/scripts/p.db ___________________________________________________________________ Name: svn:executable + * From barton at grass.itc.it Thu Mar 29 19:15:15 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Thu Mar 29 19:15:16 2007 Subject: [grass-addons] r371 - in trunk/grassaddons/gui: . gui_modules Message-ID: <200703291715.l2THFFjw005613@grass.itc.it> Author: barton Date: 2007-03-29 19:15:01 +0200 (Thu, 29 Mar 2007) New Revision: 371 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/wxgui_utils.py trunk/grassaddons/gui/wxgui.py Log: Moved grid to layers manager and grouped with d.labels. This makes more sense because both are designed to render over the entire map. The overlays menu on the map display to be used for arrow/scale, legend (currently still in layers), individual text objects, etc which need to be positioned. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-29 17:14:43 UTC (rev 370) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-29 17:15:01 UTC (rev 371) @@ -755,14 +755,6 @@ self.decmenu.AppendItem(self.addscale) self.Bind(wx.EVT_MENU, self.addBarscale, self.addscale) - self.addgrid = wx.MenuItem(self.decmenu, -1,'Add grid') -# bmp = wx.Image(os.path.join(icons,'module-d.grid.gif'), wx.BITMAP_TYPE_GIF) -# bmp.Rescale(16, 16) -# bmp = bmp.ConvertToBitmap() - self.addgrid.SetBitmap(self.bmpgrid) - self.decmenu.AppendItem(self.addgrid) - self.Bind(wx.EVT_MENU, self.addGrid, self.addgrid) - # Popup the menu. If an item is selected then its handler # will be called before PopupMenu returns. self.PopupMenu(self.decmenu) Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-29 17:14:43 UTC (rev 370) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-03-29 17:15:01 UTC (rev 371) @@ -103,6 +103,16 @@ trgif = trgif.ConvertToBitmap() self.chart_icon = il.Add(trgif) + trgif = wx.Image(icons + r'/module-d.grid.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.grid_icon = il.Add(trgif) + + trgif = wx.Image(icons + r'/module-d.labels.gif', wx.BITMAP_TYPE_GIF) + trgif.Rescale(16, 16) + trgif = trgif.ConvertToBitmap() + self.labels_icon = il.Add(trgif) + trgif = wx.Image(icons + r'/gui-cmd.gif', wx.BITMAP_TYPE_GIF) trgif.Rescale(16, 16) trgif = trgif.ConvertToBitmap() @@ -211,6 +221,16 @@ self.SetItemText(layer, 'thematic charts (double click to set properties)') # launch the properties dialog menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'grid': + self.SetItemImage(layer, self.grid_icon) + self.SetItemText(layer, 'grid (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.grid', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif type == 'labels': + self.SetItemImage(layer, self.labels_icon) + self.SetItemText(layer, 'vector labels (double click to set properties)') + # launch the properties dialog + menuform.GUI().parseCommand('d.labels', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif type == 'command': self.SetItemImage(layer, self.cmd_icon) elif type == 'group': @@ -241,6 +261,10 @@ menuform.GUI().parseCommand('d.vect.thematic', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif self.layertype[layer] == 'themechart': menuform.GUI().parseCommand('d.vect.chart', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'grid': + menuform.GUI().parseCommand('d.grid', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) + elif self.layertype[layer] == 'labels': + menuform.GUI().parseCommand('d.labels', gmpath, completed=(self.getOptData,layer,self.params), parentframe=self) elif self.layertype[layer] == 'group': if self.IsExpanded(layer): self.Collapse(layer) @@ -406,6 +430,10 @@ mapname = item.split('=')[1] elif 'h_map=' in item: mapname = item.split('=')[1] + elif 'd.grid' in item: + mapname = 'grid' + elif 'labels=' in item: + mapname = item.split('=')[1]+' labels' # set layer text to map name self.SetItemText(layer, mapname) @@ -715,6 +743,10 @@ layertype = 'thememap' elif cmd == 'd.vect.chart': layertype = 'themechart' + elif cmd == 'd.grid': + layertype = 'grid' + elif cmd == 'd.labels': + layertype = 'labels' else: print 'Command type not yet implemented' return Modified: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py 2007-03-29 17:14:43 UTC (rev 370) +++ trunk/grassaddons/gui/wxgui.py 2007-03-29 17:15:01 UTC (rev 371) @@ -316,6 +316,7 @@ ('addvect', wx.Bitmap(os.path.join(wxgui_utils.icons,'element-vector.gif'), wx.BITMAP_TYPE_ANY), 'Add vector layer', self.onVector), ('addcmd', wx.Bitmap(os.path.join(wxgui_utils.icons,'gui-cmd.gif'), wx.BITMAP_TYPE_ANY), 'Add command layer', self.addCommand), ('addgrp', wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_TOOLBAR, (16,16)), 'Add layer group', self.addGroup), + ('addovl', wx.Bitmap(os.path.join(wxgui_utils.icons,'module-d.grid.gif'), wx.BITMAP_TYPE_ANY), 'Add grid or vector labels overlay', self.onOverlay), ('delcmd', wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_TOOLBAR, (16,16)), 'Delete selected layer', self.deleteLayer), ) @@ -366,7 +367,7 @@ # toolBar button handlers def onRaster(self, event): - """Add raster item menu""" + """Add raster menu""" point = wx.GetMousePosition() rastmenu = wx.Menu() # Add items to the menu @@ -408,7 +409,7 @@ rastmenu.Destroy() def onVector(self, event): - """Add raster item menu""" + """Add vector menu""" point = wx.GetMousePosition() vectmenu = wx.Menu() @@ -440,6 +441,33 @@ self.PopupMenu(vectmenu) vectmenu.Destroy() + def onOverlay(self, event): + """Add overlay menu""" + point = wx.GetMousePosition() + ovlmenu = wx.Menu() + + addgrid = wx.MenuItem(ovlmenu, -1,'Add grid overlay') + bmp = wx.Image(os.path.join(wxgui_utils.icons,'module-d.grid.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addgrid.SetBitmap(bmp) + ovlmenu.AppendItem(addgrid) + self.Bind(wx.EVT_MENU, self.addGrid, addgrid) + + addlbl = wx.MenuItem(ovlmenu, -1,'Add vector labels overlay (create with v.label)') + bmp = wx.Image(os.path.join(wxgui_utils.icons,'module-d.labels.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addlbl.SetBitmap(bmp) + ovlmenu.AppendItem(addlbl) + self.Bind(wx.EVT_MENU, self.addLabels, addlbl) + + # Popup the menu. If an item is selected then its handler + # will be called before PopupMenu returns. + self.PopupMenu(ovlmenu) + ovlmenu.Destroy() + + def addRaster(self, event): self.SetTree('raster') @@ -475,6 +503,15 @@ """Add layer group""" self.SetTree('group') + def addGrid(self, event): + """Add layer grid""" + self.SetTree('grid') + + def addLabels(self, event): + """Add layer vector labels""" + print 'labels 1', event + self.SetTree('labels') + def GetSelectedDisplay(self): return self.notebook.GetSelection() From cepicky at grass.itc.it Thu Mar 29 19:17:06 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Thu Mar 29 19:17:07 2007 Subject: [grass-addons] r372 - trunk/grassaddons/gui/images Message-ID: <200703291717.l2THH6Ug005672@grass.itc.it> Author: cepicky Date: 2007-03-29 19:17:06 +0200 (Thu, 29 Mar 2007) New Revision: 372 Added: trunk/grassaddons/gui/images/db_open_table.png trunk/grassaddons/gui/images/grass_db.png Log: new icons for attribute manager Added: trunk/grassaddons/gui/images/db_open_table.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/images/db_open_table.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/images/grass_db.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/images/grass_db.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From chemin at grass.itc.it Thu Mar 29 21:14:18 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Thu Mar 29 21:14:19 2007 Subject: [grass-addons] r373 - trunk/grassaddons/gipe Message-ID: <200703291914.l2TJEIqU008207@grass.itc.it> Author: chemin Date: 2007-03-29 21:14:14 +0200 (Thu, 29 Mar 2007) New Revision: 373 Modified: trunk/grassaddons/gipe/gmmenu.tcl Log: Update gmmenu.tcl for r.emissivity Modified: trunk/grassaddons/gipe/gmmenu.tcl =================================================================== --- trunk/grassaddons/gipe/gmmenu.tcl 2007-03-29 17:17:06 UTC (rev 372) +++ trunk/grassaddons/gipe/gmmenu.tcl 2007-03-29 19:14:14 UTC (rev 373) @@ -605,7 +605,9 @@ {command {[G_msg "Vegetation Indices (13 types)"]} {} "r.vi" {} -command {execute r.vi }} {command {[G_msg "Vegetation Indices (13 types) cluster"]} {} "r.vi.mpi" {} -command {execute r.vi.mpi }} {command {[G_msg "Vegetation Indices (13 types) grid"]} {} "r.vi.grid" {} -command {execute r.vi.grid }} + {separator} {command {[G_msg "Albedo"]} {} "r.albedo" {} -command {execute r.albedo }} + {command {[G_msg "Emissivity (generic from NDVI)"]} {} "r.emissivity" {} -command {execute r.emissivity }} {separator} {command {[G_msg "Latitude map"]} {} "r.latitude" {} -command {execute r.latitude }} {command {[G_msg "Sunshine hours (potential)"]} {} "r.sunhours" {} -command {execute r.sunhours }} From chemin at grass.itc.it Thu Mar 29 23:15:42 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Thu Mar 29 23:15:43 2007 Subject: [grass-addons] r374 - trunk/grassaddons/gipe/r.eb.netrad Message-ID: <200703292115.l2TLFgVF010945@grass.itc.it> Author: chemin Date: 2007-03-29 23:15:38 +0200 (Thu, 29 Mar 2007) New Revision: 374 Modified: trunk/grassaddons/gipe/r.eb.netrad/main.c Log: Debugged r.eb.netrad Modified: trunk/grassaddons/gipe/r.eb.netrad/main.c =================================================================== --- trunk/grassaddons/gipe/r.eb.netrad/main.c 2007-03-29 19:14:14 UTC (rev 373) +++ trunk/grassaddons/gipe/r.eb.netrad/main.c 2007-03-29 21:15:38 UTC (rev 374) @@ -1,12 +1,12 @@ /**************************************************************************** * * MODULE: r.eb.netrad - * AUTHOR(S): Yann Chemin - ychemin@gmail.com + * AUTHOR(S): Yann Chemin - yann.chemin@gmail.com * PURPOSE: Calculates the instantaneous net radiation at * as seen in Bastiaanssen (1995) using time of * satellite overpass. * - * COPYRIGHT: (C) 2002-2006 by the GRASS Development Team + * COPYRIGHT: (C) 2006-2007 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 @@ -55,6 +55,7 @@ void *inrast_doy, *inrast_sunzangle; unsigned char *outrast; + RASTER_MAP_TYPE data_type_output=DCELL_TYPE; RASTER_MAP_TYPE data_type_albedo; RASTER_MAP_TYPE data_type_ndvi; RASTER_MAP_TYPE data_type_tempk; @@ -166,7 +167,11 @@ tempk = input3->answer; time = input4->answer; dtair = input5->answer; - + emissivity = input6->answer; + tsw = input7->answer; + doy = input8->answer; + sunzangle = input9->answer; + result = output1->answer; verbose = (!flag1->answer); /***************************************************/ @@ -252,7 +257,7 @@ G_fatal_error(_("Cell file [%s] not found"), doy); } data_type_doy = G_raster_map_type(doy,mapset); - if ( (infd_time = G_open_cell_old (doy,mapset)) < 0) + if ( (infd_doy = G_open_cell_old (doy,mapset)) < 0) G_fatal_error(_("Cannot open cell file [%s]"), doy); if (G_get_cellhd (doy, mapset, &cellhd) < 0) G_fatal_error(_("Cannot read file header of [%s]"), doy); @@ -272,9 +277,9 @@ G_debug(3, "number of rows %d",cellhd.rows); nrows = G_window_rows(); ncols = G_window_cols(); - outrast = G_allocate_raster_buf(data_type_albedo); + outrast = G_allocate_raster_buf(data_type_output); /* Create New raster files */ - if ( (outfd = G_open_raster_new (result,data_type_albedo)) < 0) + if ( (outfd = G_open_raster_new (result,data_type_output)) < 0) G_fatal_error(_("Could not open <%s>"),result); /* Process pixels */ for (row = 0; row < nrows; row++) @@ -291,8 +296,7 @@ DCELL d_sunzangle; if(verbose) G_percent(row,nrows,2); -// printf("row = %i/%i\n",row,nrows); - /* read soil input maps */ + /* read input maps */ if(G_get_raster_row(infd_albedo,inrast_albedo,row,data_type_albedo)<0) G_fatal_error(_("Could not read from <%s>"),albedo); if(G_get_raster_row(infd_ndvi,inrast_ndvi,row,data_type_ndvi)<0) @@ -303,36 +307,116 @@ G_fatal_error(_("Could not read from <%s>"),dtair); if(G_get_raster_row(infd_time,inrast_time,row,data_type_time)<0) G_fatal_error(_("Could not read from <%s>"),time); - if(G_get_raster_row(infd_time,inrast_time,row,data_type_emissivity)<0) + if(G_get_raster_row(infd_emissivity,inrast_emissivity,row,data_type_emissivity)<0) G_fatal_error(_("Could not read from <%s>"),emissivity); - if(G_get_raster_row(infd_time,inrast_time,row,data_type_tsw)<0) + if(G_get_raster_row(infd_tsw,inrast_tsw,row,data_type_tsw)<0) G_fatal_error(_("Could not read from <%s>"),tsw); - if(G_get_raster_row(infd_time,inrast_time,row,data_type_doy)<0) + if(G_get_raster_row(infd_doy,inrast_doy,row,data_type_doy)<0) G_fatal_error(_("Could not read from <%s>"),doy); - if(G_get_raster_row(infd_time,inrast_time,row,data_type_sunzangle)<0) + if(G_get_raster_row(infd_sunzangle,inrast_sunzangle,row,data_type_sunzangle)<0) G_fatal_error(_("Could not read from <%s>"),sunzangle); /*process the data */ for (col=0; col < ncols; col++) { - // printf("col=%i/%i ",col,ncols); - d_albedo = ((DCELL *) inrast_albedo)[col]; - // printf("albedo = %5.3f", d_albedo); - d_ndvi = ((DCELL *) inrast_ndvi)[col]; - // printf(" ndvi = %5.3f", d_ndvi); - d_tempk = ((DCELL *) inrast_tempk)[col]; - // printf(" tempk = %5.3f", d_tempk); - d_dtair = ((DCELL *) inrast_dtair)[col]; - // printf("inrast_dtair = %f\n", d_dtair); - d_time = ((DCELL *) inrast_time)[col]; - // printf("inrast_time = %f\n", d_time); - d_emissivity = ((DCELL *) inrast_emissivity)[col]; - // printf("inrast_emissivity = %f\n", d_emissivity); - d_tsw = ((DCELL *) inrast_tsw)[col]; - // printf("inrast_tsw = %f\n", d_tsw); - d_doy = ((DCELL *) inrast_doy)[col]; - // printf("inrast_doy = %f\n", d_doy); - d_sunzangle = ((DCELL *) inrast_sunzangle)[col]; - // printf("inrast_sunzangle = %f\n", d_sunzangle); + switch(data_type_albedo){ + case CELL_TYPE: + d_albedo = (double) ((CELL *) inrast_albedo)[col]; + break; + case FCELL_TYPE: + d_albedo = (double) ((FCELL *) inrast_albedo)[col]; + break; + case DCELL_TYPE: + d_albedo = ((DCELL *) inrast_albedo)[col]; + break; + } + switch(data_type_ndvi){ + case CELL_TYPE: + d_ndvi = (double) ((CELL *) inrast_ndvi)[col]; + break; + case FCELL_TYPE: + d_ndvi = (double) ((FCELL *) inrast_ndvi)[col]; + break; + case DCELL_TYPE: + d_ndvi = ((DCELL *) inrast_ndvi)[col]; + break; + } + switch(data_type_tempk){ + case CELL_TYPE: + d_tempk = (double) ((CELL *) inrast_tempk)[col]; + break; + case FCELL_TYPE: + d_tempk = (double) ((FCELL *) inrast_tempk)[col]; + break; + case DCELL_TYPE: + d_tempk = ((DCELL *) inrast_tempk)[col]; + break; + } + switch(data_type_dtair){ + case CELL_TYPE: + d_dtair = (double) ((CELL *) inrast_dtair)[col]; + break; + case FCELL_TYPE: + d_dtair = (double) ((FCELL *) inrast_dtair)[col]; + break; + case DCELL_TYPE: + d_dtair = ((DCELL *) inrast_dtair)[col]; + break; + } + switch(data_type_time){ + case CELL_TYPE: + d_time = (double) ((CELL *) inrast_time)[col]; + break; + case FCELL_TYPE: + d_time = (double) ((FCELL *) inrast_time)[col]; + break; + case DCELL_TYPE: + d_time = ((DCELL *) inrast_time)[col]; + break; + } + switch(data_type_emissivity){ + case CELL_TYPE: + d_emissivity = (double) ((CELL *) inrast_emissivity)[col]; + break; + case FCELL_TYPE: + d_emissivity = (double) ((FCELL *) inrast_emissivity)[col]; + break; + case DCELL_TYPE: + d_emissivity = ((DCELL *) inrast_emissivity)[col]; + break; + } + switch(data_type_tsw){ + case CELL_TYPE: + d_tsw = (double) ((CELL *) inrast_tsw)[col]; + break; + case FCELL_TYPE: + d_tsw = (double) ((FCELL *) inrast_tsw)[col]; + break; + case DCELL_TYPE: + d_tsw = ((DCELL *) inrast_tsw)[col]; + break; + } + switch(data_type_doy){ + case CELL_TYPE: + d_doy = (double) ((CELL *) inrast_doy)[col]; + break; + case FCELL_TYPE: + d_doy = (double) ((FCELL *) inrast_doy)[col]; + break; + case DCELL_TYPE: + d_doy = ((DCELL *) inrast_doy)[col]; + break; + } + switch(data_type_sunzangle){ + case CELL_TYPE: + d_sunzangle = (double) ((CELL *) inrast_sunzangle)[col]; + break; + case FCELL_TYPE: + d_sunzangle = (double) ((FCELL *) inrast_sunzangle)[col]; + break; + case DCELL_TYPE: + d_sunzangle = ((DCELL *) inrast_sunzangle)[col]; + break; + } if(G_is_d_null_value(&d_albedo)){ ((DCELL *) outrast)[col] = -999.99; }else if(G_is_d_null_value(&d_ndvi)){ @@ -363,7 +447,7 @@ // exit(EXIT_SUCCESS); // } } - if (G_put_raster_row (outfd, outrast, data_type_albedo) < 0) + if (G_put_raster_row (outfd, outrast, data_type_output) < 0) G_fatal_error(_("Cannot write to output raster file")); } From chemin at grass.itc.it Fri Mar 30 09:13:06 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Fri Mar 30 09:13:07 2007 Subject: [grass-addons] r375 - in trunk/grassaddons/gipe: r.eb.g0 r.evapo.PT Message-ID: <200703300713.l2U7D6FJ019062@grass.itc.it> Author: chemin Date: 2007-03-30 09:12:58 +0200 (Fri, 30 Mar 2007) New Revision: 375 Modified: trunk/grassaddons/gipe/r.eb.g0/g0.c trunk/grassaddons/gipe/r.eb.g0/main.c trunk/grassaddons/gipe/r.evapo.PT/description.html Log: Debugged r.eb.g0 and r.evapo.PT, tested them too, results seem OK now Modified: trunk/grassaddons/gipe/r.eb.g0/g0.c =================================================================== --- trunk/grassaddons/gipe/r.eb.g0/g0.c 2007-03-29 21:15:38 UTC (rev 374) +++ trunk/grassaddons/gipe/r.eb.g0/g0.c 2007-03-30 07:12:58 UTC (rev 375) @@ -21,7 +21,6 @@ // Spain (Bastiaanssen, 1995) result = (rnet * (tempk-273.15) / bbalb) * a * b ; -// printf("plga_g_0: result = %5.3f\n",result); // HAPEX-Sahel (Roerink, 1995) if(roerink){ Modified: trunk/grassaddons/gipe/r.eb.g0/main.c =================================================================== --- trunk/grassaddons/gipe/r.eb.g0/main.c 2007-03-29 21:15:38 UTC (rev 374) +++ trunk/grassaddons/gipe/r.eb.g0/main.c 2007-03-30 07:12:58 UTC (rev 375) @@ -294,13 +294,8 @@ /************************************/ /* calculate soil heat flux */ d = g_0(d_albedo,d_ndvi,d_tempk,d_rnet,d_time,roerink); - // printf(" || d=%5.3f",d); ((DCELL *) outrast)[col] = d; - // printf(" -> %5.3f\n",d); } - // if(row==50){ - // exit(EXIT_SUCCESS); - // } } if (G_put_raster_row (outfd, outrast, data_type_output) < 0) G_fatal_error(_("Cannot write to output raster file")); Modified: trunk/grassaddons/gipe/r.evapo.PT/description.html =================================================================== --- trunk/grassaddons/gipe/r.evapo.PT/description.html 2007-03-29 21:15:38 UTC (rev 374) +++ trunk/grassaddons/gipe/r.evapo.PT/description.html 2007-03-30 07:12:58 UTC (rev 375) @@ -3,7 +3,7 @@ r.evapo.PT Calculates the diurnal evapotranspiration after Prestley and Taylor (1972).

NOTES

- +RNETD optional output from r.evapo.potrad is giving good results as input for net radiation in this module.

TODO

From chemin at grass.itc.it Fri Mar 30 09:34:29 2007 From: chemin at grass.itc.it (chemin@grass.itc.it) Date: Fri Mar 30 09:34:29 2007 Subject: [grass-addons] r376 - trunk/grassaddons/gipe/script_examples Message-ID: <200703300734.l2U7YTVC019101@grass.itc.it> Author: chemin Date: 2007-03-30 09:34:24 +0200 (Fri, 30 Mar 2007) New Revision: 376 Modified: trunk/grassaddons/gipe/script_examples/grass_etpot.sh Log: Updated grass_ETPOT script to include ET Prestley-Taylor too Modified: trunk/grassaddons/gipe/script_examples/grass_etpot.sh =================================================================== --- trunk/grassaddons/gipe/script_examples/grass_etpot.sh 2007-03-30 07:12:58 UTC (rev 375) +++ trunk/grassaddons/gipe/script_examples/grass_etpot.sh 2007-03-30 07:34:24 UTC (rev 376) @@ -11,6 +11,9 @@ base=p127r050 date=20001104 doy=311.0 +time=11.07 +sunza=45.7 +patm=1010.0 # From here and onward dont change anything! #------------------------------------------- @@ -73,3 +76,18 @@ #clean maps r.null map=$base$date\ndvi setnull=-1.0 r.colors map=$base$date\ndvi rules=ndvi + + +#create precursor of ET Prestley-Taylor +r.mapcalc $base$date\patm=$patm +r.mapcalc $base$date\time=$time +r.mapcalc $base$date\sunza=$sunza +r.emissivity ndvi=$base$date\ndvi emissivity=$base$date\e0 --overwrite +r.eb.deltat -w tempk=$base$date\.61 delta=$base$date\delta --overwrite +r.mapcalc $base$date\tempka=$base$date\delta+$base$date\.61 + +r.eb.netrad albedo=$base$date\albedo ndvi=$base$date\ndvi tempk=$base$date\.61 time=$base$date\time dtair=$base$date\delta emissivity=$base$date\e0 tsw=$base$date\tsw doy=doy sunzangle=$base$date\sunza rnet=$base$date\rnet --overwrite +r.eb.g0 albedo=$base$date\albedo ndvi=$base$date\ndvi tempk=$base$date\.61 rnet=$base$date\rnet time=$base$date\time g0=$base$date\g0 --overwrite + +#calculate ET Prestley-Taylor +r.evapo.PT -z RNET=$base$date\rnetd G0=$base$date\g0 TEMPKA=$base$date\tempka PATM=$base$date\patm PT=1.26 output=$base$date\ETA_PT --overwrite From landa at grass.itc.it Fri Mar 30 13:29:43 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Fri Mar 30 13:29:45 2007 Subject: [grass-addons] r377 - in trunk/grassaddons/gui: gui_modules scripts Message-ID: <200703301129.l2UBThYI021920@grass.itc.it> Author: landa Date: 2007-03-30 13:29:08 +0200 (Fri, 30 Mar 2007) New Revision: 377 Added: trunk/grassaddons/gui/scripts/p.cmd Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/render.py Log: p.cmd script introduced Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 07:34:24 UTC (rev 376) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 11:29:08 UTC (rev 377) @@ -13,6 +13,7 @@ * MapApp """ +DEBUG = True # Authors: Michael Barton and Jachym Cepicky # COPYRIGHT: (C) 1999 - 2006 by the GRASS Development Team @@ -45,7 +46,6 @@ icons = os.environ["GRASS_ICONPATH"] Map = render.Map() # instance of Map class to render GRASS display output to PPM file -DEBUG = False # for cmdlinef cmdfilename = None @@ -77,33 +77,53 @@ if line: try: - #oper, lname, mapset, catlist, vallist, invert, opacity - # 0 1 2 3 4 5 6 - dispcmd = list(line.strip().split()) - #print dispcmd - if dispcmd[0]=="addraster": - try: mapset = eval(dispcmd[2]) - except: pass - try: catlist = eval(dispcmd[3]) - except: pass - try: vallist = eval(dispcmd[4]) - except: pass - try: invert = eval(dispcmd[5]) - except: pass - opacity = float(dispcmd[6]) + dispcmd = {} + name = None + mapset = None + opacity = 1 - print "# %s" % dispcmd[3] + cmd = list(line.strip().split()) + action = cmd[0] + cmd = cmd[1:] + + for kv in cmd: + if kv[0] == '-': # flag + dispcmd[kv[1:]] = True + else: # option + key,value = kv.split('=') + if key == "opacity": + try: + # opacity in [%] + opacity = int (value) / 100. + except: + pass + elif key == "map": + try: + name,mapset = value.split('@') + except: + name = value + mapset = None + else: + dispcmd[key] = value + + if DEBUG: + print "Command.run(): ", + print "opacity=%d name=%s mapset=%s" % (opacity, name, mapset), + print dispcmd - self.map.AddRasterLayer(name="%s" % (dispcmd[1]), - mapset=dispcmd[2], - catlist=1, - vallist=vallist, - l_opacity=opacity) + if action == "d.rast": + self.map.AddRasterLayer(name=name, + mapset=mapset, + l_opacity=opacity, + dispcmd=dispcmd) + elif action == "d.vect": + self.map.AddVectorLayer(name=name, + mapset=mapset, + l_opacity=opacity, + dispcmd=dispcmd) - if dispcmd[0]=="addvector": - self.map.AddVectorLayer(name="%s" % (dispcmd[1]), - mapset=dispcmd[2]) self.parent.redraw =True + except Exception, e: print "Command Thread: ",e pass Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-03-30 07:34:24 UTC (rev 376) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-03-30 11:29:08 UTC (rev 377) @@ -11,7 +11,7 @@ # # COPYRIGHT:(C) 1999 - 2007 by the GRASS Development Team -DEBUG = False +DEBUG = True class GRASSLayer: """ @@ -45,7 +45,7 @@ def __init__(self, type, name, mapset, active, hidden, opacity, - **parameters): + dispcmd={}): self.name = name self.mapset = mapset @@ -54,8 +54,13 @@ self.hidden = hidden self.opacity = opacity - self.grassLayer = GRASSLayer(parameters) + self.grassLayer = GRASSLayer(dispcmd) + if DEBUG: + print "MapLayer.__init__(): name=%s, mapset=%s, opacity=%d" % \ + (name, mapset, opacity), + print dispcmd + gtemp = utils.GetTempfile() self.maskfile = gtemp + ".pgm" self.mapfile = gtemp + ".ppm" @@ -69,16 +74,16 @@ try: self.cmd = "d.rast -o map=%s@%s" % (self.name, self.mapset) - for key in self.grassLayer.params.keys(): - value = self.grassLayer.params[key] + for key,value in self.grassLayer.params.iteritems(): + if type(value) == type(""): + self.cmd += " %s=%s" % \ + (key, value) + else: + self.cmd += " -%s" % key - if self.grassLayer.params[key]: - ##FIXME: test data type not strlen - if type(value) == type(""): - self.cmd += " %s=%s" % \ - (key, value) - else: - self.cmd += " -%s" % key + if DEBUG: + print "MapLayer.__renderRasterLayer():", + print self.cmd except StandardError, e: sys.stderr.write("Could not render raster layer <%s>: %s\n" %\ @@ -93,15 +98,17 @@ try: self.cmd = "d.vect map=%s@%s" % (self.name, self.mapset) - for key in self.grassLayer.params: - if self.grassLayer.params[key]: - ##FIXME: test data type not strlen - if len(key) > 1: - self.cmd += " %s=%s" % \ - (key, self.grassLayer.params[key]) - else: - self.cmd += " -%s" % key + for key,value in self.grassLayer.params.iteritems(): + if type(value) == type(""): + self.cmd += " %s=%s" % \ + (key, value) + else: + self.cmd += " -%s" % key + if DEBUG: + print "MapLayer.__renderVectorLayer():", + print self.cmd + except StandardError, e: sys.stderr.write("Could not render vector layer <%s>: %s\n" %\ (self.name, str(e))) @@ -639,18 +646,16 @@ os.environ["GRASS_REGION"] = tmp_region return None - def AddRasterLayer(self, name, mapset=None, catlist=None, - vallist=None, invertCats=False, l_active=True, l_hidden=False, - l_opacity=1, l_render=False): + def AddRasterLayer(self, name, mapset=None, + dispcmd = {}, + l_active=True, l_hidden=False, l_opacity=1, l_render=False): """ Adds raster layer to list of layers Layer Attributes: name - raster layer name mapset - mapset name, default: current - catlist - list of categories - vallist - list of values - invertCats - invert catlist, True/False + dicpcmd - display parameters (catlist, vallist, -i, etc.) l_active - see MapLayer class l_hidden @@ -669,11 +674,9 @@ if l_opacity < 0: l_opacity = 0 elif l_opacity > 1: l_opacity = 1 - layer = MapLayer("raster", name, mapset, - l_active, l_hidden, l_opacity, - catlist = catlist, - vallist = vallist, - i = invertCats) + layer = MapLayer(type="raster", name=name, mapset=mapset, + active=l_active, hidden=l_hidden, opacity=l_opacity, + dispcmd=dispcmd) # add maplayer to the list of layers self.layers.append(layer) @@ -726,51 +729,17 @@ return self.layers[-1] def AddVectorLayer(self, name, mapset=None, - type = "point,line,boundary,centroid,area,face", - display= "shape", attrcol= None, icon = "basic/circle", - size = 8, layer = 1, cats = None, where = None, width = 1, - wcolumn = None, wscale = 1, color = "000:000:000", - fcolor = "200:200:200", rgb_column = "GRASSRGB", llayer = 1, - lcolor = "256:000:000", bgcolor = None, bcolor = None, - lsize = 8, font = None, xref = "left", yref = "center", - minreg = None, maxreg = None, colorfromtable=False, - randomcolor=False, catsasid=False, l_active=True, - l_hidden=False, l_opacity=1, l_render=False): + dispcmd={}, + l_active=True, l_hidden=False, l_opacity=1, l_render=False): """ Adds vector layer to list of layers Layer attributes: name - raster layer name mapset - mapset name, default: current - type - feature type - display - display - attrcol - name of column to be displayed - icon - point and centroid symbol - size - symbol size - layer - layer number - cats - category values - where - WHERE conditions of SQL statement - width - line width - wcolumn - name of column for line widths - wscale - scale factor for wcolumn - color - line color - fcolor - area fill color - rgb_column - name of color definition column - llayer - layer number - lcolor - label color - bgcolor - lable border color - lsize - label size - font - font name - xref - label horizontal justification, default: left - yref - label horizontal justification, default: center - minreg - minimum region size when map is displayed - maxreg - maximum region size when map is displayed + dispcmd - see d.vect - colorfromtable - get colors from map table column - randomcolor - random colors according to category number - catsasid - use values from 'cats' option as line id - - l_active - see MapLayer class + l_active - see MapLayer class l_hidden l_opacity l_render - render an image @@ -786,36 +755,10 @@ if l_opacity < 0: l_opacity = 0 elif l_opacity > 1: l_opacity = 1 + maplayer = MapLayer(type="vector", name=name, mapset=mapset, + dispcmd=dispcmd, + active=l_active, hidden=l_hidden, opacity=l_opacity) - maplayer = MapLayer("vector", name, mapset, - l_active, l_hidden, l_opacity, - display = display, - attrcol = attrcol, - icon = icon, - size = size, - layer = layer, - cats = cats, - where = where, - width = width, - wcolumn = wcolumn, - wscale = wscale, - color = color, - fcolor = fcolor, - rgb_column = rgb_column, - llayer = llayer, - lcolor = lcolor, - bgcolor = bgcolor, - bcolor = bcolor, - lsize = lsize, - font = font, - xref = xref, - yref = yref, - minreg = minreg, - maxreg = maxreg, - colorfromtable = colorfromtable, - randomcolor = randomcolor, - catsasid = catsasid) - self.layers.append(maplayer) if l_render: @@ -1056,8 +999,8 @@ """ - overlay = MapLayer("overlay", command, mapset, - l_active, l_hidden, l_opacity) + overlay = MapLayer(type="overlay", name=command, mapset=mapset, + active=l_active, hidden=l_hidden, opacity=l_opacity) # add maplayer to the list of layers Added: trunk/grassaddons/gui/scripts/p.cmd =================================================================== --- trunk/grassaddons/gui/scripts/p.cmd (rev 0) +++ trunk/grassaddons/gui/scripts/p.cmd 2007-03-30 11:29:08 UTC (rev 377) @@ -0,0 +1,49 @@ +#!/bin/sh + +#%module +#% description: Wrapper for display commands and px monitors +#% keywords: display +#%end +#%option +#% key: cmd +#% type: string +#% required: yes +#% multiple: no +#% label: Command to be performed +#% description: Example: d.rast elevation.dem catlist=1000-1500 +#%end +#%option +#% key: opacity +#% type: string +#% required: no +#% multiple: no +#% key_desc: val[-val] +#% description: Set opacity between 0-100% +#% answer: 100 +#%end + +if [ -z "$GISBASE" ] ; then + echo "You must be in GRASS GIS to run this program." 1>&2 + exit 1 +fi + +if [ "$1" != "@ARGS_PARSED@" ] ; then + exec g.parser "$0" "$@" +fi + +cmdfile="`g.gisenv get=GRASS_PYCMDFILE`" + +if [ -e ${cmdfile} ] && [ -n "${cmdfile}" ]; then + : +else + g.message -e "GRASS_PYCMDFILE File not found. Run p.mon" + exit 1 +fi + +cmd="${GIS_OPT_CMD}" + +echo "p.cmd: ${cmd}" +echo ${cmd} >>${cmdfile} + +exit 0 + Property changes on: trunk/grassaddons/gui/scripts/p.cmd ___________________________________________________________________ Name: svn:executable + * From landa at grass.itc.it Fri Mar 30 13:56:45 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Fri Mar 30 13:56:46 2007 Subject: [grass-addons] r378 - trunk/grassaddons/gui/scripts Message-ID: <200703301156.l2UBujX7023284@grass.itc.it> Author: landa Date: 2007-03-30 13:56:29 +0200 (Fri, 30 Mar 2007) New Revision: 378 Modified: trunk/grassaddons/gui/scripts/p.cmd Log: cosmetics Modified: trunk/grassaddons/gui/scripts/p.cmd =================================================================== --- trunk/grassaddons/gui/scripts/p.cmd 2007-03-30 11:29:08 UTC (rev 377) +++ trunk/grassaddons/gui/scripts/p.cmd 2007-03-30 11:56:29 UTC (rev 378) @@ -1,7 +1,7 @@ #!/bin/sh #%module -#% description: Wrapper for display commands and px monitors +#% description: Wrapper for display commands and pX monitors #% keywords: display #%end #%option @@ -10,15 +10,15 @@ #% required: yes #% multiple: no #% label: Command to be performed -#% description: Example: d.rast elevation.dem catlist=1000-1500 +#% description: Example: "d.rast elevation.dem catlist=1000-1500 -i" #%end #%option #% key: opacity #% type: string #% required: no #% multiple: no -#% key_desc: val[-val] -#% description: Set opacity between 0-100% +#% key_desc: val +#% description: Opacity level in percentage #% answer: 100 #%end @@ -42,8 +42,8 @@ cmd="${GIS_OPT_CMD}" -echo "p.cmd: ${cmd}" -echo ${cmd} >>${cmdfile} +g.message -d message="$0: ${cmd}" +echo ${cmd} >> ${cmdfile} + exit 0 - From landa at grass.itc.it Fri Mar 30 14:30:41 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Fri Mar 30 14:30:42 2007 Subject: [grass-addons] r379 - in trunk/grassaddons/gui: gui_modules scripts Message-ID: <200703301230.l2UCUfO6023387@grass.itc.it> Author: landa Date: 2007-03-30 14:30:13 +0200 (Fri, 30 Mar 2007) New Revision: 379 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/render.py trunk/grassaddons/gui/scripts/p.cmd Log: accept missing key for the first option, e.g. d.rast soils Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 11:56:29 UTC (rev 378) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 12:30:13 UTC (rev 379) @@ -90,7 +90,13 @@ if kv[0] == '-': # flag dispcmd[kv[1:]] = True else: # option - key,value = kv.split('=') + try: + key,value = kv.split('=') + except: + # fisrt option + key = "map" + value = kv + if key == "opacity": try: # opacity in [%] @@ -104,7 +110,8 @@ name = value mapset = None else: - dispcmd[key] = value + dispcmd[key] = value + if DEBUG: print "Command.run(): ", Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-03-30 11:56:29 UTC (rev 378) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-03-30 12:30:13 UTC (rev 379) @@ -573,7 +573,8 @@ os.environ["GRASS_HEIGHT"] = str(self.height) if DEBUG: - print ("mapimg.py: Map: Render: force=%s" % (force)) + print ("Map.Render() force=%s" % (force)) + try: # render overlays self.ovlist = [] Modified: trunk/grassaddons/gui/scripts/p.cmd =================================================================== --- trunk/grassaddons/gui/scripts/p.cmd 2007-03-30 11:56:29 UTC (rev 378) +++ trunk/grassaddons/gui/scripts/p.cmd 2007-03-30 12:30:13 UTC (rev 379) @@ -10,7 +10,7 @@ #% required: yes #% multiple: no #% label: Command to be performed -#% description: Example: "d.rast elevation.dem catlist=1000-1500 -i" +#% description: Example: "d.rast map=elevation.dem@PERMANENT catlist=1300-1400 -i" #%end #%option #% key: opacity From landa at grass.itc.it Fri Mar 30 15:39:17 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Fri Mar 30 15:39:19 2007 Subject: [grass-addons] r380 - trunk/grassaddons/gui/gui_modules Message-ID: <200703301339.l2UDdH7S023955@grass.itc.it> Author: landa Date: 2007-03-30 15:39:00 +0200 (Fri, 30 Mar 2007) New Revision: 380 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: update status (extent) when extent of canvas is changed Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 12:30:13 UTC (rev 379) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 13:39:00 UTC (rev 380) @@ -7,6 +7,7 @@ mapdisp Package Classes: +* Command * BufferedWindow * DrawWindow * MapFrame @@ -155,9 +156,9 @@ """ def __init__(self, parent, id, - pos = wx.DefaultPosition, - size = wx.DefaultSize, - style=wx.NO_FULL_REPAINT_ON_RESIZE): + pos = wx.DefaultPosition, + size = wx.DefaultSize, + style=wx.NO_FULL_REPAINT_ON_RESIZE): wx.Window.__init__(self, parent, id, pos, size, style) self.parent = parent @@ -183,7 +184,7 @@ # Render output objects # self.mapfile = None # image file to be rendered - self.Img = "" # wx.Image object (self.mapfile) + self.img = "" # wx.Image object (self.mapfile) self.ovlist = [] # list of images for overlays # @@ -199,6 +200,7 @@ 'end': [0, 0], 'box': "point" } + self.zoomtype = 1 # 1 zoom in, 0 no zoom, -1 zoom out # OnSize called to make sure the buffer is initialized. @@ -234,12 +236,12 @@ self._Buffer = wx.EmptyBitmap(Map.width, Map.height) # get the image to be rendered - self.Img = self.GetImage() + self.img = self.GetImage() self.ovlist = self.GetOverlay() # update map display - if self.Img and Map.width + Map.height > 0: # scale image during resize - self.Img = self.Img.Scale(Map.width, Map.height) + if self.img and Map.width + Map.height > 0: # scale image during resize + self.img = self.img.Scale(Map.width, Map.height) self.render = False self.UpdateMap() @@ -274,28 +276,37 @@ be updated. """ + if DEBUG: + print "Buffered Window.UpdateMap(%s): render=%s" % (img, self.render) + if self.render: Map.width, Map.height = self.GetClientSize() self.mapfile = Map.Render(force=self.render) - self.Img = self.GetImage() + self.img = self.GetImage() self.resize = False - if not self.Img: return + if not self.img: return self.ovlist = self.GetOverlay() dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - self.Draw(dc, self.Img) + self.Draw(dc, self.img) if self.ovlist != []: for overlay in self.ovlist: self.Draw(dc, overlay) else: - if not self.Img: return + if not self.img: return self.ovlist = self.GetOverlay() dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - self.Draw(dc, self.Img) + self.Draw(dc, self.img) if self.ovlist != []: for overlay in self.ovlist: self.Draw(dc, overlay) + self.resize = False + # update statusbar + self.parent.statusbar.SetStatusText("Extent: %d,%d : %d,%d" % + (Map.region["w"], Map.region["e"], + Map.region["n"], Map.region["s"]), 0) + def EraseMap(self): """ Erase the map display @@ -310,7 +321,7 @@ dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) dc.SetBackground(wx.Brush("White")) - bitmap = wx.BitmapFromImage(self.Img) + bitmap = wx.BitmapFromImage(self.img) self.dragimg = wx.DragImage(bitmap) self.dragimg.BeginDrag((0, 0), self) self.dragimg.GetImageRect(moveto) @@ -324,7 +335,7 @@ """ Mouse zoom rectangles and lines """ - img = self.Img # composite map in background + img = self.img # composite map in background dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) if self.mouse['box'] == "box": mousecoords = [self.mouse['begin'][0], self.mouse['begin'][1], \ @@ -565,8 +576,8 @@ self.statusbar = self.CreateStatusBar(number=2, style=0) self.statusbar.SetStatusWidths([-2, -1]) map_frame_statusbar_fields = ["Extent: %d,%d : %d,%d" % - (Map.region["n"], Map.region["s"], - Map.region["w"], Map.region["e"]), + (Map.region["w"], Map.region["e"], + Map.region["n"], Map.region["s"]), "%s,%s" %(None, None)] for i in range(len(map_frame_statusbar_fields)): self.statusbar.SetStatusText(map_frame_statusbar_fields[i], i) @@ -588,7 +599,6 @@ self.MapWindow = DrawWindow(self) # initialize buffered DC self.MapWindow.Bind(wx.EVT_MOTION, self.OnMotion) - # # Bind various events # ONLY if we are running from GIS manager @@ -659,7 +669,7 @@ #set active display tuple in track track.Track().SetDisp(self.disp_idx, self) - # change bookcontrol page to page associted with display if > 1 display + # change bookcontrol page to page associted with display if > 1 display pg = track.Track().GetCtrls(self.disp_idx, 1) pg_count = self.ctrlbk.GetPageCount() pgnum = '0' @@ -720,7 +730,7 @@ self.MapWindow.zoomtype = 1 self.MapWindow.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH) - # change the cursor + # change the cursor self.MapWindow.SetCursor (self.cursors["cross"]) def OnZoomOut(self, event): From barton at grass.itc.it Fri Mar 30 16:23:01 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Mar 30 16:23:03 2007 Subject: [grass-addons] r381 - trunk/grassaddons/gui/gui_modules Message-ID: <200703301423.l2UEN1Sw024384@grass.itc.it> Author: barton Date: 2007-03-30 16:22:52 +0200 (Fri, 30 Mar 2007) New Revision: 381 Modified: trunk/grassaddons/gui/gui_modules/render.py Log: Updates for interactive scale and legend placing Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-03-30 13:39:00 UTC (rev 380) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-03-30 14:22:52 UTC (rev 381) @@ -1029,6 +1029,9 @@ return self.overlays[-1] + def changeOverlayActive(self, type, activ): + overlay = self.overlays[type] + overlay.active = activ def Clean(self): From barton at grass.itc.it Fri Mar 30 16:31:58 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Mar 30 16:31:59 2007 Subject: [grass-addons] r382 - trunk/grassaddons/gui/gui_modules Message-ID: <200703301431.l2UEVwT5024411@grass.itc.it> Author: barton Date: 2007-03-30 16:31:45 +0200 (Fri, 30 Mar 2007) New Revision: 382 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Close to having easily placeable scale and legend Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 14:22:52 UTC (rev 381) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 14:31:45 UTC (rev 382) @@ -86,7 +86,7 @@ cmd = list(line.strip().split()) action = cmd[0] cmd = cmd[1:] - + for kv in cmd: if kv[0] == '-': # flag dispcmd[kv[1:]] = True @@ -112,8 +112,8 @@ mapset = None else: dispcmd[key] = value - - + + if DEBUG: print "Command.run(): ", print "opacity=%d name=%s mapset=%s" % (opacity, name, mapset), @@ -208,6 +208,16 @@ # platforms at initialization, but little harm done. #!!! self.OnSize(None) + # create a PseudoDC for map decorations like scales and legends + self.pdc = wx.PseudoDC() + + self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x:None) + + # vars for handling mouse clicks + self.dragid = -1 + self.lastpos = (0,0) + + def Draw(self, dc, img=None, dctype='image', coords='0,0'): """ Just here as a place holder. @@ -221,6 +231,12 @@ """ dc = wx.BufferedPaintDC(self, self._Buffer) + # pseudoDC for map decorations like scale and legend + rgn = self.GetUpdateRegion() + rgn.Offset(0,0) + r = rgn.GetBox() + self.pdc.DrawToDCClipped(dc,r) + def OnSize(self, event): """ The Buffer init is done here, to make sure the buffer is always @@ -268,7 +284,7 @@ self._Buffer.SaveFile(FileName, FileType) def UpdateMap(self, img=None): - """ + """ This would get called if the drawing needed to change, for whatever reason. The idea here is that the drawing is based on some data generated @@ -276,29 +292,31 @@ be updated. """ + if DEBUG: print "Buffered Window.UpdateMap(%s): render=%s" % (img, self.render) - if self.render: - Map.width, Map.height = self.GetClientSize() - self.mapfile = Map.Render(force=self.render) - self.img = self.GetImage() - self.resize = False - if not self.img: return + + if self.render: + Map.width, Map.height = self.GetClientSize() + self.mapfile = Map.Render(force=self.render) + self.Img = self.GetImage() + self.resize = False + if not self.Img: return self.ovlist = self.GetOverlay() - dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - self.Draw(dc, self.img) if self.ovlist != []: for overlay in self.ovlist: - self.Draw(dc, overlay) - else: - if not self.img: return + self.DrawOvl(self.pdc, overlay) + dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) + self.Draw(dc, self.Img) + else: + if not self.Img: return self.ovlist = self.GetOverlay() - dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - self.Draw(dc, self.img) if self.ovlist != []: for overlay in self.ovlist: - self.Draw(dc, overlay) + self.DrawOvl(self.pdc, overlay) + dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) + self.Draw(dc, self.Img) self.resize = False @@ -329,8 +347,22 @@ dc.Clear() self.dragimg.DoDrawImage(dc, moveto) self.dragimg.EndDrag() - ## self.dragimg.UpdateBackingFromWindow(dc, memdc, sourcerect,destrect) + def DragItem(self, lastpos, event): + x,y = lastpos + dx = event.GetX() - x + dy = event.GetY() - y + r = self.pdc.GetIdBounds(self.dragid) + self.pdc.TranslateId(self.dragid, dx, dy) + dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) + dc.SetBackground(wx.Brush(self.GetBackgroundColour())) + bitmap = wx.BitmapFromImage(self.Img) + dc.Clear() # make sure you clear the bitmap! + dc.DrawBitmap(bitmap, 0, 0, True) # draw the composite map + self.pdc.DrawToDC(dc) + self.RefreshRect(r, True) + self.lastpos = (event.GetX(),event.GetY()) + def MouseDraw(self): """ Mouse zoom rectangles and lines @@ -352,11 +384,12 @@ """ Mouse motion and button click notifier """ - wheel = event.GetWheelRotation() # +- int + wheel = event.GetWheelRotation() # +- int # left mouse button pressed - if event.LeftDown(): + hitradius = 5 # distance for selecting map decorations + if event.LeftDown(): # start point of zoom box or drag - self.mouse['begin'] = event.GetPositionTuple()[:] + self.mouse['begin'] = event.GetPositionTuple()[:] # left mouse button released and not just a pointer elif event.LeftUp(): @@ -366,28 +399,59 @@ # set region in zoom or pan self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype) + # redraw map + self.render=True + self.UpdateMap() + # digitizing + elif self.parent.digittoolbar: + if self.parent.digittoolbar.digitize == "point": + east,north= self.Pixel2Cell(self.mouse['end'][0],self.mouse['end'][1]) + self.parent.digittoolbar.AddPoint(east,north) + # redraw map + self.render=True + self.UpdateMap() else: - # digitizing - if self.parent.digittoolbar: - if self.parent.digittoolbar.digitize == "point": - east,north= self.Pixel2Cell(self.mouse['end'][0],self.mouse['end'][1]) - self.parent.digittoolbar.AddPoint(east,north) - # redraw map - self.render=True - self.UpdateMap() + self.dragid = -1 - # dragging or drawing box with left button - elif event.Dragging() and event.LeftIsDown: - currpos = event.GetPositionTuple()[:] - end = (currpos[0]-self.mouse['begin'][0], \ - currpos[1]-self.mouse['begin'][1]) - if self.mouse['box'] == 'drag': - self.DragMap(end) - else: - self.mouse['end'] = event.GetPositionTuple()[:] - self.MouseDraw() + elif event.ButtonDClick(): + x,y = event.GetPositionTuple()[:] + #l = self.pdc.FindObjectsByBBox(x, y) + l = self.pdc.FindObjects(x, y, hitradius) + if l: + self.pdc.SetIdGreyedOut(l[0], not self.pdc.GetIdGreyedOut(l[0])) + r = self.pdc.GetIdBounds(l[0]) + r.Inflate(4,4) + r.OffsetXY(0,0) + self.RefreshRect(r, False) + elif event.RightDown(): + x,y = event.GetPositionTuple()[:] + #l = self.pdc.FindObjectsByBBox(x, y) + l = self.pdc.FindObjects(x, y, hitradius) + for id in l: + if not self.pdc.GetIdGreyedOut(id): + self.dragid = id + self.lastpos = (event.GetX(),event.GetY()) + break + + elif event.Dragging(): + currpos = event.GetPositionTuple()[:] + end = (currpos[0]-self.mouse['begin'][0], \ + currpos[1]-self.mouse['begin'][1]) + # dragging or drawing box with left button + if event.LeftIsDown(): + if self.mouse['box'] == 'drag': + self.DragMap(end) + else: + self.mouse['end'] = event.GetPositionTuple()[:] + self.MouseDraw() + + elif event.RightIsDown(): + # dragging item with right button + if self.dragid != -1: + self.DragItem(self.lastpos,event) + # zoom on mouse wheel elif wheel != 0: @@ -407,7 +471,9 @@ if Map.ovlist: for ovlfile in Map.ovlist: if os.path.isfile(ovlfile) and os.path.getsize(ovlfile): - ovlist.append(wx.Image(ovlfile, wx.BITMAP_TYPE_ANY)) + img = wx.Image(ovlfile, wx.BITMAP_TYPE_ANY) + img.ConvertAlphaToMask() + ovlist.append(img) return ovlist @@ -479,6 +545,66 @@ Map.region['e'] = newreg['e'] Map.region['w'] = newreg['w'] + + def DrawOvl(self, pdc, data, pdctype='image', coords=[0, 0]): + """ + Draws map decorations on top of map + """ + pdc.BeginDrawing() +# pdc.SetBackground(wx.Brush(self.GetBackgroundColour())) +# pdc.Clear() # make sure you clear the bitmap! + + if pdctype == 'clear': # erase the display + pdc.Clear() + pdc.EndDrawing() + return + + if pdctype == 'image': + id = wx.NewId() + pdc.SetId(id) + bitmap = wx.BitmapFromImage(data) + w,h = bitmap.GetSize() + pdc.DrawBitmap(bitmap, coords[0], coords[1], True) # draw the composite map + pdc.SetIdBounds(id,wx.Rect(coords[0], coords[1], w, h)) + + elif pdctype == 'box': # draw a box on top of the map + pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) + pdc.SetPen(self.pen) + pdc.DrawRectangle(coords[0],coords[1],coords[2]-coords[0],coords[2]-coords[1]) + r = wx.Rect(coords[0],coords[1],coords[2]-coords[0],coords[2]-coords[1]) + r.Inflate(pen.GetWidth(),pen.GetWidth()) + pdc.SetIdBounds(id,r) + + elif pdctype == 'line': # draw a line on top of the map + pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) + pdc.SetPen(self.pen) + dc.DrawLine(coords[0], coords[1], coords[2], coords[3]) + r = wx.Rect(coords[0],coords[1],coords[2]-coords[0],coords[2]-coords[1]) + r.Inflate(pen.GetWidth(),pen.GetWidth()) + pdc.SetIdBounds(id,r) + + elif pdctype == 'point': #draw point + pen = self.RandomPen() + pdc.SetPen(pen) + pdc.DrawPoint(coords[0], coords[1]) + r = wx.Rect(coords[0], coords[1], 1, 1) + r.Inflate(pen.GetWidth(),pen.GetWidth()) + pdc.SetIdBounds(id,r) + + elif pdctype == 'text': # draw text on top of map + text = data + w,h = self.GetFullTextExtent(text)[0:2] + pdc.SetFont(self.GetFont()) + pdc.SetTextForeground(self.RandomColor()) + pdc.SetTextBackground(self.RandomColor()) + pdc.DrawText(text, coords[0], coords[1]) + r = wx.Rect(coords[0], coords[1], w, h) + r.Inflate(2,2) + pdc.SetIdBounds(id, r) + + pdc.EndDrawing() + + class DrawWindow(BufferedWindow): """ Drawing routine for double buffered drawing. Overwrites Draw method @@ -592,6 +718,7 @@ Map.addOverlay(type=0, command='', l_active=False, l_render=True) Map.addOverlay(type=1, command='', l_active=False, l_render=True) + # # Init map display # @@ -682,10 +809,10 @@ self.ctrlbk.SetSelection(pgnum) event.Skip() - def SetDcommandList(self, clst): - self.MapWindow.dcmd_list = clst - self.MapWindow.ProcessDcommand() - self.MapWindow.UpdateMap() +# def SetDcommandList(self, clst): +# self.MapWindow.dcmd_list = clst +# self.MapWindow.ProcessDcommand() +# self.MapWindow.UpdateMap() def OnMotion(self, event): """ @@ -708,11 +835,11 @@ """ self.MapWindow.UpdateMap() - def ReDrawCommand(self): - """ - d.* command on command line and enter pressed. - """ - self.MapWindow.UpdateMap() +# def ReDrawCommand(self): +# """ +# d.* command on command line and enter pressed. +# """ +# self.MapWindow.UpdateMap() def Pointer(self, event): """Pointer button clicled""" @@ -785,10 +912,10 @@ self.decmenu = wx.Menu() # Add items to the menu self.addscale = wx.MenuItem(self.decmenu, -1,'Add scalebar and north arrow') -# bmp = wx.Image(os.path.join(icons,'module-d.barscale.gif'), wx.BITMAP_TYPE_GIF) -# bmp.Rescale(16, 16) -# bmp = bmp.ConvertToBitmap() - self.addscale.SetBitmap(self.bmpscale) + bmp = wx.Image(os.path.join(icons,'module-d.barscale.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + self.addscale.SetBitmap(bmp) self.decmenu.AppendItem(self.addscale) self.Bind(wx.EVT_MENU, self.addBarscale, self.addscale) @@ -800,15 +927,39 @@ def addBarscale(self, event): self.params = [] layer = 0 - if self.ovlchk == True: - self.ovlchk = False - self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) + DecDialog(self, wx.ID_ANY, 'Scale and arrow') + + dlg = DecDialog(self, wx.ID_ANY, 'Scale and North arrow', size=(350, 200), + style=wx.DEFAULT_DIALOG_STYLE, + togletxt = "Show/hide scale and arrow", + ctrltxt = "scale object") + + dlg.CenterOnScreen() + + # this does not return until the dialog is closed. + val = dlg.ShowModal() + + if val == wx.ID_OK: + print "You pressed OK" + ovlist = self.MapWindow.GetOverlay() + if ovlist != []: + for overlay in ovlist: + self.MapWindow.DrawOvl(self.MapWindow.pdc, overlay) else: - self.ovlchk = True - self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_OTHER, (16,16)) - menuform.GUI().parseCommand('d.barscale', gmpath, completed=(self.getOptData,layer,self.params), parentframe=None) - pass + print "You pressed Cancel" + dlg.Destroy() + + +# if self.ovlchk == True: +# self.ovlchk = False +# self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) +# else: +# self.ovlchk = True +# self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_OTHER, (16,16)) +# menuform.GUI().parseCommand('d.barscale', gmpath, completed=(self.getOptData,layer,self.params), parentframe=None) +# pass + def addGrid(self, event): self.params = [] layer = 1 @@ -880,6 +1031,67 @@ # end of class MapFrame +class DecDialog(wx.Dialog): + def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize, + style=wx.DEFAULT_DIALOG_STYLE, togletxt='', ctrltxt=''): + wx.Dialog.__init__(self, parent, id, title, pos, size, style) + + sizer = wx.BoxSizer(wx.VERTICAL) + + box = wx.BoxSizer(wx.HORIZONTAL) + chkbox = wx.CheckBox(self, wx.ID_ANY, togletxt ) + box.Add(chkbox, 0, wx.ALIGN_CENTRE|wx.ALL, 5) + sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + box = wx.BoxSizer(wx.HORIZONTAL) + optnbtn = wx.Button(self, wx.ID_ANY, "Set options") + box.Add(optnbtn, 0, wx.ALIGN_CENTRE|wx.ALL, 5) + sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + box = wx.BoxSizer(wx.HORIZONTAL) + label = wx.StaticText(self, -1, ("Double-click %s and drag with mouse to position" % ctrltxt)) + box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5) + sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL) + sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5) + + btnsizer = wx.StdDialogButtonSizer() + +# if wx.Platform != "__WXMSW__": +# btn = wx.ContextHelpButton(self) +# btnsizer.AddButton(btn) + + btn = wx.Button(self, wx.ID_OK) + btn.SetHelpText("The OK button completes the dialog") + btn.SetDefault() + btnsizer.AddButton(btn) + + btn = wx.Button(self, wx.ID_CANCEL) + btn.SetHelpText("The Cancel button cnacels the dialog.") + btnsizer.AddButton(btn) + btnsizer.Realize() + + sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + self.SetSizer(sizer) + sizer.Fit(self) + + self.Bind(wx.EVT_CHECKBOX, self.onToggle, chkbox) + self.Bind(wx.EVT_BUTTON, self.onOptions, optnbtn) + + + def onToggle(self, event): + check = event.IsChecked() + Map.changeOverlayActive(0, check) + + def onOptions(self, event): + self.params = [] + layer = 0 + menuform.GUI().parseCommand('d.barscale', gmpath, + completed=(self.Parent.getOptData,layer,self.params), + parentframe=None) + class MapApp(wx.App): """ MapApp class @@ -915,8 +1127,6 @@ self.mapFrm.ReDraw(None) self.redraw = False return - - # end of class MapApp if __name__ == "__main__": From landa at grass.itc.it Fri Mar 30 16:49:36 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Fri Mar 30 16:49:38 2007 Subject: [grass-addons] r383 - trunk/grassaddons/gui/gui_modules Message-ID: <200703301449.l2UEnaFZ024511@grass.itc.it> Author: landa Date: 2007-03-30 16:49:22 +0200 (Fri, 30 Mar 2007) New Revision: 383 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: cosmetics (variable name lower-case) Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 14:31:45 UTC (rev 382) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 14:49:22 UTC (rev 383) @@ -300,23 +300,23 @@ if self.render: Map.width, Map.height = self.GetClientSize() self.mapfile = Map.Render(force=self.render) - self.Img = self.GetImage() + self.img = self.GetImage() self.resize = False - if not self.Img: return + if not self.img: return self.ovlist = self.GetOverlay() if self.ovlist != []: for overlay in self.ovlist: self.DrawOvl(self.pdc, overlay) dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - self.Draw(dc, self.Img) + self.Draw(dc, self.img) else: - if not self.Img: return + if not self.img: return self.ovlist = self.GetOverlay() if self.ovlist != []: for overlay in self.ovlist: self.DrawOvl(self.pdc, overlay) dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) - self.Draw(dc, self.Img) + self.Draw(dc, self.img) self.resize = False @@ -356,7 +356,7 @@ self.pdc.TranslateId(self.dragid, dx, dy) dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) dc.SetBackground(wx.Brush(self.GetBackgroundColour())) - bitmap = wx.BitmapFromImage(self.Img) + bitmap = wx.BitmapFromImage(self.img) dc.Clear() # make sure you clear the bitmap! dc.DrawBitmap(bitmap, 0, 0, True) # draw the composite map self.pdc.DrawToDC(dc) From cepicky at grass.itc.it Fri Mar 30 17:14:12 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Fri Mar 30 17:14:14 2007 Subject: [grass-addons] r384 - in trunk/grassaddons/gui: gui_modules images Message-ID: <200703301514.l2UFECI4025484@grass.itc.it> Author: cepicky Date: 2007-03-30 17:14:12 +0200 (Fri, 30 Mar 2007) New Revision: 384 Added: trunk/grassaddons/gui/gui_modules/sqlbuilder.py trunk/grassaddons/gui/images/grass_sql.png Log: started work on sql query builder need help with sizers - it is really a pain Added: trunk/grassaddons/gui/gui_modules/sqlbuilder.py =================================================================== --- trunk/grassaddons/gui/gui_modules/sqlbuilder.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/sqlbuilder.py 2007-03-30 15:14:12 UTC (rev 384) @@ -0,0 +1,165 @@ +#!/usr/bin/env python +""" + Usage: + sqlbuilder.py table_name + +""" + +import wx +import os,sys +import time + +import grassenv +import images +imagepath = images.__path__[0] +sys.path.append(imagepath) + + +class SQLFrame(wx.Frame): + def __init__(self, parent, id, title, table, qtype="select"): + wx.Frame.__init__(self, parent, -1, title) + + self.SetTitle("SQL Builder for GRASS GIS - %s " % (qtype.upper())) + self.SetIcon(wx.Icon(os.path.join(imagepath,'grass_sql.png'), wx.BITMAP_TYPE_ANY)) + + # + # variables + # + self.tablename = table # name of the table "select * from #self.tablename# " + self.qtype = qtype # type of the uqery: SELECT, UPDATE, DELETE, ... + self.columns = [] # array with column names + self.colvalues = [] # arrya with uniqe values in selected column + + # Init + self.GetColumns() + + + # + # Buttons + # + self.btn_clear = wx.Button(self, -1, "Clear") + self.btn_verify = wx.Button(self, -1, "Verify") + self.btn_help = wx.Button(self, -1, "Help") + self.btn_load = wx.Button(self, -1, "Load") + self.btn_save = wx.Button(self, -1, "Save") + self.btn_apply = wx.Button(self, -1, "Apply") + self.btn_close = wx.Button(self, -1, "Close") + self.btn_uniqe = wx.Button(self, -1, "Get unique values") + + self.btn_is = wx.Button(self, -1, "=") + self.btn_isnot = wx.Button(self, -1, "!=") + self.btn_like = wx.Button(self, -1, "LIKE") + self.btn_gt = wx.Button(self, -1, ">=") + self.btn_gtis = wx.Button(self, -1, ">") + self.btn_lt = wx.Button(self, -1, "<=") + self.btn_ltis = wx.Button(self, -1, "<") + self.btn_or = wx.Button(self, -1, "OR") + self.btn_not = wx.Button(self, -1, "NOT") + self.btn_and = wx.Button(self, -1, "AND") + self.btn_brackets = wx.Button(self, -1, "()") + self.btn_prc = wx.Button(self, -1, "%") + + # + # Text labels + # + #self.label_headding = wx.StaticText(self, -1, '') + + # + # Textareas + # + self.text_sql = wx.TextCtrl(self, -1, '', size=(-1,50),style=wx.TE_MULTILINE) + + # + # List Boxes + # + self.list_columns = wx.ListBox(self, -1, wx.DefaultPosition, (130, 130), self.columns, wx.LB_MULTIPLE|wx.LB_SORT) + self.list_values = wx.ListBox(self, -1, wx.DefaultPosition, (130, 130), self.colvalues, wx.LB_MULTIPLE|wx.LB_SORT) + + # + # Bindings + # + self.btn_uniqe.Bind(wx.EVT_BUTTON, self.GetUniqueValues) + + # + # Layout + # + pagesizer = wx.BoxSizer(wx.VERTICAL) + + buttonsizer1 = wx.BoxSizer(wx.HORIZONTAL) + buttonsizer1.Add(self.btn_clear, 0, wx.LEFT|wx.RIGHT, 5) + buttonsizer1.Add(self.btn_verify, 0, wx.LEFT|wx.RIGHT, 5 ) + buttonsizer1.Add(self.btn_help, 0, wx.LEFT|wx.RIGHT, 5, ) + buttonsizer1.Add(self.btn_load, 0, wx.LEFT|wx.RIGHT, 5,) + buttonsizer1.Add(self.btn_save, 0, wx.LEFT|wx.RIGHT, 5, ) + buttonsizer1.Add(self.btn_apply, 0, wx.LEFT|wx.RIGHT, 5, ) + + buttonsizer2 = wx.GridBagSizer(2, 2) + buttonsizer2.Add(self.btn_is, (0,0)) + buttonsizer2.Add(self.btn_isnot, (1,0)) + buttonsizer2.Add(self.btn_like, (2, 0)) + + buttonsizer2.Add(self.btn_gt, (0, 1)) + buttonsizer2.Add(self.btn_gtis, (1, 1)) + buttonsizer2.Add(self.btn_or, (2, 1)) + + buttonsizer2.Add(self.btn_lt, (0, 2)) + buttonsizer2.Add(self.btn_ltis, (1, 2)) + buttonsizer2.Add(self.btn_not, (2, 2)) + + buttonsizer2.Add(self.btn_brackets, (0, 3)) + buttonsizer2.Add(self.btn_prc, (1, 3)) + buttonsizer2.Add(self.btn_and, (2, 3)) + + buttonsizer3 = wx.GridSizer(4, 3, 3, 3) + buttonsizer3.Add(self.btn_apply,0,wx.RIGHT,5) + buttonsizer3.Add(self.btn_close,0,wx.RIGHT,5) + + hsizer1 = wx.GridSizer(2, 2, 0, 0) + hsizer1.Add((wx.StaticText(self,-1,"Columns: ",size=(-1,22))), proportion=0,border=0) + hsizer1.Add((wx.StaticText(self,-1,"Unique values: ", size=(-1,22))), proportion=0,border=0) + hsizer1.Add(self.list_columns, 1, wx.EXPAND) + hsizer1.Add(self.list_values, 1, wx.EXPAND) + + pagesizer.Add((wx.StaticText(self,-1,self.qtype,size=(-1,22))), 0, 0) + pagesizer.Add(hsizer1, 1, wx.EXPAND, 0) + pagesizer.Add(self.btn_uniqe,0,wx.ALIGN_LEFT|wx.TOP,border=5) + pagesizer.Add(buttonsizer2, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, border=5) + pagesizer.Add(self.text_sql, proportion=1, flag=wx.EXPAND|wx.TOP, border=5) + pagesizer.Add(buttonsizer1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 5) + pagesizer.Add(buttonsizer3, proportion=0, flag=wx.TOP, border=5) + self.SetAutoLayout(True) + self.SetSizer(pagesizer) + pagesizer.Fit(self) + #pagesizer.SetSizeHints(self) + self.Layout() + self.Show(True) + + def GetColumns(self): + for line in os.popen("db.columns table=%s" % (self.tablename)): + self.columns.append(line.strip()) + return + + def GetUniqueValues(self,event): + vals = [] + try: + idx = self.list_columns.GetSelections()[0] + except: + return + self.list_values.Clear() + column = self.list_columns.GetString(idx) + for line in os.popen("""db.select -c sql="SELECT %s FROM %s" """ %\ + (column,self.tablename)): + self.list_values.Insert(line.strip(),0) + + +if __name__ == "__main__": + + if len(sys.argv) != 2: + print >>sys.stderr, __doc__ + sys.exit() + + app = wx.App(0) + sqlb = SQLFrame(None, -1, 'SQL Buiilder',sys.argv[1]) + app.MainLoop() + + Added: trunk/grassaddons/gui/images/grass_sql.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/images/grass_sql.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From cepicky at grass.itc.it Fri Mar 30 17:26:23 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Fri Mar 30 17:26:24 2007 Subject: [grass-addons] r385 - trunk/grassaddons/gui/gui_modules Message-ID: <200703301526.l2UFQNYV025624@grass.itc.it> Author: cepicky Date: 2007-03-30 17:26:23 +0200 (Fri, 30 Mar 2007) New Revision: 385 Modified: trunk/grassaddons/gui/gui_modules/sqlbuilder.py Log: started work on sql query builder need help with sizers - it is really a pain Modified: trunk/grassaddons/gui/gui_modules/sqlbuilder.py =================================================================== --- trunk/grassaddons/gui/gui_modules/sqlbuilder.py 2007-03-30 15:14:12 UTC (rev 384) +++ trunk/grassaddons/gui/gui_modules/sqlbuilder.py 2007-03-30 15:26:23 UTC (rev 385) @@ -79,6 +79,18 @@ # Bindings # self.btn_uniqe.Bind(wx.EVT_BUTTON, self.GetUniqueValues) + self.btn_is.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_isnot.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_like.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_gt.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_gtis.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_or.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_lt.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_ltis.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_not.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_brackets.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_prc.Bind(wx.EVT_BUTTON, self.AddMark) + self.btn_and.Bind(wx.EVT_BUTTON, self.AddMark) # # Layout @@ -150,6 +162,18 @@ for line in os.popen("""db.select -c sql="SELECT %s FROM %s" """ %\ (column,self.tablename)): self.list_values.Insert(line.strip(),0) + + def AddMark(self,event): + sqlstr = self.text_sql.GetValue() + newsqlstr = '' + position = self.text_sql.GetLastPosition() + selection = self.text_sql.GetSelection() + + newsqlstr = sqlstr[:position] + newsqlstr += event.GetValue() + newsqlstr += " "+sqlstr[position:] + + self.text_sql.SetValue(newsqlstr) if __name__ == "__main__": From cepicky at grass.itc.it Fri Mar 30 17:58:35 2007 From: cepicky at grass.itc.it (cepicky@grass.itc.it) Date: Fri Mar 30 17:58:36 2007 Subject: [grass-addons] r386 - trunk/grassaddons/gui/gui_modules Message-ID: <200703301558.l2UFwZjV026165@grass.itc.it> Author: cepicky Date: 2007-03-30 17:58:35 +0200 (Fri, 30 Mar 2007) New Revision: 386 Modified: trunk/grassaddons/gui/gui_modules/sqlbuilder.py Log: mar buttons and column and value selection now working Modified: trunk/grassaddons/gui/gui_modules/sqlbuilder.py =================================================================== --- trunk/grassaddons/gui/gui_modules/sqlbuilder.py 2007-03-30 15:26:23 UTC (rev 385) +++ trunk/grassaddons/gui/gui_modules/sqlbuilder.py 2007-03-30 15:58:35 UTC (rev 386) @@ -27,7 +27,8 @@ # self.tablename = table # name of the table "select * from #self.tablename# " self.qtype = qtype # type of the uqery: SELECT, UPDATE, DELETE, ... - self.columns = [] # array with column names + self.column_names = [] # array with column names + self.columns = {} # array with colum properties self.colvalues = [] # arrya with uniqe values in selected column # Init @@ -72,7 +73,7 @@ # # List Boxes # - self.list_columns = wx.ListBox(self, -1, wx.DefaultPosition, (130, 130), self.columns, wx.LB_MULTIPLE|wx.LB_SORT) + self.list_columns = wx.ListBox(self, -1, wx.DefaultPosition, (130, 130), self.column_names, wx.LB_MULTIPLE|wx.LB_SORT) self.list_values = wx.ListBox(self, -1, wx.DefaultPosition, (130, 130), self.colvalues, wx.LB_MULTIPLE|wx.LB_SORT) # @@ -92,6 +93,9 @@ self.btn_prc.Bind(wx.EVT_BUTTON, self.AddMark) self.btn_and.Bind(wx.EVT_BUTTON, self.AddMark) + self.list_columns.Bind(wx.EVT_LISTBOX, self.AddColumnName) + self.list_values.Bind(wx.EVT_LISTBOX, self.AddValue) + # # Layout # @@ -148,7 +152,10 @@ def GetColumns(self): for line in os.popen("db.columns table=%s" % (self.tablename)): - self.columns.append(line.strip()) + self.column_names.append(line.strip()) + for line in os.popen("db.describe -c table=%s" % (self.tablename)).readlines()[1:]: + x,name,ctype = line.strip().split(":") + self.columns[name] = {'type':ctype} return def GetUniqueValues(self,event): @@ -163,19 +170,58 @@ (column,self.tablename)): self.list_values.Insert(line.strip(),0) + def AddColumnName(self,event): + idx = self.list_columns.GetSelections()[0] + column = self.list_columns.GetString(idx) + self.__addSomething(column) + + def AddValue(self,event): + idx = self.list_values.GetSelections()[0] + value = self.list_values.GetString(idx) + idx = self.list_columns.GetSelections()[0] + column = self.list_columns.GetString(idx) + + if self.columns[column]['type'].lower().find("chara") > -1: + value = "'%s'" % value + self.__addSomething(value) + def AddMark(self,event): + + + if event.GetId() == self.btn_is.GetId(): mark = "=" + elif event.GetId() == self.btn_isnot.GetId(): mark = "!=" + elif event.GetId() == self.btn_like.GetId(): mark = "LIKE" + elif event.GetId() == self.btn_gt.GetId(): mark = ">" + elif event.GetId() == self.btn_gtis.GetId(): mark = ">=" + elif event.GetId() == self.btn_lt.GetId(): mark = "<" + elif event.GetId() == self.btn_ltis.GetId(): mark = "<=" + elif event.GetId() == self.btn_or.GetId(): mark = "OR" + elif event.GetId() == self.btn_not.GetId(): mark = "NOT" + elif event.GetId() == self.btn_and.GetId(): mark = "AND" + elif event.GetId() == self.btn_brackets.GetId(): mark = "()" + elif event.GetId() == self.btn_prc.GetId(): mark = "%" + self.__addSomething(mark) + + + def __addSomething(self,what): sqlstr = self.text_sql.GetValue() newsqlstr = '' position = self.text_sql.GetLastPosition() selection = self.text_sql.GetSelection() newsqlstr = sqlstr[:position] - newsqlstr += event.GetValue() + try: + if newsqlstr[-1] != " ": + newsqlstr += " " + except: + pass + newsqlstr += what newsqlstr += " "+sqlstr[position:] self.text_sql.SetValue(newsqlstr) - + self.text_sql.SetInsertionPoint(position) + if __name__ == "__main__": if len(sys.argv) != 2: From barton at grass.itc.it Fri Mar 30 18:42:45 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Mar 30 18:42:46 2007 Subject: [grass-addons] r387 - trunk/grassaddons/gui/gui_modules Message-ID: <200703301642.l2UGgjXc026293@grass.itc.it> Author: barton Date: 2007-03-30 18:42:39 +0200 (Fri, 30 Mar 2007) New Revision: 387 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: More work on placing scales with mouse Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 15:58:35 UTC (rev 386) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 16:42:39 UTC (rev 387) @@ -14,7 +14,7 @@ * MapApp """ -DEBUG = True +DEBUG = False # Authors: Michael Barton and Jachym Cepicky # COPYRIGHT: (C) 1999 - 2006 by the GRASS Development Team @@ -304,9 +304,11 @@ self.resize = False if not self.img: return self.ovlist = self.GetOverlay() + # redraw decorations on resize event + self.DrawOvl(self.pdc, data=None, pdctype='clear') if self.ovlist != []: for overlay in self.ovlist: - self.DrawOvl(self.pdc, overlay) + self.DrawOvl(self.pdc, data=overlay, pdctype='image') dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) self.Draw(dc, self.img) else: @@ -925,12 +927,11 @@ self.decmenu.Destroy() def addBarscale(self, event): - self.params = [] - layer = 0 DecDialog(self, wx.ID_ANY, 'Scale and arrow') dlg = DecDialog(self, wx.ID_ANY, 'Scale and North arrow', size=(350, 200), style=wx.DEFAULT_DIALOG_STYLE, + type=0, togletxt = "Show/hide scale and arrow", ctrltxt = "scale object") @@ -940,26 +941,14 @@ val = dlg.ShowModal() if val == wx.ID_OK: - print "You pressed OK" ovlist = self.MapWindow.GetOverlay() if ovlist != []: + self.MapWindow.DrawOvl(self.MapWindow.pdc, data=None, pdctype='clear') for overlay in ovlist: self.MapWindow.DrawOvl(self.MapWindow.pdc, overlay) - else: - print "You pressed Cancel" dlg.Destroy() - -# if self.ovlchk == True: -# self.ovlchk = False -# self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) -# else: -# self.ovlchk = True -# self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_OTHER, (16,16)) -# menuform.GUI().parseCommand('d.barscale', gmpath, completed=(self.getOptData,layer,self.params), parentframe=None) -# pass - def addGrid(self, event): self.params = [] layer = 1 @@ -973,9 +962,9 @@ pass - def getOptData(self, dcmd, layer): + def getOptData(self, dcmd, type): - Map.changeOverlay(type=layer, command=dcmd, l_active=self.ovlchk, l_render=False) + Map.changeOverlay(type=type, command=dcmd, l_active=self.ovlchk, l_render=False) def OnAlignRegion(self, event): """ @@ -1033,14 +1022,17 @@ class DecDialog(wx.Dialog): def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize, - style=wx.DEFAULT_DIALOG_STYLE, togletxt='', ctrltxt=''): + style=wx.DEFAULT_DIALOG_STYLE, type=None, togletxt='', ctrltxt=''): wx.Dialog.__init__(self, parent, id, title, pos, size, style) + self.check = {} #tracks toggling of decorations + self.type = type sizer = wx.BoxSizer(wx.VERTICAL) box = wx.BoxSizer(wx.HORIZONTAL) - chkbox = wx.CheckBox(self, wx.ID_ANY, togletxt ) - box.Add(chkbox, 0, wx.ALIGN_CENTRE|wx.ALL, 5) + self.chkbox = wx.CheckBox(self, wx.ID_ANY, togletxt ) + if self.type in self.check: self.chkbox.SetValue(self.check[self.type]) + box.Add(self.chkbox, 0, wx.ALIGN_CENTRE|wx.ALL, 5) sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) box = wx.BoxSizer(wx.HORIZONTAL) @@ -1058,10 +1050,6 @@ btnsizer = wx.StdDialogButtonSizer() -# if wx.Platform != "__WXMSW__": -# btn = wx.ContextHelpButton(self) -# btnsizer.AddButton(btn) - btn = wx.Button(self, wx.ID_OK) btn.SetHelpText("The OK button completes the dialog") btn.SetDefault() @@ -1077,19 +1065,21 @@ self.SetSizer(sizer) sizer.Fit(self) - self.Bind(wx.EVT_CHECKBOX, self.onToggle, chkbox) + self.Bind(wx.EVT_CHECKBOX, self.onToggle, self.chkbox) self.Bind(wx.EVT_BUTTON, self.onOptions, optnbtn) def onToggle(self, event): check = event.IsChecked() Map.changeOverlayActive(0, check) + self.Parent.ovlchk = check + self.check[self.type] = check + self.chkbox.SetValue(self.check[self.type]) def onOptions(self, event): - self.params = [] - layer = 0 + self.params = [] # parameters to insert into dialog (not working) menuform.GUI().parseCommand('d.barscale', gmpath, - completed=(self.Parent.getOptData,layer,self.params), + completed=(self.Parent.getOptData,self.type,self.params), parentframe=None) class MapApp(wx.App): From barton at grass.itc.it Fri Mar 30 21:12:06 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Mar 30 21:12:07 2007 Subject: [grass-addons] r388 - trunk/grassaddons/gui/gui_modules Message-ID: <200703301912.l2UJC6O8028735@grass.itc.it> Author: barton Date: 2007-03-30 21:11:59 +0200 (Fri, 30 Mar 2007) New Revision: 388 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Almost have the scale mouse placeable permanently. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 16:42:39 UTC (rev 387) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 19:11:59 UTC (rev 388) @@ -253,7 +253,7 @@ # get the image to be rendered self.img = self.GetImage() - self.ovlist = self.GetOverlay() +# self.ovlist = self.GetOverlay() # update map display if self.img and Map.width + Map.height > 0: # scale image during resize @@ -305,10 +305,10 @@ if not self.img: return self.ovlist = self.GetOverlay() # redraw decorations on resize event - self.DrawOvl(self.pdc, data=None, pdctype='clear') if self.ovlist != []: for overlay in self.ovlist: - self.DrawOvl(self.pdc, data=overlay, pdctype='image') + self.DrawOvl(self.pdc, type=0, data=None, pdctype='clear') + self.DrawOvl(self.pdc, type=0, data=overlay, pdctype='image') dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) self.Draw(dc, self.img) else: @@ -316,7 +316,8 @@ self.ovlist = self.GetOverlay() if self.ovlist != []: for overlay in self.ovlist: - self.DrawOvl(self.pdc, overlay) + self.DrawOvl(self.pdc, type=self.ovlist.index[overlay], data=None, pdctype='clear') + self.DrawOvl(self.pdc, type=self.ovlist.index[overlay], data=overlay, pdctype='image') dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) self.Draw(dc, self.img) @@ -548,7 +549,7 @@ Map.region['w'] = newreg['w'] - def DrawOvl(self, pdc, data, pdctype='image', coords=[0, 0]): + def DrawOvl(self, pdc, type, data, pdctype='image', coords=[0, 0]): """ Draws map decorations on top of map """ @@ -557,12 +558,13 @@ # pdc.Clear() # make sure you clear the bitmap! if pdctype == 'clear': # erase the display - pdc.Clear() + if type > -1: + pdc.ClearId(type) pdc.EndDrawing() return - if pdctype == 'image': - id = wx.NewId() + elif pdctype == 'image': + id = type pdc.SetId(id) bitmap = wx.BitmapFromImage(data) w,h = bitmap.GetSize() @@ -570,6 +572,8 @@ pdc.SetIdBounds(id,wx.Rect(coords[0], coords[1], w, h)) elif pdctype == 'box': # draw a box on top of the map + id = type + pdc.SetId(id) pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) pdc.SetPen(self.pen) pdc.DrawRectangle(coords[0],coords[1],coords[2]-coords[0],coords[2]-coords[1]) @@ -578,6 +582,8 @@ pdc.SetIdBounds(id,r) elif pdctype == 'line': # draw a line on top of the map + id = type + pdc.SetId(id) pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) pdc.SetPen(self.pen) dc.DrawLine(coords[0], coords[1], coords[2], coords[3]) @@ -586,6 +592,8 @@ pdc.SetIdBounds(id,r) elif pdctype == 'point': #draw point + id = type + pdc.SetId(id) pen = self.RandomPen() pdc.SetPen(pen) pdc.DrawPoint(coords[0], coords[1]) @@ -594,6 +602,8 @@ pdc.SetIdBounds(id,r) elif pdctype == 'text': # draw text on top of map + id = type + pdc.SetId(id) text = data w,h = self.GetFullTextExtent(text)[0:2] pdc.SetFont(self.GetFont()) @@ -927,6 +937,7 @@ self.decmenu.Destroy() def addBarscale(self, event): + type = 0 DecDialog(self, wx.ID_ANY, 'Scale and arrow') dlg = DecDialog(self, wx.ID_ANY, 'Scale and North arrow', size=(350, 200), @@ -943,9 +954,9 @@ if val == wx.ID_OK: ovlist = self.MapWindow.GetOverlay() if ovlist != []: - self.MapWindow.DrawOvl(self.MapWindow.pdc, data=None, pdctype='clear') for overlay in ovlist: - self.MapWindow.DrawOvl(self.MapWindow.pdc, overlay) + self.MapWindow.DrawOvl(self.MapWindow.pdc, type=0, data=None, pdctype='clear') + self.MapWindow.DrawOvl(self.MapWindow.pdc, type=0, data=overlay, pdctype='image') dlg.Destroy() From barton at grass.itc.it Sat Mar 31 00:45:27 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 31 00:45:28 2007 Subject: [grass-addons] r389 - trunk/grassaddons/gui/gui_modules Message-ID: <200703302245.l2UMjRxb030752@grass.itc.it> Author: barton Date: 2007-03-31 00:45:20 +0200 (Sat, 31 Mar 2007) New Revision: 389 Modified: trunk/grassaddons/gui/gui_modules/render.py Log: Turn off debug Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-03-30 19:11:59 UTC (rev 388) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-03-30 22:45:20 UTC (rev 389) @@ -11,7 +11,7 @@ # # COPYRIGHT:(C) 1999 - 2007 by the GRASS Development Team -DEBUG = True +DEBUG = False class GRASSLayer: """ From barton at grass.itc.it Sat Mar 31 00:47:03 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Sat Mar 31 00:47:05 2007 Subject: [grass-addons] r390 - trunk/grassaddons/gui/gui_modules Message-ID: <200703302247.l2UMl3AW030778@grass.itc.it> Author: barton Date: 2007-03-31 00:46:57 +0200 (Sat, 31 Mar 2007) New Revision: 390 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Interactive scale and legend placement working, though a few visual oddities during placement. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 22:45:20 UTC (rev 389) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-03-30 22:46:57 UTC (rev 390) @@ -51,6 +51,10 @@ # for cmdlinef cmdfilename = None +ovlchk = {} # track whether decoration overlay item is drawn or not +ovlcoords = {} # positioning coordinates for decoration overlay + + class Command(Thread): """ Creates thread, which will observe the command file and see, if there @@ -186,6 +190,7 @@ self.mapfile = None # image file to be rendered self.img = "" # wx.Image object (self.mapfile) self.ovlist = [] # list of images for overlays + ovlcoords = {} # coordinates for positioning decorative overlays # # mouse attributes like currently pressed buttons, position on @@ -307,8 +312,12 @@ # redraw decorations on resize event if self.ovlist != []: for overlay in self.ovlist: - self.DrawOvl(self.pdc, type=0, data=None, pdctype='clear') - self.DrawOvl(self.pdc, type=0, data=overlay, pdctype='image') + ovltype = self.ovlist.index(overlay) + if ovltype not in ovlcoords: + ovlcoords[ovltype] = wx.Rect(0,0,0,0) + self.DrawOvl(self.pdc, type=ovltype, data=None, pdctype='clear') + if ovlchk[ovltype] == True: + self.DrawOvl(self.pdc, type=ovltype, data=overlay, pdctype='image', rect=ovlcoords[ovltype]) dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) self.Draw(dc, self.img) else: @@ -316,8 +325,12 @@ self.ovlist = self.GetOverlay() if self.ovlist != []: for overlay in self.ovlist: - self.DrawOvl(self.pdc, type=self.ovlist.index[overlay], data=None, pdctype='clear') - self.DrawOvl(self.pdc, type=self.ovlist.index[overlay], data=overlay, pdctype='image') + ovltype = self.ovlist.index(overlay) + if ovltype not in ovlcoords: + ovlcoords[ovltype] = wx.Rect(0,0,0,0) + self.DrawOvl(self.pdc, type=ovltype, data=None, pdctype='clear') + if ovlchk[ovltype] == True: + self.DrawOvl(self.pdc, type=ovltype, data=overlay, pdctype='image', rect=ovlcoords[ovltype]) dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer) self.Draw(dc, self.img) @@ -365,6 +378,7 @@ self.pdc.DrawToDC(dc) self.RefreshRect(r, True) self.lastpos = (event.GetX(),event.GetY()) + ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid) def MouseDraw(self): """ @@ -389,16 +403,36 @@ """ wheel = event.GetWheelRotation() # +- int # left mouse button pressed - hitradius = 5 # distance for selecting map decorations + hitradius = 0 # distance for selecting map decorations if event.LeftDown(): + l = [] + id = '' # start point of zoom box or drag self.mouse['begin'] = event.GetPositionTuple()[:] + #l = self.pdc.FindObjectsByBBox(x, y) + l = self.pdc.FindObjects(self.mouse['begin'][0], self.mouse['begin'][1], hitradius) + for id in l: + self.pdc.SetIdGreyedOut(id, True) + self.dragid = id + self.lastpos = (event.GetX(),event.GetY()) + break # left mouse button released and not just a pointer elif event.LeftUp(): - if self.mouse['box'] != "point": + # dragging map decoration + if self.mouse['box'] == "point" and self.dragid > -1: + self.pdc.SetIdGreyedOut(self.dragid, False) +# +# r = self.pdc.GetIdBounds(self.dragid) +# r.Inflate(4,4) +# self.OffsetRect(r) +# self.RefreshRect(r, True) + self.dragid = -1 + self.UpdateMap() + + elif self.mouse['box'] != "point": # end point of zoom box or drag - self.mouse['end'] = event.GetPositionTuple()[:] + self.mouse['end'] = event.SetPositionTuple()[:] # set region in zoom or pan self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype) @@ -414,46 +448,20 @@ # redraw map self.render=True self.UpdateMap() - else: - self.dragid = -1 - elif event.ButtonDClick(): - x,y = event.GetPositionTuple()[:] - #l = self.pdc.FindObjectsByBBox(x, y) - l = self.pdc.FindObjects(x, y, hitradius) - if l: - self.pdc.SetIdGreyedOut(l[0], not self.pdc.GetIdGreyedOut(l[0])) - r = self.pdc.GetIdBounds(l[0]) - r.Inflate(4,4) - r.OffsetXY(0,0) - self.RefreshRect(r, False) - - elif event.RightDown(): - x,y = event.GetPositionTuple()[:] - #l = self.pdc.FindObjectsByBBox(x, y) - l = self.pdc.FindObjects(x, y, hitradius) - for id in l: - if not self.pdc.GetIdGreyedOut(id): - self.dragid = id - self.lastpos = (event.GetX(),event.GetY()) - break - elif event.Dragging(): currpos = event.GetPositionTuple()[:] end = (currpos[0]-self.mouse['begin'][0], \ currpos[1]-self.mouse['begin'][1]) # dragging or drawing box with left button - if event.LeftIsDown(): - if self.mouse['box'] == 'drag': - self.DragMap(end) - else: - self.mouse['end'] = event.GetPositionTuple()[:] - self.MouseDraw() - - elif event.RightIsDown(): - # dragging item with right button + if self.mouse['box'] == 'drag': + self.DragMap(end) + # dragging decoration overlay item + else: if self.dragid != -1: self.DragItem(self.lastpos,event) + self.mouse['end'] = event.GetPositionTuple()[:] + self.MouseDraw() # zoom on mouse wheel elif wheel != 0: @@ -549,12 +557,13 @@ Map.region['w'] = newreg['w'] - def DrawOvl(self, pdc, type, data, pdctype='image', coords=[0, 0]): + def DrawOvl(self, pdc, type, data, pdctype='image', rect=wx.Rect(0,0,0,0)): """ Draws map decorations on top of map """ pdc.BeginDrawing() -# pdc.SetBackground(wx.Brush(self.GetBackgroundColour())) + id = type + pdc.SetId(id)# pdc.SetBackground(wx.Brush(self.GetBackgroundColour())) # pdc.Clear() # make sure you clear the bitmap! if pdctype == 'clear': # erase the display @@ -564,57 +573,44 @@ return elif pdctype == 'image': - id = type - pdc.SetId(id) bitmap = wx.BitmapFromImage(data) w,h = bitmap.GetSize() - pdc.DrawBitmap(bitmap, coords[0], coords[1], True) # draw the composite map - pdc.SetIdBounds(id,wx.Rect(coords[0], coords[1], w, h)) + pdc.DrawBitmap(bitmap, rect.x, rect.y, True) # draw the composite map + pdc.SetIdBounds(id, (rect[0],rect[1],w,h)) elif pdctype == 'box': # draw a box on top of the map - id = type - pdc.SetId(id) pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) pdc.SetPen(self.pen) - pdc.DrawRectangle(coords[0],coords[1],coords[2]-coords[0],coords[2]-coords[1]) - r = wx.Rect(coords[0],coords[1],coords[2]-coords[0],coords[2]-coords[1]) - r.Inflate(pen.GetWidth(),pen.GetWidth()) - pdc.SetIdBounds(id,r) + pdc.DrawRectangleRect(rect) + rect.Inflate(pen.GetWidth(),pen.GetWidth()) + pdc.SetIdBounds(id,rect) elif pdctype == 'line': # draw a line on top of the map - id = type - pdc.SetId(id) pdc.SetBrush(wx.Brush(wx.CYAN, wx.TRANSPARENT)) pdc.SetPen(self.pen) - dc.DrawLine(coords[0], coords[1], coords[2], coords[3]) - r = wx.Rect(coords[0],coords[1],coords[2]-coords[0],coords[2]-coords[1]) - r.Inflate(pen.GetWidth(),pen.GetWidth()) - pdc.SetIdBounds(id,r) + dc.DrawLine(rect) + rect.Inflate(pen.GetWidth(),pen.GetWidth()) + pdc.SetIdBounds(id,rect) elif pdctype == 'point': #draw point - id = type - pdc.SetId(id) pen = self.RandomPen() pdc.SetPen(pen) - pdc.DrawPoint(coords[0], coords[1]) - r = wx.Rect(coords[0], coords[1], 1, 1) - r.Inflate(pen.GetWidth(),pen.GetWidth()) - pdc.SetIdBounds(id,r) + pdc.DrawPoint(rect.x, rect.y) + rect.Inflate(pen.GetWidth(),pen.GetWidth()) + pdc.SetIdBounds(id,rect) elif pdctype == 'text': # draw text on top of map - id = type - pdc.SetId(id) text = data w,h = self.GetFullTextExtent(text)[0:2] pdc.SetFont(self.GetFont()) pdc.SetTextForeground(self.RandomColor()) pdc.SetTextBackground(self.RandomColor()) - pdc.DrawText(text, coords[0], coords[1]) - r = wx.Rect(coords[0], coords[1], w, h) - r.Inflate(2,2) - pdc.SetIdBounds(id, r) + pdc.DrawText(text, rect.x, rect.y) + rect.Inflate(2,2) + pdc.SetIdBounds(id, rect) pdc.EndDrawing() + self.Refresh() class DrawWindow(BufferedWindow): @@ -720,15 +716,11 @@ for i in range(len(map_frame_statusbar_fields)): self.statusbar.SetStatusText(map_frame_statusbar_fields[i], i) - # variables for overlay menu - self.decmenu = '' #decorations menu - self.addscale = '' #barscale overlay menu item - self.addgrid = '' #grid overlay menu item - self.ovlchk = False - self.bmpscale = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) - self.bmpgrid = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_OTHER, (16,16)) - Map.addOverlay(type=0, command='', l_active=False, l_render=True) - Map.addOverlay(type=1, command='', l_active=False, l_render=True) + # decoration overlays + ovlchk[0] = False + ovlchk[1] = False + Map.addOverlay(type=0, command='d.barscale', l_active=True, l_render=False) # d.barscale overlay + Map.addOverlay(type=1, command='d.barscale', l_active=True, l_render=False) # d.legend overlay # @@ -921,28 +913,37 @@ def onDecoration(self, event): """Add decorations item menu""" point = wx.GetMousePosition() - self.decmenu = wx.Menu() + decmenu = wx.Menu() # Add items to the menu - self.addscale = wx.MenuItem(self.decmenu, -1,'Add scalebar and north arrow') + addscale = wx.MenuItem(decmenu, -1,'Add scalebar and north arrow') bmp = wx.Image(os.path.join(icons,'module-d.barscale.gif'), wx.BITMAP_TYPE_GIF) bmp.Rescale(16, 16) bmp = bmp.ConvertToBitmap() - self.addscale.SetBitmap(bmp) - self.decmenu.AppendItem(self.addscale) - self.Bind(wx.EVT_MENU, self.addBarscale, self.addscale) + addscale.SetBitmap(bmp) + decmenu.AppendItem(addscale) + self.Bind(wx.EVT_MENU, self.addBarscale, addscale) + addlegend = wx.MenuItem(decmenu, -1,'Add legend') + bmp = wx.Image(os.path.join(icons,'module-d.legend.gif'), wx.BITMAP_TYPE_GIF) + bmp.Rescale(16, 16) + bmp = bmp.ConvertToBitmap() + addlegend.SetBitmap(bmp) + decmenu.AppendItem(addlegend) + self.Bind(wx.EVT_MENU, self.addLegend, addlegend) + # Popup the menu. If an item is selected then its handler # will be called before PopupMenu returns. - self.PopupMenu(self.decmenu) - self.decmenu.Destroy() + self.PopupMenu(decmenu) + decmenu.Destroy() def addBarscale(self, event): - type = 0 + ovltype = 0 DecDialog(self, wx.ID_ANY, 'Scale and arrow') dlg = DecDialog(self, wx.ID_ANY, 'Scale and North arrow', size=(350, 200), style=wx.DEFAULT_DIALOG_STYLE, - type=0, + cmd='d.barscale', + type=ovltype, togletxt = "Show/hide scale and arrow", ctrltxt = "scale object") @@ -950,32 +951,52 @@ # this does not return until the dialog is closed. val = dlg.ShowModal() + self.MapWindow.UpdateMap() + if ovltype not in ovlcoords: + ovlcoords[ovltype] = wx.Rect(0,0,0,0) if val == wx.ID_OK: ovlist = self.MapWindow.GetOverlay() if ovlist != []: - for overlay in ovlist: - self.MapWindow.DrawOvl(self.MapWindow.pdc, type=0, data=None, pdctype='clear') - self.MapWindow.DrawOvl(self.MapWindow.pdc, type=0, data=overlay, pdctype='image') + self.MapWindow.DrawOvl(self.MapWindow.pdc, type=ovltype, data=None, pdctype='clear') + if ovlchk[ovltype] == True: + self.MapWindow.DrawOvl(self.MapWindow.pdc, type=ovltype, + data=ovlist[ovltype], pdctype='image', rect=ovlcoords[ovltype]) dlg.Destroy() - def addGrid(self, event): - self.params = [] - layer = 1 - if self.ovlchk == True: - self.ovlchk = False - self.bmpgrid = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_TOOLBAR, (16,16)) - else: - self.ovlchk = True - self.bmpgrid = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_TOOLBAR, (16,16)) - menuform.GUI().parseCommand('d.grid', gmpath, completed=(self.getOptData,layer,self.params), parentframe=None) + def addLegend(self, event): + ovltype = 1 + DecDialog(self, wx.ID_ANY, 'Legend') - pass + dlg = DecDialog(self, wx.ID_ANY, 'Legend', size=(350, 200), + style=wx.DEFAULT_DIALOG_STYLE, + cmd='d.legend', + type=ovltype, + togletxt = "Show/hide legend", + ctrltxt = "legend object") + dlg.CenterOnScreen() + + # this does not return until the dialog is closed. + val = dlg.ShowModal() + self.MapWindow.UpdateMap() + if ovltype not in ovlcoords: + ovlcoords[ovltype] = wx.Rect(0,0,0,0) + + if val == wx.ID_OK: + ovlist = self.MapWindow.GetOverlay() + if ovlist != []: + self.MapWindow.DrawOvl(self.MapWindow.pdc, type=ovltype, data=None, pdctype='clear') + if ovlchk[ovltype] == True: + self.MapWindow.DrawOvl(self.MapWindow.pdc, type=ovltype, + data=ovlist[ovltype], pdctype='image', rect=ovlcoords[ovltype]) + + dlg.Destroy() + def getOptData(self, dcmd, type): - Map.changeOverlay(type=type, command=dcmd, l_active=self.ovlchk, l_render=False) + Map.changeOverlay(type=type, command=dcmd, l_active=ovlchk, l_render=False) def OnAlignRegion(self, event): """ @@ -1033,16 +1054,21 @@ class DecDialog(wx.Dialog): def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize, - style=wx.DEFAULT_DIALOG_STYLE, type=None, togletxt='', ctrltxt=''): + style=wx.DEFAULT_DIALOG_STYLE, cmd=None, type=None, togletxt='', ctrltxt=''): wx.Dialog.__init__(self, parent, id, title, pos, size, style) - self.check = {} #tracks toggling of decorations self.type = type + self.ovlcmd = cmd + if type > -1 and type in ovlchk: #tracks toggling of decorations + check = ovlchk[type] + else: + check = False + sizer = wx.BoxSizer(wx.VERTICAL) box = wx.BoxSizer(wx.HORIZONTAL) self.chkbox = wx.CheckBox(self, wx.ID_ANY, togletxt ) - if self.type in self.check: self.chkbox.SetValue(self.check[self.type]) + self.chkbox.SetValue(check) box.Add(self.chkbox, 0, wx.ALIGN_CENTRE|wx.ALL, 5) sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) @@ -1052,7 +1078,7 @@ sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) box = wx.BoxSizer(wx.HORIZONTAL) - label = wx.StaticText(self, -1, ("Double-click %s and drag with mouse to position" % ctrltxt)) + label = wx.StaticText(self, -1, ("Drag %s with mouse in pointer mode to position" % ctrltxt)) box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5) sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) @@ -1082,14 +1108,11 @@ def onToggle(self, event): check = event.IsChecked() - Map.changeOverlayActive(0, check) - self.Parent.ovlchk = check - self.check[self.type] = check - self.chkbox.SetValue(self.check[self.type]) + ovlchk[self.type] = check def onOptions(self, event): self.params = [] # parameters to insert into dialog (not working) - menuform.GUI().parseCommand('d.barscale', gmpath, + menuform.GUI().parseCommand(self.ovlcmd, gmpath, completed=(self.Parent.getOptData,self.type,self.params), parentframe=None) From barton at grass.itc.it Sun Mar 25 08:37:57 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Fri Apr 20 15:39:42 2007 Subject: [grass-addons] r310 - in trunk/grassaddons/gui: Gism gui_modules Message-ID: <200703250637.l2P6bux4021968@grass.itc.it> Author: barton Date: 2007-03-25 08:37:41 +0200 (Sun, 25 Mar 2007) New Revision: 310 Added: trunk/grassaddons/gui/gui_modules/packages-uml.dia Removed: trunk/grassaddons/gui/Gism/packages-uml.dia Log: Moving items Deleted: trunk/grassaddons/gui/Gism/packages-uml.dia =================================================================== --- trunk/grassaddons/gui/Gism/packages-uml.dia 2007-03-25 06:37:07 UTC (rev 309) +++ trunk/grassaddons/gui/Gism/packages-uml.dia 2007-03-25 06:37:41 UTC (rev 310) @@ -1,4485 +0,0 @@ - - - - - - - - - - - - - #A4# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - #gismutils# - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - #render# - - - - - - - - - - - - - - - - - - - - #MapLayer# - - - ## - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #cmd# - - - #string# - - - ## - - - ## - - - - - - - - - - - - - - #name# - - - #string# - - - ## - - - #layer name# - - - - - - - - - - - - - - #mapset# - - - #string# - - - ## - - - ## - - - - - - - - - - - - - - #type# - - - #string# - - - ## - - - ## - - - - - - - - - - - - - - #active# - - - #boolean# - - - ## - - - ## - - - - - - - - - - - - - - #hidden# - - - #boolean# - - - ## - - - ## - - - - - - - - - - - - - - #opacity# - - - #integer# - - - ## - - - ## - - - - - - - - - - - - - - #mapfile# - - - #string# - - - ## - - - ## - - - - - - - - - - - - - - #maskfile# - - - #string# - - - ## - - - ## - - - - - - - - - - - - - - - - #init# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #type# - - - #string# - - - ## - - - ## - - - - - - - - #name# - - - #string# - - - ## - - - ## - - - - - - - - #mapset# - - - #string# - - - ## - - - ## - - - - - - - - #active# - - - #boolean# - - - ## - - - ## - - - - - - - - #hidden# - - - #boolean# - - - ## - - - ## - - - - - - - - #opacity# - - - #boolean# - - - ## - - - ## - - - - - - - - #parameters# - - - #dictionary# - - - ## - - - ## - - - - - - - - - - #renderRasterLayer# - - - ## - - - ## - - - - - - #Stores d.rast command with all parameters in the cmd variable# - - - - - - - - - - - - - - - - - - #renderVectorLayer# - - - ## - - - ## - - - - - - #Stores d.vect command with all parameters in the self.cmd variable# - - - - - - - - - - - - - - - - - - #Render# - - - ## - - - #name of rendered image or None# - - - - - - #Runs all d.* commands# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - #layer# - - - #0..*# - - - - - - - - - - - ## - - - #1# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #LayerTree# - - - #wx.lib.customtreectrl.CustomTreeCtrl# - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #init# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #...# - - - ## - - - ## - - - ## - - - - - - - - - - #AddLayer# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #idx# - - - #integer# - - - ## - - - ## - - - - - - - - #layertype# - - - #string# - - - ## - - - ## - - - - - - - - - - #onCollapseNode# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #onExpandNone# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #onActiveLayer# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #onChangeSel# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Map# - - - ## - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #env# - - - #dictionary# - - - ## - - - ## - - - - - - - - - - - - - - #verbosity# - - - #integer# - - - ## - - - ## - - - - - - - - - - - - - - #width# - - - #integer# - - - ## - - - ## - - - - - - - - - - - - - - #height# - - - #integer# - - - ## - - - ## - - - - - - - - - - - - - - #windfile# - - - #string# - - - ## - - - ## - - - - - - - - - - - - - - #region# - - - #dictionary# - - - ## - - - ## - - - - - - - - - - - - - - #layer# - - - #list# - - - ## - - - ## - - - - - - - - - - - - - - #renderRegion# - - - #dictionary# - - - ## - - - ## - - - - - - - - - - - - - - #mapfile# - - - #string# - - - ## - - - ## - - - - - - - - - - - - - - - - #init# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #initRegion# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #initMonSize# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #initEnv# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #adjustRegion# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #GetRegion# - - - ## - - - #region# - - - - - - ## - - - - - - - - - - - - - - - - - - #SetRegion# - - - ## - - - #GRASS_REGION or string# - - - - - - ## - - - - - - - - - - - - - - - - - - #GetListOfLayers# - - - ## - - - #list of layers# - - - - - - ## - - - - - - - - - - - - - - - - - #type# - - - #string# - - - #None# - - - ## - - - - - - - - #active# - - - #boolean# - - - #None# - - - ## - - - - - - - - #hidden# - - - #boolean# - - - #None# - - - ## - - - - - - - - - - #Render# - - - ## - - - #rendered image filename# - - - - - - ## - - - - - - - - - - - - - - - - - #force# - - - #boolean# - - - #None# - - - ## - - - - - - - - - - #AddRasterLayer# - - - ## - - - #added layer# - - - - - - ## - - - - - - - - - - - - - - - - - #name# - - - #string# - - - ## - - - ## - - - - - - - - #mapset# - - - #string# - - - #None# - - - ## - - - - - - - - #catlist# - - - #string# - - - #None# - - - ## - - - - - - - - #vallist# - - - #string# - - - #None# - - - ## - - - - - - - - #l_active# - - - #boolean# - - - #True# - - - ## - - - - - - - - #l_hidden# - - - #boolean# - - - #False# - - - ## - - - - - - - - #l_opacity# - - - #integer# - - - #1# - - - ## - - - - - - - - #l_render# - - - #boolean# - - - #False# - - - ## - - - - - - - - - - #AddGraphLayer# - - - ## - - - #added layer# - - - - - - ## - - - - - - - - - - - - - - - - - #name# - - - #string# - - - ## - - - ## - - - - - - - - #graph# - - - #string# - - - #None# - - - ## - - - - - - - - #color# - - - #string# - - - #255:0:0# - - - ## - - - - - - - - #coordsinmapunits# - - - #boolean# - - - #False# - - - ## - - - - - - - - #l_active# - - - #boolean# - - - #True# - - - ## - - - - - - - - #l_hidden# - - - #boolean# - - - #False# - - - ## - - - - - - - - #l_opacity# - - - #integer# - - - #1# - - - ## - - - - - - - - #l_render# - - - #boolean# - - - #False# - - - ## - - - - - - - - - - #AddVectorLayer# - - - ## - - - #added layer# - - - - - - ## - - - - - - - - - - - - - - - - - #name# - - - #string# - - - ## - - - ## - - - - - - - - #mapset# - - - #string# - - - #None# - - - ## - - - - - - - - #type# - - - #string# - - - ## - - - ## - - - - - - - - #display# - - - #string# - - - #shape# - - - ## - - - - - - - - #attrcol# - - - #string# - - - #None# - - - ## - - - - - - - - #icon# - - - #string# - - - #basic/circle# - - - ## - - - - - - - - #size# - - - #integer# - - - #8# - - - ## - - - - - - - - #layer# - - - #integer# - - - #1# - - - ## - - - - - - - - #cats# - - - #string# - - - #None# - - - ## - - - - - - - - #where# - - - #string# - - - #None# - - - ## - - - - - - - - #width# - - - #integer# - - - #1# - - - ## - - - - - - - - #wcolumn# - - - #string# - - - #None# - - - ## - - - - - - - - #wscale# - - - #inreger# - - - #1# - - - ## - - - - - - - - #color# - - - #string# - - - #000:000:000# - - - ## - - - - - - - - #fcolor# - - - #string# - - - #200:200:200# - - - ## - - - - - - - - #rgb_column# - - - #string# - - - #GRASSRBG# - - - ## - - - - - - - - #llayer# - - - #integer# - - - #1# - - - ## - - - - - - - - #lcolor# - - - #string# - - - #256:000:000# - - - ## - - - - - - - - #bgcolor# - - - #string# - - - #None# - - - ## - - - - - - - - #bcolor# - - - #string# - - - #None# - - - ## - - - - - - - - #lsize# - - - #integer# - - - #8# - - - ## - - - - - - - - #font# - - - #string# - - - #None# - - - ## - - - - - - - - #xref# - - - #string# - - - #left# - - - ## - - - - - - - - #yref# - - - #string# - - - #center# - - - ## - - - - - - - - #minreg# - - - #string# - - - #None# - - - ## - - - - - - - - #maxreg# - - - #string# - - - #None# - - - ## - - - - - - - - #colorfromtable# - - - #boolean# - - - #False# - - - ## - - - - - - - - #randomcolor# - - - #boolean# - - - #False# - - - ## - - - - - - - - #catasid# - - - #boolean# - - - #False# - - - ## - - - - - - - - #l_active# - - - #boolean# - - - #True# - - - ## - - - - - - - - #l_hidden# - - - #boolean# - - - #False# - - - ## - - - - - - - - #l_opacity# - - - #boolean# - - - #1# - - - ## - - - - - - - - #l_render# - - - #boolean# - - - #False# - - - ## - - - - - - - - - - #PopLayer# - - - ## - - - #Layer# - - - - - - ## - - - - - - - - - - - - - - - - - #name# - - - #string# - - - #None# - - - ## - - - - - - - - #mapset# - - - #string# - - - #None# - - - ## - - - - - - - - #id# - - - #integer# - - - #None# - - - ## - - - - - - - - - - #GetLayerIndex# - - - ## - - - #index or None# - - - - - - ## - - - - - - - - - - - - - - - - - #name# - - - #string# - - - ## - - - ## - - - - - - - - #mapset# - - - #string# - - - #None# - - - ## - - - - - - - - - - #Clean# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #GMConsole# - - - #wx.Panel# - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #init# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #getGRASSCmd# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #runCmd# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #event# - - - ## - - - ## - - - ## - - - - - - - - - - #clearHistory# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #event# - - - ## - - - ## - - - ## - - - - - - - - - - #saveHistory# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #event# - - - ## - - - ## - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - #GetTempFile (pref=None)# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - #toolbars# - - - - - - - - - - - - - - - - - - - - #MapToolBar# - - - ## - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #init# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #mapdisplay# - - - ## - - - ## - - - ## - - - - - - - - #map# - - - ## - - - ## - - - ## - - - - - - - - - - #onSelect# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #event# - - - ## - - - ## - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #DigitToolbar# - - - ## - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #init# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #parent# - - - ## - - - ## - - - ## - - - - - - - - #map# - - - ## - - - ## - - - ## - - - - - - - - - - #initToolbar# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - #onPoint# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #event# - - - ## - - - ## - - - ## - - - - - - - - - - #AddPoint# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #x# - - - ## - - - ## - - - ## - - - - - - - - #y# - - - ## - - - ## - - - ## - - - - - - - - - - #getListOfLayers# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - #grassenv# - - - - - - - - - - - - - - - - - - - - #NotInGRASSSession# - - - #Exception# - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #CouldNotStartMonitor# - - - #Exception# - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #CouldNotExecute# - - - #Exception# - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #CouldNotStopMonitor# - - - #Exception# - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - #env# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #GRASSLayer# - - - ## - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #params# - - - #dictionary# - - - ## - - - ## - - - - - - - - - - - - - - - - #init# - - - ## - - - ## - - - - - - ## - - - - - - - - - - - - - - - - - #parameters# - - - #dictionary# - - - ## - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - ## - - - #1# - - - - - - - - - - - #grassLayer# - - - #1# - - - - - - - - - - - - - - - - Copied: trunk/grassaddons/gui/gui_modules/packages-uml.dia (from rev 309, trunk/grassaddons/gui/Gism/packages-uml.dia) =================================================================== --- trunk/grassaddons/gui/gui_modules/packages-uml.dia (rev 0) +++ trunk/grassaddons/gui/gui_modules/packages-uml.dia 2007-03-25 06:37:41 UTC (rev 310) @@ -0,0 +1,4485 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + #gismutils# + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + #render# + + + + + + + + + + + + + + + + + + + + #MapLayer# + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #cmd# + + + #string# + + + ## + + + ## + + + + + + + + + + + + + + #name# + + + #string# + + + ## + + + #layer name# + + + + + + + + + + + + + + #mapset# + + + #string# + + + ## + + + ## + + + + + + + + + + + + + + #type# + + + #string# + + + ## + + + ## + + + + + + + + + + + + + + #active# + + + #boolean# + + + ## + + + ## + + + + + + + + + + + + + + #hidden# + + + #boolean# + + + ## + + + ## + + + + + + + + + + + + + + #opacity# + + + #integer# + + + ## + + + ## + + + + + + + + + + + + + + #mapfile# + + + #string# + + + ## + + + ## + + + + + + + + + + + + + + #maskfile# + + + #string# + + + ## + + + ## + + + + + + + + + + + + + + + + #init# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #type# + + + #string# + + + ## + + + ## + + + + + + + + #name# + + + #string# + + + ## + + + ## + + + + + + + + #mapset# + + + #string# + + + ## + + + ## + + + + + + + + #active# + + + #boolean# + + + ## + + + ## + + + + + + + + #hidden# + + + #boolean# + + + ## + + + ## + + + + + + + + #opacity# + + + #boolean# + + + ## + + + ## + + + + + + + + #parameters# + + + #dictionary# + + + ## + + + ## + + + + + + + + + + #renderRasterLayer# + + + ## + + + ## + + + + + + #Stores d.rast command with all parameters in the cmd variable# + + + + + + + + + + + + + + + + + + #renderVectorLayer# + + + ## + + + ## + + + + + + #Stores d.vect command with all parameters in the self.cmd variable# + + + + + + + + + + + + + + + + + + #Render# + + + ## + + + #name of rendered image or None# + + + + + + #Runs all d.* commands# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + + + + #layer# + + + #0..*# + + + + + + + + + + + ## + + + #1# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #LayerTree# + + + #wx.lib.customtreectrl.CustomTreeCtrl# + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #init# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #...# + + + ## + + + ## + + + ## + + + + + + + + + + #AddLayer# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #idx# + + + #integer# + + + ## + + + ## + + + + + + + + #layertype# + + + #string# + + + ## + + + ## + + + + + + + + + + #onCollapseNode# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #onExpandNone# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #onActiveLayer# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #onChangeSel# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Map# + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #env# + + + #dictionary# + + + ## + + + ## + + + + + + + + + + + + + + #verbosity# + + + #integer# + + + ## + + + ## + + + + + + + + + + + + + + #width# + + + #integer# + + + ## + + + ## + + + + + + + + + + + + + + #height# + + + #integer# + + + ## + + + ## + + + + + + + + + + + + + + #windfile# + + + #string# + + + ## + + + ## + + + + + + + + + + + + + + #region# + + + #dictionary# + + + ## + + + ## + + + + + + + + + + + + + + #layer# + + + #list# + + + ## + + + ## + + + + + + + + + + + + + + #renderRegion# + + + #dictionary# + + + ## + + + ## + + + + + + + + + + + + + + #mapfile# + + + #string# + + + ## + + + ## + + + + + + + + + + + + + + + + #init# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #initRegion# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #initMonSize# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #initEnv# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #adjustRegion# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #GetRegion# + + + ## + + + #region# + + + + + + ## + + + + + + + + + + + + + + + + + + #SetRegion# + + + ## + + + #GRASS_REGION or string# + + + + + + ## + + + + + + + + + + + + + + + + + + #GetListOfLayers# + + + ## + + + #list of layers# + + + + + + ## + + + + + + + + + + + + + + + + + #type# + + + #string# + + + #None# + + + ## + + + + + + + + #active# + + + #boolean# + + + #None# + + + ## + + + + + + + + #hidden# + + + #boolean# + + + #None# + + + ## + + + + + + + + + + #Render# + + + ## + + + #rendered image filename# + + + + + + ## + + + + + + + + + + + + + + + + + #force# + + + #boolean# + + + #None# + + + ## + + + + + + + + + + #AddRasterLayer# + + + ## + + + #added layer# + + + + + + ## + + + + + + + + + + + + + + + + + #name# + + + #string# + + + ## + + + ## + + + + + + + + #mapset# + + + #string# + + + #None# + + + ## + + + + + + + + #catlist# + + + #string# + + + #None# + + + ## + + + + + + + + #vallist# + + + #string# + + + #None# + + + ## + + + + + + + + #l_active# + + + #boolean# + + + #True# + + + ## + + + + + + + + #l_hidden# + + + #boolean# + + + #False# + + + ## + + + + + + + + #l_opacity# + + + #integer# + + + #1# + + + ## + + + + + + + + #l_render# + + + #boolean# + + + #False# + + + ## + + + + + + + + + + #AddGraphLayer# + + + ## + + + #added layer# + + + + + + ## + + + + + + + + + + + + + + + + + #name# + + + #string# + + + ## + + + ## + + + + + + + + #graph# + + + #string# + + + #None# + + + ## + + + + + + + + #color# + + + #string# + + + #255:0:0# + + + ## + + + + + + + + #coordsinmapunits# + + + #boolean# + + + #False# + + + ## + + + + + + + + #l_active# + + + #boolean# + + + #True# + + + ## + + + + + + + + #l_hidden# + + + #boolean# + + + #False# + + + ## + + + + + + + + #l_opacity# + + + #integer# + + + #1# + + + ## + + + + + + + + #l_render# + + + #boolean# + + + #False# + + + ## + + + + + + + + + + #AddVectorLayer# + + + ## + + + #added layer# + + + + + + ## + + + + + + + + + + + + + + + + + #name# + + + #string# + + + ## + + + ## + + + + + + + + #mapset# + + + #string# + + + #None# + + + ## + + + + + + + + #type# + + + #string# + + + ## + + + ## + + + + + + + + #display# + + + #string# + + + #shape# + + + ## + + + + + + + + #attrcol# + + + #string# + + + #None# + + + ## + + + + + + + + #icon# + + + #string# + + + #basic/circle# + + + ## + + + + + + + + #size# + + + #integer# + + + #8# + + + ## + + + + + + + + #layer# + + + #integer# + + + #1# + + + ## + + + + + + + + #cats# + + + #string# + + + #None# + + + ## + + + + + + + + #where# + + + #string# + + + #None# + + + ## + + + + + + + + #width# + + + #integer# + + + #1# + + + ## + + + + + + + + #wcolumn# + + + #string# + + + #None# + + + ## + + + + + + + + #wscale# + + + #inreger# + + + #1# + + + ## + + + + + + + + #color# + + + #string# + + + #000:000:000# + + + ## + + + + + + + + #fcolor# + + + #string# + + + #200:200:200# + + + ## + + + + + + + + #rgb_column# + + + #string# + + + #GRASSRBG# + + + ## + + + + + + + + #llayer# + + + #integer# + + + #1# + + + ## + + + + + + + + #lcolor# + + + #string# + + + #256:000:000# + + + ## + + + + + + + + #bgcolor# + + + #string# + + + #None# + + + ## + + + + + + + + #bcolor# + + + #string# + + + #None# + + + ## + + + + + + + + #lsize# + + + #integer# + + + #8# + + + ## + + + + + + + + #font# + + + #string# + + + #None# + + + ## + + + + + + + + #xref# + + + #string# + + + #left# + + + ## + + + + + + + + #yref# + + + #string# + + + #center# + + + ## + + + + + + + + #minreg# + + + #string# + + + #None# + + + ## + + + + + + + + #maxreg# + + + #string# + + + #None# + + + ## + + + + + + + + #colorfromtable# + + + #boolean# + + + #False# + + + ## + + + + + + + + #randomcolor# + + + #boolean# + + + #False# + + + ## + + + + + + + + #catasid# + + + #boolean# + + + #False# + + + ## + + + + + + + + #l_active# + + + #boolean# + + + #True# + + + ## + + + + + + + + #l_hidden# + + + #boolean# + + + #False# + + + ## + + + + + + + + #l_opacity# + + + #boolean# + + + #1# + + + ## + + + + + + + + #l_render# + + + #boolean# + + + #False# + + + ## + + + + + + + + + + #PopLayer# + + + ## + + + #Layer# + + + + + + ## + + + + + + + + + + + + + + + + + #name# + + + #string# + + + #None# + + + ## + + + + + + + + #mapset# + + + #string# + + + #None# + + + ## + + + + + + + + #id# + + + #integer# + + + #None# + + + ## + + + + + + + + + + #GetLayerIndex# + + + ## + + + #index or None# + + + + + + ## + + + + + + + + + + + + + + + + + #name# + + + #string# + + + ## + + + ## + + + + + + + + #mapset# + + + #string# + + + #None# + + + ## + + + + + + + + + + #Clean# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #GMConsole# + + + #wx.Panel# + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #init# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #getGRASSCmd# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #runCmd# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #event# + + + ## + + + ## + + + ## + + + + + + + + + + #clearHistory# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #event# + + + ## + + + ## + + + ## + + + + + + + + + + #saveHistory# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #event# + + + ## + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + #GetTempFile (pref=None)# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + #toolbars# + + + + + + + + + + + + + + + + + + + + #MapToolBar# + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #init# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #mapdisplay# + + + ## + + + ## + + + ## + + + + + + + + #map# + + + ## + + + ## + + + ## + + + + + + + + + + #onSelect# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #event# + + + ## + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #DigitToolbar# + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #init# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #parent# + + + ## + + + ## + + + ## + + + + + + + + #map# + + + ## + + + ## + + + ## + + + + + + + + + + #initToolbar# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + #onPoint# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #event# + + + ## + + + ## + + + ## + + + + + + + + + + #AddPoint# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #x# + + + ## + + + ## + + + ## + + + + + + + + #y# + + + ## + + + ## + + + ## + + + + + + + + + + #getListOfLayers# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + #grassenv# + + + + + + + + + + + + + + + + + + + + #NotInGRASSSession# + + + #Exception# + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #CouldNotStartMonitor# + + + #Exception# + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #CouldNotExecute# + + + #Exception# + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #CouldNotStopMonitor# + + + #Exception# + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + #env# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #GRASSLayer# + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #params# + + + #dictionary# + + + ## + + + ## + + + + + + + + + + + + + + + + #init# + + + ## + + + ## + + + + + + ## + + + + + + + + + + + + + + + + + #parameters# + + + #dictionary# + + + ## + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + + + + ## + + + #1# + + + + + + + + + + + #grassLayer# + + + #1# + + + + + + + + + + + + + + + +