1 /*
2  * aTunes
3  * Copyright (C) Alex Aranda, Sylvain Gaudard and contributors
4  *
5  * See http://www.atunes.org/wiki/index.php?title=Contributing for information about contributors
6  *
7  * http://www.atunes.org
8  * http://sourceforge.net/projects/atunes
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  */
20 
21 package net.sourceforge.atunes.kernel.modules.draganddrop;
22 
23 import java.awt.datatransfer.DataFlavor;
24 import java.util.List;
25 
26 import javax.swing.TransferHandler;
27 
28 import net.sourceforge.atunes.gui.GuiUtils;
29 import net.sourceforge.atunes.gui.TransferableList;
30 import net.sourceforge.atunes.model.INavigationHandler;
31 import net.sourceforge.atunes.utils.Logger;
32 
33 /**
34  * Some methods of this class about how to drag and drop from Gnome/KDE file
35  * managers taken from:
36  *
37  * http://www.davidgrant.ca/
38  * drag_drop_from_linux_kde_gnome_file_managers_konqueror_nautilus_to_java_applications
39  *
40  */
41 public class TreeNavigationTransferHandler extends TransferHandler {
42 
43 	private static final long serialVersionUID = 4589661138322620954L;
44 
45 	/**
46 	 * Data flavor of a list of objects dragged from inside application
47 	 */
48 	private DataFlavor internalDataFlavor;
49 
50 	private final INavigationHandler navigationHandler;
51 
52 	/**
53 	 * Default constructor
54 	 *
55 	 * @param navigationHandler
56 	 */
TreeNavigationTransferHandler( final INavigationHandler navigationHandler)57 	public TreeNavigationTransferHandler(
58 			final INavigationHandler navigationHandler) {
59 		this.navigationHandler = navigationHandler;
60 		try {
61 			internalDataFlavor = new DataFlavor(TransferableList.MIMETYPE);
62 		} catch (ClassNotFoundException e) {
63 			Logger.error(e);
64 		}
65 	}
66 
67 	@Override
canImport(final TransferSupport support)68 	public boolean canImport(final TransferSupport support) {
69 		// Check if its a drap and drop operation
70 		if (!support.isDrop()) {
71 			return false;
72 		}
73 
74 		// Check if internal data flavor is supported
75 		if (support.getTransferable().isDataFlavorSupported(internalDataFlavor)) {
76 			try {
77 				List<?> listOfObjectsDragged = (List<?>) support
78 						.getTransferable().getTransferData(internalDataFlavor);
79 				if (listOfObjectsDragged == null
80 						|| listOfObjectsDragged.isEmpty()) {
81 					return false;
82 				}
83 
84 				// Drag is made from another component...
85 				if (listOfObjectsDragged.get(0) instanceof PlayListDragableRow) {
86 					return true;
87 				}
88 
89 				return true;
90 			} catch (Exception e) {
91 				Logger.error(e);
92 			}
93 
94 			support.setShowDropLocation(true);
95 			return true;
96 		}
97 
98 		return false;
99 	}
100 
101 	@Override
importData(final TransferSupport support)102 	public boolean importData(final TransferSupport support) {
103 		if (!canImport(support)) {
104 			return false;
105 		}
106 
107 		if (support.getTransferable().isDataFlavorSupported(internalDataFlavor)) {
108 			return processInternalImport(support);
109 		}
110 
111 		return false;
112 	}
113 
114 	/**
115 	 * Perform drop with data dragged from another component
116 	 *
117 	 * @param support
118 	 * @return
119 	 */
processInternalImport(final TransferSupport support)120 	private boolean processInternalImport(final TransferSupport support) {
121 		try {
122 			List<?> listOfObjectsDragged = (List<?>) support.getTransferable()
123 					.getTransferData(internalDataFlavor);
124 			if (listOfObjectsDragged == null || listOfObjectsDragged.isEmpty()) {
125 				return false;
126 			}
127 
128 			// DRAG AND DROP OF AN ARTIST -> SELECT IN NAVIGATOR
129 			if (listOfObjectsDragged.get(0) instanceof DragableArtist) {
130 				final DragableArtist draggedArtist = (DragableArtist) listOfObjectsDragged
131 						.get(0);
132 				GuiUtils.callInEventDispatchThread(new Runnable() {
133 					@Override
134 					public void run() {
135 						navigationHandler.selectArtist(draggedArtist
136 								.getArtistInfo().getName());
137 					}
138 				});
139 
140 			}
141 
142 			// DRAG AND DROP OF A PLAY LIST ITEM -> SELECT IN NAVIGATOR
143 			if (listOfObjectsDragged.get(0) instanceof PlayListDragableRow) {
144 				final PlayListDragableRow playlistRow = (PlayListDragableRow) listOfObjectsDragged
145 						.get(0);
146 				GuiUtils.callInEventDispatchThread(new Runnable() {
147 					@Override
148 					public void run() {
149 						navigationHandler.selectAudioObject(playlistRow
150 								.getRowContent());
151 					}
152 				});
153 
154 			}
155 
156 		} catch (Exception e) {
157 			Logger.error(e);
158 		}
159 
160 		return false;
161 	}
162 
163 }
164