1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
"""
@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>
"""
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()
|