package org.limewire.ui.swing.upload; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.AbstractAction; import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.JCheckBoxMenuItem; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import net.miginfocom.swing.MigLayout; import org.jdesktop.application.Application; import org.jdesktop.application.Resource; import org.limewire.bittorrent.Torrent; import org.limewire.bittorrent.TorrentManager; import org.limewire.core.settings.SharingSettings; import org.limewire.core.settings.UploadSettings; import org.limewire.ui.swing.components.FocusJOptionPane; import org.limewire.ui.swing.downloads.ShowUploadsInTrayAction; import org.limewire.ui.swing.options.OptionsDialog; import org.limewire.ui.swing.transfer.TransferTrayNavigator; import org.limewire.ui.swing.upload.UploadMediator.SortOrder; import org.limewire.ui.swing.util.GuiUtils; import org.limewire.ui.swing.util.I18n; import com.google.inject.Provider; /** * Options menu for performing actions on the upload table. */ class UploadHeaderPopupMenu extends JPopupMenu { @Resource(key="DownloadHeaderPopupMenu.upArrow") private Icon upArrow; @Resource(key="DownloadHeaderPopupMenu.downArrow") private Icon downArrow; private final UploadMediator uploadMediator; private final Provider<TorrentManager> torrentManager; private final Provider<TransferTrayNavigator> transferTrayNavigator; /** * Constructs an UploadHeaderPopupMenu. */ public UploadHeaderPopupMenu(UploadMediator uploadMediator, Provider<TorrentManager> torrentManager, Provider<TransferTrayNavigator> transferTrayNavigator) { this.uploadMediator = uploadMediator; this.torrentManager = torrentManager; this.transferTrayNavigator = transferTrayNavigator; GuiUtils.assignResources(this); addPopupMenuListener(new PopupMenuListener() { @Override public void popupMenuCanceled(PopupMenuEvent e) { removeAll(); } @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { removeAll(); } @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { populate(); } }); } /** * Adds menu items to the popup menu. */ private void populate() { removeAll(); add(new AbstractAction(I18n.tr("Pause All")) { @Override public void actionPerformed(ActionEvent e) { uploadMediator.pauseAll(); } }).setEnabled(uploadMediator.hasPausable()); add(new AbstractAction(I18n.tr("Resume All")) { @Override public void actionPerformed(ActionEvent e) { uploadMediator.resumeAll(); } }).setEnabled(uploadMediator.hasResumable()); add(createCancelSubMenu()); addSeparator(); add(createSortSubMenu()); addSeparator(); add(createClearFinishedMenuItem()); addSeparator(); JCheckBoxMenuItem includeUploads = new JCheckBoxMenuItem(new ShowUploadsInTrayAction(transferTrayNavigator)); includeUploads.setSelected(UploadSettings.SHOW_UPLOADS_IN_TRAY.getValue()); add(includeUploads); addSeparator(); add(new TransferOptionsAction()); } /** * Creates the Cancel sub-menu. */ private JMenu createCancelSubMenu() { JMenu cancelSubMenu = new JMenu(I18n.tr("Cancel")); cancelSubMenu.add(new AbstractAction(I18n.tr("All Error")) { @Override public void actionPerformed(ActionEvent e) { if (confirmCancel(I18n.tr("Cancel all error uploads?"))) { uploadMediator.cancelAllError(); } } }).setEnabled(uploadMediator.hasErrors()); cancelSubMenu.add(new AbstractAction(I18n.tr("All Torrents")) { @Override public void actionPerformed(ActionEvent e) { JPanel message = new JPanel(new MigLayout("nogrid, fill, gapy 15")); message.setOpaque(false); message.add(new JLabel(I18n.tr("Cancel uploading all torrents?")), "wrap"); if(getNumDownloadingTorrents() > 0) { message.add(new JLabel(I18n.tr("Note: Downloading torrents will be cancelled as well.", ""))); } if (confirmCancel(message)) { uploadMediator.cancelAllTorrents(); } } }).setEnabled(uploadMediator.hasTorrents()); cancelSubMenu.add(new AbstractAction(I18n.tr("All Uploads")) { @Override public void actionPerformed(ActionEvent e) { JPanel message = new JPanel(new MigLayout("nogrid, fill, gapy 15")); message.setOpaque(false); message.add(new JLabel(I18n.tr("Cancel all uploads?")), "wrap"); if(getNumDownloadingTorrents() > 0) { message.add(new JLabel(I18n.tr("Note: Downloading torrents will be cancelled as well.", ""))); } if (confirmCancel(message)) { uploadMediator.cancelAll(); } } }).setEnabled(uploadMediator.getUploadList().size() > 0); return cancelSubMenu; } private int getNumDownloadingTorrents() { if(!torrentManager.get().isInitialized() || ! torrentManager.get().isValid()) { return 0; } int numDownloading = 0; for(Torrent torrent : torrentManager.get().getTorrents()) { if(!torrent.isFinished()) { numDownloading++; } } return numDownloading; } /** * Creates the Sort sub-menu. */ private JMenu createSortSubMenu() { JMenu sortSubMenu = new JMenu(I18n.tr("Sort by")); // Create sort key menu items. JCheckBoxMenuItem orderStarted = new JCheckBoxMenuItem( new SortAction(I18n.tr("Order Started"), SortOrder.ORDER_STARTED)); JCheckBoxMenuItem name = new JCheckBoxMenuItem( new SortAction(I18n.tr("Name"), SortOrder.NAME)); JCheckBoxMenuItem progress = new JCheckBoxMenuItem( new SortAction(I18n.tr("Progress"), SortOrder.PROGRESS)); JCheckBoxMenuItem timeRemaining = new JCheckBoxMenuItem( new SortAction(I18n.tr("Time Left"), SortOrder.TIME_REMAINING)); JCheckBoxMenuItem speed = new JCheckBoxMenuItem( new SortAction(I18n.tr("Speed"), SortOrder.SPEED)); JCheckBoxMenuItem status = new JCheckBoxMenuItem( new SortAction(I18n.tr("Status"), SortOrder.STATUS)); JCheckBoxMenuItem fileType = new JCheckBoxMenuItem( new SortAction(I18n.tr("File Type"), SortOrder.FILE_TYPE)); JCheckBoxMenuItem extension = new JCheckBoxMenuItem( new SortAction(I18n.tr("File Extension"), SortOrder.FILE_EXTENSION)); JCheckBoxMenuItem userName = new JCheckBoxMenuItem( new SortAction(I18n.tr("User Name"), SortOrder.USER_NAME)); // Create button group. ButtonGroup sortButtonGroup = new ButtonGroup(); sortButtonGroup.add(orderStarted); sortButtonGroup.add(name); sortButtonGroup.add(progress); sortButtonGroup.add(timeRemaining); sortButtonGroup.add(speed); sortButtonGroup.add(status); sortButtonGroup.add(fileType); sortButtonGroup.add(extension); sortButtonGroup.add(userName); // Add menu items to menu. sortSubMenu.add(orderStarted); sortSubMenu.add(name); sortSubMenu.add(progress); sortSubMenu.add(timeRemaining); sortSubMenu.add(speed); sortSubMenu.add(status); sortSubMenu.add(fileType); sortSubMenu.add(extension); sortSubMenu.add(userName); sortSubMenu.addSeparator(); // Add menu item to reverse sort direction. AbstractButton reverseSortButton = new JMenuItem(new ReverseSortAction()); sortSubMenu.add(reverseSortButton); return sortSubMenu; } /** * Creates a new checkbox menu item for the Clear When Finished action. */ private JCheckBoxMenuItem createClearFinishedMenuItem() { JCheckBoxMenuItem checkBoxMenuItem = new JCheckBoxMenuItem(I18n.tr("Clear When Finished")); checkBoxMenuItem.setSelected(SharingSettings.CLEAR_UPLOAD.getValue()); checkBoxMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JMenuItem menuItem = (JMenuItem) e.getSource(); SharingSettings.CLEAR_UPLOAD.setValue(menuItem.isSelected()); } }); return checkBoxMenuItem; } /** * Prompts the user to confirm an action with the specified message. */ private boolean confirmCancel(Object message) { return (FocusJOptionPane.showConfirmDialog(GuiUtils.getMainFrame(), message, I18n.tr("Cancel"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION); } /** * Action to sort the uploads list. */ private class SortAction extends AbstractAction { private final SortOrder sortOrder; public SortAction(String title, SortOrder sortOrder) { super(title); this.sortOrder = sortOrder; // Select this action if currently in use. putValue(SELECTED_KEY, sortOrder == uploadMediator.getSortOrder()); } @Override public void actionPerformed(ActionEvent e) { uploadMediator.setSortOrder(sortOrder, uploadMediator.isSortAscending()); } }; /** * Action to reverse the sort order of the uploads list. */ private class ReverseSortAction extends AbstractAction { public ReverseSortAction() { super(I18n.tr("Reverse Order")); putValue(Action.SELECTED_KEY, uploadMediator.isSortAscending()); putValue(Action.SMALL_ICON, uploadMediator.isSortAscending() ? downArrow : upArrow); } @Override public void actionPerformed(ActionEvent e) { boolean direction = !uploadMediator.isSortAscending(); putValue(Action.SMALL_ICON, direction ? downArrow : upArrow); uploadMediator.setSortOrder(uploadMediator.getSortOrder(), direction); } }; /** * Action to display the Transfer Options dialog tab. */ private static class TransferOptionsAction extends AbstractAction { public TransferOptionsAction() { super(I18n.tr("More Transfer Options...")); } @Override public void actionPerformed(ActionEvent e) { ActionMap map = Application.getInstance().getContext().getActionManager().getActionMap(); map.get("showOptionsDialog").actionPerformed(new ActionEvent( this, ActionEvent.ACTION_PERFORMED, OptionsDialog.TRANSFERS)); } } }