diff --git a/CHANGELOG.md b/CHANGELOG.md index f61d58404a8..30c66f3f772 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# ### Changed - Abbreviate journal names functionality is now running parallel, increasing performance significantly. [#2831] (https://github.com/JabRef/jabref/issues/2831) +- Changed order of items in context menu [#298] (https://github.com/koppor/jabref/issues/298) - Changed ID-based entry generator to store the last used fetcher. [#2796] (https://github.com/JabRef/jabref/issues/2796) - Reorganised annotation information on the right side of the "File annotations" tab. [#3109](https://github.com/JabRef/jabref/issues/3109) - We now show a small notification icon in the entry editor when we detect data inconsistency or other problems. [#3145](https://github.com/JabRef/jabref/issues/3145) @@ -24,6 +25,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We improved the export of the `address` and `location` field to the MS-Office XML fields. If the address field does not contain a comma, it is treated as single value and exported to the field `city`. [#1750, comment](https://github.com/JabRef/jabref/issues/1750#issuecomment-357539167) For more details refer to the [field mapping help page](http://help.jabref.org/en/MsOfficeBibFieldMapping) - We added Facebook and Twitter icons in the toolbar to link to our [Facebook](https://www.facebook.com/JabRef/) and [Twitter](https://twitter.com/jabref_org) pages. +- Renamed the _Review_ Tab into _Comments_ Tab - We no longer print empty lines when exporting an entry in RIS format [#3634](https://github.com/JabRef/jabref/issues/3634) - We improved file saving so that hard links are now preserved when a save is performed [#2633](https://github.com/JabRef/jabref/issues/2633) - We changed the default dialog option when removing a [file link](http://help.jabref.org/en/FileLinks#adding-external-links-to-an-entry) from an entry. diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index e94a6c9c367..e51014e4114 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -18,7 +18,7 @@ import org.jabref.gui.BasePanel; import org.jabref.gui.GUIGlobals; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.autosaveandbackup.BackupUIManager; +import org.jabref.gui.dialogs.BackupUIManager; import org.jabref.gui.importer.ParserResultWarningDialog; import org.jabref.gui.importer.actions.OpenDatabaseAction; import org.jabref.gui.shared.SharedDatabaseUIManager; @@ -301,5 +301,4 @@ public static JabRefFrame getMainFrame() { public static void setMainFrame(JabRefFrame mainFrame) { JabRefGUI.mainFrame = mainFrame; } - } diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 4abf2fbfe38..e47ff58554a 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -78,11 +78,11 @@ import org.jabref.gui.actions.OpenBrowserAction; import org.jabref.gui.actions.SearchForUpdateAction; import org.jabref.gui.actions.SortTabsAction; -import org.jabref.gui.autosaveandbackup.AutosaveUIManager; import org.jabref.gui.bibtexkeypattern.BibtexKeyPatternDialog; import org.jabref.gui.copyfiles.CopyFilesAction; import org.jabref.gui.customentrytypes.EntryCustomizationDialog; import org.jabref.gui.dbproperties.DatabasePropertiesDialog; +import org.jabref.gui.dialogs.AutosaveUIManager; import org.jabref.gui.documentviewer.ShowDocumentViewerAction; import org.jabref.gui.exporter.ExportAction; import org.jabref.gui.exporter.ExportCustomizationDialog; @@ -657,7 +657,6 @@ public void windowClosing(WindowEvent e) { } initShowTrackingNotification(); - } private void initShowTrackingNotification() { @@ -715,7 +714,7 @@ public void setWindowTitle() { String changeFlag = panel.isModified() && !isAutosaveEnabled ? "*" : ""; String databaseFile = panel.getBibDatabaseContext().getDatabaseFile().map(File::getPath) .orElse(GUIGlobals.UNTITLED_TITLE); - setTitle(FRAME_TITLE + " - " + databaseFile + changeFlag + modeInfo); + setTitle(FRAME_TITLE + " - " + databaseFile + changeFlag + modeInfo); } else if (panel.getBibDatabaseContext().getLocation() == DatabaseLocation.SHARED) { setTitle(FRAME_TITLE + " - " + panel.getBibDatabaseContext().getDBMSSynchronizer().getDBName() + " [" + Localization.lang("shared") + "]" + modeInfo); @@ -800,7 +799,6 @@ private void tearDownJabRef(List filenames) { File focusedDatabase = getCurrentBasePanel().getBibDatabaseContext().getDatabaseFile().orElse(null); new LastFocusedTabPreferences(prefs).setLastFocusedTab(focusedDatabase); } - } fileHistory.storeHistory(); @@ -963,7 +961,6 @@ public BasePanel getBasePanelAt(int i) { /** * Returns a list of BasePanel. - * */ public List getBasePanelList() { List returnList = new ArrayList<>(); @@ -1282,26 +1279,32 @@ private void fillMenu() { createDisabledIconsForMenuEntries(mb); } - public void addParserResult(ParserResult pr, boolean focusPanel) { - if (pr.toOpenTab()) { + public void addParserResult(ParserResult parserResult, boolean focusPanel) { + if (parserResult.toOpenTab()) { // Add the entries to the open tab. BasePanel panel = getCurrentBasePanel(); if (panel == null) { // There is no open tab to add to, so we create a new tab: - addTab(pr.getDatabaseContext(), focusPanel); + panel = addTab(parserResult.getDatabaseContext(), focusPanel); + if (parserResult.wasChangedOnMigration()) { + panel.markBaseChanged(); + } } else { - List entries = new ArrayList<>(pr.getDatabase().getEntries()); + List entries = new ArrayList<>(parserResult.getDatabase().getEntries()); addImportedEntries(panel, entries, false); } } else { // only add tab if DB is not already open Optional panel = getBasePanelList().stream() - .filter(p -> p.getBibDatabaseContext().getDatabaseFile().equals(pr.getFile())).findFirst(); + .filter(p -> p.getBibDatabaseContext().getDatabaseFile().equals(parserResult.getFile())).findFirst(); if (panel.isPresent()) { tabbedPane.setSelectedComponent(panel.get()); } else { - addTab(pr.getDatabaseContext(), focusPanel); + BasePanel basePanel = addTab(parserResult.getDatabaseContext(), focusPanel); + if (parserResult.wasChangedOnMigration()) { + basePanel.markBaseChanged(); + } } } } @@ -1447,7 +1450,6 @@ dupliCheck, autoSetFile, newEntryAction, newSpec, customizeAction, plainTextImpo atLeastOneEntryActions.addAll(Arrays.asList(downloadFullText, lookupIdentifiers, exportLinkedFiles)); tabbedPane.addChangeListener(event -> updateEnabledState()); - } /** @@ -1510,7 +1512,6 @@ public void setupAllTables() { // Update tables: if (bf.getDatabase() != null) { bf.setupMainPanel(); - } } } @@ -1561,7 +1562,7 @@ public void updateAllTabTitles() { } } - public void addTab(BasePanel basePanel, boolean raisePanel) { + public BasePanel addTab(BasePanel basePanel, boolean raisePanel) { // add tab tabbedPane.add(basePanel.getTabTitle(), basePanel); @@ -1586,22 +1587,23 @@ public void addTab(BasePanel basePanel, boolean raisePanel) { // Track opening trackOpenNewDatabase(basePanel); + return basePanel; } private void trackOpenNewDatabase(BasePanel basePanel) { Map properties = new HashMap<>(); Map measurements = new HashMap<>(); - measurements.put("NumberOfEntries", (double)basePanel.getDatabaseContext().getDatabase().getEntryCount()); + measurements.put("NumberOfEntries", (double) basePanel.getDatabaseContext().getDatabase().getEntryCount()); Globals.getTelemetryClient().ifPresent(client -> client.trackEvent("OpenNewDatabase", properties, measurements)); } public BasePanel addTab(BibDatabaseContext databaseContext, boolean raisePanel) { Objects.requireNonNull(databaseContext); - BasePanel bp = new BasePanel(JabRefFrame.this, databaseContext); - addTab(bp, raisePanel); - return bp; + BasePanel basePanel = new BasePanel(JabRefFrame.this, databaseContext); + addTab(basePanel, raisePanel); + return basePanel; } private boolean readyForAutosave(BibDatabaseContext context) { @@ -1727,7 +1729,6 @@ public void setProgressBarValue(final int value) { } else { SwingUtilities.invokeLater(() -> progressBar.setValue(value)); } - } /** @@ -1742,7 +1743,6 @@ public void setProgressBarIndeterminate(final boolean value) { } else { SwingUtilities.invokeLater(() -> progressBar.setIndeterminate(value)); } - } /** @@ -1759,11 +1759,11 @@ public void setProgressBarMaximum(final int value) { } else { SwingUtilities.invokeLater(() -> progressBar.setMaximum(value)); } - } /** * Return a boolean, if the selected entry have file + * * @param selectEntryList A selected entries list of the current base pane * @return true, if the selected entry contains file. * false, if multiple entries are selected or the selected entry doesn't contains file @@ -1778,6 +1778,7 @@ private boolean isExistFile(List selectEntryList) { /** * Return a boolean, if the selected entry have url or doi + * * @param selectEntryList A selected entries list of the current base pane * @return true, if the selected entry contains url or doi. * false, if multiple entries are selected or the selected entry doesn't contains url or doi @@ -2135,7 +2136,8 @@ public EditAction(String command, String menuTitle, String description, KeyStrok putValue(Action.SHORT_DESCRIPTION, description); } - @Override public void actionPerformed(ActionEvent e) { + @Override + public void actionPerformed(ActionEvent e) { LOGGER.debug(Globals.getFocusListener().getFocused().toString()); JComponent source = Globals.getFocusListener().getFocused(); @@ -2197,7 +2199,6 @@ public void actionPerformed(ActionEvent e) { GenFieldsCustomizer gf = new GenFieldsCustomizer(JabRefFrame.this); gf.setLocationRelativeTo(JabRefFrame.this); gf.setVisible(true); - } } @@ -2232,7 +2233,6 @@ public void actionPerformed(ActionEvent e) { propertiesDialog.setLocationRelativeTo(JabRefFrame.this); propertiesDialog.setVisible(true); } - } private class BibtexKeyPatternAction extends MnemonicAwareAction { @@ -2256,7 +2256,6 @@ public void actionPerformed(ActionEvent e) { bibtexKeyPatternDialog.setLocationRelativeTo(JabRefFrame.this); bibtexKeyPatternDialog.setVisible(true); } - } private class DefaultTableFontSizeAction extends MnemonicAwareAction { diff --git a/src/main/java/org/jabref/gui/PreviewPanel.java b/src/main/java/org/jabref/gui/PreviewPanel.java index 088c258bbd5..fedb268ae15 100644 --- a/src/main/java/org/jabref/gui/PreviewPanel.java +++ b/src/main/java/org/jabref/gui/PreviewPanel.java @@ -138,8 +138,8 @@ private ContextMenu createPopupMenu() { menu.getItems().add(copyPreview); menu.getItems().add(printEntryPreview); menu.getItems().add(new SeparatorMenuItem()); - menu.getItems().add(previousPreviewLayout); menu.getItems().add(nextPreviewLayout); + menu.getItems().add(previousPreviewLayout); return menu; } diff --git a/src/main/java/org/jabref/gui/autosaveandbackup/AutosaveUIManager.java b/src/main/java/org/jabref/gui/dialogs/AutosaveUIManager.java similarity index 95% rename from src/main/java/org/jabref/gui/autosaveandbackup/AutosaveUIManager.java rename to src/main/java/org/jabref/gui/dialogs/AutosaveUIManager.java index 99b97cf6f9d..312258be7b3 100644 --- a/src/main/java/org/jabref/gui/autosaveandbackup/AutosaveUIManager.java +++ b/src/main/java/org/jabref/gui/dialogs/AutosaveUIManager.java @@ -1,4 +1,4 @@ -package org.jabref.gui.autosaveandbackup; +package org.jabref.gui.dialogs; import org.jabref.gui.BasePanel; import org.jabref.gui.exporter.SaveDatabaseAction; diff --git a/src/main/java/org/jabref/gui/autosaveandbackup/BackupUIManager.java b/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java similarity index 96% rename from src/main/java/org/jabref/gui/autosaveandbackup/BackupUIManager.java rename to src/main/java/org/jabref/gui/dialogs/BackupUIManager.java index 3e0e3be4571..17256318f79 100644 --- a/src/main/java/org/jabref/gui/autosaveandbackup/BackupUIManager.java +++ b/src/main/java/org/jabref/gui/dialogs/BackupUIManager.java @@ -1,4 +1,4 @@ -package org.jabref.gui.autosaveandbackup; +package org.jabref.gui.dialogs; import java.nio.file.Path; diff --git a/src/main/java/org/jabref/gui/dialogs/MergeReviewIntoCommentUIManager.java b/src/main/java/org/jabref/gui/dialogs/MergeReviewIntoCommentUIManager.java new file mode 100644 index 00000000000..4e03dad775c --- /dev/null +++ b/src/main/java/org/jabref/gui/dialogs/MergeReviewIntoCommentUIManager.java @@ -0,0 +1,31 @@ +package org.jabref.gui.dialogs; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.swing.JOptionPane; + +import org.jabref.logic.l10n.Localization; +import org.jabref.model.entry.BibEntry; + +public class MergeReviewIntoCommentUIManager { + + public boolean askUserForMerge(List conflicts) { + List bibKeys = conflicts.stream() + .map(BibEntry::getCiteKeyOptional) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + + int answer = JOptionPane.showConfirmDialog( + null, + String.join(",\n", bibKeys) + " " + + Localization.lang("has/have both a 'Comment' and a 'Review' field.") + "\n" + + Localization.lang("Since the 'Review' field was deprecated in JabRef 4.2, these two fields are about to be merged into the 'Comment' field.") + "\n" + + Localization.lang("The conflicting fields of these entries will be merged into the 'Comment' field."), + Localization.lang("Review Field Migration"), JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE); + + return 0 == answer; + } +} diff --git a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java index 720422289f4..315a70497d5 100644 --- a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java +++ b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java @@ -16,9 +16,9 @@ import org.jabref.gui.DialogService; import org.jabref.gui.FXDialogService; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.autosaveandbackup.AutosaveUIManager; import org.jabref.gui.collab.ChangeScanner; import org.jabref.gui.collab.FileUpdatePanel; +import org.jabref.gui.dialogs.AutosaveUIManager; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.gui.worker.AbstractWorker; diff --git a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java index cfbcd91fc27..6a4b0dd6736 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -26,7 +26,7 @@ import org.jabref.gui.IconTheme; import org.jabref.gui.JabRefFrame; import org.jabref.gui.actions.MnemonicAwareAction; -import org.jabref.gui.autosaveandbackup.BackupUIManager; +import org.jabref.gui.dialogs.BackupUIManager; import org.jabref.gui.importer.ParserResultWarningDialog; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.shared.SharedDatabaseUIManager; diff --git a/src/main/java/org/jabref/logic/importer/OpenDatabase.java b/src/main/java/org/jabref/logic/importer/OpenDatabase.java index c9e2acfac26..1c3197e0e7b 100644 --- a/src/main/java/org/jabref/logic/importer/OpenDatabase.java +++ b/src/main/java/org/jabref/logic/importer/OpenDatabase.java @@ -6,11 +6,12 @@ import java.util.List; import org.jabref.logic.importer.fileformat.BibtexImporter; -import org.jabref.logic.importer.util.ConvertLegacyExplicitGroups; -import org.jabref.logic.importer.util.PostOpenAction; import org.jabref.logic.l10n.Localization; import org.jabref.logic.specialfields.SpecialFieldsUtils; import org.jabref.logic.util.io.FileBasedLock; +import org.jabref.migrations.ConvertLegacyExplicitGroups; +import org.jabref.migrations.MergeReviewIntoComment; +import org.jabref.migrations.PostOpenMigration; import org.jabref.model.entry.BibEntry; import org.jabref.model.util.FileUpdateMonitor; @@ -81,16 +82,17 @@ public static ParserResult loadDatabase(File fileToOpen, ImportFormatPreferences LOGGER.debug("Synchronized special fields based on keywords"); } - applyPostActions(result); + performLoadDatabaseMigrations(result); return result; } - private static void applyPostActions(ParserResult parserResult) { - List actions = Arrays.asList(new ConvertLegacyExplicitGroups()); + private static void performLoadDatabaseMigrations(ParserResult parserResult) { - for (PostOpenAction action : actions) { - action.performAction(parserResult); + List postOpenMigrations = Arrays.asList(new ConvertLegacyExplicitGroups(), new MergeReviewIntoComment()); + + for (PostOpenMigration migration : postOpenMigrations) { + migration.performMigration(parserResult); } } } diff --git a/src/main/java/org/jabref/logic/importer/ParserResult.java b/src/main/java/org/jabref/logic/importer/ParserResult.java index d6374cdde33..a19b5020a2d 100644 --- a/src/main/java/org/jabref/logic/importer/ParserResult.java +++ b/src/main/java/org/jabref/logic/importer/ParserResult.java @@ -19,7 +19,6 @@ import org.jabref.model.metadata.MetaData; public class ParserResult { - private final Map entryTypes; private final List warnings = new ArrayList<>(); private final List duplicateKeys = new ArrayList<>(); @@ -28,6 +27,7 @@ public class ParserResult { private File file; private boolean invalid; private boolean toOpenTab; + private boolean changedOnMigration = false; public ParserResult() { this(Collections.emptyList()); @@ -180,4 +180,12 @@ public void setDatabaseContext(BibDatabaseContext bibDatabaseContext) { public boolean isEmpty() { return this == new ParserResult(); } + + public boolean wasChangedOnMigration() { + return changedOnMigration; + } + + public void setChangedOnMigration(boolean wasChangedOnMigration) { + this.changedOnMigration = wasChangedOnMigration; + } } diff --git a/src/main/java/org/jabref/logic/importer/util/PostOpenAction.java b/src/main/java/org/jabref/logic/importer/util/PostOpenAction.java deleted file mode 100644 index 7eadee68c88..00000000000 --- a/src/main/java/org/jabref/logic/importer/util/PostOpenAction.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.jabref.logic.importer.util; - -import org.jabref.logic.importer.ParserResult; - -public interface PostOpenAction { - void performAction(ParserResult parserResult); -} diff --git a/src/main/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroups.java b/src/main/java/org/jabref/migrations/ConvertLegacyExplicitGroups.java similarity index 90% rename from src/main/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroups.java rename to src/main/java/org/jabref/migrations/ConvertLegacyExplicitGroups.java index 6cb4f839be3..d0f5ced7bfc 100644 --- a/src/main/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroups.java +++ b/src/main/java/org/jabref/migrations/ConvertLegacyExplicitGroups.java @@ -1,4 +1,4 @@ -package org.jabref.logic.importer.util; +package org.jabref.migrations; import java.util.ArrayList; import java.util.List; @@ -13,10 +13,10 @@ * Converts legacy explicit groups, where the group contained a list of assigned entries, to the new format, * where the entry stores a list of groups it belongs to. */ -public class ConvertLegacyExplicitGroups implements PostOpenAction { +public class ConvertLegacyExplicitGroups implements PostOpenMigration { @Override - public void performAction(ParserResult parserResult) { + public void performMigration(ParserResult parserResult) { Objects.requireNonNull(parserResult); if (!parserResult.getMetaData().getGroups().isPresent()) { return; diff --git a/src/main/java/org/jabref/migrations/MergeReviewIntoComment.java b/src/main/java/org/jabref/migrations/MergeReviewIntoComment.java new file mode 100644 index 00000000000..76280caa24a --- /dev/null +++ b/src/main/java/org/jabref/migrations/MergeReviewIntoComment.java @@ -0,0 +1,71 @@ +package org.jabref.migrations; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import javafx.collections.ObservableList; + +import org.jabref.gui.dialogs.MergeReviewIntoCommentUIManager; +import org.jabref.logic.importer.ParserResult; +import org.jabref.logic.l10n.Localization; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FieldName; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MergeReviewIntoComment implements PostOpenMigration { + public static final Logger LOGGER = LoggerFactory.getLogger(MergeReviewIntoComment.class); + + @Override + public void performMigration(ParserResult parserResult) { + ObservableList entries = Objects.requireNonNull(parserResult).getDatabase().getEntries(); + + // migrate non-conflicting entries first + entries.stream() + .filter(this::hasReviewField) + .filter(entry -> !this.hasCommentField(entry)) + .forEach(entry -> migrate(entry, parserResult)); + + // determine conflicts + List conflicts = entries.stream() + .filter(this::hasReviewField) + .filter(this::hasCommentField) + .collect(Collectors.toList()); + + // resolve conflicts if users agrees + if (!conflicts.isEmpty() && new MergeReviewIntoCommentUIManager().askUserForMerge(conflicts)) { + conflicts.stream() + .filter(this::hasReviewField) + .forEach(entry -> migrate(entry, parserResult)); + } + } + + private String mergeCommentFieldIfPresent(BibEntry entry, String review) { + if (entry.getField(FieldName.COMMENT).isPresent()) { + LOGGER.info(String.format("Both Comment and Review fields are present in %s! Merging them into the comment field.", entry.getAuthorTitleYear(150))); + return String.format("%s\n%s:\n%s", entry.getField(FieldName.COMMENT).get().trim(), Localization.lang("Review"), review.trim()); + } + return review; + } + + private boolean hasCommentField(BibEntry entry) { + return entry.getField(FieldName.COMMENT).isPresent(); + } + + private boolean hasReviewField(BibEntry entry) { + return entry.getField(FieldName.REVIEW).isPresent(); + } + + private void migrate(BibEntry entry, ParserResult parserResult) { + // this method may only be called if the review field is present + updateFields(entry, mergeCommentFieldIfPresent(entry, entry.getField(FieldName.REVIEW).get())); + parserResult.wasChangedOnMigration(); + } + + private void updateFields(BibEntry entry, String review) { + entry.setField(FieldName.COMMENT, review); + entry.clearField(FieldName.REVIEW); + } +} diff --git a/src/main/java/org/jabref/migrations/PostOpenMigration.java b/src/main/java/org/jabref/migrations/PostOpenMigration.java new file mode 100644 index 00000000000..b259ee12cb3 --- /dev/null +++ b/src/main/java/org/jabref/migrations/PostOpenMigration.java @@ -0,0 +1,7 @@ +package org.jabref.migrations; + +import org.jabref.logic.importer.ParserResult; + +public interface PostOpenMigration { + void performMigration(ParserResult parserResult); +} diff --git a/src/main/java/org/jabref/model/entry/InternalBibtexFields.java b/src/main/java/org/jabref/model/entry/InternalBibtexFields.java index 3cf4886c36f..69c8302a3df 100644 --- a/src/main/java/org/jabref/model/entry/InternalBibtexFields.java +++ b/src/main/java/org/jabref/model/entry/InternalBibtexFields.java @@ -22,10 +22,10 @@ * config files -> simple extension and definition of new fields * * TODO: - * - handling of identically fields with different names (https://github.com/JabRef/jabref/issues/521) - * e.g. LCCN = lib-congress, journaltitle = journal - * - group id for each fields, e.g. standard, jurabib, bio, ... - * - add a additional properties functionality into the BibtexSingleField class + * - handling of identically fields with different names (https://github.com/JabRef/jabref/issues/521) + * e.g. LCCN = lib-congress, journaltitle = journal + * - group id for each fields, e.g. standard, jurabib, bio, ... + * - add a additional properties functionality into the BibtexSingleField class */ public class InternalBibtexFields { @@ -35,7 +35,7 @@ public class InternalBibtexFields { * * A user can change them. The change is currently stored in the preferences only and not explicitley exposed as separte preferences object */ - public static final List DEFAULT_GENERAL_FIELDS = Arrays.asList(FieldName.CROSSREF, FieldName.KEYWORDS, FieldName.FILE, FieldName.DOI, FieldName.URL, FieldName.GROUPS, FieldName.COMMENT, FieldName.OWNER, FieldName.TIMESTAMP); + public static final List DEFAULT_GENERAL_FIELDS = Arrays.asList(FieldName.CROSSREF, FieldName.KEYWORDS, FieldName.FILE, FieldName.DOI, FieldName.URL, FieldName.GROUPS, FieldName.OWNER, FieldName.TIMESTAMP); // Lists of fields with special properties private static final List INTEGER_FIELDS = Arrays.asList(FieldName.CTLMAX_NAMES_FORCED_ETAL, @@ -382,7 +382,6 @@ public static void setNumericFields(List numFields) { field.setNumeric(true); InternalBibtexFields.RUNTIME.fieldSet.put(fieldName, field); } - } public static Set getFieldProperties(String name) { diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 149dec57782..91179882f38 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -982,9 +982,9 @@ public void setLanguageDependentDefaultValues() { defaults.put(CUSTOM_TAB_FIELDS + "_def1", FieldName.ABSTRACT); defaults.put(CUSTOM_TAB_NAME + "_def1", Localization.lang("Abstract")); - // Entry editor tab 2: Review Field - used for research comments, etc. - defaults.put(CUSTOM_TAB_FIELDS + "_def2", FieldName.REVIEW); - defaults.put(CUSTOM_TAB_NAME + "_def2", Localization.lang("Review")); + // Entry editor tab 2: Comments Field - used for research comments, etc. + defaults.put(CUSTOM_TAB_FIELDS + "_def2", FieldName.COMMENT); + defaults.put(CUSTOM_TAB_NAME + "_def2", Localization.lang("Comments")); defaults.put(EMAIL_SUBJECT, Localization.lang("References")); } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index f9cc9db3029..6b4b8ea1d3d 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -148,6 +148,7 @@ Broken\ link=Broken link Browse=Browse by=by +The\ conflicting\ fields\ of\ these\ entries\ will\ be\ merged\ into\ the\ 'Comment'\ field.=The conflicting fields of these entries will be merged into the 'Comment' field. Cancel=Cancel @@ -210,7 +211,7 @@ Color\ for\ marking\ incomplete\ entries=Color for marking incomplete entries Column\ width=Column width Command\ line\ id=Command line id - +Comments=Comments Contained\ in=Contained in @@ -560,6 +561,7 @@ Get\ fulltext=Get fulltext Gray\ out\ non-hits=Gray out non-hits Groups=Groups +has/have\ both\ a\ 'Comment'\ and\ a\ 'Review'\ field.=has/have both a 'Comment' and a 'Review' field. Have\ you\ chosen\ the\ correct\ package\ path?=Have you chosen the correct package path? @@ -1007,10 +1009,9 @@ Resolve\ strings\ for\ all\ fields\ except=Resolve strings for all fields except Resolve\ strings\ for\ standard\ BibTeX\ fields\ only=Resolve strings for standard BibTeX fields only resolved=resolved - Review=Review - Review\ changes=Review changes +Review\ Field\ Migration=Review Field Migration Right=Right @@ -1103,6 +1104,7 @@ Show\ URL/DOI\ column=Show URL/DOI column Show\ validation\ messages=Show validation messages Simple\ HTML=Simple HTML +Since\ the\ 'Review'\ field\ was\ deprecated\ in\ JabRef\ 4.2,\ these\ two\ fields\ are\ about\ to\ be\ merged\ into\ the\ 'Comment'\ field.=Since the 'Review' field was deprecated in JabRef 4.2, these two fields are about to be merged into the 'Comment' field. Size=Size diff --git a/src/test/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroupsTest.java b/src/test/java/org/jabref/migrations/ConvertLegacyExplicitGroupsTest.java similarity index 91% rename from src/test/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroupsTest.java rename to src/test/java/org/jabref/migrations/ConvertLegacyExplicitGroupsTest.java index a01fdec06dd..2d46cf37ed3 100644 --- a/src/test/java/org/jabref/logic/importer/util/ConvertLegacyExplicitGroupsTest.java +++ b/src/test/java/org/jabref/migrations/ConvertLegacyExplicitGroupsTest.java @@ -1,4 +1,4 @@ -package org.jabref.logic.importer.util; +package org.jabref.migrations; import java.util.Collections; import java.util.Optional; @@ -17,7 +17,7 @@ public class ConvertLegacyExplicitGroupsTest { - private PostOpenAction action; + private PostOpenMigration action; private BibEntry entry; private ExplicitGroup group; @@ -35,7 +35,7 @@ public void setUp() throws Exception { public void performActionWritesGroupMembershipInEntry() throws Exception { ParserResult parserResult = generateParserResult(GroupTreeNode.fromGroup(group)); - action.performAction(parserResult); + action.performMigration(parserResult); assertEquals(Optional.of("TestGroup"), entry.getField("groups")); } @@ -44,7 +44,7 @@ public void performActionWritesGroupMembershipInEntry() throws Exception { public void performActionClearsLegacyKeys() throws Exception { ParserResult parserResult = generateParserResult(GroupTreeNode.fromGroup(group)); - action.performAction(parserResult); + action.performMigration(parserResult); assertEquals(Collections.emptyList(), group.getLegacyEntryKeys()); } @@ -56,7 +56,7 @@ public void performActionWritesGroupMembershipInEntryForComplexGroupTree() throw root.addSubgroup(group); ParserResult parserResult = generateParserResult(root); - action.performAction(parserResult); + action.performMigration(parserResult); assertEquals(Optional.of("TestGroup"), entry.getField("groups")); } diff --git a/src/test/java/org/jabref/migrations/MergeReviewIntoCommentTest.java b/src/test/java/org/jabref/migrations/MergeReviewIntoCommentTest.java new file mode 100644 index 00000000000..b142e86a46c --- /dev/null +++ b/src/test/java/org/jabref/migrations/MergeReviewIntoCommentTest.java @@ -0,0 +1,85 @@ +package org.jabref.migrations; + +import java.util.Collections; + +import org.jabref.logic.importer.ParserResult; +import org.jabref.logic.l10n.Localization; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FieldName; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class MergeReviewIntoCommentTest { + + private MergeReviewIntoComment action; + + @BeforeEach + public void setUp() { + action = new MergeReviewIntoComment(); + } + + @Test + public void noFields() { + BibEntry entry = createMinimalBibEntry(); + ParserResult actualParserResult = new ParserResult(Collections.singletonList(entry)); + + action.performMigration(actualParserResult); + + assertEquals(entry, actualParserResult.getDatabase().getEntryByKey("Entry1").get()); + } + + @Test + public void reviewField() { + BibEntry actualEntry = createMinimalBibEntry(); + actualEntry.setField(FieldName.REVIEW, "My Review"); + ParserResult actualParserResult = new ParserResult(Collections.singletonList(actualEntry)); + + BibEntry expectedEntry = createMinimalBibEntry(); + expectedEntry.setField(FieldName.COMMENT, "My Review"); + + action.performMigration(actualParserResult); + + assertEquals(expectedEntry, actualParserResult.getDatabase().getEntryByKey("Entry1").get()); + } + + @Test + public void commentField() { + BibEntry entry = createMinimalBibEntry(); + entry.setField(FieldName.COMMENT, "My Comment"); + ParserResult actualParserResult = new ParserResult(Collections.singletonList(entry)); + + action.performMigration(actualParserResult); + + assertEquals(entry, actualParserResult.getDatabase().getEntryByKey("Entry1").get()); + } + + + @Test + @Disabled("Re-enable if the MergeReviewIntoComment.mergeCommentFieldIfPresent() does not block and wait for user input.") + public void reviewAndCommentField() { + BibEntry actualEntry = createMinimalBibEntry(); + actualEntry.setField(FieldName.REVIEW, "My Review"); + actualEntry.setField(FieldName.COMMENT, "My Comment"); + + ParserResult actualParserResult = new ParserResult(Collections.singletonList(actualEntry)); + + BibEntry expectedEntry = createMinimalBibEntry(); + expectedEntry.setField(FieldName.COMMENT, "My Comment\n" + Localization.lang("Review") + ":\nMy Review"); + + action.performMigration(actualParserResult); + + assertEquals(expectedEntry, actualParserResult.getDatabase().getEntryByKey("Entry1").get()); + } + + private BibEntry createMinimalBibEntry() { + BibEntry entry = new BibEntry(); + entry.setCiteKey("Entry1"); + entry.setField(FieldName.TITLE, "A random entry!"); + entry.setField(FieldName.AUTHOR, "JabRef DEVELOPERS"); + return entry; + } +}