package thaw.plugins.index;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import thaw.core.Config;
import thaw.core.ThawThread;
import thaw.core.ThawRunnable;
import thaw.fcp.FreenetURIHelper;
import thaw.core.I18n;
import thaw.gui.IconBox;
import thaw.core.Logger;
import thaw.fcp.FCPQueueManager;
import thaw.fcp.FCPTransferQuery;
import thaw.plugins.ToolbarModifier;
import thaw.gui.Table;
public class FileTable implements MouseListener, KeyListener, ActionListener {
private final JPanel panel;
private final Table table;
private FileListModel fileListModel;
private FileList fileList;
private final JPopupMenu rightClickMenu;
private final Vector rightClickActions;
private final JMenuItem gotoItem;
// Download
// Insert
// Compute keys
// Remove
// Copy file keys
private final ToolbarModifier toolbarModifier;
private final Vector toolbarActions;
private int[] selectedRows;
private IndexBrowserPanel indexBrowser;
private FCPQueueManager queueManager;
private TransferRefresher refresher;
private int columnToSort = -1;
private boolean sortAsc = false;
private thaw.plugins.index.File firstSelectedFile; /* used for the 'goto corresponding index' option */
public FileTable(final FCPQueueManager queueManager,
IndexBrowserPanel indexBrowser,
final Config config) {
this.indexBrowser = indexBrowser;
this.queueManager = queueManager;
fileListModel = new FileListModel();
table = new Table(config, "index_file_table", fileListModel);
//table = new JTable(fileListModel);
table.setShowGrid(false);
table.setIntercellSpacing(new java.awt.Dimension(0, 0));
table.specifyColumnWithKeys(2);
table.addMouseListener(this);
final JTableHeader header = table.getTableHeader();
header.setUpdateTableInRealTime(true);
header.setReorderingAllowed(true);
header.addMouseListener(new ColumnListener(table));
panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(new JLabel(I18n.getMessage("thaw.plugin.index.fileList")), BorderLayout.NORTH);
panel.add(new JScrollPane(table));
// Menu
rightClickMenu = new JPopupMenu();
rightClickActions = new Vector();
toolbarModifier = new ToolbarModifier(indexBrowser.getMainWindow());
toolbarActions = new Vector();
JButton button;
JMenuItem item;
item = new JMenuItem(I18n.getMessage("thaw.common.action.download"), IconBox.minDownloads);
button = new JButton(IconBox.downloads);
button.setToolTipText(I18n.getMessage("thaw.common.action.download"));
toolbarActions.add(new FileManagementHelper.FileDownloader(config, queueManager, indexBrowser, button));
toolbarModifier.addButtonToTheToolbar(button);
rightClickMenu.add(item);
rightClickActions.add(new FileManagementHelper.FileDownloader(config, queueManager, indexBrowser, item));
item = new JMenuItem(I18n.getMessage("thaw.plugin.index.insert"), IconBox.minInsertions);
button = new JButton(IconBox.insertions);
button.setToolTipText(I18n.getMessage("thaw.plugin.index.insert"));
toolbarActions.add(new FileManagementHelper.FileInserter(queueManager, indexBrowser, button));
toolbarModifier.addButtonToTheToolbar(button);
rightClickMenu.add(item);
rightClickActions.add(new FileManagementHelper.FileInserter(queueManager, indexBrowser, item));
item = new JMenuItem(I18n.getMessage("thaw.plugin.index.recalculateKeys"), IconBox.minKey);
button = new JButton(IconBox.key);
button.setToolTipText(I18n.getMessage("thaw.plugin.index.recalculateKeys"));
toolbarActions.add(new FileManagementHelper.FileKeyComputer(queueManager, indexBrowser, button));
toolbarModifier.addButtonToTheToolbar(button);
rightClickMenu.add(item);
rightClickActions.add(new FileManagementHelper.FileKeyComputer(queueManager, indexBrowser, item));
item = new JMenuItem(I18n.getMessage("thaw.common.removeFromTheList"), IconBox.minStop);
rightClickMenu.add(item);
rightClickActions.add(new FileManagementHelper.TransferCanceller(queueManager, indexBrowser, item));
item = new JMenuItem(I18n.getMessage("thaw.common.remove"), IconBox.minDelete);
button = new JButton(IconBox.delete);
button.setToolTipText(I18n.getMessage("thaw.common.remove"));
toolbarActions.add(new FileManagementHelper.FileRemover(indexBrowser, button));
toolbarModifier.addButtonToTheToolbar(button);
rightClickMenu.add(item);
rightClickActions.add(new FileManagementHelper.FileRemover(indexBrowser, item));
item = new JMenuItem(I18n.getMessage("thaw.common.copyKeysToClipboard"), IconBox.minCopy);
rightClickMenu.add(item);
rightClickActions.add(new FileManagementHelper.PublicKeyCopier(item));
gotoItem = new JMenuItem(I18n.getMessage("thaw.plugin.index.gotoIndex"));
rightClickMenu.add(gotoItem);
gotoItem.addActionListener(this);
updateRightClickMenu(null);
refresher = new TransferRefresher();
Thread th = new ThawThread(refresher, "File list refresher", this);
th.start();
}
public void stopRefresher() {
refresher.stop();
}
public ToolbarModifier getToolbarModifier() {
return toolbarModifier;
}
public JPanel getPanel() {
return panel;
}
protected void updateRightClickMenu(final Vector selectedFiles) {
FileManagementHelper.FileAction action;
firstSelectedFile = selectedFiles != null && selectedFiles.size() > 0 ?
((thaw.plugins.index.File)selectedFiles.get(0)) : null;
for(final Iterator it = rightClickActions.iterator();
it.hasNext();) {
action = (FileManagementHelper.FileAction)it.next();
action.setTarget(selectedFiles);
}
gotoItem.setEnabled((fileList != null) && !(fileList instanceof Index));
}
protected void updateToolbar(final Vector selectedFiles) {
FileManagementHelper.FileAction action;
for(final Iterator it = toolbarActions.iterator();
it.hasNext();) {
action = (FileManagementHelper.FileAction)it.next();
action.setTarget(selectedFiles);
}
}
protected Vector getSelectedFiles(final int[] selectedRows) {
//final Vector srcList = fileList.getFileList(fileListModel.getColumnNameInDb(columnToSort), sortAsc);
final File[] srcList = fileListModel.getFiles();
final Vector files = new Vector();
for(int i = 0 ; i < selectedRows.length ; i++) {
files.add(srcList[selectedRows[i]]);
}
return files;
}
public void setFileList(final FileList fileList) {
this.fileList = fileList;
fileListModel.reloadFileList(fileList);
}
public FileList getFileList() {
return fileList;
}
public void mouseClicked(final MouseEvent e) {
Vector selection;
if (fileList == null) {
selectedRows = null;
return;
}
selectedRows = table.getSelectedRows();
selection = getSelectedFiles(selectedRows);
if (e.getButton() == MouseEvent.BUTTON1) {
updateToolbar(selection);
toolbarModifier.displayButtonsInTheToolbar();
}
if (e.getButton() == MouseEvent.BUTTON3) {
updateRightClickMenu(selection);
rightClickMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
public void mouseEntered(final MouseEvent e) { }
public void mouseExited(final MouseEvent e) { }
public void mousePressed(final MouseEvent e) { }
public void mouseReleased(final MouseEvent e) { }
public void keyPressed(final KeyEvent e) { }
public void keyReleased(final KeyEvent e) { }
public void keyTyped(final KeyEvent e) { }
public void actionPerformed(final ActionEvent e) {
if(fileList == null)
return;
if (e.getSource() == gotoItem) {
if (selectedRows.length <= 0)
return;
if (firstSelectedFile != null)
indexBrowser.selectIndex(firstSelectedFile.getParentId());
return;
}
}
public void setSelectedRows(final int min, final int max) {
table.setRowSelectionInterval(min, max);
}
public void refresh() {
fileListModel.refresh();
}
public class FileListModel extends javax.swing.table.AbstractTableModel {
private static final long serialVersionUID = 1L;
public String[] columnNames =
{
I18n.getMessage("thaw.common.file"),
I18n.getMessage("thaw.common.size"),
I18n.getMessage("thaw.common.key"),
I18n.getMessage("thaw.common.status")
};
public String[] columnNamesInDb =
{
"LOWER(filename)",
"size",
"LOWER(publicKey)",
null
};
public File[] files = null;
public FileList fileList;
public FileListModel() {
super();
}
public void reloadFileList(final FileList newFileList) {
fileList = newFileList;
refresh();
}
public File[] getFiles() {
return files;
}
public int getRowCount() {
if (files == null)
return 0;
return files.length;
}
public int getColumnCount() {
return columnNames.length;
}
public String getColumnName(final int column) {
String result = columnNames[column];
if(column == columnToSort) {
if(sortAsc)
result = result + " >>";
else
result = result + " <<";
}
return result;
}
public String getColumnNameInDb(final int column) {
if (column < 0)
return null;
return columnNamesInDb[column];
}
public Object getValueAt(final int row, final int column) {
if (files == null)
return null;
if (row >= files.length)
return null;
final thaw.plugins.index.File file = (thaw.plugins.index.File)files[row];
if(column == 0)
return file.getFilename();
if(column == 1) {
if (file.getSize() > 0)
return new Long(file.getSize());
else
return I18n.getMessage("thaw.common.unknown");
}
//if (column == 2)
// return file.getCategory();
if (column == 2) {
String key = file.getPublicKey();
if (key == null || !FreenetURIHelper.isAKey(key))
key = I18n.getMessage("thaw.common.unknown");
return key;
}
if (column == 3) {
return file.getTransfer(queueManager);
}
return null;
}
public void refresh() {
if(fileList != null) {
files = fileList.getFileList(getColumnNameInDb(columnToSort), sortAsc);
} else {
files = null;
}
final TableModelEvent event = new TableModelEvent(this);
this.refresh(event);
}
public void refresh(final int row) {
final TableModelEvent event = new TableModelEvent(this, row);
this.refresh(event);
}
public void refresh(final TableModelEvent e) {
fireTableChanged(e);
}
}
private class TransferRefresher implements ThawRunnable {
private boolean running;
public TransferRefresher() {
running = true;
}
public void run() {
while(running) {
try {
Thread.sleep(500);
} catch(InterruptedException e) {
/* \_o< */
}
if (!running)
return;
if (fileListModel.getFiles() == null)
continue;
File[] files = fileListModel.getFiles();
for (int i = 0 ; i < files.length ; i++) {
thaw.plugins.index.File file = (thaw.plugins.index.File)files[i];
if (file.getPublicKey() == null
|| !FreenetURIHelper.isAKey(file.getPublicKey())) {
FCPTransferQuery transfer;
transfer = file.getTransfer(queueManager);
if (transfer != null) {
if (transfer.isSuccessful())
file.forceReload();
}
}
/* won't query the database */
fileListModel.refresh(i);
try {
Thread.sleep(100);
} catch(InterruptedException e) {
/* \_o< */
}
}
}
}
public void stop() {
running = false;
}
}
protected class ColumnListener extends MouseAdapter {
private JTable table;
public ColumnListener(final JTable t) {
table = t;
}
public void mouseClicked(final MouseEvent e) {
final TableColumnModel colModel = table.getColumnModel();
final int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
final int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex();
final int columnsCount = table.getColumnCount();
if (modelIndex < 0)
return;
if (modelIndex == 3) {
Logger.notice(this, "Can't order by transfer state because of performances issues");
return;
}
if (columnToSort == modelIndex)
sortAsc = !sortAsc;
else {
columnToSort = modelIndex;
sortAsc = true;
}
for (int i = 0; i < columnsCount; i++) {
final TableColumn column = colModel.getColumn(i);
column.setHeaderValue(fileListModel.getColumnName(column.getModelIndex()));
}
refresh();
}
}
}