Skip to content

Commit

Permalink
Add eprint cleanup (#4445)
Browse files Browse the repository at this point in the history
* Adds a cleanup operation that detects an arXiv identifier in the note, journal or url field and moves it to the `eprint` field.

I also took the opportunity to convert the cleanup panel to FXML and somewhat simplified/refactored the code around the cleanup.

* Implement feedback

* Fix cleanup
  • Loading branch information
tobiasdiez authored Nov 7, 2018
1 parent 57281d2 commit 144522d
Show file tree
Hide file tree
Showing 15 changed files with 367 additions and 270 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
49 changes: 23 additions & 26 deletions src/main/java/org/jabref/gui/actions/CleanupAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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<CleanupPreset> 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() {
Expand Down Expand Up @@ -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"));
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/jabref/gui/cleanup/CleanupDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<CleanupPreset> {

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) {
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<fx:root xmlns:fx="http://javafx.com/fxml/1" spacing="10.0" type="VBox" xmlns="http://javafx.com/javafx/8.0.121"
fx:controller="org.jabref.gui.cleanup.CleanupPresetPanel">

<CheckBox fx:id="cleanUpDOI" text="%Move DOIs from note and URL field to DOI field and remove http prefix"/>
<CheckBox fx:id="cleanUpEprint"
text="%Move preprint information from 'URL' and 'journal' field to the 'eprint' field"/>
<CheckBox fx:id="cleanUpISSN" text="%Reformat ISSN"/>
<CheckBox fx:id="cleanUpUpgradeExternalLinks"/>
<CheckBox fx:id="cleanUpMovePDF"/>
<CheckBox fx:id="cleanUpMakePathsRelative" text="%Make paths of linked files relative (if possible)"/>
<CheckBox fx:id="cleanUpRenamePDF" text="%Rename PDFs to given filename format pattern"/>
<VBox spacing="5.0">
<Label fx:id="cleanupRenamePDFLabel"/>
<CheckBox fx:id="cleanUpRenamePDFonlyRelativePaths" text="%Rename only PDFs having a relative path"/>
<VBox.margin>
<Insets left="40.0"/>
</VBox.margin>
</VBox>

<CheckBox fx:id="cleanUpBiblatex"
text="%Convert to biblatex format (for example, move the value of the 'journal' field to 'journaltitle')"/>
<CheckBox fx:id="cleanUpBibtex"
text="%Convert to BibTeX format (for example, move the value of the 'journaltitle' field to 'journal')"/>

<VBox fx:id="formatterContainer"/>

</fx:root>
138 changes: 58 additions & 80 deletions src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<Path> firstExistingDir = databaseContext
.getFirstExistingFileDir(JabRefPreferences.getInstance().getFilePreferences());
private void init(CleanupPreset cleanupPreset, FilePreferences filePreferences) {
Optional<Path> 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<CleanupPreset.CleanupStep> 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);
}
Expand All @@ -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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private void buildLayout() {
actionsList = new ListView<>(actions);
actionsList.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
new ViewModelListCellFactory<FieldFormatterCleanup>()
.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);
Expand Down
Loading

0 comments on commit 144522d

Please sign in to comment.