//*****************************************************************************
//*
//* (c) Copyright 2004. Glub Tech, Incorporated. All Rights Reserved.
//*
//* $Id: LocalFileTable.java 128 2009-12-10 09:18:22Z gary $
//*
//*****************************************************************************
package com.glub.secureftp.client.gui;
import com.glub.gui.table.*;
import com.glub.util.*;
import com.glub.secureftp.bean.*;
import com.glub.secureftp.client.framework.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.io.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.table.*;
public class LocalFileTable extends JSortTable {
protected static final long serialVersionUID = 1L;
private LocalPanel localPanel = null;
public static final int FILE_COLUMN = 0;
private static final int NUMBER_OF_COLUMNS = 1;
private TableDropTargetListener dropTargetListener;
private LocalFilePopupMenu popupMenu = new LocalFilePopupMenu(this);
private MouseAdapter ma = null;
public LocalFileTable( SortTableModel model,
final LocalPanel localPanel ) {
super( model );
setBackground( Color.WHITE );
setAutoscrolls( true );
this.localPanel = localPanel;
TableColumnModel tcm = getColumnModel();
TableColumn fileColumn = tcm.getColumn( FILE_COLUMN );
TableCellRenderer fileRenderer = new FileCell();
fileColumn.setCellRenderer( fileRenderer );
LocalFileTransferHandler fth =
new LocalFileTransferHandler( localPanel, this );
setTransferHandler( fth );
addKeyListener( new KeyAdapter() {
public void keyPressed( KeyEvent e ) {
if ( KeyEvent.VK_BACK_SPACE == e.getKeyCode() ) {
Thread cdThread = new Thread() {
public void run() {
localPanel.changeDirectoryUp();
}
};
cdThread.start();
}
else if ( KeyEvent.VK_F5 == e.getKeyCode() ) {
Thread lsThread = new Thread() {
public void run() {
localPanel.list();
}
};
lsThread.start();
}
else {
String modifier =
KeyEvent.getKeyModifiersText(e.getModifiers()).toLowerCase();
if ( modifier != null && !modifier.equals("shift") &&
modifier.length() > 0 ) {
return;
}
int numOfRows = getRowCount();
int i = 0;
int val = 0;
int startingPoint = getSelectedRow() + 1;
//if ( startingPoint <= 0 ) { startingPoint = 1; }
if ( startingPoint < 0 ) { startingPoint = 0; }
boolean foundMatch = false;
for( i = startingPoint, val = startingPoint;
i < numOfRows + startingPoint; i++, val++ ) {
if ( val >= numOfRows ) {
//val = 1;
val = 0;
}
File file = (File)getValueAt( val, getFileColumnIndex() );
if ( null != file && file.getName().length() > 0 ) {
char firstChar = file.getName().toLowerCase().charAt(0);
StringBuffer buf = new StringBuffer();
buf.append(e.getKeyChar());
String typedLowerStr = buf.toString().toLowerCase();
if ( typedLowerStr.length() > 0 &&
firstChar == typedLowerStr.charAt(0) ) {
foundMatch = true;
break;
}
}
}
if ( foundMatch ) {
changeSelection( val, FILE_COLUMN, false, false );
Client.getToolBar().updateToolBar();
Client.getMenus().updateMenuBar();
}
}
}
} );
addMouseListener( ma = new MouseAdapter() {
private ArrayList rowSelections = new ArrayList( 4 );
public void mouseClicked( MouseEvent e ) {
if ( e.getClickCount() >= 2 &&
!e.isPopupTrigger() && e.getButton() == MouseEvent.BUTTON1 ) {
int currentlySelectedRow = getSelectedRow();
int[] selectedRows = (int[])rowSelections.get( 0 );
boolean reselect = false;
for ( int i = 0; i < selectedRows.length; i++ ) {
if ( currentlySelectedRow == selectedRows[i] ) {
reselect = true;
addSelectedRows( selectedRows );
break;
}
}
for ( int i = 0; reselect && i < selectedRows.length; i++ ) {
addRowSelectionInterval( selectedRows[i], selectedRows[i] );
}
Thread dblClick = new Thread() {
public void run() {
handleDoubleClick();
}
};
dblClick.start();
}
}
public void mouseReleased( MouseEvent e ) {
int macContextMask = MouseEvent.CTRL_DOWN_MASK;
int unixContextMask = MouseEvent.META_DOWN_MASK;
int sysContextMask = Util.isMacOS() ? macContextMask : unixContextMask;
int rap = rowAtPoint(e.getPoint());
int[] selectedRows = getSelectedRows();
if ( e.isPopupTrigger() ) {
boolean clearSelection = true;
for ( int i = 0; i < getSelectedRowCount(); i++ ) {
if ( selectedRows[i] == rap ) {
clearSelection = false;
}
}
if ( clearSelection ) {
clearSelection();
}
if ( rap >= 0 ) {
addRowSelectionInterval(rap, rap);
}
popupMenu.updateMenu();
popupMenu.show( e.getComponent(), e.getX(), e.getY() );
}
else if ( !Util.isWindows() &&
((e.getModifiersEx() & macContextMask) == sysContextMask ||
(e.getModifiersEx() & unixContextMask) == sysContextMask ||
4 == e.getModifiers()) ) {
boolean clearSelection = true;
for ( int i = 0; i < getSelectedRowCount(); i++ ) {
if ( selectedRows[i] == rap ) {
clearSelection = false;
}
}
if ( clearSelection ) {
clearSelection();
}
if ( rap >= 0 ) {
addRowSelectionInterval(rap, rap);
}
popupMenu.updateMenu();
popupMenu.show( e.getComponent(), e.getX(), e.getY() );
}
addSelectedRows( getSelectedRows() );
}
private void addSelectedRows( int[] selectedRows ) {
rowSelections.add( selectedRows );
if ( rowSelections.size() > 3 ) {
rowSelections.remove( 0 );
}
Client.getToolBar().updateToolBar();
Client.getMenus().updateMenuBar();
}
} );
/*
addMouseListener( new MouseAdapter() {
public void mousePressed( MouseEvent e ) {
JComponent comp = (JComponent)e.getSource();
TransferHandler th = comp.getTransferHandler();
th.exportAsDrag( comp, e, TransferHandler.COPY );
}
} );
*/
dropTargetListener = new TableDropTargetListener();
new DropTarget( this, dropTargetListener );
//DragSource ds = DragSource.getDefaultDragSource();
//ds.addDragSourceListener( this );
setEnterBehavior();
setTabBehavior();
setArrowKeysBehavior();
setDragEnabled( true );
}
public int getFileColumnIndex() {
return convertColumnIndexToView( FILE_COLUMN );
}
protected MouseAdapter getMouseAdapter() { return ma; }
public TableDropTargetListener getDropTargetListener() {
return dropTargetListener;
}
public void setEnterBehavior() {
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke("ENTER"), "stop-and-next-cell");
getActionMap().put("stop-and-next-cell", new AbstractAction() {
protected static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
Thread dblClick = new Thread() {
public void run() {
handleDoubleClick();
}
};
dblClick.start();
}
} );
}
public void setTabBehavior() {
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "tab-local-view");
getActionMap().put("tab-local-view", new AbstractAction() {
protected static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
Thread switchToRemote = new Thread() {
public void run() {
FTPSession session =
FTPSessionManager.getInstance().getCurrentSession();
if ( null != session ) {
((RemotePanel)session.getRemoteUI()).setFocus();
}
}
};
switchToRemote.start();
}
} );
}
public void setArrowKeysBehavior() {
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke("DOWN"), "next-cell");
getActionMap().put("next-cell", new AbstractAction() {
protected static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
int row = getSelectedRow();
if ( row + 1 < getRowCount() ) {
changeSelection( row + 1, 0, false, false );
Client.getToolBar().updateToolBar();
Client.getMenus().updateMenuBar();
}
}
} );
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke("UP"), "prev-cell");
getActionMap().put("prev-cell", new AbstractAction() {
protected static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
int row = getSelectedRow();
if ( row - 1 >= 0 ) {
changeSelection( row - 1, 0, false, false );
Client.getToolBar().updateToolBar();
}
}
} );
}
public void selectAll() {
clearSelection();
//addRowSelectionInterval( 1, getRowCount() - 1 );
addRowSelectionInterval( 0, getRowCount() - 1 );
Client.getToolBar().updateToolBar();
Client.getMenus().updateMenuBar();
}
public void handleDoubleClick() {
int row = getSelectedRow();
File file = null;
if ( row >= 0 ) {
Object currentVal = getValueAt( row, getFileColumnIndex() );
if ( currentVal instanceof File ) {
file = (File)currentVal;
}
else {
// must be dir up
localPanel.changeDirectoryUp();
}
}
//boolean selectedIsFile = true;
boolean isDirectory = false;
if ( null != file ) {
isDirectory = file.isDirectory();
// check to make sure it's really a "directory"
if ( isDirectory )
isDirectory = !Util.isPackage(file);
}
// if this is a directory, try changing into it
if ( isDirectory ) {
SecureFTPError error = localPanel.changeDirectory( file );
int resultCode = error.getCode();
/*
selectedIsFile = SecureFTPError.NOT_A_DIRECTORY == resultCode ||
SecureFTPError.UNKNOWN == resultCode;
*/
if ( SecureFTPError.PERMISSION_DENIED == resultCode ) {
LString lstr = LString.getLocalizedString( error.getMessage() );
ErrorDialog.showDialog( lstr );
}
}
ArrayList selectedFiles = getSelectedFiles();
FTPSession session = FTPSessionManager.getInstance().getCurrentSession();
if ( null != session && selectedFiles.size() > 0 ) {
RemotePanel remotePanel = (RemotePanel)session.getRemoteUI();
remotePanel.upload( selectedFiles, new RemoteFile(".") );
}
}
public ArrayList getSelectedFiles() {
int[] rows = getSelectedRows();
ArrayList selectedFiles = new ArrayList();
for( int i = 0; i < rows.length; i++ ) {
Object currentValue = getValueAt( rows[i], getFileColumnIndex() );
File currentFile = null;
if ( currentValue instanceof File ) {
currentFile = (File)getValueAt( rows[i], getFileColumnIndex() );
boolean selectedIsFile =
currentFile.isFile() || currentFile.isDirectory();
if ( selectedIsFile ) {
selectedFiles.add( currentFile );
}
}
}
return selectedFiles;
}
public static int getNumberOfColumns() { return NUMBER_OF_COLUMNS; }
public void sortColumn( int column, boolean ascending ) {
((SortTableModel)getModel()).sortColumn( column, ascending );
sortedColumnIndex = column;
sortedColumnAscending = ascending;
getTableHeader().resizeAndRepaint();
resizeAndRepaint();
}
public void mouseReleased( MouseEvent e ) {
super.mouseReleased( e );
Client.getLocalView().setSort( sortedColumnAscending );
}
public void cueUIDrop( boolean cue ) {
if ( cue ) {
localPanel.getScrollPane().setViewportBorder(
BorderFactory.createLineBorder(SystemColor.windowBorder, 3) );
}
else {
localPanel.getScrollPane().setViewportBorder(
BorderFactory.createLineBorder(Color.white, 0) );
//clearSelection();
}
localPanel.getScrollPane().updateUI();
}
/**
* TableDropTargetListener class
*/
class TableDropTargetListener extends BasicDropTargetListener {
private int[] rows;
private int[] cols;
private int[] selectedRows;
protected void saveComponentState(JComponent comp) {
if ( !(comp instanceof JTable) ) { return; }
JTable table = (JTable) comp;
rows = table.getSelectedRows();
cols = table.getSelectedColumns();
}
protected void restoreComponentState(JComponent comp) {
if ( !(comp instanceof JTable) ) { return; }
JTable table = (JTable) comp;
table.clearSelection();
for (int i = 0; i < rows.length; i++) {
table.addRowSelectionInterval(rows[i], rows[i]);
}
for (int i = 0; i < cols.length; i++) {
table.addColumnSelectionInterval(cols[i], cols[i]);
}
}
protected void updateInsertionLocation(JComponent comp, Point p) {
if ( !(comp instanceof JTable) ) { return; }
JTable table = (JTable) comp;
int row = table.rowAtPoint( p );
File file = null;
//if ( row > 0 ) {
if ( row >= 0 ) {
file = (File)getValueAt( row, getFileColumnIndex() );
}
//if ( null != file && file.isDirectory() && row > 0 ) {
if ( null != file && file.isDirectory() && row >= 0 ) {
setRowSelectionInterval( row, row );
}
else {
clearSelection();
}
}
public void drop( DropTargetDropEvent dtde ) {
Transferable tr = dtde.getTransferable();
JComponent component = getComponent( dtde );
TransferHandler th = component.getTransferHandler();
boolean canImport = th.canImport(component, dtde.getCurrentDataFlavors());
DataFlavor[] flavors = dtde.getCurrentDataFlavors();
DataFlavor urlFlavor =
new DataFlavor( "application/x-java-url; class=java.net.URL", "URL" );
DataFlavor arrayListFlavor =
new DataFlavor( DataFlavor.javaJVMLocalObjectMimeType +
"; class=java.util.ArrayList",
"ArrayList" );
if ( flavors.length < 0 ) {
return;
}
if ( (urlFlavor.equals(flavors[0]) ||
DataFlavor.javaFileListFlavor.equals(flavors[0])) && canImport ) {
dtde.acceptDrop( DnDConstants.ACTION_COPY );
int row = getSelectedRow();
File file = null;
if ( row >= 0 ) {
file = (File)getValueAt( row, getFileColumnIndex() );
}
if ( null != file && !file.isDirectory() ) {
file = null;
}
boolean clearSelection = true;
try {
java.util.List fileList =
(java.util.List)tr.getTransferData( DataFlavor.javaFileListFlavor );
if ( null != fileList && fileList.size() > 0 ) {
File curFile = (File)fileList.get(0);
Client.getLocalView().changeDirectory( curFile );
if ( curFile.isFile() ) {
Client.getLocalView().selectFile( curFile );
clearSelection = false;
}
}
}
catch ( IOException ioe ) {
}
catch ( UnsupportedFlavorException ufe ) {
}
cueUIDrop( false );
if ( clearSelection ) {
clearSelection();
}
}
else if (arrayListFlavor.equals(flavors[0]) &&
"RemoteFileList".equals(flavors[0].getHumanPresentableName()) &&
canImport) {
try {
ArrayList remoteFileList =
(ArrayList)tr.getTransferData( arrayListFlavor );
selectedRows = getSelectedRows();
boolean changedDir = false;
File currentDir =
Client.getLocalView().getCurrentDirectory();
if ( selectedRows.length > 0 ) {
File file = (File)getValueAt( selectedRows[0], getFileColumnIndex() );
Client.getLocalView().changeSessionDirectory( file );
changedDir = true;
}
RemoteFileList rfl = new RemoteFileList( remoteFileList );
RemotePanel remotePanel = (RemotePanel)
FTPSessionManager.getInstance().getCurrentSession().getRemoteUI();
if ( null != remotePanel ) {
remotePanel.download( rfl );
}
if ( changedDir ) {
Client.getLocalView().changeSessionDirectory( currentDir );
}
}
catch ( IOException ioe ) {
}
catch ( UnsupportedFlavorException ufe ) {
}
}
else {
dtde.rejectDrop();
}
cleanup();
cueUIDrop( false );
}
public void dragEnter( DropTargetDragEvent dtde ) {
selectedRows = getSelectedRows();
super.dragEnter( dtde );
JComponent component =
(JComponent)dtde.getDropTargetContext().getComponent();
TransferHandler th = component.getTransferHandler();
boolean canImport = th.canImport(component, dtde.getCurrentDataFlavors());
if ( canImport ) {
dtde.acceptDrag( DnDConstants.ACTION_COPY );
}
else {
dtde.rejectDrag();
}
}
public void dragExit( DropTargetEvent dte ) {
clearSelection();
for ( int i = 0; i < selectedRows.length; i++ ) {
addRowSelectionInterval( selectedRows[i], selectedRows[i] );
}
super.dragExit( dte );
cueUIDrop( false );
//changeSelection( 0, 0, false, false );
}
}
/**
* LocalFileTransferHandler class
*/
class LocalFileTransferHandler extends TransferHandler {
protected static final long serialVersionUID = 1L;
public Transferable transferable;
private LocalPanel localPanel;
private JTable table;
public LocalFileTransferHandler() {
super();
}
public LocalFileTransferHandler( LocalPanel localPanel, JTable table ) {
super();
this.localPanel = localPanel;
this.table = table;
}
public Transferable createTransferable( JComponent comp ) {
transferable = new LocalFileTransfer(localPanel, table);
return transferable;
}
public int getSourceActions( JComponent c ) {
return TransferHandler.COPY;
}
public void exportAsDrag( JComponent comp, InputEvent e, int action ) {
super.exportAsDrag(comp, e, action);
}
public boolean canImport( JComponent comp, DataFlavor[] transferFlavors ) {
String name = transferFlavors[0].getHumanPresentableName();
boolean canImport = name.equals("RemoteFileList") ||
name.equals("application/x-java-url") ||
name.equals("application/x-java-file-list");
if ( canImport ) {
cueUIDrop( true );
}
return canImport;
}
protected void exportDone( JComponent c, Transferable data, int action ) {
cueUIDrop( false );
}
/*
public boolean importData( JComponent c, Transferable tr ) {
boolean status = false;
if ( tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ) {
int row = getSelectedRow();
RemoteFile file =
//(File)localPanel.getCurrentListing().get( row + 1 );
(File)localPanel.getCurrentListing().get( row );
if ( !file.isDirectory() ||
file.getName().equals("..") ) {
file = (File)localPanel.getCurrentListing().get( 0 );
}
try {
java.util.List fileList =
(java.util.List)tr.getTransferData( DataFlavor.javaFileListFlavor );
}
catch ( IOException ioe ) {
}
catch ( UnsupportedFlavorException ufe ) {
}
cueUIDrop( false );
status = true;
}
return status;
}
*/
}
/*
public void dragDropEnd( DragSourceDropEvent dsde ) {}
public void dragEnter( DragSourceDragEvent dsde ) {}
public void dragExit( DragSourceEvent dse ) {}
public void dragOver( DragSourceDragEvent dsde ) {}
public void dropActionChanged( DragSourceDragEvent dsde ) {}
*/
class FileCell extends DefaultTableCellRenderer {
protected static final long serialVersionUID = 1L;
private FileSystemView fsv = FileSystemView.getFileSystemView();
private Icon dirIcon = UIManager.getIcon("FileView.directoryIcon");
private Icon fileIcon = UIManager.getIcon("FileView.fileIcon");
private JFileChooser chooser = new JFileChooser();
/*
private ImageIcon linkIcon =
new ImageIcon( getClass().getResource("images/linkIcon.png") );
*/
protected void setValue( Object value ) {
File file = (File)value;
Icon iconToDisplay = fileIcon;
if ( null != file ) {
if ( fsv.isDrive(file) ) {
try {
iconToDisplay = chooser.getIcon( file );
//iconToDisplay = fsv.getSystemIcon(file);
}
catch ( Exception e ) {
iconToDisplay = UIManager.getIcon("FileView.hardDriveIcon");
}
}
else if ( /* Util.isWindows() && */ file.exists() ) {
try {
iconToDisplay = chooser.getIcon( file );
//iconToDisplay = fsv.getSystemIcon(file);
}
catch ( Exception e ) {
iconToDisplay = UIManager.getIcon("FileView.fileIcon");
}
}
else if ( file.isDirectory() ) {
if ( Util.isPackage(file) ) {
iconToDisplay = fileIcon;
}
else {
iconToDisplay = dirIcon;
}
}
else {
iconToDisplay = fileIcon;
}
String name =
FileSystemView.getFileSystemView().getSystemDisplayName( file );
if ( null == name || name.length() <= 0 ) {
name = file.toString();
}
//setText( " " + name + " " );
setText( name + " " );
setIcon( iconToDisplay );
}
}
// get rid of selection highlight
public Component getTableCellRendererComponent( JTable table, Object value,
boolean isSelected,
boolean hasFocus, int row,
int col ) {
JComponent c =
(JComponent)super.getTableCellRendererComponent( table, value,
isSelected, hasFocus,
row, col );
if ( hasFocus || isSelected ) {
c.setBorder( DefaultTableCellRenderer.noFocusBorder );
}
return c;
}
}
public String getToolTipText( MouseEvent e ) {
int row = rowAtPoint( e.getPoint() );
/*
if ( row < 1 ) {
return LString.getString("FileListPanel.tooltip.upDir",
"Move up directory");
}
*/
StringBuffer buffer = new StringBuffer();
buffer.append( "<html><table cellpadding=2><tr><td>" );
File file = (File)getValueAt( row, getFileColumnIndex() );
String fileName = file.getAbsolutePath();
try {
fileName = file.getCanonicalPath();
}
catch ( Exception dummy ) {}
buffer.append( "<b>" + fileName + "</b><br>");
double size = file.length();
double kb = size / 1024;
double mb = kb / 1024;
double gb = mb / 1024;
DecimalFormat df = new DecimalFormat("#.##");
df.setGroupingUsed( true );
df.setMaximumFractionDigits( 2 );
String bytesStr = LString.getString("Common.xferMetric.bytes", "bytes");
String kbStr = LString.getString("Common.xferMetric.kb", "KB");
String mbStr = LString.getString("Common.xferMetric.mb", "MB");
String gbStr = LString.getString("Common.xferMetric.gb", "GB");
if ( kb >= 1 && mb < 1 ) {
buffer.append( df.format(kb) + " " + kbStr + " <br>" );
}
else if ( mb >= 1 && gb < 1 ) {
buffer.append( df.format(mb) + " " + mbStr + " <br>" );
}
else if ( gb >= 1 ) {
buffer.append( df.format(gb) + " " + gbStr + " <br>" );
}
else {
buffer.append( df.format(size) + " " + bytesStr + " <br>" );
}
DateFormat timeDateFormat =
new SimpleDateFormat(LString.getString("Common.timeDateFormat",
"M/d/yyyy h:mm a") );
buffer.append( timeDateFormat.format(new Date(file.lastModified())) );
buffer.append( "</td></tr></table></html>" );
return buffer.toString();
}
}
class LocalFileTableViewport extends JViewport implements DropTargetListener {
protected static final long serialVersionUID = 1L;
protected DropTarget dropTarget = new DropTarget( this, this );
private final LocalFileTable dropTable;
public LocalFileTableViewport( LocalFileTable dt ) {
super();
dropTable = dt;
addMouseListener( new MouseAdapter() {
public void mouseClicked( MouseEvent e ) {
dropTable.clearSelection();
Client.getLocalView().setFocus();
Client.getToolBar().updateToolBar();
Client.getMenus().updateMenuBar();
}
public void mouseReleased( MouseEvent e ) {
dropTable.getMouseAdapter().mouseReleased(e);
}
} );
}
public TransferHandler getTransferHandler() {
return dropTable.getTransferHandler();
}
public void dragEnter( DropTargetDragEvent dtde ) {
dropTable.getDropTargetListener().dragEnter( dtde );
dropTable.clearSelection();
}
public void dragExit( DropTargetEvent dte ) {
dropTable.getDropTargetListener().dragExit( dte );
}
public void dragOver( DropTargetDragEvent dtde ) {
dropTable.getDropTargetListener().dragOver( dtde );
}
public void dropActionChanged( DropTargetDragEvent dtde ) {
dropTable.getDropTargetListener().dropActionChanged( dtde );
}
public synchronized void drop( DropTargetDropEvent dtde ) {
dropTable.getDropTargetListener().drop( dtde );
}
}