Преглед изворни кода

wxGUI: graphical modeler development started

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@41584 15284696-431f-4ddb-bdfa-cd5b030d7da7
Martin Landa пре 15 година
родитељ
комит
1e23e3ea15

+ 2 - 1
gui/wxpython/docs/Makefile

@@ -6,6 +6,7 @@ FILES = wxGUI \
 	wxGUI.Vector_Digitizing_Tool \
 	wxGUI.Vector_Digitizing_Tool \
 	wxGUI.Attribute_Table_Manager \
 	wxGUI.Attribute_Table_Manager \
 	wxGUI.Nviz \
 	wxGUI.Nviz \
-	wxGUI.Icons
+	wxGUI.Icons \
+	wxGUI.Modeler
 
 
 default: $(patsubst %,$(HTMLDIR)/%.html,$(FILES))
 default: $(patsubst %,$(HTMLDIR)/%.html,$(FILES))

+ 11 - 0
gui/wxpython/docs/wxGUI.Modeler.html

@@ -0,0 +1,11 @@
+<h2>DESCRIPTION</h2>
+
+<b>Note:</b> <em>wxGUI Modeler is currently under development. Not
+all functionality is implemented.</em>
+
+<h2>AUTHORS</h2>
+
+Martin Landa, CTU in Prague, Czech Republic
+
+<p>
+<i>$Date$</i>

+ 123 - 0
gui/wxpython/gui_modules/gmodeler.py

@@ -0,0 +1,123 @@
+"""!
+@package gmodeler.py
+
+@brief Graphical modeler to create edit, and manage models
+
+Classes:
+ - ModelFrame
+ - ModelCanvas
+
+(C) 2010 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 os
+
+import globalvar
+if not os.getenv("GRASS_WXBUNDLED"):
+    globalvar.CheckForWx()
+import wx
+import wx.lib.ogl as ogl
+
+import menu
+import menudata
+import toolbars
+
+from grass.script import core as grass
+
+class ModelFrame(wx.Frame):
+    def __init__(self, parent, id = wx.ID_ANY, title = _("Graphical modeler (under development)"), **kwargs):
+        """!Graphical modeler main window
+        
+        @param parent parent window
+        @param id window id
+        @param title window title
+
+        @param kwargs wx.Frames' arguments
+        """
+        self.parent = parent
+        
+        wx.Frame.__init__(self, parent = parent, id = id, title = title, **kwargs)
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
+        
+        self.menubar = menu.Menu(parent = self, data = menudata.ModelerData())
+        self.SetMenuBar(self.menubar)
+        
+        self.toolbar = toolbars.ModelToolbar(parent = self)
+        self.SetToolBar(self.toolbar)
+
+        self.statusbar = self.CreateStatusBar(number = 1)
+        
+        self.canvas = ModelCanvas(self)
+        self.canvas.SetBackgroundColour(wx.WHITE)
+        
+        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+        
+        self._layout()
+        self.SetMinSize((400, 300))
+        
+    def _layout(self):
+        """!Do layout"""
+        sizer = wx.BoxSizer(wx.VERTICAL)
+
+        sizer.Add(item = self.canvas, proportion = 1,
+                  flag = wx.EXPAND)
+        
+        self.SetAutoLayout(True)
+        self.SetSizer(sizer)
+        sizer.Fit(self)
+        
+        self.Layout()
+        
+    def OnCloseWindow(self, event):
+        """!Close window"""
+        self.Destroy()
+
+    def OnModelNew(self, event):
+        """!Create new model"""
+        pass
+
+    def OnModelOpen(self, event):
+        """!Load model from file"""
+        pass
+
+    def OnModelSave(self, event):
+        """!Save model to file"""
+        pass
+
+    def OnModelSaveAs(self, event):
+        """!Create model to file as"""
+        pass
+
+    def OnAddAction(self, event):
+        """!Add action to model"""
+        pass
+
+    def OnHelp(self, event):
+        """!Display manual page"""
+        grass.run_command('g.manual',
+                          entry = 'wxGUI.Modeler')
+        
+class ModelCanvas(ogl.ShapeCanvas):
+    """!Canvas where model is drawn"""
+    def __init__(self, parent):
+        ogl.OGLInitialize()
+        ogl.ShapeCanvas.__init__(self, parent)
+        
+        self.diagram = ogl.Diagram()
+        self.SetDiagram(self.diagram)
+        self.diagram.SetCanvas(self)
+        
+def main():
+    app = wx.PySimpleApp()
+    frame = ModelFrame(parent = None)
+    frame.CenterOnScreen()
+    frame.Show()
+    
+    app.MainLoop()
+    
+if __name__ == "__main__":
+    main()

+ 14 - 1
gui/wxpython/gui_modules/menu.py

@@ -27,7 +27,7 @@ class Menu(wx.MenuBar):
             else:
             else:
                 self._createMenuItem(menu, *eachItem)
                 self._createMenuItem(menu, *eachItem)
         
         
-        self.parent.Bind(wx.EVT_MENU_HIGHLIGHT_ALL, self.parent.OnMenuHighlight)
+        self.parent.Bind(wx.EVT_MENU_HIGHLIGHT_ALL, self.OnMenuHighlight)
         
         
         return menu
         return menu
 
 
@@ -69,3 +69,16 @@ class Menu(wx.MenuBar):
         """
         """
         return self.menucmd
         return self.menucmd
         
         
+    def OnMenuHighlight(self, event):
+        """
+        Default menu help handler
+        """
+         # Show how to get menu item info from this event handler
+        id = event.GetMenuId()
+        item = self.FindItemById(id)
+        if item:
+            text = item.GetText()
+            help = item.GetHelp()
+
+        # but in this case just call Skip so the default is done
+        event.Skip()

+ 41 - 33
gui/wxpython/gui_modules/menudata.py

@@ -4,7 +4,7 @@
 @brief Complex list for menu entries for wxGUI.
 @brief Complex list for menu entries for wxGUI.
 
 
 Classes:
 Classes:
- - Data
+ - MenuData
  - ManagerData
  - ManagerData
  - ModelerData
  - ModelerData
 
 
@@ -44,6 +44,38 @@ class MenuData:
     def __init__(self, filename):
     def __init__(self, filename):
 	self.tree = etree.parse(filename)
 	self.tree = etree.parse(filename)
 
 
+    def _getMenuItem(self, mi):
+        """!Get menu item
+
+        @param mi menu item instance
+        """
+	if mi.tag == 'separator':
+	    return ('', '', '', '', '')
+	elif mi.tag == 'menuitem':
+	    label    = _(mi.find('label').text)
+	    help     = _(mi.find('help').text)
+	    handler  = mi.find('handler').text
+	    gcmd     = mi.find('command')  # optional
+            keywords = mi.find('keywords') # optional
+            shortcut = mi.find('shortcut') # optional
+	    if gcmd != None:
+		gcmd = gcmd.text
+	    else:
+		gcmd = ""
+            if keywords != None:
+                keywords = keywords.text
+            else:
+                keywords = ""
+            if shortcut != None:
+                shortcut = shortcut.text
+            else:
+                shortcut = ""
+	    return (label, help, handler, gcmd, keywords, shortcut)
+	elif mi.tag == 'menu':
+	    return self._getMenu(mi)
+	else:
+	    raise Exception()
+
     def _getMenu(self, m):
     def _getMenu(self, m):
         """!Get menu
         """!Get menu
 
 
@@ -162,38 +194,6 @@ class ManagerData(MenuData):
 	    filename = os.path.join(globalvar.ETCWXDIR, 'xml', 'menudata.xml')
 	    filename = os.path.join(globalvar.ETCWXDIR, 'xml', 'menudata.xml')
         
         
         MenuData.__init__(self, filename)
         MenuData.__init__(self, filename)
-    
-    def _getMenuItem(self, mi):
-        """!Get menu item
-
-        @param mi menu item instance
-        """
-	if mi.tag == 'separator':
-	    return ('', '', '', '', '')
-	elif mi.tag == 'menuitem':
-	    label    = _(mi.find('label').text)
-	    help     = _(mi.find('help').text)
-	    handler  = mi.find('handler').text
-	    gcmd     = mi.find('command')  # optional
-            keywords = mi.find('keywords') # optional
-            shortcut = mi.find('shortcut') # optional
-	    if gcmd != None:
-		gcmd = gcmd.text
-	    else:
-		gcmd = ""
-            if keywords != None:
-                keywords = keywords.text
-            else:
-                keywords = ""
-            if shortcut != None:
-                shortcut = shortcut.text
-            else:
-                shortcut = ""
-	    return (label, help, handler, gcmd, keywords, shortcut)
-	elif mi.tag == 'menu':
-	    return self._getMenu(mi)
-	else:
-	    raise Exception()
         
         
     def GetModules(self):
     def GetModules(self):
         """!Create dictionary of modules used to search module by
         """!Create dictionary of modules used to search module by
@@ -221,6 +221,14 @@ class ManagerData(MenuData):
                 
                 
         return modules
         return modules
 
 
+class ModelerData(MenuData):
+    def __init__(self, filename = None):
+        if not filename:
+            gisbase = os.getenv('GISBASE')
+	    filename = os.path.join(globalvar.ETCWXDIR, 'xml', 'menudata_modeler.xml')
+        
+        MenuData.__init__(self, filename)
+
 if __name__ == "__main__":
 if __name__ == "__main__":
     import sys
     import sys
 
 

+ 38 - 2
gui/wxpython/gui_modules/toolbars.py

@@ -11,6 +11,7 @@ Classes:
  - VDigitToolbar
  - VDigitToolbar
  - ProfileToolbar
  - ProfileToolbar
  - NvizToolbar
  - NvizToolbar
+ - ModelToolbar
 
 
 (C) 2007-2010 by the GRASS Development Team
 (C) 2007-2010 by the GRASS Development Team
 This program is free software under the GNU General Public License
 This program is free software under the GNU General Public License
@@ -35,11 +36,11 @@ import gdialogs
 import vdigit
 import vdigit
 from vdigit import VDigitSettingsDialog as VDigitSettingsDialog
 from vdigit import VDigitSettingsDialog as VDigitSettingsDialog
 from debug import Debug as Debug
 from debug import Debug as Debug
-from icon import Icons as Icons
 from preferences import globalSettings as UserSettings
 from preferences import globalSettings as UserSettings
 
 
 gmpath = os.path.join(globalvar.ETCWXDIR, "icons")
 gmpath = os.path.join(globalvar.ETCWXDIR, "icons")
 sys.path.append(gmpath)
 sys.path.append(gmpath)
+from icon import Icons as Icons
 
 
 class AbstractToolbar(wx.ToolBar):
 class AbstractToolbar(wx.ToolBar):
     """!Abstract toolbar class"""
     """!Abstract toolbar class"""
@@ -1373,5 +1374,40 @@ class NvizToolbar(AbstractToolbar):
         
         
         # disable the toolbar
         # disable the toolbar
         self.parent.RemoveToolbar("nviz")
         self.parent.RemoveToolbar("nviz")
-        
 
 
+class ModelToolbar(AbstractToolbar):
+    """!Graphical modeler toolbar (see gmodeler.py)
+    """
+    def __init__(self, parent):
+        AbstractToolbar.__init__(self, parent)
+        
+        self.InitToolbar(self.ToolbarData())
+        
+        # realize the toolbar
+        self.Realize()
+        
+    def ToolbarData(self):
+        """!Toolbar data"""
+        self.new = wx.NewId()
+        self.open = wx.NewId()
+        self.save = wx.NewId()
+        self.quit = wx.NewId()
+        
+        # tool, label, bitmap, kind, shortHelp, longHelp, handler
+        return (
+            (self.new, 'new', Icons['modelNew'].GetBitmap(),
+             wx.ITEM_NORMAL, Icons['modelNew'].GetLabel(), Icons['modelNew'].GetDesc(),
+             self.parent.OnModelNew),
+            (self.open, 'open', Icons['modelOpen'].GetBitmap(),
+             wx.ITEM_NORMAL, Icons['modelOpen'].GetLabel(), Icons['modelOpen'].GetDesc(),
+             self.parent.OnModelOpen),
+            (self.save, 'save', Icons['modelSave'].GetBitmap(),
+             wx.ITEM_NORMAL, Icons['modelSave'].GetLabel(), Icons['modelSave'].GetDesc(),
+             self.parent.OnModelSave),
+            ('', '', '', '', '', '', ''),
+            (self.quit, 'quit', Icons['quit'].GetBitmap(),
+             wx.ITEM_NORMAL, Icons['quit'].GetLabel(), Icons['quit'].GetDesc(),
+             self.parent.OnCloseWindow),
+            )
+    
+    

+ 4 - 4
gui/wxpython/icons/grass2_icons.py

@@ -63,10 +63,10 @@ IconsGrass2 = {
     "digAdditionalTools" : 'tools.png',
     "digAdditionalTools" : 'tools.png',
     # layer manager
     # layer manager
     "newdisplay" : 'monitor-create.png',
     "newdisplay" : 'monitor-create.png',
-    "workspaceNew" : 'create.png',
-    "workspaceLoad" : 'layer-open.png',
-    "workspaceOpen" : 'open.png',
-    "workspaceSave" : 'save.png',
+    "fileNew"    : 'create.png',
+    "fileLoad"   : 'layer-open.png',
+    "fileOpen"   : 'open.png',
+    "fileSave"   : 'save.png',
     "addrast"    : 'layer-raster-add.png',
     "addrast"    : 'layer-raster-add.png',
     "addrast3d"  : 'layer-raster3d-add.png',
     "addrast3d"  : 'layer-raster3d-add.png',
     "addshaded"  : 'layer-shaded-relief-add.png',
     "addshaded"  : 'layer-shaded-relief-add.png',

+ 4 - 4
gui/wxpython/icons/grass_icons.py

@@ -52,10 +52,10 @@ IconsGrass = {
     "digAdditionalTools" : wx.ART_ERROR, # FIXME
     "digAdditionalTools" : wx.ART_ERROR, # FIXME
     # layer manager
     # layer manager
     "newdisplay" : 'gui-startmon.gif',
     "newdisplay" : 'gui-startmon.gif',
-    "workspaceNew" : 'file-new.gif',
-    "workspaceLoad" : 'file-new.gif', # change the icon if possible
-    "workspaceOpen" : 'file-open.gif',
-    "workspaceSave" : 'file-save.gif',
+    "fileNew"    : 'file-new.gif',
+    "fileLoad"   : 'file-new.gif', # change the icon if possible
+    "fileOpen"   : 'file-open.gif',
+    "fileSave"   : 'file-save.gif',
     "addrast"    : 'element-cell.gif',
     "addrast"    : 'element-cell.gif',
     "addrast3d"  : 'element-grid3.gif',
     "addrast3d"  : 'element-grid3.gif',
     "addvect"    : 'element-vector.gif',
     "addvect"    : 'element-vector.gif',

+ 14 - 9
gui/wxpython/icons/icon.py

@@ -1,4 +1,4 @@
-"""
+"""!
 @package icon
 @package icon
 
 
 @brief Icon themes
 @brief Icon themes
@@ -10,7 +10,7 @@ from icons import Icons as Icons
 Classes:
 Classes:
  - MetaIcon
  - MetaIcon
 
 
-(C) 2007-2008 by the GRASS Development Team
+(C) 2007-2008, 2010 by the GRASS Development Team
 This program is free software under the GNU General Public
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 for details.
@@ -174,18 +174,17 @@ Icons = {
                              label=_("Save display to graphic file")),
                              label=_("Save display to graphic file")),
     "printmap"   : MetaIcon (img=Icons["printmap"],
     "printmap"   : MetaIcon (img=Icons["printmap"],
                              label=_("Print display")),
                              label=_("Print display")),
-    # gis manager
+    # layer manager
     "newdisplay" : MetaIcon (img=Icons["newdisplay"],
     "newdisplay" : MetaIcon (img=Icons["newdisplay"],
                              label=_("Start new display")),
                              label=_("Start new display")),
-    "workspaceNew" : MetaIcon (img=Icons["workspaceNew"],
+    "workspaceNew" : MetaIcon (img=Icons["fileNew"],
                                label=_("Create new workspace file (Ctrl+N)")),
                                label=_("Create new workspace file (Ctrl+N)")),
-    "workspaceLoad" : MetaIcon (img=Icons["workspaceLoad"],
+    "workspaceLoad" : MetaIcon (img=Icons["fileLoad"],
                                 label=_("Load map layers into workspace (Ctrl+L)")),
                                 label=_("Load map layers into workspace (Ctrl+L)")),
-    "workspaceOpen" : MetaIcon (img=Icons["workspaceOpen"],
+    "workspaceOpen" : MetaIcon (img=Icons["fileOpen"],
                                 label=_("Open existing workspace file (Ctrl+O)")),
                                 label=_("Open existing workspace file (Ctrl+O)")),
-    "workspaceSave" : MetaIcon (img=Icons["workspaceSave"],
+    "workspaceSave" : MetaIcon (img=Icons["fileSave"],
                                 label=_("Save current workspace to file (Ctrl+S)")),
                                 label=_("Save current workspace to file (Ctrl+S)")),
-    # TODO: "layer" is not conformant with GRASS vocabulary (vector layer: 1..x) ! 
     "addrast"    : MetaIcon (img=Icons["addrast"],
     "addrast"    : MetaIcon (img=Icons["addrast"],
                              label=_("Add raster map layer (Ctrl+R)")),
                              label=_("Add raster map layer (Ctrl+R)")),
     "addvect"    : MetaIcon (img=Icons["addvect"],
     "addvect"    : MetaIcon (img=Icons["addvect"],
@@ -337,10 +336,16 @@ Icons = {
     "nvizSettings": MetaIcon (img=Icons["nvizSettings"],
     "nvizSettings": MetaIcon (img=Icons["nvizSettings"],
                               label=_("Settings"),
                               label=_("Settings"),
                               desc=_("Show Nviz settings dialog")),
                               desc=_("Show Nviz settings dialog")),
+    # modeler
+    "modelNew" : MetaIcon (img=Icons["fileNew"],
+                           label=_("Create new model (Ctrl+N)")),
+    "modelOpen" : MetaIcon (img=Icons["fileOpen"],
+                                label=_("Load model from file (Ctrl+O)")),
+    "modelSave" : MetaIcon (img=Icons["fileSave"],
+                                label=_("Save current model to file (Ctrl+S)")),
     }
     }
 
 
 # testing ...
 # testing ...
 if __name__ == "__main__":
 if __name__ == "__main__":
     for k, v in Icons.iteritems():
     for k, v in Icons.iteritems():
         print v.GetImageName()
         print v.GetImageName()
-

+ 4 - 4
gui/wxpython/icons/silk_icons.py

@@ -65,10 +65,10 @@ IconsSilk = {
     "digAdditionalTools" : 'plugin.png',
     "digAdditionalTools" : 'plugin.png',
     # layer manager
     # layer manager
     "newdisplay" : 'application_add.png',
     "newdisplay" : 'application_add.png',
-    "workspaceNew" : 'page_white.png',
-    "workspaceLoad" : 'page_white_get.png',
-    "workspaceOpen" : 'folder.png',
-    "workspaceSave" : 'page_save.png',
+    "fileNew"    : 'page_white.png',
+    "fileLoad"   : 'page_white_get.png',
+    "fileOpen"   : 'folder.png',
+    "fileSave"   : 'page_save.png',
     "addrast"    : 'image_add.png',
     "addrast"    : 'image_add.png',
     "addrast3d"  : 'bricks.png',
     "addrast3d"  : 'bricks.png',
     "addshaded"  : 'picture_empty.png',
     "addshaded"  : 'picture_empty.png',

+ 0 - 14
gui/wxpython/wxgui.py

@@ -244,20 +244,6 @@ class GMFrame(wx.Frame):
 
 
         return self.toolbar
         return self.toolbar
 
 
-    def OnMenuHighlight(self, event):
-        """
-        Default menu help handler
-        """
-         # Show how to get menu item info from this event handler
-        id = event.GetMenuId()
-        item = self.GetMenuBar().FindItemById(id)
-        if item:
-            text = item.GetText()
-            help = item.GetHelp()
-
-        # but in this case just call Skip so the default is done
-        event.Skip()
-
     def OnGeorectify(self, event):
     def OnGeorectify(self, event):
         """
         """
         Launch georectifier module
         Launch georectifier module

+ 59 - 0
gui/wxpython/xml/menudata_modeler.xml

@@ -0,0 +1,59 @@
+<menudata>
+  <menubar>
+    <menu>
+      <label>&amp;File</label>
+      <items>
+	<menuitem>
+	  <label>New</label>
+	  <help>Create new model</help>
+	  <handler>OnModelNew</handler>
+	  <shortcut>Ctrl+N</shortcut>
+	</menuitem>
+	<menuitem>
+	  <label>Open</label>
+	  <help>Load model from file</help>
+	  <handler>OnModelOpen</handler>
+	  <shortcut>Ctrl+O</shortcut>
+	</menuitem>
+	<menuitem>
+	  <label>Save</label>
+	  <help>Save model</help>
+	  <handler>OnModelSave</handler>
+	  <shortcut>Ctrl+S</shortcut>
+	</menuitem>
+	<menuitem>
+	  <label>Save as</label>
+	  <help>Save model to file</help>
+	  <handler>OnModelSaveAs</handler>
+	</menuitem>
+	<separator />
+	<menuitem>
+	  <label>Close</label>
+	  <help>Close modeler</help>
+	  <handler>OnCloseWindow</handler>
+	  <shortcut>Ctrl+E</shortcut>
+	</menuitem>
+      </items>
+    </menu>
+    <menu>
+      <label>&amp;Model</label>
+      <items>
+	<menuitem>
+	  <label>Add action</label>
+	  <help>Add action (GRASS module) to model</help>
+	  <handler>OnAddAction</handler>
+	</menuitem>
+      </items>
+    </menu>
+    <menu>
+      <label>&amp;Help</label>
+      <items>
+	<menuitem>
+	  <label>Help</label>
+	  <help>Display the HTML man pages of Graphical modeler</help>
+	  <handler>OnHelp</handler>
+	</menuitem>
+      </items>
+    </menu>
+  </menubar>
+</menudata>