NodeDropListener.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
freemind.controller |
![]() |
![]() |
FreeMind |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*FreeMind - A Program for creating and viewing Mindmaps
*Copyright (C) 2000-2001 Joerg Mueller <joergmueller@bigfoot.com>
*See COPYING for Details
*
*This program is free software; you can redistribute it and/or
*modify it under the terms of the GNU General Public License
*as published by the Free Software Foundation; either version 2
*of the License, or (at your option) any later version.
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License
*along with this program; if not, write to the Free Software
*Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package freemind.controller;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.util.List;
import java.util.ListIterator;
import javax.swing.JOptionPane;
import javax.swing.tree.TreePath;
import freemind.modes.MindMapNode;
import freemind.modes.mindmapmode.MindMapMapModel;
import freemind.modes.mindmapmode.MindMapNodeModel;
import freemind.view.mindmapview.NodeView;
//import ublic class MindMapNodesSelection implements Transferable, ClipboardOwner {
// public static DataFlavor fileListFlavor = null;
public class NodeDropListener implements DropTargetListener {
private final Controller c;
public NodeDropListener(Controller controller) {
c = controller;
}
// See DropTargetListener for the meaning.
private boolean isDragAcceptable(DropTargetDragEvent ev) {
if (ev.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return true; }
if (ev.isDataFlavorSupported(MindMapNodesSelection.fileListFlavor)) {
return true; }
return false; }
private boolean isDropAcceptable(DropTargetDropEvent event) {
MindMapNode node = ((NodeView)event.getDropTargetContext().getComponent()).getModel();
MindMapNode selected = c.getView().getSelected().getModel();
return ((node!=selected) && !node.isDescendantOf(selected));
// I think (node!=selected) is a hack for windows
}
public void drop (DropTargetDropEvent dtde) {
try {
int dropAction = dtde.getDropAction();
Transferable t = dtde.getTransferable();
NodeView targetNodeView = (NodeView)dtde.getDropTargetContext().getComponent();
MindMapNode targetNode = targetNodeView.getModel();
MindMapNodeModel targetNodeModel = (MindMapNodeModel)targetNode;
// Intra application DnD
// For some reason, getting sourceAction is only possible for local
// transfer. When I try to remove clause dtde.isLocalTransfer, I get an answer
// like "no drop current". One hypothesis is that with nonlocal transfers, I
// have to accept drop action before I can get transfer data. However, this is
// not what I want in this particular situation. A part of the problem lies in
// the hackery of sending source action using data flavour too.
if (dtde.isLocalTransfer() && t.isDataFlavorSupported(MindMapNodesSelection.dropActionFlavor)) {
String sourceAction = (String)t.getTransferData(MindMapNodesSelection.dropActionFlavor);
if (sourceAction.equals("LINK")) {
dropAction = DnDConstants.ACTION_LINK; }
if (sourceAction.equals("COPY")) {
dropAction = DnDConstants.ACTION_COPY; }}
targetNodeView.setDraggedOver(NodeView.DRAGGED_OVER_NO);
targetNodeView.repaint();
if (dtde.isLocalTransfer() && (dropAction == DnDConstants.ACTION_MOVE) && !isDropAcceptable(dtde)) {
dtde.rejectDrop();
return; }
dtde.acceptDrop(dtde.getDropAction());
if (!dtde.isLocalTransfer()) {
//if (dtde.isDataFlavorSupported(MindMapNodesSelection.fileListFlavor)) {
//System.err.println("filelist");
c.getModeController().paste (t, targetNode,
targetNodeView.dropAsSibling(dtde.getLocation().getX()),
targetNodeView.dropPosition (dtde.getLocation().getX()));
dtde.dropComplete(true);
return; }
// This all is specific to MindMap model. Needs rewrite to work for other modes.
// We ignore data transfer in dtde. We take selected nodes as drag sources.
// <problem>
// The behaviour is not so fine, when some of selected nodes is an ancestor of other selected nodes.
// Ideally, we would first unselect all nodes, which have an ancestor among selected nodes.
// I don't have time/lust to do this. This is just a minor problem.
// </problem>
// By transferable object we only transfer source action. This will be a problem, when we want
// to implement extra application dnd or dnd between different Java Virtual Machines.
if (dropAction == DnDConstants.ACTION_LINK) {
// ACTION_LINK means for us change the color, style and font.
// This is not very clean. This all should probably be
// implemented on the mindMapMapModel level. On the other
// hand, one would have to downcast to MindMapMapModel anyway.
//MindMapNode selectedNode = c.getView().getSelected().getModel();
MindMapMapModel mindMapMapModel = (MindMapMapModel)c.getModel();
// link feature continues here. fc, 01.11.2003:
// if there are more than 4 nodes, then ask the user:
int yesorno = JOptionPane.YES_OPTION;
if(c.getView().getSelecteds().size() >= 5)
{
yesorno = JOptionPane.showConfirmDialog(c.getFrame().getContentPane(),
c.getResourceString("lots_of_links_warning"),
Integer.toString(c.getView().getSelecteds().size())+" links to the same node",
JOptionPane.YES_NO_OPTION);
}
if(yesorno == JOptionPane.YES_OPTION) {
for(ListIterator it = c.getView().getSelecteds().listIterator();it.hasNext();) {
MindMapNodeModel selectedNodeModel = (MindMapNodeModel)((NodeView)it.next()).getModel();
// mindMapMapModel.setNodeColor(selectedNodeModel,targetNode.getColor());
// mindMapMapModel.setNodeFont(selectedNodeModel,targetNode.getFont());
c.getModeController().addLink(selectedNodeModel, targetNodeModel);
}
}
}
else {
Transferable trans = null;
// if move, verify, that the target is not a son of the sources.
if (DnDConstants.ACTION_MOVE == dropAction) {
List selecteds = c.getModeController().getSelecteds();
MindMapNode actualNode = targetNode;
do {
if (selecteds.contains(actualNode)) {
String message = c.getResourceString("cannot_move_to_child");
JOptionPane.showMessageDialog(c.getFrame().getContentPane(),
message,"Freemind", JOptionPane.WARNING_MESSAGE);
dtde.dropComplete(true);
return;
}
actualNode = (actualNode.isRoot())?null:actualNode.getParentNode();
} while(actualNode != null);
trans = c.getModeController().cut();
} else {
trans = c.getModel().copy();
}
c.getView().selectAsTheOnlyOneSelected(
targetNodeModel.getViewer());
c.getModeController().paste(
trans,
targetNode,
targetNode.getViewer().dropAsSibling(
dtde.getLocation().getX()),
targetNode.getViewer().dropPosition(
dtde.getLocation().getX()));
}
}
catch (Exception e) {
System.err.println("Drop exception:"+e);
e.printStackTrace();
dtde.dropComplete(false);
return; }
dtde.dropComplete(true); }
/**
* The method is called when the cursor carrying the dragged item enteres
* the area of the node. The name "dragEnter" seems to be confusing to me.
*
* I think the difference between dragAcceptable and dropAcceptable is
* that in dragAcceptable, you tell if the type of the thing being dragged
* is OK, where in dropAcceptable, you tell if your really willing to
* accept the item.
*/
public void dragEnter (DropTargetDragEvent dtde) {
// TODO: Accepting the action ACTION_MOVE is false, because we cannot
// know if the action is really ACTION_MOVE.
if(isDragAcceptable(dtde)) {
dtde.acceptDrag(DnDConstants.ACTION_MOVE); }
else {
dtde.rejectDrag(); }
}
public void dragOver (DropTargetDragEvent e) {
NodeView draggedNode = (NodeView)e.getDropTargetContext().getComponent();
int oldDraggedOver = draggedNode.getDraggedOver();
// let the node decide, which dragged over type it is:
draggedNode.setDraggedOver(e.getLocation());
int newDraggedOver = draggedNode.getDraggedOver();
boolean repaint = newDraggedOver != oldDraggedOver;
if (repaint) {
draggedNode.repaint(); }
}
public void dragExit (DropTargetEvent e) {
NodeView draggedNode = (NodeView)e.getDropTargetContext().getComponent();
draggedNode.setDraggedOver(NodeView.DRAGGED_OVER_NO);
draggedNode.repaint();
}
public void dragScroll (DropTargetDragEvent e) {}
public void dropActionChanged (DropTargetDragEvent e) {}
}
The table below shows all metrics for NodeDropListener.java.




