Changeset 173
- Timestamp:
- 12/31/02 02:48:08 (6 years ago)
- Files:
-
- trunk/gaphor/ChangeLog (modified) (1 diff)
- trunk/gaphor/TODO (modified) (1 diff)
- trunk/gaphor/configure.in (modified) (1 diff)
- trunk/gaphor/data/Makefile.am (modified) (1 diff)
- trunk/gaphor/data/gaphor-diagram-ui.xml (modified) (1 diff)
- trunk/gaphor/data/gaphor-main-ui.xml (modified) (2 diffs)
- trunk/gaphor/doc/capabilities.txt (modified) (1 diff)
- trunk/gaphor/doc/gaphor.txt (modified) (1 diff)
- trunk/gaphor/doc/ui-design.txt (modified) (1 diff)
- trunk/gaphor/gaphor/__init__.py (modified) (1 diff)
- trunk/gaphor/gaphor/misc/Files (modified) (1 diff)
- trunk/gaphor/gaphor/ui/Files (modified) (1 diff)
- trunk/gaphor/gaphor/ui/abstractwindow.py (modified) (4 diffs)
- trunk/gaphor/gaphor/ui/command/Files (modified) (1 diff)
- trunk/gaphor/gaphor/ui/command/commandinfo.py (modified) (2 diffs)
- trunk/gaphor/gaphor/ui/command/diagrampopup.py (modified) (3 diffs)
- trunk/gaphor/gaphor/ui/command/main.py (modified) (1 diff)
- trunk/gaphor/gaphor/ui/command/mainpopup.py (modified) (2 diffs)
- trunk/gaphor/gaphor/ui/commandregistry.py (modified) (4 diffs)
- trunk/gaphor/gaphor/ui/diagramwindow.py (modified) (3 diffs)
- trunk/gaphor/gaphor/ui/mainwindow.py (modified) (1 diff)
- trunk/gaphor/po/POTFILES.in (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/gaphor/ChangeLog
r167 r173 1 2002-12-30 Arjan Molenaar <arjanmolenaar@hetnet.nl> 2 3 * gaphor/ui/abstractwindow.py: hide not-relevant items in popup menus. 4 1 5 2002-12-23 Arjan Molenaar <arjanmolenaar@hetnet.nl> 2 6 trunk/gaphor/TODO
r165 r173 8 8 like classes and packages. 9 9 10 - Overall user interface... I have some vague idea how to set it up, but11 I need someone with a little vision to create me a useable UI.12 13 10 - Exporting diagrams to UML XMI, code, images (SVG/png), etc. 14 11 15 - Set up a plugin architecture. 12 - Set up a plugin architecture. Since the internals of gaphor are pretty 13 modular, plugins should not be that hard. 14 15 - Text near lines (associations, dependencies, etc.). Not having this is a 16 show-stopper... 16 17 17 18 More specific: 18 - Popup menu's: they should be created through an ItemFactory, but what is19 the most easy interface for adding those items (esp. for plugins)19 - Popup menu's: partially implemented, items which are not relevant for a 20 specific model element should be hidden. 20 21 - Some logic about what classes can be connected to each other should be 21 22 moved from the DiagramItems to the data elements. 22 - A more pattern driven design (using Factories, Singletons etc.) 23 - creeer een property subject (ro) in DiagramItem. Subjects moeten gezet 24 worden via set_property(). 23 - A more pattern driven design (using Factories, Singletons etc.). We're doing 24 a pretty good job already, though... 25 25 - Add features to classes (attribute and operation). 26 - Capability architecture27 - Main: elements (factory empty?), Model element28 - Diagram: undo/redo, Model element29 - Popup menu items for DiagramItems (should be hidden if not applicable)30 - add line segment31 - ...32 - Plugin architecture.33 - Text near lines (associations, dependencies, etc.)34 26 trunk/gaphor/configure.in
r154 r173 65 65 AM_CHECK_PYMOD(pygtk, , , AC_MSG_ERROR(not_found_msg)) 66 66 67 AC_MSG_CHECKING(for PyGTK >= 1.99.1 3)67 AC_MSG_CHECKING(for PyGTK >= 1.99.14) 68 68 prog=" 69 69 import pygtk 70 70 pygtk.require('2.0') 71 71 import sys, gtk 72 minver = (1,99,1 3)72 minver = (1,99,14) 73 73 print gtk.pygtk_version, 74 74 if gtk.pygtk_version < minver: trunk/gaphor/data/Makefile.am
r154 r173 2 2 3 3 pkgdata_DATA = \ 4 gaphor-ui.xml \ 5 gaphor-diagram-ui.xml 4 gaphor-main-ui.xml \ 5 gaphor-diagram-ui.xml \ 6 gaphor-editor-ui.xml \ 7 gaphor.dtd 6 8 7 9 EXTRA_DIST = $(pkgdata_DATA) trunk/gaphor/data/gaphor-diagram-ui.xml
r167 r173 43 43 </menu> 44 44 45 <!-- 46 <dockitem name="Toolbar" _tip="Main toolbar" behavior="detachable,exclusive"> 47 <toolitem name="FileNew" verb=""/> 48 <toolitem name="FileOpen" verb=""/> 49 <toolitem name="FileSave" verb=""/> 50 <toolitem name="FileSaveAs" verb=""/> 51 45 <dockitem name="Toolbar" _tip="Diagram toolbar" behavior="detachable,exclusive"> 46 <toolitem name="InsertActor" verb=""/> 47 <toolitem name="InsertUseCase" verb=""/> 52 48 <separator/> 53 49 <toolitem name="InsertClass" verb=""/> 50 <toolitem name="InsertPackage" verb=""/> 51 <toolitem name="InsertAssociation" verb=""/> 52 <toolitem name="InsertDependency" verb=""/> 53 <toolitem name="InsertGeneralization" verb=""/> 54 <separator/> 55 <toolitem name="InsertComment" verb=""/> 56 <toolitem name="InsertCommentLine" verb=""/> 54 57 </dockitem> 55 -->56 58 57 59 <popups> 58 60 <popup name="DiagramView"> 59 61 <menuitem name="EditDelete" verb=""/> 60 <menuitem name="SnapToGrid" verb="" />62 <menuitem name="SnapToGrid" verb="" type="toggle"/> 61 63 <separator/> 62 64 <menuitem name="CreateAttribute" verb=""/> trunk/gaphor/data/gaphor-main-ui.xml
r167 r173 71 71 <toolitem name="FileSave" verb=""/> 72 72 <toolitem name="FileSaveAs" verb=""/> 73 <separator/>74 73 </dockitem> 75 74 … … 78 77 <menuitem name="OpenModelElement" verb=""/> 79 78 <menuitem name="RenameModelElement" verb=""/> 79 <separator/> 80 <menuitem name="CreateDiagram" verb=""/> 80 81 </popup> 81 82 </popups> trunk/gaphor/doc/capabilities.txt
r152 r173 35 35 items is likely to change much often. 36 36 37 Implementation 38 ~~~~~~~~~~~~~~ 39 All windows are inherited from AbstractWindow. This class has a set_capability() 40 method. this method can be used to activate and deactivate capabilities. If 41 capabilities are (de)activated, all commands within a specific context (such 42 as 'main' or 'diagram') are verified. If their capabilities are not met, the 43 command in made insensitive (grayed out). Capabilities are desctibed as simple 44 text strings, such as 'undo' and 'snap_to_grid'. The capabilities themselves are 45 set by signal handlers which are attached during the window's construction. 46 trunk/gaphor/doc/gaphor.txt
r6 r173 2 2 ~~~~~~ 3 3 4 G Modeler is a UML CASE tool aiming for symplicity. It is written in Python and4 Gaphor is a UML CASE tool aiming for symplicity. It is written in Python and 5 5 C. The goal is to write as much as possible in Python (easy scriptable for 6 6 code generators) and only some elementary parts are written in C (this involves trunk/gaphor/doc/ui-design.txt
r147 r173 34 34 item (gaphor.diagram.DiagramItem, focused item), 35 35 item_list (list of selected DiagramItems) 36 etc. 36 37 37 38 A command should tell in it's info which context should be provided. trunk/gaphor/gaphor/__init__.py
r166 r173 1 1 __all__ = [ 'UML', 'diagram', 'tree', 'ui', 'storage', 'plugin', 'misc' ] 2 2 3 # Check for GTK-2.0, since we need it anyway. 4 import sys, pygtk 5 if not sys.modules.has_key('gtk'): 6 pygtk.require('2.0') 7 del pygtk 8 del sys 9 3 10 from gaphor import Gaphor trunk/gaphor/gaphor/misc/Files
r166 r173 5 5 signal.py 6 6 singleton.py 7 uniqueid.py trunk/gaphor/gaphor/ui/Files
r154 r173 4 4 diagramview.py 5 5 diagramwindow.py 6 editorwindow.py 6 7 mainwindow.py 7 8 namespace.py trunk/gaphor/gaphor/ui/abstractwindow.py
r167 r173 3 3 from gaphor.misc.signal import Signal 4 4 from commandregistry import CommandRegistry 5 import bonobo.ui5 import gobject, gtk, bonobo.ui 6 6 import gaphor.config as config 7 import gobject8 7 9 8 class AbstractWindow(object): … … 118 117 119 118 ui_component.set_translate ('/', command_registry.get_command_xml(context=name + '.')) 120 verbs = command_registry.get_verbs(context=name + '.menu', params=params) 119 verbs = command_registry.get_verbs(context=name + '.menu', 120 params=params) 121 121 ui_component.add_verb_list (verbs, None) 122 123 listeners = command_registry.get_listeners(context=name + '.menu', 124 params=params) 125 for n, c in listeners: 126 ui_component.add_listener(n, c) 122 127 123 128 window.show_all() … … 126 131 self.__ui_component = ui_component 127 132 128 def _construct_popup_menu(self, name, e vent, params):133 def _construct_popup_menu(self, name, element, event, params): 129 134 self._check_state(AbstractWindow.STATE_ACTIVE) 135 context = self.__name + '.popup' 130 136 command_registry = GaphorResource(CommandRegistry) 131 verbs = command_registry.get_verbs(name=self.__name + '.popup', 132 params=params) 137 verbs = command_registry.get_verbs(context, params) 133 138 self.__ui_component.add_verb_list (verbs, None) 139 140 for cmd, klass in command_registry.get_subjects(context): 141 log.debug ('%s: %s' % (cmd, klass)) 142 self.__ui_component.set_prop('/commands/' + cmd, 143 'hidden', 144 isinstance (element, klass) and '0' or '1') 145 log.debug ('done') 134 146 menu = gtk.Menu() 135 147 # The window takes care of destroying the old menu, if any... … … 150 162 """Activate or deactivate commands with capabilities.""" 151 163 if self.__state == AbstractWindow.STATE_ACTIVE: 152 com _reg= GaphorResource(CommandRegistry)164 command_registry = GaphorResource(CommandRegistry) 153 165 self_caps = self.__capabilities 154 166 log.debug('Capabilities are %s' % self_caps) 155 for name, type, caps in com _reg.get_capabilities(self.__name + '.'):156 log.debug('Checking caps for %s %s' % (name, caps))167 for name, type, caps in command_registry.get_capabilities(self.__name + '.'): 168 #log.debug('Checking caps for %s %s' % (name, caps)) 157 169 for c in caps: 158 170 if c not in self_caps: trunk/gaphor/gaphor/ui/command/Files
r154 r173 3 3 diagram.py 4 4 diagramitem.py 5 diagrampopup.py 6 editor.py 5 7 main.py 6 8 mainpopup.py trunk/gaphor/gaphor/ui/command/commandinfo.py
r167 r173 13 13 """ 14 14 __slots__ = ( 'name', '_label', 'context', '_tip', 15 'sensitive', 'state', ' popup', 'pixtype', 'pixname',15 'sensitive', 'state', 'subject', 'pixtype', 'pixname', 16 16 'accel', 'command_class', 'extra_args' ) 17 17 18 18 def __init__(self, name, _label, context, _tip=None, 19 sensitive=None, state=None, popup=None,19 sensitive=None, state=None, subject=None, 20 20 pixtype='stock', pixname=None, accel=None, 21 21 command_class=None): 22 22 """Create a new command info object.""" 23 23 assert name and name != '' 24 assert not popup or issubclass(popup, UML.ModelElement)24 assert not subject or issubclass(subject, UML.ModelElement) 25 25 assert issubclass(command_class, Command) 26 26 … … 37 37 else: 38 38 self.state = state 39 #self.sensitive = sensitive 40 #self.state = state 41 self.popup = popup 39 self.subject = subject 42 40 self.pixtype = pixtype 43 41 self.pixname = pixname trunk/gaphor/gaphor/ui/command/diagrampopup.py
r167 r173 8 8 import gaphor.UML as UML 9 9 import diacanvas 10 11 # NOTE: attributes and operations can now only be created on classes, 12 # actors and uuse-cases are also classifiers, but we can't add 13 # attrs and opers via the UI right now. 10 14 11 15 class CreateAttributeCommand(Command): … … 30 34 _tip='Create a new attribute', 31 35 context='diagram.popup', 32 sensitive=('focus',), popup=UML.Classifier,36 sensitive=('focus',), subject=UML.Class, 33 37 command_class=CreateAttributeCommand).register() 34 38 … … 54 58 _tip='Create a new operation', 55 59 context='diagram.popup', 56 sensitive=('focus',), popup=UML.Classifier,60 sensitive=('focus',), subject=UML.Class, 57 61 command_class=CreateOperationCommand).register() 58 62 trunk/gaphor/gaphor/ui/command/main.py
r167 r173 177 177 class CreateDiagramCommand(Command): 178 178 179 def set_parameters(self, params): 180 if params.has_key('element'): 181 # in a popup menu 182 self._parent = params['element'] 183 else: 184 self._parent = None 185 179 186 def execute(self): 180 187 elemfact = GaphorResource(UML.ElementFactory) 181 model = elemfact.lookup(1) # model182 188 diagram = elemfact.create(UML.Diagram) 183 diagram.namespace = model189 diagram.namespace = self._parent or elemfact.get_model() 184 190 diagram.name = "New diagram" 191 # TODO: make the self._parent node expand 185 192 186 193 CommandInfo (name='CreateDiagram', _label='_New diagram', pixname='gaphor-diagram', trunk/gaphor/gaphor/ui/command/mainpopup.py
r167 r173 27 27 CommandInfo (name='OpenModelElement', _label='_Open', 28 28 context='main.popup', 29 popup=UML.Diagram,29 subject=UML.Diagram, 30 30 command_class=OpenCommand).register() 31 31 … … 51 51 command_class=RenameCommand).register() 52 52 53 from main import CreateDiagramCommand 53 54 55 CommandInfo (name='CreateDiagram', _label='_New diagram', pixname='gaphor-diagram', 56 _tip='Create a new diagram at toplevel', 57 context='main.popup', 58 command_class=CreateDiagramCommand).register() 59 60 trunk/gaphor/gaphor/ui/commandregistry.py
r167 r173 15 15 16 16 def __call__(self, *args): 17 print 'CommandExecuter.__call__:', args17 #print 'CommandExecuter.__call__:', args 18 18 if not self.executing: 19 19 self.executing = 1 … … 72 72 in a list of (name, type, capabilities). Type if one of 'state' or 73 73 'sensitive'.""" 74 names = list()74 caps = list() 75 75 for ctx, infos in self.__registry.items(): 76 76 if ctx.startswith(context): 77 77 for info in infos: 78 78 if info.sensitive: 79 names.append((info.name, 'sensitive', info.sensitive))79 caps.append((info.name, 'sensitive', info.sensitive)) 80 80 if info.state: 81 names.append((info.name, 'state', info.state))82 return names81 caps.append((info.name, 'state', info.state)) 82 return caps 83 83 84 def get_subjects(self, context): 85 """Get a list of (name, element) tuples for all commands within 86 the context.""" 87 subjects = list() 88 for ctx, infos in self.__registry.items(): 89 if ctx.startswith(context): 90 for info in infos: 91 if info.subject: 92 subjects.append((info.name, info.subject)) 93 return subjects 94 84 95 def get_verbs(self, context, params): 85 96 """Create a list of verbs and a list of listeners. … … 89 100 This method is called by AbstractWindow to initialize the menus.""" 90 101 verbs = list() 91 #listeners = list()92 102 for ctx, infos in self.__registry.items(): 93 103 if ctx.startswith(context): … … 96 106 cmd = info.command_class() 97 107 cmd.set_parameters(params) 98 verbs.append((info.name, _CommandExecuter(cmd))) 99 #if info.state: 100 # listeners.append(v) 101 #else: 102 # verbs.append(v) 108 if not info.state: 109 verbs.append((info.name, _CommandExecuter(cmd))) 103 110 except Exception, e: 104 111 print 'No verb created for ' + info.name + ':', e 105 112 import traceback 106 113 traceback.print_exc() 107 return verbs # , listeners 114 return verbs 115 116 def get_listeners(self, context, params): 117 """Create a list of verbs and a list of listeners. 118 Verbs are used for normal menu items. Listeners for statefull menu 119 items. A dictionary of parameters can be supplied to the command 120 for instantiation. 121 This method is called by AbstractWindow to initialize the menus.""" 122 #verbs = list() 123 listeners = list() 124 for ctx, infos in self.__registry.items(): 125 if ctx.startswith(context): 126 for info in infos: 127 try: 128 cmd = info.command_class() 129 cmd.set_parameters(params) 130 if info.state: 131 listeners.append((info.name, _CommandExecuter(cmd))) 132 except Exception, e: 133 print 'No verb created for ' + info.name + ':', e 134 import traceback 135 traceback.print_exc() 136 return listeners 108 137 109 138 # Register the registry as application wide resource. trunk/gaphor/gaphor/ui/diagramwindow.py
r167 r173 36 36 self.__undo_id = dia.canvas.connect('undo', self.__on_diagram_undo) 37 37 # Why doesn't this property react? 38 self.__snap_to_grid_id = dia.canvas.connect('notify::snap _to_grid', self.__on_diagram_notify_snap_to_grid)38 self.__snap_to_grid_id = dia.canvas.connect('notify::snap-to-grid', self.__on_diagram_notify_snap_to_grid) 39 39 #dia.canvas.set_property('snap_to_grid', 1) 40 40 self.__on_diagram_undo(dia.canvas) … … 106 106 if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: 107 107 view.canvas.push_undo(None) 108 cmd_reg = GaphorResource('CommandRegistry') 109 verbs = cmd_reg.get_verbs(context='diagram.popup', 110 params={ 'window': self }) 111 self.get_ui_component().add_verb_list (verbs, None) 112 menu = gtk.Menu() 113 # The window takes care of destroying the old menu, if any... 114 self.get_window().add_popup(menu, '/popups/DiagramView') 115 menu.popup(None, None, None, event.button, 0) 108 self._construct_popup_menu(name='DiagramView', 109 element=view.focus_item and view.focus_item.item.subject or None, 110 event=event, 111 params={ 'window': self }) 116 112 view.stop_emission('event') 117 113 return True … … 130 126 self.set_capability('redo', canvas.get_redo_depth() > 0) 131 127 132 def __on_diagram_notify_snap_to_grid(self, canvas ):128 def __on_diagram_notify_snap_to_grid(self, canvas, pspec): 133 129 log.debug('notify:snap_to_grid = %d' % canvas.get_property('snap_to_grid')) 134 130 trunk/gaphor/gaphor/ui/mainwindow.py
r167 r173 96 96 path = model.get_path(element) 97 97 self._construct_popup_menu(name='NamespaceView', 98 element=element, 98 99 event=event, 99 100 params={ 'window': self, trunk/gaphor/po/POTFILES.in
r154 r173 3 3 gaphor/config.py 4 4 gaphor/plugin.py 5 gaphor/storage.py 5 6 gaphor/UML/__init__.py 6 7 gaphor/UML/enumeration.py … … 30 31 gaphor/ui/diagramview.py 31 32 gaphor/ui/diagramwindow.py 33 gaphor/ui/editorwindow.py 32 34 gaphor/ui/mainwindow.py 33 35 gaphor/ui/namespace.py … … 37 39 gaphor/ui/command/diagram.py 38 40 gaphor/ui/command/diagramitem.py 41 gaphor/ui/command/diagrampopup.py 42 gaphor/ui/command/editor.py 39 43 gaphor/ui/command/main.py 40 44 gaphor/ui/command/mainpopup.py … … 43 47 gaphor/misc/command.py 44 48 gaphor/misc/logger.py 45 gaphor/misc/menufactory.py46 49 gaphor/misc/signal.py 47 50 gaphor/misc/singleton.py 48 gaphor/misc/storage.py49 gaphor/misc/storage_libxml2.py50 gaphor/misc/storage_minidom.py
