Changeset 173

Show
Ignore:
Timestamp:
12/31/02 02:48:08 (6 years ago)
Author:
arjanmol
Message:

*** empty log message ***

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gaphor/ChangeLog

    r167 r173  
     12002-12-30  Arjan Molenaar  <arjanmolenaar@hetnet.nl> 
     2 
     3        * gaphor/ui/abstractwindow.py: hide not-relevant items in popup menus. 
     4 
    152002-12-23  Arjan Molenaar  <arjanmolenaar@hetnet.nl> 
    26 
  • trunk/gaphor/TODO

    r165 r173  
    88   like classes and packages. 
    99 
    10 - Overall user interface... I have some vague idea how to set it up, but 
    11   I need someone with a little vision to create me a useable UI. 
    12  
    1310- Exporting diagrams to UML XMI, code, images (SVG/png), etc. 
    1411 
    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... 
    1617 
    1718More specific: 
    18 - Popup menu's: they should be created through an ItemFactory, but what is 
    19   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. 
    2021- Some logic about what classes can be connected to each other should be 
    2122  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... 
    2525- Add features to classes (attribute and operation). 
    26 - Capability architecture 
    27    - Main: elements (factory empty?), Model element 
    28    - Diagram: undo/redo, Model element 
    29    - Popup menu items for DiagramItems (should be hidden if not applicable) 
    30    - add line segment 
    31    - ... 
    32 - Plugin architecture. 
    33 - Text near lines (associations, dependencies, etc.) 
    3426 
  • trunk/gaphor/configure.in

    r154 r173  
    6565AM_CHECK_PYMOD(pygtk, , , AC_MSG_ERROR(not_found_msg)) 
    6666 
    67 AC_MSG_CHECKING(for PyGTK >= 1.99.13
     67AC_MSG_CHECKING(for PyGTK >= 1.99.14
    6868prog=" 
    6969import pygtk 
    7070pygtk.require('2.0') 
    7171import sys, gtk 
    72 minver = (1,99,13
     72minver = (1,99,14
    7373print gtk.pygtk_version, 
    7474if gtk.pygtk_version < minver: 
  • trunk/gaphor/data/Makefile.am

    r154 r173  
    22 
    33pkgdata_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 
    68 
    79EXTRA_DIST = $(pkgdata_DATA) 
  • trunk/gaphor/data/gaphor-diagram-ui.xml

    r167 r173  
    4343    </menu> 
    4444 
    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=""/> 
    5248        <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=""/> 
    5457    </dockitem> 
    55 --> 
    5658 
    5759    <popups> 
    5860        <popup name="DiagramView"> 
    5961            <menuitem name="EditDelete" verb=""/> 
    60             <menuitem name="SnapToGrid" verb=""/> 
     62            <menuitem name="SnapToGrid" verb="" type="toggle"/> 
    6163            <separator/> 
    6264            <menuitem name="CreateAttribute" verb=""/> 
  • trunk/gaphor/data/gaphor-main-ui.xml

    r167 r173  
    7171        <toolitem name="FileSave" verb=""/> 
    7272        <toolitem name="FileSaveAs" verb=""/> 
    73         <separator/> 
    7473    </dockitem> 
    7574 
     
    7877            <menuitem name="OpenModelElement" verb=""/> 
    7978            <menuitem name="RenameModelElement" verb=""/> 
     79            <separator/> 
     80            <menuitem name="CreateDiagram" verb=""/> 
    8081        </popup> 
    8182    </popups> 
  • trunk/gaphor/doc/capabilities.txt

    r152 r173  
    3535  items is likely to change much often. 
    3636 
     37Implementation 
     38~~~~~~~~~~~~~~ 
     39All windows are inherited from AbstractWindow. This class has a set_capability() 
     40method. this method can be used to activate and deactivate capabilities. If 
     41capabilities are (de)activated, all commands within a specific context (such 
     42as 'main' or 'diagram') are verified. If their capabilities are not met, the 
     43command in made insensitive (grayed out). Capabilities are desctibed as simple 
     44text strings, such as 'undo' and 'snap_to_grid'. The capabilities themselves are 
     45set by signal handlers which are attached during the window's construction. 
     46 
  • trunk/gaphor/doc/gaphor.txt

    r6 r173  
    22~~~~~~ 
    33 
    4 GModeler is a UML CASE tool aiming for symplicity. It is written in Python and 
     4Gaphor is a UML CASE tool aiming for symplicity. It is written in Python and 
    55C. The goal is to write as much as possible in Python (easy scriptable for 
    66code generators) and only some elementary parts are written in C (this involves 
  • trunk/gaphor/doc/ui-design.txt

    r147 r173  
    3434                        item (gaphor.diagram.DiagramItem, focused item), 
    3535                        item_list (list of selected DiagramItems) 
     36  etc. 
    3637 
    3738A command should tell in it's info which context should be provided. 
  • trunk/gaphor/gaphor/__init__.py

    r166 r173  
    11__all__ = [ 'UML', 'diagram', 'tree', 'ui', 'storage', 'plugin', 'misc' ] 
    22 
     3# Check for GTK-2.0, since we need it anyway. 
     4import sys, pygtk 
     5if not sys.modules.has_key('gtk'): 
     6    pygtk.require('2.0') 
     7del pygtk 
     8del sys 
     9 
    310from gaphor import Gaphor 
  • trunk/gaphor/gaphor/misc/Files

    r166 r173  
    55signal.py 
    66singleton.py 
     7uniqueid.py 
  • trunk/gaphor/gaphor/ui/Files

    r154 r173  
    44diagramview.py 
    55diagramwindow.py 
     6editorwindow.py 
    67mainwindow.py 
    78namespace.py 
  • trunk/gaphor/gaphor/ui/abstractwindow.py

    r167 r173  
    33from gaphor.misc.signal import Signal 
    44from commandregistry import CommandRegistry 
    5 import bonobo.ui 
     5import gobject, gtk, bonobo.ui 
    66import gaphor.config as config 
    7 import gobject 
    87 
    98class AbstractWindow(object): 
     
    118117 
    119118        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) 
    121121        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) 
    122127 
    123128        window.show_all() 
     
    126131        self.__ui_component = ui_component 
    127132 
    128     def _construct_popup_menu(self, name, event, params): 
     133    def _construct_popup_menu(self, name, element, event, params): 
    129134        self._check_state(AbstractWindow.STATE_ACTIVE) 
     135        context = self.__name + '.popup' 
    130136        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) 
    133138        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') 
    134146        menu = gtk.Menu() 
    135147        # The window takes care of destroying the old menu, if any... 
     
    150162        """Activate or deactivate commands with capabilities.""" 
    151163        if self.__state == AbstractWindow.STATE_ACTIVE: 
    152             com_reg = GaphorResource(CommandRegistry) 
     164            command_registry = GaphorResource(CommandRegistry) 
    153165            self_caps = self.__capabilities 
    154166            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)) 
    157169                for c in caps: 
    158170                    if c not in self_caps: 
  • trunk/gaphor/gaphor/ui/command/Files

    r154 r173  
    33diagram.py 
    44diagramitem.py 
     5diagrampopup.py 
     6editor.py 
    57main.py 
    68mainpopup.py 
  • trunk/gaphor/gaphor/ui/command/commandinfo.py

    r167 r173  
    1313    """ 
    1414    __slots__ = ( 'name', '_label', 'context', '_tip', 
    15                   'sensitive', 'state', 'popup', 'pixtype', 'pixname', 
     15                  'sensitive', 'state', 'subject', 'pixtype', 'pixname', 
    1616                  'accel', 'command_class', 'extra_args' ) 
    1717 
    1818    def __init__(self, name, _label, context, _tip=None, 
    19                  sensitive=None, state=None, popup=None, 
     19                 sensitive=None, state=None, subject=None, 
    2020                 pixtype='stock', pixname=None, accel=None, 
    2121                 command_class=None): 
    2222        """Create a new command info object.""" 
    2323        assert name and name != '' 
    24         assert not popup or issubclass(popup, UML.ModelElement) 
     24        assert not subject or issubclass(subject, UML.ModelElement) 
    2525        assert issubclass(command_class, Command) 
    2626 
     
    3737        else: 
    3838            self.state = state 
    39         #self.sensitive = sensitive 
    40         #self.state = state 
    41         self.popup = popup 
     39        self.subject = subject 
    4240        self.pixtype = pixtype 
    4341        self.pixname = pixname 
  • trunk/gaphor/gaphor/ui/command/diagrampopup.py

    r167 r173  
    88import gaphor.UML as UML 
    99import 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. 
    1014 
    1115class CreateAttributeCommand(Command): 
     
    3034             _tip='Create a new attribute', 
    3135             context='diagram.popup', 
    32              sensitive=('focus',), popup=UML.Classifier
     36             sensitive=('focus',), subject=UML.Class
    3337             command_class=CreateAttributeCommand).register() 
    3438 
     
    5458             _tip='Create a new operation', 
    5559             context='diagram.popup', 
    56              sensitive=('focus',), popup=UML.Classifier
     60             sensitive=('focus',), subject=UML.Class
    5761             command_class=CreateOperationCommand).register() 
    5862 
  • trunk/gaphor/gaphor/ui/command/main.py

    r167 r173  
    177177class CreateDiagramCommand(Command): 
    178178 
     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 
    179186    def execute(self): 
    180187        elemfact = GaphorResource(UML.ElementFactory) 
    181         model = elemfact.lookup(1) # model 
    182188        diagram = elemfact.create(UML.Diagram) 
    183         diagram.namespace = model 
     189        diagram.namespace = self._parent or elemfact.get_model() 
    184190        diagram.name = "New diagram" 
     191        # TODO: make the self._parent node expand 
    185192 
    186193CommandInfo (name='CreateDiagram', _label='_New diagram', pixname='gaphor-diagram', 
  • trunk/gaphor/gaphor/ui/command/mainpopup.py

    r167 r173  
    2727CommandInfo (name='OpenModelElement', _label='_Open', 
    2828             context='main.popup', 
    29              popup=UML.Diagram, 
     29             subject=UML.Diagram, 
    3030             command_class=OpenCommand).register() 
    3131 
     
    5151             command_class=RenameCommand).register() 
    5252 
     53from main import CreateDiagramCommand 
    5354 
     55CommandInfo (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  
    1515 
    1616    def __call__(self, *args): 
    17         print 'CommandExecuter.__call__:', args 
     17        #print 'CommandExecuter.__call__:', args 
    1818        if not self.executing: 
    1919            self.executing = 1 
     
    7272        in a list of (name, type, capabilities). Type if one of 'state' or 
    7373        'sensitive'.""" 
    74         names = list() 
     74        caps = list() 
    7575        for ctx, infos in self.__registry.items(): 
    7676            if ctx.startswith(context): 
    7777                for info in infos: 
    7878                    if info.sensitive: 
    79                         names.append((info.name, 'sensitive', info.sensitive)) 
     79                        caps.append((info.name, 'sensitive', info.sensitive)) 
    8080                    if info.state: 
    81                         names.append((info.name, 'state', info.state)) 
    82         return name
     81                        caps.append((info.name, 'state', info.state)) 
     82        return cap
    8383 
     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         
    8495    def get_verbs(self, context, params): 
    8596        """Create a list of verbs and a list of listeners. 
     
    89100        This method is called by AbstractWindow to initialize the menus.""" 
    90101        verbs = list() 
    91         #listeners = list() 
    92102        for ctx, infos in self.__registry.items(): 
    93103            if ctx.startswith(context): 
     
    96106                        cmd = info.command_class() 
    97107                        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))) 
    103110                    except Exception, e: 
    104111                        print 'No verb created for ' + info.name + ':', e 
    105112                        import traceback 
    106113                        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 
    108137 
    109138# Register the registry as application wide resource. 
  • trunk/gaphor/gaphor/ui/diagramwindow.py

    r167 r173  
    3636            self.__undo_id = dia.canvas.connect('undo', self.__on_diagram_undo) 
    3737            # 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) 
    3939            #dia.canvas.set_property('snap_to_grid', 1) 
    4040            self.__on_diagram_undo(dia.canvas) 
     
    106106        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: 
    107107            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 }) 
    116112            view.stop_emission('event') 
    117113            return True 
     
    130126        self.set_capability('redo', canvas.get_redo_depth() > 0) 
    131127 
    132     def __on_diagram_notify_snap_to_grid(self, canvas): 
     128    def __on_diagram_notify_snap_to_grid(self, canvas, pspec): 
    133129        log.debug('notify:snap_to_grid = %d' % canvas.get_property('snap_to_grid')) 
    134130         
  • trunk/gaphor/gaphor/ui/mainwindow.py

    r167 r173  
    9696            path = model.get_path(element) 
    9797            self._construct_popup_menu(name='NamespaceView', 
     98                                       element=element, 
    9899                                       event=event, 
    99100                                       params={ 'window': self, 
  • trunk/gaphor/po/POTFILES.in

    r154 r173  
    33gaphor/config.py 
    44gaphor/plugin.py 
     5gaphor/storage.py 
    56gaphor/UML/__init__.py 
    67gaphor/UML/enumeration.py 
     
    3031gaphor/ui/diagramview.py 
    3132gaphor/ui/diagramwindow.py 
     33gaphor/ui/editorwindow.py 
    3234gaphor/ui/mainwindow.py 
    3335gaphor/ui/namespace.py 
     
    3739gaphor/ui/command/diagram.py 
    3840gaphor/ui/command/diagramitem.py 
     41gaphor/ui/command/diagrampopup.py 
     42gaphor/ui/command/editor.py 
    3943gaphor/ui/command/main.py 
    4044gaphor/ui/command/mainpopup.py 
     
    4347gaphor/misc/command.py 
    4448gaphor/misc/logger.py 
    45 gaphor/misc/menufactory.py 
    4649gaphor/misc/signal.py 
    4750gaphor/misc/singleton.py 
    48 gaphor/misc/storage.py 
    49 gaphor/misc/storage_libxml2.py 
    50 gaphor/misc/storage_minidom.py