package org.jabref.gui.externalfiletype; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.Optional; import javax.swing.Icon; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import org.jabref.gui.JabRefFrame; import org.jabref.gui.desktop.JabRefDesktop; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.util.FileHelper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * The menu item used in the popup menu for opening external resources associated * with an entry. Shows the resource name and icon given, and adds an action listener * to process the request if the user clicks this menu item. */ public class ExternalFileMenuItem extends JMenuItem implements ActionListener { private static final Log LOGGER = LogFactory.getLog(ExternalFileMenuItem.class); private final BibEntry entry; private final String link; private final BibDatabaseContext databaseContext; private Optional<ExternalFileType> fileType; private final JabRefFrame frame; private String fieldName; public ExternalFileMenuItem(JabRefFrame frame, BibEntry entry, String name, String link, Icon icon, BibDatabaseContext databaseContext, Optional<ExternalFileType> fileType) { super(name, icon); this.frame = frame; this.entry = entry; this.link = link; this.databaseContext = databaseContext; this.fileType = fileType; addActionListener(this); } public ExternalFileMenuItem(JabRefFrame frame, BibEntry entry, String name, String link, Icon icon, BibDatabaseContext databaseContext, String fieldName) { this(frame, entry, name, link, icon, databaseContext, Optional.empty()); this.fieldName = fieldName; } @Override public void actionPerformed(ActionEvent e) { boolean success = openLink(); if (!success) { frame.output(Localization.lang("Unable to open link.")); } } private boolean openLink() { frame.output(Localization.lang("External viewer called") + "."); try { Optional<ExternalFileType> type = fileType; if (!this.fileType.isPresent()) { if (this.fieldName == null) { // We don't already know the file type, so we try to deduce it from the extension: Optional<String> extension = FileHelper.getFileExtension(link); // Now we know the extension, check if it is one we know about: type = ExternalFileTypes.getInstance().getExternalFileTypeByExt(extension.orElse(null)); fileType = type; } else { JabRefDesktop.openExternalViewer(databaseContext, link, fieldName); return true; } } if (type.isPresent() && (type.get() instanceof UnknownExternalFileType)) { return JabRefDesktop.openExternalFileUnknown(frame, entry, databaseContext, link, (UnknownExternalFileType) type.get()); } else { return JabRefDesktop.openExternalFileAnyFormat(databaseContext, link, type); } } catch (IOException ex) { // See if we should show an error message concerning the application to open the // link with. We check if the file type is set, and if the file type has a non-empty // application link. If that link is referred by the error message, we can assume // that the problem is in the open-with-application setting: if ((fileType.isPresent()) && (!fileType.get().getOpenWithApplication().isEmpty()) && ex.getMessage().contains(fileType.get().getOpenWithApplication())) { JOptionPane.showMessageDialog(frame, Localization.lang("Unable to open link. " + "The application '%0' associated with the file type '%1' could not be called.", fileType.get().getOpenWithApplication(), fileType.get().getName()), Localization.lang("Could not open link"), JOptionPane.ERROR_MESSAGE); return false; } LOGGER.warn("Unable to open link", ex); } return false; } }