Changeset 365
- Timestamp:
- 06/26/04 11:12:59 (4 years ago)
- Files:
-
- trunk/gaphor/ChangeLog (modified) (1 diff)
- trunk/gaphor/TODO (modified) (2 diffs)
- trunk/gaphor/data/plugins/checkmetamodel/__init__.py (modified) (1 diff)
- trunk/gaphor/data/plugins/checkmetamodel/checkmodel.py (added)
- trunk/gaphor/data/plugins/checkmetamodel/checkmodelgui.py (added)
- trunk/gaphor/data/plugins/checkmetamodel/plugin.xml (modified) (3 diffs)
- trunk/gaphor/doc/plugins.txt (modified) (1 diff)
- trunk/gaphor/gaphor/UML/uml2.gaphor (modified) (21 diffs)
- trunk/gaphor/gaphor/UML/uml2.override (modified) (1 diff)
- trunk/gaphor/gaphor/__init__.py (modified) (1 diff)
- trunk/gaphor/gaphor/diagram/interface.py (modified) (6 diffs)
- trunk/gaphor/gaphor/diagram/klass.py (modified) (2 diffs)
- trunk/gaphor/gaphor/plugin.py (modified) (1 diff)
- trunk/gaphor/gaphor/pluginmanager.py (modified) (11 diffs)
- trunk/gaphor/gaphor/ui/__init__.py (modified) (1 diff)
- trunk/gaphor/gaphor/ui/diagramtab.py (modified) (2 diffs)
- trunk/gaphor/gaphor/ui/mainactions.py (modified) (3 diffs)
- trunk/gaphor/gaphor/ui/mainwindow.py (modified) (9 diffs)
- trunk/gaphor/gaphor/ui/menufactory.py (modified) (2 diffs)
- trunk/gaphor/gaphor/ui/toolbox.py (added)
- trunk/gaphor/setup.py (modified) (1 diff)
- trunk/gaphor/tests/test-wrapbox.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/gaphor/ChangeLog
r364 r365 1 2004-06-23 Arjan Molenaar <arjanmolenaar@hetnet.nl> 2 3 * gaphor/ui/mainwindow.py, gaphor/ui/toolbox.py: explicitly import 4 actions. 5 * doc/plugin.txt: explenation how plugins work 6 * setup.py: Boost version to 0.5.0. 7 1 8 2004-06-22 Arjan Molenaar <arjanmolenaar@hetnet.nl> 2 9 trunk/gaphor/TODO
r363 r365 26 26 # not differ. 27 27 28 - Exporting diagrams to UML XMI, code, images (SVG/png), etc. 28 - Exporting diagrams to UML XMI, code, images (SVG/png), etc. - make a plugin! 29 29 30 30 #- Set up a plugin architecture. Since the internals of gaphor are pretty … … 74 74 - Profiles are reusable and its common to share them with different models. 75 75 - Stereotypes can only be owned by Profiles, not by (normal) Packages. 76 - I think having associations in this one is not very useful, though.77 76 - We have to do a lookup if a MetaClass is actually part of the model. 78 77 - a stereotype can contain an image, that can be used in stead of its name 79 - Profiles should be saved with the model too. 78 - Profiles should be saved with the model too. And iit should be possible to 79 "update" a profile within a model. 80 80 81 81 Maybe it would be nice to create Stereotypes without creating the diagrams. trunk/gaphor/data/plugins/checkmetamodel/__init__.py
r363 r365 1 1 # vim:sw=4:et 2 2 3 print 'plugin',__file__4 5 3 import gaphor.plugin 4 from checkmodelgui import CheckModelWindow 5 from checkmodel import check_associations, check_attributes 6 6 7 7 class CheckMetamodelAction(gaphor.plugin.Action): 8 8 9 def init(self, window):10 self._window = window11 12 9 def execute(self): 13 print 'UMLSanityCheck' 14 10 print 'CheckMetamodelAction' 11 # TODO: override checkmodel.report 12 cw = CheckModelWindow() 13 cw.construct() 14 self.window.add_transient_window(cw) 15 cw.run() trunk/gaphor/data/plugins/checkmetamodel/plugin.xml
r363 r365 5 5 version="0.1" 6 6 author="Arjan Molenaar"> 7 <description> 8 This plugin provides a means to check the consistency of an UML model. The 9 rules have been optimized to work with the data model (gaphor/UML/uml2.gaphor), 10 so their might not be much use, except for hackers. 11 12 Also this plugin is a template for future plugins. 13 </description> 14 7 15 <require> 8 16 <!-- … … 14 22 --> 15 23 </require> 24 16 25 <provide> 17 26 <!-- … … 20 29 <action id="CheckMetamodel" 21 30 label="Check UML metamodel" 22 icon-file="uml.png"23 31 tooltip="Check the UML meta model for errors" 24 32 class="CheckMetamodelAction" slot="WindowSlot"> trunk/gaphor/doc/plugins.txt
r364 r365 14 14 removal. 15 15 16 A typical plugin.xml file looks like this: 17 18 <?xml version="1.0"?> 19 <plugin name="UML metamodel sanity check" 20 version="0.1" 21 author="Arjan Molenaar"> 22 <description> 23 A description of what this thing does. 24 </description> 25 26 <require> 27 <!-- 28 Define modules and plugins that are needed for this plugin to function 29 properly. 30 --> 31 <module name="os.path"/> 32 <plugin name="anotherPlugin"/> 33 </require> 34 35 <provide> 36 <!-- 37 Actions should be defined on the module's toplevel (like in __init__.py). 38 --> 39 <action id="MyPlugin" 40 label="Do a typical thing with the plugin" 41 icon-file="myicon.png" 42 tooltip="bla bla" 43 class="MyPluginAction" slot="WindowSlot"> 44 <!-- 45 Add optional dependencies to this action. The action is then updated 46 when actions defined in the depends tag are executed. 47 --> 48 <depends action="ItemFocus"/> 49 </action> 50 </provide> 51 </plugin> 52 53 54 A plugin contains three sections: 55 description 56 A description of the plugin (could be shown in a plugin browser for example) 57 This is just a text field. 58 require 59 Prerequisits for this plugin (such as exptic modules and other plugins) 60 provide 61 Actions that are provided by this plugin 62 63 The require section can contain modules and plugins that are needed for this plugin 64 to work. 65 66 The <provide> section contains the actions that can be added to the application. 67 An action is a Python class that extends gaphor.plugin.Action (or CheckAction for 68 checkbox actions or RadioAction for radiobutton actions). An action has an 69 id 70 Id is a unique identifier for the action 71 label 72 A label that is shown in the menu 73 tooltip 74 some extra information 75 icon-file 76 A file containing a nice (24x24) image, preferbly a PNG image. 77 class 78 The Action class to load from the module. The Action class should be 79 visible through __init__.py (class names like 'test.TestAction' do not 80 work) 81 slot 82 Slots are predefined places in a menu where new actions can be added. 83 84 Slots 85 ----- 86 Currently the following slots are defined: 87 88 Main window 89 90 main menu: 91 slot name menu comment 92 FileOpenSlot File after the 'Open' item 93 FileSaveSlot File after the 'Save' item 94 FileExportSlot File/Export 95 FileSlot File After the 'Close' item 96 EditSlot Edit 97 DiagramSlot Diagram 98 WindowSlot Window 99 HelpSlot Help 100 101 Items in a diagram can have additional actions too: 102 103 item: slot name: 104 Class ClassPopupSlot 105 106 More slots are likely to be defined in the future. 107 trunk/gaphor/gaphor/UML/uml2.gaphor
r356 r365 1 1 <?xml version="1.0"?> 2 <gaphor version="3.0" gaphor_version="0. 4.0"><Association id="DCE:12A2B620-4B3C-11D7-B391-02BBFE4396CE"><memberEnd><reflist><ref refid="DCE:12A3CA4C-4B3C-11D7-B391-02BBFE4396CE"/><ref refid="DCE:12A397CC-4B3C-11D7-B391-02BBFE4396CE"/></reflist></memberEnd><ownedEnd><reflist><ref refid="DCE:12A397CC-4B3C-11D7-B391-02BBFE4396CE"/></reflist></ownedEnd><package><ref refid="DCE:E085A412-45CE-11D7-B5CA-613352B2821F"/></package>2 <gaphor version="3.0" gaphor_version="0.5.0"><Association id="DCE:12A2B620-4B3C-11D7-B391-02BBFE4396CE"><memberEnd><reflist><ref refid="DCE:12A3CA4C-4B3C-11D7-B391-02BBFE4396CE"/><ref refid="DCE:12A397CC-4B3C-11D7-B391-02BBFE4396CE"/></reflist></memberEnd><ownedEnd><reflist><ref refid="DCE:12A397CC-4B3C-11D7-B391-02BBFE4396CE"/></reflist></ownedEnd><package><ref refid="DCE:E085A412-45CE-11D7-B5CA-613352B2821F"/></package> 3 3 <presentation><reflist><ref refid="DCE:110D08A6-4B3C-11D7-B391-02BBFE4396CE"/></reflist></presentation></Association><LiteralSpecification id="DCE:68F38E44-A419-11D8-B4C8-00061BC22919"></LiteralSpecification><Generalization id="DCE:84C5B02A-464D-11D7-AA08-1B85D5275D8A"><general><ref refid="DCE:FF594BE0-464C-11D7-AA08-1B85D5275D8A"/></general> 4 4 <presentation><reflist><ref refid="DCE:8360FB04-464D-11D7-AA08-1B85D5275D8A"/></reflist></presentation><specific><ref refid="DCE:7D753EF0-464D-11D7-AA08-1B85D5275D8A"/></specific> … … 267 267 <orthogonal><val>0</val></orthogonal> 268 268 <horizontal><val>1</val></horizontal> 269 <points><val>[(8.4073254559594 375, 5.135696545495648), (62.0, 6.0)]</val></points>269 <points><val>[(8.4073254559594659, 5.135696545495648), (62.0, 6.0)]</val></points> 270 270 <head_connection><ref refid="DCE:5138249A-863A-11D7-8239-5A25B8C2F569"/></head_connection> 271 271 <tail_connection><ref refid="DCE:91252432-863B-11D7-8239-5A25B8C2F569"/></tail_connection> … … 680 680 <grid_ofs_x><val>0.0</val></grid_ofs_x> 681 681 <grid_ofs_y><val>0.0</val></grid_ofs_y> 682 <grid_color><val> 33023</val></grid_color>682 <grid_color><val>255</val></grid_color> 683 683 <grid_bg><val>4294967295</val></grid_bg> 684 684 <root_affine><val>(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)</val></root_affine> … … 792 792 <orthogonal><val>0</val></orthogonal> 793 793 <horizontal><val>1</val></horizontal> 794 <points><val>[(-21.0, -1.0), (-80.41605839416053, 87.0 )]</val></points>794 <points><val>[(-21.0, -1.0), (-80.41605839416053, 87.000000000000057)]</val></points> 795 795 <head_connection><ref refid="DCE:2DF0AAAC-8404-11D8-82A2-7B88E55A3BEC"/></head_connection> 796 796 <tail_connection><ref refid="DCE:96EB8F86-8404-11D8-82A2-7B88E55A3BEC"/></tail_connection> … … 971 971 <presentation><reflist><ref refid="DCE:98E2A71C-6690-11D7-A84E-6C8643AD0CA4"/><ref refid="DCE:726CA564-8402-11D8-82A2-7B88E55A3BEC"/><ref refid="DCE:CAD809C6-4B33-11D7-B391-02BBFE4396CE"/><ref refid="DCE:7D1DB338-4B37-11D7-B391-02BBFE4396CE"/><ref refid="DCE:20C7308A-8323-11D8-8D1E-00C00C03A405"/></reflist></presentation></Class><Property id="DCE:DAE8A050-97BB-11D8-9E3B-00C00C03A405"><aggregation><val><![CDATA[composite]]></val></aggregation> 972 972 <association><ref refid="DCE:DAE7507E-97BB-11D8-9E3B-00C00C03A405"/></association> 973 <isDerived><val>0</val></isDerived>974 973 <lowerValue><ref refid="DCE:DAE8B2DE-97BB-11D8-9E3B-00C00C03A405"/></lowerValue> 974 <name><val><![CDATA[owiningProfile]]></val></name> 975 975 <owningAssociation><ref refid="DCE:DAE7507E-97BB-11D8-9E3B-00C00C03A405"/></owningAssociation> 976 <presentation><reflist></reflist></presentation><type><ref refid="DCE:3DB14614-97BA-11D8-9E36-00C00C03A405"/></type> 976 <presentation><reflist></reflist></presentation><taggedValue><ref refid="DCE:71DB0EA4-C536-11D8-BC38-487DAB7CBA3E"/></taggedValue> 977 <type><ref refid="DCE:3DB14614-97BA-11D8-9E36-00C00C03A405"/></type> 978 <upperValue><ref refid="DCE:71D046EC-C536-11D8-BC38-487DAB7CBA3E"/></upperValue> 977 979 </Property><Property id="DCE:99C69A58-4A89-11D7-B090-133D836EF880"><aggregation><val><![CDATA[none]]></val></aggregation> 978 980 <association><ref refid="DCE:99C5AF80-4A89-11D7-B090-133D836EF880"/></association> … … 1308 1310 <orthogonal><val>0</val></orthogonal> 1309 1311 <horizontal><val>1</val></horizontal> 1310 <points><val>[(26.158798283262 286, -4.9999999999999432), (19.456414519257578, 94.257510729613728)]</val></points>1312 <points><val>[(26.158798283262058, -5.0), (19.456414519257578, 94.257510729613728)]</val></points> 1311 1313 <head_connection><ref refid="DCE:7DDC7BDC-4B3D-11D7-B391-02BBFE4396CE"/></head_connection> 1312 1314 <tail_connection><ref refid="DCE:22D09ADC-863B-11D7-8239-5A25B8C2F569"/></tail_connection> … … 1325 1327 <orthogonal><val>0</val></orthogonal> 1326 1328 <horizontal><val>1</val></horizontal> 1327 <points><val>[(22.74565467081 22, -2.4537838083979295), (42.0, 0.0)]</val></points>1329 <points><val>[(22.745654670811973, -2.4537838083979295), (42.0, 0.0)]</val></points> 1328 1330 <head_connection><ref refid="DCE:2D5B72FE-863B-11D7-8239-5A25B8C2F569"/></head_connection> 1329 1331 <tail_connection><ref refid="DCE:50CA96AC-863B-11D7-8239-5A25B8C2F569"/></tail_connection> … … 1411 1413 </Property><LiteralSpecification id="DCE:ED5F90A2-4864-11D8-A4FB-20895068F46E"></LiteralSpecification><Property id="DCE:99C62C12-4A89-11D7-B090-133D836EF880"><aggregation><val><![CDATA[composite]]></val></aggregation> 1412 1414 <association><ref refid="DCE:99C5AF80-4A89-11D7-B090-133D836EF880"/></association> 1415 <isDerived><val>0</val></isDerived> 1413 1416 <lowerValue><ref refid="DCE:23A3A6E4-DB15-11D7-8BD0-27F1E06F5E9F"/></lowerValue> 1414 <name><val><![CDATA[namespace ]]></val></name>1417 <name><val><![CDATA[namespace_]]></val></name> 1415 1418 <owningAssociation><ref refid="DCE:99C5AF80-4A89-11D7-B090-133D836EF880"/></owningAssociation> 1416 1419 <presentation><reflist></reflist></presentation><taggedValue><ref refid="DCE:ED02710C-4864-11D8-A4FB-20895068F46E"/></taggedValue> … … 2116 2119 </LiteralString><Diagram id="DCE:DA033CF8-45CE-11D7-B5CA-613352B2821F"><name><val><![CDATA[overview]]></val></name> 2117 2120 <package><ref refid="DCE:DA01D45A-45CE-11D7-B5CA-613352B2821F"/></package> 2118 <canvas><extents><val>(32.0, 73.0, 798.0, 7 25.0)</val></extents>2121 <canvas><extents><val>(32.0, 73.0, 798.0, 741.0)</val></extents> 2119 2122 <static_extents><val>0</val></static_extents> 2120 2123 <snap_to_grid><val>0</val></snap_to_grid> … … 2206 2209 </item><item id="DCE:55703BCA-6690-11D7-A84E-6C8643AD0CA4" type="PackageItem"><affine><val>(1.0, 0.0, 0.0, 1.0, 623.0, 442.0)</val></affine> 2207 2210 <width><val>146.0</val></width> 2208 <height><val>6 5.0</val></height>2211 <height><val>66.0</val></height> 2209 2212 <auto-resize><val>0</val></auto-resize> 2210 2213 <subject><ref refid="DCE:5573D924-6690-11D7-A84E-6C8643AD0CA4"/></subject> … … 2308 2311 </item><item id="DCE:7FCE206A-B7DE-11D8-8AD1-9AC43285B64C" type="PackageItem"><affine><val>(1.0, 0.0, 0.0, 1.0, 217.0, 674.0)</val></affine> 2309 2312 <width><val>130.0</val></width> 2310 <height><val> 50.0</val></height>2313 <height><val>66.0</val></height> 2311 2314 <auto-resize><val>0</val></auto-resize> 2312 2315 <subject><ref refid="DCE:81009F78-B7DE-11D8-8AD1-9AC43285B64C"/></subject> … … 2762 2765 <grid_ofs_x><val>0.0</val></grid_ofs_x> 2763 2766 <grid_ofs_y><val>0.0</val></grid_ofs_y> 2764 <grid_color><val> 33023</val></grid_color>2767 <grid_color><val>255</val></grid_color> 2765 2768 <grid_bg><val>4294967295</val></grid_bg> 2766 2769 <root_affine><val>(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)</val></root_affine> … … 4301 4304 </Generalization><Generalization id="DCE:D0D99FA6-50A1-11D7-807A-302CB4EF44FD"><general><ref refid="DCE:7D753EF0-464D-11D7-AA08-1B85D5275D8A"/></general> 4302 4305 <presentation><reflist><ref refid="DCE:CD87C290-50A1-11D7-807A-302CB4EF44FD"/></reflist></presentation><specific><ref refid="DCE:B445FB00-4695-11D7-B567-379CA7034986"/></specific> 4303 </Generalization><LiteralSpecification id="DCE:ECCE6C10-4864-11D8-A4FB-20895068F46E"><value><val><![CDATA[subsets ownedMember]]></val></value> 4306 </Generalization><LiteralSpecification id="DCE:ECCE6C10-4864-11D8-A4FB-20895068F46E"><value><val><![CDATA[subsets ownedMember, 4307 ownedRule]]></val></value> 4304 4308 </LiteralSpecification><LiteralSpecification id="DCE:EE1BB08C-4864-11D8-A4FB-20895068F46E"><value><val><![CDATA[subsets context, 4305 4309 namespace]]></val></value> … … 6640 6644 <orthogonal><val>0</val></orthogonal> 6641 6645 <horizontal><val>1</val></horizontal> 6642 <points><val>[(-3.0, -1.0 ), (-3.0, 134.0)]</val></points>6646 <points><val>[(-3.0, -1.0000000000000284), (-3.0, 134.0)]</val></points> 6643 6647 <head_connection><ref refid="DCE:D7075AD6-65C5-11D7-89A9-9C62884CFFDE"/></head_connection> 6644 6648 <tail_connection><ref refid="DCE:84BAC096-65CE-11D7-89A9-9C62884CFFDE"/></tail_connection> … … 6662 6666 <orthogonal><val>0</val></orthogonal> 6663 6667 <horizontal><val>1</val></horizontal> 6664 <points><val>[(0.0, -1.0 ), (97.0, 134.0)]</val></points>6668 <points><val>[(0.0, -1.0000000000000284), (97.0, 134.0)]</val></points> 6665 6669 <head_connection><ref refid="DCE:D7075AD6-65C5-11D7-89A9-9C62884CFFDE"/></head_connection> 6666 6670 <tail_connection><ref refid="DCE:8C12C8AE-65CE-11D7-89A9-9C62884CFFDE"/></tail_connection> … … 6885 6889 <orthogonal><val>0</val></orthogonal> 6886 6890 <horizontal><val>1</val></horizontal> 6887 <points><val>[(1.0, -24.0), (10.124999999999943, -6 6.0)]</val></points>6891 <points><val>[(1.0, -24.0), (10.124999999999943, -65.999999999999943)]</val></points> 6888 6892 <head_connection><ref refid="DCE:80BB31C2-84DD-11D8-9086-B4BC0648889A"/></head_connection> 6889 6893 <tail_connection><ref refid="DCE:403F722A-78D6-11D7-B68E-7835A4497977"/></tail_connection> … … 7218 7222 <presentation><reflist></reflist></presentation><type><ref refid="DCE:109C134E-8402-11D8-82A2-7B88E55A3BEC"/></type> 7219 7223 <upperValue><ref refid="DCE:0466D3A2-8C98-11D8-8032-00C00C03A405"/></upperValue> 7220 </Property><LiteralSpecification id="DCE:EF1D46B2-4864-11D8-A4FB-20895068F46E"></LiteralSpecification><Property id="DCE:54F95920-6692-11D7-A84E-6C8643AD0CA4"><association><ref refid="DCE:54F91F8E-6692-11D7-A84E-6C8643AD0CA4"/></association> 7224 </Property><LiteralSpecification id="DCE:EF1D46B2-4864-11D8-A4FB-20895068F46E"><value><val><![CDATA[subsets namespace]]></val></value> 7225 </LiteralSpecification><Property id="DCE:54F95920-6692-11D7-A84E-6C8643AD0CA4"><association><ref refid="DCE:54F91F8E-6692-11D7-A84E-6C8643AD0CA4"/></association> 7221 7226 <isDerived><val>0</val></isDerived> 7222 7227 <name><val><![CDATA[]]></val></name> … … 7286 7291 <presentation><reflist><ref refid="DCE:FDB348C2-6690-11D7-A84E-6C8643AD0CA4"/></reflist></presentation></Association><Diagram id="DCE:71EC6E5E-6690-11D7-A84E-6C8643AD0CA4"><name><val><![CDATA[UseCases]]></val></name> 7287 7292 <package><ref refid="DCE:5573D924-6690-11D7-A84E-6C8643AD0CA4"/></package> 7288 <canvas><extents><val>( 53.0, 88.0, 917.0, 596.0)</val></extents>7293 <canvas><extents><val>(20.965517241379274, 88.0, 917.0, 596.0)</val></extents> 7289 7294 <static_extents><val>0</val></static_extents> 7290 7295 <snap_to_grid><val>0</val></snap_to_grid> … … 7293 7298 <grid_ofs_x><val>0.0</val></grid_ofs_x> 7294 7299 <grid_ofs_y><val>0.0</val></grid_ofs_y> 7295 <grid_color><val> 33023</val></grid_color>7300 <grid_color><val>255</val></grid_color> 7296 7301 <grid_bg><val>4294967295</val></grid_bg> 7297 7302 <root_affine><val>(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)</val></root_affine> … … 8188 8193 <grid_ofs_x><val>0.0</val></grid_ofs_x> 8189 8194 <grid_ofs_y><val>0.0</val></grid_ofs_y> 8190 <grid_color><val> 255</val></grid_color>8195 <grid_color><val>33023</val></grid_color> 8191 8196 <grid_bg><val>4294967295</val></grid_bg> 8192 8197 <root_affine><val>(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)</val></root_affine> … … 8354 8359 <upperValue><ref refid="DCE:E4353950-BE19-11D8-BBAB-00C00C03A405"/></upperValue> 8355 8360 </Property><LiteralSpecification id="DCE:D2015C82-BE19-11D8-BBAB-00C00C03A405"></LiteralSpecification><LiteralSpecification id="DCE:E4353950-BE19-11D8-BBAB-00C00C03A405"><value><val><![CDATA[*]]></val></value> 8356 </LiteralSpecification><LiteralSpecification id="DCE:E43E0DBC-BE19-11D8-BBAB-00C00C03A405"></LiteralSpecification></gaphor> 8361 </LiteralSpecification><LiteralSpecification id="DCE:E43E0DBC-BE19-11D8-BBAB-00C00C03A405"></LiteralSpecification><LiteralSpecification id="DCE:71D046EC-C536-11D8-BC38-487DAB7CBA3E"><value><val><![CDATA[1]]></val></value> 8362 </LiteralSpecification><LiteralSpecification id="DCE:71DB0EA4-C536-11D8-BC38-487DAB7CBA3E"><value><val><![CDATA[subsets namespace]]></val></value> 8363 </LiteralSpecification></gaphor> trunk/gaphor/gaphor/UML/uml2.override
r356 r365 80 80 %% 81 81 override Classifier.general 82 Classifier.general = derivedunion('inheritedMember', 0, '*') 82 def classifier_general(self): 83 return [g.general for g in self.generalization] 84 85 Classifier.general = property(classifier_general, doc="") 86 del classifier_general 87 %% 88 override Class.superClass 89 Class.superClass = Classifier.general 83 90 %% 84 91 override Namespace.importedMember trunk/gaphor/gaphor/__init__.py
r363 r365 46 46 import gtk 47 47 # Load plugin definitions: 48 import diagram 48 49 import pluginmanager 49 from ui import MainWindow50 from ui.mainwindow import MainWindow 50 51 51 52 resource('PluginManager').bootstrap() 52 53 53 54 # should we set a default icon here or something? 54 main_window = MainWindow()55 main_window = resource(MainWindow) 55 56 main_window.construct() 56 57 # When the state changes to CLOSED, quit the application 57 58 main_window.connect(lambda win: win.get_state() == MainWindow.STATE_CLOSED and gtk.main_quit()) 58 59 # Make the mainwindow accessable as a resource 59 resource('MainWindow', main_window)60 60 #gtk.threads_init() 61 61 #gtk.threads_enter() trunk/gaphor/gaphor/diagram/interface.py
r359 r365 18 18 19 19 class InterfaceItem(NamedItem): 20 """This item represents an interface drawn as a dot. The class-like 21 representation is provided by ClassItem. These representations can be switched 22 by using the Fold and Unfold actions. 23 24 TODO: Provided interfaces are shown by a Implementation dependency, 25 Required interfaces are shown by a Usage dependency (not association). 26 27 Interfaces may also be used to specify required interfaces, which are 28 specified by a usage dependency between the classifier and the 29 corresponding interfaces. Required interfaces specify services that a 30 classifier needs in order to perform its function and fulfill its own 31 obligations to its clients. 32 """ 20 33 RADIUS=10 21 34 … … 54 67 55 68 def on_update(self, affine): 69 70 # Figure out if this interface represents a required, provided or wired look. 56 71 self.association_items = 0 57 72 self.implementation_items = 0 … … 65 80 gaphor.diagram.implementation.ImplementationItem): 66 81 self.implementation_items += 1 67 68 69 82 70 83 # Center the text … … 94 107 95 108 def on_handle_motion(self, handle, wx, wy, mask): 96 """Make sure the element works with diacanavs2 <= 0.12.0. 97 """ 109 # Make sure the element works with diacanavs2 <= 0.12.0. 98 110 if handle not in self.handles[:7]: 99 111 return wx, wy … … 114 126 yield s 115 127 128 def on_connect_handle(self, handle): 129 self.request_update() 130 return NamedItem.on_connect_handle(self, handle) 131 132 def on_disconnect_handle(self, handle): 133 self.request_update() 134 return NamedItem.on_disconnect_handle(self, handle) 116 135 117 136 def _getLookType(self): … … 126 145 127 146 128 # def on_editable_start_editing(self, shape):129 # NamedItem.on_editable_start_editing(self, shape)130 # self._name.set_max_width(0)131 132 147 initialize_item(InterfaceItem, UML.Interface) trunk/gaphor/gaphor/diagram/klass.py
r361 r365 106 106 'separator', 107 107 'ShowAttributes', 108 'ShowOperations' 108 'ShowOperations', 109 '<ClassPopupSlot>' 109 110 ) 110 111 … … 146 147 147 148 def get_popup_menu(self): 148 from itemactions import ApplyStereotypeAction, register_action 149 # TODO: We should find the Stereotypes who have an Extension relationship 150 # with a Class who's name is the name of this class or one of its 151 # supertypes. 152 NamedElement = UML.NamedElement 153 Class = UML.Class 154 149 """In the popup menu a submenu is created with Stereotypes than can be 150 applied to this classifier (Class, Interface). 151 If the class itself is a metaclass, an option is added to check if the class 152 exists. 153 """ 155 154 stereotype_list = self.stereotype_list 156 155 stereotype_list[:] = [] 157 _mro = filter(lambda e:issubclass(e, NamedElement), type(self.subject).__mro__) 158 names = map(getattr, _mro, ['__name__'] * len(_mro)) 159 classes = self._subject._factory.select(lambda e: e.isKindOf(Class) and e.name in names) 160 for class_ in classes: 161 for extension in class_.extension: 162 stereotype = extension.ownedEnd.type 163 stereotype_action = ApplyStereotypeAction(stereotype) 164 register_action(stereotype_action, 'ItemFocus') 165 stereotype_list.append(stereotype_action.id) 156 if isinstance(subject, UML.Class) and subject.extension: 157 # Add an action that can be used to check if the metaclass is an 158 # existing metaclass 159 pass 160 else: 161 from itemactions import ApplyStereotypeAction, register_action 162 NamedElement = UML.NamedElement 163 Class = UML.Class 164 165 # Find classes that are superclasses of our subject 166 _mro = filter(lambda e:issubclass(e, NamedElement), type(self.subject).__mro__) 167 # Find out their names 168 names = map(getattr, _mro, ['__name__'] * len(_mro)) 169 # Find stereotypes that extend out metaclass 170 classes = self._subject._factory.select(lambda e: e.isKindOf(Class) and e.name in names) 171 172 for class_ in classes: 173 for extension in class_.extension: 174 stereotype = extension.ownedEnd.type 175 stereotype_action = ApplyStereotypeAction(stereotype) 176 register_action(stereotype_action, 'ItemFocus') 177 stereotype_list.append(stereotype_action.id) 166 178 return NamedItem.get_popup_menu(self) 167 179 trunk/gaphor/gaphor/plugin.py
r363 r365 1 # vim:sw=4:et 1 2 """This module provides everything needed to create a plugin. 2 3 3 4 resource - Get/set application wide resources 5 6 Classes to construct Actions: 7 Action 8 CheckAction (Checkbutton Action) 9 RadioAction (RadioButton Action, should set the group attribute) 10 ObjectAction (this is not an action, but it contains some code to make 11 instances of Actions behave like Action classes) 12 13 Each action is initialized. The window containing the action can be accessed 14 by the 'window' property. 4 15 """ 5 16 6 17 from gaphor import resource 7 18 8 from gaphor.misc.action import Action, CheckAction, RadioAction, ObjectAction 19 from gaphor.misc.action import Action as _Action 20 from gaphor.misc.action import CheckAction as _CheckAction 21 from gaphor.misc.action import RadioAction as _RadioAction 22 from gaphor.misc.action import ObjectAction 9 23 24 25 class _ActionMixIn(object): 26 """Handle initialization of actions in a way that the main window 27 can properly initialize the action. 28 """ 29 30 def init(self, window): 31 self._window = window 32 33 def get_window(self): 34 return self._window 35 36 window = property(get_window) 37 38 class Action(_Action, _ActionMixIn): pass 39 class CheckAction(_CheckAction, _ActionMixIn): pass 40 class RadioAction(_RadioAction, _ActionMixIn): pass 41 42 del _Action, _CheckAction, _RadioAction, _ActionMixIn 43 trunk/gaphor/gaphor/pluginmanager.py
r363 r365 1 1 # vim:sw=4 2 """Manage plugins. 2 """Plugin Manager. 3 4 The plugin manager is used to manage (register/unregister) plugins. 5 6 A Plugin is presented as a directory. This directory contains two files: 7 - plugin.xml contains a description of the plugin 8 - __init__.py is needed since the plugin is loaded as a module 9 10 The following classes are provided by this module: 11 12 PluginManager - The main class. PluginManager.bootstrap() loads all plugins 13 from the default plugin dirs ($PREFIX/share/gaphor/plugins and 14 $HOME/.gaphor/plugins). 15 Plugin - This class represents a plugin. It contains data from plugin.xml 16 as well as data gathered during the plugin loading process (such as 17 the module that was created when the plugin is imported. 18 PluginAction - Defines an gaphor.plugin.Action instance. 19 PluginLoader - SAX parser used to read the plugin.xml file of a plugin. This 20 class creates a Plugin instance from the xml file. 3 21 """ 4 22 … … 9 27 from gaphor.parser import ParserException 10 28 from gaphor.misc.action import register_action_for_slot 29 from gaphor.misc.odict import odict 11 30 12 31 XMLNS='http://gaphor.sourceforge.net/gaphor/plugin' … … 25 44 self.required_actions = [] 26 45 self.provided_actions = [] 46 self.description = '' 27 47 self.initialized = False 28 48 self.path = '' 29 49 self.module = None 30 50 self.status = '' 51 52 def requirements_met(self, manager): 53 """Check if all <require>-ments are met to load the plugin. 54 """ 55 if self.initialized: 56 return False 57 58 for mod in self.required_modules: 59 try: 60 # TODO: How to find out if a module exists without loading it? 61 __import__(mod, globals(), locals(), []) 62 except ImportError: 63 self.initialized = True 64 self.status = 'Could not initialize plugin: module %s could not be imported' % mod 65 log.debug(self.status) 66 return False 67 68 pluginstatus = {} 69 for p in manager.plugins.itervalues(): 70 pluginstatus[p.name] = bool(p.initialized) 71 for p in self.required_plugins: 72 if not pluginstatus.get(p): 73 self.status = 'Plugin %s is required by this plugin' % p 74 log.debug(self.status) 75 return False 76 77 return True 78 79 def import_plugin(self): 80 """Do the actual import of the plugin module. 81 """ 82 mod = __import__(self.path, globals(), locals(), []) 83 self.module = mod 84 self.initialized = True 85 self.status = 'Imported' 86 87 for action in self.provided_actions: 88 try: 89 action.import_action(self) 90 except Exception, e: 91 log.error('Failed to import action %s' % (action.id or action.class_), e) 92 31 93 32 94 class PluginAction(object): … … 45 107 self.depends = [] 46 108 109 def import_action(self, plugin): 110 """Import and register one action in the plugin. 111 """ 112 # Create an icon for the plugin 113 if self.icon_file: 114 from gaphor.ui.stock import add_stock_icon 115 self.stock_id = 'gaphor-plugin-' + self.id 116 add_stock_icon(self.stock_id, plugin.path, [self.icon_file]) 117 118 # Fetch the action class 119 action_class = getattr(plugin.module, self.class_) 120 121 # Copy attributes from the plugin to the class 122 for attr in ('id', 'label', 'stock_id', 'tooltip', 'accel'): 123 val = getattr(self, attr, None) 124 if val: 125 setattr(action_class, attr, val) 126 127 register_action_for_slot(action_class, self.slot, *self.depends) 128 log.debug('Providing action %s for slot %s' % (action_class, self.slot)) 47 129 48 130 class PluginLoader(handler.ContentHandler): … … 53 135 PROVIDE = 2 54 136 ACTION = 3 137 DESCRIPTION = 4 55 138 56 139 def __init__(self): … … 77 160 self.plugin.version = attrs['version'] 78 161 self.plugin.author = attrs['author'] 162 elif name == 'description': 163 self.mode = self.DESCRIPTION 79 164 if name == 'require': 80 165 self.mode = self.REQUIRE … … 111 196 112 197 def endElement(self, name): 113 if self.mode in (self.REQUIRE, self.PROVIDE ) and \114 name in (' require', 'provide'):198 if self.mode in (self.REQUIRE, self.PROVIDE, self.DESCRIPTION) and \ 199 name in ('description', 'require', 'provide'): 115 200 self.mode = self.TOPLEVEL 116 201 elif self.mode == self.ACTION and name == 'action': … … 134 219 def characters(self, content): 135 220 """Read characters.""" 136 pass 221 if self.mode == self.DESCRIPTION: 222 self.plugin.description += content 137 223 138 224 … … 142 228 143 229 def __init__(self): 144 self.plugins = {}230 self.plugins = odict() 145 231 self.bootstrapped = False 146 232 … … 164 250 import_done = False 165 251 for plugin in self.plugins.itervalues(): 166 if self.requirements_met(plugin):252 if plugin.requirements_met(self): 167 253 try: 168 self.import_plugin(plugin)254 plugin.import_plugin() 169 255 except Exception, e: 170 256 plugin.status = 'Failed to load plugin %s: %s' % (plugin.name, e) … … 193 279 log.error('Could not load plugin definition %s' % plugin_xml, e) 194 280 195 def requirements_met(self, plugin):196 """Check if all <require>-ments are met to load the plugin.197 """198 if plugin.initialized:199 return False200 201 for mod in plugin.required_modules:202 try:203 # TODO: How to find out if a module exists without loading it?204 __import__(mod, globals(), locals(), [])205 except ImportError:206 plugin.initialized = True207 plugin.status = 'Could not initialize plugin: module %s could not be imported' % mod208 log.debug(plugin.status)209 return False210 211 pluginstatus = {}212 for p in self.plugins.itervalues():213 pluginstatus[p.name] = bool(p.initialized)214 for p in plugin.required_plugins:215 if not pluginstatus.get(p):216 plugin.status = 'Plugin %s is required by this plugin' % p217 log.debug(plugin.status)218 return False219 220 return True221 222 def import_plugin(self, plugin):223 """Do the actual import of the plugin module.224 """225 mod = __import__(plugin.path, globals(), locals(), [])226 plugin.module = mod227 plugin.initialized = True228 plugin.status = 'Imported'229 230 for action in plugin.provided_actions:231 try:232 self.import_action(action, plugin)233 except Exception, e:234 log.error('Failed to import action %s' % (action.id or action.class_), e)235 236 def import_action(self, action, plugin):237 """Import and register one action in the plugin.238 """239 # Create an icon for the plugin240 if action.icon_file:241 from gaphor.ui.stock import add_stock_icon242 action.stock_id = 'gaphor-plugin-' + action.id243 add_stock_icon(action.stock_id, plugin.path, [action.icon_file])244 245 # Fetch the action class246 action_class = getattr(plugin.module, action.class_)247 248 # Copy attributes from the plugin to the class249 for attr in ('id', 'label', 'stock_id', 'tooltip', 'accel'):250 val = getattr(action, attr, None)251 if val:252 setattr(action_class, attr, val)253 254 register_action_for_slot(action_class, action.slot, *action.depends)255 log.debug('Providing entry %s for slot <%s>' % (action_class, action.slot))256 281 257 282 # Make one default plugin manager trunk/gaphor/gaphor/ui/__init__.py
r363 r365 9 9 10 10 # Should we do this: 11 from abstractwindow import AbstractWindow12 from mainwindow import MainWindow13 from diagramview import DiagramView14 from editorwindow import EditorWindow11 #from abstractwindow import AbstractWindow 12 #from mainwindow import MainWindow 13 #from diagramview import DiagramView 14 #from editorwindow import EditorWindow 15 15 16 16 # Create stock items trunk/gaphor/gaphor/ui/diagramtab.py
r304 r365 6 6 from abstractwindow import AbstractWindow 7 7 from gaphor.diagram.itemtool import ItemTool 8 9 import diagramactions 10 import gaphor.diagram.actions 8 11 9 12 class DiagramTab(object): … … 140 143 #self.get_window().set_title(self.diagram.name or '<None>') 141 144 142 import diagramactions143 import gaphor.diagram.actionstrunk/gaphor/gaphor/ui/mainactions.py
r338 r365 278 278 279 279 def execute(self): 280 from gaphor.ui import EditorWindow280 from gaphor.ui.editorwindow import EditorWindow 281 281 282 282 ew = EditorWindow() … … 305 305 306 306 register_action(OpenConsoleWindowAction) 307 308 309 class OpenStereotypeWindowAction(Action):310 id = 'OpenStereotypeWindow'311 label = 'S_tereotypes'312 tooltip = 'Open the Gaphor Stereotypes'313 314 def init(self, window):315 self._window = window316 317 def execute(self):318 from gaphor.ui.stereotypewindow import StereotypeWindow319 320 ew = StereotypeWindow()321 #ew.construct(self._window.get_window())322 ew.run(self._window.get_window())323 #self._window.add_transient_window(ew)324 #self._window.set_message('Stereortypes launched')325 326 register_action(OpenStereotypeWindowAction)327 307 328 308 … … 411 391 element = self._window.get_tree_view().get_selected_element() 412 392 if isinstance(element, UML.Diagram): 413 # Try to find an existing window/tab and let it get focus: 414 for tab in self._window.get_tabs(): 415 if tab.get_diagram() is element: 416 self._window.set_current_page(tab) 417 return 418 # Import here to avoid cyclic references 419 from gaphor.ui.diagramtab import DiagramTab 420 diagram_tab = DiagramTab(self._window) 421 #diagram_tab.set_owning_window(self._window) 422 #diagram_tab.sub_window = False 423
