001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.uml.ui.swing.drawingarea.diagramtools;
043:
044: import java.awt.Point;
045: import java.awt.event.MouseEvent;
046: import java.awt.Cursor;
047: import java.util.List;
048:
049: import javax.swing.SwingUtilities;
050:
051: //import com.tomsawyer.util.TSConstPoint;
052: import com.tomsawyer.drawing.geometry.TSConstPoint;
053: import com.tomsawyer.drawing.TSConnector;
054: import com.tomsawyer.editor.TSEConnector;
055: import com.tomsawyer.editor.TSEEdge;
056: import com.tomsawyer.editor.TSEObject;
057: import com.tomsawyer.editor.TSEObjectUI; //import com.tomsawyer.editor.TSEWindowInputState;
058: import com.tomsawyer.editor.TSEWindowInputTool;
059: import com.tomsawyer.editor.TSENode; //import com.tomsawyer.editor.state.TSEReconnectEdgeState;
060: import com.tomsawyer.editor.tool.TSEReconnectEdgeTool; //import com.tomsawyer.editor.state.TSESelectState;
061: import com.tomsawyer.editor.tool.TSESelectTool;
062: import com.tomsawyer.editor.ui.TSENodeUI;
063:
064: import org.netbeans.modules.uml.ui.support.CreationFactoryHelper;
065: import org.netbeans.modules.uml.ui.support.viewfactorysupport.ETPointEx;
066: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IETEdge;
067: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IETNode;
068: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IEdgeDrawEngine;
069: import org.netbeans.modules.uml.common.ETSystem;
070: import org.netbeans.modules.uml.common.generics.ETPairT;
071: import org.netbeans.modules.uml.common.generics.IteratorT;
072: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
073: import org.netbeans.modules.uml.core.metamodel.diagrams.IDiagram;
074: import org.netbeans.modules.uml.core.support.umlsupport.ETPoint;
075: import org.netbeans.modules.uml.core.support.umlsupport.IETPoint;
076: import org.netbeans.modules.uml.core.support.umlutils.ETArrayList;
077: import org.netbeans.modules.uml.ui.products.ad.viewfactory.IETGraphObjectUI;
078:
079: import org.netbeans.modules.uml.ui.support.relationshipVerification.AddEdgeEventDispatcher;
080: import org.netbeans.modules.uml.ui.support.relationshipVerification.IEdgeVerification;
081: import org.netbeans.modules.uml.ui.support.relationshipVerification.IReconnectEdgeEvents;
082: import org.netbeans.modules.uml.ui.support.relationshipVerification.ReconnectEdgeEvents;
083: import org.netbeans.modules.uml.ui.products.ad.viewfactory.ETGenericEdgeUI;
084: import org.netbeans.modules.uml.ui.products.ad.drawengines.ETEdgeDrawEngine;
085: import org.netbeans.modules.uml.ui.products.ad.graphobjects.ETEdge;
086:
087: import org.netbeans.modules.uml.ui.support.applicationmanager.IEdgePresentation;
088: import org.netbeans.modules.uml.ui.swing.drawingarea.ADGraphWindow;
089: import org.netbeans.modules.uml.ui.swing.drawingarea.IDrawingAreaControl;
090: import org.netbeans.modules.uml.ui.swing.drawingarea.IReconnectEdgeContext;
091: import org.netbeans.modules.uml.ui.swing.drawingarea.ReconnectEdgeContext;
092: import org.netbeans.modules.uml.ui.swing.drawingarea.cursors.NoDropCursor;
093: import org.netbeans.modules.uml.core.support.Debug;
094:
095: /*
096: *
097: * @author KevinM
098: *
099: * This class dispatches the IReconnectEdgeEvents via aggregation of the ReconnectEdgeEvents class.
100: */
101: //public class ADReconnectEdgeState extends TSEReconnectEdgeState implements IReconnectEdgeEvents
102: public class ADReconnectEdgeState extends TSEReconnectEdgeTool
103: implements IReconnectEdgeEvents {
104: protected IEdgeVerification m_IEdgeVerification;
105: protected Cursor m_defaultCuror = null;
106: protected Cursor m_noDropCursor;
107: protected TSENode m_orginalSourceNode;
108: protected TSENode m_orginalTargetNode;
109: protected IReconnectEdgeEvents m_eventDispatcher = null;
110: protected TSConstPoint m_lastMousePos;
111: protected boolean m_reconnectedEdge = false;
112: protected TSEConnector m_associatedConnector = null;
113:
114: /*
115: * Constructor for ADReconnectEdgeState
116: */
117: // public ADReconnectEdgeState(TSEWindowInputState parentState)
118: public ADReconnectEdgeState(TSEWindowInputTool parentState) {
119: super (parentState);
120: m_IEdgeVerification = null;
121: m_noDropCursor = NoDropCursor.getCursor();
122: }
123:
124: /*
125: * Returns true if the user has the mouse over an edge clipping point on a incident node.
126: */
127: public boolean possibleSourceAt(TSConstPoint pt) {
128: return super .possibleSourceAt(pt);
129: }
130:
131: /*
132: * Called by the super class just before the connectEdge is made, returns true to allow the reconnection.
133: */
134: public boolean possibleTargetAt(TSConstPoint pt) {
135: boolean mouseOverNode = isPointOverNode(pt);
136:
137: if (mouseOverNode && verifyReconnectTarget(pt)) {
138: setCursor(m_defaultCuror);
139: return super .possibleTargetAt(pt);
140: } else if (mouseOverNode) {
141: showNoDropCursor();
142: } else {
143: setCursor(m_defaultCuror);
144: }
145: return false;
146: }
147:
148: /*
149: * Displays the NoDrop Cursor.
150: */
151: protected void showNoDropCursor() {
152: setCursor(m_noDropCursor);
153: }
154:
155: /*
156: * Called by the super class when its time to reconnect the edge, please see onMousedReleased.
157: */
158: public void connectEdge() {
159: try {
160: boolean reconnectingTarget = this .isReconnectingTarget();
161: if (verifyReconnectTarget(m_lastMousePos)) {
162: if (m_associatedConnector != null) {
163: if (reconnectingTarget) {
164: setTargetConnector(m_associatedConnector);
165: } else {
166: setSourceConnector(m_associatedConnector);
167: }
168:
169: TSENode target = getTargetNode();
170: TSENode source = getSourceNode();
171:
172: ETPairT<List, List> bendPoints = getReconnectEdgeBendPoints();
173:
174: try {
175: ETGenericEdgeUI ui = (ETGenericEdgeUI) getEdge()
176: .getUI();
177: /*
178: * Reconnect the interactive Edge from the hidden node to the target node.
179: */
180: ETEdge createdEdge = (ETEdge) getGraphWindow()
181: .reconnectEdge(
182: getEdge(),
183: reconnectingTarget ? target
184: : source,
185: m_associatedConnector,
186: !reconnectingTarget,
187: bendPoints.getParamOne(),
188: bendPoints.getParamTwo());
189:
190: if (createdEdge != null) {
191: ui.setOwner(createdEdge);
192: createdEdge.setUI(ui);
193:
194: setDefaultState();
195: }
196: } catch (Exception e) {
197: // Just it ignore this exception its just an assertion.
198: }
199: } else {
200: super .connectEdge();
201: }
202: //
203: m_associatedConnector = null;
204: } else {
205: cancelAction();
206: }
207: } catch (Exception e) {
208: ETSystem.out.println(e.getMessage());
209: }
210: }
211:
212: /*
213: * Returns the Edge Verification interface.
214: */
215: protected IEdgeVerification getVerification() {
216: if (m_IEdgeVerification == null) {
217: CreationFactoryHelper helper = new CreationFactoryHelper();
218: m_IEdgeVerification = helper.getEdgeVerification();
219: }
220: return m_IEdgeVerification;
221: }
222:
223: /*
224: * Returns the Rubberbands Drawengine interface.
225: */
226: protected IEdgeDrawEngine getDrawEngine() {
227: TSEEdge edge = getEdge();
228: if (edge != null && edge.getUI() instanceof IETGraphObjectUI) {
229: IETGraphObjectUI ui = (IETGraphObjectUI) edge.getUI();
230: if (ui != null
231: && ui.getDrawEngine() instanceof IEdgeDrawEngine) {
232: return (IEdgeDrawEngine) ui.getDrawEngine();
233: }
234: }
235: return null;
236: }
237:
238: /*
239: * (non-Javadoc)
240: * @see com.tomsawyer.editor.state.TSEBuildEdgeState#initBuildEdge()
241: */
242: protected void initBuildEdge() {
243: m_associatedConnector = null;
244: m_reconnectedEdge = false;
245: m_orginalTargetNode = (TSENode) getEdge().getTargetNode();
246: m_orginalSourceNode = (TSENode) getEdge().getSourceNode();
247:
248: if (fireReconnectEdgeStart(this .getReconnectContext()) == true) {
249: // Flash the ghost busters sign.
250: this .showNoDropCursor();
251: this .cancelAction();
252: return;
253: } else {
254: super .initBuildEdge();
255: m_defaultCuror = getDefaultCursor();
256:
257: if (!getAllowReconnection()) {
258: this .cancelAction();
259: return;
260: }
261: }
262: }
263:
264: /*
265: * Returns true if we're allowed to reconnect this ModelElement type and the drawing isn't readonly.
266: */
267: protected boolean getAllowReconnection() {
268: IEdgeDrawEngine drawEngine = getDrawEngine();
269: return drawEngine != null && drawEngine.getAllowReconnection()
270: && verifyReconnectStart();
271: }
272:
273: /*
274: * Returns true if we can start the reconnect process with this Model element type.
275: */
276: protected boolean verifyReconnectStart() {
277: return getVerification().verifyReconnectStart(
278: this .isReconnectingTarget() ? this .getTargetElement()
279: : this .getSourceElement(),
280: getDrawEngine().getElementType());
281: }
282:
283: /*
284: * Returns the orginal source node's UI.
285: */
286: protected IETGraphObjectUI getSourceUI() {
287: return m_orginalSourceNode != null ? (IETGraphObjectUI) this .m_orginalSourceNode
288: .getUI()
289: : null;
290: }
291:
292: /*
293: * Returns the orginal target node's UI
294: */
295: protected IETGraphObjectUI getTargetUI() {
296: return m_orginalTargetNode != null ? (IETGraphObjectUI) this .m_orginalTargetNode
297: .getUI()
298: : null;
299: }
300:
301: /*
302: * Returns true if the object under the logical world pt is a valid reconnection target.
303: */
304: protected boolean verifyReconnectTarget(TSConstPoint pt) {
305: return verifyReconnectTarget(getUIAt(pt));
306: }
307:
308: /*
309: * Returns true if the object at the mouse event is a valid reconnection target.
310: */
311: protected boolean verifyReconnectTarget(MouseEvent pEvent) {
312: return verifyReconnectTarget(getUIAt(pEvent));
313: }
314:
315: /*
316: * Returns true if the ui' model element is valid reconnection target.
317: */
318: protected boolean verifyReconnectTarget(IETGraphObjectUI hitUI) {
319: if (hitUI == null)
320: return false;
321:
322: boolean verified = false;
323: IElement fromElement;
324: IElement toElement;
325:
326: /* Figure out which Model Elements depending if we are reconnecting our target
327: * or source node.
328: */
329: if (isReconnectingTarget()) {
330: fromElement = getSourceElement();
331: toElement = hitUI.getModelElement();
332: } else {
333: fromElement = hitUI.getModelElement();
334: toElement = getTargetElement();
335: }
336:
337: if (fromElement != null && toElement != null
338: && getDrawEngine() != null) {
339: return getVerification().verifyFinishNode(fromElement,
340: toElement, getDrawEngine().getElementType());
341: }
342: return false;
343: }
344:
345: /*
346: * Returns true if the current target node is valid reconnection target.
347: */
348: protected boolean verifyReconnectTarget() {
349: // We don't want to use the orginal nodes for this one we want the final UI's.
350: return verifyReconnectTarget(this .isReconnectingTarget() ? (IETGraphObjectUI) super
351: .getTargetNode().getUI()
352: : (IETGraphObjectUI) super .getSourceNode().getUI());
353: }
354:
355: /*
356: * Helper function that returns the model element given a node.
357: */
358: protected IElement getNodeElement(TSENode tsNode) {
359: IETGraphObjectUI nodeUI = tsNode != null ? (IETGraphObjectUI) tsNode
360: .getUI()
361: : null;
362: return nodeUI != null ? nodeUI.getModelElement() : null;
363: }
364:
365: /*
366: * Returns the orginal source nodes model element.
367: */
368: protected IElement getSourceElement() {
369: return getNodeElement(m_orginalSourceNode);
370: }
371:
372: /*
373: * Returns the orginal target nodes model element.
374: */
375: protected IElement getTargetElement() {
376: return getNodeElement(m_orginalTargetNode);
377: }
378:
379: /*
380: * Copied from the CreateEdgeState, if you can't create bends durning create edge you might not be able to durning reconnect.
381: * Give the listeners another chance to control the reconnect process.
382: */
383: protected boolean fireShouldCreateBendEvent(TSConstPoint point) {
384: AddEdgeEventDispatcher dispatch = new AddEdgeEventDispatcher(
385: getDrawingArea().getDrawingAreaDispatcher(),
386: getDrawingArea().getDiagram(), "");
387: return dispatch.fireShouldCreateBendEvent(point);
388: }
389:
390: /*
391: * (non-Javadoc)
392: * @see com.tomsawyer.editor.TSEWindowInputState#onMousePressed(java.awt.event.MouseEvent)
393: */
394: public void onMousePressed(MouseEvent pEvent) {
395: m_lastMousePos = getNonalignedWorldPoint(pEvent);
396:
397: boolean eventHandled = false;
398: boolean isLeftBtn = isLeftMouseEvent(pEvent);
399:
400: // Give the drawEngine first crack.
401: IEdgeDrawEngine drawEngine = getDrawEngine();
402: if (drawEngine != null && isLeftBtn) {
403: if (this .isDragInProgress()) {
404: eventHandled = drawEngine.handleLeftMouseBeginDrag(
405: getETPoint(m_lastMousePos),
406: getETPoint(m_lastMousePos));
407: } else {
408: eventHandled = drawEngine.handleLeftMouseButton(pEvent);
409: }
410: }
411:
412: if (!eventHandled) {
413: if (pEvent.isPopupTrigger() || !isLeftBtn) {
414: // Kill the reconnection process.
415: this .cancelAction();
416: }
417:
418: if (!isReconnecting()) {
419: super .onMousePressed(pEvent); // Start the connection process.
420: } else {
421: // Check for bends, if the don't hit a graph object.
422: if (!isMouseOverNode(pEvent) && isLeftBtn
423: && fireShouldCreateBendEvent(m_lastMousePos)) {
424: super .onMousePressed(pEvent);
425: } else if (verifyReconnectTarget(pEvent)
426: && finishReconnection(pEvent)) {
427: super .onMousePressed(pEvent);
428: }
429: }
430: }
431: }
432:
433: /*
434: * Returns true if the mouse is currently over a node.
435: */
436: protected boolean isMouseOverNode(MouseEvent pEvent) {
437: return isPointOverNode(getNonalignedWorldPoint(pEvent));
438: }
439:
440: /*
441: * Returns true if the point is currently over a node.
442: */
443: protected boolean isPointOverNode(TSConstPoint pt) {
444: IETGraphObjectUI ui = getUIAt(pt);
445: return ui != null && ui instanceof TSENodeUI;
446: }
447:
448: /*
449: * Returns the visual cursor that should be displayed at this point.
450: */
451: public Cursor cursorFromPoint(TSConstPoint pt) {
452: boolean mouseOverNode = isPointOverNode(pt);
453: if (mouseOverNode && verifyReconnectTarget(pt)) {
454: return m_defaultCuror;
455: } else if (mouseOverNode) {
456: return m_noDropCursor;
457: } else {
458: return m_defaultCuror;
459: }
460: }
461:
462: /*
463: * Changes the cursor depending if we can connect at the current mouse position.
464: */
465: public void onMouseMoved(MouseEvent pEvent) {
466: TSConstPoint pt = getNonalignedWorldPoint(pEvent);
467: m_lastMousePos = pt;
468: //setCursor(cursorFromPoint(pt));
469:
470: IReconnectEdgeContext pContext = getReconnectContext(pt);
471:
472: boolean cancel = fireReconnectEdgeMouseMove(pContext);
473: if (cancel) {
474: if (getDisconnectedFromNode() != null
475: && getDisconnectedFromNode().getETUI() != getUIAt(pt))
476: this .showNoDropCursor();
477: // else they are trying to return the edge to the orginal target.
478: } else {
479: super .onMouseMoved(pEvent);
480: this .setCursor(m_defaultCuror);
481: refresh();
482: }
483:
484: if (!cancel) {
485: this .setCursor(m_defaultCuror);
486: }
487: }
488:
489: /*
490: * (non-Javadoc)
491: * @see com.tomsawyer.editor.TSEWindowInputState#onMouseDragged(java.awt.event.MouseEvent)
492: */
493: public void onMouseDragged(MouseEvent pEvent) {
494: boolean eventHandled = false;
495: m_lastMousePos = getNonalignedWorldPoint(pEvent);
496: IEdgeDrawEngine drawEngine = getDrawEngine();
497: setCursor(cursorFromPoint(m_lastMousePos));
498: if (drawEngine != null) {
499: IETPoint pt = getETPoint(pEvent);
500: eventHandled = drawEngine.handleLeftMouseDrag(pt, pt);
501: }
502:
503: if (!eventHandled) {
504: super .onMouseDragged(pEvent);
505: } else {
506: refresh();
507: }
508: }
509:
510: /*
511: * (non-Javadoc)
512: * @see com.tomsawyer.editor.TSEWindowInputState#onMouseClicked(java.awt.event.MouseEvent)
513: */
514: public void onMouseClicked(MouseEvent pEvent) {
515: m_lastMousePos = getNonalignedWorldPoint(pEvent);
516: boolean eventHandled = false;
517:
518: IEdgeDrawEngine drawEngine = getDrawEngine();
519:
520: if (drawEngine != null) {
521: if (isLeftMouseEvent(pEvent)) {
522: eventHandled = pEvent.getClickCount() == 2 ? drawEngine
523: .handleLeftMouseButtonDoubleClick(pEvent)
524: : drawEngine.handleLeftMouseButton(pEvent);
525: } else if (isRightMouseEvent(pEvent)) {
526: eventHandled = drawEngine
527: .handleRightMouseButton(pEvent);
528: }
529:
530: refresh();
531: }
532:
533: if (!eventHandled) {
534: super .onMouseClicked(pEvent);
535: }
536: }
537:
538: /*
539: * Conversion function
540: */
541: protected IETPoint getETPoint(TSConstPoint point) {
542: return point != null ? new ETPointEx(point) : new ETPoint(0, 0);
543: }
544:
545: /*
546: * Returns the mouse position for the event or the transformed into logical space
547: */
548: protected IETPoint getETPoint(MouseEvent pEvent, boolean transform) {
549: return !transform ? getETPoint(pEvent)
550: : getETPoint(getNonalignedWorldPoint(pEvent));
551: }
552:
553: /*
554: * Returns the mouse position for the event
555: */
556: protected IETPoint getETPoint(MouseEvent pEvent) {
557: Point mousePos = pEvent.getPoint();
558: return new ETPoint(mousePos.x, mousePos.y);
559: }
560:
561: protected boolean isLeftMouseEvent(MouseEvent pEvent) {
562: return SwingUtilities.isLeftMouseButton(pEvent);
563: }
564:
565: protected boolean isRightMouseEvent(MouseEvent pEvent) {
566: return !isLeftMouseEvent(pEvent);
567: }
568:
569: /*
570: * (non-Javadoc)
571: * @see com.tomsawyer.editor.TSEWindowInputState#onMouseReleased(java.awt.event.MouseEvent)
572: */
573: public void onMouseReleased(MouseEvent pEvent) {
574: boolean eventHandled = false;
575: IEdgeDrawEngine drawEngine = getDrawEngine();
576: if (drawEngine != null && isLeftMouseEvent(pEvent)) {
577: if (pEvent.isControlDown()) {
578: eventHandled = drawEngine.handleLeftMouseDrop(
579: getETPoint(pEvent), null, false);
580: } else {
581: eventHandled = drawEngine.handleLeftMouseDrop(
582: getETPoint(pEvent), null, true);
583: }
584:
585: refresh();
586: }
587:
588: if (!eventHandled) {
589: eventHandled = !this .finishReconnection(pEvent);
590: }
591:
592: if (!eventHandled) {
593: super .onMouseReleased(pEvent);
594: // reset.
595: m_reconnectedEdge = false;
596: } else {
597: if (getDisconnectedFromNode() != null
598: && getDisconnectedFromNode().getETUI() == getUIAt(pEvent)) {
599: // They are trying to return the edge to the orginal node, just cancel out.
600: this .cancelAction();
601: } else {
602: this .showNoDropCursor();
603: }
604: }
605:
606: }
607:
608: /*
609: * Returns true if we are reconnecting the target node of this edge.
610: */
611: protected boolean isReconnectingTarget() {
612: return !this .isReconnectingSource();
613: }
614:
615: /*
616: * Hit testing function.
617: */
618: protected IETGraphObjectUI getUIAt(TSConstPoint pt) {
619: // TSEObject obj = this.getObjectAt(pt, null, this.getGraphWindow().getGraph());
620: TSEObject obj = this .getHitTesting().getGraphObjectAt(pt,
621: this .getGraphWindow().getGraph(), true);
622: if (obj instanceof TSEConnector) {
623: obj = (TSEObject) ((TSEConnector) obj).getOwner();
624: }
625:
626: /*
627: * We don't want to return ourselves.
628: */
629: if (getEdge() == obj) {
630: // obj = this.getObjectAt(pt, getEdge(), this.getGraphWindow().getGraph());
631: obj = this .getHitTesting().getGraphObjectAt(pt,
632: this .getGraphWindow().getGraph(), true);
633:
634: }
635: return obj != null && obj.getUI() instanceof IETGraphObjectUI ? (IETGraphObjectUI) obj
636: .getUI()
637: : null;
638: }
639:
640: /*
641: * Hit testing function.
642: */
643: protected IETGraphObjectUI getUIAt(MouseEvent pEvent) {
644: return getUIAt(getNonalignedWorldPoint(pEvent));
645: }
646:
647: /*
648: * Used by the reconnect context, returns the current presentation element for this edge
649: */
650: protected IEdgePresentation getIEdgePresentation() {
651: if (this .getDrawEngine() instanceof ETEdgeDrawEngine) {
652: ETEdgeDrawEngine de = (ETEdgeDrawEngine) this
653: .getDrawEngine();
654: return de.getIEdgePresentation();
655: } else {
656: return null;
657: }
658: }
659:
660: /*
661: * Returns the Anchored Node used by the Reconnect edge Events, the node returned depends if
662: * we are reconnecting the source or target end of the edge.
663: */
664: protected IETNode getAnchoredNode() {
665: return isReconnectingTarget() ? (IETNode) m_orginalSourceNode
666: : (IETNode) m_orginalTargetNode;
667: }
668:
669: /*
670: * Returns the opposite end from the AnchoredNode, the node that we just disconnected from.
671: */
672: protected IETNode getDisconnectedFromNode() {
673: return isReconnectingTarget() ? (IETNode) m_orginalTargetNode
674: : (IETNode) m_orginalSourceNode;
675: }
676:
677: /*
678: * Returns an IReconnectEdgeContext, used to fire the reconnection events.
679: */
680: protected IReconnectEdgeContext getReconnectContext(TSConstPoint pt) {
681: IETEdge edge = getIETEdge();
682:
683: IReconnectEdgeContext reconnectContext = new ReconnectEdgeContext();
684: reconnectContext.setEdge(edge);
685: reconnectContext.setReconnectTarget(isReconnectingTarget());
686: reconnectContext.setAnchoredNode(getAnchoredNode());
687:
688: reconnectContext.setLogicalPoint(getETPoint(pt));
689:
690: if (edge != null)
691: reconnectContext
692: .setPreConnectNode(isReconnectingTarget() ? edge
693: .getToNode() : edge.getFromNode());
694:
695: IETGraphObjectUI hitUI = getUIAt(pt);
696: if (hitUI != null) {
697: TSEObject ProposedEnd = hitUI.getDrawEngine().getParent()
698: .getOwner();
699:
700: if (ProposedEnd instanceof TSENode) {
701: reconnectContext
702: .setProposedEndNode((IETNode) ProposedEnd);
703: } else if (ProposedEnd instanceof TSEConnector) {
704: TSEConnector connector = (TSEConnector) ProposedEnd;
705: reconnectContext.setProposedEndNode((IETNode) connector
706: .getOwner());
707: }
708: }
709: return reconnectContext;
710: }
711:
712: protected TSConstPoint getEndPoint() {
713: ETEdgeDrawEngine de = (ETEdgeDrawEngine) this .getDrawEngine();
714: if (de != null) {
715: ETPairT<TSConstPoint, TSConstPoint> lineSegment;
716: if (this .isReconnectingTarget()) {
717: lineSegment = de.getFromLineSegment();
718: return lineSegment != null ? lineSegment.getParamTwo()
719: : null;
720: } else {
721: lineSegment = de.getToLineSegment();
722: return lineSegment != null ? lineSegment.getParamOne()
723: : null;
724: }
725: }
726: return null;
727: }
728:
729: protected TSConstPoint getStartingPoint() {
730: ETEdgeDrawEngine de = (ETEdgeDrawEngine) this .getDrawEngine();
731: if (de != null) {
732: ETPairT<TSConstPoint, TSConstPoint> lineSegment;
733: if (this .isReconnectingTarget()) {
734: lineSegment = de.getToLineSegment();
735: return lineSegment != null ? lineSegment.getParamOne()
736: : null;
737: } else {
738: lineSegment = de.getFromLineSegment();
739: return lineSegment != null ? lineSegment.getParamTwo()
740: : null;
741: }
742: }
743: return null;
744: }
745:
746: /*
747: *
748: */
749: protected IReconnectEdgeContext getReconnectContext() {
750: TSConstPoint pt = getStartingPoint();
751:
752: return pt != null ? getReconnectContext(pt) : null;
753: }
754:
755: /*
756: * Returns an IReconnectEdgeContext, used to fire the reconnection events.
757: */
758: protected IReconnectEdgeContext getReconnectContext(
759: MouseEvent pEvent) {
760: return getReconnectContext(getNonalignedWorldPoint(pEvent));
761: }
762:
763: /*
764: * Returns true if the Edge was reconnected.
765: */
766: public boolean finishReconnection(TSConstPoint atPt) {
767: boolean connected = false;
768: IReconnectEdgeContext pContext = getReconnectContext(atPt);
769: boolean cancel = m_reconnectedEdge == false ? fireReconnectEdgeFinish(pContext)
770: : false;
771: if (cancel) {
772: //showNoDropCursor();
773: //this.cancelAction();
774: connected = false;
775: } else {
776: if (pContext.getAssociatedConnector() != null
777: && pContext.getEdge() != null) {
778: m_associatedConnector = (TSEConnector) pContext
779: .getAssociatedConnector();
780: }
781: connected = true;
782: }
783:
784: return connected;
785: }
786:
787: /*
788: * Gets called when the mouse is released only if the drawEngine didn't handle this event.
789: */
790: public boolean finishReconnection(MouseEvent pEvent) {
791: boolean handled;
792:
793: if (verifyReconnectTarget(pEvent)) {
794: handled = this .finishReconnection(this
795: .getNonalignedWorldPoint(pEvent));
796: } else {
797: handled = false;
798: }
799:
800: if (handled) {
801: pEvent.consume();
802: }
803:
804: return handled;
805: }
806:
807: /*
808: * Repaints the window.
809: */
810: protected void refresh() {
811: getGraphWindow().drawGraph();
812: getGraphWindow().fastRepaint();
813: }
814:
815: /*
816: * Returns the Rubberband edge cast to and IETEdge interface.
817: */
818: public IETEdge getIETEdge() {
819: TSEEdge edge = getEdge();
820: return edge instanceof IETEdge ? (IETEdge) edge : null;
821: }
822:
823: /*
824: * Returns the DrawingArea Control.
825: */
826: protected IDrawingAreaControl getDrawingArea() {
827: ADGraphWindow graphWindow = getGraphWindow() instanceof ADGraphWindow ? (ADGraphWindow) getGraphWindow()
828: : null;
829: return graphWindow != null ? graphWindow.getDrawingArea()
830: : null;
831: }
832:
833: /*
834: * Returns the IReconnectEdgeEvents Event Dispatcher.
835: */
836: protected IReconnectEdgeEvents getEventDispatcher() {
837: if (m_eventDispatcher == null)
838: m_eventDispatcher = new ReconnectEdgeEvents(
839: getDrawingArea().getDrawingAreaDispatcher(),
840: getDrawingArea().getDiagram());
841:
842: return m_eventDispatcher;
843: }
844:
845: /* (non-Javadoc)
846: * @see com.tomsawyer.editor.TSEWindowState#cancelAction()
847: */
848: public void cancelAction() {
849: try {
850: // Return to out parent state.
851: this .stopMouseInput();
852: super .cancelAction();
853: } catch (Exception e) {
854: //finalizeState();
855: finalizeTool();
856: }
857: }
858:
859: /* (non-Javadoc)
860: * @see org.netbeans.modules.uml.ui.support.relationshipVerification.IReconnectEdgeEvents#createReconnectEdgeContext(com.tomsawyer.util.TSConstPoint, org.netbeans.modules.uml.ui.support.viewfactorysupport.IETEdge, boolean, org.netbeans.modules.uml.ui.support.viewfactorysupport.IETNode, org.netbeans.modules.uml.ui.support.viewfactorysupport.IETNode, org.netbeans.modules.uml.ui.support.viewfactorysupport.IETNode)
861: */
862: public IReconnectEdgeContext createReconnectEdgeContext(
863: TSConstPoint point, IETEdge pEdge,
864: boolean bReconnectTarget, IETNode pAnchoredNode,
865: IETNode pPreConnectNode, IETNode pProposedEndNode) {
866: IReconnectEdgeContext reconnectContext = new ReconnectEdgeContext();
867: reconnectContext.setEdge(pEdge);
868: reconnectContext.setReconnectTarget(bReconnectTarget);
869: reconnectContext.setAnchoredNode(pAnchoredNode);
870: reconnectContext.setPreConnectNode(pPreConnectNode);
871: reconnectContext.setProposedEndNode(pProposedEndNode);
872: return reconnectContext;
873: }
874:
875: /* (non-Javadoc)
876: * @see org.netbeans.modules.uml.ui.support.relationshipVerification.IReconnectEdgeEvents#fireReconnectEdgeFinish(org.netbeans.modules.uml.ui.swing.drawingarea.IReconnectEdgeContext)
877: */
878: public boolean fireReconnectEdgeFinish(
879: IReconnectEdgeContext pContext) {
880: return this .getEventDispatcher().fireReconnectEdgeFinish(
881: pContext);
882: }
883:
884: /* (non-Javadoc)
885: * @see org.netbeans.modules.uml.ui.support.relationshipVerification.IReconnectEdgeEvents#fireReconnectEdgeMouseMove(org.netbeans.modules.uml.ui.swing.drawingarea.IReconnectEdgeContext)
886: */
887: public boolean fireReconnectEdgeMouseMove(
888: IReconnectEdgeContext pContext) {
889: return this .getEventDispatcher().fireReconnectEdgeMouseMove(
890: pContext);
891: }
892:
893: /* (non-Javadoc)
894: * @see org.netbeans.modules.uml.ui.support.relationshipVerification.IReconnectEdgeEvents#fireReconnectEdgeStart(org.netbeans.modules.uml.ui.swing.drawingarea.IReconnectEdgeContext)
895: */
896: public boolean fireReconnectEdgeStart(IReconnectEdgeContext pContext) {
897: return this .getEventDispatcher().fireReconnectEdgeStart(
898: pContext);
899: }
900:
901: /* (non-Javadoc)
902: * @see org.netbeans.modules.uml.ui.support.relationshipVerification.IReconnectEdgeEvents#getParentDiagram()
903: */
904: public IDiagram getParentDiagram() {
905: return getEventDispatcher().getParentDiagram();
906: }
907:
908: /* (non-Javadoc)
909: * @see org.netbeans.modules.uml.ui.support.relationshipVerification.IReconnectEdgeEvents#setParentDiagram(org.netbeans.modules.uml.core.metamodel.diagrams.IDiagram)
910: */
911: public void setParentDiagram(IDiagram pParent) {
912: getEventDispatcher().setParentDiagram(pParent);
913: }
914:
915: protected ETPairT<List, List> getReconnectEdgeBendPoints() {
916: if (getEdge() != null) {
917: java.util.List bendPoints = this .getEdge().bendPoints();
918: java.util.List newBendPoints = new ETArrayList<TSConstPoint>();
919: IteratorT<TSConstPoint> iter = new IteratorT<TSConstPoint>(
920: bendPoints);
921: while (iter.hasNext()) {
922: newBendPoints.add((TSConstPoint) iter.next().clone());
923: }
924: return new ETPairT<List, List>(bendPoints, newBendPoints);
925: } else
926: return new ETPairT<List, List>();
927: }
928:
929: protected void setDefaultState() {
930: try {
931: // We need to recreate this, becuase we don't call the super.connectEdge() when dealing with connectors.
932: // and we have drawing problems the second time this tool is used.
933: if (this .getParentTool() instanceof TSESelectTool) {
934: //TSESelectState pSelect = (TSESelectState)getParentState();
935: TSESelectTool pSelect = (TSESelectTool) getParentTool();
936: // pSelect.setReconnectEdgeState(new ADReconnectEdgeState(pSelect));
937: pSelect.setReconnectEdgeTool(new ADReconnectEdgeState(
938: pSelect));
939: }
940:
941: ((ADGraphWindow) this .getGraphWindow()).getDrawingArea()
942: .switchToDefaultState();
943:
944: } catch (Exception e) {
945: e.printStackTrace();
946: }
947: }
948:
949: //JM: Fix for Bug#6263430
950: public void addDirtyRegion(TSEObject object) {
951: if (object == null) {
952: //Debug.out.println("addDirtyRegion == object null.. so do nothing..");
953: } else {
954: super.addDirtyRegion(object);
955: }
956: }
957: }
|