Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix selecting custom export for copy to clipboard with uppercase file ext #6290

Merged
merged 9 commits into from
May 1, 2020
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve
- We fixed an issue when importing into current library an erroneous message "import cancelled" is displayed even though import is successful. [#6266](https://github.com/JabRef/jabref/issues/6266)
- We fixed an issue where custom jstyles for Open/LibreOffice where not saved correctly. [#6170](https://github.com/JabRef/jabref/issues/6170)
- We fixed an issue where the INSPIRE fetcher was no longer working [#6229](https://github.com/JabRef/jabref/issues/6229)
- We fixed an issue where custom exports with an uppercase file extension could not be selected for "Copy...-> Export to Clipboard" [#6285](https://github.com/JabRef/jabref/issues/6285)

- We fixed the display of icon both in the main table and linked file editor. [#6169](https://github.com/JabRef/jabref/issues/6169)
- We fixed the paste entry command in the menu and toolbar, that did not do anything. [#6293](https://github.com/JabRef/jabref/issues/6293)
- We fixed an issue where the windows installer did not create an entry in the start menu [bug report in the forum](https://discourse.jabref.org/t/error-while-fetching-from-doi/2018/3)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/JabRefFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ private MenuBar createMenu() {
factory.createMenuItem(StandardActions.COPY_KEY_AND_TITLE, new CopyMoreAction(StandardActions.COPY_KEY_AND_TITLE, dialogService, stateManager, Globals.clipboardManager, prefs)),
factory.createMenuItem(StandardActions.COPY_KEY_AND_LINK, new CopyMoreAction(StandardActions.COPY_KEY_AND_LINK, dialogService, stateManager, Globals.clipboardManager, prefs)),
factory.createMenuItem(StandardActions.COPY_CITATION_PREVIEW, new CopyCitationAction(CitationStyleOutputFormat.HTML, dialogService, stateManager, Globals.clipboardManager, prefs.getPreviewPreferences())),
factory.createMenuItem(StandardActions.EXPORT_SELECTED_TO_CLIPBOARD, new ExportToClipboardAction(this, dialogService))),
factory.createMenuItem(StandardActions.EXPORT_SELECTED_TO_CLIPBOARD, new ExportToClipboardAction(this, dialogService, Globals.exportFactory, Globals.clipboardManager, Globals.TASK_EXECUTOR))),

factory.createMenuItem(StandardActions.PASTE, new EditAction(StandardActions.PASTE, this, stateManager)),

Expand Down
47 changes: 31 additions & 16 deletions src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,28 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import javafx.scene.input.ClipboardContent;

import org.jabref.Globals;
import org.jabref.gui.BasePanel;
import org.jabref.gui.ClipBoardManager;
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.TaskExecutor;
import org.jabref.logic.exporter.Exporter;
import org.jabref.logic.exporter.ExporterFactory;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.util.FileType;
import org.jabref.logic.util.OS;
import org.jabref.logic.util.StandardFileType;
import org.jabref.model.entry.BibEntry;
import org.jabref.preferences.JabRefPreferences;

Expand All @@ -34,21 +38,30 @@ public class ExportToClipboardAction extends SimpleCommand {
private static final Logger LOGGER = LoggerFactory.getLogger(ExportToClipboardAction.class);

// Only text based exporters can be used
private static final List<String> SUPPORTED_FILETYPES = Arrays.asList("txt", "rtf", "rdf", "xml", "html", "htm", "csv", "ris");
private static final Set<FileType> SUPPORTED_FILETYPES = Set.of(StandardFileType.TXT, StandardFileType.RTF, StandardFileType.RDF, StandardFileType.XML, StandardFileType.HTML, StandardFileType.CSV, StandardFileType.RIS);

private JabRefFrame frame;
private final DialogService dialogService;
private BasePanel panel;
private final List<BibEntry> entries = new ArrayList<>();
private final ExporterFactory exporterFactory;
private final ClipBoardManager clipBoardManager;
private final TaskExecutor taskExecutor;

public ExportToClipboardAction(JabRefFrame frame, DialogService dialogService) {
public ExportToClipboardAction(JabRefFrame frame, DialogService dialogService, ExporterFactory exporterFactory, ClipBoardManager clipBoardManager, TaskExecutor taskExecutor) {
this.frame = frame;
this.dialogService = dialogService;
this.exporterFactory = exporterFactory;
this.clipBoardManager = clipBoardManager;
this.taskExecutor = taskExecutor;
}

public ExportToClipboardAction(BasePanel panel, DialogService dialogService) {
public ExportToClipboardAction(BasePanel panel, DialogService dialogService, ExporterFactory exporterFactory, ClipBoardManager clipBoardManager, TaskExecutor taskExecutor) {
this.panel = panel;
this.dialogService = dialogService;
this.exporterFactory = exporterFactory;
this.clipBoardManager = clipBoardManager;
this.taskExecutor = taskExecutor;
}

@Override
Expand All @@ -62,10 +75,10 @@ public void execute() {
return;
}

List<Exporter> exporters = Globals.exportFactory.getExporters().stream()
.sorted(Comparator.comparing(Exporter::getName))
.filter(exporter -> SUPPORTED_FILETYPES.containsAll(exporter.getFileType().getExtensions()))
.collect(Collectors.toList());
List<Exporter> exporters = exporterFactory.getExporters().stream()
.sorted(Comparator.comparing(Exporter::getName))
.filter(exporter -> SUPPORTED_FILETYPES.contains(exporter.getFileType()))
.collect(Collectors.toList());

// Find default choice, if any
Exporter defaultChoice = exporters.stream()
Expand All @@ -74,12 +87,15 @@ public void execute() {
.orElse(null);

Optional<Exporter> selectedExporter = dialogService.showChoiceDialogAndWait(Localization.lang("Export"), Localization.lang("Select export format"),
Localization.lang("Export"), defaultChoice, exporters);
Localization.lang("Export"), defaultChoice, exporters);

selectedExporter.ifPresent(exporter -> BackgroundTask.wrap(() -> exportToClipboard(exporter))
.onSuccess(this::setContentToClipboard)
.onFailure(ex -> { /* swallow as already logged */ })
.executeWith(Globals.TASK_EXECUTOR));
.onSuccess(this::setContentToClipboard)
.onFailure(ex -> {
LOGGER.error("Error exporting to clipboard", ex);
dialogService.showErrorDialogAndWait("Error exporting to clipboard", ex);
})
.executeWith(taskExecutor));
}

private ExportResult exportToClipboard(Exporter exporter) throws Exception {
Expand Down Expand Up @@ -109,9 +125,7 @@ private ExportResult exportToClipboard(Exporter exporter) throws Exception {
// Read the file and put the contents on the clipboard:

return new ExportResult(readFileToString(tmp), exporter.getFileType());
} catch (Exception e) {
LOGGER.error("Error exporting to clipboard", e);
throw new Exception("Rethrow ", e);

} finally {
// Clean up:
if ((tmp != null) && Files.exists(tmp)) {
Expand All @@ -135,7 +149,7 @@ private void setContentToClipboard(ExportResult result) {
clipboardContent.putRtf(result.content);
}
clipboardContent.putString(result.content);
Globals.clipboardManager.setContent(clipboardContent);
this.clipBoardManager.setContent(clipboardContent);

dialogService.notify(Localization.lang("Entries exported to clipboard") + ": " + entries.size());

Expand All @@ -151,6 +165,7 @@ private String readFileToString(Path tmp) throws IOException {
}

private static class ExportResult {

final String content;
final FileType fileType;

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/maintable/RightClickMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private static Menu createCopySubMenu(BasePanel panel, ActionFactory factory, Di
copySpecialMenu.getItems().add(factory.createMenuItem(StandardActions.COPY_CITATION_PREVIEW, new CopyCitationAction(CitationStyleOutputFormat.HTML, dialogService, stateManager, Globals.clipboardManager, previewPreferences)));
}

copySpecialMenu.getItems().add(factory.createMenuItem(StandardActions.EXPORT_TO_CLIPBOARD, new ExportToClipboardAction(panel, dialogService)));
copySpecialMenu.getItems().add(factory.createMenuItem(StandardActions.EXPORT_TO_CLIPBOARD, new ExportToClipboardAction(panel, dialogService, Globals.exportFactory, Globals.clipboardManager, Globals.TASK_EXECUTOR)));
return copySpecialMenu;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public CopyCitationAction(CitationStyleOutputFormat outputFormat, DialogService
this.executable.bind(ActionHelper.needsEntriesSelected(stateManager));
}

@Override
public void execute() {
BackgroundTask.wrap(this::generateCitations)
.onFailure(ex -> LOGGER.error("Error while copying citations to the clipboard", ex))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public TemplateExporter(String displayName, String consoleName, String lfFileNam
*/
public TemplateExporter(String name, String lfFileName, String extension, LayoutFormatterPreferences layoutPreferences,
SavePreferences savePreferences) {
this(name, name, lfFileName, null, StandardFileType.newFileType(extension), layoutPreferences, savePreferences);
this(name, name, lfFileName, null, StandardFileType.fromExtensions(extension), layoutPreferences, savePreferences);
}

/**
Expand Down
20 changes: 12 additions & 8 deletions src/main/java/org/jabref/logic/util/StandardFileType.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
import java.util.Arrays;
import java.util.List;

import org.jabref.model.util.OptionalUtil;

/**
*
* @implNote Enter the extensions without a dot! The dot is added implicitly.
*/
public enum StandardFileType implements FileType {

BIBTEXML("bibx", "xml"),
ENDNOTE("ref", "enw"),
ISI("isi", "txt"),
Expand All @@ -21,7 +24,7 @@ public enum StandardFileType implements FileType {
CITATION_STYLE("csl"),
CLASS("class"),
CSV("csv"),
HTML("html"),
HTML("html", "htm"),
JAR("jar"),
JAVA_KEYSTORE("jks"),
JSTYLE("jstyle"),
Expand Down Expand Up @@ -51,12 +54,13 @@ public List<String> getExtensions() {
return extensions;
}

public static FileType newFileType(String... extensions) {
for (int i = 0; i < extensions.length; i++) {
if (extensions[i].contains(".")) {
extensions[i] = extensions[i].substring(extensions[i].indexOf('.') + 1);
}
}
return () -> Arrays.asList(extensions);
public static FileType fromExtensions(String... extensions) {
var exts = Arrays.asList(extensions);

return OptionalUtil.orElse(Arrays.stream(StandardFileType.values())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think OptionalUtil.orElse is no longer needed, as Java has now its own orElse method.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tobiasdiez Yes, but it did not work with the type inference, it expected a type of StandardFileType in the orElse part and created a compile error when
Therefore I had to use our util method:
https://stackoverflow.com/a/54238663

Please wait with merging I think I still need to convert the extensions to lower case before

.filter(field -> field.getExtensions().stream().anyMatch(elem -> exts.contains(elem)))
.findAny(),
new UnknownFileType(extensions));
}

}
44 changes: 44 additions & 0 deletions src/main/java/org/jabref/logic/util/UnknownFileType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.jabref.logic.util;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

public class UnknownFileType implements FileType {

private final List<String> extensions;

public UnknownFileType(String... extensions) {
for (int i = 0; i < extensions.length; i++) {
if (extensions[i].contains(".")) {
extensions[i] = extensions[i].substring(extensions[i].indexOf('.') + 1);
}
}
this.extensions = Arrays.asList(extensions);
}

@Override
public List<String> getExtensions() {
return extensions;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof FileType)) {
return false;
}
FileType other = (FileType) o;
Collections.sort(extensions);
Collections.sort(other.getExtensions());
return extensions.equals(other.getExtensions());
}

@Override
public int hashCode() {
return Objects.hash(extensions);
}
}