package thaw.plugins.transferLogs;
import javax.swing.event.TableModelEvent;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.ImageIcon;
import javax.swing.JPopupMenu;
import javax.swing.JMenuItem;
import java.util.Vector;
import java.util.Iterator;
import java.text.DateFormat;
import java.awt.Component;
import java.awt.Color;
import java.sql.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import thaw.gui.Table;
import thaw.gui.IconBox;
import thaw.core.I18n;
import thaw.core.Config;
import thaw.core.Logger;
import thaw.plugins.TransferLogs;
import thaw.plugins.Hsqldb;
/**
* Allow to see entry page per page.
* columns : "dates" (start,end), transfer "type", "filename","key already seen?" .
* A button "details" is added in each row of the column "filename".
* Button "details" add in the column "filename" the following informations:
* <ul>
* <li>Key</li>
* <li>Was finished ?</li>
* <li>If finished : Average speed</li>
* </ul>
* <br/>
* right click menu : copy key(s) to clipboard
*/
public class TransferTable implements MouseListener {
public final static int NMB_ELEMENTS_PER_PAGE = 100;
public final static int DEFAULT_LINE_HEIGHT = 18;
public final static int MAX_LINE_HEIGHT = 100;
public final static String[] COLUMN_NAMES = {
I18n.getMessage("thaw.plugin.transferLogs.dates"),
I18n.getMessage("thaw.plugin.transferLogs.type"),
I18n.getMessage("thaw.plugin.transferLogs.file"),
I18n.getMessage("thaw.plugin.transferLogs.isDup")
};
private JPanel panel;
private TransferTableModel model;
private PageSelecter pageSelecter;
private Table table;
private JPopupMenu rightClickMenu;
private Vector rightClickActions;
private TransferManagementHelper.TransferRemover remover;
private DateFormat dateFormat;
public TransferTable(Hsqldb db, Config config) {
this.dateFormat = DateFormat.getDateTimeInstance();
rightClickMenu = new JPopupMenu();
rightClickActions = new Vector();
JMenuItem item;
item = new JMenuItem(I18n.getMessage("thaw.common.remove"), IconBox.minDelete);
rightClickMenu.add(item);
rightClickActions.add(new TransferManagementHelper.TransferRemover(item, this));
item = new JMenuItem(I18n.getMessage("thaw.common.copyKeysToClipboard"), IconBox.minCopy);
rightClickMenu.add(item);
rightClickActions.add(new TransferManagementHelper.TransferKeyCopier(item));
panel = new JPanel(new BorderLayout(5, 5));
model = new TransferTableModel(db);
pageSelecter = new PageSelecter(db, model);
table = new Table(config, "table_transfer_logs", model);
table.setDefaultRenderer(table.getColumnClass(0), new TransferTableRenderer());
table.addMouseListener(this);
table.setShowGrid(true);
table.setIntercellSpacing(new java.awt.Dimension(1, 1));
panel.add(new JScrollPane(table), BorderLayout.CENTER);
panel.add(pageSelecter.getPanel(), BorderLayout.SOUTH);
remover = new TransferManagementHelper.TransferRemover(null, this);
table.addKeyListener(remover);
refresh();
}
public JPanel getPanel() {
return panel;
}
protected class TransferTableRenderer extends DefaultTableCellRenderer {
/**
*
*/
private static final long serialVersionUID = 4227879912938245537L;
private Color softGray;
private Color lightBlue;
private JTextArea textAreaRenderer;
private JLabel labelRenderer;
public TransferTableRenderer() {
softGray = new Color(240,240,240);
lightBlue = new Color(220, 220, 255);
labelRenderer = new JLabel("", JLabel.CENTER);
textAreaRenderer = new JTextArea();
textAreaRenderer.setEditable(false);
textAreaRenderer.setLineWrap(false);
}
public Component getTableCellRendererComponent(final JTable table, Object value,
final boolean isSelected, final boolean hasFocus,
final int row, final int column) {
Component cell;
if (value instanceof String && ((String)value).indexOf("\n") >= 0) {
textAreaRenderer.setText((String)value);
cell = textAreaRenderer;
} else if ((value instanceof String) && "X".equals((String)value) ) {
labelRenderer.setIcon(IconBox.minClose);
return labelRenderer;
} else if (value instanceof Integer) {
int val = ((Integer)value).intValue();
if (val == 0) {
value = TransferLogs.TRANSFER_TYPE_NAMES[val];
cell = super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
} else {
ImageIcon icon;
if (isSelected)
icon = (val == TransferLogs.TRANSFER_TYPE_DOWNLOAD) ?
IconBox.downloads : IconBox.insertions;
else
icon = (val == TransferLogs.TRANSFER_TYPE_DOWNLOAD) ?
IconBox.minDownloads : IconBox.minInsertions;
labelRenderer.setIcon(icon);
return labelRenderer;
}
} else {
cell = super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
}
if (!isSelected) {
if (row % 2 == 0)
cell.setBackground(Color.WHITE);
else
cell.setBackground(softGray);
} else {
cell.setBackground(lightBlue);
}
/*
if (isSelected) {
if (table.getRowHeight(row) < (cell.getPreferredSize().getHeight()+5))
table.setRowHeight((int)cell.getPreferredSize().getHeight()+5);
} else {
if (table.getRowHeight(row) > DEFAULT_LINE_HEIGHT)
table.setRowHeight(row, DEFAULT_LINE_HEIGHT);
}
*/
return cell;
}
}
protected class TransferTableModel
extends javax.swing.table.AbstractTableModel {
/**
*
*/
private static final long serialVersionUID = -4078889047070552383L;
private int page;
private Vector transfers = null;
private Hsqldb db;
public TransferTableModel(Hsqldb db) {
super();
this.db = db;
this.page = 0;
}
public int getRowCount() {
if (transfers != null)
return transfers.size();
else
return 0;
}
public int getColumnCount() {
return COLUMN_NAMES.length;
}
public String getColumnName(int col) {
return COLUMN_NAMES[col];
}
public String getAverageSpeed(Transfer t) {
long v = t.getAverageSpeed();
if (v < 0)
return I18n.getMessage("thaw.common.unknown");
return thaw.gui.GUIHelper.getPrintableSize(v) + "/s";
}
public Object getValueAt(final int row, int column) {
if (transfers == null)
return null;
if (row > transfers.size())
return null;
Transfer t = (Transfer)transfers.get(row);
if (column == 0) { /* dates */
String dates = I18n.getMessage("thaw.plugin.transferLogs.dateStart")+" ";
dates += dateFormat.format(t.getDateStart())+"\n";
dates += I18n.getMessage("thaw.plugin.transferLogs.dateEnd")+" ";
if (t.getDateEnd() != null)
dates += dateFormat.format(t.getDateEnd());
else
dates += I18n.getMessage("thaw.common.unknown");
return dates;
}
if (column == 1) { /* type */
return new Integer((int)t.getTransferTypeByte());
}
if (column == 2) { /* file */
String str = " "+t.getFilename()+"\n";
str += I18n.getMessage("thaw.plugin.transferLogs.key")+": ";
str += (t.getKey() != null ? t.getKey() : I18n.getMessage("thaw.common.unknown"))+"\n";
str += I18n.getMessage("thaw.plugin.transferLogs.fileSize")+": ";
str += thaw.gui.GUIHelper.getPrintableSize(t.getSize())+"\n";
str += I18n.getMessage("thaw.plugin.transferLogs.isSuccess")+": ";
if (t.getDateEnd() != null)
str += (t.isSuccess() ? I18n.getMessage("thaw.common.yes") : I18n.getMessage("thaw.common.no")) + "\n";
else
str += I18n.getMessage("thaw.common.unknown")+"\n";
str += I18n.getMessage("thaw.plugin.transferLogs.averageSpeed")+": ";
str += getAverageSpeed(t);
return str;
}
if (column == 3) { /* isDup ? */
return t.isDup() ? "X" : "";
}
return null;
}
public boolean isCellEditable(final int row, final int column) {
return false;
}
public void setPage(int page) {
this.page = page;
}
public int getPage() {
return page;
}
public void refresh(int row) {
fireTableChanged(new TableModelEvent(this, row));
}
public Vector getRows(int[] rows) {
if (transfers == null)
return null;
Vector v = new Vector();
for (int i = 0 ; i < rows.length ; i++) {
v.add(transfers.get(rows[i]));
}
return v;
}
public void refresh() {
try {
synchronized(db.dbLock) {
PreparedStatement st;
int offset = NMB_ELEMENTS_PER_PAGE * page;
st = db.getConnection().prepareStatement("SELECT id, dateStart, "+
"dateEnd, transferType, "+
"key, filename, size, "+
"isDup, isSuccess "+
"FROM transferLogs "+
"ORDER BY dateStart DESC "+
"LIMIT "+Integer.toString(NMB_ELEMENTS_PER_PAGE)+
" OFFSET "+Integer.toString(offset));
ResultSet res = st.executeQuery();
transfers = new Vector();
while(res.next()) {
transfers.add(new Transfer(db, res.getInt("id"),
res.getTimestamp("dateStart"),
res.getTimestamp("dateEnd"),
res.getByte("transferType"),
res.getString("key"),
res.getString("filename"),
res.getLong("size"),
res.getBoolean("isDup"),
res.getBoolean("isSuccess")));
}
st.close();
}
} catch(SQLException e) {
Logger.error(this, "Error while reading transfer logs: "+e.toString());
return;
}
fireTableChanged(new TableModelEvent(this));
}
}
protected class PageSelecter implements ActionListener {
private JPanel panel;
private JButton leftButton;
private JComboBox pageSelecter;
private JButton rightButton;
private Hsqldb db;
private TransferTableModel model;
private int pageMax;
public PageSelecter(Hsqldb db, TransferTableModel m) {
this.db = db;
this.model = m;
panel = new JPanel(new BorderLayout(5, 5));
leftButton = new JButton("<");
pageSelecter = new JComboBox(new String[] { "0" });
rightButton = new JButton(">");
leftButton.addActionListener(this);
pageSelecter.addActionListener(this);
rightButton.addActionListener(this);
JPanel centerPanel = new JPanel();
centerPanel.add(new JLabel(I18n.getMessage("thaw.common.page")));
centerPanel.add(pageSelecter);
panel.add(leftButton, BorderLayout.WEST);
panel.add(centerPanel, BorderLayout.CENTER);
panel.add(rightButton, BorderLayout.EAST);
}
public JPanel getPanel() {
return panel;
}
public void refresh() {
int nmb_elements = -1;
try {
synchronized(db.dbLock) {
PreparedStatement st;
st = db.getConnection().prepareStatement("SELECT count(id) FROM transferLogs");
ResultSet res = st.executeQuery();
res.next();
nmb_elements = res.getInt(1);
st.close();
}
} catch(SQLException e) {
Logger.error(this, "Unable to compute the number of pages in the logs because : "+e.toString());
return;
}
pageMax = nmb_elements / NMB_ELEMENTS_PER_PAGE;
if (nmb_elements % NMB_ELEMENTS_PER_PAGE == 0)
pageMax--;
if (model.getPage() > pageMax)
model.setPage(0);
pageSelecter.setSelectedItem("0");
pageSelecter.removeAllItems();
for (int i = 0 ; i <= pageMax ; i++)
pageSelecter.addItem(Integer.toString(i));
/* should call actionPerformed() */
pageSelecter.setSelectedItem(Integer.toString(model.getPage()));
refreshButtonState();
}
private void refreshButtonState() {
leftButton.setEnabled(model.getPage() > 0);
rightButton.setEnabled(model.getPage() < pageMax);
}
public void actionPerformed(ActionEvent e) {
int targetPage = -1;
if (e.getSource() == leftButton) {
targetPage = model.getPage() - 1;
} else if (e.getSource() == rightButton) {
targetPage = model.getPage() + 1;
} else if (e.getSource() == pageSelecter) {
if (pageSelecter.getSelectedItem() == null
|| !(pageSelecter.getSelectedItem() instanceof String))
return;
targetPage = Integer.parseInt((String)pageSelecter.getSelectedItem());
}
if (targetPage < 0 || targetPage > pageMax)
return;
model.setPage(targetPage);
model.refresh();
pageSelecter.removeActionListener(this);
pageSelecter.setSelectedItem(Integer.toString(targetPage));
pageSelecter.addActionListener(this);
refreshButtonState();
}
}
public void refresh() {
model.refresh();
pageSelecter.refresh();
}
private void updateToolbar(Vector selection) {
}
private void updateRightClickMenu(Vector selection) {
TransferManagementHelper.TransferAction action;
for(final Iterator it = rightClickActions.iterator();
it.hasNext();) {
action = (TransferManagementHelper.TransferAction)it.next();
action.setTarget(selection);
}
}
public void adjustRowHeights() {
for (int i = table.getRowCount()-1 ; i >= 0 ; i--) {
if (table.isRowSelected(i))
table.setRowHeight(i, MAX_LINE_HEIGHT);
else
table.setRowHeight(i, DEFAULT_LINE_HEIGHT);
}
}
public void mouseClicked(final MouseEvent e) {
Vector selection;
int[] selectedRows = table.getSelectedRows();
if (selectedRows == null)
return;
selection = model.getRows(selectedRows);
if (selection == null)
return;
if (e.getButton() == MouseEvent.BUTTON1) {
adjustRowHeights();
updateToolbar(selection);
remover.setTarget(selection);
}
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) {
adjustRowHeights();
}
}