package org.limewire.ui.swing.search.resultpanel;
import static org.limewire.ui.swing.util.I18n.tr;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JDialog;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;
import org.limewire.core.api.endpoint.RemoteHost;
import org.limewire.ui.swing.action.AbstractAction;
import org.limewire.ui.swing.library.LibraryMediator;
import org.limewire.ui.swing.properties.FileInfoDialogFactory;
import org.limewire.ui.swing.properties.FileInfoDialog.FileInfoType;
import org.limewire.ui.swing.search.BlockUserMenuFactory;
import org.limewire.ui.swing.search.RemoteHostMenuFactory;
import org.limewire.ui.swing.search.model.BasicDownloadState;
import org.limewire.ui.swing.search.model.VisualSearchResult;
import org.limewire.ui.swing.util.FileChooser;
import org.limewire.ui.swing.util.GuiUtils;
import org.limewire.ui.swing.util.SwingHacks;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
/**
* This class implements the popup menu that is displayed when the user
* right-clicks on a search result.
*/
public class SearchResultMenu extends JPopupMenu {
/** Defines the available display types. */
public enum ViewType {
List,
Table
}
/**
* Constructs a SearchResultMenu using the specified download handler,
* list of selected results, properties factory, and display type.
*/
@Inject
public SearchResultMenu(@Assisted final DownloadHandler downloadHandler,
@Assisted final List<VisualSearchResult> selectedItems,
final FileInfoDialogFactory fileInfoFactory,
RemoteHostMenuFactory browseMenuFactory,
BlockUserMenuFactory blockUserMenuFactory, final LibraryMediator libraryMediator,
@Assisted ViewType viewType) {
SwingHacks.fixPopupMenuForWindows(this);
final VisualSearchResult firstItem = selectedItems.get(0);
// Determine if download is enabled.
boolean downloadEnabled = false;
for (VisualSearchResult visualSearchResult : selectedItems) {
if (visualSearchResult.getDownloadState() == BasicDownloadState.NOT_STARTED &&
!visualSearchResult.isSpam()) {
downloadEnabled = true;
break;
}
}
// Determine indicators to enable menu items.
boolean locateInLibraryVisible = firstItem.getDownloadState() == BasicDownloadState.LIBRARY || firstItem.getDownloadState() == BasicDownloadState.DOWNLOADED;
boolean showHideSimilarFileVisible = selectedItems.size() == 1 && firstItem.getSimilarResults().size() > 0 && viewType == ViewType.List;
boolean showHideSimilarFileEnabled = selectedItems.size() == 1 && firstItem.getDownloadState() == BasicDownloadState.NOT_STARTED;
boolean viewFileInfoEnabled = selectedItems.size() == 1;
boolean downloadAsVisible = selectedItems.size() == 1;
// Add Download menu item.
add(new AbstractAction(tr("Download")) {
public void actionPerformed(ActionEvent e) {
for (VisualSearchResult visualSearchResult : selectedItems) {
if (visualSearchResult.getDownloadState() == BasicDownloadState.NOT_STARTED &&
!visualSearchResult.isSpam()) {
downloadHandler.download(visualSearchResult);
}
}
}
}).setEnabled(downloadEnabled);
// Add Download As menu item if visible.
if (downloadAsVisible) {
add(new AbstractAction(tr("Download As...")) {
public void actionPerformed(ActionEvent e) {
for (VisualSearchResult visualSearchResult : selectedItems) {
if (visualSearchResult.getDownloadState() == BasicDownloadState.NOT_STARTED &&
!visualSearchResult.isSpam()) {
// Create suggested file. We don't specify a directory
// path so we can use the last input directory. To get
// the default save directory, we could call
// SharingSettings.getSaveDirectory(fileName).
String fileName = visualSearchResult.getFileName();
File suggestedFile = new File(fileName);
// Prompt user for local file name.
File saveFile = FileChooser.getSaveAsFile(
GuiUtils.getMainFrame(), tr("Download As"),
suggestedFile);
// Start download if not canceled.
if (saveFile != null) {
downloadHandler.download(visualSearchResult, saveFile);
}
}
}
}
}).setEnabled(downloadEnabled);
}
// Work out whether we need Mark as Spam, Unmark as Spam, or both.
boolean anySpamItems = false, anyNonSpamItems = false;
for (VisualSearchResult visualSearchResult : selectedItems) {
if (visualSearchResult.isSpam())
anySpamItems = true;
else
anyNonSpamItems = true;
}
// Add Mark as Spam menu item if any items are not marked as spam.
if (anyNonSpamItems) {
add(new AbstractAction(tr("Mark as Spam")) {
public void actionPerformed(ActionEvent e) {
for (VisualSearchResult visualSearchResult : selectedItems) {
visualSearchResult.setSpam(true);
}
}
});
}
// Add Unmark as Spam menu item if any items are marked as spam.
if (anySpamItems) {
add(new AbstractAction(tr("Unmark as Spam")) {
public void actionPerformed(ActionEvent e) {
for (VisualSearchResult visualSearchResult : selectedItems) {
visualSearchResult.setSpam(false);
}
}
});
}
addSeparator();
// Add Locate in Library menu item if visible.
if(locateInLibraryVisible){
add(new AbstractAction(tr("Locate in Library")) {
@Override
public void actionPerformed(ActionEvent e) {
libraryMediator.selectInLibrary(firstItem.getUrn());
}
});
addSeparator();
}
// Add optional item for Similar Files.
if (showHideSimilarFileVisible) {
add(new AbstractAction(firstItem.isChildrenVisible() ? tr("Hide Similar Files") : tr("Show Similar Files")) {
@Override
public void actionPerformed(ActionEvent e) {
firstItem.toggleChildrenVisibility();
}
}).setEnabled(showHideSimilarFileEnabled);
addSeparator();
}
final List<RemoteHost> allNonSpamHosts = new ArrayList<RemoteHost>();
for (VisualSearchResult result : selectedItems) {
if (!result.isSpam())
allNonSpamHosts.addAll(result.getSources());
}
if (allNonSpamHosts.size() > 0) {
add(browseMenuFactory.createBrowseMenu(allNonSpamHosts));
}
final List<RemoteHost> allHosts = new ArrayList<RemoteHost>();
for (VisualSearchResult result : selectedItems) {
allHosts.addAll(result.getSources());
}
if (allHosts.size() > 0) {
JMenu blockUserMenu = blockUserMenuFactory.createSearchBlockMenu(allHosts, selectedItems);
if (blockUserMenu != null) {
add(blockUserMenu);
addSeparator();
}
}
// Add View File Info menu item.
add(new AbstractAction(tr("View File Info...")) {
public void actionPerformed(ActionEvent e) {
JDialog dialog = fileInfoFactory.createFileInfoDialog(firstItem, FileInfoType.REMOTE_FILE);
dialog.setVisible(true);
}
}).setEnabled(viewFileInfoEnabled);
}
}