Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
UMLDiagram |
|
| 1.5135135135135136;1.514 |
1 | /* $Id: UMLDiagram.java 18729 2010-09-10 16:10:34Z bobtarling $ | |
2 | ***************************************************************************** | |
3 | * Copyright (c) 2009-2010 Contributors - see below | |
4 | * All rights reserved. This program and the accompanying materials | |
5 | * are made available under the terms of the Eclipse Public License v1.0 | |
6 | * which accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Bob Tarling | |
11 | ***************************************************************************** | |
12 | * | |
13 | * Some portions of this file was previously release using the BSD License: | |
14 | */ | |
15 | ||
16 | // Copyright (c) 1996-2008 The Regents of the University of California. All | |
17 | // Rights Reserved. Permission to use, copy, modify, and distribute this | |
18 | // software and its documentation without fee, and without a written | |
19 | // agreement is hereby granted, provided that the above copyright notice | |
20 | // and this paragraph appear in all copies. This software program and | |
21 | // documentation are copyrighted by The Regents of the University of | |
22 | // California. The software program and documentation are supplied "AS | |
23 | // IS", without any accompanying services from The Regents. The Regents | |
24 | // does not warrant that the operation of the program will be | |
25 | // uninterrupted or error-free. The end-user understands that the program | |
26 | // was developed for research purposes and is advised not to rely | |
27 | // exclusively on the program for any reason. IN NO EVENT SHALL THE | |
28 | // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | |
29 | // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, | |
30 | // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF | |
31 | // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF | |
32 | // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY | |
33 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
34 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE | |
35 | // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF | |
36 | // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, | |
37 | // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
38 | ||
39 | package org.argouml.uml.diagram.ui; | |
40 | ||
41 | import java.awt.Component; | |
42 | import java.awt.Point; | |
43 | import java.awt.Rectangle; | |
44 | import java.beans.PropertyVetoException; | |
45 | ||
46 | import javax.swing.Action; | |
47 | import javax.swing.ButtonModel; | |
48 | import javax.swing.JToolBar; | |
49 | ||
50 | import org.apache.log4j.Logger; | |
51 | import org.argouml.gefext.ArgoModeCreateFigCircle; | |
52 | import org.argouml.gefext.ArgoModeCreateFigInk; | |
53 | import org.argouml.gefext.ArgoModeCreateFigLine; | |
54 | import org.argouml.gefext.ArgoModeCreateFigPoly; | |
55 | import org.argouml.gefext.ArgoModeCreateFigRRect; | |
56 | import org.argouml.gefext.ArgoModeCreateFigRect; | |
57 | import org.argouml.gefext.ArgoModeCreateFigSpline; | |
58 | import org.argouml.i18n.Translator; | |
59 | import org.argouml.kernel.Project; | |
60 | import org.argouml.model.Model; | |
61 | import org.argouml.ui.CmdCreateNode; | |
62 | import org.argouml.uml.UUIDHelper; | |
63 | import org.argouml.uml.diagram.ArgoDiagramImpl; | |
64 | import org.argouml.uml.diagram.DiagramElement; | |
65 | import org.argouml.uml.diagram.DiagramSettings; | |
66 | import org.argouml.uml.diagram.Relocatable; | |
67 | import org.argouml.uml.diagram.UMLMutableGraphSupport; | |
68 | import org.argouml.util.ToolBarUtility; | |
69 | import org.tigris.gef.base.LayerPerspective; | |
70 | import org.tigris.gef.base.ModeBroom; | |
71 | import org.tigris.gef.base.ModeCreatePolyEdge; | |
72 | import org.tigris.gef.base.ModePlace; | |
73 | import org.tigris.gef.base.ModeSelect; | |
74 | import org.tigris.gef.graph.GraphFactory; | |
75 | import org.tigris.gef.graph.GraphModel; | |
76 | import org.tigris.gef.presentation.FigNode; | |
77 | import org.tigris.toolbar.ToolBarFactory; | |
78 | import org.tigris.toolbar.ToolBarManager; | |
79 | import org.tigris.toolbar.toolbutton.ToolButton; | |
80 | ||
81 | /** | |
82 | * This class provides support for writing a UML diagram for argo using | |
83 | * the GEF framework. <p> | |
84 | * | |
85 | * It adds common buttons, and some help | |
86 | * with creating a valid diagram name. <p> | |
87 | * | |
88 | * There are various methods for returning 'structures' of Actions | |
89 | * which are used to build toolbars and dropdown buttons within toolbars. | |
90 | * These structures are arrays of Objects. | |
91 | * An array element is actually either an Action, null or another array. | |
92 | * When building a toolbar an Action is used to create a button and null | |
93 | * is used to create a spacer in the toolbar. | |
94 | * An element containing an array results in a dropdown toolbar button | |
95 | * being created which contains all the items in that array. <p> | |
96 | * | |
97 | * The "owner" of the UMLDiagram needs to be set to the | |
98 | * UML modelelement of which the diagram depends. | |
99 | * For a class diagram is that its namespace. | |
100 | * For a collaboration diagram is that the Collaboration UML object. | |
101 | * For a sequence diagram is that the collaboration. | |
102 | * For a deployment diagram is that the namespace. | |
103 | * For a statechart diagram is that the statemachine. | |
104 | * For a activitydiagram is that the activitygraph. | |
105 | * Override the getOwner method to return the owner. <p> | |
106 | * | |
107 | * The "owner" is shown in the diagram's properties | |
108 | * panel as the "home model". <p> | |
109 | */ | |
110 | public abstract class UMLDiagram | |
111 | extends ArgoDiagramImpl | |
112 | implements Relocatable { | |
113 | ||
114 | 900 | private static final Logger LOG = Logger.getLogger(UMLDiagram.class); |
115 | ||
116 | /** | |
117 | * Tool to add a comment node. | |
118 | */ | |
119 | 900 | private static Action actionComment = |
120 | new RadioAction(new ActionAddNote()); | |
121 | ||
122 | /** | |
123 | * Tool to create an relationship between a comment node and some other node | |
124 | * using a polyedge.<p> | |
125 | */ | |
126 | 900 | private static Action actionCommentLink = |
127 | new RadioAction(new ActionSetAddCommentLinkMode()); | |
128 | ||
129 | ||
130 | 900 | private static Action actionSelect = |
131 | new ActionSetMode(ModeSelect.class, "button.select"); | |
132 | ||
133 | 900 | private static Action actionBroom = |
134 | new ActionSetMode(ModeBroom.class, "button.broom"); | |
135 | ||
136 | 900 | private static Action actionRectangle = |
137 | new RadioAction(new ActionSetMode(ArgoModeCreateFigRect.class, | |
138 | "Rectangle", "misc.primitive.rectangle")); | |
139 | ||
140 | 900 | private static Action actionRRectangle = |
141 | new RadioAction(new ActionSetMode(ArgoModeCreateFigRRect.class, | |
142 | "RRect", "misc.primitive.rounded-rectangle")); | |
143 | ||
144 | 900 | private static Action actionCircle = |
145 | new RadioAction(new ActionSetMode(ArgoModeCreateFigCircle.class, | |
146 | "Circle", "misc.primitive.circle")); | |
147 | ||
148 | 900 | private static Action actionLine = |
149 | new RadioAction(new ActionSetMode(ArgoModeCreateFigLine.class, | |
150 | "Line", "misc.primitive.line")); | |
151 | ||
152 | 900 | private static Action actionText = |
153 | new RadioAction(new ActionSetMode(ArgoModeCreateFigText.class, | |
154 | "Text", "misc.primitive.text")); | |
155 | ||
156 | 900 | private static Action actionPoly = |
157 | new RadioAction(new ActionSetMode(ArgoModeCreateFigPoly.class, | |
158 | "Polygon", "misc.primitive.polygon")); | |
159 | ||
160 | 900 | private static Action actionSpline = |
161 | new RadioAction(new ActionSetMode(ArgoModeCreateFigSpline.class, | |
162 | "Spline", "misc.primitive.spline")); | |
163 | ||
164 | 900 | private static Action actionInk = |
165 | new RadioAction(new ActionSetMode(ArgoModeCreateFigInk.class, | |
166 | "Ink", "misc.primitive.ink")); | |
167 | ||
168 | private JToolBar toolBar; | |
169 | ||
170 | private Action selectedAction; | |
171 | ||
172 | /** | |
173 | * Default constructor will become protected. All subclasses should have | |
174 | * their constructors invoke the 3-arg version of the constructor. | |
175 | * | |
176 | * @deprecated for 0.27.2 by tfmorris. Use | |
177 | * {@link #UMLDiagram(String, Object, GraphModel)} or another | |
178 | * explicit constructor. | |
179 | */ | |
180 | @SuppressWarnings("deprecation") | |
181 | @Deprecated | |
182 | public UMLDiagram() { | |
183 | 76 | super(); |
184 | 76 | } |
185 | ||
186 | /** | |
187 | * @param ns the UML namespace of this diagram | |
188 | * @deprecated for 0.27.2 by tfmorris. Use | |
189 | * {@link #UMLDiagram(String, Object, GraphModel)}. | |
190 | */ | |
191 | @Deprecated | |
192 | public UMLDiagram(Object ns) { | |
193 | 0 | this(); |
194 | 0 | if (!Model.getFacade().isANamespace(ns)) { |
195 | 0 | throw new IllegalArgumentException(); |
196 | } | |
197 | // TODO: Should we require a GraphModel in the constructor since | |
198 | // our implementations of setNamespace are going to try and set | |
199 | // the namespace on the graphmodel as well? | |
200 | 0 | setNamespace(ns); |
201 | 0 | } |
202 | ||
203 | /** | |
204 | * @param name the name of the diagram | |
205 | * @param ns the UML namespace of this diagram | |
206 | * @deprecated for 0.27.2 by tfmorris. Use | |
207 | * {@link #UMLDiagram(String, Object, GraphModel)}. | |
208 | */ | |
209 | @Deprecated | |
210 | public UMLDiagram(String name, Object ns) { | |
211 | 0 | this(ns); |
212 | try { | |
213 | 0 | setName(name); |
214 | 0 | } catch (PropertyVetoException pve) { |
215 | 0 | LOG.fatal("Name not allowed in construction of diagram"); |
216 | 0 | } |
217 | 0 | } |
218 | ||
219 | ||
220 | /** | |
221 | * Construct a new ArgoUML diagram. This is the fully specified form | |
222 | * of the constructor typically used by subclasses. | |
223 | * | |
224 | * @param name the name of the new diagram | |
225 | * @param graphModel graph model to associate with diagram | |
226 | * @param ns the namespace which will "own" the diagram | |
227 | */ | |
228 | public UMLDiagram(String name, Object ns, GraphModel graphModel) { | |
229 | 1028 | super(name, graphModel, new LayerPerspective(name, graphModel)); |
230 | 1028 | setNamespace(ns); |
231 | 1028 | } |
232 | ||
233 | /** | |
234 | * Construct an unnamed diagram using the given GraphModel. | |
235 | * | |
236 | * @param graphModel graph model to associate with diagram | |
237 | */ | |
238 | public UMLDiagram(GraphModel graphModel) { | |
239 | 1012 | super("", graphModel, new LayerPerspective("", graphModel)); |
240 | 1012 | } |
241 | ||
242 | /** | |
243 | * Method called by PGML parser during diagram load to initialize a diagram | |
244 | * after it's been constructed. Order of method invocations currently is: | |
245 | * <ul> | |
246 | * <li>0-arg constructor | |
247 | * <li>setDiagramSettings | |
248 | * <li>initialize(Object) // UML element representing owner/home model | |
249 | * <li>setName(String) | |
250 | * <li>setScale(double) | |
251 | * <li>setShowSingleMultiplicity(boolean) | |
252 | * <ul> | |
253 | * | |
254 | * @param owner UML model element representing owner/namespace/home model | |
255 | * @see org.tigris.gef.base.Diagram#initialize(java.lang.Object) | |
256 | */ | |
257 | @Override | |
258 | public void initialize(Object owner) { | |
259 | 0 | super.initialize(owner); |
260 | /* The following is the default implementation | |
261 | * for diagrams of which the owner is a namespace. | |
262 | */ | |
263 | 0 | if (Model.getFacade().isANamespace(owner)) { |
264 | 0 | setNamespace(owner); |
265 | } | |
266 | 0 | } |
267 | ||
268 | /* | |
269 | * @see org.tigris.gef.base.Diagram#getClassAndModelID() | |
270 | */ | |
271 | public String getClassAndModelID() { | |
272 | 0 | String s = super.getClassAndModelID(); |
273 | 0 | if (getOwner() == null) { |
274 | 0 | return s; |
275 | } | |
276 | 0 | String id = UUIDHelper.getUUID(getOwner()); |
277 | 0 | return s + "|" + id; |
278 | } | |
279 | ||
280 | /** | |
281 | * Get the toolbar for the diagram. | |
282 | * @return the diagram toolbar | |
283 | */ | |
284 | public JToolBar getJToolBar() { | |
285 | 1502 | if (toolBar == null) { |
286 | 1197 | initToolBar(); |
287 | 1197 | toolBar.setName("misc.toolbar.diagram"); |
288 | } | |
289 | 1502 | return toolBar; |
290 | } | |
291 | ||
292 | /** | |
293 | * Create the toolbar based on actions for the specific diagram | |
294 | * subclass. | |
295 | * @see org.tigris.gef.base.Diagram#initToolBar() | |
296 | */ | |
297 | public void initToolBar() { | |
298 | 1197 | ToolBarFactory factory = new ToolBarFactory(getActions()); |
299 | 1197 | factory.setRollover(true); |
300 | 1197 | factory.setFloatable(false); |
301 | ||
302 | 1197 | toolBar = factory.createToolBar(); |
303 | 1197 | toolBar.putClientProperty("ToolBar.toolTipSelectTool", |
304 | Translator.localize("action.select")); | |
305 | 1197 | } |
306 | ||
307 | /** | |
308 | * Return actions available for building toolbar or similar. | |
309 | * @return an array of available actions. | |
310 | */ | |
311 | public Object[] getActions() { | |
312 | 1197 | Object[] manipulateActions = getManipulateActions(); |
313 | 1197 | Object[] umlActions = getUmlActions(); |
314 | 1197 | Object[] commentActions = getCommentActions(); |
315 | 1197 | Object[] shapeActions = getShapeActions(); |
316 | ||
317 | 1197 | Object[] actions = |
318 | new Object[manipulateActions.length | |
319 | + umlActions.length | |
320 | + commentActions.length | |
321 | + shapeActions.length]; | |
322 | ||
323 | 1197 | int posn = 0; |
324 | 1197 | System.arraycopy( |
325 | manipulateActions, // source | |
326 | 0, // source position | |
327 | actions, // destination | |
328 | posn, // destination position | |
329 | manipulateActions.length); // number of objects to be copied | |
330 | 1197 | posn += manipulateActions.length; |
331 | ||
332 | 1197 | System.arraycopy(umlActions, 0, actions, posn, umlActions.length); |
333 | 1197 | posn += umlActions.length; |
334 | ||
335 | 1197 | System.arraycopy(commentActions, 0, actions, posn, |
336 | commentActions.length); | |
337 | 1197 | posn += commentActions.length; |
338 | ||
339 | 1197 | System.arraycopy(shapeActions, 0, actions, posn, shapeActions.length); |
340 | ||
341 | 1197 | return actions; |
342 | } | |
343 | ||
344 | /** | |
345 | * Implement in the ancestor to get a 'structure' of actions for | |
346 | * appending the UML creation tools to the toolbar. | |
347 | * @return the actions structure | |
348 | */ | |
349 | protected abstract Object[] getUmlActions(); | |
350 | ||
351 | /** | |
352 | * Get a 'structure' of actions for appending the manipulation | |
353 | * mode tools to the toolbar. | |
354 | * @return the actions structure | |
355 | */ | |
356 | private Object[] getManipulateActions() { | |
357 | 1197 | Object[] actions = |
358 | { | |
359 | new RadioAction(actionSelect), | |
360 | new RadioAction(actionBroom), | |
361 | null, | |
362 | }; | |
363 | 1197 | return actions; |
364 | } | |
365 | ||
366 | /** | |
367 | * Get a 'structure' of actions for appending the comment | |
368 | * tools to the toolbar. | |
369 | * @return the actions structure | |
370 | */ | |
371 | private Object[] getCommentActions() { | |
372 | 1197 | Object[] actions = |
373 | { | |
374 | null, | |
375 | actionComment, | |
376 | actionCommentLink, | |
377 | }; | |
378 | 1197 | return actions; |
379 | } | |
380 | ||
381 | /** | |
382 | * Get a 'structure' of actions for appending primitive drawing | |
383 | * tools to the toolbar. | |
384 | * @return the actions structure | |
385 | */ | |
386 | private Object[] getShapeActions() { | |
387 | 1197 | Object[] actions = { |
388 | null, | |
389 | getShapePopupActions(), | |
390 | }; | |
391 | 1197 | return actions; |
392 | } | |
393 | ||
394 | /** | |
395 | * Get a 'structure' of actions for showing in the shape | |
396 | * primitives popup tool button. | |
397 | * @return the actions structure | |
398 | */ | |
399 | private Object[] getShapePopupActions() { | |
400 | 1197 | Object[][] actions = { |
401 | {actionRectangle, actionRRectangle }, | |
402 | {actionCircle, actionLine }, | |
403 | {actionText, actionPoly }, | |
404 | {actionSpline, actionInk }, | |
405 | }; | |
406 | ||
407 | 1197 | ToolBarUtility.manageDefault(actions, "diagram.shape"); |
408 | 1197 | return actions; |
409 | } | |
410 | ||
411 | /** | |
412 | * Set the given action as the selected action (ie pressed down on the | |
413 | * diagram toolbar). All other actions become unselected. | |
414 | * | |
415 | * @param theAction the action to become selected | |
416 | */ | |
417 | public void setSelectedAction(Action theAction) { | |
418 | 0 | selectedAction = theAction; |
419 | 0 | int toolCount = toolBar.getComponentCount(); |
420 | 0 | for (int i = 0; i < toolCount; ++i) { |
421 | 0 | Component c = toolBar.getComponent(i); |
422 | 0 | if (c instanceof ToolButton) { |
423 | 0 | ToolButton tb = (ToolButton) c; |
424 | 0 | Action action = tb.getRealAction(); |
425 | 0 | if (action instanceof RadioAction) { |
426 | 0 | action = ((RadioAction) action).getAction(); |
427 | } | |
428 | 0 | Action otherAction = theAction; |
429 | 0 | if (theAction instanceof RadioAction) { |
430 | 0 | otherAction = ((RadioAction) theAction).getAction(); |
431 | } | |
432 | 0 | if (action != null && !action.equals(otherAction)) { |
433 | 0 | tb.setSelected(false); |
434 | 0 | ButtonModel bm = tb.getModel(); |
435 | 0 | bm.setRollover(false); |
436 | 0 | bm.setSelected(false); |
437 | 0 | bm.setArmed(false); |
438 | 0 | bm.setPressed(false); |
439 | 0 | if (!ToolBarManager.alwaysUseStandardRollover()) { |
440 | 0 | tb.setBorderPainted(false); |
441 | } | |
442 | 0 | } else { |
443 | 0 | tb.setSelected(true); |
444 | 0 | ButtonModel bm = tb.getModel(); |
445 | 0 | bm.setRollover(true); |
446 | 0 | if (!ToolBarManager.alwaysUseStandardRollover()) { |
447 | 0 | tb.setBorderPainted(true); |
448 | } | |
449 | } | |
450 | } | |
451 | } | |
452 | 0 | } |
453 | ||
454 | /** | |
455 | * Get the selected action. | |
456 | * | |
457 | * @return the selected action | |
458 | */ | |
459 | public Action getSelectedAction() { | |
460 | 0 | return selectedAction; |
461 | } | |
462 | ||
463 | /** | |
464 | * Unselect all the toolbar buttons. | |
465 | */ | |
466 | public void deselectAllTools() { | |
467 | 0 | setSelectedAction(actionSelect); |
468 | 0 | actionSelect.actionPerformed(null); |
469 | 0 | } |
470 | ||
471 | /** | |
472 | * Factory method to build an Action for creating a node in the | |
473 | * diagram. | |
474 | * | |
475 | * @param modelElement identifies the model element type to make | |
476 | * @param descr the description to give this action. | |
477 | * @return The action to create a new node. | |
478 | */ | |
479 | protected Action makeCreateNodeAction(Object modelElement, String descr) { | |
480 | 8224 | return new RadioAction(new CmdCreateNode(modelElement, descr)); |
481 | } | |
482 | ||
483 | /** | |
484 | * Factory method to build an Action for creating an edge in the | |
485 | * diagram. | |
486 | * | |
487 | * @param modelElement identifies the model element type to make | |
488 | * @param descr the description to give this action. | |
489 | * @return The action to create a new node. | |
490 | */ | |
491 | protected Action makeCreateEdgeAction(Object modelElement, String descr) { | |
492 | 1028 | return new RadioAction( |
493 | new ActionSetMode(ModeCreatePolyEdge.class, "edgeClass", | |
494 | modelElement, descr)); | |
495 | } | |
496 | ||
497 | /** | |
498 | * Factory method to build an Action for creating an edge in the | |
499 | * diagram. | |
500 | * | |
501 | * @param modeClass the mode class to instantiate drawing | |
502 | * @param metaType identifies the model element type to make | |
503 | * @param descr the description to give this action. | |
504 | * @return The action to create a new node. | |
505 | */ | |
506 | protected Action makeCreateDependencyAction( | |
507 | Class modeClass, | |
508 | Object metaType, | |
509 | String descr) { | |
510 | 3084 | return new RadioAction( |
511 | new ActionSetMode(modeClass, "edgeClass", metaType, descr)); | |
512 | } | |
513 | ||
514 | /** | |
515 | * Factory method to build an Action for creating an edge in the | |
516 | * diagram. | |
517 | * @return The action to create a new generalization mode. | |
518 | */ | |
519 | protected Action makeCreateGeneralizationAction() { | |
520 | 1028 | return new RadioAction( |
521 | new ActionSetMode( | |
522 | ModeCreateGeneralization.class, | |
523 | "edgeClass", | |
524 | Model.getMetaTypes().getGeneralization(), | |
525 | "button.new-generalization")); | |
526 | } | |
527 | ||
528 | /** | |
529 | * Factory method to build an Action for creating an association edge in | |
530 | * the diagram. | |
531 | * | |
532 | * @param aggregationKind the type of aggregation for this association | |
533 | * @param unidirectional true if this is a one way association. | |
534 | * @param descr the description to give this action. | |
535 | * @return The action to create a new association. | |
536 | */ | |
537 | protected Action makeCreateAssociationAction( | |
538 | Object aggregationKind, | |
539 | boolean unidirectional, | |
540 | String descr) { | |
541 | ||
542 | 6168 | return new RadioAction( |
543 | new ActionSetAddAssociationMode(aggregationKind, | |
544 | unidirectional, descr)); | |
545 | } | |
546 | ||
547 | /** | |
548 | * Factory method to build an Action for creating an association end edge | |
549 | * in the diagram. | |
550 | * | |
551 | * @param descr the description to give this action. | |
552 | * @return The action to create a new association. | |
553 | */ | |
554 | protected Action makeCreateAssociationEndAction(String descr) { | |
555 | ||
556 | 1028 | return new RadioAction(new ActionSetAddAssociationEndMode(descr)); |
557 | } | |
558 | ||
559 | /** | |
560 | * Factory method to build an Action for creating an edge in the | |
561 | * diagram. | |
562 | * | |
563 | * @param descr the description to give this action. | |
564 | * @return The action to create a new node. | |
565 | */ | |
566 | protected Action makeCreateAssociationClassAction(String descr) { | |
567 | 1028 | return new RadioAction(new ActionSetAddAssociationClassMode(descr)); |
568 | } | |
569 | ||
570 | /** | |
571 | * Reset the diagram serial counter to the initial value. This should e.g. | |
572 | * be done when the menuitem File->New is activated. | |
573 | * | |
574 | * @deprecated for 0.27.3 by tfmorris. This is a noop. Diagram name | |
575 | * duplication is checked for and managed at the project level. | |
576 | */ | |
577 | @Deprecated | |
578 | public void resetDiagramSerial() { | |
579 | 0 | } |
580 | ||
581 | /** | |
582 | * @return Returns the diagramSerial. | |
583 | * @deprecated for 0.27.3 by tfmorris. This is always returns 1. Diagram | |
584 | * naming is managed at the project level. | |
585 | */ | |
586 | @Deprecated | |
587 | protected int getNextDiagramSerial() { | |
588 | 0 | return 1; |
589 | } | |
590 | ||
591 | /** | |
592 | * @return a string that can be used as a label for this kind of diagram | |
593 | */ | |
594 | public abstract String getLabelName(); | |
595 | ||
596 | /* | |
597 | * @see org.argouml.ui.explorer.Relocatable#isRelocationAllowed(java.lang.Object) | |
598 | */ | |
599 | public abstract boolean isRelocationAllowed(Object base); | |
600 | ||
601 | /* | |
602 | * @see org.argouml.ui.explorer.Relocatable#relocate(java.lang.Object) | |
603 | */ | |
604 | public abstract boolean relocate(Object base); | |
605 | ||
606 | @Override | |
607 | public final void setProject(Project p) { | |
608 | 2116 | super.setProject(p); |
609 | 2116 | UMLMutableGraphSupport gm = (UMLMutableGraphSupport) getGraphModel(); |
610 | 2116 | gm.setProject(p); |
611 | 2116 | } |
612 | ||
613 | /** | |
614 | * Create a new diagram name. | |
615 | * @return String | |
616 | */ | |
617 | protected String getNewDiagramName() { | |
618 | // TODO: Add "unnamed" or "new" or something? (Localized, of course) | |
619 | 2116 | return /*"unnamed " + */ getLabelName(); |
620 | } | |
621 | ||
622 | /** | |
623 | * Method to test it the diagram can accept a certain object. | |
624 | * This should be overridden by any diagram that wants to accept a certain | |
625 | * type of object. All other diagrams should not bother since the default | |
626 | * answer is false, ie. don't accept the object. | |
627 | * @param objectToAccept The object which acceptability will be checked. | |
628 | * @return True if it can accept it, false otherwise. | |
629 | */ | |
630 | public boolean doesAccept( | |
631 | @SuppressWarnings("unused") Object objectToAccept) { | |
632 | 0 | return false; |
633 | } | |
634 | ||
635 | /** | |
636 | * Handles elements dropped over. | |
637 | * @param droppedObject The dropped object. | |
638 | * @param location The location in the diagram where the object is dropped. | |
639 | * @return The object that has been added to the diagram. | |
640 | */ | |
641 | public DiagramElement drop(Object droppedObject, Point location) { | |
642 | // If location is non-null, convert to a rectangle that we can use | |
643 | 0 | Rectangle bounds = null; |
644 | 0 | if (location != null) { |
645 | 0 | bounds = new Rectangle(location.x, location.y, 0, 0); |
646 | } | |
647 | ||
648 | 0 | return createDiagramElement(droppedObject, bounds); |
649 | } | |
650 | ||
651 | /** | |
652 | * Gets the instructions to be displayed on the status bar. | |
653 | * @param droppedObject The object for which instructions will be given. | |
654 | * @return The instructions. | |
655 | */ | |
656 | public String getInstructions(Object droppedObject) { | |
657 | 0 | return Translator.localize("misc.message.click-on-diagram-to-add", |
658 | new Object[] {Model.getFacade().toString(droppedObject), }); | |
659 | } | |
660 | ||
661 | /** | |
662 | * Creates a diagram specific @see org.tigris.gef.base.ModePlace that | |
663 | * allows the diagram to place an accepted type of object | |
664 | * [ @see #doesAccept(Object) ] as it should. This is required 1. since a | |
665 | * diagram may receive an object that can't be placed as is, but needs some | |
666 | * transformation and 2. diagrams in modules should be independent from the | |
667 | * main app, and should use their own implementation of ModePlace if it's | |
668 | * required. | |
669 | * @param gf TODO | |
670 | * @param instructions a help string for the user | |
671 | * @return The created ModePlace. | |
672 | */ | |
673 | public ModePlace getModePlace(GraphFactory gf, String instructions) { | |
674 | 0 | return new ModePlace(gf, instructions); |
675 | } | |
676 | ||
677 | /** | |
678 | * Create a nary association diamond shaped FigNode on this diagram. | |
679 | * | |
680 | * @param modelElement the model element this FigNode is to represent | |
681 | * @param bounds the position and size for the diamond node. | |
682 | * @param settings the diagram setting for presentation. | |
683 | * @return The FigNode of the diamond representing the model element | |
684 | */ | |
685 | protected FigNodeModelElement createNaryAssociationNode( | |
686 | final Object modelElement, | |
687 | final Rectangle bounds, | |
688 | final DiagramSettings settings) { | |
689 | ||
690 | 0 | final FigNodeAssociation diamondFig = |
691 | new FigNodeAssociation(modelElement, bounds, settings); | |
692 | 0 | if (Model.getFacade().isAAssociationClass(modelElement) |
693 | && bounds != null) { | |
694 | 0 | final FigClassAssociationClass classBoxFig = |
695 | new FigClassAssociationClass( | |
696 | modelElement, bounds, settings); | |
697 | 0 | final FigEdgeAssociationClass dashEdgeFig = |
698 | new FigEdgeAssociationClass( | |
699 | classBoxFig, diamondFig, settings); | |
700 | 0 | classBoxFig.renderingChanged(); |
701 | ||
702 | // TODO: Why isn't this calculation for location working? | |
703 | 0 | Point location = bounds.getLocation(); |
704 | 0 | location.y = (location.y - diamondFig.getHeight()) - 32; |
705 | 0 | if (location.y < 16) { |
706 | 0 | location.y = 16; |
707 | } | |
708 | 0 | classBoxFig.setLocation(location); |
709 | 0 | this.add(diamondFig); |
710 | 0 | this.add(classBoxFig); |
711 | 0 | this.add(dashEdgeFig); |
712 | } | |
713 | 0 | return diamondFig; |
714 | } | |
715 | } |