gmodeler.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. """!
  2. @package gmodeler.py
  3. @brief Graphical modeler to create edit, and manage models
  4. Classes:
  5. - ModelFrame
  6. - ModelCanvas
  7. - ModelAction
  8. - ModelSearchDialog
  9. (C) 2010 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. import os
  15. import shlex
  16. import globalvar
  17. if not os.getenv("GRASS_WXBUNDLED"):
  18. globalvar.CheckForWx()
  19. import wx
  20. import wx.lib.ogl as ogl
  21. import menu
  22. import menudata
  23. import toolbars
  24. import menuform
  25. import prompt
  26. from grass.script import core as grass
  27. class ModelFrame(wx.Frame):
  28. def __init__(self, parent, id = wx.ID_ANY, title = _("Graphical modeler (under development)"), **kwargs):
  29. """!Graphical modeler main window
  30. @param parent parent window
  31. @param id window id
  32. @param title window title
  33. @param kwargs wx.Frames' arguments
  34. """
  35. self.parent = parent
  36. self.actions = list() # list of recoreded actions
  37. wx.Frame.__init__(self, parent = parent, id = id, title = title, **kwargs)
  38. self.SetName("Modeler")
  39. self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
  40. self.menubar = menu.Menu(parent = self, data = menudata.ModelerData())
  41. self.SetMenuBar(self.menubar)
  42. self.toolbar = toolbars.ModelToolbar(parent = self)
  43. self.SetToolBar(self.toolbar)
  44. self.statusbar = self.CreateStatusBar(number = 1)
  45. self.canvas = ModelCanvas(self)
  46. self.canvas.SetBackgroundColour(wx.WHITE)
  47. self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
  48. self._layout()
  49. self.SetMinSize((640, 480))
  50. def _layout(self):
  51. """!Do layout"""
  52. sizer = wx.BoxSizer(wx.VERTICAL)
  53. sizer.Add(item = self.canvas, proportion = 1,
  54. flag = wx.EXPAND)
  55. self.SetAutoLayout(True)
  56. self.SetSizer(sizer)
  57. sizer.Fit(self)
  58. self.Layout()
  59. def OnCloseWindow(self, event):
  60. """!Close window"""
  61. self.Destroy()
  62. def OnModelNew(self, event):
  63. """!Create new model"""
  64. pass
  65. def OnModelOpen(self, event):
  66. """!Load model from file"""
  67. pass
  68. def OnModelSave(self, event):
  69. """!Save model to file"""
  70. pass
  71. def OnModelSaveAs(self, event):
  72. """!Create model to file as"""
  73. pass
  74. def OnAddAction(self, event):
  75. """!Add action to model"""
  76. dlg = ModelSearchDialog(self)
  77. dlg.CentreOnParent()
  78. if dlg.ShowModal() == wx.CANCEL:
  79. dlg.Destroy()
  80. return
  81. cmd = dlg.GetCmd()
  82. dlg.Destroy()
  83. action = ModelAction(self, cmd = cmd, x = 100, y = 100)
  84. self.canvas.diagram.AddShape(action)
  85. action.Show(True)
  86. evthandler = ModelEvtHandler(self.statusbar,
  87. self)
  88. evthandler.SetShape(action)
  89. evthandler.SetPreviousHandler(action.GetEventHandler())
  90. action.SetEventHandler(evthandler)
  91. self.actions.append(action)
  92. self.canvas.Refresh()
  93. def OnHelp(self, event):
  94. """!Display manual page"""
  95. grass.run_command('g.manual',
  96. entry = 'wxGUI.Modeler')
  97. class ModelCanvas(ogl.ShapeCanvas):
  98. """!Canvas where model is drawn"""
  99. def __init__(self, parent):
  100. ogl.OGLInitialize()
  101. ogl.ShapeCanvas.__init__(self, parent)
  102. self.diagram = ogl.Diagram()
  103. self.SetDiagram(self.diagram)
  104. self.diagram.SetCanvas(self)
  105. self.SetScrollbars(20, 20, 1000/20, 1000/20)
  106. class ModelAction(ogl.RectangleShape):
  107. """!Action class (GRASS module)"""
  108. def __init__(self, parent, x, y, cmd = None, width = 100, height = 50):
  109. self.parent = parent
  110. ogl.RectangleShape.__init__(self, width, height)
  111. # self.Draggable(True)
  112. self.SetCanvas(self.parent)
  113. self.SetX(x)
  114. self.SetY(y)
  115. self.SetPen(wx.BLACK_PEN)
  116. self.SetBrush(wx.LIGHT_GREY_BRUSH)
  117. if cmd and len(cmd) > 0:
  118. self.AddText(cmd[0])
  119. else:
  120. self.AddText('<<module>>')
  121. class ModelEvtHandler(ogl.ShapeEvtHandler):
  122. """!Model event handler class"""
  123. def __init__(self, log, frame):
  124. ogl.ShapeEvtHandler.__init__(self)
  125. self.log = log
  126. self.frame = frame
  127. def OnLeftClick(self, x, y, keys = 0, attachment = 0):
  128. """!Left mouse button pressed -> update statusbar"""
  129. shape = self.GetShape()
  130. def OnLeftDoubleClick(self, x, y, keys = 0, attachment = 0):
  131. """!Left mouse button pressed (double-click) -> show properties"""
  132. shape = self.GetShape()
  133. module = menuform.GUI()
  134. # module.ParseCommand(['r.buffer'],
  135. # completed = (None , None, None),
  136. # parentframe = self.frame, show = True)
  137. class ModelSearchDialog(wx.Dialog):
  138. def __init__(self, parent, id = wx.ID_ANY, title = _("Find GRASS module"),
  139. style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
  140. """!Graphical modeler module search window
  141. @param parent parent window
  142. @param id window id
  143. @param title window title
  144. @param kwargs wx.Dialogs' arguments
  145. """
  146. self.parent = parent
  147. wx.Dialog.__init__(self, parent = parent, id = id, title = title, **kwargs)
  148. self.SetName("ModelerDialog")
  149. self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
  150. self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
  151. self.searchBy = wx.Choice(parent = self.panel, id = wx.ID_ANY,
  152. choices = [_("description"),
  153. _("keywords")])
  154. self.search = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
  155. value = "", size = (-1, 25))
  156. self.cmd_prompt = prompt.GPromptSTC(parent = self)
  157. self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
  158. self.btnOk = wx.Button(self.panel, wx.ID_OK)
  159. self.btnOk.SetDefault()
  160. self._layout()
  161. def _layout(self):
  162. btnSizer = wx.StdDialogButtonSizer()
  163. btnSizer.AddButton(self.btnCancel)
  164. btnSizer.AddButton(self.btnOk)
  165. btnSizer.Realize()
  166. bodyBox = wx.StaticBox(parent=self.panel, id=wx.ID_ANY,
  167. label=" %s " % _("Find GRASS module"))
  168. bodySizer = wx.StaticBoxSizer(bodyBox, wx.VERTICAL)
  169. searchSizer = wx.BoxSizer(wx.HORIZONTAL)
  170. searchSizer.Add(item = self.searchBy,
  171. proportion = 0, flag = wx.LEFT, border = 3)
  172. searchSizer.Add(item = self.search,
  173. proportion = 1, flag = wx.LEFT | wx.EXPAND, border = 3)
  174. bodySizer.Add(item=searchSizer, proportion=0,
  175. flag=wx.EXPAND | wx.ALL, border=1)
  176. bodySizer.Add(item=self.cmd_prompt, proportion=1,
  177. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=3)
  178. mainSizer = wx.BoxSizer(wx.VERTICAL)
  179. mainSizer.Add(item=bodySizer, proportion=1,
  180. flag=wx.EXPAND | wx.ALL, border=5)
  181. mainSizer.Add(item=btnSizer, proportion=0,
  182. flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
  183. self.panel.SetSizer(mainSizer)
  184. mainSizer.Fit(self.panel)
  185. def GetPanel(self):
  186. """!Get dialog panel"""
  187. return self.panel
  188. def GetCmd(self):
  189. """!Get command"""
  190. line = self.cmd_prompt.GetCurLine()[0].strip()
  191. if len(line) == 0:
  192. list()
  193. try:
  194. cmd = shlex.split(str(line))
  195. except UnicodeError:
  196. cmd = shlex.split(utils.EncodeString((line)))
  197. return cmd
  198. def OnOk(self, event):
  199. self.Close()
  200. def main():
  201. app = wx.PySimpleApp()
  202. frame = ModelFrame(parent = None)
  203. # frame.CentreOnScreen()
  204. frame.Show()
  205. app.MainLoop()
  206. if __name__ == "__main__":
  207. main()