|
@@ -20,14 +20,9 @@ This program is free software under the GNU General Public License
|
|
|
|
|
|
import sys
|
|
|
import os
|
|
|
-import tempfile
|
|
|
import stat
|
|
|
import platform
|
|
|
import re
|
|
|
-try:
|
|
|
- import xml.etree.ElementTree as etree
|
|
|
-except ImportError:
|
|
|
- import elementtree.ElementTree as etree # Python <= 2.4
|
|
|
|
|
|
from core import globalvar
|
|
|
import wx
|
|
@@ -53,7 +48,6 @@ from gui_core.preferences import MapsetAccess, PreferencesDialog
|
|
|
from lmgr.layertree import LayerTree, LMIcons
|
|
|
from lmgr.menudata import LayerManagerMenuData, LayerManagerModuleTree
|
|
|
from gui_core.widgets import GNotebook, FormNotebook
|
|
|
-from core.workspace import ProcessWorkspaceFile, ProcessGrcFile, WriteWorkspaceFile
|
|
|
from core.gconsole import GConsole, EVT_IGNORED_CMD_RUN
|
|
|
from core.giface import Notification
|
|
|
from gui_core.goutput import GConsoleWindow, GC_PROMPT
|
|
@@ -63,6 +57,7 @@ from gui_core.menu import Menu as GMenu
|
|
|
from core.debug import Debug
|
|
|
from lmgr.toolbars import LMWorkspaceToolbar, LMToolsToolbar
|
|
|
from lmgr.toolbars import LMMiscToolbar, LMNvizToolbar, DisplayPanelToolbar
|
|
|
+from lmgr.workspace import WorkspaceManager
|
|
|
from lmgr.pyshell import PyShellWindow
|
|
|
from lmgr.giface import LayerManagerGrassInterface
|
|
|
from datacatalog.catalog import DataCatalog
|
|
@@ -97,14 +92,16 @@ class GMFrame(wx.Frame):
|
|
|
self.displayIndex = 0 # index value for map displays and layer trees
|
|
|
self.currentPage = None # currently selected page for layer tree notebook
|
|
|
self.currentPageNum = None # currently selected page number for layer tree notebook
|
|
|
- self.workspaceFile = workspace # workspace file
|
|
|
- self.workspaceChanged = False # track changes in workspace
|
|
|
- # if we are currently loading workspace to ignore some events
|
|
|
- self.loadingWorkspace = False
|
|
|
self.cwdPath = None # current working directory
|
|
|
|
|
|
wx.Frame.__init__(self, parent=parent, id=id, size=size,
|
|
|
style=style, **kwargs)
|
|
|
+
|
|
|
+ self._giface = LayerManagerGrassInterface(self)
|
|
|
+
|
|
|
+ # workspace manager
|
|
|
+ self.workspace_manager = WorkspaceManager(lmgr=self,
|
|
|
+ giface=self._giface)
|
|
|
self._setTitle()
|
|
|
self.SetName("LayerManager")
|
|
|
|
|
@@ -115,8 +112,6 @@ class GMFrame(wx.Frame):
|
|
|
'grass.ico'),
|
|
|
wx.BITMAP_TYPE_ICO))
|
|
|
|
|
|
- self._giface = LayerManagerGrassInterface(self)
|
|
|
-
|
|
|
menu_errors = []
|
|
|
|
|
|
def add_menu_error(message):
|
|
@@ -218,12 +213,9 @@ class GMFrame(wx.Frame):
|
|
|
self.Show()
|
|
|
|
|
|
# load workspace file if requested
|
|
|
- if self.workspaceFile:
|
|
|
- # load given workspace file
|
|
|
- if self.LoadWorkspaceFile(self.workspaceFile):
|
|
|
+ if workspace:
|
|
|
+ if self.workspace_manager.Load(workspace):
|
|
|
self._setTitle()
|
|
|
- else:
|
|
|
- self.workspaceFile = None
|
|
|
else:
|
|
|
# start default initial display
|
|
|
self.NewDisplay(show=False)
|
|
@@ -239,8 +231,6 @@ class GMFrame(wx.Frame):
|
|
|
# fix goutput's pane size (required for Mac OSX)`
|
|
|
self.goutput.SetSashPosition(int(self.GetSize()[1] * .8))
|
|
|
|
|
|
- self.workspaceChanged = False
|
|
|
-
|
|
|
show_menu_errors(menu_errors)
|
|
|
|
|
|
# start with layer manager on top
|
|
@@ -255,8 +245,8 @@ class GMFrame(wx.Frame):
|
|
|
gisenv = grass.gisenv()
|
|
|
location = gisenv["LOCATION_NAME"]
|
|
|
mapset = gisenv["MAPSET"]
|
|
|
- if self.workspaceFile:
|
|
|
- filename = os.path.splitext(os.path.basename(self.workspaceFile))[0]
|
|
|
+ if self.workspace_manager.workspaceFile:
|
|
|
+ filename = os.path.splitext(os.path.basename(self.workspace_manager.workspaceFile))[0]
|
|
|
self.SetTitle(
|
|
|
"{workspace} - {location}/{mapset} - {program}".format(
|
|
|
location=location,
|
|
@@ -514,14 +504,6 @@ class GMFrame(wx.Frame):
|
|
|
self._auimgr.GetPane(toolbar).Row(1).Position(pos)
|
|
|
self._auimgr.Update()
|
|
|
|
|
|
- def WorkspaceChanged(self):
|
|
|
- """Update window title"""
|
|
|
- if not self.workspaceChanged:
|
|
|
- self.workspaceChanged = True
|
|
|
-
|
|
|
- if self.workspaceFile:
|
|
|
- self._setTitle()
|
|
|
-
|
|
|
def OnLocationWizard(self, event):
|
|
|
"""Launch location wizard"""
|
|
|
gisenv = grass.gisenv()
|
|
@@ -682,7 +664,7 @@ class GMFrame(wx.Frame):
|
|
|
# save changes in the workspace
|
|
|
name = self.notebookLayers.GetPageText(event.GetSelection())
|
|
|
caption = _("Close Map Display {}").format(name)
|
|
|
- if not self.CanClosePage(caption):
|
|
|
+ if not self.workspace_manager.CanClosePage(caption):
|
|
|
event.Veto()
|
|
|
return
|
|
|
|
|
@@ -702,37 +684,6 @@ class GMFrame(wx.Frame):
|
|
|
self.notebookLayers.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING,
|
|
|
self.OnCBPageClosing)
|
|
|
|
|
|
- def CanClosePage(self, caption):
|
|
|
- """Ask if page with map display(s) can be closed
|
|
|
- """
|
|
|
- # save changes in the workspace
|
|
|
- maptree = self.GetLayerTree()
|
|
|
- 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=caption,
|
|
|
- style=wx.YES_NO | wx.YES_DEFAULT |
|
|
|
- wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
|
|
|
- ret = dlg.ShowModal()
|
|
|
- dlg.Destroy()
|
|
|
- if ret == wx.ID_YES:
|
|
|
- if not self.workspaceFile:
|
|
|
- self.OnWorkspaceSaveAs()
|
|
|
- else:
|
|
|
- self.SaveToWorkspaceFile(self.workspaceFile)
|
|
|
- elif ret == wx.ID_CANCEL:
|
|
|
- return False
|
|
|
- return True
|
|
|
-
|
|
|
def _switchPageHandler(self, event, notification):
|
|
|
self._switchPage(notification=notification)
|
|
|
event.Skip()
|
|
@@ -1315,437 +1266,24 @@ class GMFrame(wx.Frame):
|
|
|
menu.Destroy()
|
|
|
|
|
|
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.currentPage:
|
|
|
- self.NewDisplay()
|
|
|
-
|
|
|
- maptrees = [self.notebookLayers.GetPage(i).maptree for i in range(self.notebookLayers.GetPageCount())]
|
|
|
-
|
|
|
- # ask user to save current settings
|
|
|
- if self.workspaceFile and self.workspaceChanged:
|
|
|
- self.OnWorkspaceSave()
|
|
|
- elif self.workspaceFile is None and any(tree.GetCount() for tree in maptrees):
|
|
|
- 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 layers in map displays
|
|
|
- for maptree in maptrees:
|
|
|
- maptree.DeleteAllLayers()
|
|
|
-
|
|
|
- # delete all decorations
|
|
|
- for display in self.GetAllMapDisplays():
|
|
|
- for overlayId in display.decorations.keys():
|
|
|
- display.RemoveOverlay(overlayId)
|
|
|
-
|
|
|
- # no workspace file loaded
|
|
|
- self.workspaceFile = None
|
|
|
- self.workspaceChanged = False
|
|
|
- self._setTitle()
|
|
|
+ """Create new workspace file"""
|
|
|
+ self.workspace_manager.New()
|
|
|
|
|
|
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.loadingWorkspace = True
|
|
|
- self.LoadWorkspaceFile(filename)
|
|
|
- self.loadingWorkspace = False
|
|
|
-
|
|
|
- self.workspaceFile = filename
|
|
|
- self._setTitle()
|
|
|
-
|
|
|
- def _tryToSwitchMapsetFromWorkspaceFile(self, gxwXml):
|
|
|
- returncode, errors = RunCommand('g.mapset',
|
|
|
- dbase=gxwXml.database,
|
|
|
- location=gxwXml.location,
|
|
|
- mapset=gxwXml.mapset,
|
|
|
- getErrorMsg=True,
|
|
|
- )
|
|
|
- if returncode != 0:
|
|
|
- # TODO: use the function from grass.py
|
|
|
- reason = _("Most likely the database, location or mapset"
|
|
|
- " does not exist")
|
|
|
- details = errors
|
|
|
- message = _("Unable to change to location and mapset"
|
|
|
- " specified in the workspace.\n"
|
|
|
- "Reason: {reason}\nDetails: {details}\n\n"
|
|
|
- "Do you want to proceed with opening"
|
|
|
- " the workspace anyway?"
|
|
|
- ).format(**locals())
|
|
|
- dlg = wx.MessageDialog(
|
|
|
- parent=self, message=message, caption=_(
|
|
|
- "Proceed with opening of the workspace?"),
|
|
|
- style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
|
|
|
- dlg.CenterOnParent()
|
|
|
- if dlg.ShowModal() in [wx.ID_NO, wx.ID_CANCEL]:
|
|
|
- return False
|
|
|
- else:
|
|
|
- # TODO: copy from ChangeLocation function
|
|
|
- GMessage(
|
|
|
- parent=self,
|
|
|
- message=_("Current location is <%(loc)s>.\n"
|
|
|
- "Current mapset is <%(mapset)s>.") %
|
|
|
- {'loc': gxwXml.location,
|
|
|
- 'mapset': gxwXml.mapset})
|
|
|
- return True
|
|
|
-
|
|
|
- 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
|
|
|
- """
|
|
|
- # parse workspace file
|
|
|
- try:
|
|
|
- gxwXml = ProcessWorkspaceFile(etree.parse(filename))
|
|
|
- except Exception as e:
|
|
|
- GError(
|
|
|
- parent=self, message=_(
|
|
|
- "Reading workspace file <%s> failed.\n"
|
|
|
- "Invalid file, unable to parse XML document.") %
|
|
|
- filename)
|
|
|
- return False
|
|
|
-
|
|
|
- if gxwXml.database and gxwXml.location and gxwXml.mapset:
|
|
|
- if not self._tryToSwitchMapsetFromWorkspaceFile(gxwXml):
|
|
|
- return False
|
|
|
-
|
|
|
- # the really busy part starts here (mapset change is fast)
|
|
|
- busy = wx.BusyInfo(_("Please wait, loading workspace..."),
|
|
|
- parent=self)
|
|
|
- wx.GetApp().Yield()
|
|
|
-
|
|
|
- #
|
|
|
- # load layer manager window properties
|
|
|
- #
|
|
|
- if UserSettings.Get(group='general', key='workspace', subkey=[
|
|
|
- 'posManager', 'enabled']) is False:
|
|
|
- if gxwXml.layerManager['pos']:
|
|
|
- self.SetPosition(gxwXml.layerManager['pos'])
|
|
|
- if gxwXml.layerManager['size']:
|
|
|
- self.SetSize(gxwXml.layerManager['size'])
|
|
|
- if gxwXml.layerManager['cwd']:
|
|
|
- self.cwdPath = gxwXml.layerManager['cwd']
|
|
|
- if os.path.isdir(self.cwdPath):
|
|
|
- os.chdir(self.cwdPath)
|
|
|
-
|
|
|
- #
|
|
|
- # start map displays first (list of layers can be empty)
|
|
|
- #
|
|
|
- displayId = 0
|
|
|
- mapdisplay = list()
|
|
|
- for display in gxwXml.displays:
|
|
|
- mapdisp = self.NewDisplay(name=display['name'], show=False)
|
|
|
- mapdisplay.append(mapdisp)
|
|
|
- maptree = self.notebookLayers.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 not UserSettings.Get(
|
|
|
- group='general', key='workspace',
|
|
|
- subkey=['posDisplay', 'enabled']):
|
|
|
- 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, b, t = 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'])
|
|
|
- if 'showStatusbar' in display and not display['showStatusbar']:
|
|
|
- mapdisp.statusbarManager.Show(False)
|
|
|
- if 'showToolbars' in display and not display['showToolbars']:
|
|
|
- for toolbar in mapdisp.GetToolbarNames():
|
|
|
- mapdisp.RemoveToolbar(toolbar)
|
|
|
-
|
|
|
- displayId += 1
|
|
|
- mapdisp.Show() # show mapdisplay
|
|
|
- # set render property to False to speed up loading layers
|
|
|
- mapdisp.mapWindowProperties.autoRender = False
|
|
|
-
|
|
|
- maptree = None
|
|
|
- selectList = [] # list of selected layers
|
|
|
- #
|
|
|
- # load list of map layers
|
|
|
- #
|
|
|
- for layer in gxwXml.layers:
|
|
|
- display = layer['display']
|
|
|
- maptree = self.notebookLayers.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'],
|
|
|
- loadWorkspace=True)
|
|
|
-
|
|
|
- if 'selected' in layer:
|
|
|
- selectList.append((maptree, newItem, layer['selected']))
|
|
|
-
|
|
|
- for maptree, layer, selected in selectList:
|
|
|
- if selected:
|
|
|
- if not layer.IsSelected():
|
|
|
- maptree.SelectItem(layer, select=True)
|
|
|
- else:
|
|
|
- maptree.SelectItem(layer, select=False)
|
|
|
-
|
|
|
- del busy
|
|
|
-
|
|
|
- # set render property again when all layers are loaded
|
|
|
- for i, display in enumerate(gxwXml.displays):
|
|
|
- mapdisplay[i].mapWindowProperties.autoRender = display['render']
|
|
|
-
|
|
|
- for overlay in gxwXml.overlays:
|
|
|
- # overlay["cmd"][0] name of command e.g. d.barscale, d.legend
|
|
|
- # overlay["cmd"][1:] parameters and flags
|
|
|
- if overlay['display'] == i:
|
|
|
- if overlay['cmd'][0] == "d.legend.vect":
|
|
|
- mapdisplay[i].AddLegendVect(overlay['cmd'])
|
|
|
- if overlay['cmd'][0] == "d.legend":
|
|
|
- mapdisplay[i].AddLegendRast(overlay['cmd'])
|
|
|
- if overlay['cmd'][0] == "d.barscale":
|
|
|
- mapdisplay[i].AddBarscale(overlay['cmd'])
|
|
|
- if overlay['cmd'][0] == "d.northarrow":
|
|
|
- mapdisplay[i].AddArrow(overlay['cmd'])
|
|
|
- if overlay['cmd'][0] == "d.text":
|
|
|
- mapdisplay[i].AddDtext(overlay['cmd'])
|
|
|
-
|
|
|
- # avoid double-rendering when loading workspace
|
|
|
- # mdisp.MapWindow2D.UpdateMap()
|
|
|
- # nviz
|
|
|
- if gxwXml.displays[i]['viewMode'] == '3d':
|
|
|
- mapdisplay[i].AddNviz()
|
|
|
- self.nviz.UpdateState(view=gxwXml.nviz_state['view'],
|
|
|
- iview=gxwXml.nviz_state['iview'],
|
|
|
- light=gxwXml.nviz_state['light'])
|
|
|
- mapdisplay[i].MapWindow3D.constants = gxwXml.nviz_state['constants']
|
|
|
- for idx, constant in enumerate(mapdisplay[i].MapWindow3D.constants):
|
|
|
- mapdisplay[i].MapWindow3D.AddConstant(constant, i + 1)
|
|
|
- for page in ('view', 'light', 'fringe', 'constant', 'cplane'):
|
|
|
- self.nviz.UpdatePage(page)
|
|
|
- self.nviz.UpdateSettings()
|
|
|
- mapdisplay[i].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.currentPage:
|
|
|
- self.NewDisplay()
|
|
|
-
|
|
|
- busy = wx.BusyInfo(_("Please wait, loading workspace..."),
|
|
|
- parent=self)
|
|
|
- wx.GetApp().Yield()
|
|
|
-
|
|
|
- maptree = None
|
|
|
- for layer in ProcessGrcFile(filename).read(self):
|
|
|
- maptree = self.notebookLayers.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'])
|
|
|
-
|
|
|
- del busy
|
|
|
-
|
|
|
- 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.workspace_manager.Open()
|
|
|
|
|
|
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.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 Exception as e:
|
|
|
- GError(parent=self,
|
|
|
- message=_("Writing current settings to workspace file "
|
|
|
- "failed."))
|
|
|
- return False
|
|
|
-
|
|
|
- try:
|
|
|
- mfile = open(filename, "wb")
|
|
|
- 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()
|
|
|
+ self.workspace_manager.Save()
|
|
|
|
|
|
- return True
|
|
|
+ def OnWorkspaceSaveAs(self, event=None):
|
|
|
+ """Save workspace definition to selected file"""
|
|
|
+ self.workspace_manager.SaveAs()
|
|
|
|
|
|
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.DisplayCloseAll()
|
|
|
- self.workspaceFile = None
|
|
|
- self.workspaceChanged = False
|
|
|
- self._setTitle()
|
|
|
- self.displayIndex = 0
|
|
|
- self.currentPage = None
|
|
|
+ """Close file with workspace definition"""
|
|
|
+ self.workspace_manager.Close()
|
|
|
|
|
|
def OnDisplayClose(self, event=None):
|
|
|
"""Close current map display window
|
|
@@ -1756,7 +1294,7 @@ class GMFrame(wx.Frame):
|
|
|
def OnDisplayCloseAll(self, event):
|
|
|
"""Close all open map display windows (from menu)
|
|
|
"""
|
|
|
- if not self.CanClosePage(caption=_("Close all Map Displays")):
|
|
|
+ if not self.workspace_manager.CanClosePage(caption=_("Close all Map Displays")):
|
|
|
return
|
|
|
self.DisplayCloseAll()
|
|
|
|
|
@@ -2167,7 +1705,7 @@ class GMFrame(wx.Frame):
|
|
|
# moved from mapdisp/frame.py
|
|
|
# TODO: why it is called 3 times when getting focus?
|
|
|
# and one times when loosing focus?
|
|
|
- if self.loadingWorkspace:
|
|
|
+ if self.workspace_manager.loadingWorkspace:
|
|
|
return
|
|
|
pgnum = self.notebookLayers.GetPageIndex(notebookLayerPage)
|
|
|
if pgnum > -1:
|
|
@@ -2565,7 +2103,7 @@ class GMFrame(wx.Frame):
|
|
|
self._auimgr.UnInit()
|
|
|
self.Destroy()
|
|
|
return
|
|
|
- if not self.CanClosePage(caption=_("Quit GRASS GUI")):
|
|
|
+ if not self.workspace_manager.CanClosePage(caption=_("Quit GRASS GUI")):
|
|
|
# when called from menu, it gets CommandEvent and not
|
|
|
# CloseEvent
|
|
|
if hasattr(event, 'Veto'):
|