001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.soa.mapper.basicmapper.canvas.jgo;
021:
022: import java.awt.Component;
023: import java.awt.Cursor;
024: import java.awt.Point;
025: import java.awt.datatransfer.DataFlavor;
026: import java.awt.datatransfer.Transferable;
027: import java.awt.dnd.DragGestureEvent;
028: import java.awt.dnd.DragSourceContext;
029: import java.awt.dnd.DragSourceDropEvent;
030: import java.awt.dnd.DropTargetDragEvent;
031: import java.awt.dnd.DropTargetDropEvent;
032: import java.awt.dnd.DropTargetEvent;
033: import java.util.ArrayList;
034: import java.util.Collection;
035: import java.util.Iterator;
036: import java.util.logging.Logger;
037:
038: import com.nwoods.jgo.JGoObject;
039: import com.nwoods.jgo.JGoView;
040: import org.netbeans.modules.soa.mapper.basicmapper.MapperLink;
041: import org.netbeans.modules.soa.mapper.basicmapper.methoid.BasicAccumulatingMethoidNode;
042: import org.netbeans.modules.soa.mapper.basicmapper.methoid.BasicMethoidNode;
043: import org.netbeans.modules.soa.mapper.basicmapper.util.MapperUtilities;
044: import org.netbeans.modules.soa.mapper.common.basicmapper.IBasicMapperView;
045: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasFieldNode;
046: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasMapperLink;
047: import org.netbeans.modules.soa.mapper.common.basicmapper.canvas.gtk.ICanvasMethoidNode;
048: import org.netbeans.modules.soa.mapper.common.basicmapper.dnd.IBasicDragController;
049: import org.netbeans.modules.soa.mapper.common.basicmapper.methoid.IMethoid;
050: import org.netbeans.modules.soa.mapper.common.basicmapper.tree.IMapperTreeNode;
051: import org.netbeans.modules.soa.mapper.common.IMapperLink;
052: import org.netbeans.modules.soa.mapper.common.IMapperLinkFromLinkRequest;
053: import org.netbeans.modules.soa.mapper.common.IMapperLinkFromNodeRequest;
054: import org.netbeans.modules.soa.mapper.common.IMapperNode;
055: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasGroupNode;
056: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasLink;
057: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasMouseData;
058: import org.netbeans.modules.soa.mapper.common.gtk.ICanvasNode;
059:
060: /**
061: * <p>
062: *
063: * Title: </p>BasicCanvasController <p>
064: *
065: * Description: </p>BasicCanvasController provides the implemenation of the mapper canvas
066: * controller. <p>
067: *
068: * Copyright: Copyright (c) 2002 </p> <p>
069: *
070: * Company: </p>
071: *
072: * @author Un Seng Leong
073: * @created December 4, 2002
074: * @version 1.0
075: */
076: public class BasicCanvasController extends AbstractCanvasController {
077: /**
078: * The drop data flavor for the drop event from palette.
079: */
080: private static final DataFlavor DROP_DATAFLAVOR = MapperUtilities
081: .getJVMLocalObjectDataFlavor();
082:
083: /**
084: * the log instance of this class
085: */
086: private Logger LOGGER = Logger
087: .getLogger(BasicCanvasController.class.getName());
088:
089: private Cursor mOriginalDragCursor;
090:
091: /**
092: * Creates a new BasicCanvasController object.
093: */
094: public BasicCanvasController() {
095: }
096:
097: /**
098: * Return true if a new link creates and contains the specified from and to
099: * nodes, false otherwise.
100: *
101: * @param from the from canvas node
102: * @param to the to canvas node
103: * @return true if a new link creates and contains the specified from
104: * and to nodes, false otherwise.
105: */
106: public boolean handleAddLink(ICanvasNode from, ICanvasNode to) {
107: if (!(from instanceof ICanvasFieldNode)
108: || !(to instanceof ICanvasFieldNode)) {
109: return false;
110: }
111:
112: MapperLink newLink = new MapperLink(((ICanvasFieldNode) from)
113: .getFieldNode(), ((ICanvasFieldNode) to).getFieldNode());
114:
115: this .requestNewLink(newLink);
116:
117: return true;
118: }
119:
120: /**
121: * Handles creation of a new link at the specified location.
122: * The link may or may not actually be created... always returns true.
123: *
124: * @param node the canvas node
125: * @param to the target location
126: * @return true
127: */
128: private boolean handleAddLink(final IMapperLink link,
129: final Point modelLocation, final Point viewLocation,
130: final int dropAction) {
131: IMapperLinkFromLinkRequest linkRequest = new IMapperLinkFromLinkRequest() {
132: public IMapperLink getSourceLink() {
133: return link;
134: }
135:
136: public Point getModelTargetLocation() {
137: return modelLocation;
138: }
139:
140: public Point getViewTargetLocation() {
141: return viewLocation;
142: }
143:
144: public int getDropAction() {
145: return dropAction;
146: }
147: };
148: this .requestNewLink(linkRequest);
149: return true;
150: }
151:
152: /**
153: * Handles creation of a new link at the specified location.
154: * The link may or may not actually be created... always returns true.
155: *
156: * @param node the canvas node
157: * @param to the target location
158: * @return true
159: */
160: public boolean handleAddLink(final ICanvasNode node,
161: final Point modelLocation, final Point viewLocation,
162: final int dropAction) {
163: IMapperLinkFromNodeRequest linkRequest = new IMapperLinkFromNodeRequest() {
164: public IMapperNode getSourceNode() {
165: return ((ICanvasFieldNode) node).getFieldNode();
166: }
167:
168: public Point getModelTargetLocation() {
169: return modelLocation;
170: }
171:
172: public Point getViewTargetLocation() {
173: return viewLocation;
174: }
175:
176: public int getDropAction() {
177: return dropAction;
178: }
179: };
180: this .requestNewLink(linkRequest);
181: return true;
182: }
183:
184: /**
185: * Return true if a new link creates and contains the specified from and to
186: * nodes, false otherwise. This method calls
187: * handleAddLink(ICanvasNode,ICanvasNode).
188: *
189: * @param fromNode the from canvas node
190: * @param toNode the to canvas node
191: * @param isComponentNode flag indicates component node
192: * @param isWithBinding flag indicates with binding
193: * @return true if a new link creates and contains the
194: * specified from and to nodes, false otherwise.
195: */
196: public boolean handleAddLink(ICanvasNode fromNode,
197: ICanvasNode toNode, boolean isComponentNode,
198: boolean isWithBinding) {
199: return handleAddLink(fromNode, toNode);
200: }
201:
202: /**
203: * Deletes all nodes that are not group nodes.
204: */
205: public void handleDeleteNonGroupNodes() {
206: Collection nodes = getCanvas().getSelectedNodes();
207:
208: if (nodes != null) {
209: Collection list = new ArrayList();
210: Iterator iter = nodes.iterator();
211:
212: while (iter.hasNext()) {
213: Object obj = iter.next();
214:
215: if (!(obj instanceof ICanvasGroupNode)) {
216: list.add(obj);
217: }
218: }
219: getCanvas().removeNodes(list);
220: }
221: }
222:
223: /**
224: * Return true if delete selection is successful, false otherwise.
225: *
226: * @return true if delete selection is successful, false otherwise.
227: */
228: public boolean handleDeleteSelection() {
229: if (!((Component) getCanvas()).isEnabled()
230: || !((Component) getCanvas()).isVisible()) {
231: return false;
232: }
233:
234: Collection selectedNodes = this .getCanvas().getSelectedNodes();
235: Collection selectedLinks = this .getCanvas().getSelectedLinks();
236:
237: Iterator iter = selectedLinks.iterator();
238:
239: while (iter.hasNext()) {
240: handleDeleteLink((ICanvasLink) iter.next());
241: }
242:
243: iter = selectedNodes.iterator();
244:
245: while (iter.hasNext()) {
246: handleDeleteNode((ICanvasNode) iter.next());
247: }
248:
249: return true;
250: }
251:
252: /**
253: * Return true if the drag drop end is handle successfully, false otherwise.
254: * This method is not applicable, it always return false.
255: *
256: * @param event the DragSourceDropEvent
257: * @return always false;
258: */
259: public boolean handleDragDropEnd(DragSourceDropEvent event) {
260: return false;
261: }
262:
263: /**
264: * Return true if the drop is handled successfully, false otherwise. This
265: * method checks if drop object is java local object, and returns
266: * handleDropObject(DropTargetDropEvent, Object). If not, it return false.
267: *
268: * @param event DropTargetDropEvent event
269: * @return true if the drop is handled successfully, false otherwise.
270: */
271: public boolean handleDrop(DropTargetDropEvent event) {
272: if (getView() instanceof IBasicMapperView
273: && !((IBasicMapperView) getView()).isMapable()) {
274: java.awt.Toolkit.getDefaultToolkit().beep();
275: return true;
276: }
277: LOGGER.finest("CanvasController handleDrop(): " + event);
278:
279: Transferable transferable = event.getTransferable();
280:
281: try {
282: if (transferable.isDataFlavorSupported(DROP_DATAFLAVOR)) {
283: return handleDropObject(event, transferable
284: .getTransferData(DROP_DATAFLAVOR));
285: }
286: } catch (java.io.IOException io) {
287: io.printStackTrace(System.err);
288: } catch (java.awt.datatransfer.UnsupportedFlavorException u) {
289: u.printStackTrace(System.err);
290: }
291:
292: return false;
293: }
294:
295: /**
296: * Return true if handles mouse clicks successfully, false otherwise. This
297: * method checks if the click is to expend or collese the group node. If
298: * yes, it calls the CanvasMethoidNode expend or collapse, otherwise, it
299: * delgates the drop event back to canvas by calling
300: * doDefaultMouseClick(ICanvasMouseData).
301: *
302: * @param data the mouse data of the canvas
303: * @return Description of the Return Value
304: */
305: public boolean handleMouseClick(ICanvasMouseData data) {
306: if (!((Component) getCanvas()).isEnabled()
307: || !((Component) getCanvas()).isVisible()) {
308: return false;
309: }
310:
311: Point clickPoint = data.getModelLocation();
312: JGoObject clickObj = ((JGoView) getCanvas()).pickDocObject(
313: clickPoint, true);
314:
315: if ((clickObj != null)
316: && clickObj instanceof BasicCanvasMethoidNode
317: && ((BasicCanvasMethoidNode) clickObj)
318: .isInButton(clickPoint)) {
319: BasicCanvasMethoidNode methoidNode = (BasicCanvasMethoidNode) clickObj;
320:
321: if (methoidNode.isExpanded()) {
322: methoidNode.collapse();
323: } else {
324: methoidNode.expand();
325: }
326:
327: return true;
328: }
329:
330: getCanvas().doDefaultMouseClick(data);
331:
332: return false;
333: }
334:
335: /**
336: * Return true if handles mouse double clicked successfully, false,
337: * otherwise. This method delgates the double clicks event back to canvas by
338: * calling doDefaultMouseDblClick(ICanvasMouseData) and return false.
339: *
340: * @param data the mouse event data.
341: * @return true if handles mouse double clicked successfully, false,
342: * otherwise.
343: */
344: public boolean handleMouseDblClick(ICanvasMouseData data) {
345: if (!((Component) getCanvas()).isEnabled()
346: || !((Component) getCanvas()).isVisible()) {
347: return false;
348: }
349: getCanvas().doDefaultMouseDblClick(data);
350: return false;
351: }
352:
353: /**
354: * Return true if handles mouse button pressed successfully, false,
355: * otherwise. This method delgates the button pressed event back to canvas
356: * by calling doDefaultMouseDown(ICanvasMouseData) and return false.
357: *
358: * @param data the mouse event data.
359: * @return true if handles mouse button pressed successfully, false,
360: * otherwise.
361: */
362: public boolean handleMouseDown(ICanvasMouseData data) {
363: if (!((Component) getCanvas()).isEnabled()
364: || !((Component) getCanvas()).isVisible()) {
365: return false;
366: }
367: getCanvas().doDefaultMouseDown(data);
368: return false;
369: }
370:
371: /**
372: * Return true if handles mouse move successfully, false, otherwise. This
373: * method delgates the mouse move event back to canvas by calling
374: * doDefaultMouseMove(ICanvasMouseData) and return false.
375: *
376: * @param data the mouse event data.
377: * @return true if handles mouse move successfully, false, otherwise.
378: */
379: public boolean handleMouseMove(ICanvasMouseData data) {
380: if (!((Component) getCanvas()).isEnabled()
381: || !((Component) getCanvas()).isVisible()) {
382: return false;
383: }
384: getCanvas().doDefaultMouseMove(data);
385: return false;
386: }
387:
388: /**
389: * Return true if handles mouse button released successfully, false,
390: * otherwise. This method delgates the mouse button released event back to
391: * canvas by calling doDefaultMouseUp(ICanvasMouseData) and return false.
392: *
393: * @param data the mouse event data.
394: * @return true if handles mouse button released successfully, false,
395: * otherwise.
396: */
397: public boolean handleMouseUp(ICanvasMouseData data) {
398: if (!((Component) getCanvas()).isEnabled()
399: || !((Component) getCanvas()).isVisible()) {
400: return false;
401: }
402: getCanvas().doDefaultMouseUp(data);
403:
404: return false;
405: }
406:
407: /**
408: * Handles delete a canvas link.
409: *
410: * @param link the link to be deleted.
411: */
412: protected void handleDeleteLink(ICanvasLink link) {
413: if (link instanceof ICanvasMapperLink) {
414: requestRemoveLink(((ICanvasMapperLink) link)
415: .getMapperLink());
416: }
417: }
418:
419: /**
420: * Handles delete a canvas node.
421: *
422: * @param node the canvas node to be deleted.
423: */
424: protected void handleDeleteNode(ICanvasNode node) {
425: if (node instanceof ICanvasMethoidNode) {
426: requestRemoveNode(((ICanvasMethoidNode) node)
427: .getMethoidNode());
428: }
429: }
430:
431: /**
432: * Return true if the drop object is handled successfully, false otherwise.
433: * The method checks if the object is IMapperLink, or IMethoid, then it
434: * handleNewLinkDrop(DropTargetDropEvent, IMapperLink) and
435: * handleNewMethoidDrop (DropTargetDropEvent, IMethoid) accordingly.
436: *
437: * @param event the DropTargetDropEvent
438: * @param transferData the transfable object in the DropTargetDropEvent
439: * @return true if the drop object is handled successfully,
440: * false otherwise.
441: */
442: protected boolean handleDropObject(DropTargetDropEvent event,
443: Object transferData) {
444: LOGGER.finest("CanvasController transferData.class="
445: + transferData.getClass().getName());
446:
447: if (transferData instanceof IMapperLink) {
448: return handleNewLinkDrop(event, (IMapperLink) transferData);
449: } else if (transferData instanceof IMethoid) {
450: return handleNewMethoidDrop(event, (IMethoid) transferData);
451: }
452:
453: return false;
454: }
455:
456: /**
457: * Return true if the new methoid is handled successfully, false otherwise.
458: *
459: * @param event the DropTargetDropEvent
460: * @param methoid the methoid object
461: * @return true if the new methoid is handled successfully, false
462: * otherwise.
463: */
464: protected boolean handleNewMethoidDrop(DropTargetDropEvent event,
465: IMethoid methoid) {
466: BasicMethoidNode newMethoidNode = null;
467: if (methoid.isAccumulative()) {
468: newMethoidNode = new BasicAccumulatingMethoidNode(methoid);
469: } else {
470: newMethoidNode = new BasicMethoidNode(methoid);
471: }
472: Point nodePt = event.getLocation();
473: ((JGoView) getCanvas()).convertViewToDoc(nodePt);
474: newMethoidNode.setX(nodePt.x);
475: newMethoidNode.setY(nodePt.y);
476: this .requestNewNode(newMethoidNode);
477:
478: return true;
479: }
480:
481: /**
482: * Return true if the new mapper link is handled successfully, false
483: * otherwise.
484: *
485: * @param event the DropTargetDropEvent
486: * @param link the mapper link object.
487: * @return true if the new mapper link is handled successfully, false
488: * otherwise.
489: */
490: protected boolean handleNewLinkDrop(DropTargetDropEvent event,
491: IMapperLink link) {
492: JGoView view = (JGoView) getCanvas();
493: Point viewLocation = event.getLocation();
494: Point modelLocation = new Point(viewLocation);
495: view.convertViewToDoc(modelLocation);
496:
497: BasicCanvasView canvasView = (BasicCanvasView) getCanvas();
498: if (canvasView.getPortObjectInModel(modelLocation, false) == null) {
499: handleAddLink(link, modelLocation, viewLocation, event
500: .getDropAction());
501: return false;
502: }
503: return canvasView.connectLinkByPoint(modelLocation, link);
504: }
505:
506: public void handleDragEnter(DropTargetDragEvent dtde) {
507: IBasicDragController dragController = getMapperDragController();
508: Object transferObject = dragController.getTransferObject();
509: if (transferObject instanceof IMapperLink) {
510: // DRAG FROM TREE: When dragging a link around from one of the trees,
511: // we need to make it so the tree draws the horizontal lines
512: // when the user drags out of the tree and into the canvas.
513: // Basically this handles the case of drawing the line on the
514: // tree containing the source node (where the link was dragged FROM)
515: // only when the dragging occurs INSIDE the canvas.
516: // We do this by grabbing the tree node from the link and
517: // setting a link on that node and then adding it to the view model.
518: // This node needs to be removed when done dragging.
519: IMapperLink link = (IMapperLink) transferObject;
520: IMapperNode node = null;
521: if (link.getStartNode() != null) {
522: node = link.getStartNode();
523: }
524: if (link.getEndNode() != null) {
525: node = link.getEndNode();
526: }
527: if (node != null && node instanceof IMapperTreeNode) {
528: IMapperLink newLink = new MapperLink();
529: // Prefer to work with our own instance of a node
530: // so we don't end up modifying nodes that are supposed
531: // to stay in the tree on a non-temporary basis.
532: IMapperNode newNode = (IMapperNode) node.clone();
533: newLink
534: .setStartNode(link.getStartNode() != null ? newNode
535: : null);
536: newLink.setEndNode(link.getEndNode() != null ? newNode
537: : null);
538: if (!MapperUtilities.isLinkAlreadyConnected(link, node)) {
539: newNode.addLink(newLink);
540: getViewModel().addNode(newNode);
541: dragController.setOriginatingDragNode(newNode);
542: }
543: }
544:
545: // Change the cursor to the hand cursor which is the drag cursor for the canvas.
546: DragSourceContext dragSourceContext = dragController
547: .getLinkDragSourceContext();
548: if (dragSourceContext != null) {
549: mOriginalDragCursor = dragSourceContext.getCursor();
550: dragSourceContext.setCursor(Cursor
551: .getPredefinedCursor(Cursor.HAND_CURSOR));
552: }
553: }
554: }
555:
556: public void handleDragExit(DropTargetEvent dte) {
557: IBasicDragController dragController = getMapperDragController();
558: if (dragController.getTransferObject() instanceof IMapperLink) {
559: // DRAG FROM TREE: When dragging a link around from one of the trees,
560: // we must remove the node we created when we first dragged into
561: // the canvas, as we're only drawing the tree lines when we're
562: // in the canvas. The tree controller takes care of all other
563: // situations, including drawing the line on the opposite tree
564: // when dragging in a tree.
565: IMapperNode node = dragController.getOriginatingDragNode();
566: if (node != null) {
567: getViewModel().removeNode(node);
568: }
569: // The link that shows up in the canvas should be reset so that
570: // it no longer appears (we set the start and end points to be the same).
571: dragController.resetDragLinkEndLocation();
572: // Restore the drag cursor.
573: dragController.getLinkDragSourceContext().setCursor(
574: mOriginalDragCursor);
575: mOriginalDragCursor = null;
576: }
577: }
578:
579: public boolean handleDragOver(DropTargetDragEvent dtde) {
580: IBasicDragController dragController = getMapperDragController();
581: if (dragController.getTransferObject() instanceof IMapperLink) {
582: // DRAG FROM TREE: When dragging a link around from one of the trees,
583: // we need to draw a link from the edge of the tree to
584: // our current drag location.
585: dragController.setDragLinkEndLocation(dtde.getLocation());
586: }
587: return true;
588: }
589:
590: public void handleDragGestureRecognized(DragGestureEvent dge) {
591: // DRAG FROM CANVAS: When dragging a link around from the canvas,
592: // set ourselves as the transfer object.
593: getMapperDragController().setTransferObject(this);
594: }
595: }
|