From 7701375f1384cae93fdffcd5e5b4cfa36e9028d7 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Thu, 18 Apr 2019 22:41:41 +0200 Subject: [PATCH 01/16] Rework PosteOpenActions to javafx (custom entry type import) Convert dialog for importing custom entry types to CheckListView Rework threading when opening a database --- src/main/java/org/jabref/JabRefGUI.java | 2 +- .../actions/CheckForNewEntryTypesAction.java | 121 +++++++++--------- .../importer/actions/GUIPostOpenAction.java | 4 +- .../actions/MergeReviewIntoCommentAction.java | 5 +- .../importer/actions/OpenDatabaseAction.java | 114 +++++++++-------- .../gui/importer/actions/ResultHelper.java | 30 +++++ .../jabref/model/entry/BiblatexEntryType.java | 5 + .../jabref/model/entry/BibtexEntryType.java | 5 + .../jabref/model/entry/CustomEntryType.java | 5 + .../org/jabref/model/entry/EntryType.java | 1 + 10 files changed, 172 insertions(+), 120 deletions(-) create mode 100644 src/main/java/org/jabref/gui/importer/actions/ResultHelper.java diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index 66fe3694ffa..21488a999aa 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -177,7 +177,7 @@ private void openWindow(Stage mainStage) { for (int i = 0; (i < bibDatabases.size()) && (i < mainFrame.getBasePanelCount()); i++) { ParserResult pr = bibDatabases.get(i); BasePanel panel = mainFrame.getBasePanelAt(i); - OpenDatabaseAction.performPostOpenActions(panel, pr); + OpenDatabaseAction.performPostOpenActions(panel, pr, mainFrame.getDialogService()); } LOGGER.debug("Finished adding panels"); diff --git a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java index 674238292a9..b3ffd71f4d6 100644 --- a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java @@ -1,21 +1,21 @@ package org.jabref.gui.importer.actions; -import java.awt.Font; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; -import javax.swing.BoxLayout; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; +import javafx.collections.FXCollections; +import javafx.scene.control.ButtonType; +import javafx.scene.control.DialogPane; +import javafx.scene.control.Label; +import javafx.scene.layout.VBox; import org.jabref.Globals; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.gui.customentrytypes.CustomEntryTypesManager; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.l10n.Localization; @@ -24,6 +24,8 @@ import org.jabref.model.entry.CustomEntryType; import org.jabref.model.entry.EntryType; +import org.controlsfx.control.CheckListView; + /** * This action checks whether any new custom entry types were loaded from this * BIB file. If so, an offer to remember these entry types is given. @@ -36,10 +38,9 @@ public boolean isActionNecessary(ParserResult parserResult) { } @Override - public void performAction(BasePanel panel, ParserResult parserResult) { + public void performAction(BasePanel panel, ParserResult parserResult, DialogService dialogService) { BibDatabaseMode mode = getBibDatabaseModeFromParserResult(parserResult); - - List typesToStore = determineEntryTypesToSave(panel, getListOfUnknownAndUnequalCustomizations(parserResult), mode); + List typesToStore = determineEntryTypesToSave(panel, getListOfUnknownAndUnequalCustomizations(parserResult), mode, dialogService); if (!typesToStore.isEmpty()) { typesToStore.forEach(type -> EntryTypes.addOrModifyCustomEntryType((CustomEntryType) type, mode)); @@ -51,13 +52,12 @@ private List getListOfUnknownAndUnequalCustomizations(ParserResult pa BibDatabaseMode mode = getBibDatabaseModeFromParserResult(parserResult); return parserResult.getEntryTypes().values().stream() - .filter(type -> - (!EntryTypes.getType(type.getName(), mode).isPresent()) - || !EntryTypes.isEqualNameAndFieldBased(type, EntryTypes.getType(type.getName(), mode).get())) - .collect(Collectors.toList()); + .filter(type -> (!EntryTypes.getType(type.getName(), mode).isPresent()) + || !EntryTypes.isEqualNameAndFieldBased(type, EntryTypes.getType(type.getName(), mode).get())) + .collect(Collectors.toList()); } - private List determineEntryTypesToSave(BasePanel panel, List allCustomizedEntryTypes, BibDatabaseMode databaseMode) { + private List determineEntryTypesToSave(BasePanel panel, List allCustomizedEntryTypes, BibDatabaseMode databaseMode, DialogService dialogService) { List newTypes = new ArrayList<>(); List differentCustomizations = new ArrayList<>(); @@ -72,63 +72,60 @@ private List determineEntryTypesToSave(BasePanel panel, List typeCheckBoxMap = new HashMap<>(); + DialogPane pane = new DialogPane(); + + CheckListView unknownEntryTypesCheckList = new CheckListView<>(FXCollections.observableArrayList(newTypes)); + + VBox vbox = new VBox(); + vbox.getChildren().add(new Label(Localization.lang("Select all customized types to be stored in local preferences") + ":")); + vbox.getChildren().add(new Label(Localization.lang("Currently unknown"))); + vbox.getChildren().add(unknownEntryTypesCheckList); - JPanel checkboxPanel = createCheckBoxPanel(newTypes, differentCustomizations, typeCheckBoxMap); + Optional> differentCustomizationCheckList = Optional.empty(); + if (!differentCustomizations.isEmpty()) { - int answer = JOptionPane.showConfirmDialog(null, - checkboxPanel, - Localization.lang("Custom entry types"), - JOptionPane.OK_CANCEL_OPTION, - JOptionPane.QUESTION_MESSAGE); + differentCustomizationCheckList = Optional.of(new CheckListView<>(FXCollections.observableArrayList(differentCustomizations))); - if (answer == JOptionPane.YES_OPTION) { - return typeCheckBoxMap.entrySet().stream().filter(entry -> entry.getValue().isSelected()) - .map(Map.Entry::getKey).collect(Collectors.toList()); - } else { - return Collections.emptyList(); + vbox.getChildren().add(new Label(Localization.lang("Different customization, current settings will be overwritten") + ":")); + vbox.getChildren().add(differentCustomizationCheckList.get()); } - } + pane.setContent(vbox); - private JPanel createCheckBoxPanel(List newTypes, List differentCustomizations, - Map typeCheckBoxMap) { - JPanel checkboxPanel = new JPanel(); - checkboxPanel.setLayout(new BoxLayout(checkboxPanel, BoxLayout.PAGE_AXIS)); - - JLabel customFoundLabel = new JLabel(Localization.lang("Custom entry types found in file") + "."); - Font boldStandardFont = new Font(customFoundLabel.getFont().getFontName(), Font.BOLD, customFoundLabel.getFont().getSize()); - customFoundLabel.setFont(boldStandardFont); - checkboxPanel.add(customFoundLabel); - - JLabel selectLabel = new JLabel(Localization.lang("Select all customized types to be stored in local preferences") + ":"); - selectLabel.setFont(boldStandardFont); - checkboxPanel.add(selectLabel); - - checkboxPanel.add(new JLabel(" ")); - - // add all unknown types: - if (!newTypes.isEmpty()) { - checkboxPanel.add(new JLabel(Localization.lang("Currently unknown") + ":")); - for (EntryType type : newTypes) { - JCheckBox box = new JCheckBox(type.getName(), true); - checkboxPanel.add(box); - typeCheckBoxMap.put(type, box); - } + Optional buttonPressed = dialogService.showCustomDialogAndWait(Localization.lang("Custom entry types"), pane, ButtonType.OK, ButtonType.CANCEL); + if (buttonPressed.isPresent() && (buttonPressed.get() == ButtonType.OK)) { + + List differentCustomizationSelected = new ArrayList<>(); + differentCustomizationCheckList.map(view -> view.getCheckModel().getCheckedItems()).ifPresent(differentCustomizationSelected::addAll); + + List selectedUnknown = unknownEntryTypesCheckList.getCheckModel().getCheckedItems(); + + return Stream.concat(selectedUnknown.stream(), differentCustomizationSelected.stream()).collect(Collectors.toList()); } + return Collections.emptyList(); + } - // add all different customizations - if (!differentCustomizations.isEmpty()) { - checkboxPanel.add(new JLabel(Localization.lang("Different customization, current settings will be overwritten") + ":")); - for (EntryType type : differentCustomizations) { - JCheckBox box = new JCheckBox(type.getName(), true); - checkboxPanel.add(box); - typeCheckBoxMap.put(type, box); - } + /* + // add all unknown types: + if (!newTypes.isEmpty()) { + checkboxPanel.add(new JLabel(Localization.lang("Currently unknown") + ":")); + for (EntryType type : newTypes) { + JCheckBox box = new JCheckBox(type.getName(), true); + checkboxPanel.add(box); + typeCheckBoxMap.put(type, box); } - return checkboxPanel; } + // add all different customizations + if (!differentCustomizations.isEmpty()) { + checkboxPanel.add(new JLabel(Localization.lang("Different customization, current settings will be overwritten") + ":")); + for (EntryType type : differentCustomizations) { + JCheckBox box = new JCheckBox(type.getName(), true); + checkboxPanel.add(box); + typeCheckBoxMap.put(type, box); + } + }*/ + private BibDatabaseMode getBibDatabaseModeFromParserResult(ParserResult parserResult) { return parserResult.getMetaData().getMode().orElse(Globals.prefs.getDefaultBibDatabaseMode()); } diff --git a/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java b/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java index 739c11305e4..a7ded93acb7 100644 --- a/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java @@ -1,6 +1,7 @@ package org.jabref.gui.importer.actions; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.logic.importer.ParserResult; /** @@ -32,6 +33,7 @@ public interface GUIPostOpenAction { * * @param panel The BasePanel where the database is shown. * @param pr The result of the BIB parse operation. + * @param dialogService */ - void performAction(BasePanel panel, ParserResult pr); + void performAction(BasePanel panel, ParserResult pr, DialogService dialogService); } diff --git a/src/main/java/org/jabref/gui/importer/actions/MergeReviewIntoCommentAction.java b/src/main/java/org/jabref/gui/importer/actions/MergeReviewIntoCommentAction.java index 3196f1c46aa..2d9d18eb075 100644 --- a/src/main/java/org/jabref/gui/importer/actions/MergeReviewIntoCommentAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/MergeReviewIntoCommentAction.java @@ -3,6 +3,7 @@ import java.util.List; import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; import org.jabref.logic.importer.ParserResult; import org.jabref.migrations.MergeReviewIntoCommentMigration; import org.jabref.model.entry.BibEntry; @@ -15,12 +16,12 @@ public boolean isActionNecessary(ParserResult parserResult) { } @Override - public void performAction(BasePanel basePanel, ParserResult parserResult) { + public void performAction(BasePanel basePanel, ParserResult parserResult, DialogService dialogService) { MergeReviewIntoCommentMigration migration = new MergeReviewIntoCommentMigration(); migration.performMigration(parserResult); List conflicts = MergeReviewIntoCommentMigration.collectConflicts(parserResult); - if (!conflicts.isEmpty() && new MergeReviewIntoCommentConfirmationDialog(basePanel.frame().getDialogService()).askUserForMerge(conflicts)) { + if (!conflicts.isEmpty() && new MergeReviewIntoCommentConfirmationDialog(dialogService).askUserForMerge(conflicts)) { migration.performConflictingMigration(parserResult); } } 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 b8be7090041..194b2b72fed 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -13,8 +13,6 @@ import java.util.Optional; import java.util.stream.Collectors; -import javax.swing.SwingUtilities; - import org.jabref.Globals; import org.jabref.JabRefExecutorService; import org.jabref.gui.BasePanel; @@ -26,6 +24,7 @@ import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.importer.ParserResultWarningDialog; import org.jabref.gui.shared.SharedDatabaseUIManager; +import org.jabref.gui.util.BackgroundTask; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.logic.autosaveandbackup.BackupManager; @@ -49,12 +48,11 @@ public class OpenDatabaseAction extends SimpleCommand { // List of actions that may need to be called after opening the file. Such as // upgrade actions etc. that may depend on the JabRef version that wrote the file: private static final List POST_OPEN_ACTIONS = Arrays.asList( - // Migrations: - // Warning for migrating the Review into the Comment field - new MergeReviewIntoCommentAction(), - // Check for new custom entry types loaded from the BIB file: - new CheckForNewEntryTypesAction() - ); + // Migrations: + // Warning for migrating the Review into the Comment field + new MergeReviewIntoCommentAction(), + // Check for new custom entry types loaded from the BIB file: + new CheckForNewEntryTypesAction()); private final JabRefFrame frame; @@ -67,11 +65,12 @@ public OpenDatabaseAction(JabRefFrame frame) { * * @param panel The BasePanel where the database is shown. * @param result The result of the BIB file parse operation. + * @param dialogService */ - public static void performPostOpenActions(BasePanel panel, ParserResult result) { + public static void performPostOpenActions(BasePanel panel, ParserResult result, DialogService dialogService) { for (GUIPostOpenAction action : OpenDatabaseAction.POST_OPEN_ACTIONS) { if (action.isActionNecessary(result)) { - action.performAction(panel, result); + action.performAction(panel, result, dialogService); panel.frame().showBasePanel(panel); } } @@ -83,10 +82,10 @@ public void execute() { DialogService ds = frame.getDialogService(); FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() - .addExtensionFilter(StandardFileType.BIBTEX_DB) - .withDefaultExtension(StandardFileType.BIBTEX_DB) - .withInitialDirectory(getInitialDirectory()) - .build(); + .addExtensionFilter(StandardFileType.BIBTEX_DB) + .withDefaultExtension(StandardFileType.BIBTEX_DB) + .withInitialDirectory(getInitialDirectory()) + .build(); List chosenFiles = ds.showFileOpenDialogAndGetMultipleFiles(fileDialogConfiguration); filesToOpen.addAll(chosenFiles); @@ -144,7 +143,7 @@ public void openFiles(List filesToOpen, boolean raisePanel) { for (int i = 0; i < frame.getTabbedPane().getTabs().size(); i++) { BasePanel basePanel = frame.getBasePanelAt(i); if ((basePanel.getBibDatabaseContext().getDatabasePath().isPresent()) - && basePanel.getBibDatabaseContext().getDatabasePath().get().equals(file)) { + && basePanel.getBibDatabaseContext().getDatabasePath().get().equals(file)) { iterator.remove(); removed++; // See if we removed the final one. If so, we must perhaps @@ -162,11 +161,11 @@ public void openFiles(List filesToOpen, boolean raisePanel) { // locking until the file is loaded. if (!filesToOpen.isEmpty()) { final List theFiles = Collections.unmodifiableList(filesToOpen); - JabRefExecutorService.INSTANCE.execute(() -> { - for (Path theFile : theFiles) { - openTheFile(theFile, raisePanel); - } - }); + + for (Path theFile : theFiles) { + openTheFile(theFile, raisePanel); + } + for (Path theFile : theFiles) { frame.getFileHistory().newFile(theFile); } @@ -175,7 +174,7 @@ public void openFiles(List filesToOpen, boolean raisePanel) { // already open. If so, we may have to raise the correct tab: else if (toRaise != null) { frame.getDialogService().notify(Localization.lang("File '%0' is already open.", - toRaise.getBibDatabaseContext().getDatabaseFile().get().getPath())); + toRaise.getBibDatabaseContext().getDatabaseFile().get().getPath())); frame.showBasePanel(toRaise); } @@ -184,49 +183,56 @@ else if (toRaise != null) { /** * @param file the file, may be null or not existing + * @return */ private void openTheFile(Path file, boolean raisePanel) { Objects.requireNonNull(file); if (Files.exists(file)) { - Path fileToLoad = file.toAbsolutePath(); - frame.getDialogService().notify(Localization.lang("Opening") + ": '" + file + "'"); + BackgroundTask.wrap(() -> loadDatabase(file, raisePanel)) + .onSuccess(result -> OpenDatabaseAction.performPostOpenActions(result.getBasePanel(), result.getParserResult(), result.getDialogService())) + .executeWith(Globals.TASK_EXECUTOR); + } - Globals.prefs.put(JabRefPreferences.WORKING_DIRECTORY, fileToLoad.getParent().toString()); + } - if (BackupManager.checkForBackupFile(fileToLoad)) { - BackupUIManager.showRestoreBackupDialog(frame.getDialogService(), fileToLoad); - } + private ResultHelper loadDatabase(Path file, boolean raisePanel) { + Path fileToLoad = file.toAbsolutePath(); - ParserResult result; - result = OpenDatabase.loadDatabase(fileToLoad.toString(), - Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); + frame.getDialogService().notify(Localization.lang("Opening") + ": '" + file + "'"); - if (result.getDatabase().isShared()) { - try { - new SharedDatabaseUIManager(frame).openSharedDatabaseFromParserResult(result); - } catch (SQLException | DatabaseNotSupportedException | InvalidDBMSConnectionPropertiesException | - NotASharedDatabaseException e) { - result.getDatabaseContext().clearDatabaseFile(); // do not open the original file - result.getDatabase().clearSharedDatabaseID(); - LOGGER.error("Connection error", e); + Globals.prefs.put(JabRefPreferences.WORKING_DIRECTORY, fileToLoad.getParent().toString()); - frame.getDialogService().showErrorDialogAndWait(Localization.lang("Connection error"), - e.getMessage() + "\n\n" + Localization.lang("A local copy will be opened.")); + if (BackupManager.checkForBackupFile(fileToLoad)) { + BackupUIManager.showRestoreBackupDialog(frame.getDialogService(), fileToLoad); + } - } + ParserResult result; + result = OpenDatabase.loadDatabase(fileToLoad.toString(), + Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); + + if (result.getDatabase().isShared()) { + try { + new SharedDatabaseUIManager(frame).openSharedDatabaseFromParserResult(result); + } catch (SQLException | DatabaseNotSupportedException | InvalidDBMSConnectionPropertiesException | + NotASharedDatabaseException e) { + result.getDatabaseContext().clearDatabaseFile(); // do not open the original file + result.getDatabase().clearSharedDatabaseID(); + LOGGER.error("Connection error", e); + + frame.getDialogService().showErrorDialogAndWait(Localization.lang("Connection error"), + e.getMessage() + "\n\n" + Localization.lang("A local copy will be opened.")); } + } - BasePanel panel = addNewDatabase(result, file, raisePanel); + BasePanel panel = addNewDatabase(result, file, raisePanel); - // After adding the database, go through our list and see if - // any post open actions need to be done. For instance, checking - // if we found new entry types that can be imported, or checking - // if the database contents should be modified due to new features - // in this version of JabRef: - final ParserResult finalReferenceToResult = result; - SwingUtilities.invokeLater(() -> OpenDatabaseAction.performPostOpenActions(panel, finalReferenceToResult)); - } + // After adding the database, go through our list and see if + // any post open actions need to be done. For instance, checking + // if we found new entry types that can be imported, or checking + // if the database contents should be modified due to new features + // in this version of JabRef: + return new ResultHelper(result, panel, frame.getDialogService()); } private BasePanel addNewDatabase(ParserResult result, final Path file, boolean raisePanel) { @@ -235,14 +241,14 @@ private BasePanel addNewDatabase(ParserResult result, final Path file, boolean r if (result.hasWarnings()) { JabRefExecutorService.INSTANCE - .execute(() -> ParserResultWarningDialog.showParserResultWarningDialog(result, frame)); + .execute(() -> ParserResultWarningDialog.showParserResultWarningDialog(result, frame)); } if (Objects.nonNull(file)) { frame.getDialogService().notify(Localization.lang("Opened library") + " '" + file.toString() + "' " - + Localization.lang("with") - + " " - + database.getEntryCount() + " " + Localization.lang("entries") + "."); + + Localization.lang("with") + + " " + + database.getEntryCount() + " " + Localization.lang("entries") + "."); } return DefaultTaskExecutor.runInJavaFXThread(() -> { diff --git a/src/main/java/org/jabref/gui/importer/actions/ResultHelper.java b/src/main/java/org/jabref/gui/importer/actions/ResultHelper.java new file mode 100644 index 00000000000..df3dd133fd9 --- /dev/null +++ b/src/main/java/org/jabref/gui/importer/actions/ResultHelper.java @@ -0,0 +1,30 @@ +package org.jabref.gui.importer.actions; + +import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; +import org.jabref.logic.importer.ParserResult; + +public class ResultHelper { + + private final ParserResult parserResult; + private final BasePanel basePanel; + private final DialogService dialogService; + + public ResultHelper(ParserResult parserResult, BasePanel basePanel, DialogService dialogService) { + this.parserResult = parserResult; + this.basePanel = basePanel; + this.dialogService = dialogService; + } + + public ParserResult getParserResult() { + return parserResult; + } + + public BasePanel getBasePanel() { + return basePanel; + } + + public DialogService getDialogService() { + return dialogService; + } +} diff --git a/src/main/java/org/jabref/model/entry/BiblatexEntryType.java b/src/main/java/org/jabref/model/entry/BiblatexEntryType.java index 44d05b7a292..420b6ff9322 100644 --- a/src/main/java/org/jabref/model/entry/BiblatexEntryType.java +++ b/src/main/java/org/jabref/model/entry/BiblatexEntryType.java @@ -56,4 +56,9 @@ private boolean isPrimary(String field) { public int compareTo(EntryType o) { return getName().compareTo(o.getName()); } + + @Override + public String toString() { + return getName(); + } } diff --git a/src/main/java/org/jabref/model/entry/BibtexEntryType.java b/src/main/java/org/jabref/model/entry/BibtexEntryType.java index bfbcfc0eaae..e347fc35b9a 100644 --- a/src/main/java/org/jabref/model/entry/BibtexEntryType.java +++ b/src/main/java/org/jabref/model/entry/BibtexEntryType.java @@ -56,4 +56,9 @@ public Set getSecondaryOptionalFields() { private boolean isPrimary(String field) { return getPrimaryOptionalFields().contains(field); } + + @Override + public String toString() { + return getName(); + } } diff --git a/src/main/java/org/jabref/model/entry/CustomEntryType.java b/src/main/java/org/jabref/model/entry/CustomEntryType.java index 8ee5bc96f79..c9e2a0ce9fe 100644 --- a/src/main/java/org/jabref/model/entry/CustomEntryType.java +++ b/src/main/java/org/jabref/model/entry/CustomEntryType.java @@ -129,4 +129,9 @@ public String getAsString() { builder.append("]"); return builder.toString(); } + + @Override + public String toString() { + return getName(); + } } diff --git a/src/main/java/org/jabref/model/entry/EntryType.java b/src/main/java/org/jabref/model/entry/EntryType.java index aa582893e4f..d0232a3d044 100644 --- a/src/main/java/org/jabref/model/entry/EntryType.java +++ b/src/main/java/org/jabref/model/entry/EntryType.java @@ -102,4 +102,5 @@ default Set getOptionalFieldsAndAliases() { } return optionalFieldsAndAliases; } + } From 9b7b7643bb038ec2007507516d6d7280cad73ee0 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Thu, 18 Apr 2019 22:41:41 +0200 Subject: [PATCH 02/16] Rework PosteOpenActions to javafx (custom entry type import) Convert dialog for importing custom entry types to CheckListView Rework threading when opening a database From 9358343f99eb5d4782def67fa5e11897941e7633 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 20 Apr 2019 10:51:34 +0200 Subject: [PATCH 03/16] rework threading stuff simplify code --- .../importer/actions/OpenDatabaseAction.java | 60 +++++++++---------- .../gui/importer/actions/ResultHelper.java | 30 ---------- 2 files changed, 27 insertions(+), 63 deletions(-) delete mode 100644 src/main/java/org/jabref/gui/importer/actions/ResultHelper.java 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 194b2b72fed..4f5a4102534 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -14,7 +14,6 @@ import java.util.stream.Collectors; import org.jabref.Globals; -import org.jabref.JabRefExecutorService; import org.jabref.gui.BasePanel; import org.jabref.gui.BasePanelPreferences; import org.jabref.gui.DialogService; @@ -25,7 +24,6 @@ import org.jabref.gui.importer.ParserResultWarningDialog; import org.jabref.gui.shared.SharedDatabaseUIManager; import org.jabref.gui.util.BackgroundTask; -import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.logic.autosaveandbackup.BackupManager; import org.jabref.logic.importer.OpenDatabase; @@ -55,9 +53,11 @@ public class OpenDatabaseAction extends SimpleCommand { new CheckForNewEntryTypesAction()); private final JabRefFrame frame; + private final DialogService dialogService; public OpenDatabaseAction(JabRefFrame frame) { this.frame = frame; + this.dialogService = frame.getDialogService(); } /** @@ -80,14 +80,13 @@ public static void performPostOpenActions(BasePanel panel, ParserResult result, public void execute() { List filesToOpen = new ArrayList<>(); - DialogService ds = frame.getDialogService(); FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .addExtensionFilter(StandardFileType.BIBTEX_DB) .withDefaultExtension(StandardFileType.BIBTEX_DB) .withInitialDirectory(getInitialDirectory()) .build(); - List chosenFiles = ds.showFileOpenDialogAndGetMultipleFiles(fileDialogConfiguration); + List chosenFiles = dialogService.showFileOpenDialogAndGetMultipleFiles(fileDialogConfiguration); filesToOpen.addAll(chosenFiles); openFiles(filesToOpen, true); @@ -173,12 +172,12 @@ public void openFiles(List filesToOpen, boolean raisePanel) { // If no files are remaining to open, this could mean that a file was // already open. If so, we may have to raise the correct tab: else if (toRaise != null) { - frame.getDialogService().notify(Localization.lang("File '%0' is already open.", - toRaise.getBibDatabaseContext().getDatabaseFile().get().getPath())); + dialogService.notify(Localization.lang("File '%0' is already open.", + toRaise.getBibDatabaseContext().getDatabasePath().get().getFileName().toString())); frame.showBasePanel(toRaise); } - frame.getDialogService().notify(Localization.lang("Files opened") + ": " + (filesToOpen.size())); + dialogService.notify(Localization.lang("Files opened") + ": " + (filesToOpen.size())); } /** @@ -189,27 +188,31 @@ private void openTheFile(Path file, boolean raisePanel) { Objects.requireNonNull(file); if (Files.exists(file)) { - BackgroundTask.wrap(() -> loadDatabase(file, raisePanel)) - .onSuccess(result -> OpenDatabaseAction.performPostOpenActions(result.getBasePanel(), result.getParserResult(), result.getDialogService())) + BackgroundTask.wrap(() -> loadDatabase(file)) + .onSuccess(result -> { + BasePanel panel = addNewDatabase(result, file, raisePanel); + OpenDatabaseAction.performPostOpenActions(panel, result, dialogService); + }) + .onFailure(ex -> dialogService.showErrorDialogAndWait(Localization.lang("Connection error"), + ex.getMessage() + "\n\n" + Localization.lang("A local copy will be opened."))) .executeWith(Globals.TASK_EXECUTOR); } } - private ResultHelper loadDatabase(Path file, boolean raisePanel) { + private ParserResult loadDatabase(Path file) throws Exception { Path fileToLoad = file.toAbsolutePath(); - frame.getDialogService().notify(Localization.lang("Opening") + ": '" + file + "'"); + dialogService.notify(Localization.lang("Opening") + ": '" + file + "'"); Globals.prefs.put(JabRefPreferences.WORKING_DIRECTORY, fileToLoad.getParent().toString()); if (BackupManager.checkForBackupFile(fileToLoad)) { - BackupUIManager.showRestoreBackupDialog(frame.getDialogService(), fileToLoad); + BackupUIManager.showRestoreBackupDialog(dialogService, fileToLoad); } - ParserResult result; - result = OpenDatabase.loadDatabase(fileToLoad.toString(), - Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); + ParserResult result = OpenDatabase.loadDatabase(fileToLoad.toString(), + Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); if (result.getDatabase().isShared()) { try { @@ -220,19 +223,12 @@ private ResultHelper loadDatabase(Path file, boolean raisePanel) { result.getDatabase().clearSharedDatabaseID(); LOGGER.error("Connection error", e); - frame.getDialogService().showErrorDialogAndWait(Localization.lang("Connection error"), - e.getMessage() + "\n\n" + Localization.lang("A local copy will be opened.")); + throw e; + } } + return result; - BasePanel panel = addNewDatabase(result, file, raisePanel); - - // After adding the database, go through our list and see if - // any post open actions need to be done. For instance, checking - // if we found new entry types that can be imported, or checking - // if the database contents should be modified due to new features - // in this version of JabRef: - return new ResultHelper(result, panel, frame.getDialogService()); } private BasePanel addNewDatabase(ParserResult result, final Path file, boolean raisePanel) { @@ -240,21 +236,19 @@ private BasePanel addNewDatabase(ParserResult result, final Path file, boolean r BibDatabase database = result.getDatabase(); if (result.hasWarnings()) { - JabRefExecutorService.INSTANCE - .execute(() -> ParserResultWarningDialog.showParserResultWarningDialog(result, frame)); + ParserResultWarningDialog.showParserResultWarningDialog(result, frame); } if (Objects.nonNull(file)) { - frame.getDialogService().notify(Localization.lang("Opened library") + " '" + file.toString() + "' " + dialogService.notify(Localization.lang("Opened library") + " '" + file.toString() + "' " + Localization.lang("with") + " " + database.getEntryCount() + " " + Localization.lang("entries") + "."); } - return DefaultTaskExecutor.runInJavaFXThread(() -> { - BasePanel basePanel = new BasePanel(frame, BasePanelPreferences.from(Globals.prefs), result.getDatabaseContext(), ExternalFileTypes.getInstance()); - frame.addTab(basePanel, raisePanel); - return basePanel; - }); + BasePanel basePanel = new BasePanel(frame, BasePanelPreferences.from(Globals.prefs), result.getDatabaseContext(), ExternalFileTypes.getInstance()); + frame.addTab(basePanel, raisePanel); + return basePanel; + } } diff --git a/src/main/java/org/jabref/gui/importer/actions/ResultHelper.java b/src/main/java/org/jabref/gui/importer/actions/ResultHelper.java deleted file mode 100644 index df3dd133fd9..00000000000 --- a/src/main/java/org/jabref/gui/importer/actions/ResultHelper.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.jabref.gui.importer.actions; - -import org.jabref.gui.BasePanel; -import org.jabref.gui.DialogService; -import org.jabref.logic.importer.ParserResult; - -public class ResultHelper { - - private final ParserResult parserResult; - private final BasePanel basePanel; - private final DialogService dialogService; - - public ResultHelper(ParserResult parserResult, BasePanel basePanel, DialogService dialogService) { - this.parserResult = parserResult; - this.basePanel = basePanel; - this.dialogService = dialogService; - } - - public ParserResult getParserResult() { - return parserResult; - } - - public BasePanel getBasePanel() { - return basePanel; - } - - public DialogService getDialogService() { - return dialogService; - } -} From af992a37f8024849970707b7f65174464508a67f Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 20 Apr 2019 12:13:47 +0200 Subject: [PATCH 04/16] rework dialog, create fxml etc fix l10n Remove obsolete code --- .../ImportCustomEntryTypesDialog.fxml | 30 ++++++ .../ImportCustomEntryTypesDialog.java | 57 ++++++++++++ ...ImportCustomEntryTypesDialogViewModel.java | 64 +++++++++++++ .../actions/CheckForNewEntryTypesAction.java | 93 +------------------ src/main/resources/l10n/JabRef_en.properties | 4 +- 5 files changed, 157 insertions(+), 91 deletions(-) create mode 100644 src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.fxml create mode 100644 src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.java create mode 100644 src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialogViewModel.java diff --git a/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.fxml b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.fxml new file mode 100644 index 00000000000..6efedfbdd11 --- /dev/null +++ b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.fxml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.java b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.java new file mode 100644 index 00000000000..a4317279893 --- /dev/null +++ b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.java @@ -0,0 +1,57 @@ +package org.jabref.gui.importer; + +import java.util.List; + +import javafx.beans.binding.Bindings; +import javafx.fxml.FXML; +import javafx.scene.control.ButtonType; +import javafx.scene.layout.VBox; + +import org.jabref.gui.util.BaseDialog; +import org.jabref.logic.l10n.Localization; +import org.jabref.model.database.BibDatabaseMode; +import org.jabref.model.entry.EntryType; + +import com.airhacks.afterburner.views.ViewLoader; +import org.controlsfx.control.CheckListView; + +public class ImportCustomEntryTypesDialog extends BaseDialog { + + @FXML private CheckListView unknownEntryTypesCheckList; + @FXML private VBox boxDifferentCustomization; + @FXML private CheckListView differentCustomizationCheckList; + + private ImportCustomEntryTypesDialogViewModel viewModel; + + private final BibDatabaseMode mode; + private final List customEntryTypes; + + public ImportCustomEntryTypesDialog(BibDatabaseMode mode, List customEntryTypes) { + this.mode = mode; + this.customEntryTypes = customEntryTypes; + + ViewLoader.view(this) + .load() + .setAsDialogPane(this); + + setResultConverter(btn -> { + if (btn == ButtonType.OK) { + viewModel.importCustomEntryTypes(unknownEntryTypesCheckList.getCheckModel().getCheckedItems(), differentCustomizationCheckList.getCheckModel().getCheckedItems()); + } + return null; + }); + + setTitle(Localization.lang("Custom entry types")); + + } + + @FXML + public void initialize() { + viewModel = new ImportCustomEntryTypesDialogViewModel(mode, customEntryTypes); + + boxDifferentCustomization.managedProperty().bind(Bindings.isNotEmpty(viewModel.differentCustomizationsProperty())); + unknownEntryTypesCheckList.itemsProperty().bind(viewModel.newTypesProperty()); + differentCustomizationCheckList.itemsProperty().bind(viewModel.differentCustomizationsProperty()); + } + +} diff --git a/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialogViewModel.java b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialogViewModel.java new file mode 100644 index 00000000000..174c7e54e73 --- /dev/null +++ b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialogViewModel.java @@ -0,0 +1,64 @@ +package org.jabref.gui.importer; + +import java.util.List; + +import javafx.beans.property.ListProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; + +import org.jabref.Globals; +import org.jabref.gui.customentrytypes.CustomEntryTypesManager; +import org.jabref.model.EntryTypes; +import org.jabref.model.database.BibDatabaseMode; +import org.jabref.model.entry.CustomEntryType; +import org.jabref.model.entry.EntryType; + +public class ImportCustomEntryTypesDialogViewModel { + + private final ListProperty newTypesProperty; + private final ListProperty differentCustomizationsProperty; + private final BibDatabaseMode mode; + + public ImportCustomEntryTypesDialogViewModel(BibDatabaseMode mode, List customEntryTypes) { + this.mode = mode; + + ObservableList newTypes = FXCollections.observableArrayList(); + ObservableList differentCustomizationTypes = FXCollections.observableArrayList(); + + for (EntryType customType : customEntryTypes) { + if (!EntryTypes.getType(customType.getName(), mode).isPresent()) { + newTypes.add(customType); + } else { + EntryType currentlyStoredType = EntryTypes.getType(customType.getName(), mode).get(); + if (!EntryTypes.isEqualNameAndFieldBased(customType, currentlyStoredType)) { + differentCustomizationTypes.add(customType); + } + } + } + + newTypesProperty = new SimpleListProperty<>(newTypes); + differentCustomizationsProperty = new SimpleListProperty<>(differentCustomizationTypes); + + } + + public ListProperty newTypesProperty() { + return this.newTypesProperty; + } + + public ListProperty differentCustomizationsProperty() { + return this.differentCustomizationsProperty; + } + + public void importCustomEntryTypes(List checkedUnknownEntryTypes, List checkedDifferentEntryTypes) { + if (!checkedUnknownEntryTypes.isEmpty()) { + checkedUnknownEntryTypes.forEach(type -> EntryTypes.addOrModifyCustomEntryType((CustomEntryType) type, mode)); + CustomEntryTypesManager.saveCustomEntryTypes(Globals.prefs); + } + if (!checkedDifferentEntryTypes.isEmpty()) { + checkedUnknownEntryTypes.forEach(type -> EntryTypes.addOrModifyCustomEntryType((CustomEntryType) type, mode)); + CustomEntryTypesManager.saveCustomEntryTypes(Globals.prefs); + } + + } +} diff --git a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java index b3ffd71f4d6..ba46182c305 100644 --- a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java @@ -1,31 +1,17 @@ package org.jabref.gui.importer.actions; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; -import java.util.stream.Stream; - -import javafx.collections.FXCollections; -import javafx.scene.control.ButtonType; -import javafx.scene.control.DialogPane; -import javafx.scene.control.Label; -import javafx.scene.layout.VBox; import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; -import org.jabref.gui.customentrytypes.CustomEntryTypesManager; +import org.jabref.gui.importer.ImportCustomEntryTypesDialog; import org.jabref.logic.importer.ParserResult; -import org.jabref.logic.l10n.Localization; import org.jabref.model.EntryTypes; import org.jabref.model.database.BibDatabaseMode; -import org.jabref.model.entry.CustomEntryType; import org.jabref.model.entry.EntryType; -import org.controlsfx.control.CheckListView; - /** * This action checks whether any new custom entry types were loaded from this * BIB file. If so, an offer to remember these entry types is given. @@ -40,12 +26,10 @@ public boolean isActionNecessary(ParserResult parserResult) { @Override public void performAction(BasePanel panel, ParserResult parserResult, DialogService dialogService) { BibDatabaseMode mode = getBibDatabaseModeFromParserResult(parserResult); - List typesToStore = determineEntryTypesToSave(panel, getListOfUnknownAndUnequalCustomizations(parserResult), mode, dialogService); - if (!typesToStore.isEmpty()) { - typesToStore.forEach(type -> EntryTypes.addOrModifyCustomEntryType((CustomEntryType) type, mode)); - CustomEntryTypesManager.saveCustomEntryTypes(Globals.prefs); - } + ImportCustomEntryTypesDialog dlg = new ImportCustomEntryTypesDialog(mode, getListOfUnknownAndUnequalCustomizations(parserResult)); + dlg.showAndWait(); + } private List getListOfUnknownAndUnequalCustomizations(ParserResult parserResult) { @@ -57,75 +41,6 @@ private List getListOfUnknownAndUnequalCustomizations(ParserResult pa .collect(Collectors.toList()); } - private List determineEntryTypesToSave(BasePanel panel, List allCustomizedEntryTypes, BibDatabaseMode databaseMode, DialogService dialogService) { - List newTypes = new ArrayList<>(); - List differentCustomizations = new ArrayList<>(); - - for (EntryType customType : allCustomizedEntryTypes) { - if (!EntryTypes.getType(customType.getName(), databaseMode).isPresent()) { - newTypes.add(customType); - } else { - EntryType currentlyStoredType = EntryTypes.getType(customType.getName(), databaseMode).get(); - if (!EntryTypes.isEqualNameAndFieldBased(customType, currentlyStoredType)) { - differentCustomizations.add(customType); - } - } - } - - DialogPane pane = new DialogPane(); - - CheckListView unknownEntryTypesCheckList = new CheckListView<>(FXCollections.observableArrayList(newTypes)); - - VBox vbox = new VBox(); - vbox.getChildren().add(new Label(Localization.lang("Select all customized types to be stored in local preferences") + ":")); - vbox.getChildren().add(new Label(Localization.lang("Currently unknown"))); - vbox.getChildren().add(unknownEntryTypesCheckList); - - Optional> differentCustomizationCheckList = Optional.empty(); - if (!differentCustomizations.isEmpty()) { - - differentCustomizationCheckList = Optional.of(new CheckListView<>(FXCollections.observableArrayList(differentCustomizations))); - - vbox.getChildren().add(new Label(Localization.lang("Different customization, current settings will be overwritten") + ":")); - vbox.getChildren().add(differentCustomizationCheckList.get()); - } - - pane.setContent(vbox); - - Optional buttonPressed = dialogService.showCustomDialogAndWait(Localization.lang("Custom entry types"), pane, ButtonType.OK, ButtonType.CANCEL); - if (buttonPressed.isPresent() && (buttonPressed.get() == ButtonType.OK)) { - - List differentCustomizationSelected = new ArrayList<>(); - differentCustomizationCheckList.map(view -> view.getCheckModel().getCheckedItems()).ifPresent(differentCustomizationSelected::addAll); - - List selectedUnknown = unknownEntryTypesCheckList.getCheckModel().getCheckedItems(); - - return Stream.concat(selectedUnknown.stream(), differentCustomizationSelected.stream()).collect(Collectors.toList()); - } - return Collections.emptyList(); - } - - /* - // add all unknown types: - if (!newTypes.isEmpty()) { - checkboxPanel.add(new JLabel(Localization.lang("Currently unknown") + ":")); - for (EntryType type : newTypes) { - JCheckBox box = new JCheckBox(type.getName(), true); - checkboxPanel.add(box); - typeCheckBoxMap.put(type, box); - } - } - - // add all different customizations - if (!differentCustomizations.isEmpty()) { - checkboxPanel.add(new JLabel(Localization.lang("Different customization, current settings will be overwritten") + ":")); - for (EntryType type : differentCustomizations) { - JCheckBox box = new JCheckBox(type.getName(), true); - checkboxPanel.add(box); - typeCheckBoxMap.put(type, box); - } - }*/ - private BibDatabaseMode getBibDatabaseModeFromParserResult(ParserResult parserResult) { return parserResult.getMetaData().getMode().orElse(Globals.prefs.getDefaultBibDatabaseMode()); } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 1546ff133c3..ef0936e9a53 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -1854,8 +1854,8 @@ Could\ not\ find\ any\ bibliographic\ information.=Could not find any bibliograp BibTeX\ key\ deviates\ from\ generated\ key=BibTeX key deviates from generated key DOI\ %0\ is\ invalid=DOI %0 is invalid -Select\ all\ customized\ types\ to\ be\ stored\ in\ local\ preferences=Select all customized types to be stored in local preferences -Currently\ unknown=Currently\ unknown +Select\ all\ customized\ types\ to\ be\ stored\ in\ local\ preferences\:=Select all customized types to be stored in local preferences\: +Currently\ unknown\:=Currently unknown\: Different\ customization,\ current\ settings\ will\ be\ overwritten=Different customization, current settings will be overwritten Entry\ type\ %0\ is\ only\ defined\ for\ Biblatex\ but\ not\ for\ BibTeX=Entry type %0 is only defined for Biblatex but not for BibTeX From 2d0f4dd9e8bc931cc4264eabf3a9d2400b4181ac Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 20 Apr 2019 12:29:44 +0200 Subject: [PATCH 05/16] remove dialog service argument --- .../gui/importer/actions/CheckForNewEntryTypesAction.java | 3 +-- .../org/jabref/gui/importer/actions/GUIPostOpenAction.java | 3 +-- .../gui/importer/actions/MergeReviewIntoCommentAction.java | 5 ++--- .../org/jabref/gui/importer/actions/OpenDatabaseAction.java | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java index ba46182c305..66a65efe8a7 100644 --- a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java @@ -5,7 +5,6 @@ import org.jabref.Globals; import org.jabref.gui.BasePanel; -import org.jabref.gui.DialogService; import org.jabref.gui.importer.ImportCustomEntryTypesDialog; import org.jabref.logic.importer.ParserResult; import org.jabref.model.EntryTypes; @@ -24,7 +23,7 @@ public boolean isActionNecessary(ParserResult parserResult) { } @Override - public void performAction(BasePanel panel, ParserResult parserResult, DialogService dialogService) { + public void performAction(BasePanel panel, ParserResult parserResult) { BibDatabaseMode mode = getBibDatabaseModeFromParserResult(parserResult); ImportCustomEntryTypesDialog dlg = new ImportCustomEntryTypesDialog(mode, getListOfUnknownAndUnequalCustomizations(parserResult)); diff --git a/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java b/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java index a7ded93acb7..5250d76d0a1 100644 --- a/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java @@ -1,7 +1,6 @@ package org.jabref.gui.importer.actions; import org.jabref.gui.BasePanel; -import org.jabref.gui.DialogService; import org.jabref.logic.importer.ParserResult; /** @@ -35,5 +34,5 @@ public interface GUIPostOpenAction { * @param pr The result of the BIB parse operation. * @param dialogService */ - void performAction(BasePanel panel, ParserResult pr, DialogService dialogService); + void performAction(BasePanel panel, ParserResult pr); } diff --git a/src/main/java/org/jabref/gui/importer/actions/MergeReviewIntoCommentAction.java b/src/main/java/org/jabref/gui/importer/actions/MergeReviewIntoCommentAction.java index 2d9d18eb075..3196f1c46aa 100644 --- a/src/main/java/org/jabref/gui/importer/actions/MergeReviewIntoCommentAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/MergeReviewIntoCommentAction.java @@ -3,7 +3,6 @@ import java.util.List; import org.jabref.gui.BasePanel; -import org.jabref.gui.DialogService; import org.jabref.logic.importer.ParserResult; import org.jabref.migrations.MergeReviewIntoCommentMigration; import org.jabref.model.entry.BibEntry; @@ -16,12 +15,12 @@ public boolean isActionNecessary(ParserResult parserResult) { } @Override - public void performAction(BasePanel basePanel, ParserResult parserResult, DialogService dialogService) { + public void performAction(BasePanel basePanel, ParserResult parserResult) { MergeReviewIntoCommentMigration migration = new MergeReviewIntoCommentMigration(); migration.performMigration(parserResult); List conflicts = MergeReviewIntoCommentMigration.collectConflicts(parserResult); - if (!conflicts.isEmpty() && new MergeReviewIntoCommentConfirmationDialog(dialogService).askUserForMerge(conflicts)) { + if (!conflicts.isEmpty() && new MergeReviewIntoCommentConfirmationDialog(basePanel.frame().getDialogService()).askUserForMerge(conflicts)) { migration.performConflictingMigration(parserResult); } } 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 4f5a4102534..87dcf8b87a1 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -70,7 +70,7 @@ public OpenDatabaseAction(JabRefFrame frame) { public static void performPostOpenActions(BasePanel panel, ParserResult result, DialogService dialogService) { for (GUIPostOpenAction action : OpenDatabaseAction.POST_OPEN_ACTIONS) { if (action.isActionNecessary(result)) { - action.performAction(panel, result, dialogService); + action.performAction(panel, result); panel.frame().showBasePanel(panel); } } From 8c302f511ed9d2e8a7dba7a9092fbd4ad54a62c1 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 20 Apr 2019 12:30:37 +0200 Subject: [PATCH 06/16] remove dialogService parameter --- src/main/java/org/jabref/JabRefGUI.java | 2 +- .../org/jabref/gui/importer/actions/OpenDatabaseAction.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index 21488a999aa..66fe3694ffa 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -177,7 +177,7 @@ private void openWindow(Stage mainStage) { for (int i = 0; (i < bibDatabases.size()) && (i < mainFrame.getBasePanelCount()); i++) { ParserResult pr = bibDatabases.get(i); BasePanel panel = mainFrame.getBasePanelAt(i); - OpenDatabaseAction.performPostOpenActions(panel, pr, mainFrame.getDialogService()); + OpenDatabaseAction.performPostOpenActions(panel, pr); } LOGGER.debug("Finished adding panels"); 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 87dcf8b87a1..170b9369350 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -67,7 +67,7 @@ public OpenDatabaseAction(JabRefFrame frame) { * @param result The result of the BIB file parse operation. * @param dialogService */ - public static void performPostOpenActions(BasePanel panel, ParserResult result, DialogService dialogService) { + public static void performPostOpenActions(BasePanel panel, ParserResult result) { for (GUIPostOpenAction action : OpenDatabaseAction.POST_OPEN_ACTIONS) { if (action.isActionNecessary(result)) { action.performAction(panel, result); @@ -191,7 +191,7 @@ private void openTheFile(Path file, boolean raisePanel) { BackgroundTask.wrap(() -> loadDatabase(file)) .onSuccess(result -> { BasePanel panel = addNewDatabase(result, file, raisePanel); - OpenDatabaseAction.performPostOpenActions(panel, result, dialogService); + OpenDatabaseAction.performPostOpenActions(panel, result); }) .onFailure(ex -> dialogService.showErrorDialogAndWait(Localization.lang("Connection error"), ex.getMessage() + "\n\n" + Localization.lang("A local copy will be opened."))) From e63bc21abb18b2495c961ef46a9f31c1ce99a1f7 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 20 Apr 2019 21:35:13 +0200 Subject: [PATCH 07/16] Adjust save exception to inlcude orgininal stack traces --- .../org/jabref/gui/exporter/SaveDatabaseAction.java | 2 +- .../java/org/jabref/logic/exporter/SaveException.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java index db4a591b1ec..edd299537a3 100644 --- a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java +++ b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java @@ -83,7 +83,7 @@ private boolean saveDatabase(Path file, boolean selectedOnly, Charset encoding, } catch (UnsupportedCharsetException ex) { throw new SaveException(Localization.lang("Character encoding '%0' is not supported.", encoding.displayName()), ex); } catch (IOException ex) { - throw new SaveException(ex); + throw new SaveException("Problems saving:", ex); } return true; diff --git a/src/main/java/org/jabref/logic/exporter/SaveException.java b/src/main/java/org/jabref/logic/exporter/SaveException.java index 88ef9693aed..b3e8c2171c9 100644 --- a/src/main/java/org/jabref/logic/exporter/SaveException.java +++ b/src/main/java/org/jabref/logic/exporter/SaveException.java @@ -15,7 +15,7 @@ public class SaveException extends Exception { public static final SaveException BACKUP_CREATION = new SaveException("Unable to create backup", Localization.lang("Unable to create backup")); - private final BibEntry entry; + private BibEntry entry; private int status; private String localizedMessage; @@ -46,18 +46,18 @@ public SaveException(String message, BibEntry entry) { this.entry = entry; } - public SaveException(String message, String localizedMessage, BibEntry entry) { - super(message); + public SaveException(String message, String localizedMessage, BibEntry entry, Throwable base) { + super(message, base); this.localizedMessage = localizedMessage; this.entry = entry; } public SaveException(Throwable base) { - this(base.getMessage(), base.getLocalizedMessage()); + super(base.getMessage(), base); } public SaveException(Throwable base, BibEntry entry) { - this(base.getMessage(), base.getLocalizedMessage(), entry); + this(base.getMessage(), base.getLocalizedMessage(), entry, base); } public int getStatus() { From 8e0ffe11d1ba4705ecff40bb5854859b4be29f57 Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 22 Apr 2019 23:04:23 +0200 Subject: [PATCH 08/16] Make Group dialog resizable (#4910) Fixes #2419 --- src/main/java/org/jabref/gui/groups/GroupDialog.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/groups/GroupDialog.java b/src/main/java/org/jabref/gui/groups/GroupDialog.java index 9fc080c8749..bfe8032f3b7 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialog.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialog.java @@ -424,8 +424,6 @@ groupName, getContext(), texGroupFilePath.setText(group.getFilePath().toString()); } } - - setResizable(false); getDialogPane().getScene().getWindow().sizeToScene(); } From 8f9358d9e131cf687c7044202527f85826fab3a6 Mon Sep 17 00:00:00 2001 From: znuznu <37243770+znuznu@users.noreply.github.com> Date: Tue, 23 Apr 2019 16:21:52 +0200 Subject: [PATCH 09/16] Rearrange the padding of the "Append library" dialog (#4914) I have added a 5 pixels padding on the left of the container. Also removed a duplicate line related to the padding. --- .../java/org/jabref/gui/importer/AppendDatabaseDialog.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/importer/AppendDatabaseDialog.java b/src/main/java/org/jabref/gui/importer/AppendDatabaseDialog.java index 10a86d95d15..221a93b0d66 100644 --- a/src/main/java/org/jabref/gui/importer/AppendDatabaseDialog.java +++ b/src/main/java/org/jabref/gui/importer/AppendDatabaseDialog.java @@ -38,12 +38,11 @@ private void init() { getDialogPane().setContent(container); container.setHgap(10); container.setVgap(10); - container.setPadding(new Insets(15, 5, 0, 0)); container.add(entries, 0, 0); container.add(strings, 0, 1); container.add(groups, 0, 2); container.add(selector, 0, 3); - container.setPadding(new Insets(15, 5, 0, 0)); + container.setPadding(new Insets(15, 5, 0, 5)); container.setGridLinesVisible(false); } From fb859248dfcb4eebddf075d86ab36d0fd4406917 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Tue, 23 Apr 2019 18:25:24 +0200 Subject: [PATCH 10/16] Create new layout for preferences regarding columns --- .../gui/preferences/TableColumnsTab.fxml | 51 +++++++++++++++++++ .../gui/preferences/TableColumnsTab.java | 4 ++ 2 files changed, 55 insertions(+) create mode 100644 src/main/java/org/jabref/gui/preferences/TableColumnsTab.fxml diff --git a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.fxml b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.fxml new file mode 100644 index 00000000000..7c09e3973df --- /dev/null +++ b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.fxml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java index 18049b23385..c2d9a53c027 100644 --- a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java @@ -316,6 +316,10 @@ public void setValues() { if (extraFileColumns.isSelected()) { List desiredColumns = prefs.getStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS); int listSize = listOfFileColumns.getSelectionModel().getSelectedIndex(); + + if (listSize < 0) { + listSize = 0; + } int[] indicesToSelect = new int[listSize]; for (int i = 0; i < listSize; i++) { indicesToSelect[i] = listSize + 1; From eaf6bf8d3cf40ae543afab51fdb4aed9e1c93cb4 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Tue, 23 Apr 2019 18:28:20 +0200 Subject: [PATCH 11/16] Revert "Create new layout for preferences regarding columns" This reverts commit fb859248dfcb4eebddf075d86ab36d0fd4406917. --- .../gui/preferences/TableColumnsTab.fxml | 51 ------------------- .../gui/preferences/TableColumnsTab.java | 4 -- 2 files changed, 55 deletions(-) delete mode 100644 src/main/java/org/jabref/gui/preferences/TableColumnsTab.fxml diff --git a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.fxml b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.fxml deleted file mode 100644 index 7c09e3973df..00000000000 --- a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.fxml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java index c2d9a53c027..18049b23385 100644 --- a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java @@ -316,10 +316,6 @@ public void setValues() { if (extraFileColumns.isSelected()) { List desiredColumns = prefs.getStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS); int listSize = listOfFileColumns.getSelectionModel().getSelectedIndex(); - - if (listSize < 0) { - listSize = 0; - } int[] indicesToSelect = new int[listSize]; for (int i = 0; i < listSize; i++) { indicesToSelect[i] = listSize + 1; From 23e9e523e36705fd2562c300e4fc7bc73f7ac8c5 Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 23 Apr 2019 18:49:11 +0200 Subject: [PATCH 12/16] Quick fix for error when opening preferences (#4917) --- src/main/java/org/jabref/gui/preferences/TableColumnsTab.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java index 18049b23385..7f5d8ba1198 100644 --- a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java @@ -316,6 +316,9 @@ public void setValues() { if (extraFileColumns.isSelected()) { List desiredColumns = prefs.getStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS); int listSize = listOfFileColumns.getSelectionModel().getSelectedIndex(); + if (listSize < 0) { + listSize = 0; + } int[] indicesToSelect = new int[listSize]; for (int i = 0; i < listSize; i++) { indicesToSelect[i] = listSize + 1; From d8b2c7ef0e7f8149c50a2b4f6b982731d612993a Mon Sep 17 00:00:00 2001 From: Yash Kothari Date: Wed, 24 Apr 2019 19:37:56 +0530 Subject: [PATCH 13/16] Fixes throwing an exception when 'id' field is present in bib file (#4918) * Fixes throwing an exception when 'id' field is present in bib file Fixes #4905 * Remove test for id field * Renamed ID_FIELD to INTERNAL_ID_FIELD * Removed unused import --- src/main/java/org/jabref/model/entry/BibEntry.java | 12 ++---------- .../java/org/jabref/model/entry/BibEntryTest.java | 11 ----------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/jabref/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index 6351d9bde36..be2842e5f88 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -45,7 +45,7 @@ public class BibEntry implements Cloneable { public static final String OBSOLETE_TYPE_HEADER = "bibtextype"; public static final String KEY_FIELD = "bibtexkey"; public static final String DEFAULT_TYPE = "misc"; - protected static final String ID_FIELD = "id"; + protected static final String INTERNAL_ID_FIELD = "JabRef-internal-id"; private static final Logger LOGGER = LoggerFactory.getLogger(BibEntry.class); private static final Pattern REMOVE_TRAILING_WHITESPACE = Pattern.compile("\\s+$"); private final SharedBibEntryData sharedBibEntryData; @@ -161,7 +161,7 @@ public void setId(String id) { String oldId = this.id; - eventBus.post(new FieldChangedEvent(this, BibEntry.ID_FIELD, id, oldId)); + eventBus.post(new FieldChangedEvent(this, BibEntry.INTERNAL_ID_FIELD, id, oldId)); this.id = id; changed = true; } @@ -408,10 +408,6 @@ public Optional setField(String name, String value, EntryEventSourc return Optional.empty(); } - if (BibEntry.ID_FIELD.equals(fieldName)) { - throw new IllegalArgumentException("The field name '" + name + "' is reserved"); - } - changed = true; fields.put(fieldName, value.intern()); @@ -463,10 +459,6 @@ public Optional clearField(String name) { public Optional clearField(String name, EntryEventSource eventSource) { String fieldName = toLowerCase(name); - if (BibEntry.ID_FIELD.equals(fieldName)) { - throw new IllegalArgumentException("The field name '" + name + "' is reserved"); - } - Optional oldValue = getField(fieldName); if (!oldValue.isPresent()) { return Optional.empty(); diff --git a/src/test/java/org/jabref/model/entry/BibEntryTest.java b/src/test/java/org/jabref/model/entry/BibEntryTest.java index 5f7e95f52ac..58261a29bc1 100644 --- a/src/test/java/org/jabref/model/entry/BibEntryTest.java +++ b/src/test/java/org/jabref/model/entry/BibEntryTest.java @@ -12,7 +12,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; public class BibEntryTest { @@ -28,16 +27,6 @@ public void tearDown() { entry = null; } - @Test - public void notOverrideReservedFields() { - assertThrows(IllegalArgumentException.class, () -> entry.setField(BibEntry.ID_FIELD, "somevalue")); - } - - @Test - public void notClearReservedFields() { - assertThrows(IllegalArgumentException.class, () -> entry.clearField(BibEntry.ID_FIELD)); - } - @Test public void getFieldIsCaseInsensitive() throws Exception { entry.setField("TeSt", "value"); From 251c44d37207663834660e9582cb36c9fcedaabe Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 24 Apr 2019 16:36:06 +0200 Subject: [PATCH 14/16] Toggle enable status of menu items (#4872) * Toggle enable status of menu items (prototype) * Use for pushtoapplication * Improve code around push to applications * Set enable status for all actions * Fix tests and checkstyle --- src/main/java/org/jabref/gui/BasePanel.java | 12 +- .../org/jabref/gui/EntryTypeViewModel.java | 1 + src/main/java/org/jabref/gui/JabRefFrame.java | 300 ++++++------------ .../jabref/gui/SaveOrderConfigDisplay.fxml | 1 - .../java/org/jabref/gui/StateManager.java | 17 +- .../org/jabref/gui/actions/ActionFactory.java | 69 +++- .../org/jabref/gui/actions/ActionHelper.java | 16 + .../java/org/jabref/gui/actions/Actions.java | 1 + .../org/jabref/gui/actions/BaseAction.java | 3 + .../gui/actions/BibtexKeyPatternAction.java | 18 -- .../org/jabref/gui/actions/JabRefAction.java | 23 +- .../actions/ManageContentSelectorAction.java | 29 -- .../jabref/gui/actions/OldCommandWrapper.java | 1 + .../OldCommandWrapperForActiveDatabase.java | 1 + .../gui/actions/SetupGeneralFieldsAction.java | 13 - .../org/jabref/gui/actions/SimpleCommand.java | 13 + .../NewSubLibraryAction.java | 11 +- .../BibtexKeyPatternAction.java | 23 ++ .../GenerateBibtexKeyAction.java | 3 +- .../GenerateBibtexKeySingleAction.java | 3 +- .../{actions => cleanup}/CleanupAction.java | 4 +- .../collab/EntryDeleteChangeViewModel.java | 2 +- .../ContentSelectorDialog.fxml | 1 - .../ManageContentSelectorAction.java | 25 ++ .../CopyFilesAction.java | 41 ++- .../jabref/gui/copyfiles/CopyFilesTask.java | 1 - .../SetupGeneralFieldsAction.java | 11 + .../ShowDocumentViewerAction.java | 4 +- .../DuplicateResolverDialog.java | 4 +- .../DuplicateSearch.java | 27 +- .../CopyBibTeXKeyAndLinkAction.java | 3 +- .../{actions => edit}/CopyDoiUrlAction.java | 3 +- .../jabref/gui/edit/ManageKeywordsAction.java | 27 +- .../jabref/gui/edit/MassSetFieldsAction.java | 32 +- .../jabref/gui/edit/MassSetFieldsDialog.java | 19 +- .../{actions => edit}/OpenBrowserAction.java | 4 +- .../jabref/gui/entryeditor/EntryEditor.java | 2 +- .../ManageCustomExportsAction.java | 4 +- .../{actions => exporter}/WriteXMPAction.java | 4 +- .../externalfiles/AutoLinkFilesAction.java | 31 +- .../FindUnlinkedFilesAction.java | 13 +- .../FindUnlinkedFilesDialog.java | 12 +- .../EditExternalFileTypeEntryDialog.fxml | 1 - .../EditExternalFileTypesAction.java | 4 +- .../BibtexKeyEditorViewModel.java | 2 +- .../fieldeditors/contextmenu/EditorMenus.java | 2 +- .../{actions => help}/ErrorConsoleAction.java | 3 +- .../SearchForUpdateAction.java | 4 +- .../gui/importer/ImportEntriesViewModel.java | 2 +- .../ManageCustomImportsAction.java | 4 +- .../NewDatabaseAction.java | 3 +- .../{actions => importer}/NewEntryAction.java | 21 +- .../fetcher}/LookupIdentifierAction.java | 35 +- .../gui/integrity/IntegrityCheckAction.java | 19 +- .../ManageJournalsAction.java | 4 +- .../CustomizeKeyBindingAction.java | 4 +- .../LibraryPropertiesAction.java | 11 +- .../LibraryPropertiesDialog.fxml | 1 - .../gui/mergeentries/MergeEntriesAction.java | 13 +- .../metadata/BibtexStringEditorAction.java | 18 +- .../metadata/BibtexStringEditorDialog.fxml | 1 - .../jabref/gui/metadata/PreambleEditor.java | 39 ++- .../jabref/gui/preferences/ExternalTab.java | 6 +- .../gui/preferences/PreferencesDialog.fxml | 3 +- .../ShowPreferencesAction.java | 4 +- .../gui/push/AbstractPushToApplication.java | 26 +- .../jabref/gui/push/PushToApplication.java | 12 +- .../gui/push/PushToApplicationAction.java | 112 +++---- ...ns.java => PushToApplicationsManager.java} | 14 +- .../java/org/jabref/gui/push/PushToEmacs.java | 12 +- .../java/org/jabref/gui/push/PushToLyx.java | 23 +- .../java/org/jabref/gui/push/PushToVim.java | 12 +- .../ConnectToSharedDatabaseCommand.java | 4 +- .../gui/shared/SharedDatabaseLoginDialog.fxml | 3 +- .../gui/shared/SharedDatabaseUIManager.java | 2 +- .../jabref/gui/undo/UndoableRemoveEntry.java | 9 +- .../org/jabref/gui/util/BindingsHelper.java | 11 + .../gui/util/OptionalObjectProperty.java | 45 +++ src/main/resources/l10n/JabRef_en.properties | 1 - 79 files changed, 691 insertions(+), 631 deletions(-) create mode 100644 src/main/java/org/jabref/gui/actions/ActionHelper.java delete mode 100644 src/main/java/org/jabref/gui/actions/BibtexKeyPatternAction.java delete mode 100644 src/main/java/org/jabref/gui/actions/ManageContentSelectorAction.java delete mode 100644 src/main/java/org/jabref/gui/actions/SetupGeneralFieldsAction.java rename src/main/java/org/jabref/gui/{actions => auximport}/NewSubLibraryAction.java (56%) create mode 100644 src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternAction.java rename src/main/java/org/jabref/gui/{actions => bibtexkeypattern}/GenerateBibtexKeyAction.java (98%) rename src/main/java/org/jabref/gui/{actions => bibtexkeypattern}/GenerateBibtexKeySingleAction.java (94%) rename src/main/java/org/jabref/gui/{actions => cleanup}/CleanupAction.java (98%) create mode 100644 src/main/java/org/jabref/gui/contentselector/ManageContentSelectorAction.java rename src/main/java/org/jabref/gui/{actions => copyfiles}/CopyFilesAction.java (66%) create mode 100644 src/main/java/org/jabref/gui/customizefields/SetupGeneralFieldsAction.java rename src/main/java/org/jabref/gui/{actions => documentviewer}/ShowDocumentViewerAction.java (63%) rename src/main/java/org/jabref/gui/{ => duplicationFinder}/DuplicateResolverDialog.java (97%) rename src/main/java/org/jabref/gui/{ => duplicationFinder}/DuplicateSearch.java (89%) rename src/main/java/org/jabref/gui/{actions => edit}/CopyBibTeXKeyAndLinkAction.java (97%) rename src/main/java/org/jabref/gui/{actions => edit}/CopyDoiUrlAction.java (93%) rename src/main/java/org/jabref/gui/{actions => edit}/OpenBrowserAction.java (82%) rename src/main/java/org/jabref/gui/{actions => exporter}/ManageCustomExportsAction.java (64%) rename src/main/java/org/jabref/gui/{actions => exporter}/WriteXMPAction.java (99%) rename src/main/java/org/jabref/gui/{actions => externalfiletype}/EditExternalFileTypesAction.java (69%) rename src/main/java/org/jabref/gui/{actions => help}/ErrorConsoleAction.java (86%) rename src/main/java/org/jabref/gui/{actions => help}/SearchForUpdateAction.java (92%) rename src/main/java/org/jabref/gui/{actions => importer}/ManageCustomImportsAction.java (70%) rename src/main/java/org/jabref/gui/{actions => importer}/NewDatabaseAction.java (92%) rename src/main/java/org/jabref/gui/{actions => importer}/NewEntryAction.java (80%) rename src/main/java/org/jabref/gui/{actions => importer/fetcher}/LookupIdentifierAction.java (78%) rename src/main/java/org/jabref/gui/{actions => journals}/ManageJournalsAction.java (63%) rename src/main/java/org/jabref/gui/{actions => keyboard}/CustomizeKeyBindingAction.java (65%) rename src/main/java/org/jabref/gui/{actions => libraryproperties}/LibraryPropertiesAction.java (66%) rename src/main/java/org/jabref/gui/{actions => preferences}/ShowPreferencesAction.java (87%) rename src/main/java/org/jabref/gui/push/{PushToApplications.java => PushToApplicationsManager.java} (67%) rename src/main/java/org/jabref/gui/{actions => shared}/ConnectToSharedDatabaseCommand.java (82%) create mode 100644 src/main/java/org/jabref/gui/util/OptionalObjectProperty.java diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index 1da5e9c58e1..055eaba332f 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -30,20 +30,20 @@ import org.jabref.JabRefExecutorService; import org.jabref.gui.actions.Actions; import org.jabref.gui.actions.BaseAction; -import org.jabref.gui.actions.CleanupAction; -import org.jabref.gui.actions.CopyBibTeXKeyAndLinkAction; -import org.jabref.gui.actions.GenerateBibtexKeyAction; -import org.jabref.gui.actions.WriteXMPAction; import org.jabref.gui.autocompleter.AutoCompletePreferences; import org.jabref.gui.autocompleter.AutoCompleteUpdater; import org.jabref.gui.autocompleter.PersonNameSuggestionProvider; import org.jabref.gui.autocompleter.SuggestionProviders; +import org.jabref.gui.bibtexkeypattern.GenerateBibtexKeyAction; +import org.jabref.gui.cleanup.CleanupAction; import org.jabref.gui.collab.DatabaseChangeMonitor; import org.jabref.gui.collab.DatabaseChangePane; import org.jabref.gui.desktop.JabRefDesktop; +import org.jabref.gui.edit.CopyBibTeXKeyAndLinkAction; import org.jabref.gui.edit.ReplaceStringAction; import org.jabref.gui.entryeditor.EntryEditor; import org.jabref.gui.exporter.SaveDatabaseAction; +import org.jabref.gui.exporter.WriteXMPAction; import org.jabref.gui.externalfiles.FindFullTextAction; import org.jabref.gui.externalfiletype.ExternalFileMenuItem; import org.jabref.gui.externalfiletype.ExternalFileType; @@ -294,7 +294,7 @@ private void setupActions() { // The action for cleaning up entry. actions.put(Actions.CLEANUP, cleanUpAction); - actions.put(Actions.MERGE_ENTRIES, () -> new MergeEntriesAction(frame).execute()); + actions.put(Actions.MERGE_ENTRIES, () -> new MergeEntriesAction(frame, Globals.stateManager).execute()); // The action for copying the selected entry's key. actions.put(Actions.COPY_KEY, this::copyKey); @@ -432,7 +432,7 @@ private void delete(boolean cut, List entries) { compound = new NamedCompound((entries.size() > 1 ? Localization.lang("delete entries") : Localization.lang("delete entry"))); } for (BibEntry entry : entries) { - compound.addEdit(new UndoableRemoveEntry(bibDatabaseContext.getDatabase(), entry, BasePanel.this)); + compound.addEdit(new UndoableRemoveEntry(bibDatabaseContext.getDatabase(), entry)); bibDatabaseContext.getDatabase().removeEntry(entry); ensureNotShowingBottomPanel(entry); } diff --git a/src/main/java/org/jabref/gui/EntryTypeViewModel.java b/src/main/java/org/jabref/gui/EntryTypeViewModel.java index 766d449f6c4..f6956a4ac23 100644 --- a/src/main/java/org/jabref/gui/EntryTypeViewModel.java +++ b/src/main/java/org/jabref/gui/EntryTypeViewModel.java @@ -14,6 +14,7 @@ import javafx.concurrent.Task; import javafx.concurrent.Worker; +import org.jabref.gui.duplicationFinder.DuplicateResolverDialog; import org.jabref.logic.bibtex.DuplicateCheck; import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator; import org.jabref.logic.importer.FetcherException; diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 9b2a792ec93..2fff7ba1116 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -1,6 +1,5 @@ package org.jabref.gui; -import java.awt.Component; import java.awt.Window; import java.io.File; import java.io.IOException; @@ -8,7 +7,6 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -16,15 +14,12 @@ import java.util.TimerTask; import java.util.stream.Collectors; -import javax.swing.Action; import javax.swing.JOptionPane; -import javax.swing.JPanel; import javax.swing.SwingUtilities; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; -import javafx.collections.ListChangeListener; import javafx.geometry.Orientation; import javafx.scene.Node; import javafx.scene.control.Alert; @@ -55,54 +50,55 @@ import org.jabref.JabRefExecutorService; import org.jabref.gui.actions.ActionFactory; import org.jabref.gui.actions.Actions; -import org.jabref.gui.actions.BibtexKeyPatternAction; -import org.jabref.gui.actions.ConnectToSharedDatabaseCommand; -import org.jabref.gui.actions.CopyFilesAction; -import org.jabref.gui.actions.CustomizeKeyBindingAction; -import org.jabref.gui.actions.EditExternalFileTypesAction; -import org.jabref.gui.actions.ErrorConsoleAction; -import org.jabref.gui.actions.LibraryPropertiesAction; -import org.jabref.gui.actions.LookupIdentifierAction; -import org.jabref.gui.actions.ManageContentSelectorAction; -import org.jabref.gui.actions.ManageCustomExportsAction; -import org.jabref.gui.actions.ManageCustomImportsAction; -import org.jabref.gui.actions.ManageJournalsAction; -import org.jabref.gui.actions.NewDatabaseAction; -import org.jabref.gui.actions.NewEntryAction; -import org.jabref.gui.actions.NewSubLibraryAction; import org.jabref.gui.actions.OldDatabaseCommandWrapper; -import org.jabref.gui.actions.OpenBrowserAction; -import org.jabref.gui.actions.SearchForUpdateAction; -import org.jabref.gui.actions.SetupGeneralFieldsAction; -import org.jabref.gui.actions.ShowDocumentViewerAction; -import org.jabref.gui.actions.ShowPreferencesAction; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.actions.StandardActions; +import org.jabref.gui.auximport.NewSubLibraryAction; +import org.jabref.gui.bibtexkeypattern.BibtexKeyPatternAction; +import org.jabref.gui.contentselector.ManageContentSelectorAction; +import org.jabref.gui.copyfiles.CopyFilesAction; +import org.jabref.gui.customizefields.SetupGeneralFieldsAction; import org.jabref.gui.dialogs.AutosaveUIManager; +import org.jabref.gui.documentviewer.ShowDocumentViewerAction; +import org.jabref.gui.duplicationFinder.DuplicateSearch; import org.jabref.gui.edit.ManageKeywordsAction; import org.jabref.gui.edit.MassSetFieldsAction; +import org.jabref.gui.edit.OpenBrowserAction; import org.jabref.gui.exporter.ExportCommand; import org.jabref.gui.exporter.ExportToClipboardAction; +import org.jabref.gui.exporter.ManageCustomExportsAction; import org.jabref.gui.exporter.SaveAllAction; import org.jabref.gui.exporter.SaveDatabaseAction; import org.jabref.gui.externalfiles.AutoLinkFilesAction; import org.jabref.gui.externalfiles.FindUnlinkedFilesAction; +import org.jabref.gui.externalfiletype.EditExternalFileTypesAction; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.help.AboutAction; +import org.jabref.gui.help.ErrorConsoleAction; import org.jabref.gui.help.HelpAction; +import org.jabref.gui.help.SearchForUpdateAction; import org.jabref.gui.importer.ImportCommand; import org.jabref.gui.importer.ImportEntriesDialog; +import org.jabref.gui.importer.ManageCustomImportsAction; +import org.jabref.gui.importer.NewDatabaseAction; +import org.jabref.gui.importer.NewEntryAction; import org.jabref.gui.importer.actions.OpenDatabaseAction; +import org.jabref.gui.importer.fetcher.LookupIdentifierAction; import org.jabref.gui.integrity.IntegrityCheckAction; +import org.jabref.gui.journals.ManageJournalsAction; +import org.jabref.gui.keyboard.CustomizeKeyBindingAction; import org.jabref.gui.keyboard.KeyBinding; +import org.jabref.gui.libraryproperties.LibraryPropertiesAction; import org.jabref.gui.menus.FileHistoryMenu; import org.jabref.gui.mergeentries.MergeEntriesAction; import org.jabref.gui.metadata.BibtexStringEditorAction; import org.jabref.gui.metadata.PreambleEditor; +import org.jabref.gui.preferences.ShowPreferencesAction; import org.jabref.gui.protectedterms.ManageProtectedTermsAction; import org.jabref.gui.push.PushToApplicationAction; -import org.jabref.gui.push.PushToApplications; +import org.jabref.gui.push.PushToApplicationsManager; import org.jabref.gui.search.GlobalSearchBar; +import org.jabref.gui.shared.ConnectToSharedDatabaseCommand; import org.jabref.gui.specialfields.SpecialFieldMenuItemFactory; import org.jabref.gui.undo.CountingUndoManager; import org.jabref.gui.util.BackgroundTask; @@ -153,52 +149,20 @@ public class JabRefFrame extends BorderPane { private final ProgressBar progressBar = new ProgressBar(); private final FileHistoryMenu fileHistory = new FileHistoryMenu(prefs, this); - // Lists containing different subsets of actions for different purposes - private final List specialFieldButtons = new LinkedList<>(); - private final List openDatabaseOnlyActions = new LinkedList<>(); - private final List severalDatabasesOnlyActions = new LinkedList<>(); - private final List openAndSavedDatabasesOnlyActions = new LinkedList<>(); - private final List sharedDatabaseOnlyActions = new LinkedList<>(); - private final List noSharedDatabaseActions = new LinkedList<>(); - private final List oneEntryOnlyActions = new LinkedList<>(); - private final List oneEntryWithFileOnlyActions = new LinkedList<>(); - private final List oneEntryWithURLorDOIOnlyActions = new LinkedList<>(); - private final List twoEntriesOnlyActions = new LinkedList<>(); - private final List atLeastOneEntryActions = new LinkedList<>(); private final Stage mainStage; - // The sidepane manager takes care of populating the sidepane. + private final StateManager stateManager; + private final CountingUndoManager undoManager; private SidePaneManager sidePaneManager; private TabPane tabbedPane; - private PushToApplications pushApplications; + private PushToApplicationsManager pushApplications; private final DialogService dialogService; private SidePane sidePane; public JabRefFrame(Stage mainStage) { this.mainStage = mainStage; this.dialogService = new JabRefDialogService(mainStage, this); - } - - /** - * Takes a list of Object and calls the method setEnabled on them, depending on whether it is an Action or a - * Component. - * - * @param list List that should contain Actions and Components. - */ - private static void setEnabled(List list, boolean enabled) { - for (Object actionOrComponent : list) { - if (actionOrComponent instanceof Action) { - ((Action) actionOrComponent).setEnabled(enabled); - } - if (actionOrComponent instanceof Component) { - ((Component) actionOrComponent).setEnabled(enabled); - if (actionOrComponent instanceof JPanel) { - JPanel root = (JPanel) actionOrComponent; - for (int index = 0; index < root.getComponentCount(); index++) { - root.getComponent(index).setEnabled(enabled); - } - } - } - } + this.stateManager = Globals.stateManager; + this.undoManager = Globals.undoManager; } public void init() { @@ -210,8 +174,6 @@ public void init() { initLayout(); - initActions(); - initKeyBindings(); tabbedPane.setOnDragOver(event -> { @@ -249,7 +211,7 @@ public void init() { */ EasyBind.subscribe(tabbedPane.getSelectionModel().selectedItemProperty(), e -> { if (e == null) { - Globals.stateManager.activeDatabaseProperty().setValue(Optional.empty()); + stateManager.activeDatabaseProperty().setValue(Optional.empty()); return; } @@ -259,8 +221,8 @@ public void init() { } // Poor-mans binding to global state - // We need to invoke this in the JavaFX thread as all the listeners sit there - Platform.runLater(() -> Globals.stateManager.activeDatabaseProperty().setValue(Optional.of(currentBasePanel.getBibDatabaseContext()))); + stateManager.activeDatabaseProperty().setValue(Optional.of(currentBasePanel.getBibDatabaseContext())); + stateManager.setSelectedEntries(currentBasePanel.getSelectedEntries()); // Update search query String content = ""; @@ -489,7 +451,7 @@ public boolean quit() { private void initLayout() { setProgressBarVisible(false); - pushApplications = new PushToApplications(this.getDialogService()); + pushApplications = new PushToApplicationsManager(this.getDialogService()); BorderPane head = new BorderPane(); head.setTop(createMenu()); @@ -553,27 +515,27 @@ private Node createToolbar() { HBox leftSide = new HBox( newLibrary, factory.createIconButton(StandardActions.OPEN_LIBRARY, new OpenDatabaseAction(this)), - factory.createIconButton(StandardActions.SAVE_LIBRARY, new OldDatabaseCommandWrapper(Actions.SAVE, this, Globals.stateManager)), + factory.createIconButton(StandardActions.SAVE_LIBRARY, new OldDatabaseCommandWrapper(Actions.SAVE, this, stateManager)), leftSpacer ); leftSide.setMinWidth(100); leftSide.prefWidthProperty().bind(sidePane.widthProperty()); leftSide.maxWidthProperty().bind(sidePane.widthProperty()); - PushToApplicationAction pushToApplicationAction = new PushToApplicationAction(this, Globals.stateManager); + PushToApplicationAction pushToApplicationAction = new PushToApplicationAction(stateManager, this.getPushApplications(), this.getDialogService()); HBox rightSide = new HBox( - factory.createIconButton(StandardActions.NEW_ARTICLE, new NewEntryAction(this, BiblatexEntryTypes.ARTICLE, dialogService, Globals.prefs)), - factory.createIconButton(StandardActions.DELETE_ENTRY, new OldDatabaseCommandWrapper(Actions.DELETE, this, Globals.stateManager)), + factory.createIconButton(StandardActions.NEW_ARTICLE, new NewEntryAction(this, BiblatexEntryTypes.ARTICLE, dialogService, Globals.prefs, stateManager)), + factory.createIconButton(StandardActions.DELETE_ENTRY, new OldDatabaseCommandWrapper(Actions.DELETE, this, stateManager)), new Separator(Orientation.VERTICAL), - factory.createIconButton(StandardActions.UNDO, new OldDatabaseCommandWrapper(Actions.UNDO, this, Globals.stateManager)), - factory.createIconButton(StandardActions.REDO, new OldDatabaseCommandWrapper(Actions.REDO, this, Globals.stateManager)), - factory.createIconButton(StandardActions.CUT, new OldDatabaseCommandWrapper(Actions.CUT, this, Globals.stateManager)), - factory.createIconButton(StandardActions.COPY, new OldDatabaseCommandWrapper(Actions.COPY, this, Globals.stateManager)), - factory.createIconButton(StandardActions.PASTE, new OldDatabaseCommandWrapper(Actions.PASTE, this, Globals.stateManager)), + factory.createIconButton(StandardActions.UNDO, new OldDatabaseCommandWrapper(Actions.UNDO, this, stateManager)), + factory.createIconButton(StandardActions.REDO, new OldDatabaseCommandWrapper(Actions.REDO, this, stateManager)), + factory.createIconButton(StandardActions.CUT, new OldDatabaseCommandWrapper(Actions.CUT, this, stateManager)), + factory.createIconButton(StandardActions.COPY, new OldDatabaseCommandWrapper(Actions.COPY, this, stateManager)), + factory.createIconButton(StandardActions.PASTE, new OldDatabaseCommandWrapper(Actions.PASTE, this, stateManager)), new Separator(Orientation.VERTICAL), factory.createIconButton(pushToApplicationAction.getActionInformation(), pushToApplicationAction), - factory.createIconButton(StandardActions.GENERATE_CITE_KEYS, new OldDatabaseCommandWrapper(Actions.MAKE_KEY, this, Globals.stateManager)), - factory.createIconButton(StandardActions.CLEANUP_ENTRIES, new OldDatabaseCommandWrapper(Actions.CLEANUP, this, Globals.stateManager)), + factory.createIconButton(StandardActions.GENERATE_CITE_KEYS, new OldDatabaseCommandWrapper(Actions.MAKE_KEY, this, stateManager)), + factory.createIconButton(StandardActions.CLEANUP_ENTRIES, new OldDatabaseCommandWrapper(Actions.CLEANUP, this, stateManager)), new Separator(Orientation.VERTICAL), factory.createIconButton(StandardActions.FORK_ME, new OpenBrowserAction("https://github.com/JabRef/jabref")), factory.createIconButton(StandardActions.OPEN_FACEBOOK, new OpenBrowserAction("https://www.facebook.com/JabRef/")), @@ -682,24 +644,24 @@ private MenuBar createMenu() { factory.createMenuItem(StandardActions.OPEN_LIBRARY, getOpenDatabaseAction()), fileHistory, - factory.createMenuItem(StandardActions.SAVE_LIBRARY, new OldDatabaseCommandWrapper(Actions.SAVE, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.SAVE_LIBRARY_AS, new OldDatabaseCommandWrapper(Actions.SAVE_AS, this, Globals.stateManager)), + factory.createMenuItem(StandardActions.SAVE_LIBRARY, new OldDatabaseCommandWrapper(Actions.SAVE, this, stateManager)), + factory.createMenuItem(StandardActions.SAVE_LIBRARY_AS, new OldDatabaseCommandWrapper(Actions.SAVE_AS, this, stateManager)), factory.createMenuItem(StandardActions.SAVE_ALL, new SaveAllAction(this)), new SeparatorMenuItem(), factory.createSubMenu(StandardActions.IMPORT, - factory.createMenuItem(StandardActions.MERGE_DATABASE, new OldDatabaseCommandWrapper(Actions.MERGE_DATABASE, this, Globals.stateManager)), // TODO: merge with import + factory.createMenuItem(StandardActions.MERGE_DATABASE, new OldDatabaseCommandWrapper(Actions.MERGE_DATABASE, this, stateManager)), // TODO: merge with import factory.createMenuItem(StandardActions.IMPORT_INTO_CURRENT_LIBRARY, new ImportCommand(this, false)), factory.createMenuItem(StandardActions.IMPORT_INTO_NEW_LIBRARY, new ImportCommand(this, true))), factory.createSubMenu(StandardActions.EXPORT, factory.createMenuItem(StandardActions.EXPORT_ALL, new ExportCommand(this, false, Globals.prefs)), factory.createMenuItem(StandardActions.EXPORT_SELECTED, new ExportCommand(this, true, Globals.prefs)), - factory.createMenuItem(StandardActions.SAVE_SELECTED_AS_PLAIN_BIBTEX, new OldDatabaseCommandWrapper(Actions.SAVE_SELECTED_AS_PLAIN, this, Globals.stateManager))), + factory.createMenuItem(StandardActions.SAVE_SELECTED_AS_PLAIN_BIBTEX, new OldDatabaseCommandWrapper(Actions.SAVE_SELECTED_AS_PLAIN, this, stateManager))), factory.createMenuItem(StandardActions.CONNECT_TO_SHARED_DB, new ConnectToSharedDatabaseCommand(this)), - factory.createMenuItem(StandardActions.PULL_CHANGES_FROM_SHARED_DB, new OldDatabaseCommandWrapper(Actions.PULL_CHANGES_FROM_SHARED_DATABASE, this, Globals.stateManager)), + factory.createMenuItem(StandardActions.PULL_CHANGES_FROM_SHARED_DB, new OldDatabaseCommandWrapper(Actions.PULL_CHANGES_FROM_SHARED_DATABASE, this, stateManager)), new SeparatorMenuItem(), @@ -708,8 +670,8 @@ private MenuBar createMenu() { ); edit.getItems().addAll( - factory.createMenuItem(StandardActions.UNDO, new OldDatabaseCommandWrapper(Actions.UNDO, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.REDO, new OldDatabaseCommandWrapper(Actions.REDO, this, Globals.stateManager)), + factory.createMenuItem(StandardActions.UNDO, new OldDatabaseCommandWrapper(Actions.UNDO, this, stateManager)), + factory.createMenuItem(StandardActions.REDO, new OldDatabaseCommandWrapper(Actions.REDO, this, stateManager)), new SeparatorMenuItem(), @@ -717,25 +679,25 @@ private MenuBar createMenu() { factory.createMenuItem(StandardActions.COPY, new EditAction(Actions.COPY)), factory.createSubMenu(StandardActions.COPY_MORE, - factory.createMenuItem(StandardActions.COPY_TITLE, new OldDatabaseCommandWrapper(Actions.COPY_TITLE, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.COPY_KEY, new OldDatabaseCommandWrapper(Actions.COPY_KEY, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.COPY_CITE_KEY, new OldDatabaseCommandWrapper(Actions.COPY_CITE_KEY, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.COPY_KEY_AND_TITLE, new OldDatabaseCommandWrapper(Actions.COPY_KEY_AND_TITLE, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.COPY_KEY_AND_LINK, new OldDatabaseCommandWrapper(Actions.COPY_KEY_AND_LINK, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.COPY_CITATION_PREVIEW, new OldDatabaseCommandWrapper(Actions.COPY_CITATION_HTML, this, Globals.stateManager)), + factory.createMenuItem(StandardActions.COPY_TITLE, new OldDatabaseCommandWrapper(Actions.COPY_TITLE, this, stateManager)), + factory.createMenuItem(StandardActions.COPY_KEY, new OldDatabaseCommandWrapper(Actions.COPY_KEY, this, stateManager)), + factory.createMenuItem(StandardActions.COPY_CITE_KEY, new OldDatabaseCommandWrapper(Actions.COPY_CITE_KEY, this, stateManager)), + factory.createMenuItem(StandardActions.COPY_KEY_AND_TITLE, new OldDatabaseCommandWrapper(Actions.COPY_KEY_AND_TITLE, this, stateManager)), + factory.createMenuItem(StandardActions.COPY_KEY_AND_LINK, new OldDatabaseCommandWrapper(Actions.COPY_KEY_AND_LINK, this, stateManager)), + factory.createMenuItem(StandardActions.COPY_CITATION_PREVIEW, new OldDatabaseCommandWrapper(Actions.COPY_CITATION_HTML, this, stateManager)), factory.createMenuItem(StandardActions.EXPORT_SELECTED_TO_CLIPBOARD, new ExportToClipboardAction(this, dialogService))), factory.createMenuItem(StandardActions.PASTE, new EditAction(Actions.PASTE)), new SeparatorMenuItem(), - factory.createMenuItem(StandardActions.MANAGE_KEYWORDS, new ManageKeywordsAction(this)) + factory.createMenuItem(StandardActions.MANAGE_KEYWORDS, new ManageKeywordsAction(stateManager)) ); if (Globals.prefs.getBoolean(JabRefPreferences.SPECIALFIELDSENABLED)) { boolean menuItemAdded = false; if (Globals.prefs.getBoolean(JabRefPreferences.SHOWCOLUMN_RANKING)) { - edit.getItems().add(SpecialFieldMenuItemFactory.createSpecialFieldMenuForActiveDatabase(SpecialField.RANKING, factory, Globals.undoManager)); + edit.getItems().add(SpecialFieldMenuItemFactory.createSpecialFieldMenuForActiveDatabase(SpecialField.RANKING, factory, undoManager)); menuItemAdded = true; } @@ -755,12 +717,12 @@ private MenuBar createMenu() { } if (Globals.prefs.getBoolean(JabRefPreferences.SHOWCOLUMN_PRIORITY)) { - edit.getItems().add(SpecialFieldMenuItemFactory.createSpecialFieldMenuForActiveDatabase(SpecialField.PRIORITY, factory, Globals.undoManager)); + edit.getItems().add(SpecialFieldMenuItemFactory.createSpecialFieldMenuForActiveDatabase(SpecialField.PRIORITY, factory, undoManager)); menuItemAdded = true; } if (Globals.prefs.getBoolean(JabRefPreferences.SHOWCOLUMN_READ)) { - edit.getItems().add(SpecialFieldMenuItemFactory.createSpecialFieldMenuForActiveDatabase(SpecialField.READ_STATUS, factory, Globals.undoManager)); + edit.getItems().add(SpecialFieldMenuItemFactory.createSpecialFieldMenuForActiveDatabase(SpecialField.READ_STATUS, factory, undoManager)); menuItemAdded = true; } @@ -770,59 +732,59 @@ private MenuBar createMenu() { } //@formatter:off library.getItems().addAll( - factory.createMenuItem(StandardActions.NEW_ENTRY, new NewEntryAction(this, dialogService, Globals.prefs)), - factory.createMenuItem(StandardActions.DELETE_ENTRY, new OldDatabaseCommandWrapper(Actions.DELETE, this, Globals.stateManager)), + factory.createMenuItem(StandardActions.NEW_ENTRY, new NewEntryAction(this, dialogService, Globals.prefs, stateManager)), + factory.createMenuItem(StandardActions.DELETE_ENTRY, new OldDatabaseCommandWrapper(Actions.DELETE, this, stateManager)), new SeparatorMenuItem(), - factory.createMenuItem(StandardActions.LIBRARY_PROPERTIES, new LibraryPropertiesAction(this, dialogService)), - factory.createMenuItem(StandardActions.EDIT_PREAMBLE, new PreambleEditor(this)), - factory.createMenuItem(StandardActions.EDIT_STRINGS, new BibtexStringEditorAction(this)), - factory.createMenuItem(StandardActions.MANAGE_CITE_KEY_PATTERNS, new BibtexKeyPatternAction(this)), - factory.createMenuItem(StandardActions.MASS_SET_FIELDS, new MassSetFieldsAction(this)) + factory.createMenuItem(StandardActions.LIBRARY_PROPERTIES, new LibraryPropertiesAction(this, dialogService, stateManager)), + factory.createMenuItem(StandardActions.EDIT_PREAMBLE, new PreambleEditor(stateManager, undoManager, this.getDialogService())), + factory.createMenuItem(StandardActions.EDIT_STRINGS, new BibtexStringEditorAction(stateManager)), + factory.createMenuItem(StandardActions.MANAGE_CITE_KEY_PATTERNS, new BibtexKeyPatternAction(this, stateManager)), + factory.createMenuItem(StandardActions.MASS_SET_FIELDS, new MassSetFieldsAction(stateManager, dialogService, undoManager)) ); Menu lookupIdentifiers = factory.createSubMenu(StandardActions.LOOKUP_DOC_IDENTIFIER); for (IdFetcher fetcher : WebFetchers.getIdFetchers(Globals.prefs.getImportFormatPreferences())) { - LookupIdentifierAction identifierAction = new LookupIdentifierAction<>(this, fetcher); + LookupIdentifierAction identifierAction = new LookupIdentifierAction<>(this, fetcher, stateManager, undoManager); lookupIdentifiers.getItems().add(factory.createMenuItem(identifierAction.getAction(), identifierAction)); } quality.getItems().addAll( - factory.createMenuItem(StandardActions.FIND_DUPLICATES, new DuplicateSearch(this, dialogService)), - factory.createMenuItem(StandardActions.MERGE_ENTRIES, new MergeEntriesAction(this)), - factory.createMenuItem(StandardActions.CHECK_INTEGRITY, new IntegrityCheckAction(this)), - factory.createMenuItem(StandardActions.CLEANUP_ENTRIES, new OldDatabaseCommandWrapper(Actions.CLEANUP, this, Globals.stateManager)), + factory.createMenuItem(StandardActions.FIND_DUPLICATES, new DuplicateSearch(this, dialogService, stateManager)), + factory.createMenuItem(StandardActions.MERGE_ENTRIES, new MergeEntriesAction(this, stateManager)), + factory.createMenuItem(StandardActions.CHECK_INTEGRITY, new IntegrityCheckAction(this, stateManager, Globals.TASK_EXECUTOR)), + factory.createMenuItem(StandardActions.CLEANUP_ENTRIES, new OldDatabaseCommandWrapper(Actions.CLEANUP, this, stateManager)), new SeparatorMenuItem(), - factory.createMenuItem(StandardActions.SET_FILE_LINKS, new AutoLinkFilesAction(this, prefs)) + factory.createMenuItem(StandardActions.SET_FILE_LINKS, new AutoLinkFilesAction(this, prefs, stateManager, undoManager)) ); - final PushToApplicationAction pushToApplicationAction = new PushToApplicationAction(this, Globals.stateManager); + final PushToApplicationAction pushToApplicationAction = new PushToApplicationAction(stateManager, this.getPushApplications(), this.getDialogService()); tools.getItems().addAll( - factory.createMenuItem(StandardActions.NEW_SUB_LIBRARY_FROM_AUX, new NewSubLibraryAction(this)), - factory.createMenuItem(StandardActions.FIND_UNLINKED_FILES, new FindUnlinkedFilesAction(this)), - factory.createMenuItem(StandardActions.WRITE_XMP, new OldDatabaseCommandWrapper(Actions.WRITE_XMP, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.COPY_LINKED_FILES, new CopyFilesAction(this)), + factory.createMenuItem(StandardActions.NEW_SUB_LIBRARY_FROM_AUX, new NewSubLibraryAction(this, stateManager)), + factory.createMenuItem(StandardActions.FIND_UNLINKED_FILES, new FindUnlinkedFilesAction(this, stateManager)), + factory.createMenuItem(StandardActions.WRITE_XMP, new OldDatabaseCommandWrapper(Actions.WRITE_XMP, this, stateManager)), + factory.createMenuItem(StandardActions.COPY_LINKED_FILES, new CopyFilesAction(stateManager, this.getDialogService())), new SeparatorMenuItem(), lookupIdentifiers, - factory.createMenuItem(StandardActions.DOWNLOAD_FULL_TEXT, new OldDatabaseCommandWrapper(Actions.DOWNLOAD_FULL_TEXT, this, Globals.stateManager)), + factory.createMenuItem(StandardActions.DOWNLOAD_FULL_TEXT, new OldDatabaseCommandWrapper(Actions.DOWNLOAD_FULL_TEXT, this, stateManager)), new SeparatorMenuItem(), - factory.createMenuItem(StandardActions.GENERATE_CITE_KEYS, new OldDatabaseCommandWrapper(Actions.MAKE_KEY, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.REPLACE_ALL, new OldDatabaseCommandWrapper(Actions.REPLACE_ALL, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.SEND_AS_EMAIL, new OldDatabaseCommandWrapper(Actions.SEND_AS_EMAIL, this, Globals.stateManager)), + factory.createMenuItem(StandardActions.GENERATE_CITE_KEYS, new OldDatabaseCommandWrapper(Actions.MAKE_KEY, this, stateManager)), + factory.createMenuItem(StandardActions.REPLACE_ALL, new OldDatabaseCommandWrapper(Actions.REPLACE_ALL, this, stateManager)), + factory.createMenuItem(StandardActions.SEND_AS_EMAIL, new OldDatabaseCommandWrapper(Actions.SEND_AS_EMAIL, this, stateManager)), factory.createMenuItem(pushToApplicationAction.getActionInformation(), pushToApplicationAction), factory.createSubMenu(StandardActions.ABBREVIATE, - factory.createMenuItem(StandardActions.ABBREVIATE_ISO, new OldDatabaseCommandWrapper(Actions.ABBREVIATE_ISO, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.ABBREVIATE_MEDLINE, new OldDatabaseCommandWrapper(Actions.ABBREVIATE_MEDLINE, this, Globals.stateManager))), + factory.createMenuItem(StandardActions.ABBREVIATE_ISO, new OldDatabaseCommandWrapper(Actions.ABBREVIATE_ISO, this, stateManager)), + factory.createMenuItem(StandardActions.ABBREVIATE_MEDLINE, new OldDatabaseCommandWrapper(Actions.ABBREVIATE_MEDLINE, this, stateManager))), - factory.createMenuItem(StandardActions.UNABBREVIATE, new OldDatabaseCommandWrapper(Actions.UNABBREVIATE, this, Globals.stateManager)) + factory.createMenuItem(StandardActions.UNABBREVIATE, new OldDatabaseCommandWrapper(Actions.UNABBREVIATE, this, stateManager)) ); SidePaneComponent webSearch = sidePaneManager.getComponent(SidePaneType.WEB_SEARCH); @@ -839,15 +801,15 @@ private MenuBar createMenu() { new SeparatorMenuItem(), - factory.createCheckMenuItem(StandardActions.TOGGLE_PREVIEW, new OldDatabaseCommandWrapper(Actions.TOGGLE_PREVIEW, this, Globals.stateManager), Globals.prefs.getPreviewPreferences().isPreviewPanelEnabled()), - factory.createMenuItem(StandardActions.NEXT_PREVIEW_STYLE, new OldDatabaseCommandWrapper(Actions.NEXT_PREVIEW_STYLE, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.PREVIOUS_PREVIEW_STYLE, new OldDatabaseCommandWrapper(Actions.PREVIOUS_PREVIEW_STYLE, this, Globals.stateManager)), + factory.createCheckMenuItem(StandardActions.TOGGLE_PREVIEW, new OldDatabaseCommandWrapper(Actions.TOGGLE_PREVIEW, this, stateManager), Globals.prefs.getPreviewPreferences().isPreviewPanelEnabled()), + factory.createMenuItem(StandardActions.NEXT_PREVIEW_STYLE, new OldDatabaseCommandWrapper(Actions.NEXT_PREVIEW_STYLE, this, stateManager)), + factory.createMenuItem(StandardActions.PREVIOUS_PREVIEW_STYLE, new OldDatabaseCommandWrapper(Actions.PREVIOUS_PREVIEW_STYLE, this, stateManager)), new SeparatorMenuItem(), factory.createMenuItem(StandardActions.SHOW_PDF_VIEWER, new ShowDocumentViewerAction()), - factory.createMenuItem(StandardActions.EDIT_ENTRY, new OldDatabaseCommandWrapper(Actions.EDIT, this, Globals.stateManager)), - factory.createMenuItem(StandardActions.OPEN_CONSOLE, new OldDatabaseCommandWrapper(Actions.OPEN_CONSOLE, this, Globals.stateManager)) + factory.createMenuItem(StandardActions.EDIT_ENTRY, new OldDatabaseCommandWrapper(Actions.EDIT, this, stateManager)), + factory.createMenuItem(StandardActions.OPEN_CONSOLE, new OldDatabaseCommandWrapper(Actions.OPEN_CONSOLE, this, stateManager)) ); }); @@ -866,7 +828,7 @@ private MenuBar createMenu() { new SeparatorMenuItem(), - factory.createMenuItem(StandardActions.MANAGE_CONTENT_SELECTORS, new ManageContentSelectorAction(this)) + factory.createMenuItem(StandardActions.MANAGE_CONTENT_SELECTORS, new ManageContentSelectorAction(this, stateManager)) // TODO: Reenable customize entry types feature (https://github.com/JabRef/jabref/issues/4719) //factory.createMenuItem(StandardActions.CUSTOMIZE_ENTRY_TYPES, new CustomizeEntryAction(this)), ); @@ -943,84 +905,6 @@ public void addParserResult(ParserResult pr, boolean focusPanel) { } } - private void initActions() { - /* - openDatabaseOnlyActions.clear(); - openDatabaseOnlyActions.addAll(Arrays.asList(manageSelectors, mergeDatabaseAction, newSubDatabaseAction, save, copyPreview, - saveAs, saveSelectedAs, saveSelectedAsPlain, undo, redo, cut, deleteEntry, copy, paste, mark, markSpecific, unmark, - unmarkAll, rankSubMenu, editEntry, selectAll, copyKey, copyCiteKey, copyKeyAndTitle, copyKeyAndLink, editPreamble, editStrings, - groupSidePane.getToggleCommand(), makeKeyAction, normalSearch, generalFetcher.getToggleCommand(), mergeEntries, cleanupEntries, exportToClipboard, replaceAll, - sendAsEmail, downloadFullText, lookupIdentifiers, writeXmpAction, openOfficePanel.getToggleCommand(), findUnlinkedFiles, addToGroup, removeFromGroup, - moveToGroup, autoLinkFile, resolveDuplicateKeys, openUrl, openFolder, openFile, togglePreview, - dupliCheck, autoSetFile, newEntryAction, newSpec, customizeAction, plainTextImport, getMassSetField(), getManageKeywords(), - pushExternalButton.getMenuAction(), closeDatabaseAction, getNextPreviewStyleAction(), getPreviousPreviewStyleAction(), checkIntegrity, - databaseProperties, abbreviateIso, abbreviateMedline, - unabbreviate, exportAll, exportSelected, importCurrent, saveAll, focusTable, increaseFontSize, decreseFontSize, defaultFontSize, - toggleRelevance, toggleQualityAssured, togglePrinted, pushExternalButton.getComponent())); - openDatabaseOnlyActions.addAll(newSpecificEntryAction); - openDatabaseOnlyActions.addAll(specialFieldButtons); - severalDatabasesOnlyActions.clear(); - severalDatabasesOnlyActions.addAll(Arrays - .asList(nextTab, prevTab, sortTabs)); - openAndSavedDatabasesOnlyActions.addAll(Collections.singletonList(openConsole)); - sharedDatabaseOnlyActions.addAll(Collections.singletonList(pullChangesFromSharedDatabase)); - noSharedDatabaseActions.addAll(Arrays.asList(save, saveAll)); - oneEntryOnlyActions.clear(); - oneEntryOnlyActions.addAll(Arrays.asList(editEntry)); - oneEntryWithFileOnlyActions.clear(); - oneEntryWithFileOnlyActions.addAll(Arrays.asList(openFolder, openFile)); - oneEntryWithURLorDOIOnlyActions.clear(); - oneEntryWithURLorDOIOnlyActions.addAll(Arrays.asList(openUrl)); - twoEntriesOnlyActions.clear(); - twoEntriesOnlyActions.addAll(Arrays.asList(mergeEntries)); - atLeastOneEntryActions.clear(); - atLeastOneEntryActions.addAll(Arrays.asList(downloadFullText, lookupIdentifiers, exportLinkedFiles)); - tabbedPane.getTabs().addListener(this::updateEnabledState); - */ - } - - /** - * Enable or Disable all actions based on the number of open tabs. - *

- * The action that are affected are set in initActions. - */ - public void updateEnabledState(ListChangeListener.Change change) { - int tabCount = tabbedPane.getTabs().size(); - if (!change.next()) { - return; - } - if (change.wasAdded() || change.wasRemoved()) { - setEnabled(openDatabaseOnlyActions, tabCount > 0); - setEnabled(severalDatabasesOnlyActions, tabCount > 1); - } - if (tabCount == 0) { - setEnabled(openAndSavedDatabasesOnlyActions, false); - setEnabled(sharedDatabaseOnlyActions, false); - setEnabled(oneEntryOnlyActions, false); - } - - if (tabCount > 0) { - BasePanel current = getCurrentBasePanel(); - boolean saved = current.getBibDatabaseContext().getDatabasePath().isPresent(); - setEnabled(openAndSavedDatabasesOnlyActions, saved); - - boolean isShared = current.getBibDatabaseContext().getLocation() == DatabaseLocation.SHARED; - setEnabled(sharedDatabaseOnlyActions, isShared); - setEnabled(noSharedDatabaseActions, !isShared); - - boolean oneEntrySelected = current.getSelectedEntries().size() == 1; - setEnabled(oneEntryOnlyActions, oneEntrySelected); - setEnabled(oneEntryWithFileOnlyActions, isExistFile(current.getSelectedEntries())); - setEnabled(oneEntryWithURLorDOIOnlyActions, isExistURLorDOI(current.getSelectedEntries())); - - boolean twoEntriesSelected = current.getSelectedEntries().size() == 2; - setEnabled(twoEntriesOnlyActions, twoEntriesSelected); - - boolean atLeastOneEntrySelected = !current.getSelectedEntries().isEmpty(); - setEnabled(atLeastOneEntryActions, atLeastOneEntrySelected); - } - } - /** * This method causes all open BasePanels to set up their tables anew. When called from PrefsDialog3, this updates * to the new settings. @@ -1310,7 +1194,7 @@ public SidePaneManager getSidePaneManager() { return sidePaneManager; } - public PushToApplications getPushApplications() { + public PushToApplicationsManager getPushApplications() { return pushApplications; } @@ -1319,7 +1203,7 @@ public GlobalSearchBar getGlobalSearchBar() { } public CountingUndoManager getUndoManager() { - return Globals.undoManager; + return undoManager; } public DialogService getDialogService() { diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.fxml b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.fxml index 4bee6851ab0..14c2655be95 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.fxml +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.fxml @@ -8,7 +8,6 @@ - diff --git a/src/main/java/org/jabref/gui/StateManager.java b/src/main/java/org/jabref/gui/StateManager.java index 2acc073ae7b..630d5511eb9 100644 --- a/src/main/java/org/jabref/gui/StateManager.java +++ b/src/main/java/org/jabref/gui/StateManager.java @@ -6,23 +6,19 @@ import java.util.stream.Collectors; import javafx.beans.binding.Bindings; -import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyListProperty; import javafx.beans.property.ReadOnlyListWrapper; -import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.ObservableMap; +import org.jabref.gui.util.OptionalObjectProperty; import org.jabref.logic.search.SearchQuery; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.groups.GroupTreeNode; import org.jabref.model.util.OptionalUtil; -import org.fxmisc.easybind.EasyBind; -import org.fxmisc.easybind.monadic.MonadicBinding; - /** * This class manages the GUI-state of JabRef, including: * - currently selected database @@ -33,22 +29,21 @@ */ public class StateManager { - private final ObjectProperty> activeDatabase = new SimpleObjectProperty<>(Optional.empty()); + private final OptionalObjectProperty activeDatabase = OptionalObjectProperty.empty(); private final ReadOnlyListWrapper activeGroups = new ReadOnlyListWrapper<>(FXCollections.observableArrayList()); private final ObservableList selectedEntries = FXCollections.observableArrayList(); private final ObservableMap> selectedGroups = FXCollections.observableHashMap(); - private final ObjectProperty> activeSearchQuery = new SimpleObjectProperty<>(Optional.empty()); + private final OptionalObjectProperty activeSearchQuery = OptionalObjectProperty.empty(); public StateManager() { - MonadicBinding currentDatabase = EasyBind.map(activeDatabase, database -> database.orElse(null)); - activeGroups.bind(Bindings.valueAt(selectedGroups, currentDatabase)); + activeGroups.bind(Bindings.valueAt(selectedGroups, activeDatabase.orElse(null))); } - public ObjectProperty> activeDatabaseProperty() { + public OptionalObjectProperty activeDatabaseProperty() { return activeDatabase; } - public ObjectProperty> activeSearchQueryProperty() { + public OptionalObjectProperty activeSearchQueryProperty() { return activeSearchQuery; } diff --git a/src/main/java/org/jabref/gui/actions/ActionFactory.java b/src/main/java/org/jabref/gui/actions/ActionFactory.java index 69c5531db65..07a8ddb3f2f 100644 --- a/src/main/java/org/jabref/gui/actions/ActionFactory.java +++ b/src/main/java/org/jabref/gui/actions/ActionFactory.java @@ -1,24 +1,35 @@ package org.jabref.gui.actions; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Objects; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.ButtonBase; import javafx.scene.control.CheckMenuItem; +import javafx.scene.control.Label; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; +import javafx.scene.control.Tooltip; import org.jabref.gui.keyboard.KeyBindingRepository; +import org.jabref.model.strings.StringUtil; +import com.sun.javafx.scene.control.skin.ContextMenuContent; import de.saxsys.mvvmfx.utils.commands.Command; import org.controlsfx.control.action.ActionUtils; +import org.fxmisc.easybind.EasyBind; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Helper class to create and style controls according to an {@link Action}. */ public class ActionFactory { + private static final Logger LOGGER = LoggerFactory.getLogger(ActionFactory.class); + private final KeyBindingRepository keyBindingRepository; public ActionFactory(KeyBindingRepository keyBindingRepository) { @@ -33,14 +44,64 @@ private static void setGraphic(MenuItem node, Action action) { action.getIcon().ifPresent(icon -> node.setGraphic(icon.getGraphicNode())); } - public MenuItem configureMenuItem(Action action, Command command, MenuItem menuItem) { - return ActionUtils.configureMenuItem(new JabRefAction(action, command, keyBindingRepository), menuItem); + /* + * Returns MenuItemContainer node associated with this menu item + * which can contain: + * 1. label node of type Label for displaying menu item text, + * 2. right node of type Label for displaying accelerator text, + * or an arrow if it's a Menu, + * 3. graphic node for displaying menu item icon, and + * 4. left node for displaying either radio button or check box. + * + * This is basically rewritten impl_styleableGetNode() which + * should not be used since it's marked as deprecated. + */ + private static Label getAssociatedNode(MenuItem menuItem) { + ContextMenuContent.MenuItemContainer container = (ContextMenuContent.MenuItemContainer) menuItem.impl_styleableGetNode(); + + if (container == null) { + return null; + } else { + // We have to use reflection to get the associated label + try { + Method getLabel = ContextMenuContent.MenuItemContainer.class.getDeclaredMethod("getLabel"); + getLabel.setAccessible(true); + return (Label) getLabel.invoke(container); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + LOGGER.warn("Could not get label of menu item", e); + } + } + return null; } - public MenuItem createMenuItem(Action action, Command command) { - MenuItem menuItem = ActionUtils.createMenuItem(new JabRefAction(action, command, keyBindingRepository)); + public MenuItem configureMenuItem(Action action, Command command, MenuItem menuItem) { + ActionUtils.configureMenuItem(new JabRefAction(action, command, keyBindingRepository), menuItem); setGraphic(menuItem, action); + // Show tooltips + if (command instanceof SimpleCommand) { + EasyBind.subscribe( + ((SimpleCommand) command).statusMessageProperty(), + message -> { + Label label = getAssociatedNode(menuItem); + if (label != null) { + label.setMouseTransparent(false); + if (StringUtil.isBlank(message)) { + label.setTooltip(null); + } else { + label.setTooltip(new Tooltip(message)); + } + } + } + ); + } + + return menuItem; + } + + public MenuItem createMenuItem(Action action, Command command) { + MenuItem menuItem = new MenuItem(); + configureMenuItem(action, command, menuItem); return menuItem; } diff --git a/src/main/java/org/jabref/gui/actions/ActionHelper.java b/src/main/java/org/jabref/gui/actions/ActionHelper.java new file mode 100644 index 00000000000..dfd66772a3a --- /dev/null +++ b/src/main/java/org/jabref/gui/actions/ActionHelper.java @@ -0,0 +1,16 @@ +package org.jabref.gui.actions; + +import javafx.beans.binding.Bindings; +import javafx.beans.binding.BooleanExpression; + +import org.jabref.gui.StateManager; + +public class ActionHelper { + public static BooleanExpression needsDatabase(StateManager stateManager) { + return stateManager.activeDatabaseProperty().isPresent(); + } + + public static BooleanExpression needsEntriesSelected(StateManager stateManager) { + return Bindings.isNotEmpty(stateManager.getSelectedEntries()); + } +} diff --git a/src/main/java/org/jabref/gui/actions/Actions.java b/src/main/java/org/jabref/gui/actions/Actions.java index f115eda059c..5348e3394ae 100644 --- a/src/main/java/org/jabref/gui/actions/Actions.java +++ b/src/main/java/org/jabref/gui/actions/Actions.java @@ -3,6 +3,7 @@ /** * Global String constants for GUI actions */ +@Deprecated public enum Actions { ABBREVIATE_ISO, diff --git a/src/main/java/org/jabref/gui/actions/BaseAction.java b/src/main/java/org/jabref/gui/actions/BaseAction.java index a29c3a8573e..0af963e1a30 100644 --- a/src/main/java/org/jabref/gui/actions/BaseAction.java +++ b/src/main/java/org/jabref/gui/actions/BaseAction.java @@ -4,8 +4,11 @@ * BaseAction is used to define actions that are called from the * base frame through runCommand(). runCommand() finds the * appropriate BaseAction object, and runs its action() method. + * + * @deprecated use {@link SimpleCommand} instead */ @FunctionalInterface +@Deprecated public interface BaseAction { void action() throws Exception; diff --git a/src/main/java/org/jabref/gui/actions/BibtexKeyPatternAction.java b/src/main/java/org/jabref/gui/actions/BibtexKeyPatternAction.java deleted file mode 100644 index 7eaae3af4df..00000000000 --- a/src/main/java/org/jabref/gui/actions/BibtexKeyPatternAction.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.jabref.gui.actions; - -import org.jabref.gui.JabRefFrame; -import org.jabref.gui.bibtexkeypattern.BibtexKeyPatternDialog; - -public class BibtexKeyPatternAction extends SimpleCommand { - - private final JabRefFrame frame; - - public BibtexKeyPatternAction(JabRefFrame frame) { - this.frame = frame; - } - - @Override - public void execute() { - new BibtexKeyPatternDialog(frame.getCurrentBasePanel()).showAndWait(); - } -} diff --git a/src/main/java/org/jabref/gui/actions/JabRefAction.java b/src/main/java/org/jabref/gui/actions/JabRefAction.java index a1188ad8115..de4c8983ecd 100644 --- a/src/main/java/org/jabref/gui/actions/JabRefAction.java +++ b/src/main/java/org/jabref/gui/actions/JabRefAction.java @@ -1,5 +1,7 @@ package org.jabref.gui.actions; +import javafx.beans.binding.Bindings; + import org.jabref.Globals; import org.jabref.gui.keyboard.KeyBindingRepository; @@ -10,7 +12,6 @@ */ class JabRefAction extends org.controlsfx.control.action.Action { - public JabRefAction(Action action, KeyBindingRepository keyBindingRepository) { super(action.getText()); action.getIcon() @@ -19,7 +20,6 @@ public JabRefAction(Action action, KeyBindingRepository keyBindingRepository) { .ifPresent(keyBinding -> setAccelerator(keyBindingRepository.getKeyCombination(keyBinding))); setLongText(action.getDescription()); - } public JabRefAction(Action action, Command command, KeyBindingRepository keyBindingRepository) { @@ -27,14 +27,27 @@ public JabRefAction(Action action, Command command, KeyBindingRepository keyBind setEventHandler(event -> { command.execute(); - trackExecute(); + trackExecute(getActionName(action, command)); }); disabledProperty().bind(command.executableProperty().not()); + + if (command instanceof SimpleCommand) { + SimpleCommand ourCommand = (SimpleCommand) command; + longTextProperty().bind(Bindings.concat(action.getDescription(), ourCommand.statusMessageProperty())); + } + } + + private String getActionName(Action action, Command command) { + if (command.getClass().isAnonymousClass()) { + return action.getText(); + } else { + return command.getClass().getSimpleName(); + } } - private void trackExecute() { + private void trackExecute(String actionName) { Globals.getTelemetryClient() - .ifPresent(telemetryClient -> telemetryClient.trackEvent(getText())); + .ifPresent(telemetryClient -> telemetryClient.trackEvent(actionName)); } } diff --git a/src/main/java/org/jabref/gui/actions/ManageContentSelectorAction.java b/src/main/java/org/jabref/gui/actions/ManageContentSelectorAction.java deleted file mode 100644 index 31e2b1e1149..00000000000 --- a/src/main/java/org/jabref/gui/actions/ManageContentSelectorAction.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.jabref.gui.actions; - -import org.jabref.gui.BasePanel; -import org.jabref.gui.JabRefFrame; -import org.jabref.gui.contentselector.ContentSelectorDialogView; -import org.jabref.logic.l10n.Localization; - -public class ManageContentSelectorAction extends SimpleCommand { - - private final JabRefFrame jabRefFrame; - - public ManageContentSelectorAction(JabRefFrame jabRefFrame) { - this.jabRefFrame = jabRefFrame; - } - - @Override - public void execute() { - BasePanel basePanel = jabRefFrame.getCurrentBasePanel(); - if (noActiveConnectionExists(basePanel)) { - jabRefFrame.getDialogService().showErrorDialogAndWait(Localization.lang("Active database connection do not exists!")); - return; - } - new ContentSelectorDialogView(basePanel).showAndWait(); - } - - private boolean noActiveConnectionExists(BasePanel basePanel) { - return basePanel == null || basePanel.getBibDatabaseContext() == null; - } -} diff --git a/src/main/java/org/jabref/gui/actions/OldCommandWrapper.java b/src/main/java/org/jabref/gui/actions/OldCommandWrapper.java index c187b412684..4a37747726a 100644 --- a/src/main/java/org/jabref/gui/actions/OldCommandWrapper.java +++ b/src/main/java/org/jabref/gui/actions/OldCommandWrapper.java @@ -13,6 +13,7 @@ * This wraps the old Swing commands so that they fit into the new infrastructure. * In the long term, this class should be removed. */ +@Deprecated public class OldCommandWrapper extends CommandBase { private static final Logger LOGGER = LoggerFactory.getLogger(OldCommandWrapper.class); diff --git a/src/main/java/org/jabref/gui/actions/OldCommandWrapperForActiveDatabase.java b/src/main/java/org/jabref/gui/actions/OldCommandWrapperForActiveDatabase.java index d0807faee27..23c2f6b86c9 100644 --- a/src/main/java/org/jabref/gui/actions/OldCommandWrapperForActiveDatabase.java +++ b/src/main/java/org/jabref/gui/actions/OldCommandWrapperForActiveDatabase.java @@ -13,6 +13,7 @@ * This wraps the old Swing commands so that they fit into the new infrastructure. * In the long term, this class should be removed. */ +@Deprecated public class OldCommandWrapperForActiveDatabase extends CommandBase { private static final Logger LOGGER = LoggerFactory.getLogger(OldCommandWrapperForActiveDatabase.class); diff --git a/src/main/java/org/jabref/gui/actions/SetupGeneralFieldsAction.java b/src/main/java/org/jabref/gui/actions/SetupGeneralFieldsAction.java deleted file mode 100644 index a6254ef288c..00000000000 --- a/src/main/java/org/jabref/gui/actions/SetupGeneralFieldsAction.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.jabref.gui.actions; - -import org.jabref.gui.customizefields.CustomizeGeneralFieldsDialogView; - -public class SetupGeneralFieldsAction extends SimpleCommand { - - @Override - public void execute() { - new CustomizeGeneralFieldsDialogView().show(); - - } - -} diff --git a/src/main/java/org/jabref/gui/actions/SimpleCommand.java b/src/main/java/org/jabref/gui/actions/SimpleCommand.java index 78b52e7f206..39e3b7ae1ad 100644 --- a/src/main/java/org/jabref/gui/actions/SimpleCommand.java +++ b/src/main/java/org/jabref/gui/actions/SimpleCommand.java @@ -1,6 +1,8 @@ package org.jabref.gui.actions; import javafx.beans.property.ReadOnlyDoubleProperty; +import javafx.beans.property.ReadOnlyStringProperty; +import javafx.beans.property.ReadOnlyStringWrapper; import org.jabref.gui.util.BindingsHelper; @@ -10,6 +12,17 @@ * A simple command that does not track progress of the action. */ public abstract class SimpleCommand extends CommandBase { + + protected ReadOnlyStringWrapper statusMessage = new ReadOnlyStringWrapper(""); + + public String getStatusMessage() { + return statusMessage.get(); + } + + public ReadOnlyStringProperty statusMessageProperty() { + return statusMessage.getReadOnlyProperty(); + } + @Override public double getProgress() { return 0; diff --git a/src/main/java/org/jabref/gui/actions/NewSubLibraryAction.java b/src/main/java/org/jabref/gui/auximport/NewSubLibraryAction.java similarity index 56% rename from src/main/java/org/jabref/gui/actions/NewSubLibraryAction.java rename to src/main/java/org/jabref/gui/auximport/NewSubLibraryAction.java index a4f42eca838..85c766f10c3 100644 --- a/src/main/java/org/jabref/gui/actions/NewSubLibraryAction.java +++ b/src/main/java/org/jabref/gui/auximport/NewSubLibraryAction.java @@ -1,7 +1,10 @@ -package org.jabref.gui.actions; +package org.jabref.gui.auximport; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.auximport.FromAuxDialog; +import org.jabref.gui.StateManager; +import org.jabref.gui.actions.SimpleCommand; + +import static org.jabref.gui.actions.ActionHelper.needsDatabase; /** * The action concerned with generate a new (sub-)database from latex AUX file. @@ -10,8 +13,10 @@ public class NewSubLibraryAction extends SimpleCommand { private final JabRefFrame jabRefFrame; - public NewSubLibraryAction(JabRefFrame jabRefFrame) { + public NewSubLibraryAction(JabRefFrame jabRefFrame, StateManager stateManager) { this.jabRefFrame = jabRefFrame; + + this.executable.bind(needsDatabase(stateManager)); } @Override diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternAction.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternAction.java new file mode 100644 index 00000000000..4564ea7b83b --- /dev/null +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternAction.java @@ -0,0 +1,23 @@ +package org.jabref.gui.bibtexkeypattern; + +import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; +import org.jabref.gui.actions.SimpleCommand; + +import static org.jabref.gui.actions.ActionHelper.needsDatabase; + +public class BibtexKeyPatternAction extends SimpleCommand { + + private final JabRefFrame frame; + + public BibtexKeyPatternAction(JabRefFrame frame, StateManager stateManager) { + this.frame = frame; + + this.executable.bind(needsDatabase(stateManager)); + } + + @Override + public void execute() { + new BibtexKeyPatternDialog(frame.getCurrentBasePanel()).showAndWait(); + } +} diff --git a/src/main/java/org/jabref/gui/actions/GenerateBibtexKeyAction.java b/src/main/java/org/jabref/gui/bibtexkeypattern/GenerateBibtexKeyAction.java similarity index 98% rename from src/main/java/org/jabref/gui/actions/GenerateBibtexKeyAction.java rename to src/main/java/org/jabref/gui/bibtexkeypattern/GenerateBibtexKeyAction.java index 744db49711c..d11de1046b7 100644 --- a/src/main/java/org/jabref/gui/actions/GenerateBibtexKeyAction.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/GenerateBibtexKeyAction.java @@ -1,10 +1,11 @@ -package org.jabref.gui.actions; +package org.jabref.gui.bibtexkeypattern; import java.util.List; import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; +import org.jabref.gui.actions.BaseAction; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableKeyChange; import org.jabref.gui.util.BackgroundTask; diff --git a/src/main/java/org/jabref/gui/actions/GenerateBibtexKeySingleAction.java b/src/main/java/org/jabref/gui/bibtexkeypattern/GenerateBibtexKeySingleAction.java similarity index 94% rename from src/main/java/org/jabref/gui/actions/GenerateBibtexKeySingleAction.java rename to src/main/java/org/jabref/gui/bibtexkeypattern/GenerateBibtexKeySingleAction.java index 0ad4345cd4a..678256e4cee 100644 --- a/src/main/java/org/jabref/gui/actions/GenerateBibtexKeySingleAction.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/GenerateBibtexKeySingleAction.java @@ -1,8 +1,9 @@ -package org.jabref.gui.actions; +package org.jabref.gui.bibtexkeypattern; import javax.swing.undo.UndoManager; import org.jabref.gui.DialogService; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.entryeditor.EntryEditorPreferences; import org.jabref.gui.undo.UndoableKeyChange; import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator; diff --git a/src/main/java/org/jabref/gui/actions/CleanupAction.java b/src/main/java/org/jabref/gui/cleanup/CleanupAction.java similarity index 98% rename from src/main/java/org/jabref/gui/actions/CleanupAction.java rename to src/main/java/org/jabref/gui/cleanup/CleanupAction.java index 4a0f89e8b61..ee47ea19ce4 100644 --- a/src/main/java/org/jabref/gui/actions/CleanupAction.java +++ b/src/main/java/org/jabref/gui/cleanup/CleanupAction.java @@ -1,4 +1,4 @@ -package org.jabref.gui.actions; +package org.jabref.gui.cleanup; import java.util.List; import java.util.Optional; @@ -6,7 +6,7 @@ import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; -import org.jabref.gui.cleanup.CleanupDialog; +import org.jabref.gui.actions.BaseAction; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.gui.util.BackgroundTask; diff --git a/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java b/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java index 3efe55cb530..82996fa1e28 100644 --- a/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java +++ b/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java @@ -41,7 +41,7 @@ public EntryDeleteChangeViewModel(BibEntry memEntry, BibEntry tmpEntry) { @Override public void makeChange(BibDatabaseContext database, NamedCompound undoEdit) { database.getDatabase().removeEntry(memEntry); - undoEdit.addEdit(new UndoableRemoveEntry(database.getDatabase(), memEntry, null)); + undoEdit.addEdit(new UndoableRemoveEntry(database.getDatabase(), memEntry)); } @Override diff --git a/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.fxml b/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.fxml index 94744038b42..091f3b3ab91 100644 --- a/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.fxml +++ b/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.fxml @@ -9,7 +9,6 @@ - diff --git a/src/main/java/org/jabref/gui/contentselector/ManageContentSelectorAction.java b/src/main/java/org/jabref/gui/contentselector/ManageContentSelectorAction.java new file mode 100644 index 00000000000..555afe1dc20 --- /dev/null +++ b/src/main/java/org/jabref/gui/contentselector/ManageContentSelectorAction.java @@ -0,0 +1,25 @@ +package org.jabref.gui.contentselector; + +import org.jabref.gui.BasePanel; +import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; +import org.jabref.gui.actions.SimpleCommand; + +import static org.jabref.gui.actions.ActionHelper.needsDatabase; + +public class ManageContentSelectorAction extends SimpleCommand { + + private final JabRefFrame jabRefFrame; + + public ManageContentSelectorAction(JabRefFrame jabRefFrame, StateManager stateManager) { + this.jabRefFrame = jabRefFrame; + + this.executable.bind(needsDatabase(stateManager)); + } + + @Override + public void execute() { + BasePanel basePanel = jabRefFrame.getCurrentBasePanel(); + new ContentSelectorDialogView(basePanel).showAndWait(); + } +} diff --git a/src/main/java/org/jabref/gui/actions/CopyFilesAction.java b/src/main/java/org/jabref/gui/copyfiles/CopyFilesAction.java similarity index 66% rename from src/main/java/org/jabref/gui/actions/CopyFilesAction.java rename to src/main/java/org/jabref/gui/copyfiles/CopyFilesAction.java index d45a78eb803..5235f164088 100644 --- a/src/main/java/org/jabref/gui/actions/CopyFilesAction.java +++ b/src/main/java/org/jabref/gui/copyfiles/CopyFilesAction.java @@ -1,4 +1,4 @@ -package org.jabref.gui.actions; +package org.jabref.gui.copyfiles; import java.nio.file.Path; import java.nio.file.Paths; @@ -9,58 +9,55 @@ import org.jabref.Globals; import org.jabref.gui.DialogService; -import org.jabref.gui.JabRefFrame; -import org.jabref.gui.copyfiles.CopyFilesDialogView; -import org.jabref.gui.copyfiles.CopyFilesResultItemViewModel; -import org.jabref.gui.copyfiles.CopyFilesResultListDependency; -import org.jabref.gui.copyfiles.CopyFilesTask; +import org.jabref.gui.StateManager; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.preferences.JabRefPreferences; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; +import static org.jabref.gui.actions.ActionHelper.needsEntriesSelected; + public class CopyFilesAction extends SimpleCommand { private final DialogService dialogService; - private BibDatabaseContext databaseContext; - private List entries; - private final JabRefFrame frame; + private final StateManager stateManager; + + public CopyFilesAction(StateManager stateManager, DialogService dialogService) { + this.stateManager = stateManager; + this.dialogService = dialogService; - public CopyFilesAction(JabRefFrame frame) { - this.frame = frame; - this.dialogService = frame.getDialogService(); + this.executable.bind(needsDatabase(this.stateManager).and(needsEntriesSelected(stateManager))); } - private void showDialog(List data) { + private void showDialog(List data, BibDatabaseContext database) { if (data.isEmpty()) { dialogService.showInformationDialogAndWait(Localization.lang("Copy linked files to folder..."), Localization.lang("No linked files found for export.")); return; } - CopyFilesDialogView dialog = new CopyFilesDialogView(databaseContext, new CopyFilesResultListDependency(data)); + CopyFilesDialogView dialog = new CopyFilesDialogView(database, new CopyFilesResultListDependency(data)); dialog.showAndWait(); } @Override public void execute() { + BibDatabaseContext database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null")); + List entries = stateManager.getSelectedEntries(); + DirectoryDialogConfiguration dirDialogConfiguration = new DirectoryDialogConfiguration.Builder() .withInitialDirectory(Paths.get(Globals.prefs.get(JabRefPreferences.EXPORT_WORKING_DIRECTORY))) .build(); - entries = frame.getCurrentBasePanel().getSelectedEntries(); - Optional exportPath = dialogService.showDirectorySelectionDialog(dirDialogConfiguration); - exportPath.ifPresent(path -> { - databaseContext = frame.getCurrentBasePanel().getBibDatabaseContext(); - - Task> exportTask = new CopyFilesTask(databaseContext, entries, path); + Task> exportTask = new CopyFilesTask(database, entries, path); dialogService.showProgressDialogAndWait( Localization.lang("Copy linked files to folder..."), Localization.lang("Copy linked files to folder..."), exportTask); Globals.TASK_EXECUTOR.execute(exportTask); - exportTask.setOnSucceeded((e) -> showDialog(exportTask.getValue())); + exportTask.setOnSucceeded((e) -> showDialog(exportTask.getValue(), database)); }); - } } diff --git a/src/main/java/org/jabref/gui/copyfiles/CopyFilesTask.java b/src/main/java/org/jabref/gui/copyfiles/CopyFilesTask.java index 0938f717905..2b78f4dd74d 100644 --- a/src/main/java/org/jabref/gui/copyfiles/CopyFilesTask.java +++ b/src/main/java/org/jabref/gui/copyfiles/CopyFilesTask.java @@ -15,7 +15,6 @@ import javafx.concurrent.Task; import org.jabref.Globals; -import org.jabref.gui.actions.CopyFilesAction; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; import org.jabref.logic.util.io.FileUtil; diff --git a/src/main/java/org/jabref/gui/customizefields/SetupGeneralFieldsAction.java b/src/main/java/org/jabref/gui/customizefields/SetupGeneralFieldsAction.java new file mode 100644 index 00000000000..35fe7eb61a7 --- /dev/null +++ b/src/main/java/org/jabref/gui/customizefields/SetupGeneralFieldsAction.java @@ -0,0 +1,11 @@ +package org.jabref.gui.customizefields; + +import org.jabref.gui.actions.SimpleCommand; + +public class SetupGeneralFieldsAction extends SimpleCommand { + + @Override + public void execute() { + new CustomizeGeneralFieldsDialogView().showAndWait(); + } +} diff --git a/src/main/java/org/jabref/gui/actions/ShowDocumentViewerAction.java b/src/main/java/org/jabref/gui/documentviewer/ShowDocumentViewerAction.java similarity index 63% rename from src/main/java/org/jabref/gui/actions/ShowDocumentViewerAction.java rename to src/main/java/org/jabref/gui/documentviewer/ShowDocumentViewerAction.java index 7c15ae6d119..9c91ca7c472 100644 --- a/src/main/java/org/jabref/gui/actions/ShowDocumentViewerAction.java +++ b/src/main/java/org/jabref/gui/documentviewer/ShowDocumentViewerAction.java @@ -1,6 +1,6 @@ -package org.jabref.gui.actions; +package org.jabref.gui.documentviewer; -import org.jabref.gui.documentviewer.DocumentViewerView; +import org.jabref.gui.actions.SimpleCommand; public class ShowDocumentViewerAction extends SimpleCommand { diff --git a/src/main/java/org/jabref/gui/DuplicateResolverDialog.java b/src/main/java/org/jabref/gui/duplicationFinder/DuplicateResolverDialog.java similarity index 97% rename from src/main/java/org/jabref/gui/DuplicateResolverDialog.java rename to src/main/java/org/jabref/gui/duplicationFinder/DuplicateResolverDialog.java index a56da356f6f..7c1a8c418c5 100644 --- a/src/main/java/org/jabref/gui/DuplicateResolverDialog.java +++ b/src/main/java/org/jabref/gui/duplicationFinder/DuplicateResolverDialog.java @@ -1,4 +1,4 @@ -package org.jabref.gui; +package org.jabref.gui.duplicationFinder; import javafx.scene.control.Button; import javafx.scene.control.ButtonBar; @@ -6,7 +6,7 @@ import javafx.scene.control.ButtonType; import javafx.scene.layout.BorderPane; -import org.jabref.gui.DuplicateResolverDialog.DuplicateResolverResult; +import org.jabref.gui.duplicationFinder.DuplicateResolverDialog.DuplicateResolverResult; import org.jabref.gui.help.HelpAction; import org.jabref.gui.mergeentries.MergeEntries; import org.jabref.gui.util.BaseDialog; diff --git a/src/main/java/org/jabref/gui/DuplicateSearch.java b/src/main/java/org/jabref/gui/duplicationFinder/DuplicateSearch.java similarity index 89% rename from src/main/java/org/jabref/gui/DuplicateSearch.java rename to src/main/java/org/jabref/gui/duplicationFinder/DuplicateSearch.java index 0db4c5df1c2..bce7d2c5554 100644 --- a/src/main/java/org/jabref/gui/DuplicateSearch.java +++ b/src/main/java/org/jabref/gui/duplicationFinder/DuplicateSearch.java @@ -1,4 +1,4 @@ -package org.jabref.gui; +package org.jabref.gui.duplicationFinder; import java.util.ArrayList; import java.util.Arrays; @@ -14,9 +14,13 @@ import org.jabref.Globals; import org.jabref.JabRefExecutorService; -import org.jabref.gui.DuplicateResolverDialog.DuplicateResolverResult; -import org.jabref.gui.DuplicateResolverDialog.DuplicateResolverType; +import org.jabref.gui.BasePanel; +import org.jabref.gui.DialogService; +import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; +import org.jabref.gui.duplicationFinder.DuplicateResolverDialog.DuplicateResolverResult; +import org.jabref.gui.duplicationFinder.DuplicateResolverDialog.DuplicateResolverType; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableInsertEntry; import org.jabref.gui.undo.UndoableRemoveEntry; @@ -24,9 +28,12 @@ import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.bibtex.DuplicateCheck; import org.jabref.logic.l10n.Localization; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.BibEntry; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; + public class DuplicateSearch extends SimpleCommand { private final JabRefFrame frame; @@ -36,18 +43,22 @@ public class DuplicateSearch extends SimpleCommand { private final AtomicBoolean autoRemoveExactDuplicates = new AtomicBoolean(); private final AtomicInteger duplicateCount = new AtomicInteger(); private final DialogService dialogService; + private final StateManager stateManager; - public DuplicateSearch(JabRefFrame frame, DialogService dialogService) { + public DuplicateSearch(JabRefFrame frame, DialogService dialogService, StateManager stateManager) { this.frame = frame; this.dialogService = dialogService; + this.stateManager = stateManager; + + this.executable.bind(needsDatabase(stateManager)); } @Override public void execute() { - BasePanel panel = frame.getCurrentBasePanel(); + BibDatabaseContext database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null")); dialogService.notify(Localization.lang("Searching for duplicates...")); - List entries = panel.getDatabase().getEntries(); + List entries = database.getEntries(); duplicates.clear(); libraryAnalyzed.set(false); autoRemoveExactDuplicates.set(false); @@ -57,7 +68,7 @@ public void execute() { return; } - JabRefExecutorService.INSTANCE.executeInterruptableTask(() -> searchPossibleDuplicates(entries, panel.getBibDatabaseContext().getMode()), "DuplicateSearcher"); + JabRefExecutorService.INSTANCE.executeInterruptableTask(() -> searchPossibleDuplicates(entries, database.getMode()), "DuplicateSearcher"); BackgroundTask.wrap(this::verifyDuplicates) .onSuccess(this::handleDuplicates) .executeWith(Globals.TASK_EXECUTOR); @@ -153,7 +164,7 @@ private void handleDuplicates(DuplicateSearchResult result) { if (!result.getToRemove().isEmpty()) { for (BibEntry entry : result.getToRemove()) { panel.getDatabase().removeEntry(entry); - compoundEdit.addEdit(new UndoableRemoveEntry(panel.getDatabase(), entry, panel)); + compoundEdit.addEdit(new UndoableRemoveEntry(panel.getDatabase(), entry)); } panel.markBaseChanged(); } diff --git a/src/main/java/org/jabref/gui/actions/CopyBibTeXKeyAndLinkAction.java b/src/main/java/org/jabref/gui/edit/CopyBibTeXKeyAndLinkAction.java similarity index 97% rename from src/main/java/org/jabref/gui/actions/CopyBibTeXKeyAndLinkAction.java rename to src/main/java/org/jabref/gui/edit/CopyBibTeXKeyAndLinkAction.java index 9c6b1e21f4a..9b528d7d66a 100644 --- a/src/main/java/org/jabref/gui/actions/CopyBibTeXKeyAndLinkAction.java +++ b/src/main/java/org/jabref/gui/edit/CopyBibTeXKeyAndLinkAction.java @@ -1,4 +1,4 @@ -package org.jabref.gui.actions; +package org.jabref.gui.edit; import java.util.List; import java.util.stream.Collectors; @@ -6,6 +6,7 @@ import org.jabref.JabRefGUI; import org.jabref.gui.ClipBoardManager; import org.jabref.gui.JabRefDialogService; +import org.jabref.gui.actions.BaseAction; import org.jabref.gui.maintable.MainTable; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.l10n.Localization; diff --git a/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java b/src/main/java/org/jabref/gui/edit/CopyDoiUrlAction.java similarity index 93% rename from src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java rename to src/main/java/org/jabref/gui/edit/CopyDoiUrlAction.java index e541cd58d5a..bbc936366ed 100644 --- a/src/main/java/org/jabref/gui/actions/CopyDoiUrlAction.java +++ b/src/main/java/org/jabref/gui/edit/CopyDoiUrlAction.java @@ -1,4 +1,4 @@ -package org.jabref.gui.actions; +package org.jabref.gui.edit; import java.util.Optional; @@ -6,6 +6,7 @@ import org.jabref.Globals; import org.jabref.JabRefGUI; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.identifier.DOI; diff --git a/src/main/java/org/jabref/gui/edit/ManageKeywordsAction.java b/src/main/java/org/jabref/gui/edit/ManageKeywordsAction.java index 333e206cd02..79a348f4c18 100644 --- a/src/main/java/org/jabref/gui/edit/ManageKeywordsAction.java +++ b/src/main/java/org/jabref/gui/edit/ManageKeywordsAction.java @@ -1,34 +1,31 @@ package org.jabref.gui.edit; -import org.jabref.gui.BasePanel; -import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; +import org.jabref.gui.util.BindingsHelper; import org.jabref.logic.l10n.Localization; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; +import static org.jabref.gui.actions.ActionHelper.needsEntriesSelected; + /** * An Action for launching keyword managing dialog * */ public class ManageKeywordsAction extends SimpleCommand { - private final JabRefFrame frame; + private final StateManager stateManager; + + public ManageKeywordsAction(StateManager stateManager) { + this.stateManager = stateManager; - public ManageKeywordsAction(JabRefFrame frame) { - this.frame = frame; + this.executable.bind(needsDatabase(stateManager).and(needsEntriesSelected(stateManager))); + this.statusMessage.bind(BindingsHelper.ifThenElse(this.executable, "", Localization.lang("Select at least one entry to manage keywords."))); } @Override public void execute() { - BasePanel basePanel = frame.getCurrentBasePanel(); - if (basePanel == null) { - return; - } - if (basePanel.getSelectedEntries().isEmpty()) { - basePanel.output(Localization.lang("Select at least one entry to manage keywords.")); - return; - } - - ManageKeywordsDialog dialog = new ManageKeywordsDialog(basePanel.getSelectedEntries()); + ManageKeywordsDialog dialog = new ManageKeywordsDialog(stateManager.getSelectedEntries()); dialog.showAndWait(); } } diff --git a/src/main/java/org/jabref/gui/edit/MassSetFieldsAction.java b/src/main/java/org/jabref/gui/edit/MassSetFieldsAction.java index 31abaec6000..a448651d0f6 100644 --- a/src/main/java/org/jabref/gui/edit/MassSetFieldsAction.java +++ b/src/main/java/org/jabref/gui/edit/MassSetFieldsAction.java @@ -1,11 +1,14 @@ package org.jabref.gui.edit; -import java.util.List; +import javax.swing.undo.UndoManager; -import org.jabref.gui.BasePanel; -import org.jabref.gui.JabRefFrame; +import org.jabref.gui.DialogService; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; -import org.jabref.model.entry.BibEntry; +import org.jabref.model.database.BibDatabaseContext; + +import static org.jabref.gui.actions.ActionHelper.needsDatabase; +import static org.jabref.gui.actions.ActionHelper.needsEntriesSelected; /** * An Action for launching mass field. @@ -17,21 +20,22 @@ */ public class MassSetFieldsAction extends SimpleCommand { - private final JabRefFrame frame; + private final StateManager stateManager; + private DialogService dialogService; + private UndoManager undoManager; + + public MassSetFieldsAction(StateManager stateManager, DialogService dialogService, UndoManager undoManager) { + this.stateManager = stateManager; + this.dialogService = dialogService; + this.undoManager = undoManager; - public MassSetFieldsAction(JabRefFrame frame) { - this.frame = frame; + this.executable.bind(needsDatabase(stateManager).and(needsEntriesSelected(stateManager))); } @Override public void execute() { - BasePanel bp = frame.getCurrentBasePanel(); - if (bp == null) { - return; - } - - List entries = bp.getSelectedEntries(); - MassSetFieldsDialog dialog = new MassSetFieldsDialog(entries, bp); + BibDatabaseContext database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null")); + MassSetFieldsDialog dialog = new MassSetFieldsDialog(stateManager.getSelectedEntries(), database, dialogService, undoManager); dialog.showAndWait(); } diff --git a/src/main/java/org/jabref/gui/edit/MassSetFieldsDialog.java b/src/main/java/org/jabref/gui/edit/MassSetFieldsDialog.java index bef87619d19..d63c9b0342b 100644 --- a/src/main/java/org/jabref/gui/edit/MassSetFieldsDialog.java +++ b/src/main/java/org/jabref/gui/edit/MassSetFieldsDialog.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Optional; +import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEdit; import javafx.application.Platform; @@ -18,13 +19,13 @@ import javafx.scene.control.Tooltip; import javafx.scene.layout.GridPane; -import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.gui.util.BaseDialog; import org.jabref.gui.util.IconValidationDecorator; import org.jabref.logic.l10n.Localization; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.strings.StringUtil; @@ -37,7 +38,7 @@ public class MassSetFieldsDialog extends BaseDialog { private final List entries; - private final BasePanel bp; + private final BibDatabaseContext database; private final DialogService dialogService; private RadioButton clearRadioButton; @@ -49,11 +50,13 @@ public class MassSetFieldsDialog extends BaseDialog { private TextField appendTextField; private TextField renameTextField; private CheckBox overwriteCheckBox; + private UndoManager undoManager; - MassSetFieldsDialog(List entries, BasePanel bp) { + MassSetFieldsDialog(List entries, BibDatabaseContext database, DialogService dialogService, UndoManager undoManager) { this.entries = entries; - this.bp = bp; - this.dialogService = bp.frame().getDialogService(); + this.database = database; + this.dialogService = dialogService; + this.undoManager = undoManager; init(); this.setTitle("Set/clear/append/rename fields"); @@ -76,7 +79,6 @@ public class MassSetFieldsDialog extends BaseDialog { * @return A CompoundEdit for the entire operation. */ private static UndoableEdit massAppendField(Collection entries, String field, String textToAppend) { - String newValue = ""; if (textToAppend != null) { @@ -140,7 +142,6 @@ private static UndoableEdit massRenameField(Collection entries, String */ private static UndoableEdit massSetField(Collection entries, String field, String textToSet, boolean overwriteValues) { - NamedCompound compoundEdit = new NamedCompound(Localization.lang("Set field")); for (BibEntry entry : entries) { Optional oldValue = entry.getField(field); @@ -164,7 +165,7 @@ private static UndoableEdit massSetField(Collection entries, String fi private void init() { fieldComboBox = new ComboBox<>(); fieldComboBox.setEditable(true); - fieldComboBox.getItems().addAll(bp.getDatabase().getAllVisibleFields()); + fieldComboBox.getItems().addAll(database.getDatabase().getAllVisibleFields()); ToggleGroup toggleGroup = new ToggleGroup(); clearRadioButton = new RadioButton(Localization.lang("Clear fields")); @@ -236,6 +237,6 @@ private void performEdits() { overwriteCheckBox.isSelected())); } compoundEdit.end(); - bp.getUndoManager().addEdit(compoundEdit); + undoManager.addEdit(compoundEdit); } } diff --git a/src/main/java/org/jabref/gui/actions/OpenBrowserAction.java b/src/main/java/org/jabref/gui/edit/OpenBrowserAction.java similarity index 82% rename from src/main/java/org/jabref/gui/actions/OpenBrowserAction.java rename to src/main/java/org/jabref/gui/edit/OpenBrowserAction.java index 9cd0b92524e..559063b631f 100644 --- a/src/main/java/org/jabref/gui/actions/OpenBrowserAction.java +++ b/src/main/java/org/jabref/gui/edit/OpenBrowserAction.java @@ -1,5 +1,6 @@ -package org.jabref.gui.actions; +package org.jabref.gui.edit; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.desktop.JabRefDesktop; public class OpenBrowserAction extends SimpleCommand { @@ -13,7 +14,6 @@ public OpenBrowserAction(String urlToOpen) { @Override public void execute() { JabRefDesktop.openBrowserShowPopup(urlToOpen); - } } diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index 4ebdb2b1b72..a85e7909357 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -28,8 +28,8 @@ import org.jabref.gui.DialogService; import org.jabref.gui.GUIGlobals; import org.jabref.gui.actions.ActionFactory; -import org.jabref.gui.actions.GenerateBibtexKeySingleAction; import org.jabref.gui.actions.StandardActions; +import org.jabref.gui.bibtexkeypattern.GenerateBibtexKeySingleAction; import org.jabref.gui.entryeditor.fileannotationtab.FileAnnotationTab; import org.jabref.gui.externalfiles.ExternalFilesEntryLinker; import org.jabref.gui.externalfiletype.ExternalFileTypes; diff --git a/src/main/java/org/jabref/gui/actions/ManageCustomExportsAction.java b/src/main/java/org/jabref/gui/exporter/ManageCustomExportsAction.java similarity index 64% rename from src/main/java/org/jabref/gui/actions/ManageCustomExportsAction.java rename to src/main/java/org/jabref/gui/exporter/ManageCustomExportsAction.java index 60298e05555..07dcde775cc 100644 --- a/src/main/java/org/jabref/gui/actions/ManageCustomExportsAction.java +++ b/src/main/java/org/jabref/gui/exporter/ManageCustomExportsAction.java @@ -1,6 +1,6 @@ -package org.jabref.gui.actions; +package org.jabref.gui.exporter; -import org.jabref.gui.exporter.ExportCustomizationDialogView; +import org.jabref.gui.actions.SimpleCommand; public class ManageCustomExportsAction extends SimpleCommand { diff --git a/src/main/java/org/jabref/gui/actions/WriteXMPAction.java b/src/main/java/org/jabref/gui/exporter/WriteXMPAction.java similarity index 99% rename from src/main/java/org/jabref/gui/actions/WriteXMPAction.java rename to src/main/java/org/jabref/gui/exporter/WriteXMPAction.java index 67a1217a113..043ceac725d 100644 --- a/src/main/java/org/jabref/gui/actions/WriteXMPAction.java +++ b/src/main/java/org/jabref/gui/exporter/WriteXMPAction.java @@ -1,4 +1,4 @@ -package org.jabref.gui.actions; +package org.jabref.gui.exporter; import java.nio.file.Files; import java.nio.file.Path; @@ -24,6 +24,7 @@ import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.FXDialog; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.BackgroundTask; import org.jabref.logic.l10n.Localization; import org.jabref.logic.xmp.XmpUtilWriter; @@ -101,7 +102,6 @@ private void writeXMP() { } for (BibEntry entry : entries) { - // Make a list of all PDFs linked from this entry: List files = entry.getFiles().stream() .filter(file -> file.getFileType().equalsIgnoreCase("pdf")) diff --git a/src/main/java/org/jabref/gui/externalfiles/AutoLinkFilesAction.java b/src/main/java/org/jabref/gui/externalfiles/AutoLinkFilesAction.java index 967243e840b..74a9d3aea77 100644 --- a/src/main/java/org/jabref/gui/externalfiles/AutoLinkFilesAction.java +++ b/src/main/java/org/jabref/gui/externalfiles/AutoLinkFilesAction.java @@ -2,17 +2,25 @@ import java.util.List; +import javax.swing.undo.UndoManager; + import javafx.concurrent.Task; import org.jabref.gui.DialogService; import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.undo.NamedCompound; +import org.jabref.gui.util.BindingsHelper; import org.jabref.logic.l10n.Localization; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.preferences.JabRefPreferences; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; +import static org.jabref.gui.actions.ActionHelper.needsEntriesSelected; + /** * This Action may only be used in a menu or button. * Never in the entry editor. FileListEditor and EntryEditor have other ways to update the file links @@ -20,25 +28,28 @@ public class AutoLinkFilesAction extends SimpleCommand { private final DialogService dialogService; - private final JabRefFrame frame; private final JabRefPreferences preferences; + private final StateManager stateManager; + private UndoManager undoManager; - public AutoLinkFilesAction(JabRefFrame frame, JabRefPreferences preferences) { - this.frame = frame; + public AutoLinkFilesAction(JabRefFrame frame, JabRefPreferences preferences, StateManager stateManager, UndoManager undoManager) { this.dialogService = frame.getDialogService(); this.preferences = preferences; + this.stateManager = stateManager; + this.undoManager = undoManager; + + this.executable.bind(needsDatabase(this.stateManager).and(needsEntriesSelected(stateManager))); + this.statusMessage.bind(BindingsHelper.ifThenElse(executable, "", Localization.lang("This operation requires one or more entries to be selected."))); + } @Override public void execute() { - List entries = frame.getCurrentBasePanel().getSelectedEntries(); - if (entries.isEmpty()) { - dialogService.notify(Localization.lang("This operation requires one or more entries to be selected.")); - return; - } + BibDatabaseContext database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null")); + List entries = stateManager.getSelectedEntries(); final NamedCompound nc = new NamedCompound(Localization.lang("Automatically set file links")); - AutoSetFileLinksUtil util = new AutoSetFileLinksUtil(frame.getCurrentBasePanel().getBibDatabaseContext(), preferences.getFilePreferences(), preferences.getAutoLinkPreferences(), ExternalFileTypes.getInstance()); + AutoSetFileLinksUtil util = new AutoSetFileLinksUtil(database, preferences.getFilePreferences(), preferences.getAutoLinkPreferences(), ExternalFileTypes.getInstance()); Task> linkFilesTask = new Task>() { @Override protected List call() { @@ -50,7 +61,7 @@ protected void succeeded() { if (!getValue().isEmpty()) { if (nc.hasEdits()) { nc.end(); - frame.getCurrentBasePanel().getUndoManager().addEdit(nc); + undoManager.addEdit(nc); } dialogService.notify(Localization.lang("Finished automatically setting external links.")); } else { diff --git a/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesAction.java b/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesAction.java index 5684869d9ff..0212978d442 100644 --- a/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesAction.java +++ b/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesAction.java @@ -1,19 +1,28 @@ package org.jabref.gui.externalfiles; import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; +import org.jabref.model.database.BibDatabaseContext; + +import static org.jabref.gui.actions.ActionHelper.needsDatabase; public class FindUnlinkedFilesAction extends SimpleCommand { private final JabRefFrame jabRefFrame; + private final StateManager stateManager; - public FindUnlinkedFilesAction(JabRefFrame jabRefFrame) { + public FindUnlinkedFilesAction(JabRefFrame jabRefFrame, StateManager stateManager) { this.jabRefFrame = jabRefFrame; + this.stateManager = stateManager; + + this.executable.bind(needsDatabase(this.stateManager)); } @Override public void execute() { - FindUnlinkedFilesDialog dlg = new FindUnlinkedFilesDialog(jabRefFrame); + BibDatabaseContext database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null")); + FindUnlinkedFilesDialog dlg = new FindUnlinkedFilesDialog(database, jabRefFrame.getDialogService(), jabRefFrame.getUndoManager()); dlg.showAndWait(); } diff --git a/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesDialog.java b/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesDialog.java index a4892565632..ff250cb7a6b 100644 --- a/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesDialog.java +++ b/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesDialog.java @@ -38,10 +38,10 @@ import org.jabref.Globals; import org.jabref.gui.DialogService; -import org.jabref.gui.JabRefFrame; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.importer.UnlinkedFilesCrawler; +import org.jabref.gui.undo.CountingUndoManager; import org.jabref.gui.util.BackgroundTask; import org.jabref.gui.util.BaseDialog; import org.jabref.gui.util.DirectoryDialogConfiguration; @@ -63,7 +63,6 @@ public class FindUnlinkedFilesDialog extends BaseDialog { private static final Logger LOGGER = LoggerFactory.getLogger(FindUnlinkedFilesDialog.class); - private final JabRefFrame frame; private final BibDatabaseContext databaseContext; private final ImportHandler importHandler; private final JabRefPreferences preferences = Globals.prefs; @@ -77,13 +76,12 @@ public class FindUnlinkedFilesDialog extends BaseDialog { private VBox panelSearchProgress; private BackgroundTask findUnlinkedFilesTask; - public FindUnlinkedFilesDialog(JabRefFrame frame) { + public FindUnlinkedFilesDialog(BibDatabaseContext database, DialogService dialogService, CountingUndoManager undoManager) { super(); this.setTitle(Localization.lang("Find unlinked files")); - this.frame = frame; - dialogService = frame.getDialogService(); + this.dialogService = dialogService; - databaseContext = frame.getCurrentBasePanel().getBibDatabaseContext(); + databaseContext = database; importHandler = new ImportHandler( dialogService, databaseContext, @@ -92,7 +90,7 @@ public FindUnlinkedFilesDialog(JabRefFrame frame) { Globals.prefs.getImportFormatPreferences(), Globals.prefs.getUpdateFieldPreferences(), Globals.getFileUpdateMonitor(), - frame.getUndoManager(), + undoManager, Globals.stateManager); initialize(); diff --git a/src/main/java/org/jabref/gui/externalfiletype/EditExternalFileTypeEntryDialog.fxml b/src/main/java/org/jabref/gui/externalfiletype/EditExternalFileTypeEntryDialog.fxml index 11da6fc3712..49501a19e19 100644 --- a/src/main/java/org/jabref/gui/externalfiletype/EditExternalFileTypeEntryDialog.fxml +++ b/src/main/java/org/jabref/gui/externalfiletype/EditExternalFileTypeEntryDialog.fxml @@ -10,7 +10,6 @@ - diff --git a/src/main/java/org/jabref/gui/actions/EditExternalFileTypesAction.java b/src/main/java/org/jabref/gui/externalfiletype/EditExternalFileTypesAction.java similarity index 69% rename from src/main/java/org/jabref/gui/actions/EditExternalFileTypesAction.java rename to src/main/java/org/jabref/gui/externalfiletype/EditExternalFileTypesAction.java index c5ea26bb8cb..d7450556f4f 100644 --- a/src/main/java/org/jabref/gui/actions/EditExternalFileTypesAction.java +++ b/src/main/java/org/jabref/gui/externalfiletype/EditExternalFileTypesAction.java @@ -1,6 +1,6 @@ -package org.jabref.gui.actions; +package org.jabref.gui.externalfiletype; -import org.jabref.gui.externalfiletype.CustomizeExternalFileTypesDialog; +import org.jabref.gui.actions.SimpleCommand; public class EditExternalFileTypesAction extends SimpleCommand { diff --git a/src/main/java/org/jabref/gui/fieldeditors/BibtexKeyEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/BibtexKeyEditorViewModel.java index bb190108497..fa3a4a8f622 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/BibtexKeyEditorViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/BibtexKeyEditorViewModel.java @@ -3,8 +3,8 @@ import javax.swing.undo.UndoManager; import org.jabref.gui.DialogService; -import org.jabref.gui.actions.GenerateBibtexKeySingleAction; import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider; +import org.jabref.gui.bibtexkeypattern.GenerateBibtexKeySingleAction; import org.jabref.gui.entryeditor.EntryEditorPreferences; import org.jabref.logic.integrity.FieldCheckers; import org.jabref.model.database.BibDatabaseContext; diff --git a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java index baaabbe8f93..abdb9700909 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java +++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java @@ -14,8 +14,8 @@ import org.jabref.Globals; import org.jabref.gui.actions.ActionFactory; -import org.jabref.gui.actions.CopyDoiUrlAction; import org.jabref.gui.actions.StandardActions; +import org.jabref.gui.edit.CopyDoiUrlAction; import org.jabref.logic.formatter.bibtexfields.CleanupURLFormatter; import org.jabref.logic.formatter.bibtexfields.NormalizeNamesFormatter; import org.jabref.logic.l10n.Localization; diff --git a/src/main/java/org/jabref/gui/actions/ErrorConsoleAction.java b/src/main/java/org/jabref/gui/help/ErrorConsoleAction.java similarity index 86% rename from src/main/java/org/jabref/gui/actions/ErrorConsoleAction.java rename to src/main/java/org/jabref/gui/help/ErrorConsoleAction.java index 2ac2dbf6623..3919b35a17b 100644 --- a/src/main/java/org/jabref/gui/actions/ErrorConsoleAction.java +++ b/src/main/java/org/jabref/gui/help/ErrorConsoleAction.java @@ -1,5 +1,6 @@ -package org.jabref.gui.actions; +package org.jabref.gui.help; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.errorconsole.ErrorConsoleView; /** diff --git a/src/main/java/org/jabref/gui/actions/SearchForUpdateAction.java b/src/main/java/org/jabref/gui/help/SearchForUpdateAction.java similarity index 92% rename from src/main/java/org/jabref/gui/actions/SearchForUpdateAction.java rename to src/main/java/org/jabref/gui/help/SearchForUpdateAction.java index be3415c2120..c1d951aaa01 100644 --- a/src/main/java/org/jabref/gui/actions/SearchForUpdateAction.java +++ b/src/main/java/org/jabref/gui/help/SearchForUpdateAction.java @@ -1,7 +1,7 @@ -package org.jabref.gui.actions; +package org.jabref.gui.help; import org.jabref.gui.DialogService; -import org.jabref.gui.help.VersionWorker; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.util.BuildInfo; import org.jabref.preferences.VersionPreferences; diff --git a/src/main/java/org/jabref/gui/importer/ImportEntriesViewModel.java b/src/main/java/org/jabref/gui/importer/ImportEntriesViewModel.java index a28a437400b..6f0b2fad4ad 100644 --- a/src/main/java/org/jabref/gui/importer/ImportEntriesViewModel.java +++ b/src/main/java/org/jabref/gui/importer/ImportEntriesViewModel.java @@ -12,8 +12,8 @@ import org.jabref.gui.AbstractViewModel; import org.jabref.gui.DialogService; -import org.jabref.gui.DuplicateResolverDialog; import org.jabref.gui.StateManager; +import org.jabref.gui.duplicationFinder.DuplicateResolverDialog; import org.jabref.gui.externalfiles.ImportHandler; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.util.BackgroundTask; diff --git a/src/main/java/org/jabref/gui/actions/ManageCustomImportsAction.java b/src/main/java/org/jabref/gui/importer/ManageCustomImportsAction.java similarity index 70% rename from src/main/java/org/jabref/gui/actions/ManageCustomImportsAction.java rename to src/main/java/org/jabref/gui/importer/ManageCustomImportsAction.java index e36ea7ac07c..7c9d36002a0 100644 --- a/src/main/java/org/jabref/gui/actions/ManageCustomImportsAction.java +++ b/src/main/java/org/jabref/gui/importer/ManageCustomImportsAction.java @@ -1,6 +1,6 @@ -package org.jabref.gui.actions; +package org.jabref.gui.importer; -import org.jabref.gui.importer.ImportCustomizationDialog; +import org.jabref.gui.actions.SimpleCommand; public class ManageCustomImportsAction extends SimpleCommand { diff --git a/src/main/java/org/jabref/gui/actions/NewDatabaseAction.java b/src/main/java/org/jabref/gui/importer/NewDatabaseAction.java similarity index 92% rename from src/main/java/org/jabref/gui/actions/NewDatabaseAction.java rename to src/main/java/org/jabref/gui/importer/NewDatabaseAction.java index e00604e3a1b..5372a81ead2 100644 --- a/src/main/java/org/jabref/gui/actions/NewDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/NewDatabaseAction.java @@ -1,6 +1,7 @@ -package org.jabref.gui.actions; +package org.jabref.gui.importer; import org.jabref.gui.JabRefFrame; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.logic.l10n.Localization; import org.jabref.model.Defaults; import org.jabref.model.database.BibDatabaseContext; diff --git a/src/main/java/org/jabref/gui/actions/NewEntryAction.java b/src/main/java/org/jabref/gui/importer/NewEntryAction.java similarity index 80% rename from src/main/java/org/jabref/gui/actions/NewEntryAction.java rename to src/main/java/org/jabref/gui/importer/NewEntryAction.java index a5b483a4d67..7aaa203d991 100644 --- a/src/main/java/org/jabref/gui/actions/NewEntryAction.java +++ b/src/main/java/org/jabref/gui/importer/NewEntryAction.java @@ -1,4 +1,4 @@ -package org.jabref.gui.actions; +package org.jabref.gui.importer; import java.util.HashMap; import java.util.Map; @@ -8,6 +8,8 @@ import org.jabref.gui.DialogService; import org.jabref.gui.EntryTypeView; import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.EntryType; import org.jabref.preferences.JabRefPreferences; @@ -15,6 +17,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; + public class NewEntryAction extends SimpleCommand { private static final Logger LOGGER = LoggerFactory.getLogger(NewEntryAction.class); @@ -23,22 +27,23 @@ public class NewEntryAction extends SimpleCommand { /** * The type of the entry to create. */ - private final Optional type; + private Optional type; private final DialogService dialogService; private final JabRefPreferences preferences; - public NewEntryAction(JabRefFrame jabRefFrame, DialogService dialogService, JabRefPreferences preferences) { + public NewEntryAction(JabRefFrame jabRefFrame, DialogService dialogService, JabRefPreferences preferences, StateManager stateManager) { this.jabRefFrame = jabRefFrame; - this.type = Optional.empty(); this.dialogService = dialogService; this.preferences = preferences; + + this.type = Optional.empty(); + + this.executable.bind(needsDatabase(stateManager)); } - public NewEntryAction(JabRefFrame jabRefFrame, EntryType type, DialogService dialogService, JabRefPreferences preferences) { - this.jabRefFrame = jabRefFrame; + public NewEntryAction(JabRefFrame jabRefFrame, EntryType type, DialogService dialogService, JabRefPreferences preferences, StateManager stateManager) { + this(jabRefFrame, dialogService, preferences, stateManager); this.type = Optional.of(type); - this.dialogService = dialogService; - this.preferences = preferences; } @Override diff --git a/src/main/java/org/jabref/gui/actions/LookupIdentifierAction.java b/src/main/java/org/jabref/gui/importer/fetcher/LookupIdentifierAction.java similarity index 78% rename from src/main/java/org/jabref/gui/actions/LookupIdentifierAction.java rename to src/main/java/org/jabref/gui/importer/fetcher/LookupIdentifierAction.java index a2d6c7372d9..31c03ca36fc 100644 --- a/src/main/java/org/jabref/gui/actions/LookupIdentifierAction.java +++ b/src/main/java/org/jabref/gui/importer/fetcher/LookupIdentifierAction.java @@ -1,17 +1,21 @@ -package org.jabref.gui.actions; +package org.jabref.gui.importer.fetcher; import java.util.List; -import java.util.Objects; import java.util.Optional; +import javax.swing.undo.UndoManager; + import org.jabref.Globals; -import org.jabref.gui.BasePanel; import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; +import org.jabref.gui.actions.Action; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.icon.JabRefIcon; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.gui.util.BackgroundTask; +import org.jabref.gui.util.BindingsHelper; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.IdFetcher; @@ -23,6 +27,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; +import static org.jabref.gui.actions.ActionHelper.needsEntriesSelected; + public class LookupIdentifierAction extends SimpleCommand { private static final Logger LOGGER = LoggerFactory.getLogger(LookupIdentifierAction.class); @@ -30,16 +37,23 @@ public class LookupIdentifierAction extends SimpleCommand private final JabRefFrame frame; private final IdFetcher fetcher; + private final StateManager stateManager; + private UndoManager undoManager; - public LookupIdentifierAction(JabRefFrame frame, IdFetcher fetcher) { + public LookupIdentifierAction(JabRefFrame frame, IdFetcher fetcher, StateManager stateManager, UndoManager undoManager) { this.frame = frame; this.fetcher = fetcher; + this.stateManager = stateManager; + this.undoManager = undoManager; + + this.executable.bind(needsDatabase(this.stateManager).and(needsEntriesSelected(this.stateManager))); + this.statusMessage.bind(BindingsHelper.ifThenElse(executable, "", Localization.lang("This operation requires one or more entries to be selected."))); } @Override public void execute() { try { - BackgroundTask.wrap(this::lookupIdentifiers) + BackgroundTask.wrap(() -> lookupIdentifiers(stateManager.getSelectedEntries())) .onSuccess(frame.getDialogService()::notify) .executeWith(Globals.TASK_EXECUTOR); } catch (Exception e) { @@ -72,13 +86,7 @@ public String getDescription() { }; } - private String lookupIdentifiers() { - BasePanel basePanel = Objects.requireNonNull(frame.getCurrentBasePanel()); - List bibEntries = basePanel.getSelectedEntries(); - if (bibEntries.isEmpty()) { - return Localization.lang("This operation requires one or more entries to be selected."); - } - + private String lookupIdentifiers(List bibEntries) { String totalCount = Integer.toString(bibEntries.size()); NamedCompound namedCompound = new NamedCompound(Localization.lang("Look up %0", fetcher.getIdentifierName())); int count = 0; @@ -107,8 +115,7 @@ private String lookupIdentifiers() { } namedCompound.end(); if (foundCount > 0) { - basePanel.getUndoManager().addEdit(namedCompound); - basePanel.markBaseChanged(); + undoManager.addEdit(namedCompound); } return Localization.lang("Determined %0 for %1 entries", fetcher.getIdentifierName(), Integer.toString(foundCount)); } diff --git a/src/main/java/org/jabref/gui/integrity/IntegrityCheckAction.java b/src/main/java/org/jabref/gui/integrity/IntegrityCheckAction.java index 0bf4c182db8..4cedba33962 100644 --- a/src/main/java/org/jabref/gui/integrity/IntegrityCheckAction.java +++ b/src/main/java/org/jabref/gui/integrity/IntegrityCheckAction.java @@ -10,6 +10,7 @@ import org.jabref.gui.Dialog; import org.jabref.gui.DialogService; import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.integrity.IntegrityCheck; @@ -19,22 +20,28 @@ import org.jabref.model.entry.BibEntry; import org.jabref.preferences.JabRefPreferences; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; + public class IntegrityCheckAction extends SimpleCommand { - private final JabRefFrame frame; private final TaskExecutor taskExecutor; private final DialogService dialogService; + private final JabRefFrame frame; + private final StateManager stateManager; - public IntegrityCheckAction(JabRefFrame frame) { + public IntegrityCheckAction(JabRefFrame frame, StateManager stateManager, TaskExecutor taskExecutor) { this.frame = frame; - this.taskExecutor = Globals.TASK_EXECUTOR; + this.stateManager = stateManager; + this.taskExecutor = taskExecutor; this.dialogService = frame.getDialogService(); + + this.executable.bind(needsDatabase(this.stateManager)); } @Override public void execute() { - BibDatabaseContext databaseContext = frame.getCurrentBasePanel().getBibDatabaseContext(); - IntegrityCheck check = new IntegrityCheck(databaseContext, + BibDatabaseContext database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null")); + IntegrityCheck check = new IntegrityCheck(database, Globals.prefs.getFilePreferences(), Globals.prefs.getBibtexKeyPatternPreferences(), Globals.journalAbbreviationLoader.getRepository(Globals.prefs.getJournalAbbreviationPreferences()), @@ -45,7 +52,7 @@ public void execute() { protected List call() { List result = new ArrayList<>(); - ObservableList entries = databaseContext.getDatabase().getEntries(); + ObservableList entries = database.getDatabase().getEntries(); for (int i = 0; i < entries.size(); i++) { if (isCancelled()) { break; diff --git a/src/main/java/org/jabref/gui/actions/ManageJournalsAction.java b/src/main/java/org/jabref/gui/journals/ManageJournalsAction.java similarity index 63% rename from src/main/java/org/jabref/gui/actions/ManageJournalsAction.java rename to src/main/java/org/jabref/gui/journals/ManageJournalsAction.java index b089a505a9e..bd3b79907d2 100644 --- a/src/main/java/org/jabref/gui/actions/ManageJournalsAction.java +++ b/src/main/java/org/jabref/gui/journals/ManageJournalsAction.java @@ -1,6 +1,6 @@ -package org.jabref.gui.actions; +package org.jabref.gui.journals; -import org.jabref.gui.journals.ManageJournalAbbreviationsView; +import org.jabref.gui.actions.SimpleCommand; public class ManageJournalsAction extends SimpleCommand { diff --git a/src/main/java/org/jabref/gui/actions/CustomizeKeyBindingAction.java b/src/main/java/org/jabref/gui/keyboard/CustomizeKeyBindingAction.java similarity index 65% rename from src/main/java/org/jabref/gui/actions/CustomizeKeyBindingAction.java rename to src/main/java/org/jabref/gui/keyboard/CustomizeKeyBindingAction.java index fdaa5538ff4..44f5861fac1 100644 --- a/src/main/java/org/jabref/gui/actions/CustomizeKeyBindingAction.java +++ b/src/main/java/org/jabref/gui/keyboard/CustomizeKeyBindingAction.java @@ -1,6 +1,6 @@ -package org.jabref.gui.actions; +package org.jabref.gui.keyboard; -import org.jabref.gui.keyboard.KeyBindingsDialogView; +import org.jabref.gui.actions.SimpleCommand; public class CustomizeKeyBindingAction extends SimpleCommand { diff --git a/src/main/java/org/jabref/gui/actions/LibraryPropertiesAction.java b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesAction.java similarity index 66% rename from src/main/java/org/jabref/gui/actions/LibraryPropertiesAction.java rename to src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesAction.java index 1b2299e3f06..6c513dbc9ce 100644 --- a/src/main/java/org/jabref/gui/actions/LibraryPropertiesAction.java +++ b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesAction.java @@ -1,17 +1,22 @@ -package org.jabref.gui.actions; +package org.jabref.gui.libraryproperties; import org.jabref.gui.DialogService; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.libraryproperties.LibraryPropertiesDialogView; +import org.jabref.gui.StateManager; +import org.jabref.gui.actions.SimpleCommand; + +import static org.jabref.gui.actions.ActionHelper.needsDatabase; public class LibraryPropertiesAction extends SimpleCommand { private final JabRefFrame frame; private final DialogService dialogService; - public LibraryPropertiesAction(JabRefFrame frame, DialogService dialogService) { + public LibraryPropertiesAction(JabRefFrame frame, DialogService dialogService, StateManager stateManager) { this.frame = frame; this.dialogService = dialogService; + + this.executable.bind(needsDatabase(stateManager)); } @Override diff --git a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialog.fxml b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialog.fxml index 2cb00861431..76aa87d595c 100644 --- a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialog.fxml +++ b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialog.fxml @@ -11,7 +11,6 @@ - diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesAction.java b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesAction.java index 22ba15d7d8a..71bae10e73b 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesAction.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesAction.java @@ -6,6 +6,7 @@ import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableInsertEntry; @@ -13,14 +14,18 @@ import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; + public class MergeEntriesAction extends SimpleCommand { private final JabRefFrame jabRefFrame; private final DialogService dialogService; - public MergeEntriesAction(JabRefFrame jabRefFrame) { + public MergeEntriesAction(JabRefFrame jabRefFrame, StateManager stateManager) { this.jabRefFrame = jabRefFrame; - dialogService = jabRefFrame.getDialogService(); + this.dialogService = jabRefFrame.getDialogService(); + + this.executable.bind(needsDatabase(stateManager)); } @Override @@ -52,9 +57,9 @@ public void execute() { // Remove the other two entries and add them to the undo stack (which is not working...) NamedCompound ce = new NamedCompound(Localization.lang("Merge entries")); ce.addEdit(new UndoableInsertEntry(basePanel.getDatabase(), mergedEntry.get())); - ce.addEdit(new UndoableRemoveEntry(basePanel.getDatabase(), one, basePanel)); + ce.addEdit(new UndoableRemoveEntry(basePanel.getDatabase(), one)); basePanel.getDatabase().removeEntry(one); - ce.addEdit(new UndoableRemoveEntry(basePanel.getDatabase(), two, basePanel)); + ce.addEdit(new UndoableRemoveEntry(basePanel.getDatabase(), two)); basePanel.getDatabase().removeEntry(two); ce.end(); basePanel.getUndoManager().addEdit(ce); diff --git a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorAction.java b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorAction.java index 7e37e175319..af36819dd91 100644 --- a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorAction.java +++ b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorAction.java @@ -1,20 +1,24 @@ package org.jabref.gui.metadata; -import org.jabref.gui.JabRefFrame; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; -import org.jabref.model.database.BibDatabase; +import org.jabref.model.database.BibDatabaseContext; + +import static org.jabref.gui.actions.ActionHelper.needsDatabase; public class BibtexStringEditorAction extends SimpleCommand { - private final JabRefFrame frame; + private final StateManager stateManager; + + public BibtexStringEditorAction(StateManager stateManager) { + this.stateManager = stateManager; - public BibtexStringEditorAction(JabRefFrame jabRefFrame) { - this.frame = jabRefFrame; + this.executable.bind(needsDatabase(this.stateManager)); } @Override public void execute() { - BibDatabase database = frame.getCurrentBasePanel().getDatabase(); - new BibtexStringEditorDialogView(database).showAndWait(); + BibDatabaseContext database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null")); + new BibtexStringEditorDialogView(database.getDatabase()).showAndWait(); } } diff --git a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialog.fxml b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialog.fxml index a9ceca60cd6..728897bd5db 100644 --- a/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialog.fxml +++ b/src/main/java/org/jabref/gui/metadata/BibtexStringEditorDialog.fxml @@ -7,7 +7,6 @@ - diff --git a/src/main/java/org/jabref/gui/metadata/PreambleEditor.java b/src/main/java/org/jabref/gui/metadata/PreambleEditor.java index 757c12aa732..00f28aea5b7 100644 --- a/src/main/java/org/jabref/gui/metadata/PreambleEditor.java +++ b/src/main/java/org/jabref/gui/metadata/PreambleEditor.java @@ -2,41 +2,45 @@ import java.util.Optional; +import javax.swing.undo.UndoManager; + import javafx.scene.control.ButtonType; import javafx.scene.control.DialogPane; import javafx.scene.control.TextArea; -import org.jabref.gui.BasePanel; -import org.jabref.gui.JabRefFrame; +import org.jabref.gui.DialogService; +import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.undo.UndoablePreambleChange; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabase; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; + public class PreambleEditor extends SimpleCommand { - private final TextArea editor = new TextArea(); + private DialogService dialogService; + private final StateManager stateManager; + private UndoManager undoManager; - private final JabRefFrame frame; + public PreambleEditor(StateManager stateManager, UndoManager undoManager, DialogService dialogService) { + this.dialogService = dialogService; + this.stateManager = stateManager; + this.undoManager = undoManager; - public PreambleEditor(JabRefFrame frame) { - this.frame = frame; + this.executable.bind(needsDatabase(stateManager)); } @Override public void execute() { - BasePanel panel = frame.getCurrentBasePanel(); - BibDatabase database = frame.getCurrentBasePanel().getDatabase(); + BibDatabase database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null")).getDatabase(); + TextArea editor = new TextArea(); + editor.setText(database.getPreamble().orElse("")); DialogPane pane = new DialogPane(); - - editor.setText(frame.getCurrentBasePanel() - .getDatabase() - .getPreamble() - .orElse("")); pane.setContent(editor); - Optional pressedButton = frame.getDialogService().showCustomDialogAndWait(Localization.lang("Edit Preamble"), pane, ButtonType.APPLY, ButtonType.CANCEL); + Optional pressedButton = dialogService.showCustomDialogAndWait(Localization.lang("Edit Preamble"), pane, ButtonType.APPLY, ButtonType.CANCEL); if (pressedButton.isPresent() && pressedButton.get().equals(ButtonType.APPLY)) { String newPreamble = editor.getText(); @@ -44,15 +48,10 @@ public void execute() { // We check if the field has changed, since we don't want to mark the // base as changed unless we have a real change. if (!database.getPreamble().orElse("").equals(newPreamble)) { - - panel.getUndoManager().addEdit( - new UndoablePreambleChange(database, database.getPreamble().orElse(null), newPreamble)); + undoManager.addEdit(new UndoablePreambleChange(database, database.getPreamble().orElse(null), newPreamble)); database.setPreamble(newPreamble); - - panel.markBaseChanged(); } } - } } diff --git a/src/main/java/org/jabref/gui/preferences/ExternalTab.java b/src/main/java/org/jabref/gui/preferences/ExternalTab.java index fc6603f9a95..381ece611a8 100644 --- a/src/main/java/org/jabref/gui/preferences/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preferences/ExternalTab.java @@ -12,11 +12,11 @@ import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.actions.EditExternalFileTypesAction; +import org.jabref.gui.externalfiletype.EditExternalFileTypesAction; import org.jabref.gui.push.PushToApplication; import org.jabref.gui.push.PushToApplicationSettings; import org.jabref.gui.push.PushToApplicationSettingsDialog; -import org.jabref.gui.push.PushToApplications; +import org.jabref.gui.push.PushToApplicationsManager; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; @@ -174,7 +174,7 @@ public Node getBuilder() { } private void addSettingsButton(final PushToApplication application, GridPane panel, int index) { - PushToApplicationSettings settings = PushToApplications.getSettings(application); + PushToApplicationSettings settings = PushToApplicationsManager.getSettings(application); Button button = new Button(Localization.lang("Settings for %0", application.getApplicationName())); button.setPrefSize(150, 20); button.setOnAction(e -> PushToApplicationSettingsDialog.showSettingsDialog(dialogService, settings, index)); diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml index 2e41e88e6c2..d28949c1983 100644 --- a/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml +++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialog.fxml @@ -1,6 +1,5 @@ - - + diff --git a/src/main/java/org/jabref/gui/actions/ShowPreferencesAction.java b/src/main/java/org/jabref/gui/preferences/ShowPreferencesAction.java similarity index 87% rename from src/main/java/org/jabref/gui/actions/ShowPreferencesAction.java rename to src/main/java/org/jabref/gui/preferences/ShowPreferencesAction.java index e6c0a29684c..b47321f0095 100644 --- a/src/main/java/org/jabref/gui/actions/ShowPreferencesAction.java +++ b/src/main/java/org/jabref/gui/preferences/ShowPreferencesAction.java @@ -1,7 +1,7 @@ -package org.jabref.gui.actions; +package org.jabref.gui.preferences; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.preferences.PreferencesDialog; +import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.TaskExecutor; public class ShowPreferencesAction extends SimpleCommand { diff --git a/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java b/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java index 0f6b18daad0..bbd62196773 100644 --- a/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java +++ b/src/main/java/org/jabref/gui/push/AbstractPushToApplication.java @@ -4,13 +4,11 @@ import java.util.List; import org.jabref.Globals; -import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; -import org.jabref.model.database.BibDatabase; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; -import org.jabref.model.metadata.MetaData; import org.jabref.preferences.JabRefPreferences; import org.slf4j.Logger; @@ -47,8 +45,7 @@ public String getTooltip() { } @Override - public void pushEntries(BibDatabase database, List entries, String keyString, MetaData metaData) { - + public void pushEntries(BibDatabaseContext database, List entries, String keyString) { couldNotConnect = false; couldNotCall = false; notDefined = false; @@ -95,18 +92,21 @@ public void pushEntries(BibDatabase database, List entries, String key } @Override - public void operationCompleted(BasePanel panel) { + public void operationCompleted() { if (notDefined) { - panel.output(Localization.lang("Error") + ": " - + Localization.lang("Path to %0 not defined", getApplicationName()) + "."); + dialogService.showErrorDialogAndWait( + Localization.lang("Error pushing entries"), + Localization.lang("Path to %0 not defined", getApplicationName()) + "."); } else if (couldNotCall) { - panel.output(Localization.lang("Error") + ": " - + Localization.lang("Could not call executable") + " '" + commandPath + "'."); + dialogService.showErrorDialogAndWait( + Localization.lang("Error pushing entries"), + Localization.lang("Could not call executable") + " '" + commandPath + "'."); } else if (couldNotConnect) { - panel.output(Localization.lang("Error") + ": " - + Localization.lang("Could not connect to %0", getApplicationName()) + "."); + dialogService.showErrorDialogAndWait( + Localization.lang("Error pushing entries"), + Localization.lang("Could not connect to %0", getApplicationName()) + "."); } else { - panel.output(Localization.lang("Pushed citations to %0", getApplicationName()) + "."); + dialogService.notify(Localization.lang("Pushed citations to %0", getApplicationName()) + "."); } } diff --git a/src/main/java/org/jabref/gui/push/PushToApplication.java b/src/main/java/org/jabref/gui/push/PushToApplication.java index a892becd602..cea92bc0ae1 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplication.java +++ b/src/main/java/org/jabref/gui/push/PushToApplication.java @@ -2,11 +2,9 @@ import java.util.List; -import org.jabref.gui.BasePanel; import org.jabref.gui.icon.JabRefIcon; -import org.jabref.model.database.BibDatabase; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; -import org.jabref.model.metadata.MetaData; /** * Class that defines interaction with an external application in the form of "pushing" selected entries to it. @@ -25,17 +23,13 @@ public interface PushToApplication { /** * The actual operation. This method will not be called on the event dispatch thread, so it should not do GUI * operations without utilizing invokeLater(). - * - * @param database - * @param entries - * @param metaData */ - void pushEntries(BibDatabase database, List entries, String keyString, MetaData metaData); + void pushEntries(BibDatabaseContext database, List entries, String keyString); /** * Reporting etc., this method is called on the event dispatch thread after pushEntries() returns. */ - void operationCompleted(BasePanel panel); + void operationCompleted(); /** * Check whether this operation requires BibTeX keys to be set for the entries. If true is returned an error message diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationAction.java b/src/main/java/org/jabref/gui/push/PushToApplicationAction.java index 3231a2a5e21..ecfb54763ad 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationAction.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationAction.java @@ -4,19 +4,21 @@ import java.util.Optional; import org.jabref.Globals; -import org.jabref.gui.BasePanel; -import org.jabref.gui.JabRefFrame; +import org.jabref.gui.DialogService; import org.jabref.gui.StateManager; import org.jabref.gui.actions.Action; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.icon.JabRefIcon; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.util.BackgroundTask; +import org.jabref.gui.util.BindingsHelper; import org.jabref.logic.l10n.Localization; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; -import org.jabref.preferences.JabRefPreferences; +import org.jabref.model.strings.StringUtil; -import org.fxmisc.easybind.EasyBind; +import static org.jabref.gui.actions.ActionHelper.needsDatabase; +import static org.jabref.gui.actions.ActionHelper.needsEntriesSelected; /** * An Action class representing the process of invoking a PushToApplication operation. @@ -24,26 +26,16 @@ public class PushToApplicationAction extends SimpleCommand { private final PushToApplication operation; - private final JabRefFrame frame; - private BasePanel panel; - private List entries; - - public PushToApplicationAction(final JabRefFrame frame, final StateManager stateManager) { - this.frame = frame; - this.operation = getLastUsedApplication(frame.getPushApplications().getApplications()); - this.executable.bind(EasyBind.map(stateManager.activeDatabaseProperty(), Optional::isPresent)); - } + private final StateManager stateManager; + private final DialogService dialogService; - private PushToApplication getLastUsedApplication(List pushActions) { - String appSelected = Globals.prefs.get(JabRefPreferences.PUSH_TO_APPLICATION); - for (PushToApplication application : pushActions) { - if (application.getApplicationName().equals(appSelected)) { - return application; - } - } + public PushToApplicationAction(StateManager stateManager, PushToApplicationsManager pushToApplicationsManager, DialogService dialogService) { + this.operation = pushToApplicationsManager.getLastUsedApplication(Globals.prefs); + this.stateManager = stateManager; + this.dialogService = dialogService; - // Nothing found, pick first - return pushActions.get(0); + this.executable.bind(needsDatabase(stateManager).and(needsEntriesSelected(stateManager))); + this.statusMessage.bind(BindingsHelper.ifThenElse(this.executable, "", Localization.lang("This operation requires one or more entries to be selected."))); } public Action getActionInformation() { @@ -71,57 +63,14 @@ public String getDescription() { }; } - @Override - public void execute() { - panel = frame.getCurrentBasePanel(); - - // Check if a BasePanel exists: - if (panel == null) { - return; - } - - // Check if any entries are selected: - entries = panel.getSelectedEntries(); - if (entries.isEmpty()) { - frame.getDialogService().showErrorDialogAndWait(operation.getApplicationName(), - Localization.lang("This operation requires one or more entries to be selected.")); - - return; - } - - // If required, check that all entries have BibTeX keys defined: - if (operation.requiresBibtexKeys()) { - for (BibEntry entry : entries) { - if (!(entry.getCiteKeyOptional().isPresent()) || entry.getCiteKeyOptional().get().trim().isEmpty()) { - frame.getDialogService().showErrorDialogAndWait(operation.getApplicationName(), - Localization.lang("This operation requires all selected entries to have BibTeX keys defined.")); - - return; - } - } - } - - // All set, call the operation in a new thread: - - BackgroundTask.wrap(this::pushentries) - .onSuccess(s -> operation.operationCompleted(panel)) - .executeWith(Globals.TASK_EXECUTOR); - - } - - private void pushentries() { - operation.pushEntries(panel.getDatabase(), entries, getKeyString(entries), panel.getBibDatabaseContext().getMetaData()); - } - - private static String getKeyString(List bibentries) { + private static String getKeyString(List entries) { StringBuilder result = new StringBuilder(); Optional citeKey; boolean first = true; - for (BibEntry bes : bibentries) { + for (BibEntry bes : entries) { citeKey = bes.getCiteKeyOptional(); - // if the key is empty we give a warning and ignore this entry - // TODO: Give warning if (!(citeKey.isPresent()) || citeKey.get().isEmpty()) { + // Should never occur, because we made sure that all entries have keys continue; } if (first) { @@ -133,4 +82,31 @@ private static String getKeyString(List bibentries) { } return result.toString(); } + + @Override + public void execute() { + // If required, check that all entries have BibTeX keys defined: + if (operation.requiresBibtexKeys()) { + for (BibEntry entry : stateManager.getSelectedEntries()) { + if (StringUtil.isBlank(entry.getCiteKeyOptional())) { + dialogService.showErrorDialogAndWait( + operation.getApplicationName(), + Localization.lang("This operation requires all selected entries to have BibTeX keys defined.")); + + return; + } + } + } + + // All set, call the operation in a new thread: + BackgroundTask.wrap(this::pushEntries) + .onSuccess(s -> operation.operationCompleted()) + .executeWith(Globals.TASK_EXECUTOR); + + } + + private void pushEntries() { + BibDatabaseContext database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null")); + operation.pushEntries(database, stateManager.getSelectedEntries(), getKeyString(stateManager.getSelectedEntries())); + } } diff --git a/src/main/java/org/jabref/gui/push/PushToApplications.java b/src/main/java/org/jabref/gui/push/PushToApplicationsManager.java similarity index 67% rename from src/main/java/org/jabref/gui/push/PushToApplications.java rename to src/main/java/org/jabref/gui/push/PushToApplicationsManager.java index 0fe5024dee7..32a13f1226b 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplications.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationsManager.java @@ -4,14 +4,14 @@ import java.util.List; import org.jabref.gui.DialogService; +import org.jabref.preferences.JabRefPreferences; -public class PushToApplications { +public class PushToApplicationsManager { private final List applications; - public PushToApplications(DialogService dialogService) { + public PushToApplicationsManager(DialogService dialogService) { // Set up the current available choices: - applications = new ArrayList<>(); applications.add(new PushToEmacs(dialogService)); applications.add(new PushToLyx(dialogService)); @@ -36,4 +36,12 @@ public static PushToApplicationSettings getSettings(PushToApplication applicatio return new PushToApplicationSettings(); } } + + public PushToApplication getLastUsedApplication(JabRefPreferences preferences) { + String appSelected = preferences.get(JabRefPreferences.PUSH_TO_APPLICATION); + return applications.stream() + .filter(application -> application.getApplicationName().equals(appSelected)) + .findAny() + .orElse(applications.get(0)); + } } diff --git a/src/main/java/org/jabref/gui/push/PushToEmacs.java b/src/main/java/org/jabref/gui/push/PushToEmacs.java index 3603bd646cb..72cbf7228f9 100644 --- a/src/main/java/org/jabref/gui/push/PushToEmacs.java +++ b/src/main/java/org/jabref/gui/push/PushToEmacs.java @@ -6,15 +6,13 @@ import org.jabref.Globals; import org.jabref.JabRefExecutorService; -import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.icon.JabRefIcon; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; -import org.jabref.model.database.BibDatabase; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; -import org.jabref.model.metadata.MetaData; import org.jabref.preferences.JabRefPreferences; import org.slf4j.Logger; @@ -39,8 +37,7 @@ public JabRefIcon getIcon() { } @Override - public void pushEntries(BibDatabase database, List entries, String keys, MetaData metaData) { - + public void pushEntries(BibDatabaseContext database, List entries, String keys) { couldNotConnect = false; couldNotCall = false; notDefined = false; @@ -105,9 +102,8 @@ public void pushEntries(BibDatabase database, List entries, String key } @Override - public void operationCompleted(BasePanel panel) { + public void operationCompleted() { if (couldNotConnect) { - dialogService.showErrorDialogAndWait(Localization.lang("Error pushing entries"), Localization.lang("Could not connect to a running gnuserv process. Make sure that " + "Emacs or XEmacs is running, and that the server has been started " @@ -119,7 +115,7 @@ public void operationCompleted(BasePanel panel) { + "the emacsclient/gnuclient program installed and available in the PATH.")); } else { - super.operationCompleted(panel); + super.operationCompleted(); } } diff --git a/src/main/java/org/jabref/gui/push/PushToLyx.java b/src/main/java/org/jabref/gui/push/PushToLyx.java index f1b58c1ec6f..38906bd3b39 100644 --- a/src/main/java/org/jabref/gui/push/PushToLyx.java +++ b/src/main/java/org/jabref/gui/push/PushToLyx.java @@ -8,14 +8,12 @@ import org.jabref.Globals; import org.jabref.JabRefExecutorService; -import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.icon.JabRefIcon; import org.jabref.logic.l10n.Localization; -import org.jabref.model.database.BibDatabase; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; -import org.jabref.model.metadata.MetaData; import org.jabref.preferences.JabRefPreferences; import org.slf4j.Logger; @@ -45,22 +43,20 @@ protected void initParameters() { } @Override - public void operationCompleted(BasePanel panel) { + public void operationCompleted() { if (couldNotConnect) { - panel.output(Localization.lang("Error") + ": " + + dialogService.showErrorDialogAndWait(Localization.lang("Error pushing entries"), Localization.lang("verify that LyX is running and that the lyxpipe is valid") + ". [" + commandPath + "]"); } else if (couldNotCall) { - panel.output(Localization.lang("Error") + ": " + - Localization.lang("unable to write to") + " " + commandPath + - ".in"); + dialogService.showErrorDialogAndWait(Localization.lang("unable to write to") + " " + commandPath + ".in"); } else { - super.operationCompleted(panel); + super.operationCompleted(); } } @Override - public void pushEntries(BibDatabase database, final List entries, final String keyString, MetaData metaData) { + public void pushEntries(BibDatabaseContext database, final List entries, final String keyString) { couldNotConnect = false; couldNotCall = false; notDefined = false; @@ -90,13 +86,8 @@ public void pushEntries(BibDatabase database, final List entries, fina JabRefExecutorService.INSTANCE.executeAndWait(() -> { try (FileWriter fw = new FileWriter(lyxpipe); BufferedWriter lyxOut = new BufferedWriter(fw)) { - String citeStr; - - citeStr = "LYXCMD:sampleclient:citation-insert:" + keyString; + String citeStr = "LYXCMD:sampleclient:citation-insert:" + keyString; lyxOut.write(citeStr + "\n"); - - lyxOut.close(); - fw.close(); } catch (IOException excep) { couldNotCall = true; LOGGER.warn("Problem pushing to LyX/Kile.", excep); diff --git a/src/main/java/org/jabref/gui/push/PushToVim.java b/src/main/java/org/jabref/gui/push/PushToVim.java index 46af5b2556d..ba0fafa1da2 100644 --- a/src/main/java/org/jabref/gui/push/PushToVim.java +++ b/src/main/java/org/jabref/gui/push/PushToVim.java @@ -6,14 +6,12 @@ import org.jabref.Globals; import org.jabref.JabRefExecutorService; -import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.icon.JabRefIcon; import org.jabref.logic.l10n.Localization; -import org.jabref.model.database.BibDatabase; +import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; -import org.jabref.model.metadata.MetaData; import org.jabref.preferences.JabRefPreferences; import org.slf4j.Logger; @@ -38,8 +36,7 @@ public JabRefIcon getIcon() { } @Override - public void pushEntries(BibDatabase database, List entries, String keys, MetaData metaData) { - + public void pushEntries(BibDatabaseContext database, List entries, String keys) { couldNotConnect = false; couldNotCall = false; notDefined = false; @@ -88,9 +85,8 @@ public void pushEntries(BibDatabase database, List entries, String key } @Override - public void operationCompleted(BasePanel panel) { + public void operationCompleted() { if (couldNotConnect) { - dialogService.showErrorDialogAndWait(Localization.lang("Error pushing entries"), Localization.lang("Could not connect to Vim server. Make sure that Vim is running with correct server name.")); @@ -99,7 +95,7 @@ public void operationCompleted(BasePanel panel) { Localization.lang("Could not run the 'vim' program.")); } else { - super.operationCompleted(panel); + super.operationCompleted(); } } diff --git a/src/main/java/org/jabref/gui/actions/ConnectToSharedDatabaseCommand.java b/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseCommand.java similarity index 82% rename from src/main/java/org/jabref/gui/actions/ConnectToSharedDatabaseCommand.java rename to src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseCommand.java index 792aff5bf34..6d8aee1b301 100644 --- a/src/main/java/org/jabref/gui/actions/ConnectToSharedDatabaseCommand.java +++ b/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseCommand.java @@ -1,7 +1,7 @@ -package org.jabref.gui.actions; +package org.jabref.gui.shared; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.shared.SharedDatabaseLoginDialogView; +import org.jabref.gui.actions.SimpleCommand; /** * Opens a shared database. diff --git a/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialog.fxml b/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialog.fxml index 30808026c50..f6f681e3c40 100644 --- a/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialog.fxml +++ b/src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialog.fxml @@ -1,6 +1,5 @@ - @@ -9,11 +8,11 @@ + - diff --git a/src/main/java/org/jabref/gui/shared/SharedDatabaseUIManager.java b/src/main/java/org/jabref/gui/shared/SharedDatabaseUIManager.java index 94bc02ddc5b..1d9de038f98 100644 --- a/src/main/java/org/jabref/gui/shared/SharedDatabaseUIManager.java +++ b/src/main/java/org/jabref/gui/shared/SharedDatabaseUIManager.java @@ -91,7 +91,7 @@ public void listen(SharedEntryNotPresentEvent event) { BasePanel panel = jabRefFrame.getCurrentBasePanel(); EntryEditor entryEditor = panel.getEntryEditor(); - panel.getUndoManager().addEdit(new UndoableRemoveEntry(panel.getDatabase(), event.getBibEntry(), panel)); + panel.getUndoManager().addEdit(new UndoableRemoveEntry(panel.getDatabase(), event.getBibEntry())); if (Objects.nonNull(entryEditor) && (entryEditor.getEntry() == event.getBibEntry())) { diff --git a/src/main/java/org/jabref/gui/undo/UndoableRemoveEntry.java b/src/main/java/org/jabref/gui/undo/UndoableRemoveEntry.java index 3190356a34d..21362cbfac8 100644 --- a/src/main/java/org/jabref/gui/undo/UndoableRemoveEntry.java +++ b/src/main/java/org/jabref/gui/undo/UndoableRemoveEntry.java @@ -1,6 +1,5 @@ package org.jabref.gui.undo; -import org.jabref.gui.BasePanel; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; @@ -22,13 +21,9 @@ public class UndoableRemoveEntry extends AbstractUndoableJabRefEdit { private final BibDatabase base; private final BibEntry entry; - private final BasePanel panel; - - public UndoableRemoveEntry(BibDatabase base, BibEntry entry, - BasePanel panel) { + public UndoableRemoveEntry(BibDatabase base, BibEntry entry) { this.base = base; this.entry = entry; - this.panel = panel; } @Override @@ -50,8 +45,6 @@ public void redo() { // Redo the change. try { base.removeEntry(entry); - // If the entry has an editor currently open, we must close it. - panel.ensureNotShowingBottomPanel(entry); } catch (Throwable ex) { LOGGER.warn("Problem to redo `remove entry`", ex); } diff --git a/src/main/java/org/jabref/gui/util/BindingsHelper.java b/src/main/java/org/jabref/gui/util/BindingsHelper.java index f53509c3f11..e3d8ad19a85 100644 --- a/src/main/java/org/jabref/gui/util/BindingsHelper.java +++ b/src/main/java/org/jabref/gui/util/BindingsHelper.java @@ -22,6 +22,7 @@ import javafx.css.PseudoClass; import javafx.scene.Node; +import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.PreboundBinding; /** @@ -187,6 +188,16 @@ public static ObservableList forUI(ObservableList list) { return new UiThreadList<>(list); } + public static ObservableValue ifThenElse(ObservableValue condition, T value, T other) { + return EasyBind.map(condition, conditionValue -> { + if (conditionValue) { + return value; + } else { + return other; + } + }); + } + private static class BidirectionalBinding { private final ObservableValue propertyA; diff --git a/src/main/java/org/jabref/gui/util/OptionalObjectProperty.java b/src/main/java/org/jabref/gui/util/OptionalObjectProperty.java new file mode 100644 index 00000000000..f8e9e5d7263 --- /dev/null +++ b/src/main/java/org/jabref/gui/util/OptionalObjectProperty.java @@ -0,0 +1,45 @@ +package org.jabref.gui.util; + +import java.util.Optional; + +import javafx.beans.binding.BooleanExpression; +import javafx.beans.binding.ObjectBinding; +import javafx.beans.property.SimpleObjectProperty; + +import org.fxmisc.easybind.PreboundBinding; + +/** + * Similar to {@link org.fxmisc.easybind.monadic.MonadicObservableValue} + */ +public class OptionalObjectProperty extends SimpleObjectProperty> { + + private OptionalObjectProperty(Optional initialValue) { + super(initialValue); + } + + public static OptionalObjectProperty empty() { + return new OptionalObjectProperty<>(Optional.empty()); + } + + /** + * Returns a new ObservableValue that holds the value held by this + * ObservableValue, or {@code other} when this ObservableValue is empty. + */ + public ObjectBinding orElse(T other) { + return new PreboundBinding(this) { + @Override + protected T computeValue() { + return OptionalObjectProperty.this.getValue().orElse(other); + } + }; + } + + public BooleanExpression isPresent() { + return BooleanExpression.booleanExpression(new PreboundBinding(this) { + @Override + protected Boolean computeValue() { + return OptionalObjectProperty.this.getValue().isPresent(); + } + }); + } +} diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 1546ff133c3..c6ad976a655 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2038,7 +2038,6 @@ Add\ new\ String=Add new String Remove\ selected\ Strings=Remove selected Strings Must\ not\ be\ empty\!=Must not be empty\! Open\ Help\ page=Open Help page -Active\ database\ connection\ do\ not\ exists\!=Active database connection do not exists! Add\ new\ field\ name=Add new field name Field\ name\:=Field name: Field\ name\ \"%0\"\ already\ exists=Field name "%0" already exists From 08b583d42e7187e4fabcad9068beede502696333 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 24 Apr 2019 20:54:11 +0200 Subject: [PATCH 15/16] Refactorings, move functionality of CustomEntryTypesManager to Preferences Use ObservableList instead of LIstProperty --- .../CustomEntryTypesManager.java | 35 ------ .../ImportCustomEntryTypesDialog.java | 12 +- ...ImportCustomEntryTypesDialogViewModel.java | 32 +++--- .../actions/CheckForNewEntryTypesAction.java | 4 +- .../importer/actions/GUIPostOpenAction.java | 1 - .../importer/actions/OpenDatabaseAction.java | 1 - .../CustomEntryTypePreferenceMigration.java | 3 +- .../jabref/preferences/JabRefPreferences.java | 105 ++++++++++-------- .../preferences/PreferencesService.java | 2 + 9 files changed, 86 insertions(+), 109 deletions(-) delete mode 100644 src/main/java/org/jabref/gui/customentrytypes/CustomEntryTypesManager.java diff --git a/src/main/java/org/jabref/gui/customentrytypes/CustomEntryTypesManager.java b/src/main/java/org/jabref/gui/customentrytypes/CustomEntryTypesManager.java deleted file mode 100644 index e3bf628cadc..00000000000 --- a/src/main/java/org/jabref/gui/customentrytypes/CustomEntryTypesManager.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.jabref.gui.customentrytypes; - -import java.util.List; -import java.util.stream.Collectors; - -import org.jabref.model.EntryTypes; -import org.jabref.model.database.BibDatabaseMode; -import org.jabref.model.entry.CustomEntryType; -import org.jabref.preferences.JabRefPreferences; - -public class CustomEntryTypesManager { - - private CustomEntryTypesManager() { - } - - /** - * Iterate through all entry types, and store those that are - * custom defined to preferences. This method is called from - * JabRefFrame when the program closes. - */ - public static void saveCustomEntryTypes(JabRefPreferences prefs) { - saveCustomEntryTypes(prefs, BibDatabaseMode.BIBTEX); - saveCustomEntryTypes(prefs, BibDatabaseMode.BIBLATEX); - - } - - private static void saveCustomEntryTypes(JabRefPreferences prefs, BibDatabaseMode mode) { - List customBiblatexTypes = EntryTypes.getAllValues(mode).stream() - .filter(type -> type instanceof CustomEntryType) - .map(entryType -> (CustomEntryType) entryType).collect(Collectors.toList()); - - prefs.storeCustomEntryTypes(customBiblatexTypes, mode); - } - -} diff --git a/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.java b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.java index a4317279893..1d8ad964228 100644 --- a/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialog.java @@ -2,6 +2,8 @@ import java.util.List; +import javax.inject.Inject; + import javafx.beans.binding.Bindings; import javafx.fxml.FXML; import javafx.scene.control.ButtonType; @@ -11,6 +13,7 @@ import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.EntryType; +import org.jabref.preferences.PreferencesService; import com.airhacks.afterburner.views.ViewLoader; import org.controlsfx.control.CheckListView; @@ -20,6 +23,7 @@ public class ImportCustomEntryTypesDialog extends BaseDialog { @FXML private CheckListView unknownEntryTypesCheckList; @FXML private VBox boxDifferentCustomization; @FXML private CheckListView differentCustomizationCheckList; + @Inject private PreferencesService preferencesService; private ImportCustomEntryTypesDialogViewModel viewModel; @@ -47,11 +51,11 @@ public ImportCustomEntryTypesDialog(BibDatabaseMode mode, List custom @FXML public void initialize() { - viewModel = new ImportCustomEntryTypesDialogViewModel(mode, customEntryTypes); + viewModel = new ImportCustomEntryTypesDialogViewModel(mode, customEntryTypes, preferencesService); - boxDifferentCustomization.managedProperty().bind(Bindings.isNotEmpty(viewModel.differentCustomizationsProperty())); - unknownEntryTypesCheckList.itemsProperty().bind(viewModel.newTypesProperty()); - differentCustomizationCheckList.itemsProperty().bind(viewModel.differentCustomizationsProperty()); + boxDifferentCustomization.managedProperty().bind(Bindings.isNotEmpty(viewModel.differentCustomizations())); + unknownEntryTypesCheckList.setItems(viewModel.newTypes()); + differentCustomizationCheckList.setItems(viewModel.differentCustomizations()); } } diff --git a/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialogViewModel.java b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialogViewModel.java index 174c7e54e73..ebac412c8d7 100644 --- a/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialogViewModel.java +++ b/src/main/java/org/jabref/gui/importer/ImportCustomEntryTypesDialogViewModel.java @@ -2,29 +2,26 @@ import java.util.List; -import javafx.beans.property.ListProperty; -import javafx.beans.property.SimpleListProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import org.jabref.Globals; -import org.jabref.gui.customentrytypes.CustomEntryTypesManager; import org.jabref.model.EntryTypes; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.CustomEntryType; import org.jabref.model.entry.EntryType; +import org.jabref.preferences.PreferencesService; public class ImportCustomEntryTypesDialogViewModel { - private final ListProperty newTypesProperty; - private final ListProperty differentCustomizationsProperty; private final BibDatabaseMode mode; + private final PreferencesService preferencesService; - public ImportCustomEntryTypesDialogViewModel(BibDatabaseMode mode, List customEntryTypes) { - this.mode = mode; + private final ObservableList newTypes = FXCollections.observableArrayList(); + private final ObservableList differentCustomizationTypes = FXCollections.observableArrayList(); - ObservableList newTypes = FXCollections.observableArrayList(); - ObservableList differentCustomizationTypes = FXCollections.observableArrayList(); + public ImportCustomEntryTypesDialogViewModel(BibDatabaseMode mode, List customEntryTypes, PreferencesService preferencesService) { + this.mode = mode; + this.preferencesService = preferencesService; for (EntryType customType : customEntryTypes) { if (!EntryTypes.getType(customType.getName(), mode).isPresent()) { @@ -37,27 +34,24 @@ public ImportCustomEntryTypesDialogViewModel(BibDatabaseMode mode, List(newTypes); - differentCustomizationsProperty = new SimpleListProperty<>(differentCustomizationTypes); - } - public ListProperty newTypesProperty() { - return this.newTypesProperty; + public ObservableList newTypes() { + return this.newTypes; } - public ListProperty differentCustomizationsProperty() { - return this.differentCustomizationsProperty; + public ObservableList differentCustomizations() { + return this.differentCustomizationTypes; } public void importCustomEntryTypes(List checkedUnknownEntryTypes, List checkedDifferentEntryTypes) { if (!checkedUnknownEntryTypes.isEmpty()) { checkedUnknownEntryTypes.forEach(type -> EntryTypes.addOrModifyCustomEntryType((CustomEntryType) type, mode)); - CustomEntryTypesManager.saveCustomEntryTypes(Globals.prefs); + preferencesService.saveCustomEntryTypes(); } if (!checkedDifferentEntryTypes.isEmpty()) { checkedUnknownEntryTypes.forEach(type -> EntryTypes.addOrModifyCustomEntryType((CustomEntryType) type, mode)); - CustomEntryTypesManager.saveCustomEntryTypes(Globals.prefs); + preferencesService.saveCustomEntryTypes(); } } diff --git a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java index 66a65efe8a7..a62dfe74838 100644 --- a/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/CheckForNewEntryTypesAction.java @@ -26,8 +26,8 @@ public boolean isActionNecessary(ParserResult parserResult) { public void performAction(BasePanel panel, ParserResult parserResult) { BibDatabaseMode mode = getBibDatabaseModeFromParserResult(parserResult); - ImportCustomEntryTypesDialog dlg = new ImportCustomEntryTypesDialog(mode, getListOfUnknownAndUnequalCustomizations(parserResult)); - dlg.showAndWait(); + ImportCustomEntryTypesDialog importCustomEntryTypesDialog = new ImportCustomEntryTypesDialog(mode, getListOfUnknownAndUnequalCustomizations(parserResult)); + importCustomEntryTypesDialog.showAndWait(); } diff --git a/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java b/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java index 5250d76d0a1..739c11305e4 100644 --- a/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/GUIPostOpenAction.java @@ -32,7 +32,6 @@ public interface GUIPostOpenAction { * * @param panel The BasePanel where the database is shown. * @param pr The result of the BIB parse operation. - * @param dialogService */ void performAction(BasePanel panel, ParserResult pr); } 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 170b9369350..d57f8bdc490 100644 --- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java +++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java @@ -65,7 +65,6 @@ public OpenDatabaseAction(JabRefFrame frame) { * * @param panel The BasePanel where the database is shown. * @param result The result of the BIB file parse operation. - * @param dialogService */ public static void performPostOpenActions(BasePanel panel, ParserResult result) { for (GUIPostOpenAction action : OpenDatabaseAction.POST_OPEN_ACTIONS) { diff --git a/src/main/java/org/jabref/migrations/CustomEntryTypePreferenceMigration.java b/src/main/java/org/jabref/migrations/CustomEntryTypePreferenceMigration.java index f4573c62236..d01bf652a52 100644 --- a/src/main/java/org/jabref/migrations/CustomEntryTypePreferenceMigration.java +++ b/src/main/java/org/jabref/migrations/CustomEntryTypePreferenceMigration.java @@ -5,7 +5,6 @@ import java.util.Optional; import org.jabref.Globals; -import org.jabref.gui.customentrytypes.CustomEntryTypesManager; import org.jabref.model.EntryTypes; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.CustomEntryType; @@ -36,7 +35,7 @@ static void upgradeStoredCustomEntryTypes(BibDatabaseMode defaultBibDatabaseMode number++; } - CustomEntryTypesManager.saveCustomEntryTypes(prefs); + prefs.saveCustomEntryTypes(); } /** diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 6c9217ba0fc..f977a0262cb 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -88,6 +88,7 @@ import org.jabref.logic.util.io.AutoLinkPreferences; import org.jabref.logic.util.io.FileHistory; import org.jabref.logic.xmp.XmpPreferences; +import org.jabref.model.EntryTypes; import org.jabref.model.bibtexkeypattern.GlobalBibtexKeyPattern; import org.jabref.model.cleanup.FieldFormatterCleanups; import org.jabref.model.database.BibDatabaseMode; @@ -872,11 +873,11 @@ 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.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)); @@ -1437,8 +1438,8 @@ public FilePreferences getFilePreferences() { @Override public UpdateFieldPreferences getUpdateFieldPreferences() { return new UpdateFieldPreferences(getBoolean(USE_OWNER), getBoolean(OVERWRITE_OWNER), get(DEFAULT_OWNER), - getBoolean(USE_TIME_STAMP), getBoolean(OVERWRITE_TIME_STAMP), get(TIME_STAMP_FIELD), - get(TIME_STAMP_FORMAT)); + getBoolean(USE_TIME_STAMP), getBoolean(OVERWRITE_TIME_STAMP), get(TIME_STAMP_FIELD), + get(TIME_STAMP_FORMAT)); } public LatexFieldFormatterPreferences getLatexFieldFormatterPreferences() { @@ -1453,14 +1454,14 @@ public FieldContentParserPreferences getFieldContentParserPreferences() { @Override public boolean isKeywordSyncEnabled() { return getBoolean(JabRefPreferences.SPECIALFIELDSENABLED) - && getBoolean(JabRefPreferences.AUTOSYNCSPECIALFIELDSTOKEYWORDS); + && getBoolean(JabRefPreferences.AUTOSYNCSPECIALFIELDSTOKEYWORDS); } @Override public ImportFormatPreferences getImportFormatPreferences() { return new ImportFormatPreferences(customImports, getDefaultEncoding(), getKeywordDelimiter(), - getBibtexKeyPatternPreferences(), getFieldContentParserPreferences(), getXMPPreferences(), - isKeywordSyncEnabled()); + getBibtexKeyPatternPreferences(), getFieldContentParserPreferences(), getXMPPreferences(), + isKeywordSyncEnabled()); } @Override @@ -1475,32 +1476,32 @@ public SavePreferences loadForExportFromPreferences() { } } return new SavePreferences( - saveInOriginalOrder, - saveOrder, - this.getDefaultEncoding(), - this.getBoolean(JabRefPreferences.BACKUP), - SavePreferences.DatabaseSaveType.ALL, - false, - this.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT), - this.getLatexFieldFormatterPreferences(), - this.getKeyPattern(), - getBoolean(JabRefPreferences.GENERATE_KEYS_BEFORE_SAVING), - getBibtexKeyPatternPreferences()); + saveInOriginalOrder, + saveOrder, + this.getDefaultEncoding(), + this.getBoolean(JabRefPreferences.BACKUP), + SavePreferences.DatabaseSaveType.ALL, + false, + this.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT), + this.getLatexFieldFormatterPreferences(), + this.getKeyPattern(), + getBoolean(JabRefPreferences.GENERATE_KEYS_BEFORE_SAVING), + getBibtexKeyPatternPreferences()); } public SavePreferences loadForSaveFromPreferences() { return new SavePreferences( - false, - null, - this.getDefaultEncoding(), - this.getBoolean(JabRefPreferences.BACKUP), - SavePreferences.DatabaseSaveType.ALL, - true, - this.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT), - this.getLatexFieldFormatterPreferences(), - this.getKeyPattern(), - getBoolean(JabRefPreferences.GENERATE_KEYS_BEFORE_SAVING), - getBibtexKeyPatternPreferences()); + false, + null, + this.getDefaultEncoding(), + this.getBoolean(JabRefPreferences.BACKUP), + SavePreferences.DatabaseSaveType.ALL, + true, + this.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT), + this.getLatexFieldFormatterPreferences(), + this.getKeyPattern(), + getBoolean(JabRefPreferences.GENERATE_KEYS_BEFORE_SAVING), + getBibtexKeyPatternPreferences()); } public ExporterFactory getExporterFactory(JournalAbbreviationLoader abbreviationLoader) { @@ -1541,14 +1542,14 @@ public XmpPreferences getXMPPreferences() { @Override public OpenOfficePreferences getOpenOfficePreferences() { return new OpenOfficePreferences( - this.get(JabRefPreferences.OO_JARS_PATH), - this.get(JabRefPreferences.OO_EXECUTABLE_PATH), - this.get(JabRefPreferences.OO_PATH), - this.getBoolean(JabRefPreferences.OO_USE_ALL_OPEN_BASES), - this.getBoolean(JabRefPreferences.OO_SYNC_WHEN_CITING), - this.getBoolean(JabRefPreferences.OO_SHOW_PANEL), - this.getStringList(JabRefPreferences.OO_EXTERNAL_STYLE_FILES), - this.get(JabRefPreferences.OO_BIBLIOGRAPHY_STYLE_FILE)); + this.get(JabRefPreferences.OO_JARS_PATH), + this.get(JabRefPreferences.OO_EXECUTABLE_PATH), + this.get(JabRefPreferences.OO_PATH), + this.getBoolean(JabRefPreferences.OO_USE_ALL_OPEN_BASES), + this.getBoolean(JabRefPreferences.OO_SYNC_WHEN_CITING), + this.getBoolean(JabRefPreferences.OO_SHOW_PANEL), + this.getStringList(JabRefPreferences.OO_EXTERNAL_STYLE_FILES), + this.get(JabRefPreferences.OO_BIBLIOGRAPHY_STYLE_FILE)); } @Override @@ -1728,10 +1729,9 @@ private SaveOrderConfig loadTableSaveOrder() { @Override public SaveOrderConfig loadExportSaveOrder() { return new SaveOrderConfig(getBoolean(EXPORT_IN_ORIGINAL_ORDER), getBoolean(EXPORT_IN_SPECIFIED_ORDER), - new SaveOrderConfig.SortCriterion(get(EXPORT_PRIMARY_SORT_FIELD), getBoolean(EXPORT_PRIMARY_SORT_DESCENDING)), - new SaveOrderConfig.SortCriterion(get(EXPORT_SECONDARY_SORT_FIELD), getBoolean(EXPORT_SECONDARY_SORT_DESCENDING)), - new SaveOrderConfig.SortCriterion(get(EXPORT_TERTIARY_SORT_FIELD), getBoolean(EXPORT_TERTIARY_SORT_DESCENDING)) - ); + new SaveOrderConfig.SortCriterion(get(EXPORT_PRIMARY_SORT_FIELD), getBoolean(EXPORT_PRIMARY_SORT_DESCENDING)), + new SaveOrderConfig.SortCriterion(get(EXPORT_SECONDARY_SORT_FIELD), getBoolean(EXPORT_SECONDARY_SORT_DESCENDING)), + new SaveOrderConfig.SortCriterion(get(EXPORT_TERTIARY_SORT_FIELD), getBoolean(EXPORT_TERTIARY_SORT_DESCENDING))); } @Override @@ -2008,7 +2008,7 @@ public List getCustomExportFormats(JournalAbbreviationLoader l filename = formatData.get(EXPORTER_FILENAME_INDEX); extension = formatData.get(EXPORTER_EXTENSION_INDEX); TemplateExporter format = new TemplateExporter(exporterName, filename, extension, - layoutPreferences, savePreferences); + layoutPreferences, savePreferences); format.setCustomExport(true); formats.add(format); i++; @@ -2060,4 +2060,19 @@ public boolean shouldWarnAboutDuplicatesForImport() { public void setShouldWarnAboutDuplicatesForImport(boolean value) { putBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION, value); } + + @Override + public void saveCustomEntryTypes() { + saveCustomEntryTypes(BibDatabaseMode.BIBTEX); + saveCustomEntryTypes(BibDatabaseMode.BIBLATEX); + } + + private void saveCustomEntryTypes(BibDatabaseMode bibDatabaseMode) { + List customBiblatexBibTexTypes = EntryTypes.getAllValues(bibDatabaseMode).stream() + .filter(type -> type instanceof CustomEntryType) + .map(entryType -> (CustomEntryType) entryType).collect(Collectors.toList()); + + storeCustomEntryTypes(customBiblatexBibTexTypes, bibDatabaseMode); + + } } diff --git a/src/main/java/org/jabref/preferences/PreferencesService.java b/src/main/java/org/jabref/preferences/PreferencesService.java index fea7e8d52b7..4947c9da8bc 100644 --- a/src/main/java/org/jabref/preferences/PreferencesService.java +++ b/src/main/java/org/jabref/preferences/PreferencesService.java @@ -87,4 +87,6 @@ public interface PreferencesService { boolean shouldWarnAboutDuplicatesForImport(); void setShouldWarnAboutDuplicatesForImport(boolean value); + + void saveCustomEntryTypes(); } From aab77a1091874a21d38c15b62c8f7469edaf3c4a Mon Sep 17 00:00:00 2001 From: znuznu <37243770+znuznu@users.noreply.github.com> Date: Wed, 24 Apr 2019 21:09:48 +0200 Subject: [PATCH 16/16] Fix for the issue #4912 (#4916) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix for the issue #4912 Apostrophe character removed from KEY_ILLEGAL_CHARACTERS in BibtexKeyGenerator * Add special character to KEY_ILLEGAL_CHARACTERS ʹ added to KEY_ILLEGAL_CHARACTERS and an assertion has been added in testMakeLabelAndCheckLegalKeysAccentGrave --- .../jabref/logic/bibtexkeypattern/BibtexKeyGenerator.java | 2 +- .../logic/bibtexkeypattern/BibtexKeyGeneratorTest.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGenerator.java b/src/main/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGenerator.java index 6309b297168..02a2fce80ac 100644 --- a/src/main/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGenerator.java +++ b/src/main/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGenerator.java @@ -26,7 +26,7 @@ public class BibtexKeyGenerator extends BracketedPattern { */ public static final String APPENDIX_CHARACTERS = "abcdefghijklmnopqrstuvwxyz"; private static final Logger LOGGER = LoggerFactory.getLogger(BibtexKeyGenerator.class); - private static final String KEY_ILLEGAL_CHARACTERS = "{}(),\\\"-#~^':`"; + private static final String KEY_ILLEGAL_CHARACTERS = "{}(),\\\"-#~^:'`ʹ"; private static final String KEY_UNWANTED_CHARACTERS = "{}(),\\\"-"; private final AbstractBibtexKeyPattern citeKeyPattern; private final BibDatabase database; diff --git a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGeneratorTest.java b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGeneratorTest.java index ad6e2d86e1c..f93a07ee22e 100644 --- a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGeneratorTest.java +++ b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGeneratorTest.java @@ -236,6 +236,12 @@ public void testMakeLabelAndCheckLegalKeysAccentGrave() throws ParseException { assertEquals("DAl", BibtexKeyGenerator.cleanKey(BibtexKeyGenerator.generateKey(entry0.get(), "auth3", new BibDatabase()), true)); + + entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andrés Aʹrnold}, year={2000}}", + importFormatPreferences, fileMonitor); + assertEquals("Arn", + BibtexKeyGenerator.cleanKey(BibtexKeyGenerator.generateKey(entry0.get(), "auth3", + new BibDatabase()), true)); } /**