1 19 20 package org.openide.explorer.view; 21 22 import java.awt.Toolkit ; 23 import java.awt.datatransfer.Clipboard ; 24 import java.awt.datatransfer.Transferable ; 25 import java.awt.datatransfer.UnsupportedFlavorException ; 26 import java.awt.dnd.DnDConstants ; 27 import java.awt.event.ActionEvent ; 28 import java.awt.event.ActionListener ; 29 import java.io.IOException ; 30 import java.util.ArrayList ; 31 import java.util.Arrays ; 32 import java.util.Iterator ; 33 import java.util.List ; 34 import java.util.TreeSet ; 35 import javax.swing.JMenuItem ; 36 import javax.swing.JPopupMenu ; 37 import javax.swing.SwingUtilities ; 38 import javax.swing.tree.TreeNode ; 39 import org.netbeans.modules.openide.explorer.ExternalDragAndDrop; 40 import org.openide.DialogDisplayer; 41 import org.openide.NotifyDescriptor; 42 import org.openide.NotifyDescriptor.Message; 43 import org.openide.awt.Mnemonics; 44 import org.openide.nodes.Node; 45 import org.openide.util.Exceptions; 46 import org.openide.util.Lookup; 47 import org.openide.util.NbBundle; 48 import org.openide.util.UserCancelException; 49 import org.openide.util.datatransfer.ExClipboard; 50 import org.openide.util.datatransfer.ExTransferable; 51 import org.openide.util.datatransfer.ExTransferable.Multi; 52 import org.openide.util.datatransfer.MultiTransferObject; 53 import org.openide.util.datatransfer.PasteType; 54 55 60 final class DragDropUtilities extends Object { 61 static final boolean dragAndDropEnabled = Boolean.parseBoolean(System.getProperty("netbeans.dnd.enabled", "true")); static final int NODE_UP = -1; 63 static final int NODE_CENTRAL = 0; 64 static final int NODE_DOWN = 1; 65 static Runnable postDropRun = null; 66 67 static final int NoDrag = 0; 69 static final int NoDrop = 1; 70 71 72 private DragDropUtilities() { 73 } 74 75 79 static boolean checkNodeForAction(Node node, int dragAction) { 80 if ( 81 node.canCut() && 82 ((dragAction == DnDConstants.ACTION_MOVE) || (dragAction == DnDConstants.ACTION_COPY_OR_MOVE)) 83 ) { 84 return true; 85 } 86 87 if ( 88 node.canCopy() && 89 ((dragAction == DnDConstants.ACTION_COPY) || (dragAction == DnDConstants.ACTION_COPY_OR_MOVE) || 90 (dragAction == DnDConstants.ACTION_LINK) || (dragAction == DnDConstants.ACTION_REFERENCE)) 91 ) { 92 return true; 93 } 94 95 return false; 97 } 98 99 104 static Transferable getNodeTransferable(Node [] nodes, int dragAction) 105 throws IOException { 106 Transferable [] tArray = new Transferable [nodes.length]; 107 108 for (int i = 0; i < nodes.length; i++) { 109 if ((dragAction & DnDConstants.ACTION_MOVE) != 0) { 110 tArray[i] = nodes[i].clipboardCut(); 111 } else { 112 tArray[i] = nodes[i].drag (); 113 } 114 } 115 Transferable result; 116 if (tArray.length == 1) { 117 result = tArray[0]; 119 } else { 120 result = ExternalDragAndDrop.maybeAddExternalFileDnd( new Multi(tArray) ); 122 } 123 124 Clipboard c = getClipboard(); 125 if (c instanceof ExClipboard) { 126 return ((ExClipboard) c).convert(result); 127 } else { 128 return result; 129 } 130 } 131 132 135 static Transferable getNodeTransferable(Node node, int dragAction) 136 throws IOException { 137 return getNodeTransferable(new Node [] { node }, dragAction); 138 } 139 140 142 static void setPostDropRun(Runnable run) { 143 postDropRun = run; 144 } 145 146 148 static private void invokePostDropRun() { 149 if (postDropRun != null) { 150 SwingUtilities.invokeLater(postDropRun); 151 postDropRun = null; 152 } 153 } 154 155 162 static Node [] performPaste(PasteType type, Node targetFolder) { 163 try { 165 if (targetFolder == null) { 166 type.paste(); 168 169 return new Node [] { }; 170 } 171 172 Node [] preNodes = targetFolder.getChildren().getNodes(true); 173 174 type.paste(); 176 177 Node [] postNodes = targetFolder.getChildren().getNodes(true); 178 179 List <Node > pre = Arrays.asList(preNodes); 181 List <Node > post = Arrays.asList(postNodes); 182 Iterator <Node > it = post.iterator(); 183 List <Node > diff = new ArrayList <Node >(); 184 185 while (it.hasNext()) { 186 Node n = it.next(); 187 188 if (!pre.contains(n)) { 189 diff.add(n); 190 } 191 } 192 193 return diff.toArray(new Node [diff.size()]); 194 195 203 } catch (UserCancelException exc) { 204 return new Node [] { }; 206 } catch (IOException e) { 207 Exceptions.printStackTrace(e); 208 209 return new Node [] { }; 210 } 211 } 212 213 223 static PasteType[] getPasteTypes(Node node, Transferable trans) { 224 if (!trans.isDataFlavorSupported(ExTransferable.multiFlavor)) { 225 PasteType[] pt = null; 227 228 try { 229 pt = node.getPasteTypes(trans); 230 } catch (NullPointerException npe) { 231 Exceptions.printStackTrace(npe); 232 233 } 235 236 return pt; 237 } else { 238 try { 240 MultiTransferObject obj = (MultiTransferObject) trans.getTransferData(ExTransferable.multiFlavor); 241 int count = obj.getCount(); 242 Transferable [] t = new Transferable [count]; 243 PasteType[] p = new PasteType[count]; 244 PasteType[] curTypes = null; 245 246 for (int i = 0; i < count; i++) { 248 t[i] = obj.getTransferableAt(i); 249 curTypes = node.getPasteTypes(t[i]); 250 251 if (curTypes.length == 0) { 253 return curTypes; 254 } 255 256 p[i] = curTypes[0]; 257 } 258 259 return new PasteType[] { new MultiPasteType(t, p) }; 261 } catch (UnsupportedFlavorException e) { 262 } catch (IOException e) { 264 } 266 } 267 268 return new PasteType[0]; 269 } 270 271 283 static PasteType getDropType(Node node, Transferable trans, int action, int dropIndex) { 284 PasteType paste = null; 285 286 try { 287 paste = node.getDropType(trans, action, dropIndex); 288 if (paste!=null) 289 return paste; 290 } catch (NullPointerException npe) { 291 Exceptions.printStackTrace(npe); 292 } 293 294 if (trans.isDataFlavorSupported(ExTransferable.multiFlavor)) { 295 try { 297 MultiTransferObject obj = (MultiTransferObject) trans.getTransferData(ExTransferable.multiFlavor); 298 int count = obj.getCount(); 299 Transferable [] t = new Transferable [count]; 300 PasteType[] p = new PasteType[count]; 301 PasteType pt = null; 302 303 for (int i = 0; i < count; i++) { 305 t[i] = obj.getTransferableAt(i); 306 pt = node.getDropType(t[i], action, dropIndex); 307 308 if (pt == null) { 310 return pt; 311 } 312 313 p[i] = pt; 314 } 315 316 return new MultiPasteType(t, p); 318 } catch (UnsupportedFlavorException e) { 319 } catch (IOException e) { 321 } 323 } 324 325 return null; 326 } 327 328 329 static void dropNotSuccesfull() { 330 DialogDisplayer.getDefault().notify( 331 new Message( 332 NbBundle.getBundle(TreeViewDropSupport.class).getString("MSG_NoPasteTypes"), 333 NotifyDescriptor.WARNING_MESSAGE 334 ) 335 ); 336 } 337 338 339 private static Clipboard getClipboard() { 340 Clipboard c = (Clipboard ) Lookup.getDefault().lookup(Clipboard .class); 341 342 if (c == null) { 343 c = Toolkit.getDefaultToolkit().getSystemClipboard(); 344 } 345 346 return c; 347 } 348 349 352 static Node secureFindNode(Object o) { 353 assert o instanceof TreeNode : "Object " + o + " is instanceof TreeNode"; 354 try { 355 return Visualizer.findNode(o); 356 } catch (ClassCastException e) { 357 e.printStackTrace(); 358 359 return null; 360 } 361 } 362 363 368 static JPopupMenu createDropFinishPopup(final TreeSet pasteTypes) { 369 JPopupMenu menu = new JPopupMenu (); 370 371 final JMenuItem [] items_ = new JMenuItem [pasteTypes.size()]; 373 374 ActionListener aListener = new ActionListener () { 375 public void actionPerformed(ActionEvent e) { 376 JMenuItem source = (JMenuItem ) e.getSource(); 377 378 final Iterator it = pasteTypes.iterator(); 379 380 for (int i = 0; it.hasNext(); i++) { 381 PasteType action = (PasteType) it.next(); 382 383 if (items_[i].equals(source)) { 384 DragDropUtilities.performPaste(action, null); 385 invokePostDropRun(); 386 387 break; 388 } 389 } 390 } 391 }; 392 393 Iterator it = pasteTypes.iterator(); 394 395 for (int i = 0; it.hasNext(); i++) { 396 items_[i] = new JMenuItem (); 397 Mnemonics.setLocalizedText(items_[i], ((PasteType) it.next()).getName()); 398 items_[i].addActionListener(aListener); 399 menu.add(items_[i]); 400 } 401 402 menu.addSeparator(); 403 404 JMenuItem abortItem = new JMenuItem (NbBundle.getBundle(DragDropUtilities.class).getString("MSG_ABORT")); 405 menu.add(abortItem); 406 407 return menu; 408 } 409 410 411 static final class MultiPasteType extends PasteType { 412 414 415 Transferable [] t; 416 417 418 PasteType[] p; 419 420 422 424 MultiPasteType(Transferable [] t, PasteType[] p) { 425 this.t = t; 426 this.p = p; 427 } 428 429 434 public Transferable paste() throws IOException { 435 int size = p.length; 436 Transferable [] arr = new Transferable [size]; 437 438 for (int i = 0; i < size; i++) { 440 arr[i] = p[i].paste(); 442 } 443 444 return new Multi(arr); 445 } 446 } 447 } 449 | Popular Tags |