diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index f9f1641a7e3..229ee4ad24b 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -50,7 +50,6 @@ import org.jabref.gui.contentselector.ContentSelectorDialog; import org.jabref.gui.desktop.JabRefDesktop; import org.jabref.gui.entryeditor.EntryEditor; -import org.jabref.gui.exporter.ExportToClipboardAction; import org.jabref.gui.exporter.SaveDatabaseAction; import org.jabref.gui.externalfiles.FindFullTextAction; import org.jabref.gui.externalfiletype.ExternalFileMenuItem; @@ -434,7 +433,6 @@ private void setupActions() { csd.setVisible(true); }); - actions.put(Actions.EXPORT_TO_CLIPBOARD, new ExportToClipboardAction(this)); actions.put(Actions.SEND_AS_EMAIL, new SendAsEMailAction(frame)); actions.put(Actions.WRITE_XMP, new WriteXMPAction(this)::execute); diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 7996a474587..179bcb9f0f5 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -88,6 +88,7 @@ import org.jabref.gui.actions.StandardActions; import org.jabref.gui.dialogs.AutosaveUIManager; import org.jabref.gui.exporter.ExportCommand; +import org.jabref.gui.exporter.ExportToClipboardAction; import org.jabref.gui.exporter.SaveAllAction; import org.jabref.gui.exporter.SaveDatabaseAction; import org.jabref.gui.externalfiletype.ExternalFileTypes; @@ -781,7 +782,7 @@ private MenuBar createMenu() { factory.createMenuItem(StandardActions.COPY_KEY_AND_TITLE, new OldDatabaseCommandWrapper(Actions.COPY_KEY_AND_TITLE, this, Globals.stateManager)), factory.createMenuItem(StandardActions.COPY_KEY_AND_LINK, new OldDatabaseCommandWrapper(Actions.COPY_KEY_AND_LINK, this, Globals.stateManager)), factory.createMenuItem(StandardActions.COPY_CITATION_PREVIEW, new OldDatabaseCommandWrapper(Actions.COPY_CITATION_HTML, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.EXPORT_SELECTED_TO_CLIPBOARD, new OldDatabaseCommandWrapper(Actions.EXPORT_TO_CLIPBOARD, this, Globals.stateManager))), + factory.createMenuItem(StandardActions.EXPORT_SELECTED_TO_CLIPBOARD, new ExportToClipboardAction(this, dialogService))), factory.createMenuItem(StandardActions.PASTE, new EditAction(Actions.PASTE)), diff --git a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java index 97dc2a559e4..ee1cfad868d 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java +++ b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java @@ -1,12 +1,10 @@ package org.jabref.gui.exporter; -import java.awt.datatransfer.ClipboardOwner; +import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardOpenOption; +import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Optional; @@ -16,30 +14,43 @@ import org.jabref.Globals; import org.jabref.gui.BasePanel; -import org.jabref.gui.actions.BaseAction; +import org.jabref.gui.DialogService; +import org.jabref.gui.JabRefFrame; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.BackgroundTask; -import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.exporter.Exporter; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.util.OS; import org.jabref.model.entry.BibEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ExportToClipboardAction implements BaseAction { +public class ExportToClipboardAction extends SimpleCommand { + private static final Logger LOGGER = LoggerFactory.getLogger(ExportToClipboardAction.class); - private final BasePanel panel; + private JabRefFrame frame; + private final DialogService dialogService; + private BasePanel panel; + private final List entries = new ArrayList<>(); + + public ExportToClipboardAction(JabRefFrame frame, DialogService dialogService) { + this.frame = frame; + this.dialogService = dialogService; + } - public ExportToClipboardAction(BasePanel panel) { + public ExportToClipboardAction(BasePanel panel, DialogService dialogService) { this.panel = panel; + this.dialogService = dialogService; } @Override - public void action() { + public void execute() { if (panel == null) { - return; + panel = frame.getCurrentBasePanel(); } + if (panel.getSelectedEntries().isEmpty()) { panel.output(Localization.lang("This operation requires one or more entries to be selected.")); return; @@ -49,14 +60,12 @@ public void action() { .sorted(Comparator.comparing(Exporter::getName)) .collect(Collectors.toList()); - DefaultTaskExecutor.runInJavaFXThread(() -> { - Optional selectedExporter = panel.frame().getDialogService().showChoiceDialogAndWait(Localization.lang("Export"), Localization.lang("Select export format"), - Localization.lang("Export"), exporters); + Optional selectedExporter = dialogService.showChoiceDialogAndWait(Localization.lang("Export"), Localization.lang("Select export format"), + Localization.lang("Export"), exporters); - selectedExporter.ifPresent(exporter -> BackgroundTask.wrap(() -> exportToClipboard(exporter)) - .onSuccess(panel::output) - .executeWith(Globals.TASK_EXECUTOR)); - }); + selectedExporter.ifPresent(exporter -> BackgroundTask.wrap(() -> exportToClipboard(exporter)) + .onSuccess(this::setContentToClipboard) + .executeWith(Globals.TASK_EXECUTOR)); } @@ -64,8 +73,7 @@ private String exportToClipboard(Exporter exporter) { // Set the global variable for this database's file directory before exporting, // so formatters can resolve linked files correctly. // (This is an ugly hack!) - Globals.prefs.fileDirForDatabase = panel.getBibDatabaseContext() - .getFileDirectories(Globals.prefs.getFileDirectoryPreferences()); + Globals.prefs.fileDirForDatabase = panel.getBibDatabaseContext().getFileDirectoriesAsPaths(Globals.prefs.getFileDirectoryPreferences()).stream().map(Path::toString).collect(Collectors.toList()); Path tmp = null; try { @@ -73,38 +81,20 @@ private String exportToClipboard(Exporter exporter) { // file, and read the contents afterwards: tmp = Files.createTempFile("jabrefCb", ".tmp"); - List entries = panel.getSelectedEntries(); + entries.addAll(panel.getSelectedEntries()); // Write to file: exporter.export(panel.getBibDatabaseContext(), tmp, - panel.getBibDatabaseContext() - .getMetaData() - .getEncoding() - .orElse(Globals.prefs.getDefaultEncoding()), - entries); + panel.getBibDatabaseContext() + .getMetaData() + .getEncoding() + .orElse(Globals.prefs.getDefaultEncoding()), + entries); // Read the file and put the contents on the clipboard: - StringBuilder sb = new StringBuilder(); - try (Reader reader = new InputStreamReader(Files.newInputStream(tmp, StandardOpenOption.DELETE_ON_CLOSE), - panel.getBibDatabaseContext() - .getMetaData() - .getEncoding() - .orElse(Globals.prefs.getDefaultEncoding()))) { - int s; - while ((s = reader.read()) != -1) { - sb.append((char) s); - } - } - ClipboardOwner owner = (clipboard, content) -> { - // Do nothing - }; - ClipboardContent clipboardContent = new ClipboardContent(); - clipboardContent.putRtf(sb.toString()); - Globals.clipboardManager.setContent(clipboardContent); - return Localization.lang("Entries exported to clipboard") + ": " + entries.size(); + return readFileToString(tmp); } catch (Exception e) { LOGGER.error("Error exporting to clipboard", e); - return Localization.lang("Error exporting to clipboard"); } finally { // Clean up: if ((tmp != null) && Files.exists(tmp)) { @@ -115,5 +105,24 @@ private String exportToClipboard(Exporter exporter) { } } } + return ""; + } + + private void setContentToClipboard(String content) { + ClipboardContent clipboardContent = new ClipboardContent(); + clipboardContent.putRtf(content); + Globals.clipboardManager.setContent(clipboardContent); + + panel.output(Localization.lang("Entries exported to clipboard") + ": " + entries.size()); + + } + + private String readFileToString(Path tmp) throws IOException { + try (BufferedReader reader = Files.newBufferedReader(tmp, panel.getBibDatabaseContext() + .getMetaData() + .getEncoding() + .orElse(Globals.prefs.getDefaultEncoding()))) { + return reader.lines().collect(Collectors.joining(OS.NEWLINE)); + } } } diff --git a/src/main/java/org/jabref/gui/maintable/RightClickMenu.java b/src/main/java/org/jabref/gui/maintable/RightClickMenu.java index 28c188eca9c..f0bd9d61775 100644 --- a/src/main/java/org/jabref/gui/maintable/RightClickMenu.java +++ b/src/main/java/org/jabref/gui/maintable/RightClickMenu.java @@ -14,6 +14,7 @@ import org.jabref.gui.actions.Actions; import org.jabref.gui.actions.OldCommandWrapper; import org.jabref.gui.actions.StandardActions; +import org.jabref.gui.exporter.ExportToClipboardAction; import org.jabref.gui.filelist.AttachFileAction; import org.jabref.gui.keyboard.KeyBindingRepository; import org.jabref.gui.menus.ChangeEntryTypeMenu; @@ -34,7 +35,7 @@ public static ContextMenu create(BibEntryTableViewModel entry, KeyBindingReposit ActionFactory factory = new ActionFactory(keyBindingRepository); contextMenu.getItems().add(factory.createMenuItem(StandardActions.COPY, new OldCommandWrapper(Actions.COPY, panel))); - contextMenu.getItems().add(createCopySubMenu(panel, factory)); + contextMenu.getItems().add(createCopySubMenu(panel, factory, dialogService)); contextMenu.getItems().add(factory.createMenuItem(StandardActions.PASTE, new OldCommandWrapper(Actions.PASTE, panel))); contextMenu.getItems().add(factory.createMenuItem(StandardActions.CUT, new OldCommandWrapper(Actions.CUT, panel))); contextMenu.getItems().add(factory.createMenuItem(StandardActions.DELETE, new OldCommandWrapper(Actions.DELETE, panel))); @@ -141,7 +142,7 @@ private static OldCommandWrapper getOpenFolderCommand(BasePanel panel) { return command; } - private static Menu createCopySubMenu(BasePanel panel, ActionFactory factory) { + private static Menu createCopySubMenu(BasePanel panel, ActionFactory factory, DialogService dialogService) { Menu copySpecialMenu = factory.createMenu(StandardActions.COPY_MORE); copySpecialMenu.getItems().add(factory.createMenuItem(StandardActions.COPY_TITLE, new OldCommandWrapper(Actions.COPY_TITLE, panel))); copySpecialMenu.getItems().add(factory.createMenuItem(StandardActions.COPY_KEY, new OldCommandWrapper(Actions.COPY_KEY, panel))); @@ -164,7 +165,7 @@ private static Menu createCopySubMenu(BasePanel panel, ActionFactory factory) { copySpecialMenu.getItems().add(factory.createMenuItem(StandardActions.COPY_CITATION_PREVIEW, new OldCommandWrapper(Actions.COPY_CITATION_HTML, panel))); } - copySpecialMenu.getItems().add(factory.createMenuItem(StandardActions.EXPORT_TO_CLIPBOARD, new OldCommandWrapper(Actions.EXPORT_TO_CLIPBOARD, panel))); + copySpecialMenu.getItems().add(factory.createMenuItem(StandardActions.EXPORT_TO_CLIPBOARD, new ExportToClipboardAction(panel, dialogService))); return copySpecialMenu; } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 0b3bfa33c0a..d088df6710c 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -378,7 +378,6 @@ Entry\ type\ names\ are\ not\ allowed\ to\ contain\ white\ space\ or\ the\ follo Entry\ types=Entry types Error=Error -Error\ exporting\ to\ clipboard=Error exporting to clipboard Error\ occurred\ when\ parsing\ entry=Error occurred when parsing entry