0001: /*
0002: * This program is free software; you can redistribute it and/or
0003: * modify it under the terms of the GNU General Public License
0004: * as published by the Free Software Foundation; either version 2
0005: * of the License, or (at your option) any later version.
0006: *
0007: * This program is distributed in the hope that it will be useful,
0008: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0009: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0010: * GNU General Public License for more details.
0011:
0012: * You should have received a copy of the GNU General Public License
0013: * along with this program; if not, write to the Free Software
0014: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0015: */
0016: package net.sf.jftp.gui.base;
0017:
0018: import java.awt.BorderLayout;
0019: import java.awt.Cursor;
0020: import java.awt.FlowLayout;
0021: import java.awt.Insets;
0022: import java.awt.event.ActionEvent;
0023: import java.awt.event.ActionListener;
0024: import java.awt.event.KeyEvent;
0025: import java.awt.event.KeyListener;
0026: import java.awt.event.MouseAdapter;
0027: import java.awt.event.MouseEvent;
0028: import java.awt.event.MouseListener;
0029: import java.io.BufferedInputStream;
0030: import java.io.BufferedOutputStream;
0031: import java.io.File;
0032: import java.io.FileInputStream;
0033: import java.io.FileOutputStream;
0034: import java.io.IOException;
0035: import java.io.StreamTokenizer;
0036: import java.util.Date;
0037: import java.util.Enumeration;
0038: import java.util.Hashtable;
0039: import java.util.zip.ZipEntry;
0040: import java.util.zip.ZipFile;
0041:
0042: import javax.swing.DefaultListModel;
0043: import javax.swing.ImageIcon;
0044: import javax.swing.JComboBox;
0045: import javax.swing.JEditorPane;
0046: import javax.swing.JLabel;
0047: import javax.swing.JList;
0048: import javax.swing.JMenuItem;
0049: import javax.swing.JOptionPane;
0050: import javax.swing.JPanel;
0051: import javax.swing.JPopupMenu;
0052: import javax.swing.JScrollPane;
0053: import javax.swing.JToolBar;
0054: import javax.swing.SwingUtilities;
0055: import javax.swing.event.ListSelectionEvent;
0056: import javax.swing.event.ListSelectionListener;
0057:
0058: import net.sf.jftp.JFtp;
0059: import net.sf.jftp.config.SaveSet;
0060: import net.sf.jftp.config.Settings;
0061: import net.sf.jftp.gui.base.dir.DirCanvas;
0062: import net.sf.jftp.gui.base.dir.DirCellRenderer;
0063: import net.sf.jftp.gui.base.dir.DirComponent;
0064: import net.sf.jftp.gui.base.dir.DirEntry;
0065: import net.sf.jftp.gui.base.dir.DirLister;
0066: import net.sf.jftp.gui.base.dir.DirPanel;
0067: import net.sf.jftp.gui.base.dir.TableUtils;
0068: import net.sf.jftp.gui.framework.HImage;
0069: import net.sf.jftp.gui.framework.HImageButton;
0070: import net.sf.jftp.gui.framework.HPanel;
0071: import net.sf.jftp.gui.tasks.Creator;
0072: import net.sf.jftp.gui.tasks.ImageViewer;
0073: import net.sf.jftp.gui.tasks.NameChooser;
0074: import net.sf.jftp.gui.tasks.RemoteCommand;
0075: import net.sf.jftp.net.BasicConnection;
0076: import net.sf.jftp.net.ConnectionListener;
0077: import net.sf.jftp.net.FilesystemConnection;
0078: import net.sf.jftp.net.FtpConnection;
0079: import net.sf.jftp.net.SmbConnection;
0080: import net.sf.jftp.system.LocalIO;
0081: import net.sf.jftp.system.StringUtils;
0082: import net.sf.jftp.system.UpdateDaemon;
0083: import net.sf.jftp.system.logging.Log;
0084: import net.sf.jftp.util.ZipFileCreator;
0085:
0086: public class LocalDir extends DirComponent implements
0087: ListSelectionListener, ActionListener, ConnectionListener,
0088: KeyListener {
0089: static final String deleteString = "rm";
0090: static final String mkdirString = "mkdir";
0091: static final String refreshString = "fresh";
0092: static final String cdString = "cd";
0093: static final String cmdString = "cmd";
0094: static final String downloadString = "<-";
0095: static final String uploadString = "->";
0096: static final String zipString = "zip";
0097: static final String cpString = "cp";
0098: static final String rnString = "rn";
0099: static final String cdUpString = "cdUp";
0100: HImageButton deleteButton;
0101: HImageButton mkdirButton;
0102: HImageButton cmdButton;
0103: HImageButton refreshButton;
0104: HImageButton cdButton;
0105: HImageButton uploadButton;
0106: HImageButton zipButton;
0107: HImageButton cpButton;
0108: HImageButton rnButton;
0109: private DirCanvas label = new DirCanvas(this );
0110: private boolean pathChanged = true;
0111: private boolean firstGui = true;
0112: private int pos = 0;
0113: private JPanel p = new JPanel();
0114: private JToolBar buttonPanel = new JToolBar() {
0115: public Insets getInsets() {
0116: return new Insets(0, 0, 0, 0);
0117: }
0118: };
0119:
0120: private JToolBar currDirPanel = new JToolBar() {
0121: public Insets getInsets() {
0122: return new Insets(0, 0, 0, 0);
0123: }
0124: };
0125:
0126: private DefaultListModel jlm;
0127: private JScrollPane jsp = new JScrollPane(jl);
0128: private int tmpindex = -1;
0129: private Hashtable dummy = new Hashtable();
0130: private JPopupMenu popupMenu = new JPopupMenu();
0131: private JMenuItem runFile = new JMenuItem("Launch file");
0132: private JMenuItem viewFile = new JMenuItem("View file");
0133: private JMenuItem props = new JMenuItem("Properties");
0134: private DirEntry currentPopup = null;
0135: private String sortMode = null;
0136: String[] sortTypes = new String[] { "Normal", "Reverse", "Size",
0137: "Size/Re" };
0138: private JComboBox sorter = new JComboBox(sortTypes);
0139: HImageButton cdUpButton;
0140: private boolean dateEnabled = false;
0141:
0142: /**
0143: * LocalDir constructor.
0144: */
0145: public LocalDir() {
0146: type = "local";
0147: con = new FilesystemConnection();
0148: con.addConnectionListener(this );
0149: }
0150:
0151: /**
0152: * LocalDir constructor.
0153: */
0154: public LocalDir(String path) {
0155: type = "local";
0156: this .path = path;
0157: con = new FilesystemConnection();
0158: con.addConnectionListener(this );
0159: con.chdir(path);
0160:
0161: //gui(false);
0162: }
0163:
0164: /**
0165: * Creates the gui and adds the MouseListener etc.
0166: */
0167: public void gui_init() {
0168: setLayout(new BorderLayout());
0169: currDirPanel.setFloatable(false);
0170: buttonPanel.setFloatable(false);
0171:
0172: FlowLayout f = new FlowLayout(FlowLayout.RIGHT);
0173: f.setHgap(1);
0174: f.setVgap(2);
0175:
0176: buttonPanel.setLayout(f);
0177: buttonPanel.setMargin(new Insets(0, 0, 0, 0));
0178:
0179: runFile.addActionListener(this );
0180: viewFile.addActionListener(this );
0181: props.addActionListener(this );
0182: popupMenu.add(runFile);
0183: popupMenu.add(viewFile);
0184: popupMenu.add(props);
0185:
0186: deleteButton = new HImageButton(Settings.deleteImage,
0187: deleteString, "Delete selected", this );
0188: deleteButton.setToolTipText("Delete selected");
0189:
0190: mkdirButton = new HImageButton(Settings.mkdirImage,
0191: mkdirString, "Create a new directory", this );
0192: mkdirButton.setToolTipText("Create directory");
0193:
0194: refreshButton = new HImageButton(Settings.refreshImage,
0195: refreshString, "Refresh current directory", this );
0196: refreshButton.setToolTipText("Refresh directory");
0197: refreshButton.setRolloverIcon(new ImageIcon(HImage.getImage(
0198: this , Settings.refreshImage2)));
0199: refreshButton.setRolloverEnabled(true);
0200:
0201: cdButton = new HImageButton(Settings.cdImage, cdString,
0202: "Change directory", this );
0203: cdButton.setToolTipText("Change directory");
0204:
0205: uploadButton = new HImageButton(Settings.uploadImage,
0206: uploadString, "Upload selected", this );
0207: uploadButton.setToolTipText("Upload selected");
0208:
0209: zipButton = new HImageButton(Settings.zipFileImage, zipString,
0210: "Add selected to new zip file", this );
0211: zipButton.setToolTipText("Create zip");
0212:
0213: cpButton = new HImageButton(Settings.copyImage, cpString,
0214: "Copy selected files to another local dir", this );
0215: cpButton.setToolTipText("Local copy selected");
0216:
0217: rnButton = new HImageButton(Settings.textFileImage, rnString,
0218: "Rename selected file or directory", this );
0219: rnButton.setToolTipText("Rename selected");
0220:
0221: cdUpButton = new HImageButton(Settings.cdUpImage, cdUpString,
0222: "Go to Parent Directory", this );
0223: cdUpButton.setToolTipText("Go to Parent Directory");
0224:
0225: label.setText("Filesystem: " + StringUtils.cutPath(path));
0226: label.setSize(getSize().width - 10, 24);
0227: currDirPanel.add(label);
0228: currDirPanel.setSize(getSize().width - 10, 32);
0229: label.setSize(getSize().width - 20, 24);
0230:
0231: p.setLayout(new BorderLayout());
0232: p.add("North", currDirPanel);
0233:
0234: buttonPanel.add(sorter);
0235:
0236: buttonPanel.add(new JLabel(" "));
0237:
0238: buttonPanel.add(refreshButton);
0239: buttonPanel.add(new JLabel(" "));
0240:
0241: buttonPanel.add(cpButton);
0242: buttonPanel.add(rnButton);
0243: buttonPanel.add(mkdirButton);
0244:
0245: buttonPanel.add(cdButton);
0246: buttonPanel.add(deleteButton);
0247: buttonPanel.add(cdUpButton);
0248: buttonPanel.add(new JLabel(" "));
0249:
0250: buttonPanel.add(zipButton);
0251: buttonPanel.add(new JLabel(" "));
0252:
0253: buttonPanel.add(uploadButton);
0254:
0255: buttonPanel.setVisible(true);
0256:
0257: buttonPanel.setSize(getSize().width - 10, 32);
0258:
0259: //JPanel sortPanel = new JPanel();
0260: p.add("East", buttonPanel);
0261:
0262: //p.add("West", sortPanel);
0263: sorter.addActionListener(this );
0264:
0265: add("North", p);
0266:
0267: setDirList(true);
0268: jlm = new DefaultListModel();
0269: jl = new JList(jlm);
0270: jl.setCellRenderer(new DirCellRenderer());
0271: jl.setVisibleRowCount(Settings.visibleFileRows);
0272:
0273: // add this becaus we need to fetch only doubleclicks
0274: MouseListener mouseListener = new MouseAdapter() {
0275: public void mousePressed(MouseEvent e) {
0276: if (JFtp.uiBlocked) {
0277: return;
0278: }
0279:
0280: if (e.isPopupTrigger()
0281: || SwingUtilities.isRightMouseButton(e)) {
0282: int index = jl.getSelectedIndex() - 1;
0283:
0284: if (index < -1) {
0285: return;
0286: }
0287:
0288: String tgt = (String) jl.getSelectedValue()
0289: .toString();
0290:
0291: if (index < 0) {
0292: } else if ((dirEntry == null)
0293: || (dirEntry.length < index)
0294: || (dirEntry[index] == null)) {
0295: return;
0296: } else {
0297: currentPopup = dirEntry[index];
0298: popupMenu.show(e.getComponent(), e.getX(), e
0299: .getY());
0300: }
0301: }
0302: }
0303:
0304: public void mouseClicked(MouseEvent e) {
0305: if (JFtp.uiBlocked) {
0306: return;
0307: }
0308:
0309: if (Settings.getUseJTableLayout()) {
0310: TableUtils.copyTableSelectionsToJList(jl, table);
0311: }
0312:
0313: //System.out.println("DirEntryListener::");
0314: if (e.getClickCount() == 2) {
0315: //System.out.println("2xList selection: "+jl.getSelectedValue().toString());
0316: int index = jl.getSelectedIndex() - 1;
0317:
0318: // mousewheel bugfix, ui refresh bugfix
0319: if (index < -1) {
0320: return;
0321: }
0322:
0323: String tgt = (String) jl.getSelectedValue()
0324: .toString();
0325:
0326: //System.out.println("List selection: "+index);
0327: if (index < 0) {
0328: chdir(path + tgt);
0329: } else if ((dirEntry == null)
0330: || (dirEntry.length < index)
0331: || (dirEntry[index] == null)) {
0332: return;
0333: } else if (dirEntry[index].isDirectory()) {
0334: if (JFtp.mainFrame != null) {
0335: JFtp.mainFrame
0336: .setCursor(Cursor.WAIT_CURSOR);
0337: }
0338:
0339: chdir(path + tgt);
0340:
0341: if (JFtp.mainFrame != null) {
0342: JFtp.mainFrame
0343: .setCursor(Cursor.DEFAULT_CURSOR);
0344: }
0345: } else {
0346: showContentWindow(path
0347: + dirEntry[index].toString(),
0348: dirEntry[index]);
0349:
0350: //blockedTransfer(index);
0351: }
0352: }
0353: }
0354: };
0355:
0356: if (Settings.newTableGui) {
0357: jsp = new JScrollPane(table);
0358: table.getSelectionModel().addListSelectionListener(this );
0359: table.addMouseListener(mouseListener);
0360: } else {
0361: jsp = new JScrollPane(jl);
0362: jl.addListSelectionListener(this );
0363: jl.addKeyListener(this );
0364: jl.addMouseListener(mouseListener);
0365:
0366: jl.requestFocus();
0367: }
0368:
0369: jsp.setSize(getSize().width - 20, getSize().height - 72);
0370: add("Center", jsp);
0371: jsp.setVisible(true);
0372:
0373: TableUtils.tryToEnableRowSorting(table);
0374:
0375: if (Settings.IS_JAVA_1_6) {
0376: //sorter.setVisible(false);
0377: buttonPanel.remove(sorter);
0378: }
0379:
0380: setVisible(true);
0381: }
0382:
0383: public void setViewPort() {
0384: }
0385:
0386: /**
0387: * Part of a gui refresh.
0388: * There's no need to call this by hand.
0389: */
0390: public void gui(boolean fakeInit) {
0391: if (firstGui) {
0392: gui_init();
0393: firstGui = false;
0394: }
0395:
0396: if (con instanceof FilesystemConnection) {
0397: label.setText("Filesystem: " + StringUtils.cutPath(path));
0398: } else {
0399: label.setText("Remote: " + StringUtils.cutPath(path));
0400: }
0401:
0402: if (!fakeInit) {
0403: setDirList(false);
0404: }
0405:
0406: invalidate();
0407: validate();
0408: }
0409:
0410: /**
0411: * List directory and create/update the whole file list.
0412: * There's no need to call this by hand.
0413: */
0414: public void setDirList(boolean fakeInit) {
0415: jlm = new DefaultListModel();
0416:
0417: DirEntry dwn = new DirEntry("..", this );
0418: dwn.setDirectory();
0419: jlm.addElement(dwn);
0420:
0421: if (!fakeInit) {
0422: if (pathChanged) {
0423: pathChanged = false;
0424:
0425: DirLister dir = new DirLister(con, sortMode, Settings
0426: .getHideLocalDotNames());
0427:
0428: while (!dir.finished) {
0429: LocalIO.pause(10);
0430: }
0431:
0432: if (dir.isOk()) {
0433: length = dir.getLength();
0434: dirEntry = new DirEntry[length];
0435: files = dir.list();
0436:
0437: String[] fSize = dir.sList();
0438: int[] perms = dir.getPermissions();
0439:
0440: // --------- sorting aphabetically ------------
0441: // is now in DirLister
0442:
0443: /*
0444: if(Settings.sortDir)
0445: {
0446: String[] tmpx = new String[length];
0447:
0448: //if(fSize != null) System.out.println(":"+length+":"+fSize.length+":"+files.length);
0449: int pLength = length;
0450:
0451: if(perms != null)
0452: {
0453: pLength = perms.length;
0454: }
0455:
0456: //System.out.println(files.length + ":" + fSize.length+":"+ pLength + ":"+ length);
0457: if((fSize.length != files.length) ||
0458: (pLength != files.length) ||
0459: (length != files.length))
0460: {
0461: System.out.println("Sort mismatch - hopefully ignoring it...");
0462: }
0463:
0464: for(int x = 0; x < length; x++)
0465: {
0466: if(perms != null)
0467: {
0468: tmpx[x] = files[x] + "@@@" + fSize[x] + "@@@" +
0469: perms[x];
0470: }
0471: else
0472: {
0473: tmpx[x] = files[x] + "@@@" + fSize[x];
0474: }
0475: }
0476:
0477: LocalIO.sortStrings(tmpx);
0478:
0479: for(int y = 0; y < length; y++)
0480: {
0481: files[y] = tmpx[y].substring(0,
0482: tmpx[y].indexOf("@@@"));
0483:
0484: String tmp = tmpx[y].substring(tmpx[y].indexOf("@@@") +
0485: 3);
0486: fSize[y] = tmp.substring(0, tmp.lastIndexOf("@@@"));
0487:
0488: if(perms != null)
0489: {
0490: perms[y] = Integer.parseInt(tmpx[y].substring(tmpx[y].lastIndexOf("@@@") +
0491: 3));
0492: }
0493: }
0494: }
0495: */
0496:
0497: // ----------- end sorting --------------------
0498: for (int i = 0; i < length; i++) {
0499: if ((files == null) || (files[i] == null)) {
0500: //System.out.println("Critical error, files or files[i] is null!\nPlease report when and how this happened...");
0501: System.out
0502: .println("skipping setDirList, files or files[i] is null!");
0503:
0504: return;
0505:
0506: //System.exit(0);
0507: }
0508:
0509: dirEntry[i] = new DirEntry(files[i], this );
0510:
0511: if (dirEntry[i] == null) {
0512: System.out
0513: .println("\nskipping setDirList, dirEntry[i] is null!");
0514:
0515: return;
0516: }
0517:
0518: if (dirEntry[i].file == null) {
0519: System.out
0520: .println("\nskipping setDirList, dirEntry[i].file is null!");
0521:
0522: return;
0523: }
0524:
0525: if (perms != null) {
0526: dirEntry[i].setPermission(perms[i]);
0527: }
0528:
0529: if (fSize[i].startsWith("@")) {
0530: fSize[i] = fSize[i].substring(1);
0531: }
0532:
0533: dirEntry[i].setFileSize(Long
0534: .parseLong(fSize[i]));
0535:
0536: if (dirEntry[i].file.endsWith("/")) {
0537: dirEntry[i].setDirectory();
0538: } else {
0539: dirEntry[i].setFile();
0540: }
0541:
0542: //------ date parser -------
0543: Object[] d = dir.getDates();
0544:
0545: if (d != null) {
0546: dirEntry[i].setDate((Date) d[i]);
0547: }
0548:
0549: //--------------------------
0550: jlm.addElement(dirEntry[i]);
0551: }
0552: } else {
0553: Log.debug("Not a directory: " + path);
0554: }
0555: }
0556:
0557: //System.out.println("length: "+dirEntry.length);
0558: }
0559:
0560: jl.setModel(jlm);
0561:
0562: update();
0563: }
0564:
0565: // 20011213:rb - Added logic for MSDOS style root dir
0566:
0567: /**
0568: * Change the directory of this connection and update the gui
0569: */
0570: public boolean chdir(String p) {
0571: if ((JFtp.remoteDir == null) || (p == null)
0572: || p.trim().equals("")) {
0573: return false;
0574: }
0575:
0576: BasicConnection c = JFtp.remoteDir.getCon();
0577:
0578: if ((c != null) && (c instanceof FtpConnection)) {
0579: FtpConnection con = (FtpConnection) c;
0580:
0581: //con.setLocalPath(path);
0582: SaveSet s = new SaveSet(Settings.login_def, con.getHost(),
0583: con.getUsername(), con.getPassword(), Integer
0584: .toString(con.getPort()), con
0585: .getCachedPWD(), con.getLocalPath());
0586: }
0587:
0588: if (con.chdirNoRefresh(p)) {
0589: path = con.getPWD();
0590:
0591: if (con instanceof FilesystemConnection) {
0592: JFtp.remoteDir.getCon().setLocalPath(path);
0593:
0594: //con.fireDirectoryUpdate(con);
0595: //OR
0596: setDate();
0597: }
0598:
0599: pathChanged = true;
0600: gui(false);
0601:
0602: return true;
0603: }
0604:
0605: //Log.debug("CWD (local) : " + p);
0606: return false;
0607: }
0608:
0609: /**
0610: * Handles the user events if the ui is unlocked
0611: */
0612: public void actionPerformed(ActionEvent e) {
0613: if (JFtp.uiBlocked) {
0614: return;
0615: }
0616:
0617: if (e.getActionCommand().equals("rm")) {
0618: lock(false);
0619:
0620: if (Settings.getAskToDelete()) {
0621: if (!UITool.askToDelete(this )) {
0622: unlock(false);
0623:
0624: return;
0625: }
0626: }
0627:
0628: for (int i = 0; i < length; i++) {
0629: if (dirEntry[i].selected) {
0630: con.removeFileOrDir(dirEntry[i].file);
0631: }
0632: }
0633:
0634: unlock(false);
0635: fresh();
0636: } else if (e.getActionCommand().equals("mkdir")) {
0637: Creator c = new Creator("Create:", con);
0638:
0639: //fresh();
0640: } else if (e.getActionCommand().equals("cmd")) {
0641: RemoteCommand rc = new RemoteCommand();
0642:
0643: //fresh();
0644: } else if (e.getActionCommand().equals("cd")) {
0645: String tmp = UITool.getPathFromDialog(path);
0646: chdir(tmp);
0647: } else if (e.getActionCommand().equals("fresh")) {
0648: fresh();
0649: } else if (e.getActionCommand().equals("cp")) {
0650: Object[] o = jl.getSelectedValues();
0651:
0652: if (o == null) {
0653: return;
0654: }
0655:
0656: String tmp = UITool.getPathFromDialog(path);
0657:
0658: if (tmp == null) {
0659: return;
0660: }
0661:
0662: if (!tmp.endsWith("/")) {
0663: tmp = tmp + "/";
0664: }
0665:
0666: try {
0667: copy(o, path, "", tmp);
0668:
0669: //fresh();
0670: Log.debug("Copy finished...");
0671: } catch (Exception ex) {
0672: ex.printStackTrace();
0673: Log.debug("Copy failed!");
0674: }
0675: } else if (e.getActionCommand().equals("zip")) {
0676: try {
0677: Object[] entry = jl.getSelectedValues();
0678:
0679: if (entry == null) {
0680: return;
0681: }
0682:
0683: String[] tmp = new String[entry.length];
0684:
0685: for (int i = 0; i < tmp.length; i++) {
0686: tmp[i] = entry[i].toString();
0687: }
0688:
0689: NameChooser n = new NameChooser();
0690: String name = n.text.getText();
0691: ZipFileCreator z = new ZipFileCreator(tmp, path, name);
0692: fresh();
0693: } catch (Exception ex) {
0694: ex.printStackTrace();
0695: }
0696: } else if (e.getActionCommand().equals("->")) {
0697: blockedTransfer(-2);
0698: } else if (e.getActionCommand().equals("<-")) {
0699: blockedTransfer(-2);
0700: } else if (e.getActionCommand().equals("rn")) {
0701: Object[] target = jl.getSelectedValues();
0702:
0703: if ((target == null) || (target.length == 0)) {
0704: Log.debug("No file selected");
0705:
0706: return;
0707: } else if (target.length > 1) {
0708: Log.debug("Too many files selected");
0709:
0710: return;
0711: }
0712:
0713: //Renamer r = new Renamer(target[0].toString(), path);
0714: //fresh();
0715: String val = JOptionPane.showInternalInputDialog(
0716: JFtp.desktop, "Choose a name...");
0717:
0718: if (val != null) {
0719: if (!con.rename(target[0].toString(), val)) {
0720: Log.debug("Rename failed.");
0721: } else {
0722: Log.debug("Successfully renamed.");
0723: fresh();
0724: }
0725: }
0726: } else if (e.getSource() == props) {
0727: JFtp.statusP.jftp.clearLog();
0728:
0729: int x = currentPopup.getPermission();
0730: String tmp;
0731:
0732: if (x == FtpConnection.R) {
0733: tmp = "read only";
0734: } else if (x == FtpConnection.W) {
0735: tmp = "read/write";
0736: } else if (x == FtpConnection.DENIED) {
0737: tmp = "denied";
0738: } else {
0739: tmp = "undefined";
0740: }
0741:
0742: String msg = "File: " + currentPopup.toString() + "\n"
0743: + " Size: " + currentPopup.getFileSize()
0744: + " raw size: " + currentPopup.getRawSize() + "\n"
0745: + " Symlink: " + currentPopup.isLink() + "\n"
0746: + " Directory: " + currentPopup.isDirectory()
0747: + "\n" + " Permission: " + tmp + "\n";
0748: Log.debug(msg);
0749: } else if (e.getSource() == viewFile) {
0750: if (currentPopup.isDirectory()) {
0751: Log.debug("This is a directory, not a file.");
0752:
0753: return;
0754: }
0755:
0756: String url = JFtp.localDir.getPath()
0757: + currentPopup.toString();
0758: showContentWindow(url, currentPopup);
0759: } else if (e.getSource() == runFile) {
0760: if (currentPopup.isDirectory()) {
0761: Log.debug("This is a directory, not a file.");
0762:
0763: return;
0764: }
0765:
0766: String url = JFtp.localDir.getPath()
0767: + currentPopup.toString();
0768: showContentWindow("popup-run@" + url, currentPopup);
0769: } else if (e.getSource() == sorter) {
0770: sortMode = (String) sorter.getSelectedItem();
0771:
0772: if (sortMode.equals("Date")) {
0773: Settings.showLocalDateNoSize = true;
0774: } else {
0775: Settings.showLocalDateNoSize = false;
0776: }
0777:
0778: fresh();
0779: } else if (e.getActionCommand().equals("cdUp")) {
0780: chdir("..");
0781: }
0782: }
0783:
0784: private void copy(Object[] fRaw, String path, String offset,
0785: String target) throws Exception {
0786: String[] files = new String[fRaw.length];
0787:
0788: for (int j = 0; j < fRaw.length; j++) {
0789: files[j] = fRaw[j].toString();
0790: }
0791:
0792: for (int i = 0; i < files.length; i++) {
0793: File f = new File(path + offset + files[i]);
0794: BufferedInputStream in = null;
0795: BufferedOutputStream out = null;
0796: byte[] buf = new byte[4096];
0797:
0798: if (f.exists() && !f.isDirectory()) {
0799: in = new BufferedInputStream(new FileInputStream(path
0800: + offset + files[i]));
0801: out = new BufferedOutputStream(new FileOutputStream(
0802: target + offset + files[i]));
0803:
0804: int len = 0;
0805:
0806: while (in != null) {
0807: len = in.read(buf);
0808:
0809: if (len == StreamTokenizer.TT_EOF) {
0810: break;
0811: }
0812:
0813: out.write(buf, 0, len);
0814: }
0815:
0816: out.flush();
0817: out.close();
0818: } else if (f.exists()) {
0819: if (!files[i].endsWith("/")) {
0820: files[i] = files[i] + "/";
0821: }
0822:
0823: File f2 = new File(target + offset + files[i]);
0824:
0825: if (!f.exists()) {
0826: f.mkdir();
0827: }
0828:
0829: copy(f.list(), path, offset + files[i], target);
0830: }
0831: }
0832: }
0833:
0834: /**
0835: * Initiate a tranfer with ui locking enabled
0836: */
0837: public synchronized void blockedTransfer(int index) {
0838: tmpindex = index;
0839:
0840: Runnable r = new Runnable() {
0841: public void run() { // --------------- local -------------------
0842:
0843: boolean block = !Settings.getEnableMultiThreading();
0844:
0845: if (!(con instanceof FtpConnection)) {
0846: block = true;
0847: }
0848:
0849: if (block || Settings.getNoUploadMultiThreading()) {
0850: lock(false);
0851: }
0852:
0853: transfer(tmpindex);
0854:
0855: if (block || Settings.getNoUploadMultiThreading()) {
0856: unlock(false);
0857: }
0858:
0859: //{
0860: //JFtp.remoteDir.fresh();
0861: //unlock(false);
0862: //}
0863: }
0864: };
0865:
0866: Thread t = new Thread(r);
0867: t.start();
0868: }
0869:
0870: /**
0871: * Lock the gui.
0872: */
0873: public void lock(boolean first) {
0874: JFtp.uiBlocked = true;
0875: jl.setEnabled(false);
0876:
0877: if (!first) {
0878: JFtp.remoteDir.lock(true);
0879: }
0880: }
0881:
0882: /**
0883: * Unlock the gui.
0884: */
0885: public void unlock(boolean first) {
0886: JFtp.uiBlocked = false;
0887: jl.setEnabled(true);
0888:
0889: if (!first) {
0890: JFtp.remoteDir.unlock(true);
0891: }
0892: }
0893:
0894: /**
0895: * Do a hard UI refresh - do no longer call this directly, use
0896: * safeUpdate() instead.
0897: */
0898: public void fresh() {
0899: if (JFtp.mainFrame != null) {
0900: JFtp.mainFrame.setCursor(Cursor.WAIT_CURSOR);
0901: }
0902:
0903: String i = "";
0904: int idx = jl.getSelectedIndex();
0905:
0906: if (idx >= 0) {
0907: Object o = jl.getSelectedValue();
0908:
0909: if (o != null) {
0910: i = o.toString();
0911: }
0912: }
0913:
0914: chdir(path);
0915:
0916: if ((idx >= 0) && (idx < jl.getModel().getSize())) {
0917: if (jl.getModel().getElementAt(idx).toString().equals(i)) {
0918: jl.setSelectedIndex(idx);
0919: } else {
0920: jl.setSelectedIndex(0);
0921: }
0922: }
0923:
0924: update();
0925:
0926: if (JFtp.mainFrame != null) {
0927: JFtp.mainFrame.setCursor(Cursor.DEFAULT_CURSOR);
0928: }
0929: }
0930:
0931: /**
0932: * Transfers all selected files
0933: */
0934: public synchronized void transfer() {
0935: boolean[] bFileSelected = new boolean[dirEntry.length + 1];
0936: DirEntry[] cacheEntry = new DirEntry[dirEntry.length];
0937: System.arraycopy(dirEntry, 0, cacheEntry, 0, cacheEntry.length);
0938:
0939: for (int i = 0; i < dirEntry.length; i++) {
0940: bFileSelected[i] = cacheEntry[i].selected;
0941:
0942: if (!cacheEntry[i].equals(dirEntry[i])) {
0943: Log.out("mismatch");
0944: }
0945: }
0946:
0947: for (int i = 0; i < cacheEntry.length; i++) {
0948: if (bFileSelected[i]) {
0949: startTransfer(cacheEntry[i]);
0950: }
0951: }
0952: }
0953:
0954: /**
0955: * Start a file transfer.
0956: * Depending on the local and remote connection types some things like
0957: * local working directory have to be set, resuming may have to be checked etc.
0958: * As with ftp to ftp transfers the action used to download a file might actually be
0959: * an upload.
0960: *
0961: * WARNING: If you do anything here, please check RemoteDir.startTransfer(), too!
0962: */
0963: public void startTransfer(DirEntry entry) {
0964: if (con instanceof FilesystemConnection
0965: && JFtp.remoteDir.getCon() instanceof FtpConnection) {
0966: if ((entry.getRawSize() < Settings.smallSizeUp)
0967: && !entry.isDirectory()) {
0968: JFtp.remoteDir.getCon().upload(path + entry.file);
0969: } else {
0970: JFtp.remoteDir.getCon().handleUpload(path + entry.file);
0971: }
0972: } else if (con instanceof FtpConnection
0973: && JFtp.remoteDir.getCon() instanceof FtpConnection) {
0974: // local: ftp, remote: ftp
0975: if (entry.isDirectory()) {
0976: Log
0977: .debug("Directory transfer between remote connections is not supported yet!");
0978:
0979: return;
0980: }
0981:
0982: Log.out("direct ftp transfer started (upload)");
0983: ((FtpConnection) JFtp.remoteDir.getCon()).upload(
0984: entry.file,
0985: ((FtpConnection) JFtp.localDir.getCon())
0986: .getDownloadInputStream(path + entry.file));
0987: } else if (con instanceof FtpConnection
0988: && JFtp.remoteDir.getCon() instanceof FilesystemConnection) {
0989: con.setLocalPath(JFtp.remoteDir.getPath());
0990: con.handleDownload(path + entry.file);
0991: } else if (con instanceof FilesystemConnection
0992: && JFtp.remoteDir.getCon() instanceof FilesystemConnection) {
0993: con.upload(entry.file);
0994: JFtp.remoteDir.actionPerformed(con, "FRESH");
0995: } else if (con instanceof FilesystemConnection) {
0996: // local: file, remote: smb,sftp,nfs
0997: JFtp.remoteDir.getCon().handleUpload(entry.file);
0998: JFtp.remoteDir.actionPerformed(con, "FRESH");
0999: } else {
1000: if (entry.isDirectory()) {
1001: Log
1002: .debug("Directory transfer between remote connections is not supported yet!");
1003:
1004: return;
1005: }
1006:
1007: Log.out("direct transfer started (upload)");
1008: JFtp.remoteDir.getCon().upload(
1009: entry.file,
1010: JFtp.localDir.getCon().getDownloadInputStream(
1011: path + entry.file));
1012: JFtp.remoteDir.actionPerformed(con, "FRESH");
1013: }
1014: }
1015:
1016: /**
1017: * Transfers single file, or all selected files if index is -1
1018: */
1019: public void transfer(int i) {
1020: if (i == -2) {
1021: transfer();
1022:
1023: return;
1024: } else if (dirEntry[i].selected) {
1025: startTransfer(dirEntry[i]);
1026: }
1027: }
1028:
1029: /**
1030: * Safely refresh the UI.
1031: */
1032: public void safeUpdate() {
1033: UpdateDaemon.updateLocalDir();
1034: }
1035:
1036: /**
1037: * Called by FtpConnection
1038: */
1039: public void actionPerformed(Object target, String msg) {
1040: //System.out.print(msg);
1041: //fresh();
1042: safeUpdate();
1043: }
1044:
1045: /**
1046: * Called by FtpConnection, DownloadList is updated from here
1047: */
1048: public void updateProgress(String file, String type, long bytes) // only for url-downloads, for other see RemoteDir
1049: {
1050: if ((dList == null) || (dirEntry == null)) {
1051: return;
1052: }
1053:
1054: boolean flag = false;
1055:
1056: if (file.endsWith("/") && (file.length() > 1)) {
1057: flag = true;
1058: file = file.substring(0, file.lastIndexOf("/"));
1059: }
1060:
1061: file = file.substring(file.lastIndexOf("/") + 1);
1062:
1063: if (flag) {
1064: file = file + "/";
1065: }
1066:
1067: long s = 0;
1068:
1069: if (JFtp.dList.sizeCache.containsKey(file)) {
1070: s = ((Long) JFtp.dList.sizeCache.get(file)).longValue();
1071: } else {
1072: s = new File(getPath() + file).length();
1073: JFtp.dList.sizeCache.put(file, new Long(s));
1074: }
1075:
1076: dList.updateList(file, type, bytes, s);
1077: }
1078:
1079: /**
1080: * Called by FtpConnection
1081: */
1082: public void connectionInitialized(BasicConnection con) {
1083: }
1084:
1085: /**
1086: * Called by FtpConnection
1087: */
1088: public void actionFinished(BasicConnection con) {
1089: //fresh();
1090: safeUpdate();
1091: }
1092:
1093: /**
1094: * Called by FtpConnection
1095: */
1096: public void connectionFailed(BasicConnection con, String reason) {
1097: }
1098:
1099: private void setDate() {
1100: if (!(con instanceof FtpConnection)
1101: && !(con instanceof FilesystemConnection)) {
1102: try {
1103: sorter.removeItem("Date");
1104: } catch (Exception ex) {
1105: }
1106:
1107: dateEnabled = false;
1108:
1109: return;
1110: }
1111:
1112: //Log.debug(">>> date gui init (local)");
1113: if ((con instanceof FtpConnection)
1114: && (((FtpConnection) con).dateVector.size() > 0)) {
1115: if (!dateEnabled) {
1116: sorter.addItem("Date");
1117: dateEnabled = true;
1118: UpdateDaemon.updateRemoteDirGUI();
1119: }
1120: } else if ((con instanceof FilesystemConnection)
1121: && (((FilesystemConnection) con).dateVector.size() > 0)) {
1122: if (!dateEnabled) {
1123: sorter.addItem("Date");
1124: dateEnabled = true;
1125: UpdateDaemon.updateRemoteDirGUI();
1126: }
1127: } else {
1128: if (dateEnabled) {
1129: sorter.removeItem("Date");
1130: dateEnabled = false;
1131: Settings.showLocalDateNoSize = false;
1132: UpdateDaemon.updateRemoteDirGUI();
1133: }
1134: }
1135: }
1136:
1137: /**
1138: * Called by FtpConnection
1139: */
1140: public void updateRemoteDirectory(BasicConnection c) {
1141: if (con instanceof FtpConnection) {
1142: path = ((FtpConnection) con).getCachedPWD();
1143: } else if (con instanceof SmbConnection
1144: && !path.startsWith("smb://")) {
1145: path = con.getPWD();
1146: } else {
1147: path = con.getPWD();
1148: }
1149:
1150: //Log.out(">>> update local dir");
1151: //fresh();
1152: safeUpdate();
1153: }
1154:
1155: /**
1156: * Extract a zip file and change to the directory
1157: */
1158: private void setZipFilePath(DirEntry entry) {
1159: if (JFtp.mainFrame != null) {
1160: JFtp.mainFrame.setCursor(Cursor.WAIT_CURSOR);
1161: }
1162:
1163: String n = entry.toString();
1164: String tmp = path + n + "-dir/";
1165: Log.debug("\nExtracting: " + path + n);
1166:
1167: File tmpDir = new File(tmp);
1168:
1169: if (tmpDir.exists() || tmpDir.mkdir()) {
1170: try {
1171: ZipFile z = new ZipFile(path + n);
1172: Enumeration e = z.entries();
1173:
1174: while (e.hasMoreElements()) {
1175: ZipEntry z1 = (ZipEntry) e.nextElement();
1176: Log.debug("-> " + z1.getName());
1177:
1178: BufferedInputStream in = new BufferedInputStream(z
1179: .getInputStream(z1));
1180: BufferedOutputStream out = new BufferedOutputStream(
1181: new FileOutputStream(tmp + z1.getName()));
1182: byte[] buf = new byte[8192];
1183:
1184: while (in.read(buf, 0, 8192) != StreamTokenizer.TT_EOF) {
1185: out.write(buf);
1186: }
1187:
1188: out.flush();
1189: out.close();
1190: in.close();
1191: }
1192:
1193: chdir(tmp);
1194: } catch (IOException ex) {
1195: ex.printStackTrace();
1196: Log.debug("ERROR: " + ex);
1197: }
1198: } else {
1199: Log
1200: .debug("Cannot create directory, skipping extraction...");
1201: }
1202:
1203: //chdir(path + tgt);
1204: if (JFtp.mainFrame != null) {
1205: JFtp.mainFrame.setCursor(Cursor.DEFAULT_CURSOR);
1206: }
1207: }
1208:
1209: /**
1210: * Mime type handler for doubleclicks on files
1211: */
1212: public void showContentWindow(String url, DirEntry d) {
1213: //------- popup -> run
1214: if (Settings.runtimeCommands > 0
1215: && url.startsWith("popup-run@")) {
1216: String ext = url.substring(10);
1217:
1218: try {
1219: System.out.println("xx: " + ext);
1220: if (!Settings.askToRun
1221: || (Settings.askToRun && UITool.askToRun(this )))
1222: UIUtils.runCommand(ext);
1223: } catch (Exception ex) {
1224: Log.out("Could not launch file: " + ext);
1225: }
1226:
1227: return;
1228: }
1229:
1230: //------------
1231:
1232: if (d.toString().endsWith(".zip")) {
1233: setZipFilePath(d);
1234: } else {
1235: try {
1236: url = "file://" + url;
1237:
1238: // -------- images ----------
1239: String ext = url.toLowerCase();
1240:
1241: if (ext.endsWith(".jpg") || ext.endsWith(".gif")
1242: || ext.endsWith(".jpeg")
1243: || ext.endsWith(".png")) {
1244: ImageViewer d1 = new ImageViewer(url);
1245: JFtp.desktop.add(d1, new Integer(
1246: Integer.MAX_VALUE - 11));
1247:
1248: return;
1249: }
1250:
1251: if (Settings.runtimeCommands > 1) {
1252: try {
1253: if (!Settings.askToRun
1254: || (Settings.askToRun && UITool
1255: .askToRun(this ))) {
1256: UIUtils.runCommand(ext);
1257: return;
1258: }
1259: } catch (Exception ex) {
1260: Log.out("Could not launch file: " + ext);
1261: }
1262: }
1263:
1264: // -----------------
1265: if (d.getRawSize() > 200000) {
1266: Log
1267: .debug("File is too big - 200kb is the maximum, sorry.");
1268:
1269: return;
1270: }
1271:
1272: HPanel f = new HPanel();
1273:
1274: JEditorPane pane = new JEditorPane(url);
1275: pane.setEditable(false);
1276:
1277: if (!pane.getEditorKit().getContentType().equals(
1278: "text/html")
1279: && !pane.getEditorKit().getContentType()
1280: .equals("text/rtf")) {
1281: if (!pane.getEditorKit().getContentType().equals(
1282: "text/plain")) {
1283: Log
1284: .debug("Nothing to do with this filetype - use the buttons if you want to transfer files.");
1285:
1286: return;
1287: }
1288:
1289: pane.setEditable(false);
1290: }
1291:
1292: JScrollPane jsp = new JScrollPane(pane);
1293:
1294: f.setLayout(new BorderLayout());
1295: f.add("Center", jsp);
1296: JFtp.statusP.jftp.addToDesktop(url, f, 600, 400);
1297: } catch (Exception ex) {
1298: Log.debug("File error: " + ex);
1299: }
1300: }
1301: }
1302:
1303: public void keyPressed(KeyEvent e) {
1304: if (e.getKeyCode() == KeyEvent.VK_ENTER) {
1305: Object o = jl.getSelectedValue();
1306:
1307: if (o == null) {
1308: return;
1309: }
1310:
1311: String tmp = ((DirEntry) o).toString();
1312:
1313: if (tmp.endsWith("/") || tmp.equals("..")) {
1314: chdir(tmp);
1315: } else {
1316: showContentWindow(path + tmp, (DirEntry) o);
1317: }
1318: } else if (e.getKeyCode() == KeyEvent.VK_SPACE) {
1319: int x = ((DirPanel) JFtp.remoteDir).jl.getSelectedIndex();
1320:
1321: if (x == -1) {
1322: x = 0;
1323: }
1324:
1325: ((DirPanel) JFtp.remoteDir).jl.grabFocus();
1326: ((DirPanel) JFtp.remoteDir).jl.setSelectedIndex(x);
1327: }
1328: }
1329:
1330: public void keyReleased(KeyEvent e) {
1331: }
1332:
1333: public void keyTyped(KeyEvent e) {
1334: }
1335: }
|