package org.freeplane.plugin.workspace.mindmapmode; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.dnd.DnDConstants; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.apache.commons.io.FileUtils; import org.freeplane.core.util.LogUtils; import org.freeplane.plugin.workspace.URIUtils; import org.freeplane.plugin.workspace.WorkspaceController; import org.freeplane.plugin.workspace.components.IWorkspaceView; import org.freeplane.plugin.workspace.dnd.WorkspaceTransferable; import org.freeplane.plugin.workspace.io.FileSystemManager; import org.freeplane.plugin.workspace.io.ITask; import org.freeplane.plugin.workspace.io.IFileSystemRepresentation; import org.freeplane.plugin.workspace.io.SkipTaskException; import org.freeplane.plugin.workspace.model.AWorkspaceTreeNode; import org.freeplane.plugin.workspace.model.WorkspaceTreeModel; import org.freeplane.plugin.workspace.nodes.DefaultFileNode; import org.freeplane.plugin.workspace.nodes.FolderLinkNode; import org.freeplane.plugin.workspace.nodes.LinkTypeFileNode; public class FileFolderDropHandler extends DefaultFileDropHandler { /*********************************************************************************** * CONSTRUCTORS **********************************************************************************/ /*********************************************************************************** * METHODS **********************************************************************************/ private void processWorkspaceNodeDrop(AWorkspaceTreeNode targetNode, List<AWorkspaceTreeNode> nodes, int dropAction) { try { File targetDir = ((IFileSystemRepresentation) targetNode).getFile(); if (targetDir != null && targetDir.isDirectory()) { List<ITask> opList = new ArrayList<ITask>(); for (AWorkspaceTreeNode node : nodes) { if (node instanceof DefaultFileNode) { File srcFile = ((DefaultFileNode) node).getFile(); File destFile = new File(targetDir, srcFile.getName()); if (srcFile.equals(destFile) || srcFile.equals(targetDir)) { continue; } if (dropAction == DnDConstants.ACTION_COPY) { FileSystemManager.buildCopyOperationList(srcFile, destFile, opList); } else if (dropAction == DnDConstants.ACTION_MOVE) { FileSystemManager.buildMoveOperationList(srcFile, destFile, opList); opList.add(getPostOperation(targetNode, node, srcFile, destFile)); } } else if (node instanceof LinkTypeFileNode) { File srcFile = URIUtils.getAbsoluteFile(((LinkTypeFileNode) node).getLinkURI()); File destFile = new File(targetDir, srcFile.getName()); if (srcFile.equals(destFile) || srcFile.equals(targetDir)) { continue; } FileSystemManager.buildCopyOperationList(srcFile, destFile, opList); if (dropAction == DnDConstants.ACTION_MOVE) { opList.add(getPostOperation(targetNode, node, srcFile, destFile)); } } else if (node instanceof FolderLinkNode) { File srcFile = URIUtils.getAbsoluteFile(((FolderLinkNode) node).getPath()); File destFile = new File(targetDir, srcFile.getName()); if (srcFile.equals(destFile) || srcFile.equals(targetDir)) { continue; } FileSystemManager.buildCopyOperationList(srcFile, destFile, opList); if (dropAction == DnDConstants.ACTION_MOVE) { opList.add(getPostOperation(targetNode, node, srcFile, destFile)); } } } FileSystemManager.execOperations(opList); } } catch (Exception e) { LogUtils.warn(e); } } private ITask getPostOperation(final AWorkspaceTreeNode targetNode, final AWorkspaceTreeNode node, final File srcFile, final File destFile) { return new ITask() { public void exec(Properties properties) throws IOException { if(onSkipList(destFile.getParentFile(), properties)) { throw new SkipTaskException(); } WorkspaceTreeModel model = targetNode.getModel(); AWorkspaceTreeNode parent = node.getParent(); model.cutNodeFromParent(node); parent.refresh(); model.nodeMoved(node, srcFile, destFile); } private boolean onSkipList(File dest, Properties properties) { if(properties == null || dest == null) { return false; } String list = properties.getProperty("skippedDirs", ""); String entry = dest.getPath()+";"; if(list.contains(entry)) { return true; } return false; } }; } private void processFileListDrop(AWorkspaceTreeNode targetNode, List<File> files, int dropAction) { try { File targetDir = ((IFileSystemRepresentation) targetNode).getFile(); FileSystemManager.copyFiles(files, targetDir, false); } catch (Exception e) { LogUtils.warn(e); } targetNode.refresh(); } private void processUriListDrop(AWorkspaceTreeNode targetNode, List<URI> uris, int dropAction) { try { File targetDir = ((IFileSystemRepresentation) targetNode).getFile(); for (URI uri : uris) { File srcFile = new File(uri); if (srcFile == null || !srcFile.exists()) { continue; } if (srcFile.isDirectory()) { FileUtils.copyDirectoryToDirectory(srcFile, targetDir); } else { FileUtils.copyFileToDirectory(srcFile, targetDir, true); } } } catch (Exception e) { LogUtils.warn(e); } targetNode.refresh(); } /*********************************************************************************** * REQUIRED METHODS FOR INTERFACES **********************************************************************************/ @SuppressWarnings("unchecked") public boolean processDrop(AWorkspaceTreeNode targetNode, Transferable transferable, int dropAction) { try { if (transferable.isDataFlavorSupported(WorkspaceTransferable.WORKSPACE_NODE_FLAVOR)) { processWorkspaceNodeDrop(targetNode, (List<AWorkspaceTreeNode>) transferable.getTransferData(WorkspaceTransferable.WORKSPACE_NODE_FLAVOR), dropAction); } else if (transferable.isDataFlavorSupported(WorkspaceTransferable.WORKSPACE_FILE_LIST_FLAVOR)) { processFileListDrop(targetNode, (List<File>) transferable.getTransferData(WorkspaceTransferable.WORKSPACE_FILE_LIST_FLAVOR), dropAction); } else if (transferable.isDataFlavorSupported(WorkspaceTransferable.WORKSPACE_URI_LIST_FLAVOR)) { ArrayList<URI> uriList = new ArrayList<URI>(); String uriString = (String) transferable.getTransferData(WorkspaceTransferable.WORKSPACE_URI_LIST_FLAVOR); if (!uriString.startsWith("file://")) { return false; } String[] uriArray = uriString.split("\r\n"); for (String singleUri : uriArray) { try { uriList.add(URIUtils.createURI(singleUri)); } catch (Exception e) { LogUtils.info("org.freeplane.plugin.workspace.mindmapmode.FolderFileDropHandler.processDrop(targetNode, transferable, dropAction)@1" + e.getMessage()); } } processUriListDrop(targetNode, uriList, dropAction); } targetNode.refresh(); IWorkspaceView view = WorkspaceController.getCurrentModeExtension().getView(); if(view != null) { view.expandPath(targetNode.getTreePath()); WorkspaceController.getCurrentModeExtension().getView().refreshView(); } } catch (Exception e) { LogUtils.warn("org.freeplane.plugin.workspace.mindmapmode.FolderFileDropHandler.processDrop(targetNode, transferable, dropAction)@2", e); } return true; } public boolean acceptDrop(Transferable transferable) { for (DataFlavor flavor : transferable.getTransferDataFlavors()) { if (WorkspaceTransferable.WORKSPACE_FILE_LIST_FLAVOR.equals(flavor) || WorkspaceTransferable.WORKSPACE_URI_LIST_FLAVOR.equals(flavor) || WorkspaceTransferable.WORKSPACE_NODE_FLAVOR.equals(flavor)) { return true; } } return false; } }