[GRASS-SVN] r49630 - in grass/branches/develbranch_6/gui/wxpython: . lmgr

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Dec 8 15:41:46 EST 2011


Author: martinl
Date: 2011-12-08 12:41:45 -0800 (Thu, 08 Dec 2011)
New Revision: 49630

Added:
   grass/branches/develbranch_6/gui/wxpython/lmgr/frame.py
Modified:
   grass/branches/develbranch_6/gui/wxpython/wxgui.py
Log:
wxGUI: move GMFrame to lmgr/frame.py


Copied: grass/branches/develbranch_6/gui/wxpython/lmgr/frame.py (from rev 49629, grass/branches/develbranch_6/gui/wxpython/wxgui.py)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/lmgr/frame.py	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/lmgr/frame.py	2011-12-08 20:41:45 UTC (rev 49630)
@@ -0,0 +1,1668 @@
+"""!
+ at package lmgr::frame
+
+ at brief Layer Manager - main menu, layer management toolbar, notebook
+control for display management and access to command console.
+
+Classes:
+ - frame::GMFrame
+
+(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 Michael Barton (Arizona State University)
+ at author Jachym Cepicky (Mendel University of Agriculture)
+ at author Martin Landa <landa.martin gmail.com>
+ at author Vaclav Petras <wenzeslaus gmail.com> (menu customization)
+"""
+
+import sys
+import os
+import tempfile
+try:
+    import xml.etree.ElementTree as etree
+except ImportError:
+    import elementtree.ElementTree as etree # Python <= 2.4
+
+from core import globalvar
+import wx
+import wx.aui
+try:
+    import wx.lib.agw.flatnotebook   as FN
+except ImportError:
+    import wx.lib.flatnotebook   as FN
+
+sys.path.append(os.path.join(globalvar.ETCDIR, "python"))
+from grass.script          import core as grass
+
+from core.gcmd             import RunCommand, GError, GMessage
+from core.settings         import UserSettings
+from icons.icon            import Icons
+from gui_core.preferences  import MapsetAccess, PreferencesDialog, EVT_SETTINGS_CHANGED
+from lmgr.layertree        import LayerTree
+from lmgr.menudata         import ManagerData
+from gui_core.widgets      import GNotebook
+from modules.mcalc_builder import MapCalcFrame
+from dbmgr.manager         import AttributeManager
+from core.workspace        import ProcessWorkspaceFile, ProcessGrcFile, WriteWorkspaceFile
+from gui_core.goutput      import GMConsole
+from gui_core.dialogs      import DxfImportDialog, GdalImportDialog, MapLayersDialog
+from gui_core.dialogs      import LocationDialog, MapsetDialog, CreateNewVector, GroupDialog
+from modules.ogc_services  import WMSDialog
+from modules.colorrules    import RasterColorTable, VectorColorTable
+from gui_core.menu         import Menu
+from gmodeler.model        import Model
+from gmodeler.frame        import ModelFrame
+from modules.vclean        import VectorCleaningFrame
+from nviz.tools            import NvizToolWindow
+from psmap.frame           import PsMapFrame
+from core.debug            import Debug
+from gui_core.ghelp        import MenuTreeWindow, AboutWindow
+from modules.extensions    import InstallExtensionWindow
+from lmgr.toolbars         import LMWorkspaceToolbar, LMDataToolbar, LMToolsToolbar
+from lmgr.toolbars         import LMMiscToolbar, LMVectorToolbar, LMNvizToolbar
+from lmgr.pyshell          import PyShellWindow
+from gui_core.forms        import GUI
+from gcp.manager           import GCPWizard
+
+class GMFrame(wx.Frame):
+    """!Layer Manager frame with notebook widget for controlling GRASS
+    GIS. Includes command console page for typing GRASS (and other)
+    commands, tree widget page for managing map layers.
+    """
+    def __init__(self, parent, id = wx.ID_ANY, title = _("GRASS GIS Layer Manager"),
+                 workspace = None,
+                 size = globalvar.GM_WINDOW_SIZE, style = wx.DEFAULT_FRAME_STYLE, **kwargs):
+        self.parent    = parent
+        self.baseTitle = title
+        self.iconsize  = (16, 16)
+        
+        wx.Frame.__init__(self, parent = parent, id = id, size = size,
+                          style = style, **kwargs)
+                          
+        self.SetTitle(self.baseTitle)
+        self.SetName("LayerManager")
+
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
+
+        self._auimgr = wx.aui.AuiManager(self)
+
+        # initialize variables
+        self.disp_idx      = 0            # index value for map displays and layer trees
+        self.curr_page     = None         # currently selected page for layer tree notebook
+        self.curr_pagenum  = None         # currently selected page number for layer tree notebook
+        self.workspaceFile = workspace    # workspace file
+        self.workspaceChanged = False     # track changes in workspace
+        self.georectifying = None         # reference to GCP class or None
+        self.gcpmanagement = None         # reference to GCP class or None
+        
+        # list of open dialogs
+        self.dialogs        = dict()
+        self.dialogs['preferences'] = None
+        self.dialogs['atm'] = list()
+        
+        # creating widgets
+        self._createMenuBar()
+        self.statusbar = self.CreateStatusBar(number = 1)
+        self.notebook  = self._createNoteBook()
+        self.toolbars  = { 'workspace' : LMWorkspaceToolbar(parent = self),
+                           'data'      : LMDataToolbar(parent = self),
+                           'tools'     : LMToolsToolbar(parent = self),
+                           'misc'      : LMMiscToolbar(parent = self),
+                           'vector'    : LMVectorToolbar(parent = self),
+                           'nviz'      : LMNvizToolbar(parent = self)}
+        
+        self._toolbarsData = { 'workspace' : ("toolbarWorkspace",     # name
+                                              _("Workspace Toolbar"), # caption
+                                              1),                     # row
+                               'data'      : ("toolbarData",
+                                              _("Data Toolbar"),
+                                              1),
+                               'misc'      : ("toolbarMisc",
+                                              _("Misc Toolbar"),
+                                              2),
+                               'tools'     : ("toolbarTools",
+                                              _("Tools Toolbar"),
+                                              2),
+                               'vector'    : ("toolbarVector",
+                                              _("Vector Toolbar"),
+                                              2),
+                               'nviz'      : ("toolbarNviz",
+                                              _("3D view Toolbar"),
+                                              2),                                            
+                               }
+        if sys.platform == 'win32':
+            self._toolbarsList = ('workspace', 'data',
+                                  'vector', 'tools', 'misc', 'nviz')
+        else:
+            self._toolbarsList = ('data', 'workspace',
+                                  'nviz', 'misc', 'tools', 'vector')
+        for toolbar in self._toolbarsList:
+            name, caption, row = self._toolbarsData[toolbar]
+            self._auimgr.AddPane(self.toolbars[toolbar],
+                                 wx.aui.AuiPaneInfo().
+                                 Name(name).Caption(caption).
+                                 ToolbarPane().Top().Row(row).
+                                 LeftDockable(False).RightDockable(False).
+                                 BottomDockable(False).TopDockable(True).
+                                 CloseButton(False).Layer(2).
+                                 BestSize((self.toolbars[toolbar].GetBestSize())))
+        
+        self._auimgr.GetPane('toolbarNviz').Hide()
+        # bindings
+        self.Bind(wx.EVT_CLOSE,    self.OnCloseWindow)
+        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+
+        # minimal frame size
+        self.SetMinSize((500, 400))
+
+        # AUI stuff
+        self._auimgr.AddPane(self.notebook, wx.aui.AuiPaneInfo().
+                             Left().CentrePane().BestSize((-1,-1)).Dockable(False).
+                             CloseButton(False).DestroyOnClose(True).Row(1).Layer(0))
+
+        self._auimgr.Update()
+
+        wx.CallAfter(self.notebook.SetSelectionByName, 'layers')
+        
+        # use default window layout ?
+        if UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'enabled'):
+            dim = UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'dim')
+            try:
+               x, y = map(int, dim.split(',')[0:2])
+               w, h = map(int, dim.split(',')[2:4])
+               self.SetPosition((x, y))
+               self.SetSize((w, h))
+            except:
+                pass
+        else:
+            self.Centre()
+        
+        self.Layout()
+        self.Show()
+        
+        # load workspace file if requested
+        if self.workspaceFile:
+            # load given workspace file
+            if self.LoadWorkspaceFile(self.workspaceFile):
+                self.SetTitle(self.baseTitle + " - " +  os.path.basename(self.workspaceFile))
+            else:
+                self.workspaceFile = None
+        else:
+            # start default initial display
+            self.NewDisplay(show = False)
+
+        # show map display widnow
+        # -> OnSize() -> UpdateMap()
+        if self.curr_page and not self.curr_page.maptree.mapdisplay.IsShown():
+            self.curr_page.maptree.mapdisplay.Show()
+        
+        # redirect stderr to log area    
+        self.goutput.Redirect()
+        
+        # fix goutput's pane size (required for Mac OSX)`
+        self.goutput.SetSashPosition(int(self.GetSize()[1] * .8))
+        
+        self.workspaceChanged = False
+        
+        # start with layer manager on top
+        if self.curr_page:
+            self.curr_page.maptree.mapdisplay.Raise()
+        wx.CallAfter(self.Raise)
+        
+    def _createMenuBar(self):
+        """!Creates menu bar"""
+        self.menubar = Menu(parent = self, data = ManagerData())
+        self.SetMenuBar(self.menubar)
+        self.menucmd = self.menubar.GetCmd()
+        
+    def _setCopyingOfSelectedText(self):
+        copy = UserSettings.Get(group = 'manager', key = 'copySelectedTextToClipboard', subkey = 'enabled')
+        self.goutput.SetCopyingOfSelectedText(copy)
+    
+    def IsPaneShown(self, name):
+        """!Check if pane (toolbar, ...) of given name is currently shown"""
+        if self._auimgr.GetPane(name).IsOk():
+            return self._auimgr.GetPane(name).IsShown()
+        return False
+    
+    def _createNoteBook(self):
+        """!Creates notebook widgets"""
+        self.notebook = GNotebook(parent = self, style = globalvar.FNPageDStyle)
+        # create displays notebook widget and add it to main notebook page
+        cbStyle = globalvar.FNPageStyle
+        if globalvar.hasAgw:
+            self.gm_cb = FN.FlatNotebook(self, id = wx.ID_ANY, agwStyle = cbStyle)
+        else:
+            self.gm_cb = FN.FlatNotebook(self, id = wx.ID_ANY, style = cbStyle)
+        self.gm_cb.SetTabAreaColour(globalvar.FNPageColor)
+        self.notebook.AddPage(page = self.gm_cb, text = _("Map layers"), name = 'layers')
+        
+        # create 'command output' text area
+        self.goutput = GMConsole(self)
+        self.notebook.AddPage(page = self.goutput, text = _("Command console"), name = 'output')
+        self._setCopyingOfSelectedText()
+        
+        # create 'search module' notebook page
+        if not UserSettings.Get(group = 'manager', key = 'hideTabs', subkey = 'search'):
+            self.search = MenuTreeWindow(parent = self)
+            self.notebook.AddPage(page = self.search, text = _("Search module"), name = 'search')
+        else:
+            self.search = None
+        
+        # create 'python shell' notebook page
+        if not UserSettings.Get(group = 'manager', key = 'hideTabs', subkey = 'pyshell'):
+            self.pyshell = PyShellWindow(parent = self)
+            self.notebook.AddPage(page = self.pyshell, text = _("Python shell"), name = 'pyshell')
+        else:
+            self.pyshell = None
+        
+        # bindings
+        self.gm_cb.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED,    self.OnCBPageChanged)
+        self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
+        self.gm_cb.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING,    self.OnCBPageClosed)
+        
+        return self.notebook
+            
+    def AddNvizTools(self):
+        """!Add nviz notebook page"""
+        Debug.msg(5, "GMFrame.AddNvizTools()")
+        # show toolbar
+        self._auimgr.GetPane('toolbarNviz').Show()
+        # reorder other toolbars
+        for pos, toolbar in enumerate(('toolbarVector', 'toolbarTools', 'toolbarMisc','toolbarNviz')):
+            self._auimgr.GetPane(toolbar).Row(2).Position(pos)
+        self._auimgr.Update()
+        
+        # create nviz tools tab
+        self.nviz = NvizToolWindow(parent = self,
+                                   display = self.curr_page.maptree.GetMapDisplay())
+        idx = self.notebook.GetPageIndexByName('layers')
+        self.notebook.InsertPage(indx = idx + 1, page = self.nviz, text = _("3D view"), name = 'nviz')
+        self.notebook.SetSelectionByName('nviz')
+        
+        
+    def RemoveNvizTools(self):
+        """!Remove nviz notebook page"""
+        # if more mapwindow3D were possible, check here if nb page should be removed
+        self.notebook.SetSelectionByName('layers')
+        self.notebook.RemovePage(self.notebook.GetPageIndexByName('nviz'))
+        del self.nviz
+        # hide toolbar
+        self._auimgr.GetPane('toolbarNviz').Hide()
+        for pos, toolbar in enumerate(('toolbarVector', 'toolbarTools', 'toolbarMisc')):
+            self._auimgr.GetPane(toolbar).Row(2).Position(pos)
+        self._auimgr.Update()
+    
+    def WorkspaceChanged(self):
+        """!Update window title"""
+        if not self.workspaceChanged:
+            self.workspaceChanged = True
+        
+        if self.workspaceFile:
+            self.SetTitle(self.baseTitle + " - " +  os.path.basename(self.workspaceFile) + '*')
+        
+    def OnLocationWizard(self, event):
+        """!Launch location wizard"""
+        gisdbase = grass.gisenv()['GISDBASE']
+        gWizard = location_wizard.LocationWizard(parent = self,
+                                                 grassdatabase = gisdbase)
+        
+        if gWizard.location !=  None:
+            dlg = wx.MessageDialog(parent = self,
+                                   message = _('Location <%s> created.\n\n'
+                                               'Do you want to switch to the '
+                                               'new location?') % gWizard.location,
+                                   caption=_("Switch to new location?"),
+                                   style = wx.YES_NO | wx.NO_DEFAULT |
+                                   wx.ICON_QUESTION | wx.CENTRE)
+            
+            ret = dlg.ShowModal()
+            if ret == wx.ID_YES:
+                RunCommand("g.gisenv",
+                           set = "LOCATION_NAME=%s" % gWizard.location)
+                RunCommand("g.gisenv",
+                           set = "MAPSET=PERMANENT")
+            
+            dlg.Destroy()
+            
+    def OnSettingsChanged(self, event):
+        """!Here can be functions which have to be called after EVT_SETTINGS_CHANGED. 
+        Now only set copying of selected text to clipboard (in goutput).
+        """
+        ### self._createMenuBar() # bug when menu is re-created on the fly
+        self._setCopyingOfSelectedText()
+        
+    def OnGCPManager(self, event):
+        """!Launch georectifier module
+        """
+        GCPWizard(self)
+
+    def OnGModeler(self, event):
+        """!Launch Graphical Modeler"""
+        win = ModelFrame(parent = self)
+        win.CentreOnScreen()
+        
+        win.Show()
+        
+    def OnPsMap(self, event):
+        """!Launch Cartographic Composer
+        """
+        win = PsMapFrame(parent = self)
+        win.CentreOnScreen()
+        
+        win.Show()
+        
+    def OnDone(self, cmd, returncode):
+        """Command execution finised"""
+        if hasattr(self, "model"):
+            self.model.DeleteIntermediateData(log = self.goutput)
+            del self.model
+        self.SetStatusText('')
+        
+    def OnRunModel(self, event):
+        """!Run model"""
+        filename = ''
+        dlg = wx.FileDialog(parent = self, message =_("Choose model to run"),
+                            defaultDir = os.getcwd(),
+                            wildcard = _("GRASS Model File (*.gxm)|*.gxm"))
+        if dlg.ShowModal() == wx.ID_OK:
+            filename = dlg.GetPath()
+        
+        if not filename:
+            dlg.Destroy()
+            return
+        
+        self.model = Model()
+        self.model.LoadModel(filename)
+        self.model.Run(log = self.goutput, onDone = self.OnDone, parent = self)
+        
+        dlg.Destroy()
+        
+    def OnMapsets(self, event):
+        """!Launch mapset access dialog
+        """
+        dlg = MapsetAccess(parent = self, id = wx.ID_ANY)
+        dlg.CenterOnScreen()
+        
+        if dlg.ShowModal() == wx.ID_OK:
+            ms = dlg.GetMapsets()
+            RunCommand('g.mapsets',
+                       parent = self,
+                       mapset = '%s' % ','.join(ms))
+            
+    def OnCBPageChanged(self, event):
+        """!Page in notebook (display) changed"""
+        old_pgnum = event.GetOldSelection()
+        new_pgnum = event.GetSelection()
+        
+        self.curr_page   = self.gm_cb.GetCurrentPage()
+        self.curr_pagenum = self.gm_cb.GetSelection()
+        try:
+            self.curr_page.maptree.mapdisplay.SetFocus()
+            self.curr_page.maptree.mapdisplay.Raise()
+        except:
+            pass
+        
+        event.Skip()
+
+    def OnPageChanged(self, event):
+        """!Page in notebook changed"""
+        page = event.GetSelection()
+        if page == self.notebook.GetPageIndexByName('output'):
+            # remove '(...)'
+            self.notebook.SetPageText(page, _("Command console"))
+            wx.CallAfter(self.goutput.ResetFocus)
+        self.SetStatusText('', 0)
+        
+        event.Skip()
+
+    def OnCBPageClosed(self, event):
+        """!Page of notebook closed
+        Also close associated map display
+        """
+        if UserSettings.Get(group = 'manager', key = 'askOnQuit', subkey = 'enabled'):
+            maptree = self.curr_page.maptree
+            
+            if self.workspaceFile:
+                message = _("Do you want to save changes in the workspace?")
+            else:
+                message = _("Do you want to store current settings "
+                            "to workspace file?")
+            
+            # ask user to save current settings
+            if maptree.GetCount() > 0:
+                dlg = wx.MessageDialog(self,
+                                       message = message,
+                                       caption = _("Close Map Display %d") % (self.curr_pagenum + 1),
+                                       style = wx.YES_NO | wx.YES_DEFAULT |
+                                       wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
+                ret = dlg.ShowModal()
+                if ret == wx.ID_YES:
+                    if not self.workspaceFile:
+                        self.OnWorkspaceSaveAs()
+                    else:
+                        self.SaveToWorkspaceFile(self.workspaceFile)
+                elif ret == wx.ID_CANCEL:
+                    event.Veto()
+                    dlg.Destroy()
+                    return
+                dlg.Destroy()
+
+        self.gm_cb.GetPage(event.GetSelection()).maptree.Map.Clean()
+        self.gm_cb.GetPage(event.GetSelection()).maptree.Close(True)
+
+        self.curr_page = None
+
+        event.Skip()
+
+    def GetLayerTree(self):
+        """!Get current layer tree"""
+        return self.curr_page.maptree
+    
+    def GetLogWindow(self):
+        """!Get widget for command output"""
+        return self.goutput
+    
+    def GetMenuCmd(self, event):
+        """!Get GRASS command from menu item
+
+        Return command as a list"""
+        layer = None
+        
+        if event:
+            cmd = self.menucmd[event.GetId()]
+        
+        try:
+            cmdlist = cmd.split(' ')
+        except: # already list?
+            cmdlist = cmd
+        
+        # check list of dummy commands for GUI modules that do not have GRASS
+        # bin modules or scripts. 
+        if cmd in ['vcolors', 'r.mapcalc', 'r3.mapcalc']:
+            return cmdlist
+
+        try:
+            layer = self.curr_page.maptree.layer_selected
+            name = self.curr_page.maptree.GetPyData(layer)[0]['maplayer'].name
+            type = self.curr_page.maptree.GetPyData(layer)[0]['type']
+        except:
+            layer = None
+
+        if layer and len(cmdlist) == 1: # only if no paramaters given
+            if (type == 'raster' and cmdlist[0][0] == 'r' and cmdlist[0][1] != '3') or \
+                    (type == 'vector' and cmdlist[0][0] == 'v'):
+                input = GUI().GetCommandInputMapParamKey(cmdlist[0])
+                if input:
+                    cmdlist.append("%s=%s" % (input, name))
+        
+        return cmdlist
+
+    def RunMenuCmd(self, event = None, cmd = []):
+        """!Run command selected from menu"""
+        if event:
+            cmd = self.GetMenuCmd(event)
+        self.goutput.RunCmd(cmd, switchPage = False)
+
+    def OnMenuCmd(self, event = None, cmd = []):
+        """!Parse command selected from menu"""
+        if event:
+            cmd = self.GetMenuCmd(event)
+        GUI(parent = self).ParseCommand(cmd)
+        
+    def OnVDigit(self, event):
+        """!Start vector digitizer
+        """
+        if not self.curr_page:
+            self.MsgNoLayerSelected()
+            return
+        
+        tree = self.GetLayerTree()
+        layer = tree.layer_selected
+        # no map layer selected
+        if not layer:
+            self.MsgNoLayerSelected()
+            return
+        
+        # available only for vector map layers
+        try:
+            mapLayer = tree.GetPyData(layer)[0]['maplayer']
+        except:
+            mapLayer = None
+        
+        if not mapLayer or mapLayer.GetType() != 'vector':
+            GMessage(parent = self,
+                     message = _("Selected map layer is not vector."))
+            return
+        
+        if mapLayer.GetMapset() != grass.gisenv()['MAPSET']:
+            GMessage(parent = self,
+                     message = _("Editing is allowed only for vector maps from the "
+                                 "current mapset."))
+            return
+        
+        if not tree.GetPyData(layer)[0]:
+            return
+        dcmd = tree.GetPyData(layer)[0]['cmd']
+        if not dcmd:
+            return
+        
+        tree.OnStartEditing(None)
+        
+    def OnRunScript(self, event):
+        """!Run script"""
+        # open dialog and choose script file
+        dlg = wx.FileDialog(parent = self, message = _("Choose script file to run"),
+                            defaultDir = os.getcwd(),
+                            wildcard = _("Python script (*.py)|*.py|Bash script (*.sh)|*.sh"))
+        
+        filename = None
+        if dlg.ShowModal() == wx.ID_OK:
+            filename = dlg.GetPath()
+        
+        if not filename:
+            return False
+
+        if not os.path.exists(filename):
+            GError(parent = self,
+                   message = _("Script file '%s' doesn't exist. "
+                               "Operation cancelled.") % filename)
+            return
+        
+        self.goutput.WriteCmdLog(_("Launching script '%s'...") % filename)
+        self.goutput.RunCmd([filename], switchPage = True)
+        
+    def OnChangeLocation(self, event):
+        """Change current location"""
+        dlg = LocationDialog(parent = self)
+        if dlg.ShowModal() == wx.ID_OK:
+            location, mapset = dlg.GetValues()
+            if location and mapset:
+                ret = RunCommand("g.gisenv",
+                                 set = "LOCATION_NAME=%s" % location)
+                ret += RunCommand("g.gisenv",
+                                  set = "MAPSET=%s" % mapset)
+                if ret > 0:
+                    wx.MessageBox(parent = self,
+                                  message = _("Unable to switch to location <%(loc)s> mapset <%(mapset)s>.") % \
+                                      { 'loc' : location, 'mapset' : mapset },
+                                  caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
+                else:
+                    # close workspace
+                    self.OnWorkspaceClose()
+                    self.OnWorkspaceNew()
+                    wx.MessageBox(parent = self,
+                                  message = _("Current location is <%(loc)s>.\n"
+                                              "Current mapset is <%(mapset)s>.") % \
+                                      { 'loc' : location, 'mapset' : mapset },
+                                  caption = _("Info"), style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
+                    
+    def OnCreateMapset(self, event):
+        """!Create new mapset"""
+        dlg = wx.TextEntryDialog(parent = self,
+                                 message = _('Enter name for new mapset:'),
+                                 caption = _('Create new mapset'))
+        
+        if dlg.ShowModal() ==  wx.ID_OK:
+            mapset = dlg.GetValue()
+            if not mapset:
+                GError(parent = self,
+                       message = _("No mapset provided. Operation canceled."))
+                return
+            
+            ret = RunCommand('g.mapset',
+                             parent = self,
+                             flags = 'c',
+                             mapset = mapset)
+            if ret == 0:
+                GMessage(parent = self,
+                         message = _("Current mapset is <%s>.") % mapset)
+            
+    def OnChangeMapset(self, event):
+        """Change current mapset"""
+        dlg = MapsetDialog(parent = self)
+        
+        if dlg.ShowModal() == wx.ID_OK:
+            mapset = dlg.GetMapset()
+            if not mapset:
+                GError(parent = self,
+                       message = _("No mapset provided. Operation canceled."))
+                return
+            
+            ret = RunCommand('g.mapset',
+                             parent = self,
+                             mapset = mapset)
+            
+            if ret == 0:
+                GMessage(parent = self,
+                         message = _("Current mapset is <%s>.") % mapset)
+        
+    def OnNewVector(self, event):
+        """!Create new vector map layer"""
+        dlg = CreateNewVector(self, log = self.goutput,
+                              cmd = (('v.edit',
+                                      { 'tool' : 'create' },
+                                      'map')))
+        
+        if not dlg:
+            return
+        
+        name = dlg.GetName(full = True)
+        if name and dlg.IsChecked('add'):
+            # add layer to map layer tree
+            self.curr_page.maptree.AddLayer(ltype = 'vector',
+                                            lname = name,
+                                            lcmd = ['d.vect', 'map=%s' % name])
+        dlg.Destroy()
+        
+    def OnAboutGRASS(self, event):
+        """!Display 'About GRASS' dialog"""
+        win = AboutWindow(self)
+        win.CentreOnScreen()
+        win.Show(True)  
+        
+    def _popupMenu(self, data):
+        """!Create popup menu
+        """
+        point = wx.GetMousePosition()
+        menu = wx.Menu()
+        
+        for key, handler in data:
+            if key is None:
+                menu.AppendSeparator()
+                continue
+            item = wx.MenuItem(menu, wx.ID_ANY, Icons['layerManager'][key].GetLabel())
+            item.SetBitmap(Icons['layerManager'][key].GetBitmap(self.iconsize))
+            menu.AppendItem(item)
+            self.Bind(wx.EVT_MENU, handler, item)
+        
+        # create menu
+        self.PopupMenu(menu)
+        menu.Destroy()
+
+    def OnImportMenu(self, event):
+        """!Import maps menu (import, link)
+        """
+        self._popupMenu((('rastImport',    self.OnImportGdalLayers),
+                         ('vectImport',    self.OnImportOgrLayers)))
+        
+    def OnWorkspaceNew(self, event = None):
+        """!Create new workspace file
+
+        Erase current workspace settings first
+        """
+        Debug.msg(4, "GMFrame.OnWorkspaceNew():")
+        
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay()
+        
+        maptree = self.curr_page.maptree
+        
+        # ask user to save current settings
+        if self.workspaceFile and self.workspaceChanged:
+            self.OnWorkspaceSave()
+        elif self.workspaceFile is None and maptree.GetCount() > 0:
+             dlg = wx.MessageDialog(self, message = _("Current workspace is not empty. "
+                                                    "Do you want to store current settings "
+                                                    "to workspace file?"),
+                                    caption = _("Create new workspace?"),
+                                    style = wx.YES_NO | wx.YES_DEFAULT | \
+                                        wx.CANCEL | wx.ICON_QUESTION)
+             ret = dlg.ShowModal()
+             if ret == wx.ID_YES:
+                 self.OnWorkspaceSaveAs()
+             elif ret == wx.ID_CANCEL:
+                 dlg.Destroy()
+                 return
+             
+             dlg.Destroy()
+        
+        # delete all items
+        maptree.DeleteAllItems()
+        
+        # add new root element
+        maptree.root = maptree.AddRoot("Map Layers")
+        self.curr_page.maptree.SetPyData(maptree.root, (None,None))
+        
+        # no workspace file loaded
+        self.workspaceFile = None
+        self.workspaceChanged = False
+        self.SetTitle(self.baseTitle)
+        
+    def OnWorkspaceOpen(self, event = None):
+        """!Open file with workspace definition"""
+        dlg = wx.FileDialog(parent = self, message = _("Choose workspace file"),
+                            defaultDir = os.getcwd(), wildcard = _("GRASS Workspace File (*.gxw)|*.gxw"))
+
+        filename = ''
+        if dlg.ShowModal() == wx.ID_OK:
+            filename = dlg.GetPath()
+
+        if filename == '':
+            return
+
+        Debug.msg(4, "GMFrame.OnWorkspaceOpen(): filename=%s" % filename)
+        
+        # delete current layer tree content
+        self.OnWorkspaceClose()
+        
+        self.LoadWorkspaceFile(filename)
+
+        self.workspaceFile = filename
+        self.SetTitle(self.baseTitle + " - " +  os.path.basename(self.workspaceFile))
+
+    def LoadWorkspaceFile(self, filename):
+        """!Load layer tree definition stored in GRASS Workspace XML file (gxw)
+
+        @todo Validate against DTD
+        
+        @return True on success
+        @return False on error
+        """
+        # dtd
+        dtdFilename = os.path.join(globalvar.ETCWXDIR, "xml", "grass-gxw.dtd")
+        
+        # parse workspace file
+        try:
+            gxwXml = ProcessWorkspaceFile(etree.parse(filename))
+        except Exception, e:
+            GError(parent = self,
+                   message = _("Reading workspace file <%s> failed.\n"
+                                    "Invalid file, unable to parse XML document.") % filename)
+            return
+        
+        busy = wx.BusyInfo(message = _("Please wait, loading workspace..."),
+                           parent = self)
+        wx.Yield()
+
+        #
+        # load layer manager window properties
+        #
+        if UserSettings.Get(group = 'workspace', key = 'posManager', subkey = 'enabled') is False:
+            if gxwXml.layerManager['pos']:
+                self.SetPosition(gxwXml.layerManager['pos'])
+            if gxwXml.layerManager['size']:
+                self.SetSize(gxwXml.layerManager['size'])
+        
+        #
+        # start map displays first (list of layers can be empty)
+        #
+        displayId = 0
+        mapdisplay = list()
+        for display in gxwXml.displays:
+            mapdisp = self.NewDisplay(show = False)
+            mapdisplay.append(mapdisp)
+            maptree = self.gm_cb.GetPage(displayId).maptree
+            
+            # set windows properties
+            mapdisp.SetProperties(render = display['render'],
+                                  mode = display['mode'],
+                                  showCompExtent = display['showCompExtent'],
+                                  alignExtent = display['alignExtent'],
+                                  constrainRes = display['constrainRes'],
+                                  projection = display['projection']['enabled'])
+
+            if display['projection']['enabled']:
+                if display['projection']['epsg']:
+                    UserSettings.Set(group = 'display', key = 'projection', subkey = 'epsg',
+                                     value = display['projection']['epsg'])
+                    if display['projection']['proj']:
+                        UserSettings.Set(group = 'display', key = 'projection', subkey = 'proj4',
+                                         value = display['projection']['proj'])
+            
+            # set position and size of map display
+            if UserSettings.Get(group = 'workspace', key = 'posDisplay', subkey = 'enabled') is False:
+                if display['pos']:
+                    mapdisp.SetPosition(display['pos'])
+                if display['size']:
+                    mapdisp.SetSize(display['size'])
+                    
+            # set extent if defined
+            if display['extent']:
+                w, s, e, n = display['extent']
+                region = maptree.Map.region = maptree.Map.GetRegion(w = w, s = s, e = e, n = n)
+                mapdisp.GetWindow().ResetZoomHistory()
+                mapdisp.GetWindow().ZoomHistory(region['n'],
+                                                region['s'],
+                                                region['e'],
+                                                region['w'])
+                
+            mapdisp.Show()
+            
+            displayId += 1
+    
+        maptree = None 
+        selected = [] # list of selected layers
+        # 
+        # load list of map layers
+        #
+        for layer in gxwXml.layers:
+            display = layer['display']
+            maptree = self.gm_cb.GetPage(display).maptree
+            
+            newItem = maptree.AddLayer(ltype = layer['type'],
+                                       lname = layer['name'],
+                                       lchecked = layer['checked'],
+                                       lopacity = layer['opacity'],
+                                       lcmd = layer['cmd'],
+                                       lgroup = layer['group'],
+                                       lnviz = layer['nviz'],
+                                       lvdigit = layer['vdigit'])
+            
+            if layer.has_key('selected'):
+                if layer['selected']:
+                    selected.append((maptree, newItem))
+                else:
+                    maptree.SelectItem(newItem, select = False)
+            
+        for maptree, layer in selected:
+            if not maptree.IsSelected(layer):
+                maptree.SelectItem(layer, select = True)
+                maptree.layer_selected = layer
+                
+        busy.Destroy()
+        
+        if maptree:
+            # reverse list of map layers
+            maptree.Map.ReverseListOfLayers()
+            
+        for idx, mdisp in enumerate(mapdisplay):
+            mdisp.MapWindow2D.UpdateMap()
+            #nviz
+            if gxwXml.displays[idx]['viewMode'] == '3d':
+                mdisp.AddNviz()
+                self.nviz.UpdateState(view = gxwXml.nviz_state['view'],
+                                              iview = gxwXml.nviz_state['iview'],
+                                              light = gxwXml.nviz_state['light'])
+                mdisp.MapWindow3D.constants = gxwXml.nviz_state['constants']
+                for idx, constant in enumerate(mdisp.MapWindow3D.constants):
+                    mdisp.MapWindow3D.AddConstant(constant, idx + 1)
+                for page in ('view', 'light', 'fringe', 'constant', 'cplane'):
+                    self.nviz.UpdatePage(page)
+                self.nviz.UpdateSettings()
+                mapdisp.toolbars['map'].combo.SetSelection(1)
+
+
+        return True
+    
+    def OnWorkspaceLoadGrcFile(self, event):
+        """!Load map layers from GRC file (Tcl/Tk GUI) into map layer tree"""
+        dlg = wx.FileDialog(parent = self, message = _("Choose GRC file to load"),
+                            defaultDir = os.getcwd(), wildcard = _("Old GRASS Workspace File (*.grc)|*.grc"))
+
+        filename = ''
+        if dlg.ShowModal() == wx.ID_OK:
+            filename = dlg.GetPath()
+
+        if filename == '':
+            return
+
+        Debug.msg(4, "GMFrame.OnWorkspaceLoadGrcFile(): filename=%s" % filename)
+
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay()
+
+        busy = wx.BusyInfo(message = _("Please wait, loading workspace..."),
+                           parent = self)
+        wx.Yield()
+
+        maptree = None
+        for layer in ProcessGrcFile(filename).read(self):
+            maptree = self.gm_cb.GetPage(layer['display']).maptree
+            newItem = maptree.AddLayer(ltype = layer['type'],
+                                       lname = layer['name'],
+                                       lchecked = layer['checked'],
+                                       lopacity = layer['opacity'],
+                                       lcmd = layer['cmd'],
+                                       lgroup = layer['group'])
+
+            busy.Destroy()
+            
+        if maptree:
+            # reverse list of map layers
+            maptree.Map.ReverseListOfLayers()
+
+    def OnWorkspaceSaveAs(self, event = None):
+        """!Save workspace definition to selected file"""
+        dlg = wx.FileDialog(parent = self, message = _("Choose file to save current workspace"),
+                            defaultDir = os.getcwd(), wildcard = _("GRASS Workspace File (*.gxw)|*.gxw"), style = wx.FD_SAVE)
+
+        filename = ''
+        if dlg.ShowModal() == wx.ID_OK:
+            filename = dlg.GetPath()
+
+        if filename == '':
+            return False
+
+        # check for extension
+        if filename[-4:] != ".gxw":
+            filename += ".gxw"
+
+        if os.path.exists(filename):
+            dlg = wx.MessageDialog(self, message = _("Workspace file <%s> already exists. "
+                                                     "Do you want to overwrite this file?") % filename,
+                                   caption = _("Save workspace"), style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
+            if dlg.ShowModal() != wx.ID_YES:
+                dlg.Destroy()
+                return False
+
+        Debug.msg(4, "GMFrame.OnWorkspaceSaveAs(): filename=%s" % filename)
+
+        self.SaveToWorkspaceFile(filename)
+        self.workspaceFile = filename
+        self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
+
+    def OnWorkspaceSave(self, event = None):
+        """!Save file with workspace definition"""
+        if self.workspaceFile:
+            dlg = wx.MessageDialog(self, message = _("Workspace file <%s> already exists. "
+                                                   "Do you want to overwrite this file?") % \
+                                       self.workspaceFile,
+                                   caption = _("Save workspace"), style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
+            if dlg.ShowModal() == wx.ID_NO:
+                dlg.Destroy()
+            else:
+                Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % self.workspaceFile)
+                self.SaveToWorkspaceFile(self.workspaceFile)
+                self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
+                self.workspaceChanged = False
+        else:
+            self.OnWorkspaceSaveAs()
+
+    def SaveToWorkspaceFile(self, filename):
+        """!Save layer tree layout to workspace file
+        
+        Return True on success, False on error
+        """
+        tmpfile = tempfile.TemporaryFile(mode = 'w+b')
+        try:
+            WriteWorkspaceFile(lmgr = self, file = tmpfile)
+        except StandardError, e:
+            GError(parent = self,
+                   message = _("Writing current settings to workspace file "
+                               "failed."))
+            return False
+        
+        try:
+            mfile = open(filename, "w")
+            tmpfile.seek(0)
+            for line in tmpfile.readlines():
+                mfile.write(line)
+        except IOError:
+            GError(parent = self,
+                   message = _("Unable to open file <%s> for writing.") % filename)
+            return False
+        
+        mfile.close()
+        
+        return True
+    
+    def OnWorkspaceClose(self, event = None):
+        """!Close file with workspace definition
+        
+        If workspace has been modified ask user to save the changes.
+        """
+        Debug.msg(4, "GMFrame.OnWorkspaceClose(): file=%s" % self.workspaceFile)
+        
+        self.OnDisplayCloseAll()
+        self.workspaceFile = None
+        self.workspaceChanged = False
+        self.SetTitle(self.baseTitle)
+        self.disp_idx = 0
+        self.curr_page = None
+        
+    def OnDisplayClose(self, event = None):
+        """!Close current map display window
+        """
+        if self.curr_page and self.curr_page.maptree.mapdisplay:
+            self.curr_page.maptree.mapdisplay.OnCloseWindow(event)
+        
+    def OnDisplayCloseAll(self, event = None):
+        """!Close all open map display windows
+        """
+        displays = list()
+        for page in range(0, self.gm_cb.GetPageCount()):
+            displays.append(self.gm_cb.GetPage(page).maptree.mapdisplay)
+        
+        for display in displays:
+            display.OnCloseWindow(event)
+        
+    def RulesCmd(self, event):
+        """!Launches dialog for commands that need rules input and
+        processes rules
+        """
+        cmd = self.GetMenuCmd(event)
+        
+        if cmd[0] == 'r.colors':
+            ctable = RasterColorTable(self)
+        else:
+            ctable = VectorColorTable(self, attributeType = 'color')
+        ctable.CentreOnScreen()
+        ctable.Show()
+        
+    def OnXTermNoXMon(self, event):
+        """!
+        Run commands that need xterm
+        """
+        self.OnXTerm(event, need_xmon = False)
+        
+    def OnXTerm(self, event, need_xmon = True):
+        """!
+        Run commands that need interactive xmon
+
+        @param need_xmon True to start X monitor
+        """
+        # unset display mode
+        del os.environ['GRASS_RENDER_IMMEDIATE']
+        
+        if need_xmon:
+            # open next available xmon
+            xmonlist = []
+            
+            # make list of xmons that are not running
+            ret = RunCommand('d.mon',
+                             flags = 'L',
+                             read = True)
+            
+            for line in ret.split('\n'):               
+                line = line.strip()
+                if line.startswith('x') and 'not running' in line:
+                    xmonlist.append(line[0:2])
+            
+            # find available xmon
+            xmon = xmonlist[0]
+            
+            # bring up the xmon
+            cmdlist = ['d.mon', xmon]
+            p = Command(cmdlist, wait=False)
+        
+        # run the command        
+        command = self.GetMenuCmd(event)
+        command = ' '.join(command)
+        
+        gisbase = os.environ['GISBASE']
+        
+        if sys.platform == "win32":
+            runbat = os.path.join(gisbase,'etc','grass-run.bat')
+            cmdlist = ["start", runbat, runbat, command]
+        else:
+            if sys.platform == "darwin":
+                xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-mac')
+            else:
+                xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-wrapper')
+            
+            grassrun = os.path.join(gisbase,'etc','grass-run.sh')
+            cmdlist = [xtermwrapper, '-e', grassrun, command]
+        
+        p = Command(cmdlist, wait=False)
+        
+        # reset display mode
+        os.environ['GRASS_RENDER_IMMEDIATE'] = 'TRUE'
+        
+    def OnEditImageryGroups(self, event, cmd = None):
+        """!Show dialog for creating and editing groups.
+        """
+        dlg = GroupDialog(self)
+        dlg.CentreOnScreen()
+        dlg.Show()
+        
+    def OnInstallExtension(self, event):
+        """!Install extension from GRASS Addons SVN repository"""
+        win = InstallExtensionWindow(self, size = (650, 550))
+        win.CentreOnScreen()
+        win.Show()
+
+    def OnPreferences(self, event):
+        """!General GUI preferences/settings
+        """
+        if not self.dialogs['preferences']:
+            dlg = PreferencesDialog(parent = self)
+            self.dialogs['preferences'] = dlg
+            self.dialogs['preferences'].CenterOnScreen()
+            
+            dlg.Bind(EVT_SETTINGS_CHANGED, self.OnSettingsChanged)
+        
+        self.dialogs['preferences'].ShowModal()
+        
+    def OnHelp(self, event):
+        """!Show help
+        """
+        self.goutput.RunCmd(['g.manual','-i'])
+        
+    def DispHistogram(self, event):
+        """
+        Init histogram display canvas and tools
+        """
+        self.histogram = HistogramFrame(self, size = (400,300),
+                                        style = wx.DEFAULT_FRAME_STYLE)
+        
+        #show new display
+        self.histogram.Show()
+        self.histogram.Refresh()
+        self.histogram.Update()
+
+    def DispProfile(self, event):
+        """
+        Init profile canvas and tools
+        """
+        self.profile = profile.ProfileFrame(self,
+                                           id = wx.ID_ANY, pos = wx.DefaultPosition, size = (400,300),
+                                           style = wx.DEFAULT_FRAME_STYLE)
+        self.profile.Show()
+        self.profile.Refresh()
+        self.profile.Update()
+        
+    def OnMapCalculator(self, event, cmd = ''):
+        """!Init map calculator for interactive creation of mapcalc statements
+        """
+        if event:
+            try:
+                cmd = self.GetMenuCmd(event)
+            except KeyError:
+                cmd = ['r.mapcalc']
+        
+        win = MapCalcFrame(parent = self,
+                           cmd = cmd[0])
+        win.CentreOnScreen()
+        win.Show()
+        
+    def OnVectorCleaning(self, event, cmd = ''):
+        """!Init interactive vector cleaning
+        """
+        
+        if event:
+            cmd = self.GetMenuCmd(event)
+
+        win = VectorCleaningFrame(parent = self, cmd = cmd[0])
+        win.CentreOnScreen()
+        win.Show()
+        
+    def OnImportDxfFile(self, event, cmd = None):
+        """!Convert multiple DXF layers to GRASS vector map layers"""
+        dlg = DxfImportDialog(parent = self)
+        dlg.CentreOnScreen()
+        dlg.Show()
+
+    def OnImportGdalLayers(self, event, cmd = None):
+        """!Convert multiple GDAL layers to GRASS raster map layers"""
+        dlg = GdalImportDialog(parent = self)
+        dlg.CentreOnScreen()
+        dlg.Show()
+
+    def OnLinkGdalLayers(self, event, cmd = None):
+        """!Link multiple GDAL layers to GRASS raster map layers"""
+        dlg = GdalImportDialog(parent = self, link = True)
+        dlg.CentreOnScreen()
+        dlg.Show()
+        
+    def OnImportOgrLayers(self, event, cmd = None):
+        """!Convert multiple OGR layers to GRASS vector map layers"""
+        dlg = GdalImportDialog(parent = self, ogr = True)
+        dlg.CentreOnScreen()
+        dlg.Show()
+        
+    def OnLinkOgrLayers(self, event, cmd = None):
+        """!Links multiple OGR layers to GRASS vector map layers"""
+        dlg = GdalImportDialog(parent = self, ogr = True, link = True)
+        dlg.CentreOnScreen()
+        dlg.Show()
+        
+    def OnImportWMS(self, event):
+        """!Import data from OGC WMS server"""
+        dlg = WMSDialog(parent = self, service = 'wms')
+        dlg.CenterOnScreen()
+        
+        if dlg.ShowModal() == wx.ID_OK: # -> import layers
+            layers = dlg.GetLayers()
+            
+            if len(layers.keys()) > 0:
+                for layer in layers.keys():
+                    cmd = ['r.in.wms',
+                           'mapserver=%s' % dlg.GetSettings()['server'],
+                           'layers=%s' % layer,
+                           'output=%s' % layer,
+                           'format=png',
+                           '--overwrite']
+                    styles = ','.join(layers[layer])
+                    if styles:
+                        cmd.append('styles=%s' % styles)
+                    self.goutput.RunCmd(cmd, switchPage = True)
+
+                    self.curr_page.maptree.AddLayer(ltype = 'raster',
+                                                    lname = layer,
+                                                    lcmd = ['d.rast', 'map=%s' % layer],
+                                                    multiple = False)
+            else:
+                self.goutput.WriteWarning(_("Nothing to import. No WMS layer selected."))
+                
+                
+        dlg.Destroy()
+        
+    def OnShowAttributeTable(self, event, selection = None):
+        """!Show attribute table of the given vector map layer
+        """
+        if not self.curr_page:
+            self.MsgNoLayerSelected()
+            return
+        
+        tree = self.GetLayerTree()
+        layer = tree.layer_selected
+        # no map layer selected
+        if not layer:
+            self.MsgNoLayerSelected()
+            return
+        
+        # available only for vector map layers
+        try:
+            maptype = tree.GetPyData(layer)[0]['maplayer'].type
+        except:
+            maptype = None
+        
+        if not maptype or maptype != 'vector':
+            GMessage(parent = self,
+                          message = _("Selected map layer is not vector."))
+            return
+        
+        if not tree.GetPyData(layer)[0]:
+            return
+        dcmd = tree.GetPyData(layer)[0]['cmd']
+        if not dcmd:
+            return
+        
+        busy = wx.BusyInfo(message = _("Please wait, loading attribute data..."),
+                           parent = self)
+        wx.Yield()
+        
+        dbmanager = AttributeManager(parent = self, id = wx.ID_ANY,
+                                     size = wx.Size(500, 300),
+                                     item = layer, log = self.goutput,
+                                     selection = selection)
+        
+        busy.Destroy()
+        
+        # register ATM dialog
+        self.dialogs['atm'].append(dbmanager)
+        
+        # show ATM window
+        dbmanager.Show()
+        
+    def OnNewDisplayWMS(self, event = None):
+        """!Create new layer tree and map display instance"""
+        self.NewDisplayWMS()
+
+    def OnNewDisplay(self, event = None):
+        """!Create new layer tree and map display instance"""
+        self.NewDisplay()
+
+    def NewDisplay(self, show = True):
+        """!Create new layer tree, which will
+        create an associated map display frame
+
+        @param show show map display window if True
+
+        @return reference to mapdisplay intance
+        """
+        Debug.msg(1, "GMFrame.NewDisplay(): idx=%d" % self.disp_idx)
+        
+        # make a new page in the bookcontrol for the layer tree (on page 0 of the notebook)
+        self.pg_panel = wx.Panel(self.gm_cb, id = wx.ID_ANY, style = wx.EXPAND)
+        self.gm_cb.AddPage(self.pg_panel, text = "Display "+ str(self.disp_idx + 1), select = True)
+        self.curr_page = self.gm_cb.GetCurrentPage()
+        
+        # create layer tree (tree control for managing GIS layers)  and put on new notebook page
+        self.curr_page.maptree = LayerTree(self.curr_page, id = wx.ID_ANY, pos = wx.DefaultPosition,
+                                           size = wx.DefaultSize, style = wx.TR_HAS_BUTTONS |
+                                           wx.TR_LINES_AT_ROOT| wx.TR_HIDE_ROOT |
+                                           wx.TR_DEFAULT_STYLE| wx.NO_BORDER | wx.FULL_REPAINT_ON_RESIZE,
+                                           idx = self.disp_idx, lmgr = self, notebook = self.gm_cb,
+                                           auimgr = self._auimgr, showMapDisplay = show)
+        
+        # layout for controls
+        cb_boxsizer = wx.BoxSizer(wx.VERTICAL)
+        cb_boxsizer.Add(self.curr_page.maptree, proportion = 1, flag = wx.EXPAND, border = 1)
+        self.curr_page.SetSizer(cb_boxsizer)
+        cb_boxsizer.Fit(self.curr_page.maptree)
+        self.curr_page.Layout()
+        self.curr_page.maptree.Layout()
+        
+        # use default window layout
+        if UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'enabled'):
+            dim = UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'dim')
+            idx = 4 + self.disp_idx * 4
+            try:
+                x, y = map(int, dim.split(',')[idx:idx + 2])
+                w, h = map(int, dim.split(',')[idx + 2:idx + 4])
+                self.curr_page.maptree.mapdisplay.SetPosition((x, y))
+                self.curr_page.maptree.mapdisplay.SetSize((w, h))
+            except:
+                pass
+        
+        self.disp_idx += 1
+        
+        return self.curr_page.maptree.mapdisplay
+    
+    def OnAddMaps(self, event = None):
+        """!Add selected map layers into layer tree"""
+        dialog = MapLayersDialog(parent = self, title = _("Add selected map layers into layer tree"))
+        
+        if dialog.ShowModal() != wx.ID_OK:
+            dialog.Destroy()
+            return
+        
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay()
+            
+        maptree = self.curr_page.maptree
+        
+        for layerName in dialog.GetMapLayers():
+            ltype = dialog.GetLayerType(cmd = True)
+            if ltype == 'rast':
+                cmd = ['d.rast', 'map=%s' % layerName]
+                wxType = 'raster'
+            elif ltype == 'rast3d':
+                cmd = ['d.rast3d', 'map=%s' % layerName]
+                wxType = '3d-raster'
+            elif ltype == 'vect':
+                cmd = ['d.vect', 'map=%s' % layerName]
+                wxType = 'vector'
+            else:
+                GError(parent = self,
+                       message = _("Unsupported map layer type <%s>.") % ltype)
+                return
+            
+            newItem = maptree.AddLayer(ltype = wxType,
+                                       lname = layerName,
+                                       lchecked = False,
+                                       lopacity = 1.0,
+                                       lcmd = cmd,
+                                       lgroup = None)
+        dialog.Destroy()
+        
+    def OnAddRaster(self, event):
+        """!Add raster map layer"""
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show = True)
+        
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('raster')
+        
+    def OnAddRaster3D(self, event):
+        """!Add 3D raster map layer"""
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show = True)
+        
+        self.AddRaster3D(event)
+        
+    def OnAddRasterMisc(self, event):
+        """!Create misc raster popup-menu"""
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show = True)
+        
+        self._popupMenu((('addRast3d', self.OnAddRaster3D),
+                         (None, None),
+                         ('addRgb',    self.OnAddRasterRGB),
+                         ('addHis',    self.OnAddRasterHIS),
+                         (None, None),
+                         ('addShaded', self.OnAddRasterShaded),
+                         (None, None),
+                         ('addRArrow', self.OnAddRasterArrow),
+                         ('addRNum',   self.OnAddRasterNum)))
+        
+        # show map display
+        self.curr_page.maptree.mapdisplay.Show()
+        
+    def OnAddVector(self, event):
+        """!Add vector map to the current layer tree"""
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show = True)
+        
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('vector')
+
+    def OnAddVectorMisc(self, event):
+        """!Create misc vector popup-menu"""
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show = True)
+
+        self._popupMenu((('addThematic', self.OnAddVectorTheme),
+                         ('addChart',    self.OnAddVectorChart)))
+        
+        # show map display
+        self.curr_page.maptree.mapdisplay.Show()
+
+    def OnAddVectorTheme(self, event):
+        """!Add thematic vector map to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('thememap')
+
+    def OnAddVectorChart(self, event):
+        """!Add chart vector map to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('themechart')
+
+    def OnAddOverlay(self, event):
+        """!Create decoration overlay menu""" 
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show = True)
+
+        self._popupMenu((('addGrid',     self.OnAddGrid),
+                         ('addLabels',   self.OnAddLabels),
+                         ('addGeodesic', self.OnAddGeodesic),
+                         ('addRhumb',    self.OnAddRhumb),
+                         (None, None),
+                         ('addCmd',      self.OnAddCommand)))
+        
+        # show map display
+        self.curr_page.maptree.mapdisplay.Show()
+        
+    def OnAddRaster3D(self, event):
+        """!Add 3D raster map to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('3d-raster')
+
+    def OnAddRasterRGB(self, event):
+        """!Add RGB raster map to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('rgb')
+
+    def OnAddRasterHIS(self, event):
+        """!Add HIS raster map to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('his')
+
+    def OnAddRasterShaded(self, event):
+        """!Add shaded relief raster map to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('shaded')
+
+    def OnAddRasterArrow(self, event):
+        """!Add flow arrows raster map to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('rastarrow')
+
+    def OnAddRasterNum(self, event):
+        """!Add cell number raster map to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('rastnum')
+
+    def OnAddCommand(self, event):
+        """!Add command line map layer to the current layer tree"""
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show = True)
+
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('command')
+
+        # show map display
+        self.curr_page.maptree.mapdisplay.Show()
+
+    def OnAddGroup(self, event):
+        """!Add layer group"""
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show = True)
+
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('group')
+
+        # show map display
+        self.curr_page.maptree.mapdisplay.Show()
+
+    def OnAddGrid(self, event):
+        """!Add grid map layer to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('grid')
+
+    def OnAddGeodesic(self, event):
+        """!Add geodesic line map layer to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('geodesic')
+
+    def OnAddRhumb(self, event):
+        """!Add rhumb map layer to the current layer tree"""
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('rhumb')
+
+    def OnAddLabels(self, event):
+        """!Add vector labels map layer to the current layer tree"""
+        # start new map display if no display is available
+        if not self.curr_page:
+            self.NewDisplay(show = True)
+
+        self.notebook.SetSelectionByName('layers')
+        self.curr_page.maptree.AddLayer('labels')
+
+        # show map display
+        self.curr_page.maptree.mapdisplay.Show()
+
+    def OnDeleteLayer(self, event):
+        """!Remove selected map layer from the current layer Tree
+        """
+        if not self.curr_page or not self.curr_page.maptree.layer_selected:
+            self.MsgNoLayerSelected()
+            return
+
+        if UserSettings.Get(group = 'manager', key = 'askOnRemoveLayer', subkey = 'enabled'):
+            layerName = ''
+            for item in self.curr_page.maptree.GetSelections():
+                name = str(self.curr_page.maptree.GetItemText(item))
+                idx = name.find('(opacity')
+                if idx > -1:
+                    layerName += '<' + name[:idx].strip(' ') + '>,\n'
+                else:
+                    layerName += '<' + name + '>,\n'
+            layerName = layerName.rstrip(',\n')
+            
+            if len(layerName) > 2: # <>
+                message = _("Do you want to remove map layer(s)\n%s\n"
+                            "from layer tree?") % layerName
+            else:
+                message = _("Do you want to remove selected map layer(s) "
+                            "from layer tree?")
+
+            dlg = wx.MessageDialog (parent = self, message = message,
+                                    caption = _("Remove map layer"),
+                                    style  =  wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
+
+            if dlg.ShowModal() != wx.ID_YES:
+                dlg.Destroy()
+                return
+            
+            dlg.Destroy()
+
+        for layer in self.curr_page.maptree.GetSelections():
+            if self.curr_page.maptree.GetPyData(layer)[0]['type'] == 'group':
+                self.curr_page.maptree.DeleteChildren(layer)
+            self.curr_page.maptree.Delete(layer)
+        
+    def OnKeyDown(self, event):
+        """!Key pressed"""
+        kc = event.GetKeyCode()
+        
+        if event.ControlDown():
+            if kc == wx.WXK_TAB:
+                # switch layer list / command output
+                if self.notebook.GetSelection() == self.notebook.GetPageIndexByName('layers'):
+                    self.notebook.SetSelectionByName('output')
+                else:
+                    self.notebook.SetSelectionByName('layers')
+        
+        try:
+            ckc = chr(kc)
+        except ValueError:
+            event.Skip()
+            return
+        
+        if event.CtrlDown():
+            if kc == 'R':
+                self.OnAddRaster(None)
+            elif kc == 'V':
+                self.OnAddVector(None)
+        
+        event.Skip()
+
+    def OnCloseWindow(self, event):
+        """!Cleanup when wxGUI is quitted"""
+        if not self.curr_page:
+            self._auimgr.UnInit()
+            self.Destroy()
+            return
+        
+        maptree = self.curr_page.maptree
+        if self.workspaceChanged and \
+                UserSettings.Get(group = 'manager', key = 'askOnQuit', subkey = 'enabled'):
+            if self.workspaceFile:
+                message = _("Do you want to save changes in the workspace?")
+            else:
+                message = _("Do you want to store current settings "
+                            "to workspace file?")
+            
+            # ask user to save current settings
+            if maptree.GetCount() > 0:
+                dlg = wx.MessageDialog(self,
+                                       message = message,
+                                       caption = _("Quit GRASS GUI"),
+                                       style = wx.YES_NO | wx.YES_DEFAULT |
+                                       wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
+                ret = dlg.ShowModal()
+                if ret == wx.ID_YES:
+                    if not self.workspaceFile:
+                        self.OnWorkspaceSaveAs()
+                    else:
+                        self.SaveToWorkspaceFile(self.workspaceFile)
+                elif ret == wx.ID_CANCEL:
+                    event.Veto()
+                    dlg.Destroy()
+                    return
+                dlg.Destroy()
+        
+        # don't ask any more...
+        UserSettings.Set(group = 'manager', key = 'askOnQuit', subkey = 'enabled',
+                         value = False)
+        
+        self.OnDisplayCloseAll()
+        
+        self.gm_cb.DeleteAllPages()
+        
+        self._auimgr.UnInit()
+        self.Destroy()
+        
+    def MsgNoLayerSelected(self):
+        """!Show dialog message 'No layer selected'"""
+        wx.MessageBox(parent = self,
+                      message = _("No map layer selected. Operation cancelled."),
+                      caption = _("Message"),
+                      style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)

Modified: grass/branches/develbranch_6/gui/wxpython/wxgui.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/wxgui.py	2011-12-08 20:34:16 UTC (rev 49629)
+++ grass/branches/develbranch_6/gui/wxpython/wxgui.py	2011-12-08 20:41:45 UTC (rev 49630)
@@ -3,15 +3,12 @@
 
 @brief Main Python application for GRASS wxPython GUI
 
-Layer Manager - main menu, layer management toolbar, notebook control
-for display management and access to command console.
-
 Classes:
- - wxgui::GMFrame
  - wxgui::GMApp
  - wxgui::Usage
 
 (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.
 
@@ -21,1662 +18,21 @@
 @author Vaclav Petras <wenzeslaus gmail.com> (menu customization)
 """
 
-import sys
 import os
+import sys
 import getopt
-import tempfile
-try:
-    import xml.etree.ElementTree as etree
-except ImportError:
-    import elementtree.ElementTree as etree # Python <= 2.4
 
+if __name__ == "__main__":
+    sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'wxpython'))
 from core import globalvar
 import wx
-import wx.aui
 try:
-    import wx.lib.agw.flatnotebook   as FN
-except ImportError:
-    import wx.lib.flatnotebook   as FN
-try:
     import wx.lib.agw.advancedsplash as SC
 except ImportError:
     SC = None
 
-sys.path.append(os.path.join(globalvar.ETCDIR, "python"))
-from grass.script          import core as grass
+from lmgr.frame import GMFrame
 
-from core                  import utils
-from core.gcmd             import RunCommand, GError, GMessage, Command
-from core.settings         import UserSettings
-from icons.icon            import Icons
-from gui_core.preferences  import MapsetAccess, PreferencesDialog, EVT_SETTINGS_CHANGED
-from lmgr.layertree        import LayerTree
-from lmgr.menudata         import ManagerData
-from gui_core.widgets      import GNotebook
-from modules.histogram     import HistogramFrame
-from modules.mcalc_builder import MapCalcFrame
-from dbmgr.manager         import AttributeManager
-from core.workspace        import ProcessWorkspaceFile, ProcessGrcFile, WriteWorkspaceFile
-from gui_core.goutput      import GMConsole
-from gui_core.dialogs      import DxfImportDialog, GdalImportDialog, MapLayersDialog
-from gui_core.dialogs      import LocationDialog, MapsetDialog, CreateNewVector, GroupDialog
-from modules.ogc_services  import WMSDialog
-from modules.colorrules    import RasterColorTable, VectorColorTable
-from gui_core.menu         import Menu
-from gmodeler.model        import Model
-from gmodeler.frame        import ModelFrame
-from modules.vclean        import VectorCleaningFrame
-from nviz.tools            import NvizToolWindow
-from psmap.frame           import PsMapFrame
-from core.debug            import Debug
-from gui_core.ghelp        import MenuTreeWindow, AboutWindow
-from modules.extensions    import InstallExtensionWindow
-from lmgr.toolbars         import LMWorkspaceToolbar, LMDataToolbar, LMToolsToolbar
-from lmgr.toolbars         import LMMiscToolbar, LMVectorToolbar, LMNvizToolbar
-from lmgr.pyshell          import PyShellWindow
-from gui_core.forms        import GUI
-from gcp.manager           import GCPWizard
-
-class GMFrame(wx.Frame):
-    """!Layer Manager frame with notebook widget for controlling GRASS
-    GIS. Includes command console page for typing GRASS (and other)
-    commands, tree widget page for managing map layers.
-    """
-    def __init__(self, parent, id = wx.ID_ANY, title = _("GRASS GIS Layer Manager"),
-                 workspace = None,
-                 size = globalvar.GM_WINDOW_SIZE, style = wx.DEFAULT_FRAME_STYLE, **kwargs):
-        self.parent    = parent
-        self.baseTitle = title
-        self.iconsize  = (16, 16)
-        
-        wx.Frame.__init__(self, parent = parent, id = id, size = size,
-                          style = style, **kwargs)
-                          
-        self.SetTitle(self.baseTitle)
-        self.SetName("LayerManager")
-
-        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
-
-        self._auimgr = wx.aui.AuiManager(self)
-
-        # initialize variables
-        self.disp_idx      = 0            # index value for map displays and layer trees
-        self.curr_page     = None         # currently selected page for layer tree notebook
-        self.curr_pagenum  = None         # currently selected page number for layer tree notebook
-        self.workspaceFile = workspace    # workspace file
-        self.workspaceChanged = False     # track changes in workspace
-        self.georectifying = None         # reference to GCP class or None
-        self.gcpmanagement = None         # reference to GCP class or None
-        
-        # list of open dialogs
-        self.dialogs        = dict()
-        self.dialogs['preferences'] = None
-        self.dialogs['atm'] = list()
-        
-        # creating widgets
-        self._createMenuBar()
-        self.statusbar = self.CreateStatusBar(number = 1)
-        self.notebook  = self._createNoteBook()
-        self.toolbars  = { 'workspace' : LMWorkspaceToolbar(parent = self),
-                           'data'      : LMDataToolbar(parent = self),
-                           'tools'     : LMToolsToolbar(parent = self),
-                           'misc'      : LMMiscToolbar(parent = self),
-                           'vector'    : LMVectorToolbar(parent = self),
-                           'nviz'      : LMNvizToolbar(parent = self)}
-        
-        self._toolbarsData = { 'workspace' : ("toolbarWorkspace",     # name
-                                              _("Workspace Toolbar"), # caption
-                                              1),                     # row
-                               'data'      : ("toolbarData",
-                                              _("Data Toolbar"),
-                                              1),
-                               'misc'      : ("toolbarMisc",
-                                              _("Misc Toolbar"),
-                                              2),
-                               'tools'     : ("toolbarTools",
-                                              _("Tools Toolbar"),
-                                              2),
-                               'vector'    : ("toolbarVector",
-                                              _("Vector Toolbar"),
-                                              2),
-                               'nviz'      : ("toolbarNviz",
-                                              _("3D view Toolbar"),
-                                              2),                                            
-                               }
-        if sys.platform == 'win32':
-            self._toolbarsList = ('workspace', 'data',
-                                  'vector', 'tools', 'misc', 'nviz')
-        else:
-            self._toolbarsList = ('data', 'workspace',
-                                  'nviz', 'misc', 'tools', 'vector')
-        for toolbar in self._toolbarsList:
-            name, caption, row = self._toolbarsData[toolbar]
-            self._auimgr.AddPane(self.toolbars[toolbar],
-                                 wx.aui.AuiPaneInfo().
-                                 Name(name).Caption(caption).
-                                 ToolbarPane().Top().Row(row).
-                                 LeftDockable(False).RightDockable(False).
-                                 BottomDockable(False).TopDockable(True).
-                                 CloseButton(False).Layer(2).
-                                 BestSize((self.toolbars[toolbar].GetBestSize())))
-        
-        self._auimgr.GetPane('toolbarNviz').Hide()
-        # bindings
-        self.Bind(wx.EVT_CLOSE,    self.OnCloseWindow)
-        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
-
-        # minimal frame size
-        self.SetMinSize((500, 400))
-
-        # AUI stuff
-        self._auimgr.AddPane(self.notebook, wx.aui.AuiPaneInfo().
-                             Left().CentrePane().BestSize((-1,-1)).Dockable(False).
-                             CloseButton(False).DestroyOnClose(True).Row(1).Layer(0))
-
-        self._auimgr.Update()
-
-        wx.CallAfter(self.notebook.SetSelectionByName, 'layers')
-        
-        # use default window layout ?
-        if UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'enabled'):
-            dim = UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'dim')
-            try:
-               x, y = map(int, dim.split(',')[0:2])
-               w, h = map(int, dim.split(',')[2:4])
-               self.SetPosition((x, y))
-               self.SetSize((w, h))
-            except:
-                pass
-        else:
-            self.Centre()
-        
-        self.Layout()
-        self.Show()
-        
-        # load workspace file if requested
-        if self.workspaceFile:
-            # load given workspace file
-            if self.LoadWorkspaceFile(self.workspaceFile):
-                self.SetTitle(self.baseTitle + " - " +  os.path.basename(self.workspaceFile))
-            else:
-                self.workspaceFile = None
-        else:
-            # start default initial display
-            self.NewDisplay(show = False)
-
-        # show map display widnow
-        # -> OnSize() -> UpdateMap()
-        if self.curr_page and not self.curr_page.maptree.mapdisplay.IsShown():
-            self.curr_page.maptree.mapdisplay.Show()
-        
-        # redirect stderr to log area    
-        self.goutput.Redirect()
-        
-        # fix goutput's pane size (required for Mac OSX)`
-        self.goutput.SetSashPosition(int(self.GetSize()[1] * .8))
-        
-        self.workspaceChanged = False
-        
-        # start with layer manager on top
-        if self.curr_page:
-            self.curr_page.maptree.mapdisplay.Raise()
-        wx.CallAfter(self.Raise)
-        
-    def _createMenuBar(self):
-        """!Creates menu bar"""
-        self.menubar = Menu(parent = self, data = ManagerData())
-        self.SetMenuBar(self.menubar)
-        self.menucmd = self.menubar.GetCmd()
-        
-    def _setCopyingOfSelectedText(self):
-        copy = UserSettings.Get(group = 'manager', key = 'copySelectedTextToClipboard', subkey = 'enabled')
-        self.goutput.SetCopyingOfSelectedText(copy)
-    
-    def IsPaneShown(self, name):
-        """!Check if pane (toolbar, ...) of given name is currently shown"""
-        if self._auimgr.GetPane(name).IsOk():
-            return self._auimgr.GetPane(name).IsShown()
-        return False
-    
-    def _createNoteBook(self):
-        """!Creates notebook widgets"""
-        self.notebook = GNotebook(parent = self, style = globalvar.FNPageDStyle)
-        # create displays notebook widget and add it to main notebook page
-        cbStyle = globalvar.FNPageStyle
-        if globalvar.hasAgw:
-            self.gm_cb = FN.FlatNotebook(self, id = wx.ID_ANY, agwStyle = cbStyle)
-        else:
-            self.gm_cb = FN.FlatNotebook(self, id = wx.ID_ANY, style = cbStyle)
-        self.gm_cb.SetTabAreaColour(globalvar.FNPageColor)
-        self.notebook.AddPage(page = self.gm_cb, text = _("Map layers"), name = 'layers')
-        
-        # create 'command output' text area
-        self.goutput = GMConsole(self)
-        self.notebook.AddPage(page = self.goutput, text = _("Command console"), name = 'output')
-        self._setCopyingOfSelectedText()
-        
-        # create 'search module' notebook page
-        if not UserSettings.Get(group = 'manager', key = 'hideTabs', subkey = 'search'):
-            self.search = MenuTreeWindow(parent = self)
-            self.notebook.AddPage(page = self.search, text = _("Search module"), name = 'search')
-        else:
-            self.search = None
-        
-        # create 'python shell' notebook page
-        if not UserSettings.Get(group = 'manager', key = 'hideTabs', subkey = 'pyshell'):
-            self.pyshell = PyShellWindow(parent = self)
-            self.notebook.AddPage(page = self.pyshell, text = _("Python shell"), name = 'pyshell')
-        else:
-            self.pyshell = None
-        
-        # bindings
-        self.gm_cb.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED,    self.OnCBPageChanged)
-        self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
-        self.gm_cb.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING,    self.OnCBPageClosed)
-        
-        return self.notebook
-            
-    def AddNvizTools(self):
-        """!Add nviz notebook page"""
-        Debug.msg(5, "GMFrame.AddNvizTools()")
-        # show toolbar
-        self._auimgr.GetPane('toolbarNviz').Show()
-        # reorder other toolbars
-        for pos, toolbar in enumerate(('toolbarVector', 'toolbarTools', 'toolbarMisc','toolbarNviz')):
-            self._auimgr.GetPane(toolbar).Row(2).Position(pos)
-        self._auimgr.Update()
-        
-        # create nviz tools tab
-        self.nviz = NvizToolWindow(parent = self,
-                                   display = self.curr_page.maptree.GetMapDisplay())
-        idx = self.notebook.GetPageIndexByName('layers')
-        self.notebook.InsertPage(indx = idx + 1, page = self.nviz, text = _("3D view"), name = 'nviz')
-        self.notebook.SetSelectionByName('nviz')
-        
-        
-    def RemoveNvizTools(self):
-        """!Remove nviz notebook page"""
-        # if more mapwindow3D were possible, check here if nb page should be removed
-        self.notebook.SetSelectionByName('layers')
-        self.notebook.RemovePage(self.notebook.GetPageIndexByName('nviz'))
-        del self.nviz
-        # hide toolbar
-        self._auimgr.GetPane('toolbarNviz').Hide()
-        for pos, toolbar in enumerate(('toolbarVector', 'toolbarTools', 'toolbarMisc')):
-            self._auimgr.GetPane(toolbar).Row(2).Position(pos)
-        self._auimgr.Update()
-    
-    def WorkspaceChanged(self):
-        """!Update window title"""
-        if not self.workspaceChanged:
-            self.workspaceChanged = True
-        
-        if self.workspaceFile:
-            self.SetTitle(self.baseTitle + " - " +  os.path.basename(self.workspaceFile) + '*')
-        
-    def OnLocationWizard(self, event):
-        """!Launch location wizard"""
-        gisdbase = grass.gisenv()['GISDBASE']
-        gWizard = location_wizard.LocationWizard(parent = self,
-                                                 grassdatabase = gisdbase)
-        
-        if gWizard.location !=  None:
-            dlg = wx.MessageDialog(parent = self,
-                                   message = _('Location <%s> created.\n\n'
-                                               'Do you want to switch to the '
-                                               'new location?') % gWizard.location,
-                                   caption=_("Switch to new location?"),
-                                   style = wx.YES_NO | wx.NO_DEFAULT |
-                                   wx.ICON_QUESTION | wx.CENTRE)
-            
-            ret = dlg.ShowModal()
-            if ret == wx.ID_YES:
-                RunCommand("g.gisenv",
-                           set = "LOCATION_NAME=%s" % gWizard.location)
-                RunCommand("g.gisenv",
-                           set = "MAPSET=PERMANENT")
-            
-            dlg.Destroy()
-            
-    def OnSettingsChanged(self, event):
-        """!Here can be functions which have to be called after EVT_SETTINGS_CHANGED. 
-        Now only set copying of selected text to clipboard (in goutput).
-        """
-        ### self._createMenuBar() # bug when menu is re-created on the fly
-        self._setCopyingOfSelectedText()
-        
-    def OnGCPManager(self, event):
-        """!Launch georectifier module
-        """
-        GCPWizard(self)
-
-    def OnGModeler(self, event):
-        """!Launch Graphical Modeler"""
-        win = ModelFrame(parent = self)
-        win.CentreOnScreen()
-        
-        win.Show()
-        
-    def OnPsMap(self, event):
-        """!Launch Cartographic Composer
-        """
-        win = PsMapFrame(parent = self)
-        win.CentreOnScreen()
-        
-        win.Show()
-        
-    def OnDone(self, cmd, returncode):
-        """Command execution finised"""
-        if hasattr(self, "model"):
-            self.model.DeleteIntermediateData(log = self.goutput)
-            del self.model
-        self.SetStatusText('')
-        
-    def OnRunModel(self, event):
-        """!Run model"""
-        filename = ''
-        dlg = wx.FileDialog(parent = self, message =_("Choose model to run"),
-                            defaultDir = os.getcwd(),
-                            wildcard = _("GRASS Model File (*.gxm)|*.gxm"))
-        if dlg.ShowModal() == wx.ID_OK:
-            filename = dlg.GetPath()
-        
-        if not filename:
-            dlg.Destroy()
-            return
-        
-        self.model = Model()
-        self.model.LoadModel(filename)
-        self.model.Run(log = self.goutput, onDone = self.OnDone, parent = self)
-        
-        dlg.Destroy()
-        
-    def OnMapsets(self, event):
-        """!Launch mapset access dialog
-        """
-        dlg = MapsetAccess(parent = self, id = wx.ID_ANY)
-        dlg.CenterOnScreen()
-        
-        if dlg.ShowModal() == wx.ID_OK:
-            ms = dlg.GetMapsets()
-            RunCommand('g.mapsets',
-                       parent = self,
-                       mapset = '%s' % ','.join(ms))
-            
-    def OnCBPageChanged(self, event):
-        """!Page in notebook (display) changed"""
-        old_pgnum = event.GetOldSelection()
-        new_pgnum = event.GetSelection()
-        
-        self.curr_page   = self.gm_cb.GetCurrentPage()
-        self.curr_pagenum = self.gm_cb.GetSelection()
-        try:
-            self.curr_page.maptree.mapdisplay.SetFocus()
-            self.curr_page.maptree.mapdisplay.Raise()
-        except:
-            pass
-        
-        event.Skip()
-
-    def OnPageChanged(self, event):
-        """!Page in notebook changed"""
-        page = event.GetSelection()
-        if page == self.notebook.GetPageIndexByName('output'):
-            # remove '(...)'
-            self.notebook.SetPageText(page, _("Command console"))
-            wx.CallAfter(self.goutput.ResetFocus)
-        self.SetStatusText('', 0)
-        
-        event.Skip()
-
-    def OnCBPageClosed(self, event):
-        """!Page of notebook closed
-        Also close associated map display
-        """
-        if UserSettings.Get(group = 'manager', key = 'askOnQuit', subkey = 'enabled'):
-            maptree = self.curr_page.maptree
-            
-            if self.workspaceFile:
-                message = _("Do you want to save changes in the workspace?")
-            else:
-                message = _("Do you want to store current settings "
-                            "to workspace file?")
-            
-            # ask user to save current settings
-            if maptree.GetCount() > 0:
-                dlg = wx.MessageDialog(self,
-                                       message = message,
-                                       caption = _("Close Map Display %d") % (self.curr_pagenum + 1),
-                                       style = wx.YES_NO | wx.YES_DEFAULT |
-                                       wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
-                ret = dlg.ShowModal()
-                if ret == wx.ID_YES:
-                    if not self.workspaceFile:
-                        self.OnWorkspaceSaveAs()
-                    else:
-                        self.SaveToWorkspaceFile(self.workspaceFile)
-                elif ret == wx.ID_CANCEL:
-                    event.Veto()
-                    dlg.Destroy()
-                    return
-                dlg.Destroy()
-
-        self.gm_cb.GetPage(event.GetSelection()).maptree.Map.Clean()
-        self.gm_cb.GetPage(event.GetSelection()).maptree.Close(True)
-
-        self.curr_page = None
-
-        event.Skip()
-
-    def GetLayerTree(self):
-        """!Get current layer tree"""
-        return self.curr_page.maptree
-    
-    def GetLogWindow(self):
-        """!Get widget for command output"""
-        return self.goutput
-    
-    def GetMenuCmd(self, event):
-        """!Get GRASS command from menu item
-
-        Return command as a list"""
-        layer = None
-        
-        if event:
-            cmd = self.menucmd[event.GetId()]
-        
-        try:
-            cmdlist = cmd.split(' ')
-        except: # already list?
-            cmdlist = cmd
-        
-        # check list of dummy commands for GUI modules that do not have GRASS
-        # bin modules or scripts. 
-        if cmd in ['vcolors', 'r.mapcalc', 'r3.mapcalc']:
-            return cmdlist
-
-        try:
-            layer = self.curr_page.maptree.layer_selected
-            name = self.curr_page.maptree.GetPyData(layer)[0]['maplayer'].name
-            type = self.curr_page.maptree.GetPyData(layer)[0]['type']
-        except:
-            layer = None
-
-        if layer and len(cmdlist) == 1: # only if no paramaters given
-            if (type == 'raster' and cmdlist[0][0] == 'r' and cmdlist[0][1] != '3') or \
-                    (type == 'vector' and cmdlist[0][0] == 'v'):
-                input = GUI().GetCommandInputMapParamKey(cmdlist[0])
-                if input:
-                    cmdlist.append("%s=%s" % (input, name))
-        
-        return cmdlist
-
-    def RunMenuCmd(self, event = None, cmd = []):
-        """!Run command selected from menu"""
-        if event:
-            cmd = self.GetMenuCmd(event)
-        self.goutput.RunCmd(cmd, switchPage = False)
-
-    def OnMenuCmd(self, event = None, cmd = []):
-        """!Parse command selected from menu"""
-        if event:
-            cmd = self.GetMenuCmd(event)
-        GUI(parent = self).ParseCommand(cmd)
-        
-    def OnVDigit(self, event):
-        """!Start vector digitizer
-        """
-        if not self.curr_page:
-            self.MsgNoLayerSelected()
-            return
-        
-        tree = self.GetLayerTree()
-        layer = tree.layer_selected
-        # no map layer selected
-        if not layer:
-            self.MsgNoLayerSelected()
-            return
-        
-        # available only for vector map layers
-        try:
-            mapLayer = tree.GetPyData(layer)[0]['maplayer']
-        except:
-            mapLayer = None
-        
-        if not mapLayer or mapLayer.GetType() != 'vector':
-            GMessage(parent = self,
-                     message = _("Selected map layer is not vector."))
-            return
-        
-        if mapLayer.GetMapset() != grass.gisenv()['MAPSET']:
-            GMessage(parent = self,
-                     message = _("Editing is allowed only for vector maps from the "
-                                 "current mapset."))
-            return
-        
-        if not tree.GetPyData(layer)[0]:
-            return
-        dcmd = tree.GetPyData(layer)[0]['cmd']
-        if not dcmd:
-            return
-        
-        tree.OnStartEditing(None)
-        
-    def OnRunScript(self, event):
-        """!Run script"""
-        # open dialog and choose script file
-        dlg = wx.FileDialog(parent = self, message = _("Choose script file to run"),
-                            defaultDir = os.getcwd(),
-                            wildcard = _("Python script (*.py)|*.py|Bash script (*.sh)|*.sh"))
-        
-        filename = None
-        if dlg.ShowModal() == wx.ID_OK:
-            filename = dlg.GetPath()
-        
-        if not filename:
-            return False
-
-        if not os.path.exists(filename):
-            GError(parent = self,
-                   message = _("Script file '%s' doesn't exist. "
-                               "Operation cancelled.") % filename)
-            return
-        
-        self.goutput.WriteCmdLog(_("Launching script '%s'...") % filename)
-        self.goutput.RunCmd([filename], switchPage = True)
-        
-    def OnChangeLocation(self, event):
-        """Change current location"""
-        dlg = LocationDialog(parent = self)
-        if dlg.ShowModal() == wx.ID_OK:
-            location, mapset = dlg.GetValues()
-            if location and mapset:
-                ret = RunCommand("g.gisenv",
-                                 set = "LOCATION_NAME=%s" % location)
-                ret += RunCommand("g.gisenv",
-                                  set = "MAPSET=%s" % mapset)
-                if ret > 0:
-                    wx.MessageBox(parent = self,
-                                  message = _("Unable to switch to location <%(loc)s> mapset <%(mapset)s>.") % \
-                                      { 'loc' : location, 'mapset' : mapset },
-                                  caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
-                else:
-                    # close workspace
-                    self.OnWorkspaceClose()
-                    self.OnWorkspaceNew()
-                    wx.MessageBox(parent = self,
-                                  message = _("Current location is <%(loc)s>.\n"
-                                              "Current mapset is <%(mapset)s>.") % \
-                                      { 'loc' : location, 'mapset' : mapset },
-                                  caption = _("Info"), style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
-                    
-    def OnCreateMapset(self, event):
-        """!Create new mapset"""
-        dlg = wx.TextEntryDialog(parent = self,
-                                 message = _('Enter name for new mapset:'),
-                                 caption = _('Create new mapset'))
-        
-        if dlg.ShowModal() ==  wx.ID_OK:
-            mapset = dlg.GetValue()
-            if not mapset:
-                GError(parent = self,
-                       message = _("No mapset provided. Operation canceled."))
-                return
-            
-            ret = RunCommand('g.mapset',
-                             parent = self,
-                             flags = 'c',
-                             mapset = mapset)
-            if ret == 0:
-                GMessage(parent = self,
-                         message = _("Current mapset is <%s>.") % mapset)
-            
-    def OnChangeMapset(self, event):
-        """Change current mapset"""
-        dlg = MapsetDialog(parent = self)
-        
-        if dlg.ShowModal() == wx.ID_OK:
-            mapset = dlg.GetMapset()
-            if not mapset:
-                GError(parent = self,
-                       message = _("No mapset provided. Operation canceled."))
-                return
-            
-            ret = RunCommand('g.mapset',
-                             parent = self,
-                             mapset = mapset)
-            
-            if ret == 0:
-                GMessage(parent = self,
-                         message = _("Current mapset is <%s>.") % mapset)
-        
-    def OnNewVector(self, event):
-        """!Create new vector map layer"""
-        dlg = CreateNewVector(self, log = self.goutput,
-                              cmd = (('v.edit',
-                                      { 'tool' : 'create' },
-                                      'map')))
-        
-        if not dlg:
-            return
-        
-        name = dlg.GetName(full = True)
-        if name and dlg.IsChecked('add'):
-            # add layer to map layer tree
-            self.curr_page.maptree.AddLayer(ltype = 'vector',
-                                            lname = name,
-                                            lcmd = ['d.vect', 'map=%s' % name])
-        dlg.Destroy()
-        
-    def OnAboutGRASS(self, event):
-        """!Display 'About GRASS' dialog"""
-        win = AboutWindow(self)
-        win.CentreOnScreen()
-        win.Show(True)  
-        
-    def _popupMenu(self, data):
-        """!Create popup menu
-        """
-        point = wx.GetMousePosition()
-        menu = wx.Menu()
-        
-        for key, handler in data:
-            if key is None:
-                menu.AppendSeparator()
-                continue
-            item = wx.MenuItem(menu, wx.ID_ANY, Icons['layerManager'][key].GetLabel())
-            item.SetBitmap(Icons['layerManager'][key].GetBitmap(self.iconsize))
-            menu.AppendItem(item)
-            self.Bind(wx.EVT_MENU, handler, item)
-        
-        # create menu
-        self.PopupMenu(menu)
-        menu.Destroy()
-
-    def OnImportMenu(self, event):
-        """!Import maps menu (import, link)
-        """
-        self._popupMenu((('rastImport',    self.OnImportGdalLayers),
-                         ('vectImport',    self.OnImportOgrLayers)))
-        
-    def OnWorkspaceNew(self, event = None):
-        """!Create new workspace file
-
-        Erase current workspace settings first
-        """
-        Debug.msg(4, "GMFrame.OnWorkspaceNew():")
-        
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay()
-        
-        maptree = self.curr_page.maptree
-        
-        # ask user to save current settings
-        if self.workspaceFile and self.workspaceChanged:
-            self.OnWorkspaceSave()
-        elif self.workspaceFile is None and maptree.GetCount() > 0:
-             dlg = wx.MessageDialog(self, message = _("Current workspace is not empty. "
-                                                    "Do you want to store current settings "
-                                                    "to workspace file?"),
-                                    caption = _("Create new workspace?"),
-                                    style = wx.YES_NO | wx.YES_DEFAULT | \
-                                        wx.CANCEL | wx.ICON_QUESTION)
-             ret = dlg.ShowModal()
-             if ret == wx.ID_YES:
-                 self.OnWorkspaceSaveAs()
-             elif ret == wx.ID_CANCEL:
-                 dlg.Destroy()
-                 return
-             
-             dlg.Destroy()
-        
-        # delete all items
-        maptree.DeleteAllItems()
-        
-        # add new root element
-        maptree.root = maptree.AddRoot("Map Layers")
-        self.curr_page.maptree.SetPyData(maptree.root, (None,None))
-        
-        # no workspace file loaded
-        self.workspaceFile = None
-        self.workspaceChanged = False
-        self.SetTitle(self.baseTitle)
-        
-    def OnWorkspaceOpen(self, event = None):
-        """!Open file with workspace definition"""
-        dlg = wx.FileDialog(parent = self, message = _("Choose workspace file"),
-                            defaultDir = os.getcwd(), wildcard = _("GRASS Workspace File (*.gxw)|*.gxw"))
-
-        filename = ''
-        if dlg.ShowModal() == wx.ID_OK:
-            filename = dlg.GetPath()
-
-        if filename == '':
-            return
-
-        Debug.msg(4, "GMFrame.OnWorkspaceOpen(): filename=%s" % filename)
-        
-        # delete current layer tree content
-        self.OnWorkspaceClose()
-        
-        self.LoadWorkspaceFile(filename)
-
-        self.workspaceFile = filename
-        self.SetTitle(self.baseTitle + " - " +  os.path.basename(self.workspaceFile))
-
-    def LoadWorkspaceFile(self, filename):
-        """!Load layer tree definition stored in GRASS Workspace XML file (gxw)
-
-        @todo Validate against DTD
-        
-        @return True on success
-        @return False on error
-        """
-        # dtd
-        dtdFilename = os.path.join(globalvar.ETCWXDIR, "xml", "grass-gxw.dtd")
-        
-        # parse workspace file
-        try:
-            gxwXml = ProcessWorkspaceFile(etree.parse(filename))
-        except Exception, e:
-            GError(parent = self,
-                   message = _("Reading workspace file <%s> failed.\n"
-                                    "Invalid file, unable to parse XML document.") % filename)
-            return
-        
-        busy = wx.BusyInfo(message = _("Please wait, loading workspace..."),
-                           parent = self)
-        wx.Yield()
-
-        #
-        # load layer manager window properties
-        #
-        if UserSettings.Get(group = 'workspace', key = 'posManager', subkey = 'enabled') is False:
-            if gxwXml.layerManager['pos']:
-                self.SetPosition(gxwXml.layerManager['pos'])
-            if gxwXml.layerManager['size']:
-                self.SetSize(gxwXml.layerManager['size'])
-        
-        #
-        # start map displays first (list of layers can be empty)
-        #
-        displayId = 0
-        mapdisplay = list()
-        for display in gxwXml.displays:
-            mapdisp = self.NewDisplay(show = False)
-            mapdisplay.append(mapdisp)
-            maptree = self.gm_cb.GetPage(displayId).maptree
-            
-            # set windows properties
-            mapdisp.SetProperties(render = display['render'],
-                                  mode = display['mode'],
-                                  showCompExtent = display['showCompExtent'],
-                                  alignExtent = display['alignExtent'],
-                                  constrainRes = display['constrainRes'],
-                                  projection = display['projection']['enabled'])
-
-            if display['projection']['enabled']:
-                if display['projection']['epsg']:
-                    UserSettings.Set(group = 'display', key = 'projection', subkey = 'epsg',
-                                     value = display['projection']['epsg'])
-                    if display['projection']['proj']:
-                        UserSettings.Set(group = 'display', key = 'projection', subkey = 'proj4',
-                                         value = display['projection']['proj'])
-            
-            # set position and size of map display
-            if UserSettings.Get(group = 'workspace', key = 'posDisplay', subkey = 'enabled') is False:
-                if display['pos']:
-                    mapdisp.SetPosition(display['pos'])
-                if display['size']:
-                    mapdisp.SetSize(display['size'])
-                    
-            # set extent if defined
-            if display['extent']:
-                w, s, e, n = display['extent']
-                region = maptree.Map.region = maptree.Map.GetRegion(w = w, s = s, e = e, n = n)
-                mapdisp.GetWindow().ResetZoomHistory()
-                mapdisp.GetWindow().ZoomHistory(region['n'],
-                                                region['s'],
-                                                region['e'],
-                                                region['w'])
-                
-            mapdisp.Show()
-            
-            displayId += 1
-    
-        maptree = None 
-        selected = [] # list of selected layers
-        # 
-        # load list of map layers
-        #
-        for layer in gxwXml.layers:
-            display = layer['display']
-            maptree = self.gm_cb.GetPage(display).maptree
-            
-            newItem = maptree.AddLayer(ltype = layer['type'],
-                                       lname = layer['name'],
-                                       lchecked = layer['checked'],
-                                       lopacity = layer['opacity'],
-                                       lcmd = layer['cmd'],
-                                       lgroup = layer['group'],
-                                       lnviz = layer['nviz'],
-                                       lvdigit = layer['vdigit'])
-            
-            if layer.has_key('selected'):
-                if layer['selected']:
-                    selected.append((maptree, newItem))
-                else:
-                    maptree.SelectItem(newItem, select = False)
-            
-        for maptree, layer in selected:
-            if not maptree.IsSelected(layer):
-                maptree.SelectItem(layer, select = True)
-                maptree.layer_selected = layer
-                
-        busy.Destroy()
-        
-        if maptree:
-            # reverse list of map layers
-            maptree.Map.ReverseListOfLayers()
-            
-        for idx, mdisp in enumerate(mapdisplay):
-            mdisp.MapWindow2D.UpdateMap()
-            #nviz
-            if gxwXml.displays[idx]['viewMode'] == '3d':
-                mdisp.AddNviz()
-                self.nviz.UpdateState(view = gxwXml.nviz_state['view'],
-                                              iview = gxwXml.nviz_state['iview'],
-                                              light = gxwXml.nviz_state['light'])
-                mdisp.MapWindow3D.constants = gxwXml.nviz_state['constants']
-                for idx, constant in enumerate(mdisp.MapWindow3D.constants):
-                    mdisp.MapWindow3D.AddConstant(constant, idx + 1)
-                for page in ('view', 'light', 'fringe', 'constant', 'cplane'):
-                    self.nviz.UpdatePage(page)
-                self.nviz.UpdateSettings()
-                mapdisp.toolbars['map'].combo.SetSelection(1)
-
-
-        return True
-    
-    def OnWorkspaceLoadGrcFile(self, event):
-        """!Load map layers from GRC file (Tcl/Tk GUI) into map layer tree"""
-        dlg = wx.FileDialog(parent = self, message = _("Choose GRC file to load"),
-                            defaultDir = os.getcwd(), wildcard = _("Old GRASS Workspace File (*.grc)|*.grc"))
-
-        filename = ''
-        if dlg.ShowModal() == wx.ID_OK:
-            filename = dlg.GetPath()
-
-        if filename == '':
-            return
-
-        Debug.msg(4, "GMFrame.OnWorkspaceLoadGrcFile(): filename=%s" % filename)
-
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay()
-
-        busy = wx.BusyInfo(message = _("Please wait, loading workspace..."),
-                           parent = self)
-        wx.Yield()
-
-        maptree = None
-        for layer in ProcessGrcFile(filename).read(self):
-            maptree = self.gm_cb.GetPage(layer['display']).maptree
-            newItem = maptree.AddLayer(ltype = layer['type'],
-                                       lname = layer['name'],
-                                       lchecked = layer['checked'],
-                                       lopacity = layer['opacity'],
-                                       lcmd = layer['cmd'],
-                                       lgroup = layer['group'])
-
-            busy.Destroy()
-            
-        if maptree:
-            # reverse list of map layers
-            maptree.Map.ReverseListOfLayers()
-
-    def OnWorkspaceSaveAs(self, event = None):
-        """!Save workspace definition to selected file"""
-        dlg = wx.FileDialog(parent = self, message = _("Choose file to save current workspace"),
-                            defaultDir = os.getcwd(), wildcard = _("GRASS Workspace File (*.gxw)|*.gxw"), style = wx.FD_SAVE)
-
-        filename = ''
-        if dlg.ShowModal() == wx.ID_OK:
-            filename = dlg.GetPath()
-
-        if filename == '':
-            return False
-
-        # check for extension
-        if filename[-4:] != ".gxw":
-            filename += ".gxw"
-
-        if os.path.exists(filename):
-            dlg = wx.MessageDialog(self, message = _("Workspace file <%s> already exists. "
-                                                     "Do you want to overwrite this file?") % filename,
-                                   caption = _("Save workspace"), style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
-            if dlg.ShowModal() != wx.ID_YES:
-                dlg.Destroy()
-                return False
-
-        Debug.msg(4, "GMFrame.OnWorkspaceSaveAs(): filename=%s" % filename)
-
-        self.SaveToWorkspaceFile(filename)
-        self.workspaceFile = filename
-        self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
-
-    def OnWorkspaceSave(self, event = None):
-        """!Save file with workspace definition"""
-        if self.workspaceFile:
-            dlg = wx.MessageDialog(self, message = _("Workspace file <%s> already exists. "
-                                                   "Do you want to overwrite this file?") % \
-                                       self.workspaceFile,
-                                   caption = _("Save workspace"), style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
-            if dlg.ShowModal() == wx.ID_NO:
-                dlg.Destroy()
-            else:
-                Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % self.workspaceFile)
-                self.SaveToWorkspaceFile(self.workspaceFile)
-                self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
-                self.workspaceChanged = False
-        else:
-            self.OnWorkspaceSaveAs()
-
-    def SaveToWorkspaceFile(self, filename):
-        """!Save layer tree layout to workspace file
-        
-        Return True on success, False on error
-        """
-        tmpfile = tempfile.TemporaryFile(mode = 'w+b')
-        try:
-            WriteWorkspaceFile(lmgr = self, file = tmpfile)
-        except StandardError, e:
-            GError(parent = self,
-                   message = _("Writing current settings to workspace file "
-                               "failed."))
-            return False
-        
-        try:
-            mfile = open(filename, "w")
-            tmpfile.seek(0)
-            for line in tmpfile.readlines():
-                mfile.write(line)
-        except IOError:
-            GError(parent = self,
-                   message = _("Unable to open file <%s> for writing.") % filename)
-            return False
-        
-        mfile.close()
-        
-        return True
-    
-    def OnWorkspaceClose(self, event = None):
-        """!Close file with workspace definition
-        
-        If workspace has been modified ask user to save the changes.
-        """
-        Debug.msg(4, "GMFrame.OnWorkspaceClose(): file=%s" % self.workspaceFile)
-        
-        self.OnDisplayCloseAll()
-        self.workspaceFile = None
-        self.workspaceChanged = False
-        self.SetTitle(self.baseTitle)
-        self.disp_idx = 0
-        self.curr_page = None
-        
-    def OnDisplayClose(self, event = None):
-        """!Close current map display window
-        """
-        if self.curr_page and self.curr_page.maptree.mapdisplay:
-            self.curr_page.maptree.mapdisplay.OnCloseWindow(event)
-        
-    def OnDisplayCloseAll(self, event = None):
-        """!Close all open map display windows
-        """
-        displays = list()
-        for page in range(0, self.gm_cb.GetPageCount()):
-            displays.append(self.gm_cb.GetPage(page).maptree.mapdisplay)
-        
-        for display in displays:
-            display.OnCloseWindow(event)
-        
-    def RulesCmd(self, event):
-        """!Launches dialog for commands that need rules input and
-        processes rules
-        """
-        cmd = self.GetMenuCmd(event)
-        
-        if cmd[0] == 'r.colors':
-            ctable = RasterColorTable(self)
-        else:
-            ctable = VectorColorTable(self, attributeType = 'color')
-        ctable.CentreOnScreen()
-        ctable.Show()
-        
-    def OnXTermNoXMon(self, event):
-        """!
-        Run commands that need xterm
-        """
-        self.OnXTerm(event, need_xmon = False)
-        
-    def OnXTerm(self, event, need_xmon = True):
-        """!
-        Run commands that need interactive xmon
-
-        @param need_xmon True to start X monitor
-        """
-        # unset display mode
-        del os.environ['GRASS_RENDER_IMMEDIATE']
-        
-        if need_xmon:
-            # open next available xmon
-            xmonlist = []
-            
-            # make list of xmons that are not running
-            ret = RunCommand('d.mon',
-                             flags = 'L',
-                             read = True)
-            
-            for line in ret.split('\n'):               
-                line = line.strip()
-                if line.startswith('x') and 'not running' in line:
-                    xmonlist.append(line[0:2])
-            
-            # find available xmon
-            xmon = xmonlist[0]
-            
-            # bring up the xmon
-            cmdlist = ['d.mon', xmon]
-            p = Command(cmdlist, wait=False)
-        
-        # run the command        
-        command = self.GetMenuCmd(event)
-        command = ' '.join(command)
-        
-        gisbase = os.environ['GISBASE']
-        
-        if sys.platform == "win32":
-            runbat = os.path.join(gisbase,'etc','grass-run.bat')
-            cmdlist = ["start", runbat, runbat, command]
-        else:
-            if sys.platform == "darwin":
-                xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-mac')
-            else:
-                xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-wrapper')
-            
-            grassrun = os.path.join(gisbase,'etc','grass-run.sh')
-            cmdlist = [xtermwrapper, '-e', grassrun, command]
-        
-        p = Command(cmdlist, wait=False)
-        
-        # reset display mode
-        os.environ['GRASS_RENDER_IMMEDIATE'] = 'TRUE'
-        
-    def OnEditImageryGroups(self, event, cmd = None):
-        """!Show dialog for creating and editing groups.
-        """
-        dlg = GroupDialog(self)
-        dlg.CentreOnScreen()
-        dlg.Show()
-        
-    def OnInstallExtension(self, event):
-        """!Install extension from GRASS Addons SVN repository"""
-        win = InstallExtensionWindow(self, size = (650, 550))
-        win.CentreOnScreen()
-        win.Show()
-
-    def OnPreferences(self, event):
-        """!General GUI preferences/settings
-        """
-        if not self.dialogs['preferences']:
-            dlg = PreferencesDialog(parent = self)
-            self.dialogs['preferences'] = dlg
-            self.dialogs['preferences'].CenterOnScreen()
-            
-            dlg.Bind(EVT_SETTINGS_CHANGED, self.OnSettingsChanged)
-        
-        self.dialogs['preferences'].ShowModal()
-        
-    def OnHelp(self, event):
-        """!Show help
-        """
-        self.goutput.RunCmd(['g.manual','-i'])
-        
-    def DispHistogram(self, event):
-        """
-        Init histogram display canvas and tools
-        """
-        self.histogram = HistogramFrame(self, size = (400,300),
-                                        style = wx.DEFAULT_FRAME_STYLE)
-        
-        #show new display
-        self.histogram.Show()
-        self.histogram.Refresh()
-        self.histogram.Update()
-
-    def DispProfile(self, event):
-        """
-        Init profile canvas and tools
-        """
-        self.profile = profile.ProfileFrame(self,
-                                           id = wx.ID_ANY, pos = wx.DefaultPosition, size = (400,300),
-                                           style = wx.DEFAULT_FRAME_STYLE)
-        self.profile.Show()
-        self.profile.Refresh()
-        self.profile.Update()
-        
-    def OnMapCalculator(self, event, cmd = ''):
-        """!Init map calculator for interactive creation of mapcalc statements
-        """
-        if event:
-            try:
-                cmd = self.GetMenuCmd(event)
-            except KeyError:
-                cmd = ['r.mapcalc']
-        
-        win = MapCalcFrame(parent = self,
-                           cmd = cmd[0])
-        win.CentreOnScreen()
-        win.Show()
-        
-    def OnVectorCleaning(self, event, cmd = ''):
-        """!Init interactive vector cleaning
-        """
-        
-        if event:
-            cmd = self.GetMenuCmd(event)
-
-        win = VectorCleaningFrame(parent = self, cmd = cmd[0])
-        win.CentreOnScreen()
-        win.Show()
-        
-    def OnImportDxfFile(self, event, cmd = None):
-        """!Convert multiple DXF layers to GRASS vector map layers"""
-        dlg = DxfImportDialog(parent = self)
-        dlg.CentreOnScreen()
-        dlg.Show()
-
-    def OnImportGdalLayers(self, event, cmd = None):
-        """!Convert multiple GDAL layers to GRASS raster map layers"""
-        dlg = GdalImportDialog(parent = self)
-        dlg.CentreOnScreen()
-        dlg.Show()
-
-    def OnLinkGdalLayers(self, event, cmd = None):
-        """!Link multiple GDAL layers to GRASS raster map layers"""
-        dlg = GdalImportDialog(parent = self, link = True)
-        dlg.CentreOnScreen()
-        dlg.Show()
-        
-    def OnImportOgrLayers(self, event, cmd = None):
-        """!Convert multiple OGR layers to GRASS vector map layers"""
-        dlg = GdalImportDialog(parent = self, ogr = True)
-        dlg.CentreOnScreen()
-        dlg.Show()
-        
-    def OnLinkOgrLayers(self, event, cmd = None):
-        """!Links multiple OGR layers to GRASS vector map layers"""
-        dlg = GdalImportDialog(parent = self, ogr = True, link = True)
-        dlg.CentreOnScreen()
-        dlg.Show()
-        
-    def OnImportWMS(self, event):
-        """!Import data from OGC WMS server"""
-        dlg = WMSDialog(parent = self, service = 'wms')
-        dlg.CenterOnScreen()
-        
-        if dlg.ShowModal() == wx.ID_OK: # -> import layers
-            layers = dlg.GetLayers()
-            
-            if len(layers.keys()) > 0:
-                for layer in layers.keys():
-                    cmd = ['r.in.wms',
-                           'mapserver=%s' % dlg.GetSettings()['server'],
-                           'layers=%s' % layer,
-                           'output=%s' % layer,
-                           'format=png',
-                           '--overwrite']
-                    styles = ','.join(layers[layer])
-                    if styles:
-                        cmd.append('styles=%s' % styles)
-                    self.goutput.RunCmd(cmd, switchPage = True)
-
-                    self.curr_page.maptree.AddLayer(ltype = 'raster',
-                                                    lname = layer,
-                                                    lcmd = ['d.rast', 'map=%s' % layer],
-                                                    multiple = False)
-            else:
-                self.goutput.WriteWarning(_("Nothing to import. No WMS layer selected."))
-                
-                
-        dlg.Destroy()
-        
-    def OnShowAttributeTable(self, event, selection = None):
-        """!Show attribute table of the given vector map layer
-        """
-        if not self.curr_page:
-            self.MsgNoLayerSelected()
-            return
-        
-        tree = self.GetLayerTree()
-        layer = tree.layer_selected
-        # no map layer selected
-        if not layer:
-            self.MsgNoLayerSelected()
-            return
-        
-        # available only for vector map layers
-        try:
-            maptype = tree.GetPyData(layer)[0]['maplayer'].type
-        except:
-            maptype = None
-        
-        if not maptype or maptype != 'vector':
-            GMessage(parent = self,
-                          message = _("Selected map layer is not vector."))
-            return
-        
-        if not tree.GetPyData(layer)[0]:
-            return
-        dcmd = tree.GetPyData(layer)[0]['cmd']
-        if not dcmd:
-            return
-        
-        busy = wx.BusyInfo(message = _("Please wait, loading attribute data..."),
-                           parent = self)
-        wx.Yield()
-        
-        dbmanager = AttributeManager(parent = self, id = wx.ID_ANY,
-                                     size = wx.Size(500, 300),
-                                     item = layer, log = self.goutput,
-                                     selection = selection)
-        
-        busy.Destroy()
-        
-        # register ATM dialog
-        self.dialogs['atm'].append(dbmanager)
-        
-        # show ATM window
-        dbmanager.Show()
-        
-    def OnNewDisplayWMS(self, event = None):
-        """!Create new layer tree and map display instance"""
-        self.NewDisplayWMS()
-
-    def OnNewDisplay(self, event = None):
-        """!Create new layer tree and map display instance"""
-        self.NewDisplay()
-
-    def NewDisplay(self, show = True):
-        """!Create new layer tree, which will
-        create an associated map display frame
-
-        @param show show map display window if True
-
-        @return reference to mapdisplay intance
-        """
-        Debug.msg(1, "GMFrame.NewDisplay(): idx=%d" % self.disp_idx)
-        
-        # make a new page in the bookcontrol for the layer tree (on page 0 of the notebook)
-        self.pg_panel = wx.Panel(self.gm_cb, id = wx.ID_ANY, style = wx.EXPAND)
-        self.gm_cb.AddPage(self.pg_panel, text = "Display "+ str(self.disp_idx + 1), select = True)
-        self.curr_page = self.gm_cb.GetCurrentPage()
-        
-        # create layer tree (tree control for managing GIS layers)  and put on new notebook page
-        self.curr_page.maptree = LayerTree(self.curr_page, id = wx.ID_ANY, pos = wx.DefaultPosition,
-                                           size = wx.DefaultSize, style = wx.TR_HAS_BUTTONS |
-                                           wx.TR_LINES_AT_ROOT| wx.TR_HIDE_ROOT |
-                                           wx.TR_DEFAULT_STYLE| wx.NO_BORDER | wx.FULL_REPAINT_ON_RESIZE,
-                                           idx = self.disp_idx, lmgr = self, notebook = self.gm_cb,
-                                           auimgr = self._auimgr, showMapDisplay = show)
-        
-        # layout for controls
-        cb_boxsizer = wx.BoxSizer(wx.VERTICAL)
-        cb_boxsizer.Add(self.curr_page.maptree, proportion = 1, flag = wx.EXPAND, border = 1)
-        self.curr_page.SetSizer(cb_boxsizer)
-        cb_boxsizer.Fit(self.curr_page.maptree)
-        self.curr_page.Layout()
-        self.curr_page.maptree.Layout()
-        
-        # use default window layout
-        if UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'enabled'):
-            dim = UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'dim')
-            idx = 4 + self.disp_idx * 4
-            try:
-                x, y = map(int, dim.split(',')[idx:idx + 2])
-                w, h = map(int, dim.split(',')[idx + 2:idx + 4])
-                self.curr_page.maptree.mapdisplay.SetPosition((x, y))
-                self.curr_page.maptree.mapdisplay.SetSize((w, h))
-            except:
-                pass
-        
-        self.disp_idx += 1
-        
-        return self.curr_page.maptree.mapdisplay
-    
-    def OnAddMaps(self, event = None):
-        """!Add selected map layers into layer tree"""
-        dialog = MapLayersDialog(parent = self, title = _("Add selected map layers into layer tree"))
-        
-        if dialog.ShowModal() != wx.ID_OK:
-            dialog.Destroy()
-            return
-        
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay()
-            
-        maptree = self.curr_page.maptree
-        
-        for layerName in dialog.GetMapLayers():
-            ltype = dialog.GetLayerType(cmd = True)
-            if ltype == 'rast':
-                cmd = ['d.rast', 'map=%s' % layerName]
-                wxType = 'raster'
-            elif ltype == 'rast3d':
-                cmd = ['d.rast3d', 'map=%s' % layerName]
-                wxType = '3d-raster'
-            elif ltype == 'vect':
-                cmd = ['d.vect', 'map=%s' % layerName]
-                wxType = 'vector'
-            else:
-                GError(parent = self,
-                       message = _("Unsupported map layer type <%s>.") % ltype)
-                return
-            
-            newItem = maptree.AddLayer(ltype = wxType,
-                                       lname = layerName,
-                                       lchecked = False,
-                                       lopacity = 1.0,
-                                       lcmd = cmd,
-                                       lgroup = None)
-        dialog.Destroy()
-        
-    def OnAddRaster(self, event):
-        """!Add raster map layer"""
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay(show = True)
-        
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('raster')
-        
-    def OnAddRaster3D(self, event):
-        """!Add 3D raster map layer"""
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay(show = True)
-        
-        self.AddRaster3D(event)
-        
-    def OnAddRasterMisc(self, event):
-        """!Create misc raster popup-menu"""
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay(show = True)
-        
-        self._popupMenu((('addRast3d', self.OnAddRaster3D),
-                         (None, None),
-                         ('addRgb',    self.OnAddRasterRGB),
-                         ('addHis',    self.OnAddRasterHIS),
-                         (None, None),
-                         ('addShaded', self.OnAddRasterShaded),
-                         (None, None),
-                         ('addRArrow', self.OnAddRasterArrow),
-                         ('addRNum',   self.OnAddRasterNum)))
-        
-        # show map display
-        self.curr_page.maptree.mapdisplay.Show()
-        
-    def OnAddVector(self, event):
-        """!Add vector map to the current layer tree"""
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay(show = True)
-        
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('vector')
-
-    def OnAddVectorMisc(self, event):
-        """!Create misc vector popup-menu"""
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay(show = True)
-
-        self._popupMenu((('addThematic', self.OnAddVectorTheme),
-                         ('addChart',    self.OnAddVectorChart)))
-        
-        # show map display
-        self.curr_page.maptree.mapdisplay.Show()
-
-    def OnAddVectorTheme(self, event):
-        """!Add thematic vector map to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('thememap')
-
-    def OnAddVectorChart(self, event):
-        """!Add chart vector map to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('themechart')
-
-    def OnAddOverlay(self, event):
-        """!Create decoration overlay menu""" 
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay(show = True)
-
-        self._popupMenu((('addGrid',     self.OnAddGrid),
-                         ('addLabels',   self.OnAddLabels),
-                         ('addGeodesic', self.OnAddGeodesic),
-                         ('addRhumb',    self.OnAddRhumb),
-                         (None, None),
-                         ('addCmd',      self.OnAddCommand)))
-        
-        # show map display
-        self.curr_page.maptree.mapdisplay.Show()
-        
-    def OnAddRaster3D(self, event):
-        """!Add 3D raster map to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('3d-raster')
-
-    def OnAddRasterRGB(self, event):
-        """!Add RGB raster map to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('rgb')
-
-    def OnAddRasterHIS(self, event):
-        """!Add HIS raster map to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('his')
-
-    def OnAddRasterShaded(self, event):
-        """!Add shaded relief raster map to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('shaded')
-
-    def OnAddRasterArrow(self, event):
-        """!Add flow arrows raster map to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('rastarrow')
-
-    def OnAddRasterNum(self, event):
-        """!Add cell number raster map to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('rastnum')
-
-    def OnAddCommand(self, event):
-        """!Add command line map layer to the current layer tree"""
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay(show = True)
-
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('command')
-
-        # show map display
-        self.curr_page.maptree.mapdisplay.Show()
-
-    def OnAddGroup(self, event):
-        """!Add layer group"""
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay(show = True)
-
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('group')
-
-        # show map display
-        self.curr_page.maptree.mapdisplay.Show()
-
-    def OnAddGrid(self, event):
-        """!Add grid map layer to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('grid')
-
-    def OnAddGeodesic(self, event):
-        """!Add geodesic line map layer to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('geodesic')
-
-    def OnAddRhumb(self, event):
-        """!Add rhumb map layer to the current layer tree"""
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('rhumb')
-
-    def OnAddLabels(self, event):
-        """!Add vector labels map layer to the current layer tree"""
-        # start new map display if no display is available
-        if not self.curr_page:
-            self.NewDisplay(show = True)
-
-        self.notebook.SetSelectionByName('layers')
-        self.curr_page.maptree.AddLayer('labels')
-
-        # show map display
-        self.curr_page.maptree.mapdisplay.Show()
-
-    def OnDeleteLayer(self, event):
-        """!Remove selected map layer from the current layer Tree
-        """
-        if not self.curr_page or not self.curr_page.maptree.layer_selected:
-            self.MsgNoLayerSelected()
-            return
-
-        if UserSettings.Get(group = 'manager', key = 'askOnRemoveLayer', subkey = 'enabled'):
-            layerName = ''
-            for item in self.curr_page.maptree.GetSelections():
-                name = str(self.curr_page.maptree.GetItemText(item))
-                idx = name.find('(opacity')
-                if idx > -1:
-                    layerName += '<' + name[:idx].strip(' ') + '>,\n'
-                else:
-                    layerName += '<' + name + '>,\n'
-            layerName = layerName.rstrip(',\n')
-            
-            if len(layerName) > 2: # <>
-                message = _("Do you want to remove map layer(s)\n%s\n"
-                            "from layer tree?") % layerName
-            else:
-                message = _("Do you want to remove selected map layer(s) "
-                            "from layer tree?")
-
-            dlg = wx.MessageDialog (parent = self, message = message,
-                                    caption = _("Remove map layer"),
-                                    style  =  wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
-
-            if dlg.ShowModal() != wx.ID_YES:
-                dlg.Destroy()
-                return
-            
-            dlg.Destroy()
-
-        for layer in self.curr_page.maptree.GetSelections():
-            if self.curr_page.maptree.GetPyData(layer)[0]['type'] == 'group':
-                self.curr_page.maptree.DeleteChildren(layer)
-            self.curr_page.maptree.Delete(layer)
-        
-    def OnKeyDown(self, event):
-        """!Key pressed"""
-        kc = event.GetKeyCode()
-        
-        if event.ControlDown():
-            if kc == wx.WXK_TAB:
-                # switch layer list / command output
-                if self.notebook.GetSelection() == self.notebook.GetPageIndexByName('layers'):
-                    self.notebook.SetSelectionByName('output')
-                else:
-                    self.notebook.SetSelectionByName('layers')
-        
-        try:
-            ckc = chr(kc)
-        except ValueError:
-            event.Skip()
-            return
-        
-        if event.CtrlDown():
-            if kc == 'R':
-                self.OnAddRaster(None)
-            elif kc == 'V':
-                self.OnAddVector(None)
-        
-        event.Skip()
-
-    def OnCloseWindow(self, event):
-        """!Cleanup when wxGUI is quitted"""
-        if not self.curr_page:
-            self._auimgr.UnInit()
-            self.Destroy()
-            return
-        
-        maptree = self.curr_page.maptree
-        if self.workspaceChanged and \
-                UserSettings.Get(group = 'manager', key = 'askOnQuit', subkey = 'enabled'):
-            if self.workspaceFile:
-                message = _("Do you want to save changes in the workspace?")
-            else:
-                message = _("Do you want to store current settings "
-                            "to workspace file?")
-            
-            # ask user to save current settings
-            if maptree.GetCount() > 0:
-                dlg = wx.MessageDialog(self,
-                                       message = message,
-                                       caption = _("Quit GRASS GUI"),
-                                       style = wx.YES_NO | wx.YES_DEFAULT |
-                                       wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
-                ret = dlg.ShowModal()
-                if ret == wx.ID_YES:
-                    if not self.workspaceFile:
-                        self.OnWorkspaceSaveAs()
-                    else:
-                        self.SaveToWorkspaceFile(self.workspaceFile)
-                elif ret == wx.ID_CANCEL:
-                    event.Veto()
-                    dlg.Destroy()
-                    return
-                dlg.Destroy()
-        
-        # don't ask any more...
-        UserSettings.Set(group = 'manager', key = 'askOnQuit', subkey = 'enabled',
-                         value = False)
-        
-        self.OnDisplayCloseAll()
-        
-        self.gm_cb.DeleteAllPages()
-        
-        self._auimgr.UnInit()
-        self.Destroy()
-        
-    def MsgNoLayerSelected(self):
-        """!Show dialog message 'No layer selected'"""
-        wx.MessageBox(parent = self,
-                      message = _("No map layer selected. Operation cancelled."),
-                      caption = _("Message"),
-                      style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
-    
 class GMApp(wx.App):
     def __init__(self, workspace = None):
         """!Main GUI class.
@@ -1715,27 +71,6 @@
         
         wx.Yield()
         
-        ### TODO: adjust initial window layout if necessary
-        w, h = wx.GetDisplaySize()
-        # only neccessary if one of the windows is falling out of
-        # the current display size
-        
-        # check if settings file exists
-        # if settings file exists, check if we should use the stored settings
-        #     if we should use stored settings, use stored settings
-        #     else use default settings
-        # else if settings file does not exist, use default settings
-        # check if any of the windows is falling out of the current display
-        # if yes, pull it in
-        #   falling out to the right
-        #   x pos = display width - window width
-        #   falling out to the bottom
-        #   y pos = 0
-        # update settings
-        # if settings file exists, update settings but keep settings for
-        # additional map display windows, or update them too
-        # do not erase settings for additional map display windows !
-        
         # create and show main frame
         mainframe = GMFrame(parent = None, id = wx.ID_ANY,
                             workspace = self.workspaceFile)



More information about the grass-commit mailing list