package org.limewire.ui.swing.advanced.connection;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.util.Arrays;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import org.limewire.collection.glazedlists.GlazedListsFactory;
import org.limewire.core.api.connection.ConnectionItem;
import org.limewire.core.api.connection.GnutellaConnectionManager;
import org.limewire.friend.api.FriendPresence;
import org.limewire.ui.swing.components.Disposable;
import org.limewire.ui.swing.components.FocusJOptionPane;
import org.limewire.ui.swing.search.FriendPresenceActions;
import org.limewire.ui.swing.table.TableDoubleClickHandler;
import org.limewire.ui.swing.table.TablePopupHandler;
import org.limewire.ui.swing.util.I18n;
import ca.odell.glazedlists.TransformedList;
import ca.odell.glazedlists.swing.DefaultEventTableModel;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.inject.Inject;
/**
* Display panel for the connection details table.
*/
public class ConnectionDetailPanel extends JPanel implements Disposable {
/** Manager instance for connection data. */
private GnutellaConnectionManager gnutellaConnectionManager;
/** Action to remove connection. */
private Action removeConnectionAction = new RemoveConnectionAction(I18n.tr("Remove"));
/** Action to view files on host. */
private Action viewLibraryAction = new ViewLibraryAction(I18n.tr("Browse Files"));
private JScrollPane scrollPane = new JScrollPane();
private ConnectionTable connectionTable = new ConnectionTable();
private JPopupMenu popupMenu = new JPopupMenu();
private final FriendPresenceActions remoteHostActions;
/**
* Constructs the ConnectionDetailPanel to display connections details.
*/
@Inject
public ConnectionDetailPanel(GnutellaConnectionManager gnutellaConnectionManager, FriendPresenceActions remoteHostActions) {
this.gnutellaConnectionManager = gnutellaConnectionManager;
this.remoteHostActions = remoteHostActions;
initComponents();
}
/**
* Initializes the components in the container.
*/
private void initComponents() {
setLayout(new BorderLayout());
setOpaque(false);
scrollPane.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
scrollPane.setPreferredSize(new Dimension(120, 120));
// Set table popup handler to display context menu.
connectionTable.setPopupHandler(new TablePopupHandler() {
@Override
public boolean isPopupShowing(int row) {
// Always return false to prevent color highlighting when popup
// menu is displayed. See MouseableTable.MenuHighlightPredicate.
return false;
}
@Override
public void maybeShowPopup(Component component, int x, int y) {
// Get target row.
int row = connectionTable.rowAtPoint(new Point(x, y));
// Change selection to include target row.
if ((row >= 0) && !connectionTable.isRowSelected(row)) {
connectionTable.setRowSelectionInterval(row, row);
}
// Enable View Library action only if host is connected.
ConnectionItem[] items = connectionTable.getSelectedConnections();
if (items.length > 0) {
viewLibraryAction.setEnabled(items[0].isConnected());
}
// Show popup menu.
popupMenu.show(component, x, y);
}
});
// Set table double-click handler to view library.
connectionTable.setDoubleClickHandler(new TableDoubleClickHandler() {
@Override
public void handleDoubleClick(int row) {
if (row >= 0) {
connectionTable.setRowSelectionInterval(row, row);
}
viewLibrary();
}
});
// Add View Library action.
JMenuItem menuItem = new JMenuItem(viewLibraryAction);
popupMenu.add(menuItem);
popupMenu.addSeparator();
// Add Remove action.
menuItem = new JMenuItem(removeConnectionAction);
popupMenu.add(menuItem);
add(scrollPane, BorderLayout.CENTER);
scrollPane.setViewportView(connectionTable);
}
/**
* Initializes the data models in the container.
*/
public void initData() {
if (!(connectionTable.getModel() instanceof DefaultEventTableModel)) {
// Create connection list for Swing. We wrap the actual list in a
// Swing list to ensure that all events are fired on the UI thread.
TransformedList<ConnectionItem, ConnectionItem> connectionList =
GlazedListsFactory.swingThreadProxyEventList(
gnutellaConnectionManager.getConnectionList());
// Create table format.
ConnectionTableFormat connectionTableFormat = new ConnectionTableFormat();
// Set up connection table model.
connectionTable.setEventList(connectionList, connectionTableFormat);
}
}
/**
* Clears the data models in the container.
*/
@Override
public void dispose() {
connectionTable.clearEventList();
}
/**
* Triggers a refresh of the data being displayed.
*/
public void refresh() {
connectionTable.refresh();
}
/**
* Displays the libraries for all selected connections.
*/
private void viewLibrary() {
// Browse hosts and display all selected connections.
ConnectionItem[] items = connectionTable.getSelectedConnections();
remoteHostActions.viewLibrariesOf(Collections2.transform(Collections2.filter(Arrays.asList(items), new Predicate<ConnectionItem>() {
@Override
public boolean apply(ConnectionItem input) {
return input.isConnected();
}
}), new Function<ConnectionItem, FriendPresence>() {
public FriendPresence apply(ConnectionItem from) {
return from.getFriendPresence();
}
}));
for (ConnectionItem item : items) {
if(!item.isConnected()) {
FocusJOptionPane.showMessageDialog(this,
I18n.tr("Unable to view files - not yet connected to host"),
I18n.tr("Connections"), JOptionPane.INFORMATION_MESSAGE);
}
}
}
/**
* Action to remove the selected connections.
*/
private class RemoveConnectionAction extends AbstractAction {
public RemoveConnectionAction(String name) {
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
// Remove all selected connections.
ConnectionItem[] items = connectionTable.getSelectedConnections();
for (ConnectionItem item : items) {
gnutellaConnectionManager.removeConnection(item);
}
connectionTable.clearSelection();
}
}
/**
* Action to display the library for the selected connections.
*/
private class ViewLibraryAction extends AbstractAction {
public ViewLibraryAction(String name) {
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
viewLibrary();
}
}
}