package ij.plugin;
import ij.*;
import ij.gui.*;
import ij.io.*;
import ij.process.ImageProcessor;
import java.io.*;
import java.awt.Point;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.util.*;
import java.util.Iterator;
import java.util.ArrayList;
public class DragAndDrop implements PlugIn, DropTargetListener, Runnable {
private Iterator iterator;
private static boolean convertToRGB;
private static boolean virtualStack;
private boolean openAsVirtualStack;
public void run(String arg) {
ImageJ ij = IJ.getInstance();
ij.setDropTarget(null);
new DropTarget(ij, this);
new DropTarget(Toolbar.getInstance(), this);
new DropTarget(ij.getStatusBar(), this);
}
public void drop(DropTargetDropEvent dtde) {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
DataFlavor[] flavors = null;
try {
Transferable t = dtde.getTransferable();
iterator = null;
flavors = t.getTransferDataFlavors();
if (IJ.debugMode) IJ.log("DragAndDrop.drop: "+flavors.length+" flavors");
for (int i=0; i<flavors.length; i++) {
if (IJ.debugMode) IJ.log(" flavor["+i+"]: "+flavors[i].getMimeType());
if (flavors[i].isFlavorJavaFileListType()) {
Object data = t.getTransferData(DataFlavor.javaFileListFlavor);
iterator = ((List)data).iterator();
break;
} else if (flavors[i].isFlavorTextType()) {
Object ob = t.getTransferData(flavors[i]);
if (!(ob instanceof String)) continue;
String s = ob.toString().trim();
if (IJ.isLinux() && s.length()>1 && (int)s.charAt(1)==0)
s = fixLinuxString(s);
ArrayList list = new ArrayList();
if (s.indexOf("href=\"")!=-1 || s.indexOf("src=\"")!=-1) {
s = parseHTML(s);
if (IJ.debugMode) IJ.log(" url: "+s);
list.add(s);
this.iterator = list.iterator();
break;
}
BufferedReader br = new BufferedReader(new StringReader(s));
String tmp;
while (null != (tmp = br.readLine())) {
tmp = java.net.URLDecoder.decode(tmp.replaceAll("\\+","%2b"), "UTF-8");
if (tmp.startsWith("file://")) tmp = tmp.substring(7);
if (IJ.debugMode) IJ.log(" content: "+tmp);
if (tmp.startsWith("http://"))
list.add(s);
else
list.add(new File(tmp));
}
this.iterator = list.iterator();
break;
}
}
if (iterator!=null) {
Thread thread = new Thread(this, "DrawAndDrop");
thread.setPriority(Math.max(thread.getPriority()-1, Thread.MIN_PRIORITY));
thread.start();
}
}
catch(Exception e) {
dtde.dropComplete(false);
return;
}
dtde.dropComplete(true);
if (flavors==null || flavors.length==0) {
if (IJ.isMacOSX())
IJ.error("First drag and drop ignored. Please try again. You can avoid this\n"
+"problem by dragging to the toolbar instead of the status bar.");
else
IJ.error("Drag and drop failed");
}
}
private String fixLinuxString(String s) {
StringBuffer sb = new StringBuffer(200);
for (int i=0; i<s.length(); i+=2)
sb.append(s.charAt(i));
return new String(sb);
}
private String parseHTML(String s) {
if (IJ.debugMode) IJ.log("parseHTML:\n"+s);
int index1 = s.indexOf("src=\"");
if (index1>=0) {
int index2 = s.indexOf("\"", index1+5);
if (index2>0)
return s.substring(index1+5, index2);
}
index1 = s.indexOf("href=\"");
if (index1>=0) {
int index2 = s.indexOf("\"", index1+6);
if (index2>0)
return s.substring(index1+6, index2);
}
return s;
}
public void dragEnter(DropTargetDragEvent e) {
IJ.showStatus("<<Drag and Drop>>");
if (IJ.debugMode) IJ.log("DragEnter: "+e.getLocation());
e.acceptDrag(DnDConstants.ACTION_COPY);
openAsVirtualStack = false;
}
public void dragOver(DropTargetDragEvent e) {
if (IJ.debugMode) IJ.log("DragOver: "+e.getLocation());
Point loc = e.getLocation();
int buttonSize = Toolbar.getButtonSize();
int width = IJ.getInstance().getSize().width;
openAsVirtualStack = width-loc.x<=buttonSize;
if (openAsVirtualStack)
IJ.showStatus("<<Open as Virtual Stack>>");
else
IJ.showStatus("<<Drag and Drop>>");
}
public void dragExit(DropTargetEvent e) {
IJ.showStatus("");
}
public void dropActionChanged(DropTargetDragEvent e) {}
public void run() {
Iterator iterator = this.iterator;
while(iterator.hasNext()) {
Object obj = iterator.next();
String str = ""+obj;
if (str!=null && str.startsWith("https:/")) {
if (!str.startsWith("https://"))
str = str.replace("https:/", "http://");
obj = str;
}
if (obj!=null && (obj instanceof String))
openURL((String)obj);
else
openFile((File)obj);
}
}
private void openURL(String url) {
if (IJ.debugMode) IJ.log("DragAndDrop.openURL: "+url);
if (url!=null)
IJ.open(url);
}
public void openFile(File f) {
if (IJ.debugMode) IJ.log("DragAndDrop.openFile: "+f);
try {
if (null == f) return;
String path = f.getCanonicalPath();
if (f.exists()) {
if (f.isDirectory()) {
if (openAsVirtualStack)
IJ.run("Image Sequence...", "open=[" + path + "] sort use");
else
openDirectory(f, path);
} else {
if (openAsVirtualStack && (path.endsWith(".tif")||path.endsWith(".TIF")))
(new FileInfoVirtualStack()).run(path);
else if (openAsVirtualStack && (path.endsWith(".avi")||path.endsWith(".AVI")))
IJ.run("AVI...", "open=["+path+"] use");
else if (openAsVirtualStack && (path.endsWith(".txt"))) {
ImageProcessor ip = (new TextReader()).open(path);
if (ip!=null)
new ImagePlus(f.getName(),ip).show();
} else
(new Opener()).openAndAddToRecent(path);
OpenDialog.setLastDirectory(f.getParent()+File.separator);
OpenDialog.setLastName(f.getName());
}
} else {
IJ.log("File not found: " + path);
}
} catch (Throwable e) {
if (!Macro.MACRO_CANCELED.equals(e.getMessage()))
IJ.handleException(e);
}
}
private void openDirectory(File f, String path) {
if (path==null) return;
if (!(path.endsWith(File.separator)||path.endsWith("/")))
path += File.separator;
String[] names = f.list();
names = (new FolderOpener()).trimFileList(names);
if (names==null)
return;
String msg = "Open all "+names.length+" images in \"" + f.getName() + "\" as a stack?";
GenericDialog gd = new GenericDialog("Open Folder");
gd.setInsets(10,5,0);
gd.addMessage(msg);
gd.setInsets(15,35,0);
gd.addCheckbox("Convert to RGB", convertToRGB);
gd.setInsets(0,35,0);
gd.addCheckbox("Use Virtual Stack", virtualStack);
gd.enableYesNoCancel();
gd.showDialog();
if (gd.wasCanceled())
return;
if (gd.wasOKed()) {
convertToRGB = gd.getNextBoolean();
virtualStack = gd.getNextBoolean();
String options = " sort";
if (convertToRGB) options += " convert_to_rgb";
if (virtualStack) options += " use";
IJ.run("Image Sequence...", "open=[" + path + "]"+options);
DirectoryChooser.setDefaultDirectory(path);
} else {
for (int k=0; k<names.length; k++) {
if (!names[k].startsWith(".")) {
IJ.redirectErrorMessages(true);
ImagePlus imp = IJ.openImage(path+names[k]);
if (imp!=null) {
imp.setIJMenuBar(k==names.length-1);
imp.show();
}
IJ.redirectErrorMessages(false);
}
}
}
IJ.register(DragAndDrop.class);
}
}