/* nixonFTP
* FTP client version 0.1
* Copyright (C) 2010 NIXON Development Corporation.
* All rights reserved.
* http://members.shaw.ca/nixon.com
*/
package nixonftp;
import nixonftp.ui.*;
import nixonftp.list.*;
import java.awt.*;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIManager.*;
import javax.swing.*;
import javax.swing.event.MenuEvent;
import javax.swing.event.PopupMenuEvent;
import sun.net.ftp.FtpLoginException;
import sun.net.ftp.FtpProtocolException;
import javax.swing.event.MenuListener;
import javax.swing.event.PopupMenuListener;
import nixonftp.list.NXDefaultListModel;
import nixonftp.ui.NXLogPanel;
import nixonftp.ui.NXMenu;
public class NixonFTP extends java.applet.Applet implements ActionListener {
static NXFtpClient ftpClient;
static JFrame frame;
static NXSubFrame previewFrame;
static NXLog ftpLog;
private NXToolbar toolBar;
private NXFtpBrowserPanel remotePanel;
private NXFtpBrowserPanel localPanel;
private JButton btnLog;
private JProgressBar progressBar;
private NXSplitPane splitBrowser;
private NXSplitPane splitOverall;
private NXSidebar sideBar;
private javax.swing.Timer splitBrowserAnimator;
private boolean splitBrowserReverse;
private NXQueue queue;
private JProgressBar overallProgressBar;
private JPanel bottomPanel;
private NXObjectIndex drives;
private NXDragFeedbackLabel dragFeedbackLabel;
private int proxyType = -1;
private int PROXY_TYPE_HTTP = 0;
private int PROXY_TYPE_SOCKS = 1;
private NXQueuePanel queuePanel;
private NXLogPanel logPanel;
private JMenu menu;
private NXListAdapter dragItem;
public NixonFTP() {
frame = new JFrame("nixonFTP");
try {
frame.setIconImages(NXIcon.iconList);
} catch (NoSuchMethodError ex) {
frame.setIconImage((Image) NXIcon.iconList.get(0));
}
frame.getRootPane().putClientProperty("apple.awt.brushMetalLook", Boolean.TRUE);
Container contentPane = frame.getContentPane();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(816, 580));
frame.setGlassPane(new NXDragFeedbackLabel());
construct(contentPane);
frame.pack();
frame.setVisible(true);
}
private void construct(Container contentPane) {
ftpLog = new NXLog();
toolBar = new NXToolbar(this);
SpringLayout frameLayout = new SpringLayout();
contentPane.setLayout(frameLayout);
remotePanel = new NXFtpBrowserPanel(true, false);
//NXScrollPane remoteScroll = new NXScrollPane(remotePanel);
remotePanel.btnConnect.addActionListener(this);
remotePanel.txtHost.addActionListener(this);
remotePanel.txtUser.addActionListener(this);
remotePanel.txtPassword.addActionListener(this);
//addRemoteList("", 0);
localPanel = new NXFtpBrowserPanel(false, true);
//NXScrollPane localScroll = new NXScrollPane(localPanel);
splitBrowser = new NXSplitPane(JSplitPane.VERTICAL_SPLIT,
remotePanel, null);
splitBrowser.setSecondComponent(localPanel);
sideBar = new NXSidebar();
splitOverall = new NXSplitPane(JSplitPane.HORIZONTAL_SPLIT,
null, splitBrowser);
splitOverall.setFirstComponent(sideBar);
bottomPanel = new JPanel();
bottomPanel.setLayout(new GridLayout(0, 2));
bottomPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY));
progressBar = new JProgressBar(0, 100);
progressBar.setVisible(false);
progressBar.setStringPainted(true);
bottomPanel.add(progressBar);
overallProgressBar = new JProgressBar(0, 100);
overallProgressBar.setVisible(false);
overallProgressBar.setStringPainted(true);
overallProgressBar.setString("All");
bottomPanel.add(overallProgressBar);
contentPane.add(toolBar);
contentPane.add(splitOverall);
contentPane.add(bottomPanel);
// Make object expand to window.
frameLayout.putConstraint(SpringLayout.EAST, toolBar, 0,
SpringLayout.EAST, contentPane);
frameLayout.putConstraint(SpringLayout.WEST, toolBar, 0,
SpringLayout.WEST, contentPane);
frameLayout.putConstraint(SpringLayout.EAST, splitOverall, 0,
SpringLayout.EAST, contentPane);
frameLayout.putConstraint(SpringLayout.WEST, splitOverall, 0,
SpringLayout.WEST, contentPane);
frameLayout.putConstraint(SpringLayout.SOUTH, splitOverall, 0,
SpringLayout.NORTH, bottomPanel);
frameLayout.putConstraint(SpringLayout.SOUTH, bottomPanel, 0,
SpringLayout.SOUTH, contentPane);
frameLayout.putConstraint(SpringLayout.EAST, bottomPanel, 0,
SpringLayout.EAST, contentPane);
frameLayout.putConstraint(SpringLayout.WEST, bottomPanel, 0,
SpringLayout.WEST, contentPane);
frameLayout.putConstraint(SpringLayout.NORTH, splitOverall, 0,
SpringLayout.SOUTH, toolBar);
queue = new NXQueue();
addLocalList("", 0);
//if (File.listRoots()[0].getPath().equals("/")) {
// (new ListingWorker("/", true)).execute();
//} else {
(new DriveWorker()).execute();
//}
splitBrowser.setDividerLocation(0.6);
doTable(remotePanel.table);
doTable(localPanel.table);
queuePanel = new NXQueuePanel();
sideBar.addImpl("Queue", queuePanel);
logPanel = new NXLogPanel();
ftpLog.setArea(logPanel);
sideBar.addImpl("Log", logPanel);
}
private void makeMenu() {
JMenuBar bar = new JMenuBar();
menu = new JMenu();
menu.add(new JMenuItem("Filters..."));
//menu.addMenuListener(this);
}
public NixonFTP(Container contentPane, NXDragFeedbackLabel lbl) {
construct(contentPane);
dragFeedbackLabel = lbl;
}
public void setProxyType(String type) {
if (type.equals("0")) {
proxyType = PROXY_TYPE_HTTP;
} else if (type.equals("1")) {
proxyType = PROXY_TYPE_SOCKS;
}
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
boolean accountPanel = source.equals(remotePanel.btnConnect)
|| source.equals(remotePanel.txtHost)
|| source.equals(remotePanel.txtUser)
|| source.equals(remotePanel.txtPassword);
if (accountPanel) { //from account interface inside browser
String[] s = remotePanel.getValues();
connect(s[0], s[1], s[2]);
} else if (source.equals(toolBar.btnConnect)) {
if (!remotePanel.init) {
switchAccountPanel();
}
} else if (source.equals(toolBar.btnListing)) {
if (!remotePanel.accountPanel.isVisible()) {
doListing(false, !remotePanel.listing);
}
} else if (source.equals(toolBar.btnListingLocal)) {
doListing(true, !localPanel.listing);
} else if (source.equals(toolBar.btnFilters)) {
doFilters();
} else if (source.equals(toolBar.btnLocal)) {
toolBar.btnLocal.setSelected(splitBrowser.toggle(false));
} else if (source.equals(toolBar.btnQueue)) {
//queuePanel.setVisible(toolBar.btnQueue.isSelected());
toolBar.btnQueue.setSelected(splitOverall.toggle(true));
}
}
private void doListing(boolean local, boolean b) {
NXFtpBrowserPanel panel = (local) ? localPanel : remotePanel;
panel.listing = b;
panel.listingPanel.setVisible(b);
panel.browserScroll.setVisible(!b);
ImageIcon i = null;
if (b) {
NXList list = panel.getListBoxes(-1);
String dir = list.getDirectory();
String getDir = (dir.equals("")) ? "/" : dir;
if (local) {
(new ListingWorker(dir, true)).execute();
} else {
updateList(panel.table, (NXObjectIndex) ftpClient.getObjectIndex().get(getDir), local);
}
doCrumbs(dir, local);
panel.browserScroll.getViewport().setViewPosition(new Point(0, 0));
i = NXIcon.columns;
} else {
traversePath(local, panel.table.getDirectory());
i = NXIcon.detail;
}
if (!local) {
/*JButton btn = (local) ? toolBar.btnListingLocal : toolBar.btnListing;
btn.setIcon(i);*/
toolBar.btnListing.setIcon(i);
}
}
private void switchAccountPanel() {
boolean b = remotePanel.toggleAccountPanel();
if (b) {
String[] s = ftpClient.getCredentials();
remotePanel.txtHost.setText(s[0]);
remotePanel.txtUser.setText(s[1]);
remotePanel.txtPassword.setText(s[2]);
}
remotePanel.validateAccountPanel();
toolBar.btnConnect.setText((b) ? "Return" : "");
if (!remotePanel.init) {
toolBar.btnListing.setVisible(!b);
//toolBar.btnFilters.setVisible(!b);
}
}
private void traversePath(boolean local, String dir) {
NXFtpBrowserPanel panel = (local) ? localPanel : remotePanel;
String[] dirs = dir.split("/");
panel.removeList(1);
NXList list;
String initialPath = "";
String newDir;
NXObjectIndex oi;
for (int x = 1; x < dirs.length; x++) {
newDir = initialPath + "/" + dirs[x];
if (local) {
addLocalList(newDir, x);
} else {
addRemoteList(newDir, x);
}
list = panel.getListBoxes(-1);
if (local) {
(new ListingWorker(newDir, true, list)).execute();
} else {
oi = (NXObjectIndex) ftpClient.getObjectIndex().get(newDir);
if (oi != null) {
updateList(list, oi, false);
}
}
initialPath = newDir;
}
}
private Proxy getProxy() {
if (proxyType == -1) {
return null;
}
Proxy proxy = null;
String proxyHost = System.getProperty("ftp.proxyHost");
if (proxyHost != null) {
System.out.println("Using proxy server");
int proxyPort = 1080;
String portProperty = System.getProperty("ftp.proxyPort");
if (portProperty != null) {
try {
proxyPort = Integer.parseInt(portProperty);
} catch (NumberFormatException e) {
}
}
SocketAddress addr = new InetSocketAddress(proxyHost, proxyPort);
Proxy.Type type = (proxyType == 0) ? Proxy.Type.HTTP : Proxy.Type.SOCKS;
proxy = new Proxy(type, addr);
}
return proxy;
}
private void connect(String host, String user, String password) {
ftpClient = new NXFtpClient(ftpLog, getProxy());
ftpClient.setCredentials(
new String[]{host,
user,
password,
""});
remotePanel.setInit(false);
switchAccountPanel();
(new ConnectWorker()).execute();
}
private void updateList(NXListAdapter list, NXObjectIndex oi, boolean local) {
Object model = null;
Object[] data = null;
NXDefaultListModel listModel = null;
NXTableModel tableModel = null;
NXList nixonList = null;
NXTable table = null;
NXFilter[] filters = null;
boolean blFilter = false;
NXFtpBrowserPanel panel = (local) ? localPanel : remotePanel;
if (!panel.listing) {
listModel = new NXDefaultListModel();
nixonList = (NXList) list;
filters = nixonList.getFilters();
blFilter = filters != null;
} else {
tableModel = new NXTableModel();
table = panel.table;
}
boolean showOnly = false;
boolean hide = false;
boolean add = false;
for (Object obj : oi.objects.values()) {
NXObjectIndex oioi = (NXObjectIndex) obj;
if (blFilter) {
add = false;
hide = false;
NXFilter[] filter = nixonList.filter(filters, oioi);
for (int x = 0; x < filter.length; x++) {
if (filter[x] != null) {
hide = filter[x].action == NXFilter.HIDE;
showOnly = filter[x].action == NXFilter.SHOW;
add = filter[x].action == NXFilter.SHOW || filter[x].action == NXFilter.COLOR;
} else {
if (!showOnly) {
add = true;
}
}
}
if (!add && hide) {
continue;
}
}
if (panel.listing) {
tableModel.addRow(oioi);
} else {
listModel.addElement(oioi);
}
}
if (!panel.listing) {
model = new NXSortedListModel(listModel, NXSortedListModel.SortOrder.DESCENDING, new NXObjectComparator());
nixonList.setModel((ListModel) model);
} else {
table.setModel(tableModel);
table.getColumnModel().getColumn(0).setHeaderValue("Name");
table.getColumnModel().getColumn(1).setHeaderValue("Size");
table.getColumnModel().getColumn(2).setHeaderValue("Modified");
table.dirty = false;
}
}
class NXObjectComparator implements Comparator {
public int compare(Object o1, Object o2) {
NXObjectIndex oi1 = (NXObjectIndex) o1;
NXObjectIndex oi2 = (NXObjectIndex) o2;
String name1 = oi1.name;
String name2 = oi2.name;
if (oi1.type == oi2.type) {
return name2.compareToIgnoreCase(name1);
} else if (oi1.type > oi2.type) { //folders/links take precedence
return 1;
} else {
return -1;
}
}
}
class ConnectWorker extends SwingWorker {
String[] credentials;
public ConnectWorker() {
super();
credentials = ftpClient.getCredentials();
setStatus("Connecting to \"" + credentials[0] + "\"...", true);
}
@Override
protected Object doInBackground() throws Exception {
NXMessageLabel lbl = new NXMessageLabel();
String[] sError = new String[2];
try {
ftpClient.connect();
} catch (FtpLoginException e) {
sError[0] = "Could not log in to the server \"" + credentials[0] + "\".";
sError[1] = "Make sure that you entered your username and password correctly.";
} catch (FtpProtocolException e) {
sError[0] = "Could not connect to the server \"" + credentials[0] + "\".";
sError[1] = "Make sure that the server is an RFC 959-compliant FTP server.";
} catch (UnknownHostException e) {
sError[0] = "Could not find the server \"" + credentials[0] + "\".";
sError[1] = "Make sure you entered the address correctly. The server could be down at the moment. ";
} catch (IOException e) {
sError[0] = "Could not connect to the server \"" + credentials[0] + "\".";
sError[1] = "The error was: " + e.getMessage();
}
if (sError[0] != null) {
lbl.setInfo(sError[0], sError[1]);
JOptionPane.showMessageDialog(frame, lbl,
"", JOptionPane.ERROR_MESSAGE);
switchAccountPanel();
}
return new Object();
}
@Override
public void done() {
NXListAdapter obj = null;
if (!remotePanel.listing) {
addRemoteList("", 0);
obj = remotePanel.getListBoxes(-1);
} else {
remotePanel.table.setDirectory("");
}
updateList(obj, (NXObjectIndex) ftpClient.getObjectIndex().get("/"), false);
progressBar.setVisible(false);
}
};
class DriveWorker extends SwingWorker {
File[] roots;
@Override
protected Object doInBackground() throws Exception {
roots = File.listRoots();
return new Object();
}
@Override
public void done() {
JList list = null;
NXDefaultListModel listModel = new NXDefaultListModel();
;
NXTable table = null;
NXTableModel tableModel = null;
NXSortedListModel sortedModel = null;
if (localPanel.listing) {
table = localPanel.table;
tableModel = new NXTableModel();
} else {
list = localPanel.getListBoxes(-1);
}
String drivePath;
drives = new NXObjectIndex('z', "");
for (Object obj : roots) {
File drive = (File) obj;
drivePath = drive.getPath();
if (drivePath.length() >= 3) {
drivePath = drivePath.substring(0, 2);
}
NXObjectIndex driveIndex = new NXObjectIndex('z', drivePath);
if (localPanel.listing) {
tableModel.addRow(driveIndex);
} else {
listModel.addElement(driveIndex);
}
drives.objects.put(drivePath, driveIndex);
}
NXObjectIndex homeItem = new NXObjectIndex('h', "Home");
if (localPanel.listing) {
tableModel.addRow(homeItem);
table.setModel(tableModel);
} else {
listModel.addElement(homeItem);
sortedModel = new NXSortedListModel(listModel, NXSortedListModel.SortOrder.DESCENDING, new NXObjectComparator());
list.setModel(sortedModel);
}
drives.objects.put("Home", homeItem);
}
};
class ListingWorker extends SwingWorker {
private String directory;
private boolean local = false;
private File[] files;
private NXListAdapter list = null;
private boolean blDrives = false;
private int listingSize;
private String fake;
protected ListingWorker(String directory, boolean local, Object list) {
this.local = local;
if (list != null) {
this.list = (NXListAdapter) list;
}
setUp(directory);
}
protected ListingWorker(String directory, boolean local) {
this.local = true;
setUp(directory);
}
protected ListingWorker(String directory) {
setUp(directory);
toolBar.btnListing.setEnabled(false);
}
public void setFakeDirectory(String dir) {
fake = dir;
}
@Override
protected Object doInBackground() throws Exception {
if (local) {
if (directory.equals("")) {
blDrives = true;
} else {
if (directory.equals("/")) {
directory = "";
}
File f = new File(directory + "/");
files = f.listFiles(new HiddenFileFilter());
}
} else {
listingSize = ftpClient.indexDirectory(directory);
}
return new Object();
}
private void doLocal() {
String name;
char type;
char[] perms = new char[3];
String strPerms;
long size;
Date date;
boolean exe = false;
NXObjectIndex root = new NXObjectIndex('d', directory, "rwxrwxrwx", "", "", 0, 0, new Date());
File testFile = new File("");
try {
exe = testFile.canExecute();
exe = true;
} catch (NoSuchMethodError e) { //Java 5
exe = false;
}
if (files != null) {
for (int x = 0; x < files.length; x++) {
name = files[x].getName();
type = (files[x].isDirectory()) ? ('d') : ('-');
perms[0] = (files[x].canRead()) ? ('w') : ('-');
perms[1] = (files[x].canWrite()) ? ('r') : ('-');
if (exe) { //Java 6
perms[2] = (files[x].canExecute()) ? ('x') : ('-');
} else {
perms[2] = '-';
}
strPerms = new String(perms);
size = files[x].length();
date = new Date(files[x].lastModified());
NXObjectIndex oi = new NXObjectIndex(type, name, strPerms, "", "", size, 0, date);
root.objects.put(oi.name, oi);
}
}
if (list == null) {
list = localPanel.getListBoxes(-1);
}
updateList(list, root, true);
resetBars();
}
private void resetBars() {
if (queue.queue.isEmpty()) {
progressBar.setVisible(false);
overallProgressBar.setVisible(false);
}
}
@Override
public void done() {
if (blDrives) {
(new DriveWorker()).execute();
resetBars();
} else if (local) {
doLocal();
} else {
progressBar.setVisible(false);
toolBar.btnListing.setEnabled(true);
NXObjectIndex dirObj = (NXObjectIndex) ftpClient.getObjectIndex().get(directory);
if (fake != null) {
ftpClient.fakeDirectory(dirObj, fake);
}
if (remotePanel.listing) {
updateList(null, dirObj, false);
} else {
boolean listDefined = (list != null);
if (!listDefined) {
list = remotePanel.getListBoxes(-1);
}
if (list.getDirectory().equals(directory) || listDefined) { //user didn't move to another directory
updateList(list, dirObj, false);
}
}
queue.totalSize += listingSize;
queue.totalTransferred += listingSize;
queue.process();
}
}
private void setUp(String directory) {
this.directory = directory;
setStatus("Getting contents of \"" + directory + "\"...", true);
}
};
private void uploadFromFileList(String dir, java.util.List files) {
File file;
for (int x = 0; x < files.size(); x++) {
file = (File) files.get(x);
if (file.isDirectory()) {
String name = file.getPath();
String basePath = dir + '/' + NXFormat.getNameFromPath(name, false);
recursiveUpload(file.listFiles(), basePath);
} else {
queue.add(new NXQueueItem("upload", file.getAbsolutePath(), dir + '/' + file.getName(), ""), false);
}
}
}
private void recursiveUpload(File[] files, String basePath) {
createDirectoryIf(basePath);
for (int x = 0; x < files.length; x++) {
if (files[x].isDirectory()) {
String name = files[x].getPath();
String newPath = basePath + '/' + NXFormat.getNameFromPath(name, false);
recursiveUpload(files[x].listFiles(), newPath);
} else {
queue.add(new NXQueueItem("upload", files[x].getAbsolutePath(), basePath + '/' + files[x].getName(), ""), false);
}
}
}
class NXListTransferHandler extends TransferHandler {
DataFlavor localObjectFlavor;
String localArrayListType = DataFlavor.javaJVMLocalObjectMimeType;
private final boolean local;
private final boolean listing;
public NXListTransferHandler(boolean local, boolean listing) {
this.local = local;
this.listing = listing;
try {
localObjectFlavor = new DataFlavor(localArrayListType);
} catch (ClassNotFoundException ex) {
}
}
@Override
public int getSourceActions(JComponent c) {
if (dragItem != null) {
if (((NXListAdapter) c).getLocal() == dragItem.getLocal()) return MOVE;
else return COPY;
} else {
return COPY_OR_MOVE;
}
//return NONE;
}
@Override
public Transferable createTransferable(JComponent c) {
NXObjectIndex[] objs = null;
String dir = "";
boolean blLocal = false;
if (listing) {
NXTable table = (NXTable) c;
int[] rows = table.getSelectedRows();
NXTableModel model = (NXTableModel) table.getModel();
objs = new NXObjectIndex[rows.length];
for (int x = 0; x < rows.length; x++) {
objs[x] = model.getValueAt(rows[x]);
}
dir = table.getDirectory();
blLocal = table.getLocal();
} else {
NXList list = (NXList) c;
objs = list.getSelectedObjects();
dir = list.getDirectory();
blLocal = list.getLocal();
}
dragItem = (NXListAdapter) c;
return new NXObjectTransferable(objs, dir, blLocal);
}
@Override
public void exportDone(JComponent c, Transferable t, int action) {
}
@Override
public boolean importData(JComponent comp, Transferable t) {
NXObjectIndex[] oi = null;
NXListAdapter list = (NXListAdapter) comp;
DataFlavor unix = null;
try {
DataFlavor[] flavors = t.getTransferDataFlavors();
try {
unix = new DataFlavor("text/uri-list;class=java.io.Reader");
} catch (ClassNotFoundException ex) {
Logger.getLogger(NixonFTP.class.getName()).log(Level.SEVERE, null, ex);
}
String dir = list.getDirectory();
NXObjectIndex val = list.getSelectedValue();
if (val != null && (val.type == 2 || val.realType == 2) && list.dropLeft()) {
dir += '/' + val.name;
}
for (int x = 0; x < flavors.length; x++) {
if (flavors[x].isFlavorJavaFileListType()) {
java.util.List fileList = (java.util.List) t.getTransferData(DataFlavor.javaFileListFlavor);
uploadFromFileList(dir, fileList);
break;
} else if (flavors[x].equals(unix)) {
uploadFromFileList(dir, doUnix(flavors[x], t));
} else if (flavors[x].equals(localObjectFlavor)) {
Object[] data = (Object[]) t.getTransferData(flavors[x]);
NXObjectIndex[] o = (NXObjectIndex[]) data[0];
String dir2 = (String) data[1];
boolean importFromLocal = data[2].equals(true);
if (dir2.equals(dir)) return false;
if (importFromLocal == list.getLocal()) { //move operation
if (importFromLocal) { localMoveFromIndex(dir2, dir, o);
} else { remoteMoveFromIndex(dir2, dir, o); }
} else if (importFromLocal) {
uploadFromIndex(dir, dir2, o, list);
} else {
downloadFromIndex(dir2, dir, o, list);
return true;
}
break;
}
}
} catch (UnsupportedFlavorException ex) {
} catch (IOException ex) {
}
return true;
}
private ArrayList doUnix(DataFlavor f, Transferable t) throws UnsupportedFlavorException, IOException {
BufferedReader read = new BufferedReader(f.getReaderForText(t));
// Delete "file://" protocol from filename
String fileName;
ArrayList fileList = new ArrayList();
while ((fileName = read.readLine()) != null) {
fileName = fileName.substring(7).replace("%20", " ");
String test = fileName.substring(0, 9);
if (test.equals("localhost")) {
fileName = fileName.substring(9);
}
fileList.add(new File(fileName));
}
// Delete "localhost" from Mac filenames
read.close();
return fileList;
}
@Override
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
if (dragItem != null) {
if (comp.equals(dragItem) && !dragItem.dropLeft()) return false;
return true;
}
return false;
}
class NXObjectTransferable implements Transferable {
private NXObjectIndex[] objects;
public boolean local;
public String dir;
public NXObjectTransferable(NXObjectIndex[] files, String dir, boolean local) {
objects = files;
this.dir = dir;
this.local = local;
}
public synchronized Object getTransferData(DataFlavor flavor) {
return new Object[]{objects, dir, local};
}
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{localObjectFlavor};
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(localObjectFlavor);
}
}
}
class UploadWorker extends SwingWorker {
private String localFile;
private String remoteFile;
private Object list;
private File file;
protected UploadWorker(String localFile, String remoteFile, Object list) {
this.localFile = localFile;
this.remoteFile = remoteFile;
this.list = list;
setStatus("Uploading " + NXFormat.getNameFromPath(localFile, false), false);
}
protected Object doInBackground() throws IOException {
int i = 0;
long uploaded = 0;
byte[] bytesIn = new byte[1024];
if (!ftpClient.getBinary()) {
ftpClient.binary();
}
file = new File(localFile);
long size = file.length();
FileInputStream in = new FileInputStream(localFile);
BufferedOutputStream out = null;
double progress = 0.0;
try {
out = new BufferedOutputStream(ftpClient.put(remoteFile));
while ((i = in.read(bytesIn)) >= 0) {
uploaded += i;
//frame.setTitle(Long.toString(uploaded));
progress = (double) uploaded / (double) size * (double) 100;
queue.updateTransferred(i);
progressBar.setValue((int) progress);
if (progressBar.isIndeterminate()) {
progressBar.setIndeterminate(false);
}
out.write(bytesIn, 0, i);
}
in.close();
out.close();
addToList();
} catch (Exception e) {
String message = e.getMessage();
if (message.contains("550")) {
NXQueueItem curr = (NXQueueItem) queue.get(0);
curr.setError("You do not have permission to upload the file " + NXFormat.getNameFromPath(curr.localFile, false));
queue.addError(curr);
}
}
return new Object();
}
private void addToList() {
addItem(false, remoteFile, new Date(file.lastModified()), file.length());
}
@Override
public void done() {
progressBar.setVisible(false);
queue.process();
}
};
private void addItem(boolean local, String file, Date modified, long size) {
NXObjectIndex oi;
String[] elements = NXFormat.getNameFromPath(file);
NXFtpBrowserPanel panel = (local) ? localPanel : remotePanel;
NXListAdapter l = panel.getListIfShown(elements[0]);
NXObjectIndex dirIndex = (NXObjectIndex) ftpClient.getObjectIndex().get(elements[0]);
if (l != null) {
oi = new NXObjectIndex('-', elements[1], "wrxwrxwrx", "", "", size, 0, modified);
l.addElement(oi);
if (dirIndex != null) {
dirIndex.objects.put(elements[1], oi);
}
}
}
private void setStatus(String s, boolean indeterminate) {
progressBar.setVisible(true);
progressBar.setString(s);
queue.currentString = s;
progressBar.setIndeterminate(indeterminate);
}
private void updateOverall() {
float progress = (float) queue.totalTransferred / (float) queue.totalSize * 100;
overallProgressBar.setValue((int) progress);
overallProgressBar.setVisible(true);
}
class DownloadWorker extends SwingWorker {
private String localFile;
private String remoteFile;
private boolean preview;
private Object list = null;
private NXObjectIndex obj;
byte[] bytesIn;
byte[] bytesOut;
boolean error = false;
long size;
private boolean temp;
File tempFile;
protected DownloadWorker(String localFile, String remoteFile, Object list) {
this.list = list;
setUp(localFile, remoteFile);
}
protected DownloadWorker(String localFile, String remoteFile, boolean preview, boolean temp) {
this.preview = preview;
this.temp = temp;
setUp(localFile, remoteFile);
}
protected void setUp(String localFile, String remoteFile) {
if (temp) {
try {
tempFile = File.createTempFile("nixonftp", NXFormat.getNameFromPath(remoteFile, false));
this.localFile = tempFile.getAbsolutePath();
tempFile.deleteOnExit();
} catch (IOException ex) {
System.out.println("DownloadWorker: IOException creating local temp file");
}
} else { this.localFile = localFile; }
this.remoteFile = remoteFile;
setStatus("Downloading " + NXFormat.getNameFromPath(this.remoteFile, false), false);
}
protected Object doInBackground() throws IOException {
int i = 0;
int downloaded = 0;
FileOutputStream out = null;
if (!ftpClient.getBinary()) {
ftpClient.binary();
}
if (!preview) {
out = new FileOutputStream(localFile);
}
String[] parts = NXFormat.getNameFromPath(remoteFile); //get parent directory, filename only
String fileName = parts[1];
String pathName = parts[0];
NXObjectIndex oi = (NXObjectIndex) ftpClient.getObjectIndex().get(pathName);
obj = (NXObjectIndex) oi.objects.get(fileName);
size = obj.size;
BufferedInputStream in = null;
bytesIn = new byte[4096];
if (preview) {
bytesOut = new byte[(int) size];
}
double progress;
try {
in = new BufferedInputStream(ftpClient.get(remoteFile));
if (preview) {
while (downloaded < size
&& (i = in.read(bytesOut, downloaded, bytesOut.length - downloaded)) >= 0) {
downloaded += i;
}
} else {
while ((i = in.read(bytesIn)) >= 0) {
downloaded += i;
out.write(bytesIn, 0, i);
progress = (double) downloaded / (double) size * (double) 100;
progressBar.setValue((int) progress);
queue.updateTransferred(i);
}
}
} catch (Exception e) {
error = true;
String message = e.getMessage();
System.out.println("Error in DownloadWorker: " + message);
if (message.contains("550")) {
NXQueueItem curr = (NXQueueItem) queue.get(0);
curr.setError("You do not have permission to download the file " + NXFormat.getNameFromPath(curr.localFile, false));
queue.addError(curr);
} else {
}
} finally {
in.close();
out.close();
}
return new Object();
}
@Override
public void done() {
progressBar.setVisible(false);
queue.process();
if (!error) {
addItem(true, localFile, new Date(), size);
}
if (temp) {
openFile(localFile);
java.util.Timer t = new java.util.Timer();
t.schedule(new FileWatcher(tempFile, remoteFile), 3000, 3000);
}
if (preview) {
(new PreviewWorker(remoteFile, bytesOut)).execute();
}
}
};
class FileWatcher extends TimerTask {
File f;
long lastModified;
String origFile;
boolean pending;
public FileWatcher(File f, String origFile) {
this.f = f;
this.origFile = origFile;
lastModified = f.lastModified();
}
@Override
public void run() {
long currentModified = f.lastModified();
if (currentModified != lastModified) {
int result = uploadTempFile(f, origFile);
if (result == 0) { //upload it nao!
queue.add(new NXQueueItem("upload", f.getAbsolutePath(), origFile, "", null, f.length()), true);
cancel();
} else if (result == 1) {
lastModified = currentModified;
} else {
f.delete();
cancel();
}
}
}
}
int uploadTempFile(File temp, String remoteFile) {
int result = NXFormat.alertBox(this,
"The local file representing " + NXFormat.getNameFromPath(remoteFile, false) + " has changed. Do you want to upload these changes?",
"<b>Full remote file path: </b>" + remoteFile +
"<br /><b>Modified: </b>" + NXFormat.parseDate(new Date(temp.lastModified())),
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,
new String[] {"Upload","Don't Upload Yet","Never Upload"}, 0);
return result;
}
class PreviewWorker extends SwingWorker {
private File file;
private String data;
boolean image = false;
String title;
private byte[] bytes;
protected PreviewWorker(String remoteFile, byte[] bytes) {
this.bytes = bytes;
setUp(remoteFile);
}
protected PreviewWorker(String remoteFile, File file) {
this.file = file;
setUp(remoteFile);
}
private void setUp(String remoteFile) {
image = NXFormat.isImage(remoteFile);
title = NXFormat.getNameFromPath(remoteFile, false);
ImageIcon img = null;
if (image) {
if (file != null) {
img = new ImageIcon(file.getAbsolutePath());
} else if (bytes != null) {
img = new ImageIcon(bytes);
}
}
if (!(previewFrame instanceof NXSubFrame)) {
previewFrame = new NXSubFrame(frame, title, image, img);
} else {
//previewFrame already created
previewFrame.setTitle(title);
//previewFrame.setUp(image, img);
if (img != null) {
previewFrame.setImage(img);
}
}
previewFrame.setVisible(true);
if (!image) {
previewFrame.displayPlainText("");
}
}
private boolean verifyLoad(long size) {
Object[] options = {"Load",
"Cancel"};
int n = JOptionPane.showOptionDialog(frame,
"<html><table width='360'><tr><td><strong>The file " + title + " may take a long time to preview. Would you still like to load it?</strong>"
+ "</td></tr><tr><td>" + title + " is " + NXFormat.fileSize(size) + ". Text files larger than 128 KB need a lot of time to load.</td></tr></table></html>",
null,
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[1]);
return (n == JOptionPane.OK_OPTION);
}
@Override
protected Object doInBackground() throws Exception {
if (!image && file != null) {
if (file.length() > 131072) {
if (!verifyLoad(file.length())) {
return new Object();
}
}
FileInputStream in = null;
BufferedInputStream bis;
DataInputStream dis = null;
BufferedReader br = null;
try {
in = new FileInputStream(file);
// Get the object of DataInputStream
dis = new DataInputStream(in);
br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
data += strLine + "\n";
}
//Close the input stream
} finally {
dis.close();
in.close();
br.close();
}
}
return new Object();
}
@Override
public void done() {
if (data == null && bytes != null) {
data = new String(bytes);
}
if (data != null && image == false) {
if (bytes.length > 131072) {
if (!verifyLoad(bytes.length)) {
return;
}
}
previewFrame.displayPlainText(data);
}
}
};
class CommandWorker extends SwingWorker {
private String cmd;
private final boolean explicit;
private String error;
protected CommandWorker(String cmd, String message, boolean explicit) {
this.cmd = cmd;
this.explicit = explicit;
setStatus(message, true);
}
@Override
protected Object doInBackground() throws Exception {
String[] sError = new String[2];
try {
ftpClient.cd("/");
ftpClient.sendCommand(cmd);
} catch (Exception e) {
String msg = e.getMessage();
NXQueueItem curr = (NXQueueItem) queue.get(0);
if (cmd.contains("MKD") && !explicit) {
error = "You do not have permission to create a folder here.";
if (explicit) {
if (msg.contains("550")) {
sError[0] = "Could not create new folder.";
sError[1] = error;
}
}
} else if (cmd.contains("RMD")) {
error = "You do not have permission to delete the folder.";
if (explicit) {
if (msg.contains("550")) {
sError[0] = "Could not delete the folder.";
sError[1] = error;
}
}
}
if (!explicit && error != null) {
curr.setError(error);
queue.addError(curr);
}
if (sError[0] != null) {
showError(sError);
}
}
return new Object();
}
@Override
public void done() {
progressBar.setVisible(false);
overallProgressBar.setVisible(false);
if (error == null && cmd.startsWith("MKD")) {
String base = cmd.substring(4);
String[] pathElements = NXFormat.getNameFromPath(base);
NXListAdapter list = remotePanel.getListIfShown(pathElements[0]);
if (list != null) {
list.addElement(new NXObjectIndex('d', pathElements[1]));
}
}
queue.process();
}
};
class RenameWorker extends SwingWorker {
private String oldFile;
private String newFile;
protected RenameWorker(String oldFile, String newFile) {
this.oldFile = oldFile;
this.newFile = newFile;
setStatus("Renaming \"" + NXFormat.getNameFromPath(oldFile, false) + "\"", true);
}
@Override
protected Object doInBackground() throws Exception {
String[] sError = new String[2];
try {
ftpClient.rename(oldFile, newFile);
} catch (Exception e) {
String msg = e.getMessage();
if (msg.contains("550")) {
String[] parts = NXFormat.getNameFromPath(oldFile);
sError[0] = "Could not rename the file \""
+ parts[1] + "\" to \""
+ NXFormat.getNameFromPath(newFile, false) + "\".";
sError[1] = "You do not have permission to rename files in \""
+ parts[0] + "\".";
}
if (sError[0] != null) {
showError(sError);
}
}
return new Object();
}
@Override
public void done() {
queue.process();
}
};
class DeleteWorker extends SwingWorker {
private String file;
protected DeleteWorker(String file) {
this.file = file;
setStatus("Deleting \"" + NXFormat.getNameFromPath(file, false) + "\".", true);
}
@Override
protected Object doInBackground() throws Exception {
deleteRemoteFile(file);
return new Object();
}
@Override
public void done() {
queue.process();
}
};
void deleteRemoteFile(String file) {
String[] sError = new String[2];
try {
ftpClient.sendCommand("DELE " + file);
} catch (Exception e) {
String msg = e.getMessage();
if (msg.contains("550")) {
NXQueueItem curr = new NXQueueItem("delete", "", file, "");
curr.setError("You do not have permission to delete the file " + NXFormat.getNameFromPath(file, false));
queue.addError(curr);
}
}
}
class LocalDeleteWorker extends SwingWorker {
private String initialPath;
private NXListAdapter list;
private char type = '-';
private boolean success;
protected LocalDeleteWorker(String initialPath, NXListAdapter list) {
super();
this.initialPath = initialPath;
this.list = list;
setStatus("Deleting \"" + NXFormat.getNameFromPath(initialPath, false) + "\".", true);
}
@Override
protected Object doInBackground() throws Exception {
deleteRecursively(initialPath);
return new Object();
}
private void deleteRecursively(String path) {
File f = new File(path);
if (f.isDirectory()) {
type = 'd';
File[] files = f.listFiles();
for (int x = 0; x < files.length; x++) {
if (files[x].isDirectory()) {
deleteRecursively(files[x].getPath());
} else {
files[x].delete();
}
}
}
boolean b = f.delete();
if (path.equals(initialPath)) {
success = b;
}
}
@Override
public void done() {
if (success) {
NXObjectIndex[] items = new NXObjectIndex[1];
items[0] = new NXObjectIndex(type, NXFormat.getNameFromPath(initialPath, false));
localPanel.remoteItemsFromList(list, items);
if (type == 'd') {
localPanel.removeList(list.getIndex() + 1);
}
}
progressBar.setVisible(false);
}
};
private void showError(String[] s) {
NXMessageLabel lbl = new NXMessageLabel();
lbl.setInfo(s[0], s[1]);
JOptionPane.showMessageDialog(frame, lbl,
"", JOptionPane.ERROR_MESSAGE);
}
private void doTable(NXTable t) {
t.addMouseListener(new ListListener(t.getLocal()));
setMenu(t, t.getLocal());
t.setTransferHandler(new NXListTransferHandler(t.getLocal(), true));
try {
t.getDropTarget().addDropTargetListener(new NXDropListener(t));
} catch (TooManyListenersException ex) {
}
}
private void doCrumbs(String dir, boolean local) {
NXFtpBrowserPanel panel = null;
panel = (local) ? localPanel : remotePanel;
if (local) {
dir = dir.replace("\\", "/");
}
panel.crumbPanel.removeAll();
String[] dirs = dir.split("/");
String lastDir = "";
String currDir;
NXCrumb crumb;
boolean first;
for (int x = 0; x < dirs.length; x++) {
first = dirs[x].equals("");
if (first) {
currDir = (local) ? "" : "/";
} else {
currDir = dirs[x];
}
crumb = new NXCrumb(currDir, lastDir + currDir);
crumb.first = first;
if (first && local) {
crumb.setText("Computer");
}
crumb.addMouseListener(new CrumbListener(local));
panel.crumbPanel.add(crumb);
lastDir += dirs[x] + "/";
}
panel.crumbPanel.updateUI();
panel.table.setDirectory(dir);
}
class CrumbListener implements MouseListener {
private boolean local;
public CrumbListener(boolean local) {
this.local = local;
}
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
return;
}
NXCrumb crumb = (NXCrumb) e.getComponent();
NXFtpBrowserPanel panel = (local) ? localPanel : remotePanel;
String dir = (crumb.dir.equals("/") || crumb.first) ? "" : crumb.dir;
panel.table.setDirectory(dir);
if (local) {
(new ListingWorker(dir, true)).execute();
} else {
HashMap map = ftpClient.getObjectIndex();
if (map.containsKey(crumb.dir)) {
updateList(null,
(NXObjectIndex) ftpClient.getObjectIndex().get(crumb.dir), local);
} else {
queue.add(new NXQueueItem("list", "", crumb.dir, ""), true);
}
}
doCrumbs(dir, local);
}
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
JPopupMenu menu = new JPopupMenu();
HashMap map = ftpClient.getObjectIndex();
NXCrumb lbl = (NXCrumb) e.getComponent();
if (!local) {
NXObjectIndex oi = (NXObjectIndex) ftpClient.getObjectIndex().get(lbl.dir);
NXObjectIndex obj;
NXTraverseMenu m;
String dir = (lbl.dir.equals("/")) ? "" : lbl.dir;
Object[] objects = oi.objects.values().toArray();
for (int x = 0; x < objects.length; x++) {
obj = (NXObjectIndex) objects[x];
if (obj.type == 2 || obj.realType == 2) {
m = new NXTraverseMenu(obj.name, dir + "/" + obj.name, false);
m.setIcon(NXIcon.small[2]);
m.addMenuListener(new ListTraverseMenuListener(true, null));
menu.add(m);
}
}
}
menu.show(lbl, 0, lbl.getHeight());
}
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
private void addRemoteList(String dir, int index) {
if (remotePanel.listing) {
return;
}
remotePanel.removeList(index);
remotePanel.addList();
final NXList list = remotePanel.getListBoxes(-1);
list.setDirectory(dir);
list.addMouseListener(new ListListener(false));
list.addKeyListener(new ListListener(false));
list.setTransferHandler(new NXListTransferHandler(false, false));
try {
list.getDropTarget().addDropTargetListener(new NXDropListener(list));
} catch (TooManyListenersException ex) {
}
//list.setTransferHandler(new ListTransferHandler());
setMenu(list, false);
NXMenu menu = (NXMenu) list.getMenu();
JMenu transferTo = (JMenu) menu.getIndex().get("TransferTo");
transferTo.addMenuListener(new ListTraverseMenuListener(list.getLocal(), new TransferToActionListener(list)));
}
private void addUniqueLocation(NXTraverseMenu menu, boolean local) {
boolean conflict = false;
NXFtpBrowserPanel panel = (local) ? localPanel : remotePanel;
String dir;
for (int x = 0; x < panel.locations.size(); x++) {
dir = panel.locations.get(x).getDir();
if (menu.getDir().contains(dir)) {
conflict = true; //already added in subfolder!
}
}
if (!conflict) {
panel.locations.add(menu);
}
}
class TransferToActionListener implements ActionListener {
private final NXListAdapter list;
public TransferToActionListener(NXList list) {
this.list = list;
}
public void actionPerformed(ActionEvent e) {
NXTraverseMenu menu;
if (e.getSource() instanceof NXMenuItem) {
NXMenuItem item = (NXMenuItem) e.getSource();
menu = (NXTraverseMenu) item.parent;
} else {
menu = (NXTraverseMenu) e.getSource();
}
addUniqueLocation(menu, list.getLocal());
NXListAdapter otherList;
NXFtpBrowserPanel panel = (list.getLocal()) ? remotePanel : localPanel;
otherList = panel.getListIfShown(menu.getDir());
if (list.getLocal()) {
uploadFromIndex(menu.getDir(), list.getDirectory(), list.getSelectedValues(), otherList);
} else {
downloadFromIndex(list.getDirectory(), menu.getDir(), list.getSelectedValues(), otherList);
}
NXMenu popUpMenu = (NXMenu) list.getMenu();
popUpMenu.setVisible(false);
popUpMenu.updateUI();
}
}
class TraverseMenuListener implements MenuListener {
boolean local;
ActionListener listener;
public TraverseMenuListener(boolean local, ActionListener listener) {
}
void showLocalMenu(String root, NXTraverseMenu topMenu) {
topMenu.removeAll();
if (ftpClient == null) {
return;
}
NXObjectIndex rootIndex = (NXObjectIndex) ftpClient.getObjectIndex().get(root);
if (rootIndex != null) {
Object[] folderContents = rootIndex.objects.values().toArray();
String name;
String path;
for (int x = 0; x < rootIndex.objects.size(); x++) {
NXObjectIndex oi = (NXObjectIndex) folderContents[x];
path = (root.equals("/")) ? '/' + oi.name : root + '/' + oi.name;
name = NXFormat.getNameFromPath(path, false);
if (oi.type == 2 || oi.realType == 2) {
NXTraverseMenu newMenu = new NXTraverseMenu(name, path, false);
newMenu.addMenuListener(this);
topMenu.add(newMenu);
}
}
}
addAction(topMenu);
}
public void showMenu(String root, NXTraverseMenu topMenu) {
topMenu.removeAll();
NXMenuItem here = new NXMenuItem("Here", "Here");
topMenu.add(here);
here.parent = topMenu;
here.addActionListener(listener);
File f = new File(root);
File[] files = f.listFiles(new HiddenFileFilter());
if (files == null) {
return;
}
String name;
String path;
for (int x = 0; x < files.length; x++) {
path = files[x].getPath();
name = NXFormat.getNameFromPath(path, false);
if (files[x].isDirectory()) {
NXTraverseMenu newMenu = new NXTraverseMenu(name, path, false);
newMenu.addMenuListener(this);
topMenu.add(newMenu);
}
}
addAction(topMenu);
}
private void addAction(NXTraverseMenu menu) {
menu.addActionListener(listener);
}
public void doMenu(EventObject e) {
NXTraverseMenu m = (NXTraverseMenu) e.getSource();
String dir = m.getDir();
if (!local) {
if (dir.equals("")) { //initial
Object[] roots = drives.objects.values().toArray();
m.removeAll();
String path;
boolean home;
NXFtpBrowserPanel panel = (local) ? localPanel : remotePanel;
int size = panel.locations.size();
for (int x = 0; x < size; x++) {
m.add(panel.locations.get(x));
}
if (size > 0) {
m.addSeparator();
}
for (int x = 0; x < roots.length; x++) {
NXObjectIndex oi = (NXObjectIndex) roots[x];
home = oi.type == 4;
path = home ? System.getProperty("user.home") : oi.name + '/';
NXTraverseMenu newMenu = new NXTraverseMenu(oi.name, path, true);
newMenu.setIcon((home) ? NXIcon.small[4] : NXIcon.small[3]);
newMenu.addMenuListener(this);
m.add(newMenu);
}
} else {
showMenu(m.getDir(), m);
}
} else {
if (dir.equals("")) { //inital
showLocalMenu("/", m);
} else {
showLocalMenu(dir, m);
}
}
}
public void menuSelected(MenuEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void menuDeselected(MenuEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void menuCanceled(MenuEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class ListTraverseMenuListener extends TraverseMenuListener implements MenuListener {
public ListTraverseMenuListener(boolean local, ActionListener listener) {
super(local, listener);
this.local = local;
this.listener = listener;
}
@Override
public void menuCanceled(MenuEvent evt) {
}
@Override
public void menuDeselected(MenuEvent evt) {
}
public void menuSelected(MenuEvent evt) {
doMenu(evt);
}
}
class CrumbMenuListener extends TraverseMenuListener implements PopupMenuListener {
public CrumbMenuListener(boolean local, ActionListener listener) {
super(local, listener);
this.local = local;
this.listener = listener;
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
doMenu(e);
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
public void popupMenuCanceled(PopupMenuEvent e) {
}
}
class HiddenFileFilter implements FilenameFilter {
public boolean accept(File f, String name) {
return !new File(f.getPath() + '/' + name).isHidden();
}
}
private void addLocalList(String dir, int index) {
if (localPanel.listing) {
return;
}
localPanel.removeList(index);
localPanel.addList();
NXList list = localPanel.getListBoxes(-1);
list.setDirectory(dir);
list.setTransferHandler(new NXListTransferHandler(true, false));
try {
list.getDropTarget().addDropTargetListener(new NXDropListener(list));
} catch (TooManyListenersException ex) {
}
list.addMouseListener(new ListListener(true));
list.addKeyListener(new ListListener(true));
setMenu(list, true);
NXContextMenu m = (NXContextMenu) list.getMenu();
JMenu transferTo = (JMenu) m.getIndex().get("TransferTo");
transferTo.addMenuListener(new ListTraverseMenuListener(list.getLocal(), new TransferToActionListener(list)));
localPanel.originalMenu = transferTo;
}
private void setMenu(NXListAdapter list, boolean local) {
MouseListener popupListener = new PopupListener();
list.addMouseListener(popupListener);
NXMenu m = (NXMenu) list.getMenu();
Object[] menuItems = (Object[]) m.getIndex().values().toArray();
for (int x = 0; x < menuItems.length; x++) {
try {
((JMenuItem) menuItems[x]).addActionListener(new ListPopupListener(list, local));
} catch (Exception e) {
continue;
} //separator
}
}
class ListListener implements MouseListener, KeyListener {
private boolean local;
private NXFtpBrowserPanel panel;
public ListListener(boolean local) {
super();
this.local = local;
if (local) {
this.panel = localPanel;
} else {
this.panel = remotePanel;
}
}
public void mouseClicked(MouseEvent e) {
NXListAdapter adapter = (NXListAdapter) e.getComponent();
if (e.getButton() != MouseEvent.BUTTON3) {
listAction(adapter, e.getClickCount() - 1);
}
}
private void listAction(NXListAdapter adapter, int eventType) { // type 0 for single-click; 1 for double
NXObjectIndex selectedObject = (NXObjectIndex) adapter.getSelectedValue();
boolean quit = panel.table.dirty && panel.listing;
if (selectedObject == null || quit) {
return;
}
NXListAdapter list = (panel.listing) ? null : adapter;
String dir = null;
if (adapter.getSelectedItemCount() == 1) {
String pre = "";
pre += (adapter.getDirectory().equals("")) ? "/" : adapter.getDirectory() + "/";
boolean home = selectedObject.type == 4;
dir = home ? //home directory?
System.getProperty("user.home") : pre + selectedObject.name;
int type = getType(pre, selectedObject);
if (eventType == 0) {
if (type >= 1) { //directory
if (local) {
if (!panel.listing) {
addLocalList(dir, list.getIndex() + 1);
}
(new ListingWorker(dir, true)).execute();
} else { //remote
NXList update = null;
if (!panel.listing) {
addRemoteList(dir, list.getIndex() + 1);
update = remotePanel.getListBoxes(-1);
} else {
panel.table.setDirectory(dir);
}
HashMap map = ftpClient.getObjectIndex();
if (map.containsKey(dir)) {
updateList(update,
(NXObjectIndex) ftpClient.getObjectIndex().get(dir), local);
} else {
NXQueueItem qi = new NXQueueItem("list", "", dir, "");
if (selectedObject.type == 1) { //link, must update real location too!
qi.fakePath = pre + selectedObject.realLoc;
System.out.println(qi.fakePath);
}
queue.add(qi, true);
if (panel.listing) {
panel.table.dirty = true;
}
}
}
if (panel.listing) {
if (home) {
dir = "/" + dir;
}
doCrumbs(dir, local);
}
} else if (type == 0) {
//check if image
if (previewFrame != null && previewFrame.isVisible()) {
previewImage(dir, local);
}
if (!panel.listing) {
panel.removeList(list.getIndex() + 1);
}
}
} else if (eventType == 1 && type == 0) { //double-click on file
if (local) { openFile(dir);
} else {
//previewImage(dir, local);
queue.add(new NXQueueItem("open", "", dir, ""), true);
}
}
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
NXListAdapter list = (NXListAdapter) e.getComponent();
switch (e.getKeyCode()) {
case KeyEvent.VK_DELETE:
deleteFromList(list, local);
break;
case KeyEvent.VK_CONTEXT_MENU:
case KeyEvent.VK_F10:
showPopup(list, 0, list.getRealBounds().height);
break;
case KeyEvent.VK_LEFT:
NXList l = panel.getListBoxes(list.getIndex() - 1);
l.requestFocusInWindow();
panel.browserScroll.getViewport().scrollRectToVisible(l.getRealBounds());
break;
case KeyEvent.VK_ENTER:
case KeyEvent.VK_RIGHT:
int type = (e.isControlDown()) ? 1 : 0;
listAction(list, type);
break;
}
}
}
class PopupListener extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
@Override
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.getButton() == 3) {
NXListAdapter c = (NXListAdapter) e.getComponent();
showPopup(c, e.getX(), e.getY());
}
}
}
void showPopup(NXListAdapter c, int posX, int posY) {
NXContextMenu m = (NXContextMenu) c.getMenu();
int selDiff = c.getSelectedItemCount();
HashMap idx = m.getIndex();
NXObjectIndex selectedObject = (NXObjectIndex) c.getSelectedValue();
NXMenuItem newFolder = (NXMenuItem) m.getIndex().get("NewFolder");
NXMenuItem newFolderInItem = (NXMenuItem) m.getIndex().get("NewFolderIn");
NXMenuItem preview = (NXMenuItem) idx.get("Preview");
NXMenuItem transfer = (NXMenuItem) idx.get("Transfer");
NXMenuItem switchView = (NXMenuItem) idx.get("SwitchView");
NXTraverseMenu transferTo = (NXTraverseMenu) idx.get("TransferTo");
NXMenuItem rename = (NXMenuItem) idx.get("Rename");
JMenu deleteMenu = m.getDeleteMenu();
newFolderInItem.setVisible(false);
preview.setVisible(false);
m.switchView(c.getLocal() ? localPanel.listing : remotePanel.listing);
String appe;
boolean selection = selectedObject != null;
if (selection) {
if (selDiff == 1) { // 1 item selected
if (selectedObject.type == 2 || selectedObject.realType == 2) {
newFolderInItem.setText("New Folder in " + selectedObject.name);
newFolderInItem.setVisible(true);
} else if (selectedObject.type == 0 || selectedObject.realType == 0) {
if (selectedObject.size <= 524288) {
preview.setVisible(true);
}
}
appe = " \"" + selectedObject.name + "\"";
} else { // more than 1 item selected
appe = " these " + selDiff + " items";
}
deleteMenu.setText("Delete" + appe);
String strTransfer = (m.local) ? "Upload" : "Download";
transfer.setText(strTransfer + appe);
transferTo.setText(strTransfer + " To");
rename.setText("Rename" + appe);
}
transfer.setVisible(selection);
transferTo.setVisible(selection);
HashMap separators = m.getSeparators();
//((JSeparator) separators.get("bottom")).setVisible(selection);
((JSeparator) separators.get("middle")).setVisible(selection);
deleteMenu.setVisible(selection);
rename.setVisible(selection);
m.show((Component) c, posX, posY);
}
class ListPopupListener implements ActionListener {
private final NXListAdapter list;
private String id;
private NXObjectIndex selectedObject;
private final boolean local;
public ListPopupListener(NXListAdapter list, boolean local) {
this.list = list;
this.local = local;
}
public void actionPerformed(ActionEvent e) {
NXMenuItem menuItem = (NXMenuItem) e.getSource();
selectedObject = (NXObjectIndex) list.getSelectedValue();
id = menuItem.getId();
if (id.contains("NewFolder")) {
newFolder();
/*} else if (id.equals("ShowLog")) {
showLog();
} else if (id.equals("ShowQueue")) {
showQueue();
} else if (id.equals("Filters")) {
doFilters();*/
} else if (id.equals("Preview")) {
preview();
} else if (id.equals("Open")) {
open();
} else if (id.equals("Rename")) {
rename();
} else if (id.equals("Delete")) {
deleteFromList(list, local);
} else if (id.equals("Transfer")) {
transfer();
} else if (id.equals("Reload")) {
reload();
} else if (id.equals("SwitchView")) {
NXFtpBrowserPanel panel = list.getLocal() ? localPanel : remotePanel;
doListing(list.getLocal(), !panel.listing);
}
}
private void rename() {
String currFile = list.getDirectory() + '/' + selectedObject.name;
String newName = (String) JOptionPane.showInputDialog(
frame,
"Enter the new name of the file \"" + selectedObject.name + "\".",
"Rename",
JOptionPane.QUESTION_MESSAGE,
null,
null,
selectedObject.name);
String fullPath = list.getDirectory() + '/' + newName;
if (newName != null && !newName.equals(selectedObject.name)) {
if (!local) {
queue.add(new NXQueueItem("rename", currFile, fullPath, ""), true);
} else {
File f = new File(currFile);
boolean success = f.renameTo(new File(fullPath));
if (success) {
selectedObject.name = newName;
list.updateUI();
} else { //could not rename
NXMessageLabel lbl = new NXMessageLabel();
lbl.setInfo("Could not rename \"" + selectedObject.name + "\" to \"" + newName + "\".",
"Make sure there is not already a file or folder with the same name in \"" + list.getDirectory() + "\".");
JOptionPane.showMessageDialog(frame, lbl,
"", JOptionPane.ERROR_MESSAGE);
}
}
}
}
private void newFolder() {
String shortDir;
String initialDir = list.getDirectory();
boolean in;
in = id.equals("NewFolderIn");
if (in) {
initialDir += '/' + selectedObject.name;
shortDir = selectedObject.name;
} else {
if (list.getDirectory().equals("")) {
shortDir = "/";
} else {
shortDir = NXFormat.getNameFromPath(list.getDirectory(), false);
}
}
String newDir = (String) JOptionPane.showInputDialog(
frame,
"Enter the name of the folder that will be created in: \n"
+ "<html><font face='Helvetica' size='+1'>" + shortDir + "</font><br>"
+ "<font color='#336699' size='-2'>" + initialDir + "</font></html>\n",
"Create New Folder",
JOptionPane.QUESTION_MESSAGE,
NXIcon.folder,
null,
"");
if (newDir != null) {
String newPath = initialDir + '/' + newDir;
NXObjectIndex dir = new NXObjectIndex('d', newDir, "rwxrwxrwx", "", "", 0, 0, new Date());
NXListAdapter updateList;
if (!local) {
queue.add(new NXQueueItem("mkdir-explicit", "", newPath, "", list), true);
} else {
File f = new File(newPath);
f.mkdir();
if (in) {
updateList = localPanel.getListBoxes(-1);
} else {
updateList = list;
}
NXObjectIndex[] dirs = new NXObjectIndex[1];
dirs[0] = dir;
localPanel.addItemsToList(updateList, dirs);
}
}
} //newFolder
private void preview() {
previewImage(list.getDirectory() + '/' + selectedObject.name, local);
}
private void open() {
openFile(list.getDirectory() + '/' + selectedObject.name);
}
private void transfer() {
String toBase;
NXListAdapter dest;
NXFtpBrowserPanel panel;
panel = (local) ? remotePanel : localPanel;
dest = (panel.listing) ? panel.table : panel.getListBoxes(-1);
if (!local) {
toBase = dest.getDirectory();
downloadFromIndex(list.getDirectory(), toBase, list.getSelectedValues(), dest);
} else {
toBase = remotePanel.getListBoxes(-1).getDirectory();
uploadFromIndex(toBase, list.getDirectory(), list.getSelectedValues(), dest);
}
}
private void reload() {
reloadList(list);
}
private void showQueue() {
if (!queuePanel.isVisible()) {
queuePanel.setVisible(true);
}
}
}
private void openFile(String file) {
try {
Desktop.getDesktop().open(new File(file));
} catch (IOException ex) {
}
}
private void deleteFromList(NXListAdapter list, boolean local) {
Object[] values = list.getSelectedValues();
if (!local) {
NXQueueItem i = new NXQueueItem("deletefromindex", "", list.getDirectory(), "", values);
i.setDisplay(list);
queue.add(i, false);
} else {
for (int x = 0; x < values.length; x++) {
(new LocalDeleteWorker(list.getDirectory() + '/' + ((NXObjectIndex) values[x]).name, list)).execute();
}
}
}
private void reloadList(NXListAdapter list) {
if (list.getLocal()) {
(new ListingWorker(list.getDirectory(), true, list)).execute();
} else {
String dir = list.getDirectory();
if (dir.equals("")) {
dir = "/";
}
queue.add(new NXQueueItem("list", "", dir, "", list), false);
}
}
private void doFilters() {
NXFilterDialog dlg = new NXFilterDialog(frame);
dlg.setFilters(remotePanel.getFilters());
dlg.setModal(true);
dlg.setVisible(true);
NXFilter[] filters = dlg.getFilters();
remotePanel.setFilters(filters);
localPanel.setFilters(filters);
}
private void previewImage(String path, boolean local) {
try {
if (!local) {
queue.add(new NXQueueItem("preview", "", path, ""), true);
} else {
(new PreviewWorker(path, new File(path))).execute();
}
} catch (Exception ex) {
System.out.println("OH SHIT");
}
}
private void downloadFromIndex(String base, String localBase, Object[] index, NXListAdapter list) {
NXObjectIndex oi;
String pwf;
String localFile;
File f = new File(localBase);
if (!f.exists()) {
f.mkdir();
}
int type;
for (int x = 0; x < index.length; x++) {
oi = (NXObjectIndex) index[x];
pwf = base + '/' + oi.name;
localFile = localBase + '/' + oi.name;
type = getType(base, oi);
if (type > 0) {
if (list != null) {
list.addElement(new NXObjectIndex('d', oi.name));
}
NXQueueItem item = new NXQueueItem("index", localFile, pwf, "");
if (oi.type == 1) { //link
item.fakePath = oi.realLoc;
}
queue.add(item, false);
} else {
queue.add(new NXQueueItem("download", localFile, pwf, "", list, oi.size), false);
}
}
}
private void createDirectoryIf(String base) {
String indexBase;
String[] pathElements = NXFormat.getNameFromPath(base);
if (pathElements[1] == null) {
return;
}
indexBase = base.equals("") ? "/" : pathElements[0];
NXObjectIndex check = (NXObjectIndex) ftpClient.getObjectIndex().get(indexBase);
if (check == null || !check.objects.containsKey(pathElements[1])) {
queue.add(new NXQueueItem("mkdir", "", base, ""), true);
}
}
private void uploadFromIndex(String base, String localBase, Object[] index, Object list) {
NXObjectIndex oi;
String pwf;
String localFile;
File file;
String folderFileName;
char type;
int inType;
createDirectoryIf(base);
for (int x = 0; x < index.length; x++) {
oi = (NXObjectIndex) index[x];
pwf = base + '/' + oi.name;
localFile = localBase + '/' + oi.name;
inType = getType(base, oi);
if (inType > 0) {
File folder = new File(localBase + '/' + oi.name);
File[] files = folder.listFiles();
NXObjectIndex[] folderIndex = new NXObjectIndex[files.length];
for (int y = 0; y < files.length; y++) {
folderFileName = NXFormat.getNameFromPath(files[y].getPath(), false);
File folderFile = new File(files[y].getPath());
type = (folderFile.isDirectory()) ? 'd' : '-';
folderIndex[y] = new NXObjectIndex(type, folderFileName);
}
uploadFromIndex(pwf, localFile, folderIndex, list);
} else {
file = new File(localFile);
queue.add(new NXQueueItem("upload", localFile, pwf, "", remotePanel.getListIfShown(pwf), file.length()), false);
}
}
}
private void localMoveFromIndex(String base, String destBase, Object[] index) {
NXObjectIndex oi;
String strDestFile;
String strSrcFile;
File file;
NXListAdapter srcList = localPanel.getListIfShown(base);
NXListAdapter destList = localPanel.getListIfShown(destBase);
for (int x = 0; x < index.length; x++) {
oi = (NXObjectIndex) index[x];
strDestFile = destBase + '/' + oi.name;
strSrcFile = base + '/' + oi.name;
file = new File(strSrcFile);
File destFile = new File(strDestFile);
if (file.renameTo(destFile)) {
if (destList != null) destList.addElement(oi);
}
}
reloadList(srcList);
if (destList != null) localPanel.removeList(destList.getIndex() + 1);
}
private void remoteMoveFromIndex(String base, String destBase, Object[] index) {
NXObjectIndex oi;
String strDestFile;
String strSrcFile;
NXListAdapter srcList = remotePanel.getListIfShown(base);
NXListAdapter destList = remotePanel.getListIfShown(destBase);
for (int x = 0; x < index.length; x++) {
oi = (NXObjectIndex) index[x];
strDestFile = destBase + '/' + oi.name;
strSrcFile = base + '/' + oi.name;
File destFile = new File(strDestFile);
queue.add(new NXQueueItem("rename", strSrcFile, strDestFile, ""), true);
}
reloadList(srcList);
if (destList != null) {
reloadList(destList);
remotePanel.removeList(destList.getIndex() + 1);
} else {
ftpClient.getObjectIndex().remove(destBase);
}
}
private int getType(String base, NXObjectIndex oi) {
int type;
if (oi.type == 1) { //link
if (oi.realType == -1) { //don't know type yet
type = (ftpClient.isDirectory(base + "/" + oi.name)) ? 2 : 0;
oi.setRealType(type);
} else { //already know type
type = oi.realType;
}
} else {
type = oi.type;
}
return type;
}
class DeleteIndexWorker extends SwingWorker {
private final String folder;
private final Object[] index;
private final NXListAdapter display;
protected DeleteIndexWorker(String folder, Object[] index, NXListAdapter display) {
this.folder = folder;
this.index = index;
this.display = display;
}
@Override
protected Object doInBackground() throws Exception {
deleteFromIndex(folder, index, true);
reloadList(display);
remotePanel.removeList(display.getIndex() + 1);
return new Object();
}
private void deleteFromIndex(String base, Object[] index, boolean start) {
NXObjectIndex oi;
String pwf;
setStatus("Deleting \"" + NXFormat.getNameFromPath(base, false) + "\".", true);
int type;
for (int x = 0; x < index.length; x++) {
oi = (NXObjectIndex) index[x];
pwf = base + '/' + oi.name;
type = getType(base, oi);
if (type > 0) {
ftpClient.indexDirectory(pwf);
NXObjectIndex folderIndex = (NXObjectIndex) ftpClient.getObjectIndex().get(pwf);
deleteFromIndex(pwf, folderIndex.objects.values().toArray(), false);
} else {
queue.add(new NXQueueItem("delete", "", pwf, ""), false);
}
}
if (!start) {
queue.add(new NXQueueItem("command", "Removing directory " + NXFormat.getNameFromPath(base, false), "RMD " + base, ""), false);
}
}
@Override
public void done() {
queue.process();
}
};
class IndexWorker extends SwingWorker {
private final String folder;
private final String localFolder;
private final boolean download;
private int listingSize;
protected IndexWorker(String localFolder, String folder, boolean download) {
this.folder = folder;
this.localFolder = localFolder;
this.download = download;
setStatus("Indexing \"" + NXFormat.getNameFromPath(folder, false) + "\".", true);
}
@Override
protected Object doInBackground() throws Exception {
listingSize = ftpClient.indexDirectory(folder);
return new Object();
}
@Override
public void done() {
NXObjectIndex folderIndex = (NXObjectIndex) ftpClient.getObjectIndex().get(folder);
Object[] arrObjects = folderIndex.objects.values().toArray();
queue.totalSize += listingSize;
queue.totalTransferred += listingSize;
queue.process();
if (download) {
downloadFromIndex(folder, localFolder, arrObjects, null);
}
}
};
public class NXQueue implements ActionListener {
public ArrayList queue = new ArrayList();
public ArrayList errorQueue = new ArrayList();
int done = 0;
int totalTransferred = 0;
long totalSize = 0;
int seconds = 0;
int currentSeconds = 0;
String currentString = "";
private final javax.swing.Timer timer = new javax.swing.Timer(1000, this);
private int currentTransferred;
public void add(NXQueueItem q, boolean priority) {
int size = queue.size();
int pos = (priority && size != 0) ? 1 : size;
queue.add(pos, q);
queuePanel.addItem(q, pos);
totalSize += q.totalSize;
if (size + 1 == 1) {
doItem(queue.get(0));
update();
timer.start();
}
}
public void addError(NXQueueItem q) {
errorQueue.add(q);
}
public Object get(int item) {
return queue.get(item);
}
public int getDone() {
return done;
}
public int getLength() {
return queue.size();
}
public void process() {
currentTransferred = 0;
currentSeconds = 0;
if (queue.size() > 0) {
queuePanel.removeItem((NXQueueItem) queue.get(0));
queue.remove(0);
}
if (queue.size() > 0) {
doItem(queue.get(0));
done++;
} else { //end of queue
done = 0;
seconds = 0;
totalTransferred = 0;
timer.stop();
totalSize = 0;
overallProgressBar.setVisible(false);
progressBar.setVisible(false);
if (errorQueue.size() > 0) {
NXTransferDialog m = new NXTransferDialog(frame, errorQueue);
m.setVisible(true);
errorQueue.clear();
}
}
}
public void updateTransferred(int add) {
currentTransferred += add;
totalTransferred += add;
}
private void doItem(Object i) {
NXQueueItem qi = (NXQueueItem) i;
boolean explicit = qi.activity.contains("-explicit");
queuePanel.updateActivity(qi);
if (qi.activity.equals("list")) {
ListingWorker lw = new ListingWorker(qi.remoteFile, false, qi.list);
if (qi.fakePath != null) { //used for directory links so that real path is updated
lw.fake = qi.fakePath;
}
lw.execute();
}
if (qi.activity.contains("mkdir")) {
(new CommandWorker("MKD " + qi.remoteFile, "Creating remote directory "
+ NXFormat.getNameFromPath(qi.remoteFile, false) + "...", explicit)).execute();
}
if (qi.activity.contains("command")) {
(new CommandWorker(qi.remoteFile, qi.localFile, explicit)).execute();
}
if (qi.activity.equals("upload")) {
(new UploadWorker(qi.localFile, qi.remoteFile, qi.list)).execute();
}
if (qi.activity.equals("download")) {
(new DownloadWorker(qi.localFile, qi.remoteFile, qi.list)).execute();
}
if (qi.activity.equals("preview")) {
(new DownloadWorker(qi.localFile, qi.remoteFile, true, false)).execute();
}
if (qi.activity.equals("open")) {
(new DownloadWorker(qi.localFile, qi.remoteFile, false, true)).execute();
}
if (qi.activity.equals("index")) {
(new IndexWorker(qi.localFile, qi.remoteFile, true)).execute();
}
if (qi.activity.equals("delete")) {
(new DeleteWorker(qi.remoteFile)).execute();
}
if (qi.activity.equals("deletefromindex")) {
(new DeleteIndexWorker(qi.remoteFile, (Object[]) qi.list, (NXListAdapter) qi.display)).execute();
}
if (qi.activity.equals("rename")) {
(new RenameWorker(qi.localFile, qi.remoteFile)).execute();
}
}
private void update() {
seconds++;
currentSeconds++;
queuePanel.updateProgress(currentTransferred, currentSeconds, totalTransferred, seconds, totalSize);
updateOverall();
updateSpeed();
}
private void updateSpeed() {
int bps = 0;
if (currentSeconds != 0) {
bps = (int) (currentTransferred / currentSeconds);
progressBar.setString(currentString + " at " + NXFormat.fileSize(bps, true) + "/s");
}
if (seconds != 0) {
bps = (int) (totalTransferred / seconds);
} else {
bps = 0;
}
int eta = NXFormat.getEta(totalSize, totalTransferred, bps);
if (seconds != 0) {
overallProgressBar.setString("All Actions" + eta(eta));
}
}
private String eta(int eta) {
String strEta = NXFormat.parseTime(eta);
if (!strEta.equals("")) {
strEta = " (" + strEta + " remaining)";
}
return strEta;
}
public void actionPerformed(ActionEvent e) { //timer to update queue data
update();
}
}
private class NXDropListener implements DropTargetListener {
private JToolTip label;
private NXDragFeedbackLabel glassPane;
private NXListAdapter source;
private boolean reject;
private String initial;
private String dir;
public NXDropListener(NXListAdapter source) {
this.source = source;
dir = (source.getDirectory().equals("")) ? "/" : NXFormat.getNameFromPath(source.getDirectory(), false);
label = new JToolTip();
label.setTipText(initial + dir);
label.setOpaque(true);
label.setSize(label.getPreferredSize());
if (frame != null) {
glassPane = (NXDragFeedbackLabel) frame.getGlassPane();
} else {
glassPane = dragFeedbackLabel;
}
}
public void dragEnter(DropTargetDragEvent dtde) {
if (source.equals(dragItem)) {
dtde.rejectDrag();
}
}
public void dragOver(DropTargetDragEvent dtde) {
if (reject) {
return;
}
Component c = label;
BufferedImage image = new BufferedImage(c.getWidth(),
c.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
c.paint(g);
int top = 0;
int listLeft = 0;
boolean leftSide = false;
top = (source.getLocal()) ? splitBrowser.getDividerLocation() : 0;
NXFtpBrowserPanel panel = (!source.getLocal()) ? remotePanel : localPanel;
if (source.getType() == false) {
//list
NXList l = (NXList) source;
NXScrollPane sp = (NXScrollPane) l.getParent().getParent();
listLeft = sp.getX();
listLeft += splitOverall.getDividerLocation() + splitOverall.getDividerSize();
top -= ((JViewport) l.getParent()).getViewPosition().y;
leftSide = dtde.getLocation().x < l.getWidth() / 2;
}
NXListAdapter a = (NXListAdapter) source;
a.setDropLeft(leftSide);
Object[] obj = a.getSelectedValues();
if (source.getLocal() != dragItem.getLocal()) {
initial = source.getLocal() ? "Download" : "Upload";
} else {
initial = "Move";
}
initial += " to ";
if (obj.length > 0 && leftSide) {
NXObjectIndex oi = (NXObjectIndex) obj[0];
label.setTipText((oi.type == 2 || oi.realType == 2) ? initial + oi.name : initial + dir);
} else {
label.setTipText(initial + dir);
}
label.setSize(label.getPreferredSize());
glassPane.setVisible(true);
Point p = (Point) dtde.getLocation().clone();
int left = 0;
JViewport scrollBrowser = (JViewport) panel.browserScroll.getViewport();
int start = scrollBrowser.getViewPosition().x;
int end = scrollBrowser.getViewSize().width;
System.out.println(end);
int diff = listLeft - start + p.x;
if (diff + label.getSize().width + 24 > end) {
left = end - label.getSize().width - 24;
} else {
left = diff;
}
p.x = left;
p.y += top;
glassPane.setPoint(p);
glassPane.setImage(image);
glassPane.repaint();
}
public void dropActionChanged(DropTargetDragEvent dtde) {
}
public void dragExit(DropTargetEvent dte) {
glassPane.setVisible(false);
}
public void drop(DropTargetDropEvent dtde) {
dtde.getLocation();
glassPane.setVisible(false);
}
}
}
class NXDragFeedbackLabel extends JLabel {
private AlphaComposite composite;
private BufferedImage dragged = null;
private Point location = new Point(0, 0);
public NXDragFeedbackLabel() {
super();
setOpaque(false);
composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f);
}
public void setImage(BufferedImage dragged) {
this.dragged = dragged;
}
public void setPoint(Point location) {
this.location = location;
}
public void paintComponent(Graphics g) {
if (dragged == null) {
return;
}
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(composite);
g2.drawImage(dragged,
(int) (location.getX() + 24),
(int) (location.getY() + 64),
null);
}
}