diff --git a/CHANGELOG.md b/CHANGELOG.md
index f2119c71557..3ace7046089 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We changed the behavior of the field formatting dialog such that the `bibtexkey` is not changed when formatting all fields or all text fields.
- We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166)
- Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070)
+- We added a cleanup operation that detects an arXiv identifier in the note, journal or url field and moves it to the `eprint` field.
+ Because of this change, the last-used cleanup operations were reset.
- We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093)
- The special fields like `Printed` and `Read status` now show gray icons when the row is hovered.
- We added a button in the tab header which allows you to close the database with one click. https://github.com/JabRef/jabref/issues/494
@@ -28,6 +30,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down.
- Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file.
- Window state is saved on close and restored on start.
+- We made the MathSciNet fetcher more reliable.
+- We added the ISBN fetcher to the list of fetcher available under "Update with bibliographic information from the web" in the entry editor toolbar.
- Files without a defined external file type are now directly opened with the default application of the operating system
- We streamlined the process to rename and move files by removing the confirmation dialogs.
- We removed the redundant new lines of markings and wrapped the summary in the File annotation tab. [#3823](https://github.com/JabRef/jabref/issues/3823)
@@ -76,7 +80,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We fixed an issue where the list of XMP Exclusion fields in the preferences was not be saved [#4072](https://github.com/JabRef/jabref/issues/4072)
- We fixed an issue where the ArXiv Fetcher did not support HTTP URLs [koppor#328](https://github.com/koppor/jabref/issues/328)
- We fixed an issue where only one PDF file could be imported [#4422](https://github.com/JabRef/jabref/issues/4422)
-
+- We fixed an issue where "Move to group" would always move the first entry in the library and not the selected [#4414](https://github.com/JabRef/jabref/issues/4414)
diff --git a/src/main/java/org/jabref/gui/actions/CleanupAction.java b/src/main/java/org/jabref/gui/actions/CleanupAction.java
index a4814735c8d..648af8313b7 100644
--- a/src/main/java/org/jabref/gui/actions/CleanupAction.java
+++ b/src/main/java/org/jabref/gui/actions/CleanupAction.java
@@ -10,7 +10,6 @@
import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.undo.UndoableFieldChange;
import org.jabref.gui.util.BackgroundTask;
-import org.jabref.gui.util.DefaultTaskExecutor;
import org.jabref.logic.cleanup.CleanupPreset;
import org.jabref.logic.cleanup.CleanupWorker;
import org.jabref.logic.l10n.Localization;
@@ -23,11 +22,6 @@ public class CleanupAction implements BaseAction {
private final BasePanel panel;
private final DialogService dialogService;
- /**
- * Global variable to count unsuccessful renames
- */
- private int unsuccessfulRenames;
-
private boolean isCanceled;
private int modifiedEntriesCount;
private final JabRefPreferences preferences;
@@ -44,13 +38,31 @@ public void action() {
if (isCanceled) {
return;
}
- CleanupDialog cleanupDialog = new CleanupDialog(panel.getBibDatabaseContext(), preferences.getCleanupPreset());
+ CleanupDialog cleanupDialog = new CleanupDialog(panel.getBibDatabaseContext(), preferences.getCleanupPreset(), preferences.getFilePreferences());
Optional chosenPreset = cleanupDialog.showAndWait();
- chosenPreset.ifPresent(cleanupPreset ->
- BackgroundTask.wrap(() -> cleanup(cleanupPreset))
- .onSuccess(x -> showResults())
- .executeWith(Globals.TASK_EXECUTOR));
+
+ if (chosenPreset.isPresent()) {
+ if (chosenPreset.get().isRenamePDFActive() && preferences.getBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN)) {
+ boolean confirmed = dialogService.showConfirmationDialogWithOptOutAndWait(Localization.lang("Autogenerate PDF Names"),
+ Localization.lang("Auto-generating PDF-Names does not support undo. Continue?"),
+ Localization.lang("Autogenerate PDF Names"),
+ Localization.lang("Cancel"),
+ Localization.lang("Disable this confirmation dialog"),
+ optOut -> Globals.prefs.putBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN, !optOut));
+
+ if (!confirmed) {
+ isCanceled = true;
+ return;
+ }
+ }
+
+ preferences.setCleanupPreset(chosenPreset.get());
+
+ BackgroundTask.wrap(() -> cleanup(chosenPreset.get()))
+ .onSuccess(result -> showResults())
+ .executeWith(Globals.TASK_EXECUTOR);
+ }
}
public void init() {
@@ -111,21 +123,6 @@ private void showResults() {
private void cleanup(CleanupPreset cleanupPreset) {
preferences.setCleanupPreset(cleanupPreset);
- if (cleanupPreset.isRenamePDF() && preferences.getBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN)) {
-
- boolean confirmed = DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showConfirmationDialogWithOptOutAndWait(Localization.lang("Autogenerate PDF Names"),
- Localization.lang("Auto-generating PDF-Names does not support undo. Continue?"),
- Localization.lang("Autogenerate PDF Names"),
- Localization.lang("Cancel"),
- Localization.lang("Disable this confirmation dialog"),
- optOut -> Globals.prefs.putBoolean(JabRefPreferences.ASK_AUTO_NAMING_PDFS_AGAIN, !optOut)));
-
- if (!confirmed) {
- isCanceled = true;
- return;
- }
- }
-
for (BibEntry entry : panel.getSelectedEntries()) {
// undo granularity is on entry level
NamedCompound ce = new NamedCompound(Localization.lang("Cleanup entry"));
diff --git a/src/main/java/org/jabref/gui/cleanup/CleanupDialog.java b/src/main/java/org/jabref/gui/cleanup/CleanupDialog.java
index 4e672761366..83d9e810b05 100644
--- a/src/main/java/org/jabref/gui/cleanup/CleanupDialog.java
+++ b/src/main/java/org/jabref/gui/cleanup/CleanupDialog.java
@@ -6,15 +6,16 @@
import org.jabref.logic.cleanup.CleanupPreset;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
+import org.jabref.model.metadata.FilePreferences;
public class CleanupDialog extends BaseDialog {
- public CleanupDialog(BibDatabaseContext databaseContext, CleanupPreset initialPreset) {
+ public CleanupDialog(BibDatabaseContext databaseContext, CleanupPreset initialPreset, FilePreferences filePreferences) {
setTitle(Localization.lang("Cleanup entries"));
getDialogPane().setPrefSize(600, 600);
getDialogPane().getButtonTypes().setAll(ButtonType.OK, ButtonType.CANCEL);
- CleanupPresetPanel presetPanel = new CleanupPresetPanel(databaseContext, initialPreset);
+ CleanupPresetPanel presetPanel = new CleanupPresetPanel(databaseContext, initialPreset, filePreferences);
getDialogPane().setContent(presetPanel);
setResultConverter(button -> {
if (button == ButtonType.OK) {
diff --git a/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.fxml b/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.fxml
new file mode 100644
index 00000000000..1ca9d6ebafa
--- /dev/null
+++ b/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.fxml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java b/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java
index 4bd64ec1f62..9149ef4a5f0 100644
--- a/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java
+++ b/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java
@@ -6,124 +6,103 @@
import java.util.Optional;
import java.util.Set;
-import javafx.scene.Group;
+import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.layout.GridPane;
+import javafx.scene.layout.VBox;
-import org.jabref.Globals;
import org.jabref.logic.cleanup.CleanupPreset;
import org.jabref.logic.cleanup.Cleanups;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.FieldName;
-import org.jabref.preferences.JabRefPreferences;
+import org.jabref.model.metadata.FilePreferences;
-public class CleanupPresetPanel extends ScrollPane {
+import com.airhacks.afterburner.views.ViewLoader;
+
+public class CleanupPresetPanel extends VBox {
private final BibDatabaseContext databaseContext;
- private CheckBox cleanUpDOI;
- private CheckBox cleanUpISSN;
- private CheckBox cleanUpMovePDF;
- private CheckBox cleanUpMakePathsRelative;
- private CheckBox cleanUpRenamePDF;
- private CheckBox cleanUpRenamePDFonlyRelativePaths;
- private CheckBox cleanUpUpgradeExternalLinks;
- private CheckBox cleanUpBiblatex;
- private CheckBox cleanUpBibtex;
+ @FXML private Label cleanupRenamePDFLabel;
+ @FXML private CheckBox cleanUpDOI;
+ @FXML private CheckBox cleanUpEprint;
+ @FXML private CheckBox cleanUpISSN;
+ @FXML private CheckBox cleanUpMovePDF;
+ @FXML private CheckBox cleanUpMakePathsRelative;
+ @FXML private CheckBox cleanUpRenamePDF;
+ @FXML private CheckBox cleanUpRenamePDFonlyRelativePaths;
+ @FXML private CheckBox cleanUpUpgradeExternalLinks;
+ @FXML private CheckBox cleanUpBiblatex;
+ @FXML private CheckBox cleanUpBibtex;
+ @FXML private VBox formatterContainer;
private FieldFormatterCleanupsPanel cleanUpFormatters;
- private CleanupPreset cleanupPreset;
-
- public CleanupPresetPanel(BibDatabaseContext databaseContext, CleanupPreset cleanupPreset) {
- this.cleanupPreset = Objects.requireNonNull(cleanupPreset);
+ public CleanupPresetPanel(BibDatabaseContext databaseContext, CleanupPreset cleanupPreset, FilePreferences filePreferences) {
this.databaseContext = Objects.requireNonNull(databaseContext);
- init();
+
+ // Load FXML
+ ViewLoader.view(this)
+ .root(this)
+ .load();
+
+ init(cleanupPreset, filePreferences);
}
- private void init() {
- cleanUpDOI = new CheckBox(
- Localization.lang("Move DOIs from note and URL field to DOI field and remove http prefix"));
- cleanUpISSN = new CheckBox(Localization.lang("Reformat ISSN"));
- Optional firstExistingDir = databaseContext
- .getFirstExistingFileDir(JabRefPreferences.getInstance().getFilePreferences());
+ private void init(CleanupPreset cleanupPreset, FilePreferences filePreferences) {
+ Optional firstExistingDir = databaseContext.getFirstExistingFileDir(filePreferences);
if (firstExistingDir.isPresent()) {
- cleanUpMovePDF = new CheckBox(Localization.lang("Move linked files to default file directory %0",
- firstExistingDir.get().toString()));
+ cleanUpMovePDF.setText(Localization.lang("Move linked files to default file directory %0", firstExistingDir.get().toString()));
} else {
- cleanUpMovePDF = new CheckBox(Localization.lang("Move linked files to default file directory %0", "..."));
- cleanUpMovePDF.setDisable(true);
+ cleanUpMovePDF.setText(Localization.lang("Move linked files to default file directory %0", "..."));
+
// Since the directory does not exist, we cannot move it to there. So, this option is not checked - regardless of the presets stored in the preferences.
+ cleanUpMovePDF.setDisable(true);
cleanUpMovePDF.setSelected(false);
}
- cleanUpMakePathsRelative = new CheckBox(
- Localization.lang("Make paths of linked files relative (if possible)"));
- cleanUpRenamePDF = new CheckBox(Localization.lang("Rename PDFs to given filename format pattern"));
- cleanUpRenamePDF.selectedProperty().addListener(
- event -> cleanUpRenamePDFonlyRelativePaths.setDisable(!cleanUpRenamePDF.isSelected()));
- cleanUpRenamePDFonlyRelativePaths = new CheckBox(Localization.lang("Rename only PDFs having a relative path"));
- cleanUpUpgradeExternalLinks = new CheckBox(
- Localization.lang("Upgrade external PDF/PS links to use the '%0' field.", FieldName.FILE));
- cleanUpBiblatex = new CheckBox(Localization.lang(
- "Convert to biblatex format (for example, move the value of the 'journal' field to 'journaltitle')"));
- cleanUpBibtex = new CheckBox(Localization.lang(
- "Convert to BibTeX format (for example, move the value of the 'journaltitle' field to 'journal')"));
- Group biblatexConversion = new Group(); // Only make "to Biblatex" or "to BibTeX" selectable
- biblatexConversion.getChildren().add(cleanUpBiblatex);
- biblatexConversion.getChildren().add(cleanUpBibtex);
-
- cleanUpFormatters = new FieldFormatterCleanupsPanel(Localization.lang("Run field formatter:"),
- Cleanups.DEFAULT_SAVE_ACTIONS);
- updateDisplay(cleanupPreset);
+ cleanUpRenamePDFonlyRelativePaths.disableProperty().bind(cleanUpRenamePDF.selectedProperty().not());
- GridPane container = new GridPane();
- container.add(cleanUpDOI, 0, 0);
- container.add(cleanUpUpgradeExternalLinks, 0, 1);
- container.add(cleanUpMovePDF, 0, 2);
- container.add(cleanUpMakePathsRelative, 0, 3);
- container.add(cleanUpRenamePDF, 0, 4);
- String currentPattern = Localization.lang("Filename format pattern").concat(": ");
- currentPattern = currentPattern.concat(Globals.prefs.get(JabRefPreferences.IMPORT_FILENAMEPATTERN));
- container.add(new Label(currentPattern), 0, 5);
- container.add(cleanUpRenamePDFonlyRelativePaths, 0, 6);
- container.add(cleanUpBibtex, 0, 7);
- container.add(cleanUpBiblatex, 0, 8);
- container.add(cleanUpISSN, 0, 9);
- container.add(cleanUpFormatters, 0, 10);
-
- setContent(container);
- setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
+ cleanUpUpgradeExternalLinks.setText(Localization.lang("Upgrade external PDF/PS links to use the '%0' field.", FieldName.FILE));
+
+ cleanUpFormatters = new FieldFormatterCleanupsPanel(Localization.lang("Run field formatter:"), Cleanups.DEFAULT_SAVE_ACTIONS);
+ formatterContainer.getChildren().setAll(cleanUpFormatters);
+
+ String currentPattern = Localization.lang("Filename format pattern")
+ .concat(": ")
+ .concat(filePreferences.getFileNamePattern());
+ cleanupRenamePDFLabel.setText(currentPattern);
+
+ updateDisplay(cleanupPreset);
}
private void updateDisplay(CleanupPreset preset) {
- cleanUpDOI.setSelected(preset.isCleanUpDOI());
+ cleanUpDOI.setSelected(preset.isActive(CleanupPreset.CleanupStep.CLEAN_UP_DOI));
+ cleanUpEprint.setSelected(preset.isActive(CleanupPreset.CleanupStep.CLEANUP_EPRINT));
if (!cleanUpMovePDF.isDisabled()) {
- cleanUpMovePDF.setSelected(preset.isMovePDF());
+ cleanUpMovePDF.setSelected(preset.isActive(CleanupPreset.CleanupStep.MOVE_PDF));
}
- cleanUpMakePathsRelative.setSelected(preset.isMakePathsRelative());
- cleanUpRenamePDF.setSelected(preset.isRenamePDF());
- cleanUpRenamePDFonlyRelativePaths.setSelected(preset.isRenamePdfOnlyRelativePaths());
- cleanUpRenamePDFonlyRelativePaths.setDisable(!cleanUpRenamePDF.isSelected());
- cleanUpUpgradeExternalLinks.setSelected(preset.isCleanUpUpgradeExternalLinks());
- cleanUpBiblatex.setSelected(preset.isConvertToBiblatex());
- cleanUpBibtex.setSelected(preset.isConvertToBibtex());
- cleanUpISSN.setSelected(preset.isCleanUpISSN());
+ cleanUpMakePathsRelative.setSelected(preset.isActive(CleanupPreset.CleanupStep.MAKE_PATHS_RELATIVE));
+ cleanUpRenamePDF.setSelected(preset.isRenamePDFActive());
+ cleanUpRenamePDFonlyRelativePaths.setSelected(preset.isActive(CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS));
+ cleanUpUpgradeExternalLinks.setSelected(preset.isActive(CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS));
+ cleanUpBiblatex.setSelected(preset.isActive(CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX));
+ cleanUpBibtex.setSelected(preset.isActive(CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX));
+ cleanUpISSN.setSelected(preset.isActive(CleanupPreset.CleanupStep.CLEAN_UP_ISSN));
cleanUpFormatters.setValues(preset.getFormatterCleanups());
}
public CleanupPreset getCleanupPreset() {
-
Set activeJobs = EnumSet.noneOf(CleanupPreset.CleanupStep.class);
if (cleanUpMovePDF.isSelected()) {
activeJobs.add(CleanupPreset.CleanupStep.MOVE_PDF);
}
-
if (cleanUpDOI.isSelected()) {
activeJobs.add(CleanupPreset.CleanupStep.CLEAN_UP_DOI);
}
+ if (cleanUpEprint.isSelected()) {
+ activeJobs.add(CleanupPreset.CleanupStep.CLEANUP_EPRINT);
+ }
if (cleanUpISSN.isSelected()) {
activeJobs.add(CleanupPreset.CleanupStep.CLEAN_UP_ISSN);
}
@@ -149,7 +128,6 @@ public CleanupPreset getCleanupPreset() {
activeJobs.add(CleanupPreset.CleanupStep.FIX_FILE_LINKS);
- cleanupPreset = new CleanupPreset(activeJobs, cleanUpFormatters.getFormatterCleanups());
- return cleanupPreset;
+ return new CleanupPreset(activeJobs, cleanUpFormatters.getFormatterCleanups());
}
}
diff --git a/src/main/java/org/jabref/gui/cleanup/FieldFormatterCleanupsPanel.java b/src/main/java/org/jabref/gui/cleanup/FieldFormatterCleanupsPanel.java
index b2aaec4108c..ab544366e0d 100644
--- a/src/main/java/org/jabref/gui/cleanup/FieldFormatterCleanupsPanel.java
+++ b/src/main/java/org/jabref/gui/cleanup/FieldFormatterCleanupsPanel.java
@@ -103,7 +103,7 @@ private void buildLayout() {
actionsList = new ListView<>(actions);
actionsList.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
new ViewModelListCellFactory()
- .withText(action -> action.getFormatter().getName())
+ .withText(action -> action.getField() + ": " + action.getFormatter().getName())
.withTooltip(action -> action.getFormatter().getDescription())
.install(actionsList);
add(actionsList, 1, 1, 3, 1);
diff --git a/src/main/java/org/jabref/gui/groups/GroupAddRemoveDialog.java b/src/main/java/org/jabref/gui/groups/GroupAddRemoveDialog.java
index 9cfc6d32bef..870af219e7b 100644
--- a/src/main/java/org/jabref/gui/groups/GroupAddRemoveDialog.java
+++ b/src/main/java/org/jabref/gui/groups/GroupAddRemoveDialog.java
@@ -4,6 +4,7 @@
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
+import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -57,9 +58,9 @@ public void action() throws Exception {
selection = panel.getSelectedEntries();
final JDialog diag = new JDialog((JFrame) null,
- (add ? (move ? Localization.lang("Move to group") : Localization.lang("Add to group")) : Localization
- .lang("Remove from group")),
- true);
+ (add ? (move ? Localization.lang("Move to group") : Localization.lang("Add to group")) : Localization
+ .lang("Remove from group")),
+ true);
JButton ok = new JButton(Localization.lang("OK"));
JButton cancel = new JButton(Localization.lang("Cancel"));
tree = new JTree(new GroupTreeNodeViewModel(groups.get()));
@@ -166,7 +167,9 @@ private boolean doAddOrRemove() {
GroupTreeNodeViewModel node = (GroupTreeNodeViewModel) path.getLastPathComponent();
if (checkGroupEnable(node)) {
- List entries = Globals.stateManager.getSelectedEntries();
+ //we need to copy the contents of the observable list here, because when removeFromEntries is called,
+ //probably the focus changes to the first entry in the all entries group and thus getSelectedEntries() no longer contains our entry we want to move
+ List entries = new ArrayList<>(Globals.stateManager.getSelectedEntries());
if (move) {
recuriveRemoveFromNode((GroupTreeNodeViewModel) tree.getModel().getRoot(), entries);
@@ -175,7 +178,7 @@ private boolean doAddOrRemove() {
if (add) {
node.addEntriesToGroup(entries);
} else {
- node.removeEntriesFromGroup(Globals.stateManager.getSelectedEntries());
+ node.removeEntriesFromGroup(entries);
}
return true;
@@ -187,7 +190,7 @@ private boolean doAddOrRemove() {
private void recuriveRemoveFromNode(GroupTreeNodeViewModel node, List entries) {
node.removeEntriesFromGroup(entries);
- for (GroupTreeNodeViewModel child: node.getChildren()) {
+ for (GroupTreeNodeViewModel child : node.getChildren()) {
recuriveRemoveFromNode(child, entries);
}
}
@@ -207,7 +210,7 @@ class AddRemoveGroupTreeCellRenderer extends GroupTreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
- boolean leaf, int row, boolean hasFocus) {
+ boolean leaf, int row, boolean hasFocus) {
Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
GroupTreeNodeViewModel node = (GroupTreeNodeViewModel) value;
diff --git a/src/main/java/org/jabref/gui/preferences/GeneralTab.java b/src/main/java/org/jabref/gui/preferences/GeneralTab.java
index 2cb74aca865..d2c27c1a97c 100644
--- a/src/main/java/org/jabref/gui/preferences/GeneralTab.java
+++ b/src/main/java/org/jabref/gui/preferences/GeneralTab.java
@@ -26,6 +26,8 @@
import org.jabref.model.entry.InternalBibtexFields;
import org.jabref.preferences.JabRefPreferences;
+import static javafx.beans.binding.Bindings.not;
+
class GeneralTab extends Pane implements PrefsTab {
private final CheckBox useOwner;
@@ -59,10 +61,7 @@ public GeneralTab(DialogService dialogService, JabRefPreferences prefs) {
updateTimeStamp = new CheckBox(Localization.lang("Update timestamp on modification"));
useTimeStamp = new CheckBox(Localization.lang("Mark new entries with addition date") + ". "
+ Localization.lang("Date format") + ':');
- if (!useTimeStamp.isSelected()) {
- updateTimeStamp.setDisable(true);
- }
- useTimeStamp.setOnAction(e->updateTimeStamp.setDisable(!useTimeStamp.isSelected()));
+ updateTimeStamp.disableProperty().bind(not(useTimeStamp.selectedProperty()));
overwriteOwner = new CheckBox(Localization.lang("Overwrite"));
overwriteTimeStamp = new CheckBox(Localization.lang("If a pasted or imported entry already has the field set, overwrite."));
enforceLegalKeys = new CheckBox(Localization.lang("Enforce legal characters in BibTeX keys"));
@@ -140,7 +139,6 @@ public void setValues() {
useTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP));
overwriteTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP));
updateTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.UPDATE_TIMESTAMP));
- updateTimeStamp.setSelected(useTimeStamp.isSelected());
enforceLegalKeys.setSelected(prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY));
shouldCollectTelemetry.setSelected(prefs.shouldCollectTelemetry());
memoryStick.setSelected(prefs.getBoolean(JabRefPreferences.MEMORY_STICK_MODE));
@@ -182,9 +180,9 @@ public void storeSettings() {
// Update name of the time stamp field based on preferences
InternalBibtexFields.updateTimeStampField(prefs.get(JabRefPreferences.TIME_STAMP_FIELD));
prefs.setDefaultEncoding(encodings.getValue());
- prefs.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, biblatexMode.getValue().equals(BibDatabaseMode.BIBLATEX));
+ prefs.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, biblatexMode.getValue() == BibDatabaseMode.BIBLATEX);
- if (!languageSelection.getValue().equals(prefs.getLanguage())) {
+ if (languageSelection.getValue() != prefs.getLanguage()) {
prefs.setLanguage(languageSelection.getValue());
Localization.setLanguage(languageSelection.getValue());
diff --git a/src/main/java/org/jabref/logic/cleanup/CleanupPreset.java b/src/main/java/org/jabref/logic/cleanup/CleanupPreset.java
index 06db606b591..a326dc6eed8 100644
--- a/src/main/java/org/jabref/logic/cleanup/CleanupPreset.java
+++ b/src/main/java/org/jabref/logic/cleanup/CleanupPreset.java
@@ -1,6 +1,7 @@
package org.jabref.logic.cleanup;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
@@ -12,7 +13,6 @@ public class CleanupPreset {
private final Set activeJobs;
private final FieldFormatterCleanups formatterCleanups;
-
public CleanupPreset(Set activeJobs) {
this(activeJobs, new FieldFormatterCleanups(false, new ArrayList<>()));
}
@@ -30,46 +30,14 @@ public CleanupPreset(Set activeJobs, FieldFormatterCleanups formatt
this.formatterCleanups = Objects.requireNonNull(formatterCleanups);
}
- public boolean isCleanUpUpgradeExternalLinks() {
- return isActive(CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS);
- }
-
- public boolean isCleanUpDOI() {
- return isActive(CleanupStep.CLEAN_UP_DOI);
- }
-
- public boolean isCleanUpISSN() {
- return isActive(CleanupStep.CLEAN_UP_ISSN);
- }
-
- public boolean isFixFileLinks() {
- return isActive(CleanupStep.FIX_FILE_LINKS);
- }
-
- public boolean isMovePDF() {
- return isActive(CleanupStep.MOVE_PDF);
+ public Set getActiveJobs() {
+ return Collections.unmodifiableSet(activeJobs);
}
- public boolean isMakePathsRelative() {
- return isActive(CleanupStep.MAKE_PATHS_RELATIVE);
- }
-
- public boolean isRenamePDF() {
+ public boolean isRenamePDFActive() {
return isActive(CleanupStep.RENAME_PDF) || isActive(CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS);
}
- public boolean isConvertToBiblatex() {
- return isActive(CleanupStep.CONVERT_TO_BIBLATEX);
- }
-
- public boolean isConvertToBibtex() {
- return isActive(CleanupStep.CONVERT_TO_BIBTEX);
- }
-
- public boolean isRenamePdfOnlyRelativePaths() {
- return isActive(CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS);
- }
-
public Boolean isActive(CleanupStep step) {
return activeJobs.contains(step);
}
@@ -83,6 +51,7 @@ public enum CleanupStep {
* Removes the http://... for each DOI. Moves DOIs from URL and NOTE filed to DOI field.
*/
CLEAN_UP_DOI,
+ CLEANUP_EPRINT,
MAKE_PATHS_RELATIVE,
RENAME_PDF,
RENAME_PDF_ONLY_RELATIVE_PATHS,
@@ -102,5 +71,4 @@ public enum CleanupStep {
FIX_FILE_LINKS,
CLEAN_UP_ISSN
}
-
}
diff --git a/src/main/java/org/jabref/logic/cleanup/CleanupWorker.java b/src/main/java/org/jabref/logic/cleanup/CleanupWorker.java
index c07650436d1..1831064a286 100644
--- a/src/main/java/org/jabref/logic/cleanup/CleanupWorker.java
+++ b/src/main/java/org/jabref/logic/cleanup/CleanupWorker.java
@@ -37,38 +37,43 @@ public List cleanup(CleanupPreset preset, BibEntry entry) {
private List determineCleanupActions(CleanupPreset preset) {
List jobs = new ArrayList<>();
- if (preset.isConvertToBiblatex()) {
- jobs.add(new ConvertToBiblatexCleanup());
- }
- if (preset.isConvertToBibtex()) {
- jobs.add(new ConvertToBibtexCleanup());
+ for (CleanupPreset.CleanupStep action : preset.getActiveJobs()) {
+ jobs.add(toJob(action));
}
+
if (preset.getFormatterCleanups().isEnabled()) {
jobs.addAll(preset.getFormatterCleanups().getConfiguredActions());
}
- if (preset.isCleanUpUpgradeExternalLinks()) {
- jobs.add(new UpgradePdfPsToFileCleanup());
- }
- if (preset.isCleanUpDOI()) {
- jobs.add(new DoiCleanup());
- }
- if (preset.isCleanUpISSN()) {
- jobs.add(new ISSNCleanup());
- }
- if (preset.isFixFileLinks()) {
- jobs.add(new FileLinksCleanup());
- }
- if (preset.isMovePDF()) {
- jobs.add(new MoveFilesCleanup(databaseContext, filePreferences));
- }
- if (preset.isMakePathsRelative()) {
- jobs.add(new RelativePathsCleanup(databaseContext, filePreferences));
- }
- if (preset.isRenamePDF()) {
- RenamePdfCleanup cleaner = new RenamePdfCleanup(preset.isRenamePdfOnlyRelativePaths(), databaseContext, filePreferences);
- jobs.add(cleaner);
- }
return jobs;
}
+
+ private CleanupJob toJob(CleanupPreset.CleanupStep action) {
+ switch (action) {
+ case CLEAN_UP_DOI:
+ return new DoiCleanup();
+ case CLEANUP_EPRINT:
+ return new EprintCleanup();
+ case MAKE_PATHS_RELATIVE:
+ return new RelativePathsCleanup(databaseContext, filePreferences);
+ case RENAME_PDF:
+ return new RenamePdfCleanup(false, databaseContext, filePreferences);
+ case RENAME_PDF_ONLY_RELATIVE_PATHS:
+ return new RenamePdfCleanup(true, databaseContext, filePreferences);
+ case CLEAN_UP_UPGRADE_EXTERNAL_LINKS:
+ return new UpgradePdfPsToFileCleanup();
+ case CONVERT_TO_BIBLATEX:
+ return new ConvertToBiblatexCleanup();
+ case CONVERT_TO_BIBTEX:
+ return new ConvertToBibtexCleanup();
+ case MOVE_PDF:
+ return new MoveFilesCleanup(databaseContext, filePreferences);
+ case FIX_FILE_LINKS:
+ return new FileLinksCleanup();
+ case CLEAN_UP_ISSN:
+ return new ISSNCleanup();
+ default:
+ throw new UnsupportedOperationException(action.name());
+ }
+ }
}
diff --git a/src/main/java/org/jabref/logic/cleanup/DoiCleanup.java b/src/main/java/org/jabref/logic/cleanup/DoiCleanup.java
index 03417e00e3e..9bee454b409 100644
--- a/src/main/java/org/jabref/logic/cleanup/DoiCleanup.java
+++ b/src/main/java/org/jabref/logic/cleanup/DoiCleanup.java
@@ -55,14 +55,9 @@ public List cleanup(BibEntry entry) {
Optional doi = entry.getField(field).flatMap(DOI::parse);
if (doi.isPresent()) {
- // update Doi
- String oldValue = entry.getField(FieldName.DOI).orElse(null);
- String newValue = doi.get().getDOI();
-
- entry.setField(FieldName.DOI, newValue);
-
- FieldChange change = new FieldChange(entry, FieldName.DOI, oldValue, newValue);
- changes.add(change);
+ // Update Doi
+ Optional change = entry.setField(FieldName.DOI, doi.get().getDOI());
+ change.ifPresent(changes::add);
removeFieldValue(entry, field, changes);
}
diff --git a/src/main/java/org/jabref/logic/cleanup/EprintCleanup.java b/src/main/java/org/jabref/logic/cleanup/EprintCleanup.java
new file mode 100644
index 00000000000..973fc1d0705
--- /dev/null
+++ b/src/main/java/org/jabref/logic/cleanup/EprintCleanup.java
@@ -0,0 +1,52 @@
+package org.jabref.logic.cleanup;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import org.jabref.model.FieldChange;
+import org.jabref.model.cleanup.CleanupJob;
+import org.jabref.model.entry.BibEntry;
+import org.jabref.model.entry.FieldName;
+import org.jabref.model.entry.identifier.ArXivIdentifier;
+
+/**
+ * Formats the DOI (e.g. removes http part) and also moves DOIs from note, url or ee field to the doi field.
+ */
+public class EprintCleanup implements CleanupJob {
+
+ @Override
+ public List cleanup(BibEntry entry) {
+
+ List changes = new ArrayList<>();
+
+ for (String field : Arrays.asList(FieldName.URL, FieldName.JOURNAL, FieldName.JOURNALTITLE, FieldName.NOTE)) {
+ Optional arXivIdentifier = entry.getField(field).flatMap(ArXivIdentifier::parse);
+
+ if (arXivIdentifier.isPresent()) {
+ entry.setField(FieldName.EPRINT, arXivIdentifier.get().getNormalized())
+ .ifPresent(changes::add);
+
+ entry.setField(FieldName.EPRINTTYPE, "arxiv")
+ .ifPresent(changes::add);
+
+ arXivIdentifier.get().getClassification().ifPresent(classification ->
+ entry.setField(FieldName.EPRINTCLASS, classification)
+ .ifPresent(changes::add)
+ );
+
+ entry.clearField(field)
+ .ifPresent(changes::add);
+
+ if (field.equals(FieldName.URL)) {
+ // If we clear the URL field, we should also clear the URL-date field
+ entry.clearField(FieldName.URLDATE)
+ .ifPresent(changes::add);
+ }
+ }
+ }
+
+ return changes;
+ }
+}
diff --git a/src/main/java/org/jabref/logic/importer/WebFetchers.java b/src/main/java/org/jabref/logic/importer/WebFetchers.java
index 3329a6215f2..c06849201f3 100644
--- a/src/main/java/org/jabref/logic/importer/WebFetchers.java
+++ b/src/main/java/org/jabref/logic/importer/WebFetchers.java
@@ -119,6 +119,7 @@ public static List getEntryBasedFetchers(ImportFormatPreferen
ArrayList list = new ArrayList<>();
list.add(new AstrophysicsDataSystem(importFormatPreferences));
list.add(new DoiFetcher(importFormatPreferences));
+ list.add(new IsbnFetcher(importFormatPreferences));
list.add(new MathSciNet(importFormatPreferences));
list.add(new CrossRef());
list.sort(Comparator.comparing(WebFetcher::getName));
diff --git a/src/main/java/org/jabref/logic/importer/fetcher/IsbnFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/IsbnFetcher.java
index 343d5e3e8cd..c1d13f862e9 100644
--- a/src/main/java/org/jabref/logic/importer/fetcher/IsbnFetcher.java
+++ b/src/main/java/org/jabref/logic/importer/fetcher/IsbnFetcher.java
@@ -1,23 +1,32 @@
package org.jabref.logic.importer.fetcher;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
+import java.util.Collections;
+import java.util.List;
import java.util.Optional;
+import org.jabref.logic.help.HelpFile;
+import org.jabref.logic.importer.EntryBasedFetcher;
import org.jabref.logic.importer.FetcherException;
+import org.jabref.logic.importer.IdBasedFetcher;
import org.jabref.logic.importer.ImportFormatPreferences;
import org.jabref.model.entry.BibEntry;
+import org.jabref.model.entry.FieldName;
+import org.jabref.model.util.OptionalUtil;
import org.jsoup.helper.StringUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Fetcher for ISBN trying ebook.de first and then chimbori.com
*/
-public class IsbnFetcher extends AbstractIsbnFetcher {
+public class IsbnFetcher implements EntryBasedFetcher, IdBasedFetcher {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(IsbnFetcher.class);
+ protected final ImportFormatPreferences importFormatPreferences;
public IsbnFetcher(ImportFormatPreferences importFormatPreferences) {
- super(importFormatPreferences);
+ this.importFormatPreferences = importFormatPreferences;
}
@Override
@@ -25,12 +34,9 @@ public String getName() {
return "ISBN";
}
- /**
- * Method never used
- */
@Override
- public URL getURLForID(String identifier) throws URISyntaxException, MalformedURLException, FetcherException {
- return null;
+ public Optional getHelpPage() {
+ return Optional.of(HelpFile.FETCHER_ISBN);
}
@Override
@@ -39,8 +45,6 @@ public Optional performSearchById(String identifier) throws FetcherExc
return Optional.empty();
}
- this.ensureThatIsbnIsValid(identifier);
-
IsbnViaEbookDeFetcher isbnViaEbookDeFetcher = new IsbnViaEbookDeFetcher(importFormatPreferences);
Optional bibEntry = isbnViaEbookDeFetcher.performSearchById(identifier);
// nothing found at ebook.de, try chimbori.com
@@ -55,8 +59,12 @@ public Optional performSearchById(String identifier) throws FetcherExc
}
@Override
- public void doPostCleanup(BibEntry entry) {
- // no action needed
+ public List performSearch(BibEntry entry) throws FetcherException {
+ Optional isbn = entry.getField(FieldName.ISBN);
+ if (isbn.isPresent()) {
+ return OptionalUtil.toList(performSearchById(isbn.get()));
+ } else {
+ return Collections.emptyList();
+ }
}
-
}
diff --git a/src/main/java/org/jabref/logic/importer/fetcher/MathSciNet.java b/src/main/java/org/jabref/logic/importer/fetcher/MathSciNet.java
index 603e84eac60..774d4155c00 100644
--- a/src/main/java/org/jabref/logic/importer/fetcher/MathSciNet.java
+++ b/src/main/java/org/jabref/logic/importer/fetcher/MathSciNet.java
@@ -8,6 +8,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -52,6 +53,12 @@ public String getName() {
*/
@Override
public URL getURLForEntry(BibEntry entry) throws URISyntaxException, MalformedURLException, FetcherException {
+ Optional mrNumberInEntry = entry.getField(FieldName.MR_NUMBER);
+ if (mrNumberInEntry.isPresent()) {
+ // We are lucky and already know the id, so use it instead
+ return getURLForID(mrNumberInEntry.get());
+ }
+
URIBuilder uriBuilder = new URIBuilder("https://mathscinet.ams.org/mrlookup");
uriBuilder.addParameter("format", "bibtex");
diff --git a/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java b/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java
index 8b9287d3e2b..ba01e496518 100644
--- a/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java
+++ b/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java
@@ -4,20 +4,72 @@
import java.net.URISyntaxException;
import java.util.Objects;
import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.jabref.model.entry.FieldName;
+/**
+ * Identifier for the arXiv. See https://arxiv.org/help/arxiv_identifier
+ */
public class ArXivIdentifier implements Identifier {
private final String identifier;
+ private final String classification;
ArXivIdentifier(String identifier) {
- this.identifier = Objects.requireNonNull(identifier).trim();
+ this(identifier, "");
+ }
+
+ ArXivIdentifier(String identifier, String classification) {
+ this.identifier = identifier.trim();
+ this.classification = classification.trim();
}
public static Optional parse(String value) {
- String identifier = value.replaceAll("(?i)arxiv:", "");
- return Optional.of(new ArXivIdentifier(identifier));
+ Pattern identifierPattern = Pattern.compile("(arxiv|arXiv)?\\s?:?\\s?(?\\d{4}.\\d{4,5}(v\\d+)?)\\s?(\\[(?\\S+)\\])?");
+ Matcher identifierMatcher = identifierPattern.matcher(value);
+ if (identifierMatcher.matches()) {
+ String id = identifierMatcher.group("id");
+ String classification = identifierMatcher.group("classification");
+ if (classification == null) {
+ classification = "";
+ }
+ return Optional.of(new ArXivIdentifier(id, classification));
+ }
+
+ Pattern oldIdentifierPattern = Pattern.compile("(arxiv|arXiv)?\\s?:?\\s?(?(?[a-z\\-]+(\\.[A-Z]{2})?)/\\d{7})");
+ Matcher oldIdentifierMatcher = oldIdentifierPattern.matcher(value);
+ if (oldIdentifierMatcher.matches()) {
+ String id = oldIdentifierMatcher.group("id");
+ String classification = oldIdentifierMatcher.group("classification");
+ return Optional.of(new ArXivIdentifier(id, classification));
+ }
+
+ Pattern urlPattern = Pattern.compile("(http://arxiv.org/abs/)(?\\S+)");
+ Matcher urlMatcher = urlPattern.matcher(value);
+ if (urlMatcher.matches()) {
+ String id = urlMatcher.group("id");
+ return Optional.of(new ArXivIdentifier(id));
+ }
+
+ return Optional.empty();
+ }
+
+ public Optional getClassification() {
+ if (classification.isEmpty()) {
+ return Optional.empty();
+ } else {
+ return Optional.of(classification);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ArXivIdentifier{" +
+ "identifier='" + identifier + '\'' +
+ ", classification='" + classification + '\'' +
+ '}';
}
@Override
@@ -25,18 +77,18 @@ public boolean equals(Object o) {
if (this == o) {
return true;
}
- if ((o == null) || (getClass() != o.getClass())) {
+ if (o == null || getClass() != o.getClass()) {
return false;
}
ArXivIdentifier that = (ArXivIdentifier) o;
-
- return identifier.equals(that.identifier);
+ return Objects.equals(identifier, that.identifier) &&
+ Objects.equals(classification, that.classification);
}
@Override
public int hashCode() {
- return identifier.hashCode();
+ return Objects.hash(identifier, classification);
}
@Override
@@ -49,11 +101,6 @@ public String getNormalized() {
return identifier;
}
- @Override
- public String toString() {
- return "ArXivIdentifier [identifier=" + identifier + "]";
- }
-
@Override
public Optional getExternalURI() {
try {
diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java
index 45332334475..c2a0d45ed65 100644
--- a/src/main/java/org/jabref/preferences/JabRefPreferences.java
+++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java
@@ -286,16 +286,7 @@ public class JabRefPreferences implements PreferencesService {
public static final String USE_UNIT_FORMATTER_ON_SEARCH = "useUnitFormatterOnSearch";
public static final String USE_CASE_KEEPER_ON_SEARCH = "useCaseKeeperOnSearch";
public static final String ASK_AUTO_NAMING_PDFS_AGAIN = "AskAutoNamingPDFsAgain";
- public static final String CLEANUP_DOI = "CleanUpDOI";
- public static final String CLEANUP_ISSN = "CleanUpISSN";
- public static final String CLEANUP_MOVE_PDF = "CleanUpMovePDF";
- public static final String CLEANUP_MAKE_PATHS_RELATIVE = "CleanUpMakePathsRelative";
- public static final String CLEANUP_RENAME_PDF = "CleanUpRenamePDF";
- public static final String CLEANUP_RENAME_PDF_ONLY_RELATIVE_PATHS = "CleanUpRenamePDFonlyRelativePaths";
- public static final String CLEANUP_UPGRADE_EXTERNAL_LINKS = "CleanUpUpgradeExternalLinks";
- public static final String CLEANUP_CONVERT_TO_BIBLATEX = "CleanUpConvertToBiblatex";
- public static final String CLEANUP_CONVERT_TO_BIBTEX = "CleanUpConvertToBibtex";
- public static final String CLEANUP_FIX_FILE_LINKS = "CleanUpFixFileLinks";
+ public static final String CLEANUP = "CleanUp";
public static final String CLEANUP_FORMATTERS = "CleanUpFormatters";
public static final String IMPORT_DEFAULT_PDF_IMPORT_STYLE = "importDefaultPDFimportStyle";
public static final String IMPORT_ALWAYSUSE = "importAlwaysUsePDFImportStyle";
@@ -887,25 +878,16 @@ private static Optional getNextUnit(Reader data) throws IOException {
private static void insertDefaultCleanupPreset(Map storage) {
EnumSet deactivatedJobs = EnumSet.of(
- CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS,
- CleanupPreset.CleanupStep.MOVE_PDF,
- CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS,
- CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX,
- CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX);
-
- CleanupPreset preset = new CleanupPreset(EnumSet.complementOf(deactivatedJobs), Cleanups.DEFAULT_SAVE_ACTIONS);
-
- storage.put(CLEANUP_DOI, preset.isCleanUpDOI());
- storage.put(CLEANUP_ISSN, preset.isCleanUpISSN());
- storage.put(CLEANUP_MOVE_PDF, preset.isMovePDF());
- storage.put(CLEANUP_MAKE_PATHS_RELATIVE, preset.isMakePathsRelative());
- storage.put(CLEANUP_RENAME_PDF, preset.isRenamePDF());
- storage.put(CLEANUP_RENAME_PDF_ONLY_RELATIVE_PATHS, preset.isRenamePdfOnlyRelativePaths());
- storage.put(CLEANUP_UPGRADE_EXTERNAL_LINKS, preset.isCleanUpUpgradeExternalLinks());
- storage.put(CLEANUP_CONVERT_TO_BIBLATEX, preset.isConvertToBiblatex());
- storage.put(CLEANUP_CONVERT_TO_BIBTEX, preset.isConvertToBibtex());
- storage.put(CLEANUP_FIX_FILE_LINKS, preset.isFixFileLinks());
- storage.put(CLEANUP_FORMATTERS, convertListToString(preset.getFormatterCleanups().getAsStringList(OS.NEWLINE)));
+ CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS,
+ CleanupPreset.CleanupStep.MOVE_PDF,
+ CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS,
+ CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX,
+ CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX);
+
+ for (CleanupPreset.CleanupStep action : EnumSet.allOf(CleanupPreset.CleanupStep.class)) {
+ storage.put(JabRefPreferences.CLEANUP + action.name(), !deactivatedJobs.contains(action));
+ }
+ storage.put(CLEANUP_FORMATTERS, convertListToString(Cleanups.DEFAULT_SAVE_ACTIONS.getAsStringList(OS.NEWLINE)));
}
public EntryEditorPreferences getEntryEditorPreferences() {
@@ -1689,57 +1671,23 @@ public CleanupPreferences getCleanupPreferences(JournalAbbreviationLoader journa
public CleanupPreset getCleanupPreset() {
Set activeJobs = EnumSet.noneOf(CleanupPreset.CleanupStep.class);
- if (this.getBoolean(JabRefPreferences.CLEANUP_DOI)) {
- activeJobs.add(CleanupPreset.CleanupStep.CLEAN_UP_DOI);
- }
- if (this.getBoolean(JabRefPreferences.CLEANUP_ISSN)) {
- activeJobs.add(CleanupPreset.CleanupStep.CLEAN_UP_ISSN);
- }
- if (this.getBoolean(JabRefPreferences.CLEANUP_MOVE_PDF)) {
- activeJobs.add(CleanupPreset.CleanupStep.MOVE_PDF);
- }
- if (this.getBoolean(JabRefPreferences.CLEANUP_MAKE_PATHS_RELATIVE)) {
- activeJobs.add(CleanupPreset.CleanupStep.MAKE_PATHS_RELATIVE);
- }
- if (this.getBoolean(JabRefPreferences.CLEANUP_RENAME_PDF)) {
- activeJobs.add(CleanupPreset.CleanupStep.RENAME_PDF);
- }
- if (this.getBoolean(JabRefPreferences.CLEANUP_RENAME_PDF_ONLY_RELATIVE_PATHS)) {
- activeJobs.add(CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS);
- }
- if (this.getBoolean(JabRefPreferences.CLEANUP_UPGRADE_EXTERNAL_LINKS)) {
- activeJobs.add(CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS);
- }
- if (this.getBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBLATEX)) {
- activeJobs.add(CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX);
- }
- if (this.getBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBTEX)) {
- activeJobs.add(CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX);
- }
- if (this.getBoolean(JabRefPreferences.CLEANUP_FIX_FILE_LINKS)) {
- activeJobs.add(CleanupPreset.CleanupStep.FIX_FILE_LINKS);
+ for (CleanupPreset.CleanupStep action : EnumSet.allOf(CleanupPreset.CleanupStep.class)) {
+ if (getBoolean(JabRefPreferences.CLEANUP + action.name())) {
+ activeJobs.add(action);
+ }
}
- FieldFormatterCleanups formatterCleanups = Cleanups.parse(
- this.getStringList(JabRefPreferences.CLEANUP_FORMATTERS));
+ FieldFormatterCleanups formatterCleanups = Cleanups.parse(getStringList(JabRefPreferences.CLEANUP_FORMATTERS));
return new CleanupPreset(activeJobs, formatterCleanups);
}
public void setCleanupPreset(CleanupPreset cleanupPreset) {
- this.putBoolean(JabRefPreferences.CLEANUP_DOI, cleanupPreset.isActive(CleanupPreset.CleanupStep.CLEAN_UP_DOI));
- this.putBoolean(JabRefPreferences.CLEANUP_ISSN, cleanupPreset.isActive(CleanupPreset.CleanupStep.CLEAN_UP_ISSN));
- this.putBoolean(JabRefPreferences.CLEANUP_MOVE_PDF, cleanupPreset.isActive(CleanupPreset.CleanupStep.MOVE_PDF));
- this.putBoolean(JabRefPreferences.CLEANUP_MAKE_PATHS_RELATIVE, cleanupPreset.isActive(CleanupPreset.CleanupStep.MAKE_PATHS_RELATIVE));
- this.putBoolean(JabRefPreferences.CLEANUP_RENAME_PDF, cleanupPreset.isActive(CleanupPreset.CleanupStep.RENAME_PDF));
- this.putBoolean(JabRefPreferences.CLEANUP_RENAME_PDF_ONLY_RELATIVE_PATHS,
- cleanupPreset.isActive(CleanupPreset.CleanupStep.RENAME_PDF_ONLY_RELATIVE_PATHS));
- this.putBoolean(JabRefPreferences.CLEANUP_UPGRADE_EXTERNAL_LINKS,
- cleanupPreset.isActive(CleanupPreset.CleanupStep.CLEAN_UP_UPGRADE_EXTERNAL_LINKS));
- this.putBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBLATEX, cleanupPreset.isActive(CleanupPreset.CleanupStep.CONVERT_TO_BIBLATEX));
- this.putBoolean(JabRefPreferences.CLEANUP_CONVERT_TO_BIBTEX, cleanupPreset.isActive(CleanupPreset.CleanupStep.CONVERT_TO_BIBTEX));
- this.putBoolean(JabRefPreferences.CLEANUP_FIX_FILE_LINKS, cleanupPreset.isActive(CleanupPreset.CleanupStep.FIX_FILE_LINKS));
- this.putStringList(JabRefPreferences.CLEANUP_FORMATTERS, cleanupPreset.getFormatterCleanups().getAsStringList(OS.NEWLINE));
+ for (CleanupPreset.CleanupStep action : EnumSet.allOf(CleanupPreset.CleanupStep.class)) {
+ putBoolean(JabRefPreferences.CLEANUP + action.name(), cleanupPreset.isActive(action));
+ }
+
+ putStringList(JabRefPreferences.CLEANUP_FORMATTERS, cleanupPreset.getFormatterCleanups().getAsStringList(OS.NEWLINE));
}
public RemotePreferences getRemotePreferences() {
diff --git a/src/main/resources/l10n/JabRef_de.properties b/src/main/resources/l10n/JabRef_de.properties
index f266b945a78..74cc9c60665 100644
--- a/src/main/resources/l10n/JabRef_de.properties
+++ b/src/main/resources/l10n/JabRef_de.properties
@@ -32,6 +32,7 @@ Accept=Übernehmen
Accept\ change=Änderung akzeptieren
+Accept\ recommendations\ from\ Mr.\ DLib=Empfehlungen von Mr. DLib akzeptieren
Action=Aktion
@@ -159,6 +160,7 @@ Clear\ fields=Felder löschen
Close=Schließen
+Close\ entry=Eintrag schließen
Close\ dialog=Dialog schließen
@@ -215,6 +217,7 @@ Could\ not\ run\ the\ 'vim'\ program.=Das Programm 'vim' konnte nicht gestartet
Could\ not\ save\ file.=Datei konnte nicht gespeichert werden.
Character\ encoding\ '%0'\ is\ not\ supported.=Die Zeichenkodierung '%0' wird nicht unterstützt.
+Create\ custom\ fields\ for\ each\ BibTeX\ entry=Erstellen Sie benutzerdefinierte Felder für jeden BibTeX-Eintrag
crossreferenced\ entries\ included=Inklusive querverwiesenen Einträgen
@@ -325,6 +328,7 @@ Dynamically\ group\ entries\ by\ a\ free-form\ search\ expression=Dynamisches Gr
Dynamically\ group\ entries\ by\ searching\ a\ field\ for\ a\ keyword=Dynamisches Gruppieren der Einträge anhand eines Stichworts in einem Feld
+Each\ line\ must\ be\ of\ the\ following\ form=Jede Zeile muss das folgende Format aufweisen
Edit=Bearbeiten
@@ -376,6 +380,7 @@ Error\ occurred\ when\ parsing\ entry=Fehler beim Analysieren des Eintrags
Error\ opening\ file=Fehler beim Öffnen der Datei
+Error\ while\ fetching\ from\ Mr.DLib.=Fehler beim Abrufen von Mr.DLib.
Error\ while\ writing=Fehler beim Schreiben
@@ -452,6 +457,7 @@ Float=Oben einsortieren
for=für
+Format\:\ Tab\:field;field;...\ (e.g.\ General\:url;pdf;note...)=Format\: Tab\:Feld;Feld\:... (z. B. General\:url;pdf\:note...)
Format\ of\ author\ and\ editor\ names=Format der Autoren- und Hrsg.-Namen
Format\ string=Formatier-Ausdruck
@@ -463,9 +469,11 @@ found\ in\ AUX\ file=gefundene Schlüssel in AUX Datei
Full\ name=Kompletter Name
+Further\ information\ about\ Mr\ DLib.\ for\ JabRef\ users.=Weitere Informationen über Mr. DLib für JabRef Benutzer.
General=Allgemein
+General\ Fields=Allgemeine Felder
Generate=Erzeugen
@@ -557,6 +565,7 @@ Independent\ group\:\ When\ selected,\ view\ only\ this\ group's\ entries=Unabh
Work\ options=Bearbeitungsoptionen
+I\ Agree=Ich stimme zu
Insert=einfügen
@@ -654,6 +663,7 @@ Move\ up=Nach oben
Moved\ group\ "%0".=Gruppe "%0" verschoben.
+Mr.\ DLib\ is\ an\ external\ service\ which\ provides\ article\ recommendations\ based\ on\ the\ currently\ selected\ entry.\ Data\ about\ the\ selected\ entry\ must\ be\ sent\ to\ Mr.\ DLib\ in\ order\ to\ provide\ these\ recommendations.\ Do\ you\ agree\ that\ this\ data\ may\ be\ sent?=Mr. DLib ist ein externer Service der Artikelempfehlungen basierend auf den aktuell ausgewählten Eintrag anbietet. Daten über den ausgewählten Eintrag müssen an Mr. DLib gesendet werden, um diese Empfehlungen anzubieten. Sind Sie einverstanden, dass diese Daten gesendet werden dürfen?
Name=Name
@@ -786,6 +796,7 @@ Please\ enter\ the\ string's\ label=Geben Sie bitte den Namen des Strings ein.
Please\ select\ an\ importer.=Bitte Importer auswählen.
+Please\ restart\ JabRef\ for\ preferences\ to\ take\ effect.=Bitte starten Sie die Anwendung neu, damit die Änderungen wirksam werden.
Possible\ duplicate\ entries=Mögliche doppelte Einträge
@@ -875,6 +886,9 @@ Removed\ string=String gelöscht
Renamed\ string=String umbenannt
Replace=Ersetzen
+Replace\ With\:=Ersetzen durch\:
+Limit\ to\ Selected\ Entries=Auf ausgewählten Einträge begrenzen
+Limit\ to\ Fields=Auf folgende Felder begrenzen
Replace\ (regular\ expression)=Ersetzen (regulärer Ausdruck)
diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties
index f7b09efbf18..46918dfc565 100644
--- a/src/main/resources/l10n/JabRef_en.properties
+++ b/src/main/resources/l10n/JabRef_en.properties
@@ -2229,7 +2229,7 @@ Keystore\:=Keystore\:
Password\:=Password\:
Remember\ Password=Remember Password
Use\ SSL=Use SSL
-
+Move\ preprint\ information\ from\ 'URL'\ and\ 'journal'\ field\ to\ the\ 'eprint'\ field=Move preprint information from 'URL' and 'journal' field to the 'eprint' field
Default\ drag\ &\ drop\ action=Default drag & drop action
Copy\ file\ to\ default\ file\ folder=Copy file to default file folder
Link\ file\ (without\ copying)=Link file (without copying)
diff --git a/src/test/java/org/jabref/logic/cleanup/EprintCleanupTest.java b/src/test/java/org/jabref/logic/cleanup/EprintCleanupTest.java
new file mode 100644
index 00000000000..2ad3bebfb36
--- /dev/null
+++ b/src/test/java/org/jabref/logic/cleanup/EprintCleanupTest.java
@@ -0,0 +1,29 @@
+package org.jabref.logic.cleanup;
+
+import org.jabref.model.entry.BibEntry;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class EprintCleanupTest {
+
+ @Test
+ void cleanupCompleteEntry() {
+ BibEntry input = new BibEntry()
+ .withField("journaltitle", "arXiv:1502.05795 [math]")
+ .withField("note", "arXiv: 1502.05795")
+ .withField("url", "http://arxiv.org/abs/1502.05795")
+ .withField("urldate", "2018-09-07TZ");
+
+ BibEntry expected = new BibEntry()
+ .withField("eprint", "1502.05795")
+ .withField("eprintclass", "math")
+ .withField("eprinttype", "arxiv");
+
+ EprintCleanup cleanup = new EprintCleanup();
+ cleanup.cleanup(input);
+
+ assertEquals(expected, input);
+ }
+}
diff --git a/src/test/java/org/jabref/logic/importer/fetcher/IsbnFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/IsbnFetcherTest.java
index ed140ff3dc8..b6b34971a17 100644
--- a/src/test/java/org/jabref/logic/importer/fetcher/IsbnFetcherTest.java
+++ b/src/test/java/org/jabref/logic/importer/fetcher/IsbnFetcherTest.java
@@ -1,5 +1,7 @@
package org.jabref.logic.importer.fetcher;
+import java.util.Collections;
+import java.util.List;
import java.util.Optional;
import org.jabref.logic.importer.FetcherException;
@@ -18,13 +20,13 @@
import static org.mockito.Mockito.mock;
@FetcherTest
-public class IsbnFetcherTest {
+class IsbnFetcherTest {
private IsbnFetcher fetcher;
private BibEntry bibEntry;
@BeforeEach
- public void setUp() {
+ void setUp() {
fetcher = new IsbnFetcher(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS));
bibEntry = new BibEntry();
@@ -41,54 +43,62 @@ public void setUp() {
}
@Test
- public void testName() {
+ void testName() {
assertEquals("ISBN", fetcher.getName());
}
@Test
- public void testHelpPage() {
+ void testHelpPage() {
assertEquals("ISBNtoBibTeX", fetcher.getHelpPage().get().getPageName());
}
@Test
- public void searchByIdSuccessfulWithShortISBN() throws FetcherException {
+ void searchByIdSuccessfulWithShortISBN() throws FetcherException {
Optional fetchedEntry = fetcher.performSearchById("0134685997");
assertEquals(Optional.of(bibEntry), fetchedEntry);
}
@Test
- public void searchByIdSuccessfulWithLongISBN() throws FetcherException {
+ void searchByIdSuccessfulWithLongISBN() throws FetcherException {
Optional fetchedEntry = fetcher.performSearchById("9780134685991");
assertEquals(Optional.of(bibEntry), fetchedEntry);
}
@Test
- public void searchByIdReturnsEmptyWithEmptyISBN() throws FetcherException {
+ void searchByIdReturnsEmptyWithEmptyISBN() throws FetcherException {
Optional fetchedEntry = fetcher.performSearchById("");
assertEquals(Optional.empty(), fetchedEntry);
}
@Test
- public void searchByIdThrowsExceptionForShortInvalidISBN() {
+ void searchByIdThrowsExceptionForShortInvalidISBN() {
assertThrows(FetcherException.class, () -> fetcher.performSearchById("123456789"));
}
@Test
- public void searchByIdThrowsExceptionForLongInvalidISB() {
+ void searchByIdThrowsExceptionForLongInvalidISB() {
assertThrows(FetcherException.class, () -> fetcher.performSearchById("012345678910"));
}
@Test
- public void searchByIdThrowsExceptionForInvalidISBN() {
+ void searchByIdThrowsExceptionForInvalidISBN() {
assertThrows(FetcherException.class, () -> fetcher.performSearchById("jabref-4-ever"));
}
+ @Test
+ void searchByEntryWithISBNSuccessful() throws FetcherException {
+ BibEntry input = new BibEntry().withField("isbn", "0134685997");
+
+ List fetchedEntry = fetcher.performSearch(input);
+ assertEquals(Collections.singletonList(bibEntry), fetchedEntry);
+ }
+
/**
* This test searches for a valid ISBN. See https://www.amazon.de/dp/3728128155/?tag=jabref-21 However, this ISBN is
* not available on ebook.de. The fetcher should something as it falls back to Chimbori
*/
@Test
- public void searchForIsbnAvailableAtChimboriButNonOnEbookDe() throws FetcherException {
+ void searchForIsbnAvailableAtChimboriButNonOnEbookDe() throws FetcherException {
Optional fetchedEntry = fetcher.performSearchById("3728128155");
assertNotEquals(Optional.empty(), fetchedEntry);
}
diff --git a/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java b/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java
index e66d81f0948..cf938c036bb 100644
--- a/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java
+++ b/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java
@@ -1,5 +1,6 @@
package org.jabref.logic.importer.fetcher;
+import java.util.Collections;
import java.util.List;
import java.util.Optional;
@@ -55,8 +56,16 @@ void searchByEntryFindsEntry() throws Exception {
searchEntry.setField("journal", "fluid");
List fetchedEntries = fetcher.performSearch(searchEntry);
- assertFalse(fetchedEntries.isEmpty());
- assertEquals(ratiuEntry, fetchedEntries.get(0));
+ assertEquals(Collections.singletonList(ratiuEntry), fetchedEntries);
+ }
+
+ @Test
+ void searchByIdInEntryFindsEntry() throws Exception {
+ BibEntry searchEntry = new BibEntry();
+ searchEntry.setField("mrnumber", "3537908");
+
+ List fetchedEntries = fetcher.performSearch(searchEntry);
+ assertEquals(Collections.singletonList(ratiuEntry), fetchedEntries);
}
@Test
diff --git a/src/test/java/org/jabref/model/entry/identifier/ArXivIdentifierTest.java b/src/test/java/org/jabref/model/entry/identifier/ArXivIdentifierTest.java
index 3109f4b3c76..0c9250c5529 100644
--- a/src/test/java/org/jabref/model/entry/identifier/ArXivIdentifierTest.java
+++ b/src/test/java/org/jabref/model/entry/identifier/ArXivIdentifierTest.java
@@ -6,19 +6,61 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
-public class ArXivIdentifierTest {
+class ArXivIdentifierTest {
@Test
- public void parseIgnoresArXivPrefix() throws Exception {
+ void parse() throws Exception {
+ Optional parsed = ArXivIdentifier.parse("0710.0994");
+
+ assertEquals(Optional.of(new ArXivIdentifier("0710.0994")), parsed);
+ }
+
+ @Test
+ void parseWithArXivPrefix() throws Exception {
Optional parsed = ArXivIdentifier.parse("arXiv:0710.0994");
assertEquals(Optional.of(new ArXivIdentifier("0710.0994")), parsed);
}
@Test
- public void parseIgnoresArxivPrefix() throws Exception {
+ void parseWithArxivPrefix() throws Exception {
Optional parsed = ArXivIdentifier.parse("arxiv:0710.0994");
assertEquals(Optional.of(new ArXivIdentifier("0710.0994")), parsed);
}
+
+ @Test
+ void parseWithClassification() throws Exception {
+ Optional parsed = ArXivIdentifier.parse("0706.0001v1 [q-bio.CB]");
+
+ assertEquals(Optional.of(new ArXivIdentifier("0706.0001v1", "q-bio.CB")), parsed);
+ }
+
+ @Test
+ void parseWithArXivPrefixAndClassification() throws Exception {
+ Optional parsed = ArXivIdentifier.parse("arXiv:0706.0001v1 [q-bio.CB]");
+
+ assertEquals(Optional.of(new ArXivIdentifier("0706.0001v1", "q-bio.CB")), parsed);
+ }
+
+ @Test
+ void parseOldIdentifier() throws Exception {
+ Optional parsed = ArXivIdentifier.parse("math.GT/0309136");
+
+ assertEquals(Optional.of(new ArXivIdentifier("math.GT/0309136", "math.GT")), parsed);
+ }
+
+ @Test
+ void parseOldIdentifierWithArXivPrefix() throws Exception {
+ Optional parsed = ArXivIdentifier.parse("arXiv:math.GT/0309136");
+
+ assertEquals(Optional.of(new ArXivIdentifier("math.GT/0309136", "math.GT")), parsed);
+ }
+
+ @Test
+ void parseUrl() throws Exception {
+ Optional parsed = ArXivIdentifier.parse("http://arxiv.org/abs/1502.05795");
+
+ assertEquals(Optional.of(new ArXivIdentifier("1502.05795", "")), parsed);
+ }
}