/* * GeoGebra - Dynamic Mathematics for Everyone * http://www.geogebra.org * * This file is part of GeoGebra. * * 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. */ package org.geogebra.desktop.gui; 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.io.File; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; import java.util.StringTokenizer; import org.geogebra.common.util.FileExtensions; import org.geogebra.common.util.StringUtil; import org.geogebra.common.util.debug.Log; import org.geogebra.desktop.main.AppD; public class FileDropTargetListener implements DropTargetListener { static DataFlavor urlFlavor; static { try { urlFlavor = new DataFlavor( "application/x-java-url; class=java.net.URL"); } catch (ClassNotFoundException cnfe) { cnfe.printStackTrace(); } } private AppD app; /** * @param app * application */ public FileDropTargetListener(AppD app) { this.app = app; } @Override public void dragEnter(DropTargetDragEvent event) { // only dragOver /drop } @Override public void dragExit(DropTargetEvent event) { // only dragOver /drop } @Override public void dragOver(DropTargetDragEvent event) { // provide visual feedback event.acceptDrag(DnDConstants.ACTION_COPY); } @Override public void dropActionChanged(DropTargetDragEvent event) { // only dragOver /drop } @Override public void drop(DropTargetDropEvent event) { if ((event.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { event.acceptDrop(DnDConstants.ACTION_COPY); } else { event.rejectDrop(); return; } event.dropComplete(handleFileDrop(event.getTransferable())); } /** * Determines if a transferable contains ggb/ggt files and attempts to open * them. * * @param t * @return */ public boolean handleFileDrop(Transferable t) { ArrayList<File> al = getGGBfiles(t); if (al.size() == 0) { return false; } boolean allGGT = true; for (int i = al.size() - 1; i >= 0; i--) { if (!isGGBFile(al.get(i).getName()) && !isGGTFile(al.get(i).getName())) { al.remove(i); } else { if (!isGGTFile(al.get(i).getName())) { allGGT = false; } } } if (al.size() == 0) { return false; } else if (allGGT || app.isSaved() || app.saveCurrentFile()) { File[] files = new File[al.size()]; for (int i = 0; i < al.size(); i++) { files[i] = al.get(i); } ((GuiManagerD) app.getGuiManager()).doOpenFiles(files, true); return true; } return false; } /** * Tests if a file has the GeoGebra ggb extension * * @param fileName * @return */ private static boolean isGGBFile(String fileName) { return StringUtil.getFileExtension(fileName) .equals(FileExtensions.GEOGEBRA); } /** * Tests if a file has the GeoGebra ggt extension * * @param fileName * @return */ private static boolean isGGTFile(String fileName) { FileExtensions ext = StringUtil.getFileExtension(fileName); return ext.equals(FileExtensions.GEOGEBRA_TOOL); } private ArrayList<File> getGGBfiles(Transferable transferable) { ArrayList<File> al = new ArrayList<File>(); try { // try to get an image if (transferable.isDataFlavorSupported(DataFlavor.imageFlavor)) { Log.debug("image flavor not supported"); // Image img = (Image) trans.getTransferData // (DataFlavor.imageFlavor); } else if (transferable .isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { // Application.debug("javaFileList is supported"); List<File> list = (List<File>) transferable .getTransferData(DataFlavor.javaFileListFlavor); ListIterator<File> it = list.listIterator(); while (it.hasNext()) { File f = it.next(); al.add(f); } } else if (transferable .isDataFlavorSupported(GuiManagerD.uriListFlavor)) { // Application.debug("uri-list flavor is supported"); String uris = (String) transferable .getTransferData(GuiManagerD.uriListFlavor); // url-lists are defined by rfc 2483 as crlf-delimited StringTokenizer st = new StringTokenizer(uris, "\r\n"); while (st.hasMoreTokens()) { String uriString = st.nextToken(); if (uriString.startsWith("http://") && isGGBFile(uriString)) { ((GuiManagerD) app.getGuiManager()).loadURL(uriString, true); } else { URI uri = new URI(uriString); al.add(new File(uri)); } } } else if (transferable.isDataFlavorSupported(urlFlavor)) { Log.debug("url flavor not supported"); // URL url = (URL) trans.getTransferData (urlFlavor); } else { Log.debug("flavor not supported: " + transferable); } } catch (Exception e) { e.printStackTrace(); } return al; } }