pyshell.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. """
  2. @package lmgr.pyshell
  3. @brief wxGUI Interactive Python Shell for Layer Manager
  4. Classes:
  5. - pyshell::PyShellWindow
  6. .. todo::
  7. Run pyshell and evaluate code in a separate instance of python &
  8. design the widget communicate back and forth with it
  9. (C) 2011 by the GRASS Development Team
  10. This program is free software under the GNU General Public License
  11. (>=v2). Read the file COPYING that comes with GRASS for details.
  12. @author Martin Landa <landa.martin gmail.com>
  13. """
  14. from __future__ import print_function
  15. import sys
  16. import wx
  17. from wx import stc
  18. from wx.py.shell import Shell as PyShell
  19. from wx.py.version import VERSION
  20. import grass.script as grass
  21. from grass.script.utils import try_remove
  22. from gui_core.wrap import Button, ClearButton, IsDark
  23. from gui_core.pystc import SetDarkMode
  24. from core.globalvar import CheckWxVersion
  25. class PyShellWindow(wx.Panel):
  26. """Python Shell Window"""
  27. def __init__(self, parent, giface, id=wx.ID_ANY, simpleEditorHandler=None, **kwargs):
  28. self.parent = parent
  29. self.giface = giface
  30. wx.Panel.__init__(self, parent=parent, id=id, **kwargs)
  31. self.intro = _("Welcome to wxGUI Interactive Python Shell %s") % VERSION + "\n\n" + \
  32. _("Type %s for more GRASS scripting related information.") % "\"help(gs)\"" + "\n" + \
  33. _("Type %s to add raster or vector to the layer tree.") % "\"AddLayer()\"" + "\n\n"
  34. shellargs = dict(
  35. parent=self,
  36. id=wx.ID_ANY,
  37. introText=self.intro,
  38. locals={"gs": grass, "AddLayer": self.AddLayer},
  39. )
  40. # useStockId (available since wxPython 4.0.2) should be False on macOS
  41. if sys.platform == "darwin" and CheckWxVersion([4, 0, 2]):
  42. shellargs["useStockId"] = False
  43. self.shell = PyShell(**shellargs)
  44. if IsDark():
  45. SetDarkMode(self.shell)
  46. sys.displayhook = self._displayhook
  47. self.btnClear = ClearButton(self)
  48. self.btnClear.Bind(wx.EVT_BUTTON, self.OnClear)
  49. self.btnClear.SetToolTip(_("Delete all text from the shell"))
  50. self.simpleEditorHandler = simpleEditorHandler
  51. if simpleEditorHandler:
  52. self.btnSimpleEditor = Button(
  53. self, id=wx.ID_ANY, label=_("Simple &editor"))
  54. self.btnSimpleEditor.Bind(wx.EVT_BUTTON, simpleEditorHandler)
  55. self.btnSimpleEditor.SetToolTip(
  56. _("Open a simple Python code editor"))
  57. self._layout()
  58. def _displayhook(self, value):
  59. print(value) # do not modify __builtin__._
  60. def _layout(self):
  61. sizer = wx.BoxSizer(wx.VERTICAL)
  62. sizer.Add(self.shell, proportion=1,
  63. flag=wx.EXPAND)
  64. btnSizer = wx.BoxSizer(wx.HORIZONTAL)
  65. if self.simpleEditorHandler:
  66. btnSizer.Add(self.btnSimpleEditor, proportion=0,
  67. flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5)
  68. btnSizer.AddStretchSpacer()
  69. btnSizer.Add(self.btnClear, proportion=0,
  70. flag=wx.EXPAND, border=5)
  71. sizer.Add(btnSizer, proportion=0,
  72. flag=wx.ALL | wx.EXPAND, border=5)
  73. sizer.Fit(self)
  74. sizer.SetSizeHints(self)
  75. self.SetSizer(sizer)
  76. self.Fit()
  77. self.SetAutoLayout(True)
  78. self.Layout()
  79. def AddLayer(self, name, ltype='auto'):
  80. """Add selected map to the layer tree
  81. :param name: name of raster/vector map to be added
  82. :param type: map type ('raster', 'vector', 'auto' for autodetection)
  83. """
  84. fname = None
  85. if ltype == 'raster' or ltype != 'vector':
  86. # check for raster
  87. fname = grass.find_file(name, element='cell')['fullname']
  88. if fname:
  89. ltype = 'raster'
  90. lcmd = 'd.rast'
  91. if not fname and (ltype == 'vector' or ltype != 'raster'):
  92. # if not found check for vector
  93. fname = grass.find_file(name, element='vector')['fullname']
  94. if fname:
  95. ltype = 'vector'
  96. lcmd = 'd.vect'
  97. if not fname:
  98. return _("Raster or vector map <%s> not found") % (name)
  99. self.giface.GetLayerTree().AddLayer(ltype=ltype,
  100. lname=fname,
  101. lchecked=True,
  102. lcmd=[lcmd, 'map=%s' % fname])
  103. if ltype == 'raster':
  104. return _('Raster map <%s> added') % fname
  105. return _('Vector map <%s> added') % fname
  106. def OnClear(self, event):
  107. """Delete all text from the shell
  108. """
  109. self.shell.clear()
  110. self.shell.showIntro(self.intro)
  111. self.shell.prompt()