123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- """
- @package lmgr.pyshell
- @brief wxGUI Interactive Python Shell for Layer Manager
- Classes:
- - pyshell::PyShellWindow
- .. todo::
- Run pyshell and evaluate code in a separate instance of python &
- design the widget communicate back and forth with it
- (C) 2011 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- @author Martin Landa <landa.martin gmail.com>
- """
- from __future__ import print_function
- import io
- from contextlib import redirect_stdout
- import sys
- import wx
- from wx.py.shell import Shell as PyShell
- from wx.py.version import VERSION
- import grass.script as grass
- from gui_core.wrap import Button, ClearButton, IsDark
- from gui_core.pystc import SetDarkMode
- from core.globalvar import CheckWxVersion
- class PyShellWindow(wx.Panel):
- """Python Shell Window"""
- def __init__(
- self, parent, giface, id=wx.ID_ANY, simpleEditorHandler=None, **kwargs
- ):
- self.parent = parent
- self.giface = giface
- wx.Panel.__init__(self, parent=parent, id=id, **kwargs)
- self.intro = (
- _("Welcome to wxGUI Interactive Python Shell %s") % VERSION
- + "\n\n"
- + _("Type %s for more GRASS scripting related information.") % '"help(gs)"'
- + "\n"
- + _("Type %s to add raster or vector to the layer tree.")
- % "\"AddLayer('map_name')\""
- + "\n\n"
- )
- shellargs = dict(
- parent=self,
- id=wx.ID_ANY,
- introText=self.intro,
- locals={"gs": grass, "AddLayer": self.AddLayer, "help": self.Help},
- )
- # useStockId (available since wxPython 4.0.2) should be False on macOS
- if sys.platform == "darwin" and CheckWxVersion([4, 0, 2]):
- shellargs["useStockId"] = False
- self.shell = PyShell(**shellargs)
- if IsDark():
- SetDarkMode(self.shell)
- sys.displayhook = self._displayhook
- self.btnClear = ClearButton(self)
- self.btnClear.Bind(wx.EVT_BUTTON, self.OnClear)
- self.btnClear.SetToolTip(_("Delete all text from the shell"))
- self.simpleEditorHandler = simpleEditorHandler
- if simpleEditorHandler:
- self.btnSimpleEditor = Button(self, id=wx.ID_ANY, label=_("Simple &editor"))
- self.btnSimpleEditor.Bind(wx.EVT_BUTTON, simpleEditorHandler)
- self.btnSimpleEditor.SetToolTip(_("Open a simple Python code editor"))
- self._layout()
- def _displayhook(self, value):
- print(value) # do not modify __builtin__._
- def _layout(self):
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(self.shell, proportion=1, flag=wx.EXPAND)
- btnSizer = wx.BoxSizer(wx.HORIZONTAL)
- if self.simpleEditorHandler:
- btnSizer.Add(
- self.btnSimpleEditor,
- proportion=0,
- flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
- border=5,
- )
- btnSizer.AddStretchSpacer()
- btnSizer.Add(self.btnClear, proportion=0, flag=wx.EXPAND, border=5)
- sizer.Add(btnSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
- sizer.Fit(self)
- sizer.SetSizeHints(self)
- self.SetSizer(sizer)
- self.Fit()
- self.SetAutoLayout(True)
- self.Layout()
- def AddLayer(self, name, ltype="auto"):
- """Add selected map to the layer tree
- :param name: name of raster/vector map to be added
- :param type: map type ('raster', 'vector', 'auto' for autodetection)
- """
- fname = None
- if ltype == "raster" or ltype != "vector":
- # check for raster
- fname = grass.find_file(name, element="cell")["fullname"]
- if fname:
- ltype = "raster"
- lcmd = "d.rast"
- if not fname and (ltype == "vector" or ltype != "raster"):
- # if not found check for vector
- fname = grass.find_file(name, element="vector")["fullname"]
- if fname:
- ltype = "vector"
- lcmd = "d.vect"
- if not fname:
- return _("Raster or vector map <%s> not found") % (name)
- self.giface.GetLayerTree().AddLayer(
- ltype=ltype, lname=fname, lchecked=True, lcmd=[lcmd, "map=%s" % fname]
- )
- if ltype == "raster":
- return _("Raster map <%s> added") % fname
- return _("Vector map <%s> added") % fname
- def Help(self, obj):
- """Override help() function
- :param obj object/str: generate the help of the given object
- return str: help str of the given object
- """
- with redirect_stdout(io.StringIO()) as f:
- help(obj)
- return f.getvalue()
- def OnClear(self, event):
- """Delete all text from the shell"""
- self.shell.clear()
- self.shell.showIntro(self.intro)
- self.shell.prompt()
|