[GRASS-SVN] r49361 - in grass/trunk/gui/wxpython: . core gcp gmodeler gui_core psmap

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Nov 25 16:09:24 EST 2011


Author: martinl
Date: 2011-11-25 13:09:24 -0800 (Fri, 25 Nov 2011)
New Revision: 49361

Added:
   grass/trunk/gui/wxpython/gcp/mapdisplay.py
Removed:
   grass/trunk/gui/wxpython/gcp/mapdisp.py
Modified:
   grass/trunk/gui/wxpython/core/utils.py
   grass/trunk/gui/wxpython/gcp/manager.py
   grass/trunk/gui/wxpython/gmodeler/dialogs.py
   grass/trunk/gui/wxpython/gmodeler/frame.py
   grass/trunk/gui/wxpython/gmodeler/model.py
   grass/trunk/gui/wxpython/gui_core/dialogs.py
   grass/trunk/gui/wxpython/psmap/frame.py
   grass/trunk/gui/wxpython/psmap/menudata.py
   grass/trunk/gui/wxpython/psmap/toolbars.py
   grass/trunk/gui/wxpython/wxgui.py
Log:
wxGUI major code reorganization (more fixes)


Modified: grass/trunk/gui/wxpython/core/utils.py
===================================================================
--- grass/trunk/gui/wxpython/core/utils.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/core/utils.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -50,8 +50,6 @@
 
     @return Path to file name (string) or None
     """
-    from core import cmd as gcmd
-    
     ret = RunCommand('g.tempfile',
                      read = True,
                      pid = os.getpid())

Modified: grass/trunk/gui/wxpython/gcp/manager.py
===================================================================
--- grass/trunk/gui/wxpython/gcp/manager.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/gcp/manager.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -39,11 +39,10 @@
 from core              import utils
 from core.render       import Map
 from gui_core.gselect  import Select, LocationSelect, MapsetSelect
-from gui_core.gdialogs import GroupDialog
+from gui_core.dialogs  import GroupDialog
 from core.gcmd         import RunCommand, GMessage, GError, GWarning
 from core.settings     import UserSettings
-from gcp.mapdisp       import MapFrame
-from mapdisp.window    import BufferedWindow
+from gcp.mapdisplay    import MapFrame
 
 from location_wizard.wizard   import TitledPage as TitledPage
 

Deleted: grass/trunk/gui/wxpython/gcp/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gcp/mapdisp.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/gcp/mapdisp.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -1,629 +0,0 @@
-"""!
- at package gcp.mapdisp
-
- at brief Display to manage ground control points with two toolbars, one
-for various display management functions, one for manipulating GCPs.
-
-Classes:
-- MapFrame
-
-(C) 2006-2011 by the GRASS Development Team
-This program is free software under the GNU General Public License
-(>=v2). Read the file COPYING that comes with GRASS for details.
-
- at author Markus Metz
-"""
-
-import os
-import math
-import platform
-
-from core import globalvar
-import wx
-import wx.aui
-
-from core.render      import EVT_UPDATE_PRGBAR
-from mapdisp.toolbars import MapToolbar
-from gcp.toolbars     import GCPDisplayToolbar, GCPManToolbar
-from mapdisp.gprint   import PrintOptions
-from core.gcmd        import GMessage
-from gui_core.dialogs import GetImageHandlers, ImageSizeDialog
-from gui_core.mapdisp import MapFrameBase
-from core.settings    import UserSettings
-from mapdisp.window   import BufferedWindow
-
-import mapdisp.statusbar as sb
-
-# for standalone app
-cmdfilename = None
-
-class MapFrame(MapFrameBase):
-    """!Main frame for map display window. Drawing takes place in
-    child double buffered drawing window.
-    """
-    def __init__(self, parent=None, title=_("GRASS GIS Manage Ground Control Points"),
-                 toolbars=["gcpdisp"], tree=None, notebook=None, lmgr=None,
-                 page=None, Map=None, auimgr=None, name = 'GCPMapWindow', **kwargs):
-        """!Main map display window with toolbars, statusbar and
-        DrawWindow
-
-        @param toolbars array of activated toolbars, e.g. ['map', 'digit']
-        @param tree reference to layer tree
-        @param notebook control book ID in Layer Manager
-        @param lmgr Layer Manager
-        @param page notebook page with layer tree
-        @param Map instance of render.Map
-        @param auimgs AUI manager
-        @param kwargs wx.Frame attribures
-        """
-        
-        MapFrameBase.__init__(self, parent = parent, title = title, toolbars = toolbars,
-                              Map = Map, auimgr = auimgr, name = name, **kwargs)
-        
-        self._layerManager = lmgr   # Layer Manager object
-        self.tree       = tree      # Layer Manager layer tree object
-        self.page       = page      # Notebook page holding the layer tree
-        self.layerbook  = notebook  # Layer Manager layer tree notebook
-        #
-        # Add toolbars
-        #
-        for toolb in toolbars:
-            self.AddToolbar(toolb)
-
-        self.activemap = self.toolbars['gcpdisp'].togglemap
-        self.activemap.SetSelection(0)
-        
-        self.SrcMap        = self.grwiz.SrcMap       # instance of render.Map
-        self.TgtMap        = self.grwiz.TgtMap       # instance of render.Map
-        self._mgr.SetDockSizeConstraint(0.5, 0.5)
-
-        #
-        # Add statusbar
-        #
-        
-        # items for choice
-        self.statusbarItems = [sb.SbCoordinates,
-                               sb.SbRegionExtent,
-                               sb.SbCompRegionExtent,
-                               sb.SbShowRegion,
-                               sb.SbResolution,
-                               sb.SbDisplayGeometry,
-                               sb.SbMapScale,
-                               sb.SbProjection,
-                               sb.SbGoToGCP,
-                               sb.SbRMSError]
-                            
-        
-        # create statusbar and its manager
-        statusbar = self.CreateStatusBar(number = 4, style = 0)
-        statusbar.SetStatusWidths([-5, -2, -1, -1])
-        self.statusbarManager = sb.SbManager(mapframe = self, statusbar = statusbar)
-        
-        # fill statusbar manager
-        self.statusbarManager.AddStatusbarItemsByClass(self.statusbarItems, mapframe = self, statusbar = statusbar)
-        self.statusbarManager.AddStatusbarItem(sb.SbMask(self, statusbar = statusbar, position = 2))
-        self.statusbarManager.AddStatusbarItem(sb.SbRender(self, statusbar = statusbar, position = 3))
-        
-        self.statusbarManager.SetMode(8) # goto GCP
-        self.statusbarManager.Update()
-        
-
-        #
-        # Init map display (buffered DC & set default cursor)
-        #
-        self.grwiz.SwitchEnv('source')
-        self.SrcMapWindow = BufferedWindow(self, id=wx.ID_ANY,
-                                          Map=self.SrcMap, tree=self.tree, lmgr=self._layerManager)
-
-        self.grwiz.SwitchEnv('target')
-        self.TgtMapWindow = BufferedWindow(self, id=wx.ID_ANY,
-                                          Map=self.TgtMap, tree=self.tree, lmgr=self._layerManager)
-        self.MapWindow = self.SrcMapWindow
-        self.Map = self.SrcMap
-        self.SrcMapWindow.SetCursor(self.cursors["cross"])
-        self.TgtMapWindow.SetCursor(self.cursors["cross"])
-
-        #
-        # initialize region values
-        #
-        self._initMap(map = self.SrcMap) 
-        self._initMap(map = self.TgtMap) 
-
-        #
-        # Bind various events
-        #
-        self.Bind(wx.EVT_ACTIVATE, self.OnFocus)
-        self.Bind(EVT_UPDATE_PRGBAR, self.OnUpdateProgress)
-        self.Bind(wx.EVT_SIZE,     self.OnDispResize)
-        self.activemap.Bind(wx.EVT_CHOICE, self.OnUpdateActive)
-        
-        #
-        # Update fancy gui style
-        #
-        # AuiManager wants a CentrePane, workaround to get two equally sized windows
-        self.list = self.CreateGCPList()
-
-        #self.SrcMapWindow.SetSize((300, 300))
-        #self.TgtMapWindow.SetSize((300, 300))
-        self.list.SetSize((100, 150))
-        self._mgr.AddPane(self.list, wx.aui.AuiPaneInfo().
-                  Name("gcplist").Caption(_("GCP List")).LeftDockable(False).
-                  RightDockable(False).PinButton().FloatingSize((600,200)).
-                  CloseButton(False).DestroyOnClose(True).
-                  Top().Layer(1).MinSize((200,100)))
-        self._mgr.AddPane(self.SrcMapWindow, wx.aui.AuiPaneInfo().
-                  Name("source").Caption(_("Source Display")).Dockable(False).
-                  CloseButton(False).DestroyOnClose(True).Floatable(False).
-                  Centre())
-        self._mgr.AddPane(self.TgtMapWindow, wx.aui.AuiPaneInfo().
-                  Name("target").Caption(_("Target Display")).Dockable(False).
-                  CloseButton(False).DestroyOnClose(True).Floatable(False).
-                  Right().Layer(0))
-
-        srcwidth, srcheight = self.SrcMapWindow.GetSize()
-        tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
-        srcwidth = (srcwidth + tgtwidth) / 2
-        self._mgr.GetPane("target").Hide()
-        self._mgr.Update()
-        self._mgr.GetPane("source").BestSize((srcwidth, srcheight))
-        self._mgr.GetPane("target").BestSize((srcwidth, srcheight))
-        if self.show_target:
-            self._mgr.GetPane("target").Show()
-        else:
-            self.activemap.Enable(False)
-        # needed by Mac OS, does not harm on Linux, breaks display on Windows
-        if platform.system() != 'Windows':
-            self._mgr.Update()
-
-        #
-        # Init print module and classes
-        #
-        self.printopt = PrintOptions(self, self.MapWindow)
-        
-        #
-        # Initialization of digitization tool
-        #
-        self.digit = None
-
-        # set active map
-        self.MapWindow = self.SrcMapWindow
-        self.Map = self.SrcMap
-        
-        # do not init zoom history here, that happens when zooming to map(s)
-
-        #
-        # Re-use dialogs
-        #
-        self.dialogs = {}
-        self.dialogs['attributes'] = None
-        self.dialogs['category'] = None
-        self.dialogs['barscale'] = None
-        self.dialogs['legend'] = None
-
-        self.decorationDialog = None # decoration/overlays
-
-    def AddToolbar(self, name):
-        """!Add defined toolbar to the window
-        
-        Currently known toolbars are:
-         - 'map'     - basic map toolbar
-         - 'vdigit'  - vector digitizer
-         - 'gcpdisp' - GCP Manager, Display
-         - 'gcpman'  - GCP Manager, points management
-         - 'nviz'    - 3D view mode
-        """
-        # default toolbar
-        if name == "map":
-            self.toolbars['map'] = MapToolbar(self, self.Map)
-
-            self._mgr.AddPane(self.toolbars['map'],
-                              wx.aui.AuiPaneInfo().
-                              Name("maptoolbar").Caption(_("Map Toolbar")).
-                              ToolbarPane().Top().
-                              LeftDockable(False).RightDockable(False).
-                              BottomDockable(False).TopDockable(True).
-                              CloseButton(False).Layer(2).
-                              BestSize((self.toolbars['map'].GetSize())))
-
-        # GCP display
-        elif name == "gcpdisp":
-            self.toolbars['gcpdisp'] = GCPDisplayToolbar(self)
-
-            self._mgr.AddPane(self.toolbars['gcpdisp'],
-                              wx.aui.AuiPaneInfo().
-                              Name("gcpdisplaytoolbar").Caption(_("GCP Display toolbar")).
-                              ToolbarPane().Top().
-                              LeftDockable(False).RightDockable(False).
-                              BottomDockable(False).TopDockable(True).
-                              CloseButton(False).Layer(2))
-
-            if self.show_target == False:
-                self.toolbars['gcpdisp'].Enable('zoommenu', enable = False)
-
-            self.toolbars['gcpman'] = GCPManToolbar(self)
-
-            self._mgr.AddPane(self.toolbars['gcpman'],
-                              wx.aui.AuiPaneInfo().
-                              Name("gcpmanagertoolbar").Caption(_("GCP Manager toolbar")).
-                              ToolbarPane().Top().Row(1).
-                              LeftDockable(False).RightDockable(False).
-                              BottomDockable(False).TopDockable(True).
-                              CloseButton(False).Layer(2))
-            
-        self._mgr.Update()
-
-    def OnUpdateProgress(self, event):
-        """
-        Update progress bar info
-        """
-        self.GetProgressBar().SetValue(event.value)
-        
-        event.Skip()
-        
-    def OnFocus(self, event):
-        """
-        Change choicebook page to match display.
-        Or set display for georectifying
-        """
-        if self._layerManager and \
-                self._layerManager.gcpmanagement:
-            # in GCP Management, set focus to current MapWindow for mouse actions
-            self.OnPointer(event)
-            self.MapWindow.SetFocus()
-        else:
-            # change bookcontrol page to page associated with display
-            # GCP Manager: use bookcontrol?
-            if self.page:
-                pgnum = self.layerbook.GetPageIndex(self.page)
-                if pgnum > -1:
-                    self.layerbook.SetSelection(pgnum)
-        
-        event.Skip()
-
-    def OnDraw(self, event):
-        """!Re-display current map composition
-        """
-        self.MapWindow.UpdateMap(render = False)
-        
-    def OnRender(self, event):
-        """!Re-render map composition (each map layer)
-        """
-        # delete tmp map layers (queries)
-        qlayer = self.Map.GetListOfLayers(l_name=globalvar.QUERYLAYER)
-        for layer in qlayer:
-            self.Map.DeleteLayer(layer)
-
-        self.SrcMapWindow.UpdateMap(render=True)
-        if self.show_target:
-            self.TgtMapWindow.UpdateMap(render=True)
-        
-        # update statusbar
-        self.StatusbarUpdate()
-
-    def OnPointer(self, event):
-        """!Pointer button clicked
-        """
-        # change the cursor
-        self.SrcMapWindow.SetCursor(self.cursors["cross"])
-        self.SrcMapWindow.mouse['use'] = "pointer"
-        self.SrcMapWindow.mouse['box'] = "point"
-        self.TgtMapWindow.SetCursor(self.cursors["cross"])
-        self.TgtMapWindow.mouse['use'] = "pointer"
-        self.TgtMapWindow.mouse['box'] = "point"
-
-    def OnZoomIn(self, event):
-        """
-        Zoom in the map.
-        Set mouse cursor, zoombox attributes, and zoom direction
-        """
-        if self.GetToolbar('map'):
-            self.toolbars['map'].OnTool(event)
-            self.toolbars['map'].action['desc'] = ''
-        
-        self.MapWindow.mouse['use'] = "zoom"
-        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"])
-
-        if self.MapWindow == self.SrcMapWindow:
-            win = self.TgtMapWindow
-        elif self.MapWindow == self.TgtMapWindow:
-            win = self.SrcMapWindow
-
-        win.mouse['use'] = "zoom"
-        win.mouse['box'] = "box"
-        win.zoomtype = 1
-        win.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
-        
-        # change the cursor
-        win.SetCursor(self.cursors["cross"])
-
-    def OnZoomOut(self, event):
-        """
-        Zoom out the map.
-        Set mouse cursor, zoombox attributes, and zoom direction
-        """
-        if self.GetToolbar('map'):
-            self.toolbars['map'].OnTool(event)
-            self.toolbars['map'].action['desc'] = ''
-        
-        self.MapWindow.mouse['use'] = "zoom"
-        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"])
-
-        if self.MapWindow == self.SrcMapWindow:
-            win = self.TgtMapWindow
-        elif self.MapWindow == self.TgtMapWindow:
-            win = self.SrcMapWindow
-
-        win.mouse['use'] = "zoom"
-        win.mouse['box'] = "box"
-        win.zoomtype = -1
-        win.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
-        
-        # change the cursor
-        win.SetCursor(self.cursors["cross"])
-
-    def OnPan(self, event):
-        """
-        Panning, set mouse to drag
-        """
-        if self.GetToolbar('map'):
-            self.toolbars['map'].OnTool(event)
-            self.toolbars['map'].action['desc'] = ''
-        
-        self.MapWindow.mouse['use'] = "pan"
-        self.MapWindow.mouse['box'] = "pan"
-        self.MapWindow.zoomtype = 0
-        
-        # change the cursor
-        self.MapWindow.SetCursor(self.cursors["hand"])
-
-        if self.MapWindow == self.SrcMapWindow:
-            win = self.TgtMapWindow
-        elif self.MapWindow == self.TgtMapWindow:
-            win = self.SrcMapWindow
-
-        win.mouse['use'] = "pan"
-        win.mouse['box'] = "pan"
-        win.zoomtype = 0
-        
-        # change the cursor
-        win.SetCursor(self.cursors["hand"])
-
-    def OnErase(self, event):
-        """
-        Erase the canvas
-        """
-        self.MapWindow.EraseMap()
-
-        if self.MapWindow == self.SrcMapWindow:
-            win = self.TgtMapWindow
-        elif self.MapWindow == self.TgtMapWindow:
-            win = self.SrcMapWindow
-
-        win.EraseMap()
-
-    def OnZoomRegion(self, event):
-        """
-        Zoom to region
-        """
-        self.Map.getRegion()
-        self.Map.getResolution()
-        self.UpdateMap()
-        # event.Skip()
-
-    def OnAlignRegion(self, event):
-        """
-        Align region
-        """
-        if not self.Map.alignRegion:
-            self.Map.alignRegion = True
-        else:
-            self.Map.alignRegion = False
-        # event.Skip()
-    
-    def SaveToFile(self, event):
-        """!Save map to image
-        """
-        img = self.MapWindow.img
-        if not img:
-            GMessage(parent = self,
-                     message = _("Nothing to render (empty map). Operation canceled."))
-            return
-        filetype, ltype = GetImageHandlers(img)
-
-        # get size
-        dlg = ImageSizeDialog(self)
-        dlg.CentreOnParent()
-        if dlg.ShowModal() != wx.ID_OK:
-            dlg.Destroy()
-            return
-        width, height = dlg.GetValues()
-        dlg.Destroy()
-        
-        # get filename
-        dlg = wx.FileDialog(parent = self,
-                            message = _("Choose a file name to save the image "
-                                        "(no need to add extension)"),
-                            wildcard = filetype,
-                            style=wx.SAVE | wx.FD_OVERWRITE_PROMPT)
-        
-        if dlg.ShowModal() == wx.ID_OK:
-            path = dlg.GetPath()
-            if not path:
-                dlg.Destroy()
-                return
-            
-            base, ext = os.path.splitext(path)
-            fileType = ltype[dlg.GetFilterIndex()]['type']
-            extType  = ltype[dlg.GetFilterIndex()]['ext']
-            if ext != extType:
-                path = base + '.' + extType
-            
-            self.MapWindow.SaveToFile(path, fileType,
-                                      width, height)
-            
-        dlg.Destroy()
-
-    def PrintMenu(self, event):
-        """
-        Print options and output menu for map display
-        """
-        point = wx.GetMousePosition()
-        printmenu = wx.Menu()
-        # Add items to the menu
-        setup = wx.MenuItem(printmenu, wx.ID_ANY, _('Page setup'))
-        printmenu.AppendItem(setup)
-        self.Bind(wx.EVT_MENU, self.printopt.OnPageSetup, setup)
-
-        preview = wx.MenuItem(printmenu, wx.ID_ANY, _('Print preview'))
-        printmenu.AppendItem(preview)
-        self.Bind(wx.EVT_MENU, self.printopt.OnPrintPreview, preview)
-
-        doprint = wx.MenuItem(printmenu, wx.ID_ANY, _('Print display'))
-        printmenu.AppendItem(doprint)
-        self.Bind(wx.EVT_MENU, self.printopt.OnDoPrint, doprint)
-
-        # Popup the menu.  If an item is selected then its handler
-        # will be called before PopupMenu returns.
-        self.PopupMenu(printmenu)
-        printmenu.Destroy()
-    
-    
-    def FormatDist(self, dist):
-        """!Format length numbers and units in a nice way,
-        as a function of length. From code by Hamish Bowman
-        Grass Development Team 2006"""
-
-        mapunits = self.Map.projinfo['units']
-        if mapunits == 'metres': mapunits = 'meters'
-        outunits = mapunits
-        dist = float(dist)
-        divisor = 1.0
-
-        # figure out which units to use
-        if mapunits == 'meters':
-            if dist > 2500.0:
-                outunits = 'km'
-                divisor = 1000.0
-            else: outunits = 'm'
-        elif mapunits == 'feet':
-            # nano-bug: we match any "feet", but US Survey feet is really
-            #  5279.9894 per statute mile, or 10.6' per 1000 miles. As >1000
-            #  miles the tick markers are rounded to the nearest 10th of a
-            #  mile (528'), the difference in foot flavours is ignored.
-            if dist > 5280.0:
-                outunits = 'miles'
-                divisor = 5280.0
-            else:
-                outunits = 'ft'
-        elif 'degree' in mapunits:
-            if dist < 1:
-                outunits = 'min'
-                divisor = (1/60.0)
-            else:
-                outunits = 'deg'
-
-        # format numbers in a nice way
-        if (dist/divisor) >= 2500.0:
-            outdist = round(dist/divisor)
-        elif (dist/divisor) >= 1000.0:
-            outdist = round(dist/divisor,1)
-        elif (dist/divisor) > 0.0:
-            outdist = round(dist/divisor,int(math.ceil(3-math.log10(dist/divisor))))
-        else:
-            outdist = float(dist/divisor)
-
-        return (outdist, outunits)
-
-    def OnZoomToRaster(self, event):
-        """!
-        Set display extents to match selected raster map (ignore NULLs)
-        """
-        self.MapWindow.ZoomToMap(ignoreNulls = True)
-        
-    def OnZoomToSaved(self, event):
-        """!Set display geometry to match extents in
-        saved region file
-        """
-        self.MapWindow.ZoomToSaved()
-        
-    def OnDisplayToWind(self, event):
-        """!Set computational region (WIND file) to match display
-        extents
-        """
-        self.MapWindow.DisplayToWind()
- 
-    def SaveDisplayRegion(self, event):
-        """!Save display extents to named region file.
-        """
-        self.MapWindow.SaveDisplayRegion()
-        
-    def OnZoomMenu(self, event):
-        """!Popup Zoom menu
-        """
-        point = wx.GetMousePosition()
-        zoommenu = wx.Menu()
-        # Add items to the menu
-
-        zoomwind = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to computational region (set with g.region)'))
-        zoommenu.AppendItem(zoomwind)
-        self.Bind(wx.EVT_MENU, self.OnZoomToWind, zoomwind)
-
-        zoomdefault = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to default region'))
-        zoommenu.AppendItem(zoomdefault)
-        self.Bind(wx.EVT_MENU, self.OnZoomToDefault, zoomdefault)
-
-        zoomsaved = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to saved region'))
-        zoommenu.AppendItem(zoomsaved)
-        self.Bind(wx.EVT_MENU, self.OnZoomToSaved, zoomsaved)
-
-        savewind = wx.MenuItem(zoommenu, wx.ID_ANY, _('Set computational region from display'))
-        zoommenu.AppendItem(savewind)
-        self.Bind(wx.EVT_MENU, self.OnDisplayToWind, savewind)
-
-        savezoom = wx.MenuItem(zoommenu, wx.ID_ANY, _('Save display geometry to named region'))
-        zoommenu.AppendItem(savezoom)
-        self.Bind(wx.EVT_MENU, self.SaveDisplayRegion, savezoom)
-
-        # Popup the menu. If an item is selected then its handler
-        # will be called before PopupMenu returns.
-        self.PopupMenu(zoommenu)
-        zoommenu.Destroy()
-        
-        
-    def IsStandalone(self):
-        """!Check if Map display is standalone"""
-        if self._layerManager:
-            return False
-        
-        return True
-    
-    def GetLayerManager(self):
-        """!Get reference to Layer Manager
-
-        @return window reference
-        @return None (if standalone)
-        """
-        return self._layerManager
-    
-    def GetSrcWindow(self):
-        return self.SrcMapWindow
-        
-    def GetTgtWindow(self):
-        return self.TgtMapWindow
-    
-    def GetShowTarget(self):
-        return self.show_target
-        
-    def GetMapToolbar(self):
-        """!Returns toolbar with zooming tools"""
-        return self.toolbars['gcpdisp']

Copied: grass/trunk/gui/wxpython/gcp/mapdisplay.py (from rev 49357, grass/trunk/gui/wxpython/gcp/mapdisp.py)
===================================================================
--- grass/trunk/gui/wxpython/gcp/mapdisplay.py	                        (rev 0)
+++ grass/trunk/gui/wxpython/gcp/mapdisplay.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -0,0 +1,629 @@
+"""!
+ at package gcp.mapdisp
+
+ at brief Display to manage ground control points with two toolbars, one
+for various display management functions, one for manipulating GCPs.
+
+Classes:
+- MapFrame
+
+(C) 2006-2011 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Markus Metz
+"""
+
+import os
+import math
+import platform
+
+from core import globalvar
+import wx
+import wx.aui
+
+from core.render       import EVT_UPDATE_PRGBAR
+from mapdisp.toolbars  import MapToolbar
+from gcp.toolbars      import GCPDisplayToolbar, GCPManToolbar
+from mapdisp.gprint    import PrintOptions
+from core.gcmd         import GMessage
+from gui_core.dialogs  import GetImageHandlers, ImageSizeDialog
+from gui_core.mapdisp  import MapFrameBase
+from core.settings     import UserSettings
+from mapdisp.mapwindow import BufferedWindow
+
+import mapdisp.statusbar as sb
+
+# for standalone app
+cmdfilename = None
+
+class MapFrame(MapFrameBase):
+    """!Main frame for map display window. Drawing takes place in
+    child double buffered drawing window.
+    """
+    def __init__(self, parent=None, title=_("GRASS GIS Manage Ground Control Points"),
+                 toolbars=["gcpdisp"], tree=None, notebook=None, lmgr=None,
+                 page=None, Map=None, auimgr=None, name = 'GCPMapWindow', **kwargs):
+        """!Main map display window with toolbars, statusbar and
+        DrawWindow
+
+        @param toolbars array of activated toolbars, e.g. ['map', 'digit']
+        @param tree reference to layer tree
+        @param notebook control book ID in Layer Manager
+        @param lmgr Layer Manager
+        @param page notebook page with layer tree
+        @param Map instance of render.Map
+        @param auimgs AUI manager
+        @param kwargs wx.Frame attribures
+        """
+        
+        MapFrameBase.__init__(self, parent = parent, title = title, toolbars = toolbars,
+                              Map = Map, auimgr = auimgr, name = name, **kwargs)
+        
+        self._layerManager = lmgr   # Layer Manager object
+        self.tree       = tree      # Layer Manager layer tree object
+        self.page       = page      # Notebook page holding the layer tree
+        self.layerbook  = notebook  # Layer Manager layer tree notebook
+        #
+        # Add toolbars
+        #
+        for toolb in toolbars:
+            self.AddToolbar(toolb)
+
+        self.activemap = self.toolbars['gcpdisp'].togglemap
+        self.activemap.SetSelection(0)
+        
+        self.SrcMap        = self.grwiz.SrcMap       # instance of render.Map
+        self.TgtMap        = self.grwiz.TgtMap       # instance of render.Map
+        self._mgr.SetDockSizeConstraint(0.5, 0.5)
+
+        #
+        # Add statusbar
+        #
+        
+        # items for choice
+        self.statusbarItems = [sb.SbCoordinates,
+                               sb.SbRegionExtent,
+                               sb.SbCompRegionExtent,
+                               sb.SbShowRegion,
+                               sb.SbResolution,
+                               sb.SbDisplayGeometry,
+                               sb.SbMapScale,
+                               sb.SbProjection,
+                               sb.SbGoToGCP,
+                               sb.SbRMSError]
+                            
+        
+        # create statusbar and its manager
+        statusbar = self.CreateStatusBar(number = 4, style = 0)
+        statusbar.SetStatusWidths([-5, -2, -1, -1])
+        self.statusbarManager = sb.SbManager(mapframe = self, statusbar = statusbar)
+        
+        # fill statusbar manager
+        self.statusbarManager.AddStatusbarItemsByClass(self.statusbarItems, mapframe = self, statusbar = statusbar)
+        self.statusbarManager.AddStatusbarItem(sb.SbMask(self, statusbar = statusbar, position = 2))
+        self.statusbarManager.AddStatusbarItem(sb.SbRender(self, statusbar = statusbar, position = 3))
+        
+        self.statusbarManager.SetMode(8) # goto GCP
+        self.statusbarManager.Update()
+        
+
+        #
+        # Init map display (buffered DC & set default cursor)
+        #
+        self.grwiz.SwitchEnv('source')
+        self.SrcMapWindow = BufferedWindow(self, id=wx.ID_ANY,
+                                          Map=self.SrcMap, tree=self.tree, lmgr=self._layerManager)
+
+        self.grwiz.SwitchEnv('target')
+        self.TgtMapWindow = BufferedWindow(self, id=wx.ID_ANY,
+                                          Map=self.TgtMap, tree=self.tree, lmgr=self._layerManager)
+        self.MapWindow = self.SrcMapWindow
+        self.Map = self.SrcMap
+        self.SrcMapWindow.SetCursor(self.cursors["cross"])
+        self.TgtMapWindow.SetCursor(self.cursors["cross"])
+
+        #
+        # initialize region values
+        #
+        self._initMap(map = self.SrcMap) 
+        self._initMap(map = self.TgtMap) 
+
+        #
+        # Bind various events
+        #
+        self.Bind(wx.EVT_ACTIVATE, self.OnFocus)
+        self.Bind(EVT_UPDATE_PRGBAR, self.OnUpdateProgress)
+        self.Bind(wx.EVT_SIZE,     self.OnDispResize)
+        self.activemap.Bind(wx.EVT_CHOICE, self.OnUpdateActive)
+        
+        #
+        # Update fancy gui style
+        #
+        # AuiManager wants a CentrePane, workaround to get two equally sized windows
+        self.list = self.CreateGCPList()
+
+        #self.SrcMapWindow.SetSize((300, 300))
+        #self.TgtMapWindow.SetSize((300, 300))
+        self.list.SetSize((100, 150))
+        self._mgr.AddPane(self.list, wx.aui.AuiPaneInfo().
+                  Name("gcplist").Caption(_("GCP List")).LeftDockable(False).
+                  RightDockable(False).PinButton().FloatingSize((600,200)).
+                  CloseButton(False).DestroyOnClose(True).
+                  Top().Layer(1).MinSize((200,100)))
+        self._mgr.AddPane(self.SrcMapWindow, wx.aui.AuiPaneInfo().
+                  Name("source").Caption(_("Source Display")).Dockable(False).
+                  CloseButton(False).DestroyOnClose(True).Floatable(False).
+                  Centre())
+        self._mgr.AddPane(self.TgtMapWindow, wx.aui.AuiPaneInfo().
+                  Name("target").Caption(_("Target Display")).Dockable(False).
+                  CloseButton(False).DestroyOnClose(True).Floatable(False).
+                  Right().Layer(0))
+
+        srcwidth, srcheight = self.SrcMapWindow.GetSize()
+        tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
+        srcwidth = (srcwidth + tgtwidth) / 2
+        self._mgr.GetPane("target").Hide()
+        self._mgr.Update()
+        self._mgr.GetPane("source").BestSize((srcwidth, srcheight))
+        self._mgr.GetPane("target").BestSize((srcwidth, srcheight))
+        if self.show_target:
+            self._mgr.GetPane("target").Show()
+        else:
+            self.activemap.Enable(False)
+        # needed by Mac OS, does not harm on Linux, breaks display on Windows
+        if platform.system() != 'Windows':
+            self._mgr.Update()
+
+        #
+        # Init print module and classes
+        #
+        self.printopt = PrintOptions(self, self.MapWindow)
+        
+        #
+        # Initialization of digitization tool
+        #
+        self.digit = None
+
+        # set active map
+        self.MapWindow = self.SrcMapWindow
+        self.Map = self.SrcMap
+        
+        # do not init zoom history here, that happens when zooming to map(s)
+
+        #
+        # Re-use dialogs
+        #
+        self.dialogs = {}
+        self.dialogs['attributes'] = None
+        self.dialogs['category'] = None
+        self.dialogs['barscale'] = None
+        self.dialogs['legend'] = None
+
+        self.decorationDialog = None # decoration/overlays
+
+    def AddToolbar(self, name):
+        """!Add defined toolbar to the window
+        
+        Currently known toolbars are:
+         - 'map'     - basic map toolbar
+         - 'vdigit'  - vector digitizer
+         - 'gcpdisp' - GCP Manager, Display
+         - 'gcpman'  - GCP Manager, points management
+         - 'nviz'    - 3D view mode
+        """
+        # default toolbar
+        if name == "map":
+            self.toolbars['map'] = MapToolbar(self, self.Map)
+
+            self._mgr.AddPane(self.toolbars['map'],
+                              wx.aui.AuiPaneInfo().
+                              Name("maptoolbar").Caption(_("Map Toolbar")).
+                              ToolbarPane().Top().
+                              LeftDockable(False).RightDockable(False).
+                              BottomDockable(False).TopDockable(True).
+                              CloseButton(False).Layer(2).
+                              BestSize((self.toolbars['map'].GetSize())))
+
+        # GCP display
+        elif name == "gcpdisp":
+            self.toolbars['gcpdisp'] = GCPDisplayToolbar(self)
+
+            self._mgr.AddPane(self.toolbars['gcpdisp'],
+                              wx.aui.AuiPaneInfo().
+                              Name("gcpdisplaytoolbar").Caption(_("GCP Display toolbar")).
+                              ToolbarPane().Top().
+                              LeftDockable(False).RightDockable(False).
+                              BottomDockable(False).TopDockable(True).
+                              CloseButton(False).Layer(2))
+
+            if self.show_target == False:
+                self.toolbars['gcpdisp'].Enable('zoommenu', enable = False)
+
+            self.toolbars['gcpman'] = GCPManToolbar(self)
+
+            self._mgr.AddPane(self.toolbars['gcpman'],
+                              wx.aui.AuiPaneInfo().
+                              Name("gcpmanagertoolbar").Caption(_("GCP Manager toolbar")).
+                              ToolbarPane().Top().Row(1).
+                              LeftDockable(False).RightDockable(False).
+                              BottomDockable(False).TopDockable(True).
+                              CloseButton(False).Layer(2))
+            
+        self._mgr.Update()
+
+    def OnUpdateProgress(self, event):
+        """
+        Update progress bar info
+        """
+        self.GetProgressBar().SetValue(event.value)
+        
+        event.Skip()
+        
+    def OnFocus(self, event):
+        """
+        Change choicebook page to match display.
+        Or set display for georectifying
+        """
+        if self._layerManager and \
+                self._layerManager.gcpmanagement:
+            # in GCP Management, set focus to current MapWindow for mouse actions
+            self.OnPointer(event)
+            self.MapWindow.SetFocus()
+        else:
+            # change bookcontrol page to page associated with display
+            # GCP Manager: use bookcontrol?
+            if self.page:
+                pgnum = self.layerbook.GetPageIndex(self.page)
+                if pgnum > -1:
+                    self.layerbook.SetSelection(pgnum)
+        
+        event.Skip()
+
+    def OnDraw(self, event):
+        """!Re-display current map composition
+        """
+        self.MapWindow.UpdateMap(render = False)
+        
+    def OnRender(self, event):
+        """!Re-render map composition (each map layer)
+        """
+        # delete tmp map layers (queries)
+        qlayer = self.Map.GetListOfLayers(l_name=globalvar.QUERYLAYER)
+        for layer in qlayer:
+            self.Map.DeleteLayer(layer)
+
+        self.SrcMapWindow.UpdateMap(render=True)
+        if self.show_target:
+            self.TgtMapWindow.UpdateMap(render=True)
+        
+        # update statusbar
+        self.StatusbarUpdate()
+
+    def OnPointer(self, event):
+        """!Pointer button clicked
+        """
+        # change the cursor
+        self.SrcMapWindow.SetCursor(self.cursors["cross"])
+        self.SrcMapWindow.mouse['use'] = "pointer"
+        self.SrcMapWindow.mouse['box'] = "point"
+        self.TgtMapWindow.SetCursor(self.cursors["cross"])
+        self.TgtMapWindow.mouse['use'] = "pointer"
+        self.TgtMapWindow.mouse['box'] = "point"
+
+    def OnZoomIn(self, event):
+        """
+        Zoom in the map.
+        Set mouse cursor, zoombox attributes, and zoom direction
+        """
+        if self.GetToolbar('map'):
+            self.toolbars['map'].OnTool(event)
+            self.toolbars['map'].action['desc'] = ''
+        
+        self.MapWindow.mouse['use'] = "zoom"
+        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"])
+
+        if self.MapWindow == self.SrcMapWindow:
+            win = self.TgtMapWindow
+        elif self.MapWindow == self.TgtMapWindow:
+            win = self.SrcMapWindow
+
+        win.mouse['use'] = "zoom"
+        win.mouse['box'] = "box"
+        win.zoomtype = 1
+        win.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
+        
+        # change the cursor
+        win.SetCursor(self.cursors["cross"])
+
+    def OnZoomOut(self, event):
+        """
+        Zoom out the map.
+        Set mouse cursor, zoombox attributes, and zoom direction
+        """
+        if self.GetToolbar('map'):
+            self.toolbars['map'].OnTool(event)
+            self.toolbars['map'].action['desc'] = ''
+        
+        self.MapWindow.mouse['use'] = "zoom"
+        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"])
+
+        if self.MapWindow == self.SrcMapWindow:
+            win = self.TgtMapWindow
+        elif self.MapWindow == self.TgtMapWindow:
+            win = self.SrcMapWindow
+
+        win.mouse['use'] = "zoom"
+        win.mouse['box'] = "box"
+        win.zoomtype = -1
+        win.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
+        
+        # change the cursor
+        win.SetCursor(self.cursors["cross"])
+
+    def OnPan(self, event):
+        """
+        Panning, set mouse to drag
+        """
+        if self.GetToolbar('map'):
+            self.toolbars['map'].OnTool(event)
+            self.toolbars['map'].action['desc'] = ''
+        
+        self.MapWindow.mouse['use'] = "pan"
+        self.MapWindow.mouse['box'] = "pan"
+        self.MapWindow.zoomtype = 0
+        
+        # change the cursor
+        self.MapWindow.SetCursor(self.cursors["hand"])
+
+        if self.MapWindow == self.SrcMapWindow:
+            win = self.TgtMapWindow
+        elif self.MapWindow == self.TgtMapWindow:
+            win = self.SrcMapWindow
+
+        win.mouse['use'] = "pan"
+        win.mouse['box'] = "pan"
+        win.zoomtype = 0
+        
+        # change the cursor
+        win.SetCursor(self.cursors["hand"])
+
+    def OnErase(self, event):
+        """
+        Erase the canvas
+        """
+        self.MapWindow.EraseMap()
+
+        if self.MapWindow == self.SrcMapWindow:
+            win = self.TgtMapWindow
+        elif self.MapWindow == self.TgtMapWindow:
+            win = self.SrcMapWindow
+
+        win.EraseMap()
+
+    def OnZoomRegion(self, event):
+        """
+        Zoom to region
+        """
+        self.Map.getRegion()
+        self.Map.getResolution()
+        self.UpdateMap()
+        # event.Skip()
+
+    def OnAlignRegion(self, event):
+        """
+        Align region
+        """
+        if not self.Map.alignRegion:
+            self.Map.alignRegion = True
+        else:
+            self.Map.alignRegion = False
+        # event.Skip()
+    
+    def SaveToFile(self, event):
+        """!Save map to image
+        """
+        img = self.MapWindow.img
+        if not img:
+            GMessage(parent = self,
+                     message = _("Nothing to render (empty map). Operation canceled."))
+            return
+        filetype, ltype = GetImageHandlers(img)
+
+        # get size
+        dlg = ImageSizeDialog(self)
+        dlg.CentreOnParent()
+        if dlg.ShowModal() != wx.ID_OK:
+            dlg.Destroy()
+            return
+        width, height = dlg.GetValues()
+        dlg.Destroy()
+        
+        # get filename
+        dlg = wx.FileDialog(parent = self,
+                            message = _("Choose a file name to save the image "
+                                        "(no need to add extension)"),
+                            wildcard = filetype,
+                            style=wx.SAVE | wx.FD_OVERWRITE_PROMPT)
+        
+        if dlg.ShowModal() == wx.ID_OK:
+            path = dlg.GetPath()
+            if not path:
+                dlg.Destroy()
+                return
+            
+            base, ext = os.path.splitext(path)
+            fileType = ltype[dlg.GetFilterIndex()]['type']
+            extType  = ltype[dlg.GetFilterIndex()]['ext']
+            if ext != extType:
+                path = base + '.' + extType
+            
+            self.MapWindow.SaveToFile(path, fileType,
+                                      width, height)
+            
+        dlg.Destroy()
+
+    def PrintMenu(self, event):
+        """
+        Print options and output menu for map display
+        """
+        point = wx.GetMousePosition()
+        printmenu = wx.Menu()
+        # Add items to the menu
+        setup = wx.MenuItem(printmenu, wx.ID_ANY, _('Page setup'))
+        printmenu.AppendItem(setup)
+        self.Bind(wx.EVT_MENU, self.printopt.OnPageSetup, setup)
+
+        preview = wx.MenuItem(printmenu, wx.ID_ANY, _('Print preview'))
+        printmenu.AppendItem(preview)
+        self.Bind(wx.EVT_MENU, self.printopt.OnPrintPreview, preview)
+
+        doprint = wx.MenuItem(printmenu, wx.ID_ANY, _('Print display'))
+        printmenu.AppendItem(doprint)
+        self.Bind(wx.EVT_MENU, self.printopt.OnDoPrint, doprint)
+
+        # Popup the menu.  If an item is selected then its handler
+        # will be called before PopupMenu returns.
+        self.PopupMenu(printmenu)
+        printmenu.Destroy()
+    
+    
+    def FormatDist(self, dist):
+        """!Format length numbers and units in a nice way,
+        as a function of length. From code by Hamish Bowman
+        Grass Development Team 2006"""
+
+        mapunits = self.Map.projinfo['units']
+        if mapunits == 'metres': mapunits = 'meters'
+        outunits = mapunits
+        dist = float(dist)
+        divisor = 1.0
+
+        # figure out which units to use
+        if mapunits == 'meters':
+            if dist > 2500.0:
+                outunits = 'km'
+                divisor = 1000.0
+            else: outunits = 'm'
+        elif mapunits == 'feet':
+            # nano-bug: we match any "feet", but US Survey feet is really
+            #  5279.9894 per statute mile, or 10.6' per 1000 miles. As >1000
+            #  miles the tick markers are rounded to the nearest 10th of a
+            #  mile (528'), the difference in foot flavours is ignored.
+            if dist > 5280.0:
+                outunits = 'miles'
+                divisor = 5280.0
+            else:
+                outunits = 'ft'
+        elif 'degree' in mapunits:
+            if dist < 1:
+                outunits = 'min'
+                divisor = (1/60.0)
+            else:
+                outunits = 'deg'
+
+        # format numbers in a nice way
+        if (dist/divisor) >= 2500.0:
+            outdist = round(dist/divisor)
+        elif (dist/divisor) >= 1000.0:
+            outdist = round(dist/divisor,1)
+        elif (dist/divisor) > 0.0:
+            outdist = round(dist/divisor,int(math.ceil(3-math.log10(dist/divisor))))
+        else:
+            outdist = float(dist/divisor)
+
+        return (outdist, outunits)
+
+    def OnZoomToRaster(self, event):
+        """!
+        Set display extents to match selected raster map (ignore NULLs)
+        """
+        self.MapWindow.ZoomToMap(ignoreNulls = True)
+        
+    def OnZoomToSaved(self, event):
+        """!Set display geometry to match extents in
+        saved region file
+        """
+        self.MapWindow.ZoomToSaved()
+        
+    def OnDisplayToWind(self, event):
+        """!Set computational region (WIND file) to match display
+        extents
+        """
+        self.MapWindow.DisplayToWind()
+ 
+    def SaveDisplayRegion(self, event):
+        """!Save display extents to named region file.
+        """
+        self.MapWindow.SaveDisplayRegion()
+        
+    def OnZoomMenu(self, event):
+        """!Popup Zoom menu
+        """
+        point = wx.GetMousePosition()
+        zoommenu = wx.Menu()
+        # Add items to the menu
+
+        zoomwind = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to computational region (set with g.region)'))
+        zoommenu.AppendItem(zoomwind)
+        self.Bind(wx.EVT_MENU, self.OnZoomToWind, zoomwind)
+
+        zoomdefault = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to default region'))
+        zoommenu.AppendItem(zoomdefault)
+        self.Bind(wx.EVT_MENU, self.OnZoomToDefault, zoomdefault)
+
+        zoomsaved = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to saved region'))
+        zoommenu.AppendItem(zoomsaved)
+        self.Bind(wx.EVT_MENU, self.OnZoomToSaved, zoomsaved)
+
+        savewind = wx.MenuItem(zoommenu, wx.ID_ANY, _('Set computational region from display'))
+        zoommenu.AppendItem(savewind)
+        self.Bind(wx.EVT_MENU, self.OnDisplayToWind, savewind)
+
+        savezoom = wx.MenuItem(zoommenu, wx.ID_ANY, _('Save display geometry to named region'))
+        zoommenu.AppendItem(savezoom)
+        self.Bind(wx.EVT_MENU, self.SaveDisplayRegion, savezoom)
+
+        # Popup the menu. If an item is selected then its handler
+        # will be called before PopupMenu returns.
+        self.PopupMenu(zoommenu)
+        zoommenu.Destroy()
+        
+        
+    def IsStandalone(self):
+        """!Check if Map display is standalone"""
+        if self._layerManager:
+            return False
+        
+        return True
+    
+    def GetLayerManager(self):
+        """!Get reference to Layer Manager
+
+        @return window reference
+        @return None (if standalone)
+        """
+        return self._layerManager
+    
+    def GetSrcWindow(self):
+        return self.SrcMapWindow
+        
+    def GetTgtWindow(self):
+        return self.TgtMapWindow
+    
+    def GetShowTarget(self):
+        return self.show_target
+        
+    def GetMapToolbar(self):
+        """!Returns toolbar with zooming tools"""
+        return self.toolbars['gcpdisp']

Modified: grass/trunk/gui/wxpython/gmodeler/dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/dialogs.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/gmodeler/dialogs.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -24,10 +24,12 @@
 import wx
 
 from core                 import globalvar
+from core                 import utils
 from gui_core.widgets     import GNotebook
 from core.gcmd            import GError, EncodeString
 from gui_core.dialogs     import ElementDialog, MapLayersDialog
 from gui_core.ghelp       import SearchModuleWindow
+from gui_core.prompt      import GPromptSTC
 
 from grass.script import task as gtask
 
@@ -124,7 +126,7 @@
         self.cmdBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
                                    label=" %s " % _("Command"))
         
-        self.cmd_prompt = prompt.GPromptSTC(parent = self)
+        self.cmd_prompt = GPromptSTC(parent = self)
         self.search = SearchModuleWindow(parent = self.panel, cmdPrompt = self.cmd_prompt, showTip = True)
         wx.CallAfter(self.cmd_prompt.SetFocus)
         

Modified: grass/trunk/gui/wxpython/gmodeler/frame.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/frame.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/gmodeler/frame.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -7,20 +7,13 @@
  - ModelToolbar
  - ModelFrame
  - ModelCanvas
- - ModelObject
- - ModelAction
- - ModelData
  - ModelEvtHandler
- - ModelRelation
  - ModelListCtrl
  - VariablePanel
  - ValiableListCtrl
- - ModelItem
- - ModelLoop
  - ItemPanel
  - ItemListCtrl
  - ItemCheckListCtrl
- - ModelCondition
 
 (C) 2010-2011 by the GRASS Development Team
 This program is free software under the GNU General Public License
@@ -39,7 +32,7 @@
 import re
 
 import wx
-import wx.lib.ogl             as ogl
+from wx.lib import ogl
 import wx.lib.flatnotebook    as FN
 import wx.lib.mixins.listctrl as listmix
 
@@ -53,7 +46,14 @@
 from core.settings        import UserSettings
 from core.menudata        import MenuData
 from gui_core.toolbars    import BaseToolbar
+from gui_core.menu        import Menu
+from gmodeler.menudata    import ModelerData
+from icons.icon           import Icons
+from gui_core.forms       import GUI
 
+from gmodeler.model       import *
+from gmodeler.dialogs     import *
+
 from grass.script import core as grass
 
 class ModelToolbar(BaseToolbar):
@@ -1073,497 +1073,7 @@
                 item.Update()
         
         self.Refresh()
-        
-class ModelObject:
-    def __init__(self, id = -1):
-        self.id   = id
-        self.rels = list() # list of ModelRelations
-        
-        self.isEnabled = True
-        self.inBlock   = list() # list of related loops/conditions
-        
-    def __del__(self):
-        pass
-    
-    def GetId(self):
-        """!Get id"""
-        return self.id
-    
-    def AddRelation(self, rel):
-        """!Record new relation
-        """
-        self.rels.append(rel)
-
-    def GetRelations(self, fdir = None):
-        """!Get list of relations
-        
-        @param fdir True for 'from'
-        """
-        if fdir is None:
-            return self.rels
-        
-        result = list()
-        for rel in self.rels:
-            if fdir == 'from':
-                if rel.GetFrom() == self:
-                    result.append(rel)
-            else:
-                if rel.GetTo() == self:
-                    result.append(rel)
-        
-        return result
-    
-    def IsEnabled(self):
-        """!Get True if action is enabled, otherwise False"""
-        return self.isEnabled
-    
-    def Enable(self, enabled = True):
-        """!Enable/disable action"""
-        self.isEnabled = enabled
-        self.Update()
-
-    def Update(self):
-        pass
-
-    def SetBlock(self, item):
-        """!Add object to the block (loop/condition)
-
-        @param item reference to ModelLoop or ModelCondition which
-        defines loops/condition
-        """
-        if item not in self.inBlock:
-            self.inBlock.append(item)
-        
-    def UnSetBlock(self, item):
-        """!Remove object from the block (loop/consition)
-
-        @param item reference to ModelLoop or ModelCondition which
-        defines loops/codition
-        """
-        if item in self.inBlock:
-            self.inBlock.remove(item)
-        
-    def GetBlock(self):
-        """!Get list of related ModelObject(s) which defines block
-        (loop/condition)
-
-        @return list of ModelObjects
-        """
-        return self.inBlock
-    
-    def GetBlockId(self):
-        """!Get list of related ids which defines block
-
-        @return list of ids
-        """
-        ret = list()
-        for mo in self.inBlock:
-            ret.append(mo.GetId())
-        
-        return ret
-    
-class ModelAction(ModelObject, ogl.RectangleShape):
-    """!Action class (GRASS module)"""
-    def __init__(self, parent, x, y, id = -1, cmd = None, task = None, width = None, height = None):
-        ModelObject.__init__(self, id)
-        
-        self.parent  = parent
-        self.task    = task
-        
-        if not width:
-            width = UserSettings.Get(group='modeler', key='action', subkey=('size', 'width'))
-        if not height:
-            height = UserSettings.Get(group='modeler', key='action', subkey=('size', 'height'))
-        
-        if cmd:
-            self.task = GUI(show = None).ParseCommand(cmd = cmd)
-        else:
-            if task:
-                self.task = task
-            else:
-                self.task = None
-        
-        self.propWin = None
-        
-        self.data = list()   # list of connected data items
-        
-        self.isValid = False
-        self.isParameterized = False
-        
-        if self.parent.GetCanvas():
-            ogl.RectangleShape.__init__(self, width, height)
-            
-            self.SetCanvas(self.parent)
-            self.SetX(x)
-            self.SetY(y)
-            self.SetPen(wx.BLACK_PEN)
-            self._setPen()
-            self._setBrush()
-            self.SetId(id)
-        
-        if self.task:
-            self.SetValid(self.task.get_options())
-        
-    def _setBrush(self, running = False):
-        """!Set brush"""
-        if running:
-            color = UserSettings.Get(group='modeler', key='action',
-                                     subkey=('color', 'running'))
-        elif not self.isEnabled:
-            color = UserSettings.Get(group='modeler', key='disabled',
-                                     subkey='color')
-        elif self.isValid:
-            color = UserSettings.Get(group='modeler', key='action',
-                                     subkey=('color', 'valid'))
-        else:
-            color = UserSettings.Get(group='modeler', key='action',
-                                     subkey=('color', 'invalid'))
-        
-        wxColor = wx.Color(color[0], color[1], color[2])
-        self.SetBrush(wx.Brush(wxColor))
-        
-    def _setPen(self):
-        """!Set pen"""
-        if self.isParameterized:
-            width = int(UserSettings.Get(group='modeler', key='action',
-                                         subkey=('width', 'parameterized')))
-        else:
-            width = int(UserSettings.Get(group='modeler', key='action',
-                                         subkey=('width', 'default')))
-        pen = self.GetPen()
-        pen.SetWidth(width)
-        self.SetPen(pen)
-
-    def SetId(self, id):
-        """!Set id"""
-        self.id = id
-        cmd = self.task.get_cmd(ignoreErrors = True)
-        if cmd and len(cmd) > 0:
-            self.ClearText()
-            self.AddText('(%d) %s' % (self.id, cmd[0]))
-        else:
-            self.AddText('(%d) <<%s>>' % (self.id, _("unknown")))
-        
-    def SetProperties(self, params, propwin):
-        """!Record properties dialog"""
-        self.task.params = params['params']
-        self.task.flags  = params['flags']
-        self.propWin = propwin
-
-    def GetPropDialog(self):
-        """!Get properties dialog"""
-        return self.propWin
-
-    def GetLog(self, string = True, substitute = None):
-        """!Get logging info
-
-        @param string True to get cmd as a string otherwise a list
-        @param substitute dictionary of parameter to substitute or None
-        """
-        cmd = self.task.get_cmd(ignoreErrors = True, ignoreRequired = True,
-                                ignoreDefault = False)
-        
-        # substitute variables
-        if substitute:
-            variables = []
-            if 'variables' in substitute:
-                for p in substitute['variables']['params']:
-                    variables.append(p.get('name', ''))
-            else:
-                variables = self.parent.GetVariables()
-            for variable in variables:
-                pattern= re.compile('%' + variable)
-                value = ''
-                if substitute and 'variables' in substitute:
-                    for p in substitute['variables']['params']:
-                        if variable == p.get('name', ''):
-                            if p.get('type', 'string') == 'string':
-                                value = p.get('value', '')
-                            else:
-                                value = str(p.get('value', ''))
-                            break
-                    
-                if not value:
-                    value = variables[variable].get('value', '')
-                
-                if not value:
-                    continue
-                
-                for idx in range(len(cmd)):
-                    if pattern.search(cmd[idx]):
-                        cmd[idx] = pattern.sub(value, cmd[idx])
-                        break
-                    idx += 1
-        
-        if string:
-            if cmd is None:
-                return ''
-            else:
-                return ' '.join(cmd)
-        
-        return cmd
-    
-    def GetName(self):
-        """!Get name"""
-        cmd = self.task.get_cmd(ignoreErrors = True)
-        if cmd and len(cmd) > 0:
-            return cmd[0]
-        
-        return _('unknown')
-
-    def GetParams(self, dcopy = False):
-        """!Get dictionary of parameters"""
-        if dcopy:
-            return copy.deepcopy(self.task.get_options())
-        
-        return self.task.get_options()
-
-    def GetTask(self):
-        """!Get grassTask instance"""
-        return self.task
-    
-    def SetParams(self, params):
-        """!Set dictionary of parameters"""
-        self.task.params = params['params']
-        self.task.flags  = params['flags']
-        
-    def MergeParams(self, params):
-        """!Merge dictionary of parameters"""
-        if 'flags' in params:
-            for f in params['flags']:
-                self.task.set_flag(f['name'],
-                                   f.get('value', False))
-        if 'params' in params:
-            for p in params['params']:
-                self.task.set_param(p['name'],
-                                    p.get('value', ''))
-        
-    def SetValid(self, options):
-        """!Set validity for action
-        
-        @param options dictionary with flags and params (gtask)
-        """
-        self.isValid = True
-        self.isParameterized = False
-        
-        for f in options['flags']:
-            if f.get('parameterized', False):
-                self.IsParameterized = True
-                break
-        
-        for p in options['params']:
-            if self.isValid and p.get('required', False) and \
-                    p.get('value', '') == '' and \
-                    p.get('default', '') == '':
-                self.isValid = False
-            if not self.isParameterized and p.get('parameterized', False):
-                self.isParameterized = True
-        
-        if self.parent.GetCanvas():
-            self._setBrush()
-            self._setPen()
-        
-    def IsValid(self):
-        """!Check validity (all required parameters set)"""
-        return self.isValid
-    
-    def IsParameterized(self):
-        """!Check if action is parameterized"""
-        return self.isParameterized
-    
-    def FindData(self, name):
-        """!Find data item by name"""
-        for rel in self.GetRelations():
-            data = rel.GetData()
-            if name == rel.GetName() and name in data.GetName():
-                return data
-        
-        return None
-
-    def Update(self, running = False):
-        """!Update action"""
-        if running:
-            self._setBrush(running = True)
-        else:
-            self._setBrush()
-        self._setPen()
-
-    def OnDraw(self, dc):
-        """!Draw action in canvas"""
-        self._setBrush()
-        self._setPen()
-        ogl.RectangleShape.OnDraw(self, dc)
-
-class ModelData(ModelObject, ogl.EllipseShape):
-    def __init__(self, parent, x, y, value = '', prompt = '', width = None, height = None):
-        """Data item class
-        
-        @param parent window parent
-        @param x, y   position of the shape
-        @param fname, tname list of parameter names from / to
-        @param value  value
-        @param prompt type of GIS element
-        @param width,height dimension of the shape
-        """
-        ModelObject.__init__(self)
-        
-        self.parent  = parent
-        self.value   = value
-        self.prompt  = prompt
-        self.intermediate = False
-        self.propWin = None
-        if not width:
-            width = UserSettings.Get(group='modeler', key='data', subkey=('size', 'width'))
-        if not height:
-            height = UserSettings.Get(group='modeler', key='data', subkey=('size', 'height'))
-        
-        if self.parent.GetCanvas():
-            ogl.EllipseShape.__init__(self, width, height)
-            
-            self.SetCanvas(self.parent)
-            self.SetX(x)
-            self.SetY(y)
-            self.SetPen(wx.BLACK_PEN)
-            self._setBrush()
-            
-            self._setText()
-            
-    def IsIntermediate(self):
-        """!Checks if data item is intermediate"""
-        return self.intermediate
-    
-    def SetIntermediate(self, im):
-        """!Set intermediate flag"""
-        self.intermediate = im
   
-    def OnDraw(self, dc):
-        pen = self.GetPen()
-        pen.SetWidth(1)
-        if self.intermediate:
-            pen.SetStyle(wx.SHORT_DASH)
-        else:
-            pen.SetStyle(wx.SOLID)
-        self.SetPen(pen)
-        
-        ogl.EllipseShape.OnDraw(self, dc)
-        
-    def GetLog(self, string = True):
-        """!Get logging info"""
-        name = list()
-        for rel in self.GetRelations():
-            name.append(rel.GetName())
-        if name:
-            return '/'.join(name) + '=' + self.value + ' (' + self.prompt + ')'
-        else:
-            return self.value + ' (' + self.prompt + ')'
-
-    def GetName(self):
-        """!Get list of names"""
-        name = list()
-        for rel in self.GetRelations():
-            name.append(rel.GetName())
-        
-        return name
-    
-    def GetPrompt(self):
-        """!Get prompt"""
-        return self.prompt
-
-    def SetPrompt(self, prompt):
-        """!Set prompt
-        
-        @param prompt
-        """
-        self.prompt = prompt
-        
-    def GetValue(self):
-        """!Get value"""
-        return self.value
-
-    def SetValue(self, value):
-        """!Set value
-
-        @param value
-        """
-        self.value = value
-        self._setText()
-        for direction in ('from', 'to'):
-            for rel in self.GetRelations(direction):
-                if direction == 'from':
-                    action = rel.GetTo()
-                else:
-                    action = rel.GetFrom()
-                
-                task = GUI(show = None).ParseCommand(cmd = action.GetLog(string = False))
-                task.set_param(rel.GetName(), self.value)
-                action.SetParams(params = task.get_options())
-        
-    def GetPropDialog(self):
-        """!Get properties dialog"""
-        return self.propWin
-
-    def SetPropDialog(self, win):
-        """!Get properties dialog"""
-        self.propWin = win
-
-    def _setBrush(self):
-        """!Set brush"""
-        if self.prompt == 'raster':
-            color = UserSettings.Get(group = 'modeler', key = 'data',
-                                     subkey = ('color', 'raster'))
-        elif self.prompt == 'raster3d':
-            color = UserSettings.Get(group = 'modeler', key = 'data',
-                                     subkey = ('color', 'raster3d'))
-        elif self.prompt == 'vector':
-            color = UserSettings.Get(group = 'modeler', key = 'data',
-                                     subkey = ('color', 'vector'))
-        else:
-            color = UserSettings.Get(group = 'modeler', key = 'action',
-                                     subkey = ('color', 'invalid'))
-        wxColor = wx.Color(color[0], color[1], color[2])
-        self.SetBrush(wx.Brush(wxColor))
-        
-    def _setPen(self):
-        """!Set pen"""
-        isParameterized = False
-        for rel in self.GetRelations('from'):
-            if rel.GetTo().IsParameterized():
-                isParameterized = True
-                break
-        if not isParameterized:
-            for rel in self.GetRelations('to'):
-                if rel.GetFrom().IsParameterized():
-                    isParameterized = True
-                    break
-
-        if isParameterized:
-            width = int(UserSettings.Get(group = 'modeler', key = 'action',
-                                         subkey = ('width', 'parameterized')))
-        else:
-            width = int(UserSettings.Get(group = 'modeler', key = 'action',
-                                         subkey = ('width', 'default')))
-        pen = self.GetPen()
-        pen.SetWidth(width)
-        self.SetPen(pen)
-        
-    def _setText(self):
-        """!Update text"""
-        self.ClearText()
-        name = []
-        for rel in self.GetRelations():
-            name.append(rel.GetName())
-        self.AddText('/'.join(name))
-        if self.value:
-            self.AddText(self.value)
-        else:
-            self.AddText(_('<not defined>'))
-        
-    def Update(self):
-        """!Update action"""
-        self._setBrush()
-        self._setPen()
-        self._setText()
-       
 class ModelEvtHandler(ogl.ShapeEvtHandler):
     """!Model event handler class"""
     def __init__(self, log, frame):
@@ -1815,80 +1325,7 @@
         """
         self.frame.GetCanvas().RemoveSelected()
         self.frame.itemPanel.Update()
-        
-class ModelRelation(ogl.LineShape):
-    """!Data - action relation"""
-    def __init__(self, parent, fromShape, toShape, param = ''):
-        self.fromShape = fromShape
-        self.toShape   = toShape
-        self.param     = param
-        self.parent    = parent
-        
-        self._points    = None
-        
-        if self.parent.GetCanvas():        
-            ogl.LineShape.__init__(self)
-    
-    def __del__(self):
-        if self in self.fromShape.rels:
-            self.fromShape.rels.remove(self)
-        if self in self.toShape.rels:
-            self.toShape.rels.remove(self)
-        
-    def GetFrom(self):
-        """!Get id of 'from' shape"""
-        return self.fromShape
-    
-    def GetTo(self):
-        """!Get id of 'to' shape"""
-        return self.toShape
-    
-    def GetData(self):
-        """!Get related ModelData instance
-
-        @return ModelData instance
-        @return None if not found
-        """
-        if isinstance(self.fromShape, ModelData):
-            return self.fromShape
-        elif isinstance(self.toShape, ModelData):
-            return self.toShape
-        
-        return None
-    
-    def GetName(self):
-        """!Get parameter name"""
-        return self.param
-    
-    def ResetShapes(self):
-        """!Reset related objects"""
-        self.fromShape.ResetControlPoints()
-        self.toShape.ResetControlPoints()
-        self.ResetControlPoints()
-        
-    def SetControlPoints(self, points):
-        """!Set control points"""
-        self._points = points
-        
-    def GetControlPoints(self):
-        """!Get list of control points"""
-        return self._points
-    
-    def _setPen(self):
-        """!Set pen"""
-        pen = self.GetPen()
-        pen.SetWidth(1)
-        pen.SetStyle(wx.SOLID)
-        self.SetPen(pen)
-        
-    def OnDraw(self, dc):
-        """!Draw relation"""
-        self._setPen()
-        ogl.LineShape.OnDraw(self, dc)
-    
-    def SetName(self, param):
-        self.param = param
-        
+       
 class ModelListCtrl(wx.ListCtrl,
                     listmix.ListCtrlAutoWidthMixin,
                     listmix.TextEditMixin,
@@ -2209,105 +1646,7 @@
         
         self.PopupMenu(menu)
         menu.Destroy()
-        
-class ModelItem(ModelObject):
-    def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '', items = []):
-        """!Abstract class for loops and conditions"""
-        ModelObject.__init__(self, id)
-        self.parent  = parent
-        self.text    = text
-        self.items   = items  # list of items in the loop
-        
-    def GetText(self):
-        """!Get loop text"""
-        return self.text
 
-    def GetItems(self):
-        """!Get items (id)"""
-        return self.items
-
-    def SetId(self, id):
-        """!Set loop id"""
-        self.id = id
-
-    def SetText(self, cond):
-        """!Set loop text (condition)"""
-        self.text = cond
-        self.ClearText()
-        self.AddText('(' + str(self.id) + ') ' + self.text)
-
-    def GetLog(self):
-        """!Get log info"""
-        if self.text:
-            return _("Condition: ") + self.text
-        else:
-            return _("Condition: not defined")
-
-    def AddRelation(self, rel):
-        """!Record relation"""
-        self.rels.append(rel)
-        
-    def Clear(self):
-        """!Clear object, remove rels"""
-        self.rels = list()
-   
-class ModelLoop(ModelItem, ogl.RectangleShape):
-    def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '', items = []):
-        """!Defines a loop"""
-        ModelItem.__init__(self, parent, x, y, id, width, height, text, items)
-        
-        if not width:
-            width = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'width'))
-        if not height:
-            height = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'height'))
-        
-        if self.parent.GetCanvas():
-            ogl.RectangleShape.__init__(self, width, height)
-            
-            self.SetCanvas(self.parent)
-            self.SetX(x)
-            self.SetY(y)
-            self.SetPen(wx.BLACK_PEN)
-            self.SetCornerRadius(100)
-            if text:
-                self.AddText('(' + str(self.id) + ') ' + text)
-            else:
-                self.AddText('(' + str(self.id) + ')')
-        
-        self._setBrush()
-        
-    def _setBrush(self):
-        """!Set brush"""
-        if not self.isEnabled:
-            color = UserSettings.Get(group='modeler', key='disabled',
-                                     subkey='color')
-        else:
-            color = UserSettings.Get(group='modeler', key='loop',
-                                     subkey=('color', 'valid'))
-        
-        wxColor = wx.Color(color[0], color[1], color[2])
-        self.SetBrush(wx.Brush(wxColor))
-
-    def Enable(self, enabled = True):
-        """!Enable/disable action"""
-        for item in self.items:
-            if not isinstance(item, ModelAction):
-                continue
-            item.Enable(enabled)
-        
-        ModelObject.Enable(self, enabled)
-        
-    def Update(self):
-        self._setBrush()
-        
-    def GetName(self):
-        """!Get name"""
-        return _("loop")
-    
-    def SetItems(self, items):
-        """!Set items (id)"""
-        self.items = items
-
 class ItemPanel(wx.Panel):
     def __init__(self, parent, id = wx.ID_ANY,
                  **kwargs):
@@ -2575,60 +1914,6 @@
                 self.CheckItem(i, flag)
                 break
         
-class ModelCondition(ModelItem, ogl.PolygonShape):
-    def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '',
-                 items = { 'if' : [], 'else' : [] }):
-        """!Defines a if-else condition"""
-        ModelItem.__init__(self, parent, x, y, id, width, height, text, items)
-        
-        if not width:
-            self.width = UserSettings.Get(group='modeler', key='if-else', subkey=('size', 'width'))
-        else:
-            self.width = width
-        if not height:
-            self.height = UserSettings.Get(group='modeler', key='if-else', subkey=('size', 'height'))
-        else:
-            self.height = height
-        
-        if self.parent.GetCanvas():
-            ogl.PolygonShape.__init__(self)
-            
-            points = [(0, - self.height / 2),
-                      (self.width / 2, 0),
-                      (0, self.height / 2),
-                      (- self.width / 2, 0)]
-            self.Create(points)
-            
-            self.SetCanvas(self.parent)
-            self.SetX(x)
-            self.SetY(y)
-            self.SetPen(wx.BLACK_PEN)
-            if text:
-                self.AddText('(' + str(self.id) + ') ' + text)
-            else:
-                self.AddText('(' + str(self.id) + ')')
-
-    def GetName(self):
-        """!Get name"""
-        return _("if-else")
-
-    def GetWidth(self):
-        """!Get object width"""
-        return self.width
-
-    def GetHeight(self):
-        """!Get object height"""
-        return self.height
-
-    def SetItems(self, items, branch = 'if'):
-        """!Set items (id)
-
-        @param items list of items
-        @param branch 'if' / 'else'
-        """
-        if branch in ['if', 'else']:
-            self.items[branch] = items
-        
 def main():
     import gettext
     gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode = True)

Modified: grass/trunk/gui/wxpython/gmodeler/model.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/model.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/gmodeler/model.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -5,6 +5,13 @@
 
 Classes:
  - Model
+ - ModelObject
+ - ModelAction
+ - ModelData
+ - ModelRelation
+ - ModelItem
+ - ModelLoop
+ - ModelCondition
 
 (C) 2010-2011 by the GRASS Development Team
 This program is free software under the GNU General Public License
@@ -23,9 +30,11 @@
     import elementtree.ElementTree as etree # Python <= 2.4
 
 import wx
+from wx.lib import ogl
 
-from core.globalvar import ETCWXDIR
-from core.gcmd      import GMessage, GException, GError, RunCommand
+from core.globalvar   import ETCWXDIR
+from core.gcmd        import GMessage, GException, GError, RunCommand
+from gmodeler.dialogs import ModelParamDialog
 
 from grass.script import core as grass
 from grass.script import task as gtask
@@ -729,3 +738,718 @@
         self.variablesParams = result # record parameters
         
         return result
+
+class ModelObject:
+    def __init__(self, id = -1):
+        self.id   = id
+        self.rels = list() # list of ModelRelations
+        
+        self.isEnabled = True
+        self.inBlock   = list() # list of related loops/conditions
+        
+    def __del__(self):
+        pass
+    
+    def GetId(self):
+        """!Get id"""
+        return self.id
+    
+    def AddRelation(self, rel):
+        """!Record new relation
+        """
+        self.rels.append(rel)
+
+    def GetRelations(self, fdir = None):
+        """!Get list of relations
+        
+        @param fdir True for 'from'
+        """
+        if fdir is None:
+            return self.rels
+        
+        result = list()
+        for rel in self.rels:
+            if fdir == 'from':
+                if rel.GetFrom() == self:
+                    result.append(rel)
+            else:
+                if rel.GetTo() == self:
+                    result.append(rel)
+        
+        return result
+    
+    def IsEnabled(self):
+        """!Get True if action is enabled, otherwise False"""
+        return self.isEnabled
+    
+    def Enable(self, enabled = True):
+        """!Enable/disable action"""
+        self.isEnabled = enabled
+        self.Update()
+
+    def Update(self):
+        pass
+
+    def SetBlock(self, item):
+        """!Add object to the block (loop/condition)
+
+        @param item reference to ModelLoop or ModelCondition which
+        defines loops/condition
+        """
+        if item not in self.inBlock:
+            self.inBlock.append(item)
+        
+    def UnSetBlock(self, item):
+        """!Remove object from the block (loop/consition)
+
+        @param item reference to ModelLoop or ModelCondition which
+        defines loops/codition
+        """
+        if item in self.inBlock:
+            self.inBlock.remove(item)
+        
+    def GetBlock(self):
+        """!Get list of related ModelObject(s) which defines block
+        (loop/condition)
+
+        @return list of ModelObjects
+        """
+        return self.inBlock
+    
+    def GetBlockId(self):
+        """!Get list of related ids which defines block
+
+        @return list of ids
+        """
+        ret = list()
+        for mo in self.inBlock:
+            ret.append(mo.GetId())
+        
+        return ret
+    
+class ModelAction(ModelObject, ogl.RectangleShape):
+    """!Action class (GRASS module)"""
+    def __init__(self, parent, x, y, id = -1, cmd = None, task = None, width = None, height = None):
+        ModelObject.__init__(self, id)
+        
+        self.parent  = parent
+        self.task    = task
+        
+        if not width:
+            width = UserSettings.Get(group='modeler', key='action', subkey=('size', 'width'))
+        if not height:
+            height = UserSettings.Get(group='modeler', key='action', subkey=('size', 'height'))
+        
+        if cmd:
+            self.task = GUI(show = None).ParseCommand(cmd = cmd)
+        else:
+            if task:
+                self.task = task
+            else:
+                self.task = None
+        
+        self.propWin = None
+        
+        self.data = list()   # list of connected data items
+        
+        self.isValid = False
+        self.isParameterized = False
+        
+        if self.parent.GetCanvas():
+            ogl.RectangleShape.__init__(self, width, height)
+            
+            self.SetCanvas(self.parent)
+            self.SetX(x)
+            self.SetY(y)
+            self.SetPen(wx.BLACK_PEN)
+            self._setPen()
+            self._setBrush()
+            self.SetId(id)
+        
+        if self.task:
+            self.SetValid(self.task.get_options())
+        
+    def _setBrush(self, running = False):
+        """!Set brush"""
+        if running:
+            color = UserSettings.Get(group='modeler', key='action',
+                                     subkey=('color', 'running'))
+        elif not self.isEnabled:
+            color = UserSettings.Get(group='modeler', key='disabled',
+                                     subkey='color')
+        elif self.isValid:
+            color = UserSettings.Get(group='modeler', key='action',
+                                     subkey=('color', 'valid'))
+        else:
+            color = UserSettings.Get(group='modeler', key='action',
+                                     subkey=('color', 'invalid'))
+        
+        wxColor = wx.Color(color[0], color[1], color[2])
+        self.SetBrush(wx.Brush(wxColor))
+        
+    def _setPen(self):
+        """!Set pen"""
+        if self.isParameterized:
+            width = int(UserSettings.Get(group='modeler', key='action',
+                                         subkey=('width', 'parameterized')))
+        else:
+            width = int(UserSettings.Get(group='modeler', key='action',
+                                         subkey=('width', 'default')))
+        pen = self.GetPen()
+        pen.SetWidth(width)
+        self.SetPen(pen)
+
+    def SetId(self, id):
+        """!Set id"""
+        self.id = id
+        cmd = self.task.get_cmd(ignoreErrors = True)
+        if cmd and len(cmd) > 0:
+            self.ClearText()
+            self.AddText('(%d) %s' % (self.id, cmd[0]))
+        else:
+            self.AddText('(%d) <<%s>>' % (self.id, _("unknown")))
+        
+    def SetProperties(self, params, propwin):
+        """!Record properties dialog"""
+        self.task.params = params['params']
+        self.task.flags  = params['flags']
+        self.propWin = propwin
+
+    def GetPropDialog(self):
+        """!Get properties dialog"""
+        return self.propWin
+
+    def GetLog(self, string = True, substitute = None):
+        """!Get logging info
+
+        @param string True to get cmd as a string otherwise a list
+        @param substitute dictionary of parameter to substitute or None
+        """
+        cmd = self.task.get_cmd(ignoreErrors = True, ignoreRequired = True,
+                                ignoreDefault = False)
+        
+        # substitute variables
+        if substitute:
+            variables = []
+            if 'variables' in substitute:
+                for p in substitute['variables']['params']:
+                    variables.append(p.get('name', ''))
+            else:
+                variables = self.parent.GetVariables()
+            for variable in variables:
+                pattern= re.compile('%' + variable)
+                value = ''
+                if substitute and 'variables' in substitute:
+                    for p in substitute['variables']['params']:
+                        if variable == p.get('name', ''):
+                            if p.get('type', 'string') == 'string':
+                                value = p.get('value', '')
+                            else:
+                                value = str(p.get('value', ''))
+                            break
+                    
+                if not value:
+                    value = variables[variable].get('value', '')
+                
+                if not value:
+                    continue
+                
+                for idx in range(len(cmd)):
+                    if pattern.search(cmd[idx]):
+                        cmd[idx] = pattern.sub(value, cmd[idx])
+                        break
+                    idx += 1
+        
+        if string:
+            if cmd is None:
+                return ''
+            else:
+                return ' '.join(cmd)
+        
+        return cmd
+    
+    def GetName(self):
+        """!Get name"""
+        cmd = self.task.get_cmd(ignoreErrors = True)
+        if cmd and len(cmd) > 0:
+            return cmd[0]
+        
+        return _('unknown')
+
+    def GetParams(self, dcopy = False):
+        """!Get dictionary of parameters"""
+        if dcopy:
+            return copy.deepcopy(self.task.get_options())
+        
+        return self.task.get_options()
+
+    def GetTask(self):
+        """!Get grassTask instance"""
+        return self.task
+    
+    def SetParams(self, params):
+        """!Set dictionary of parameters"""
+        self.task.params = params['params']
+        self.task.flags  = params['flags']
+        
+    def MergeParams(self, params):
+        """!Merge dictionary of parameters"""
+        if 'flags' in params:
+            for f in params['flags']:
+                self.task.set_flag(f['name'],
+                                   f.get('value', False))
+        if 'params' in params:
+            for p in params['params']:
+                self.task.set_param(p['name'],
+                                    p.get('value', ''))
+        
+    def SetValid(self, options):
+        """!Set validity for action
+        
+        @param options dictionary with flags and params (gtask)
+        """
+        self.isValid = True
+        self.isParameterized = False
+        
+        for f in options['flags']:
+            if f.get('parameterized', False):
+                self.IsParameterized = True
+                break
+        
+        for p in options['params']:
+            if self.isValid and p.get('required', False) and \
+                    p.get('value', '') == '' and \
+                    p.get('default', '') == '':
+                self.isValid = False
+            if not self.isParameterized and p.get('parameterized', False):
+                self.isParameterized = True
+        
+        if self.parent.GetCanvas():
+            self._setBrush()
+            self._setPen()
+        
+    def IsValid(self):
+        """!Check validity (all required parameters set)"""
+        return self.isValid
+    
+    def IsParameterized(self):
+        """!Check if action is parameterized"""
+        return self.isParameterized
+    
+    def FindData(self, name):
+        """!Find data item by name"""
+        for rel in self.GetRelations():
+            data = rel.GetData()
+            if name == rel.GetName() and name in data.GetName():
+                return data
+        
+        return None
+
+    def Update(self, running = False):
+        """!Update action"""
+        if running:
+            self._setBrush(running = True)
+        else:
+            self._setBrush()
+        self._setPen()
+
+    def OnDraw(self, dc):
+        """!Draw action in canvas"""
+        self._setBrush()
+        self._setPen()
+        ogl.RectangleShape.OnDraw(self, dc)
+
+class ModelData(ModelObject, ogl.EllipseShape):
+    def __init__(self, parent, x, y, value = '', prompt = '', width = None, height = None):
+        """Data item class
+        
+        @param parent window parent
+        @param x, y   position of the shape
+        @param fname, tname list of parameter names from / to
+        @param value  value
+        @param prompt type of GIS element
+        @param width,height dimension of the shape
+        """
+        ModelObject.__init__(self)
+        
+        self.parent  = parent
+        self.value   = value
+        self.prompt  = prompt
+        self.intermediate = False
+        self.propWin = None
+        if not width:
+            width = UserSettings.Get(group='modeler', key='data', subkey=('size', 'width'))
+        if not height:
+            height = UserSettings.Get(group='modeler', key='data', subkey=('size', 'height'))
+        
+        if self.parent.GetCanvas():
+            ogl.EllipseShape.__init__(self, width, height)
+            
+            self.SetCanvas(self.parent)
+            self.SetX(x)
+            self.SetY(y)
+            self.SetPen(wx.BLACK_PEN)
+            self._setBrush()
+            
+            self._setText()
+            
+    def IsIntermediate(self):
+        """!Checks if data item is intermediate"""
+        return self.intermediate
+    
+    def SetIntermediate(self, im):
+        """!Set intermediate flag"""
+        self.intermediate = im
+  
+    def OnDraw(self, dc):
+        pen = self.GetPen()
+        pen.SetWidth(1)
+        if self.intermediate:
+            pen.SetStyle(wx.SHORT_DASH)
+        else:
+            pen.SetStyle(wx.SOLID)
+        self.SetPen(pen)
+        
+        ogl.EllipseShape.OnDraw(self, dc)
+        
+    def GetLog(self, string = True):
+        """!Get logging info"""
+        name = list()
+        for rel in self.GetRelations():
+            name.append(rel.GetName())
+        if name:
+            return '/'.join(name) + '=' + self.value + ' (' + self.prompt + ')'
+        else:
+            return self.value + ' (' + self.prompt + ')'
+
+    def GetName(self):
+        """!Get list of names"""
+        name = list()
+        for rel in self.GetRelations():
+            name.append(rel.GetName())
+        
+        return name
+    
+    def GetPrompt(self):
+        """!Get prompt"""
+        return self.prompt
+
+    def SetPrompt(self, prompt):
+        """!Set prompt
+        
+        @param prompt
+        """
+        self.prompt = prompt
+        
+    def GetValue(self):
+        """!Get value"""
+        return self.value
+
+    def SetValue(self, value):
+        """!Set value
+
+        @param value
+        """
+        self.value = value
+        self._setText()
+        for direction in ('from', 'to'):
+            for rel in self.GetRelations(direction):
+                if direction == 'from':
+                    action = rel.GetTo()
+                else:
+                    action = rel.GetFrom()
+                
+                task = GUI(show = None).ParseCommand(cmd = action.GetLog(string = False))
+                task.set_param(rel.GetName(), self.value)
+                action.SetParams(params = task.get_options())
+        
+    def GetPropDialog(self):
+        """!Get properties dialog"""
+        return self.propWin
+
+    def SetPropDialog(self, win):
+        """!Get properties dialog"""
+        self.propWin = win
+
+    def _setBrush(self):
+        """!Set brush"""
+        if self.prompt == 'raster':
+            color = UserSettings.Get(group = 'modeler', key = 'data',
+                                     subkey = ('color', 'raster'))
+        elif self.prompt == 'raster3d':
+            color = UserSettings.Get(group = 'modeler', key = 'data',
+                                     subkey = ('color', 'raster3d'))
+        elif self.prompt == 'vector':
+            color = UserSettings.Get(group = 'modeler', key = 'data',
+                                     subkey = ('color', 'vector'))
+        else:
+            color = UserSettings.Get(group = 'modeler', key = 'action',
+                                     subkey = ('color', 'invalid'))
+        wxColor = wx.Color(color[0], color[1], color[2])
+        self.SetBrush(wx.Brush(wxColor))
+        
+    def _setPen(self):
+        """!Set pen"""
+        isParameterized = False
+        for rel in self.GetRelations('from'):
+            if rel.GetTo().IsParameterized():
+                isParameterized = True
+                break
+        if not isParameterized:
+            for rel in self.GetRelations('to'):
+                if rel.GetFrom().IsParameterized():
+                    isParameterized = True
+                    break
+
+        if isParameterized:
+            width = int(UserSettings.Get(group = 'modeler', key = 'action',
+                                         subkey = ('width', 'parameterized')))
+        else:
+            width = int(UserSettings.Get(group = 'modeler', key = 'action',
+                                         subkey = ('width', 'default')))
+        pen = self.GetPen()
+        pen.SetWidth(width)
+        self.SetPen(pen)
+        
+    def _setText(self):
+        """!Update text"""
+        self.ClearText()
+        name = []
+        for rel in self.GetRelations():
+            name.append(rel.GetName())
+        self.AddText('/'.join(name))
+        if self.value:
+            self.AddText(self.value)
+        else:
+            self.AddText(_('<not defined>'))
+        
+    def Update(self):
+        """!Update action"""
+        self._setBrush()
+        self._setPen()
+        self._setText()
+
+class ModelRelation(ogl.LineShape):
+    """!Data - action relation"""
+    def __init__(self, parent, fromShape, toShape, param = ''):
+        self.fromShape = fromShape
+        self.toShape   = toShape
+        self.param     = param
+        self.parent    = parent
+        
+        self._points    = None
+        
+        if self.parent.GetCanvas():        
+            ogl.LineShape.__init__(self)
+    
+    def __del__(self):
+        if self in self.fromShape.rels:
+            self.fromShape.rels.remove(self)
+        if self in self.toShape.rels:
+            self.toShape.rels.remove(self)
+        
+    def GetFrom(self):
+        """!Get id of 'from' shape"""
+        return self.fromShape
+    
+    def GetTo(self):
+        """!Get id of 'to' shape"""
+        return self.toShape
+    
+    def GetData(self):
+        """!Get related ModelData instance
+
+        @return ModelData instance
+        @return None if not found
+        """
+        if isinstance(self.fromShape, ModelData):
+            return self.fromShape
+        elif isinstance(self.toShape, ModelData):
+            return self.toShape
+        
+        return None
+    
+    def GetName(self):
+        """!Get parameter name"""
+        return self.param
+    
+    def ResetShapes(self):
+        """!Reset related objects"""
+        self.fromShape.ResetControlPoints()
+        self.toShape.ResetControlPoints()
+        self.ResetControlPoints()
+        
+    def SetControlPoints(self, points):
+        """!Set control points"""
+        self._points = points
+        
+    def GetControlPoints(self):
+        """!Get list of control points"""
+        return self._points
+    
+    def _setPen(self):
+        """!Set pen"""
+        pen = self.GetPen()
+        pen.SetWidth(1)
+        pen.SetStyle(wx.SOLID)
+        self.SetPen(pen)
+        
+    def OnDraw(self, dc):
+        """!Draw relation"""
+        self._setPen()
+        ogl.LineShape.OnDraw(self, dc)
+    
+    def SetName(self, param):
+        self.param = param
+
+class ModelItem(ModelObject):
+    def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '', items = []):
+        """!Abstract class for loops and conditions"""
+        ModelObject.__init__(self, id)
+        self.parent  = parent
+        self.text    = text
+        self.items   = items  # list of items in the loop
+        
+    def GetText(self):
+        """!Get loop text"""
+        return self.text
+
+    def GetItems(self):
+        """!Get items (id)"""
+        return self.items
+
+    def SetId(self, id):
+        """!Set loop id"""
+        self.id = id
+
+    def SetText(self, cond):
+        """!Set loop text (condition)"""
+        self.text = cond
+        self.ClearText()
+        self.AddText('(' + str(self.id) + ') ' + self.text)
+
+    def GetLog(self):
+        """!Get log info"""
+        if self.text:
+            return _("Condition: ") + self.text
+        else:
+            return _("Condition: not defined")
+
+    def AddRelation(self, rel):
+        """!Record relation"""
+        self.rels.append(rel)
+        
+    def Clear(self):
+        """!Clear object, remove rels"""
+        self.rels = list()
+   
+class ModelLoop(ModelItem, ogl.RectangleShape):
+    def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '', items = []):
+        """!Defines a loop"""
+        ModelItem.__init__(self, parent, x, y, id, width, height, text, items)
+        
+        if not width:
+            width = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'width'))
+        if not height:
+            height = UserSettings.Get(group='modeler', key='loop', subkey=('size', 'height'))
+        
+        if self.parent.GetCanvas():
+            ogl.RectangleShape.__init__(self, width, height)
+            
+            self.SetCanvas(self.parent)
+            self.SetX(x)
+            self.SetY(y)
+            self.SetPen(wx.BLACK_PEN)
+            self.SetCornerRadius(100)
+            if text:
+                self.AddText('(' + str(self.id) + ') ' + text)
+            else:
+                self.AddText('(' + str(self.id) + ')')
+        
+        self._setBrush()
+        
+    def _setBrush(self):
+        """!Set brush"""
+        if not self.isEnabled:
+            color = UserSettings.Get(group='modeler', key='disabled',
+                                     subkey='color')
+        else:
+            color = UserSettings.Get(group='modeler', key='loop',
+                                     subkey=('color', 'valid'))
+        
+        wxColor = wx.Color(color[0], color[1], color[2])
+        self.SetBrush(wx.Brush(wxColor))
+
+    def Enable(self, enabled = True):
+        """!Enable/disable action"""
+        for item in self.items:
+            if not isinstance(item, ModelAction):
+                continue
+            item.Enable(enabled)
+        
+        ModelObject.Enable(self, enabled)
+        
+    def Update(self):
+        self._setBrush()
+        
+    def GetName(self):
+        """!Get name"""
+        return _("loop")
+    
+    def SetItems(self, items):
+        """!Set items (id)"""
+        self.items = items
+
+class ModelCondition(ModelItem, ogl.PolygonShape):
+    def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '',
+                 items = { 'if' : [], 'else' : [] }):
+        """!Defines a if-else condition"""
+        ModelItem.__init__(self, parent, x, y, id, width, height, text, items)
+        
+        if not width:
+            self.width = UserSettings.Get(group='modeler', key='if-else', subkey=('size', 'width'))
+        else:
+            self.width = width
+        if not height:
+            self.height = UserSettings.Get(group='modeler', key='if-else', subkey=('size', 'height'))
+        else:
+            self.height = height
+        
+        if self.parent.GetCanvas():
+            ogl.PolygonShape.__init__(self)
+            
+            points = [(0, - self.height / 2),
+                      (self.width / 2, 0),
+                      (0, self.height / 2),
+                      (- self.width / 2, 0)]
+            self.Create(points)
+            
+            self.SetCanvas(self.parent)
+            self.SetX(x)
+            self.SetY(y)
+            self.SetPen(wx.BLACK_PEN)
+            if text:
+                self.AddText('(' + str(self.id) + ') ' + text)
+            else:
+                self.AddText('(' + str(self.id) + ')')
+
+    def GetName(self):
+        """!Get name"""
+        return _("if-else")
+
+    def GetWidth(self):
+        """!Get object width"""
+        return self.width
+
+    def GetHeight(self):
+        """!Get object height"""
+        return self.height
+
+    def SetItems(self, items, branch = 'if'):
+        """!Set items (id)
+
+        @param items list of items
+        @param branch 'if' / 'else'
+        """
+        if branch in ['if', 'else']:
+            self.items[branch] = items

Modified: grass/trunk/gui/wxpython/gui_core/dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/gui_core/dialogs.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/gui_core/dialogs.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -1,5 +1,5 @@
 """!
- at package gui_core.gdialogs
+ at package gui_core.dialogs
 
 @brief Various dialogs used in wxGUI.
 

Modified: grass/trunk/gui/wxpython/psmap/frame.py
===================================================================
--- grass/trunk/gui/wxpython/psmap/frame.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/psmap/frame.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -42,6 +42,8 @@
 from icon             import Icons, MetaIcon, iconSet
 from core.gcmd        import RunCommand, GError, GMessage
 from gui_core.forms   import GUI
+from psmap.menudata   import PsMapData
+
 from psmap.dialogs    import *
 
 class PsMapFrame(wx.Frame):

Modified: grass/trunk/gui/wxpython/psmap/menudata.py
===================================================================
--- grass/trunk/gui/wxpython/psmap/menudata.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/psmap/menudata.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -1,39 +1,30 @@
 """!
- at package core.menudata
+ at package ps.menudata
 
- at brief Complex list for menu entries for wxGUI
+ at brief wxPsMap - menu entries
 
 Classes:
- - MenuData
+ - PsMapData
 
-Usage:
- at code
-python menudata.py [action] [manager|modeler]
- at endcode
-
-where <i>action</i>:
- - strings (default)
- - tree
- - commands
- - dump
-
-(C) 2007-2011 by the GRASS Development Team
+(C) 2011 by the GRASS Development Team
 This program is free software under the GNU General Public License
 (>=v2). Read the file COPYING that comes with GRASS for details.
 
- at author Michael Barton (Arizona State University)
- at author Yann Chemin <yann.chemin gmail.com>
- at author Martin Landa <landa.martin gmail.com>
- at author Glynn Clements
 @author Anna Kratochvilova <kratochanna gmail.com>
 """
 
 import os
-import sys
-import pprint
-try:
-    import xml.etree.ElementTree as etree
-except ImportError:
-    import elementtree.ElementTree as etree # Python <= 2.4
 
-import wx
+from core                 import globalvar
+from core.menudata        import MenuData
+
+class PsMapData(MenuData):
+    def __init__(self, path = None):
+        """!Menu for Cartographic Composer (psmap.py)
+        
+        @path path to XML to be read (None for menudata_psmap.xml)
+        """
+        if not path:
+            path = os.path.join(globalvar.ETCWXDIR, 'xml', 'menudata_psmap.xml')
+        
+        MenuData.__init__(self, path)

Modified: grass/trunk/gui/wxpython/psmap/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/psmap/toolbars.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/psmap/toolbars.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -30,7 +30,7 @@
         
         @param parent parent window
         """
-        AbstractToolbar.__init__(self, parent)
+        BaseToolbar.__init__(self, parent)
         
         self.InitToolbar(self._toolbarData())
         
@@ -41,7 +41,7 @@
                                'bind' : self.parent.OnPointer }
         self.OnTool(None)
         
-        from psmap import havePILImage
+        from psmap.frame import havePILImage
         if not havePILImage:
             self.EnableTool(self.preview, False)
         

Modified: grass/trunk/gui/wxpython/wxgui.py
===================================================================
--- grass/trunk/gui/wxpython/wxgui.py	2011-11-25 20:19:06 UTC (rev 49360)
+++ grass/trunk/gui/wxpython/wxgui.py	2011-11-25 21:09:24 UTC (rev 49361)
@@ -351,7 +351,7 @@
 
     def OnGModeler(self, event):
         """!Launch Graphical Modeler"""
-        win = gmodeler.ModelFrame(parent = self)
+        win = ModelFrame(parent = self)
         win.CentreOnScreen()
         
         win.Show()



More information about the grass-commit mailing list