diff --git a/CHANGELOG.md b/CHANGELOG.md
index 560b2236e0a..be3982fb06c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -52,7 +52,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We added the ability to add field names from the Preferences Dialog [#4546](https://github.com/JabRef/jabref/issues/4546)
- We added the ability change the column widths directly in the main table. [#4546](https://github.com/JabRef/jabref/issues/4546)
- We added the ability to execute default action in dialog by using with Ctrl + Enter combination [#4496](https://github.com/JabRef/jabref/issues/4496)
-
+- We grouped and reordered the Main Menu (File, Edit, Library, Quality, Tools, and View tabs & icons). [#4666](https://github.com/JabRef/jabref/issues/4666) [#4667](https://github.com/JabRef/jabref/issues/4667) [#4668](https://github.com/JabRef/jabref/issues/4668) [#4669](https://github.com/JabRef/jabref/issues/4669) [#4670](https://github.com/JabRef/jabref/issues/4670) [#4671](https://github.com/JabRef/jabref/issues/4671) [#4672](https://github.com/JabRef/jabref/issues/4672) [#4673](https://github.com/JabRef/jabref/issues/4673)
+- We added additional modifiers (capitalize, titlecase and sentencecase) to the Bibtex key generator. [#1506](https://github.com/JabRef/jabref/issues/1506)
diff --git a/build.gradle b/build.gradle
index ea5d8e813b2..d08efe7b1a2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -167,7 +167,7 @@ dependencies {
testRuntime 'org.apache.logging.log4j:log4j-core:2.11.1'
testRuntime 'org.apache.logging.log4j:log4j-jul:2.11.2'
- testCompile 'org.mockito:mockito-core:2.24.5'
+ testCompile 'org.mockito:mockito-core:2.25.0'
testCompile 'com.github.tomakehurst:wiremock:2.21.0'
testCompile 'org.assertj:assertj-swing-junit:3.9.2'
testCompile 'org.reflections:reflections:0.9.11'
diff --git a/src/main/java/org/jabref/gui/Base.css b/src/main/java/org/jabref/gui/Base.css
index ab4097899cc..e9c36458ba8 100644
--- a/src/main/java/org/jabref/gui/Base.css
+++ b/src/main/java/org/jabref/gui/Base.css
@@ -818,8 +818,8 @@
.separator:horizontal .line {
-fx-border-color: -jr-separator;
- -fx-border-width: 0;
- -fx-border-insets: 1 0 0 0;
+ -fx-border-width: 0.3;
+ -fx-border-insets: 1 15 0 20;
}
.separator:vertical .line {
diff --git a/src/main/java/org/jabref/gui/DefaultInjector.java b/src/main/java/org/jabref/gui/DefaultInjector.java
index e94e6fe8697..4f18a03b9e6 100644
--- a/src/main/java/org/jabref/gui/DefaultInjector.java
+++ b/src/main/java/org/jabref/gui/DefaultInjector.java
@@ -6,6 +6,7 @@
import org.jabref.gui.keyboard.KeyBindingRepository;
import org.jabref.gui.util.TaskExecutor;
import org.jabref.logic.journals.JournalAbbreviationLoader;
+import org.jabref.logic.protectedterms.ProtectedTermsLoader;
import org.jabref.model.util.FileUpdateMonitor;
import org.jabref.preferences.PreferencesService;
@@ -38,6 +39,8 @@ private static Object createDependency(Class> clazz) {
return Globals.stateManager;
} else if (clazz == FileUpdateMonitor.class) {
return Globals.getFileUpdateMonitor();
+ } else if (clazz == ProtectedTermsLoader.class) {
+ return Globals.protectedTermsLoader;
} else if (clazz == ClipBoardManager.class) {
return Globals.clipboardManager;
} else {
diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java
index 8346fe58e7f..2e41bbc7e64 100644
--- a/src/main/java/org/jabref/gui/JabRefFrame.java
+++ b/src/main/java/org/jabref/gui/JabRefFrame.java
@@ -58,7 +58,6 @@
import org.jabref.gui.actions.BibtexKeyPatternAction;
import org.jabref.gui.actions.ConnectToSharedDatabaseCommand;
import org.jabref.gui.actions.CopyFilesAction;
-import org.jabref.gui.actions.CustomizeEntryAction;
import org.jabref.gui.actions.CustomizeKeyBindingAction;
import org.jabref.gui.actions.DatabasePropertiesAction;
import org.jabref.gui.actions.EditExternalFileTypesAction;
@@ -68,8 +67,6 @@
import org.jabref.gui.actions.ManageCustomExportsAction;
import org.jabref.gui.actions.ManageCustomImportsAction;
import org.jabref.gui.actions.ManageJournalsAction;
-import org.jabref.gui.actions.ManageKeywordsAction;
-import org.jabref.gui.actions.ManageProtectedTermsAction;
import org.jabref.gui.actions.NewDatabaseAction;
import org.jabref.gui.actions.NewEntryAction;
import org.jabref.gui.actions.NewEntryFromPlainTextAction;
@@ -83,6 +80,7 @@
import org.jabref.gui.actions.SimpleCommand;
import org.jabref.gui.actions.StandardActions;
import org.jabref.gui.dialogs.AutosaveUIManager;
+import org.jabref.gui.edit.ManageKeywordsAction;
import org.jabref.gui.edit.MassSetFieldsAction;
import org.jabref.gui.exporter.ExportCommand;
import org.jabref.gui.exporter.ExportToClipboardAction;
@@ -101,6 +99,7 @@
import org.jabref.gui.mergeentries.MergeEntriesAction;
import org.jabref.gui.metadata.BibtexStringEditorAction;
import org.jabref.gui.metadata.PreambleEditor;
+import org.jabref.gui.protectedterms.ManageProtectedTermsAction;
import org.jabref.gui.push.PushToApplicationButton;
import org.jabref.gui.push.PushToApplications;
import org.jabref.gui.search.GlobalSearchBar;
@@ -126,7 +125,6 @@
import org.jabref.model.database.shared.DatabaseLocation;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.BiblatexEntryTypes;
-import org.jabref.model.entry.BibtexEntryTypes;
import org.jabref.model.entry.FieldName;
import org.jabref.model.entry.specialfields.SpecialField;
import org.jabref.preferences.JabRefPreferences;
@@ -735,35 +733,35 @@ private MenuBar createMenu() {
Menu help = new Menu(Localization.lang("Help"));
file.getItems().addAll(
- factory.createMenuItem(StandardActions.NEW_LIBRARY_BIBTEX, new NewDatabaseAction(this, BibDatabaseMode.BIBTEX)),
- factory.createMenuItem(StandardActions.NEW_LIBRARY_BIBLATEX, new NewDatabaseAction(this, BibDatabaseMode.BIBLATEX)),
+ factory.createSubMenu(StandardActions.NEW_LIBRARY,
+ factory.createMenuItem(StandardActions.NEW_LIBRARY_BIBTEX, new NewDatabaseAction(this, BibDatabaseMode.BIBTEX)),
+ factory.createMenuItem(StandardActions.NEW_LIBRARY_BIBLATEX, new NewDatabaseAction(this, BibDatabaseMode.BIBLATEX))),
+
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_ALL, new SaveAllAction(this)),
- factory.createSubMenu(StandardActions.IMPORT_EXPORT,
+ 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.IMPORT_INTO_CURRENT_LIBRARY, new ImportCommand(this, false)),
- factory.createMenuItem(StandardActions.IMPORT_INTO_NEW_LIBRARY, new ImportCommand(this, true)),
+ 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))),
- new SeparatorMenuItem(),
-
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)),
new SeparatorMenuItem(),
- fileHistory,
-
- new SeparatorMenuItem(),
-
factory.createMenuItem(StandardActions.CLOSE_LIBRARY, new CloseDatabaseAction()),
factory.createMenuItem(StandardActions.QUIT, new CloseAction())
-
);
edit.getItems().addAll(
@@ -788,10 +786,7 @@ private MenuBar createMenu() {
new SeparatorMenuItem(),
- factory.createMenuItem(StandardActions.SEND_AS_EMAIL, new OldDatabaseCommandWrapper(Actions.SEND_AS_EMAIL, this, Globals.stateManager)),
-
- new SeparatorMenuItem()
-
+ factory.createMenuItem(StandardActions.MANAGE_KEYWORDS, new ManageKeywordsAction(this))
);
if (Globals.prefs.getBoolean(JabRefPreferences.SPECIALFIELDSENABLED)) {
@@ -831,28 +826,17 @@ private MenuBar createMenu() {
}
}
- edit.getItems().addAll(
- factory.createMenuItem(StandardActions.MANAGE_KEYWORDS, new ManageKeywordsAction(this)),
- factory.createMenuItem(StandardActions.REPLACE_ALL, new OldDatabaseCommandWrapper(Actions.REPLACE_ALL, this, Globals.stateManager)),
- factory.createMenuItem(StandardActions.MASS_SET_FIELDS, new MassSetFieldsAction(this))
-
- );
-
library.getItems().addAll(
- factory.createMenuItem(StandardActions.NEW_ARTICLE, new NewEntryAction(this, BibtexEntryTypes.ARTICLE, dialogService, Globals.prefs)),
factory.createMenuItem(StandardActions.NEW_ENTRY, new NewEntryAction(this, dialogService, Globals.prefs)),
factory.createMenuItem(StandardActions.NEW_ENTRY_FROM_PLAINTEX, new NewEntryFromPlainTextAction(this, Globals.prefs.getUpdateFieldPreferences(), dialogService, Globals.prefs)),
-
- new SeparatorMenuItem(),
-
factory.createMenuItem(StandardActions.DELETE_ENTRY, new OldDatabaseCommandWrapper(Actions.DELETE, this, Globals.stateManager)),
new SeparatorMenuItem(),
factory.createMenuItem(StandardActions.LIBRARY_PROPERTIES, new DatabasePropertiesAction(this)),
factory.createMenuItem(StandardActions.EDIT_PREAMBLE, new PreambleEditor(this)),
- factory.createMenuItem(StandardActions.EDIT_STRINGS, new BibtexStringEditorAction(this))
-
+ factory.createMenuItem(StandardActions.EDIT_STRINGS, new BibtexStringEditorAction(this)),
+ factory.createMenuItem(StandardActions.MASS_SET_FIELDS, new MassSetFieldsAction(this))
);
Menu lookupIdentifiers = factory.createSubMenu(StandardActions.LOOKUP_DOC_IDENTIFIER);
@@ -865,67 +849,66 @@ private MenuBar createMenu() {
quality.getItems().addAll(
factory.createMenuItem(StandardActions.FIND_DUPLICATES, new DuplicateSearch(this, dialogService)),
factory.createMenuItem(StandardActions.MERGE_ENTRIES, new MergeEntriesAction(this)),
-
- new SeparatorMenuItem(),
-
factory.createMenuItem(StandardActions.CHECK_INTEGRITY, new IntegrityCheckAction(this)),
factory.createMenuItem(StandardActions.CLEANUP_ENTRIES, new OldDatabaseCommandWrapper(Actions.CLEANUP, this, Globals.stateManager)),
- factory.createMenuItem(StandardActions.GENERATE_CITE_KEYS, new OldDatabaseCommandWrapper(Actions.MAKE_KEY, this, Globals.stateManager)),
-
- new SeparatorMenuItem(),
-
- factory.createMenuItem(StandardActions.SET_FILE_LINKS, new AutoLinkFilesAction()),
- factory.createMenuItem(StandardActions.FIND_UNLINKED_FILES, new FindUnlinkedFilesAction(this)),
- lookupIdentifiers,
- factory.createMenuItem(StandardActions.DOWNLOAD_FULL_TEXT, new OldDatabaseCommandWrapper(Actions.DOWNLOAD_FULL_TEXT, this, Globals.stateManager))
- );
-
- SidePaneComponent webSearch = sidePaneManager.getComponent(SidePaneType.WEB_SEARCH);
- SidePaneComponent groups = sidePaneManager.getComponent(SidePaneType.GROUPS);
- SidePaneComponent openOffice = sidePaneManager.getComponent(SidePaneType.OPEN_OFFICE);
-
- view.getItems().addAll(
- factory.createMenuItem(webSearch.getToggleAction(), webSearch.getToggleCommand()),
- factory.createMenuItem(groups.getToggleAction(), groups.getToggleCommand()),
- factory.createMenuItem(StandardActions.TOGGLE_PREVIEW, new OldDatabaseCommandWrapper(Actions.TOGGLE_PREVIEW, this, Globals.stateManager)),
- factory.createMenuItem(StandardActions.EDIT_ENTRY, new OldDatabaseCommandWrapper(Actions.EDIT, this, Globals.stateManager)),
- factory.createMenuItem(StandardActions.SHOW_PDV_VIEWER, new ShowDocumentViewerAction()),
new SeparatorMenuItem(),
- factory.createMenuItem(StandardActions.SELECT_ALL, new OldDatabaseCommandWrapper(Actions.SELECT_ALL, this, Globals.stateManager)),
-
- new SeparatorMenuItem(),
-
- 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.createMenuItem(StandardActions.SET_FILE_LINKS, new AutoLinkFilesAction())
);
PushToApplicationButton pushToExternal = new PushToApplicationButton(this, pushApplications.getApplications());
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)),
new SeparatorMenuItem(),
- factory.createMenuItem(openOffice.getToggleAction(), openOffice.getToggleCommand()),
- factory.createMenuItem(pushToExternal.getMenuAction(), pushToExternal),
+ lookupIdentifiers,
+ factory.createMenuItem(StandardActions.DOWNLOAD_FULL_TEXT, new OldDatabaseCommandWrapper(Actions.DOWNLOAD_FULL_TEXT, this, Globals.stateManager)),
new SeparatorMenuItem(),
- factory.createMenuItem(StandardActions.OPEN_FOLDER, new OldDatabaseCommandWrapper(Actions.OPEN_FOLDER, this, Globals.stateManager)),
- factory.createMenuItem(StandardActions.OPEN_FILE, new OldDatabaseCommandWrapper(Actions.OPEN_EXTERNAL_FILE, this, Globals.stateManager)),
- factory.createMenuItem(StandardActions.OPEN_URL, new OldDatabaseCommandWrapper(Actions.OPEN_URL, this, Globals.stateManager)),
- factory.createMenuItem(StandardActions.OPEN_CONSOLE, new OldDatabaseCommandWrapper(Actions.OPEN_CONSOLE, this, Globals.stateManager)),
- factory.createMenuItem(StandardActions.COPY_LINKED_FILES, new CopyFilesAction(this)),
+ 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(pushToExternal.getMenuAction(), pushToExternal),
- new SeparatorMenuItem(),
+ 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, Globals.stateManager)),
- factory.createMenuItem(StandardActions.ABBREVIATE_MEDLINE, new OldDatabaseCommandWrapper(Actions.ABBREVIATE_MEDLINE, this, Globals.stateManager)),
factory.createMenuItem(StandardActions.UNABBREVIATE, new OldDatabaseCommandWrapper(Actions.UNABBREVIATE, this, Globals.stateManager))
);
+ SidePaneComponent webSearch = sidePaneManager.getComponent(SidePaneType.WEB_SEARCH);
+ SidePaneComponent groups = sidePaneManager.getComponent(SidePaneType.GROUPS);
+ SidePaneComponent openOffice = sidePaneManager.getComponent(SidePaneType.OPEN_OFFICE);
+
+ view.getItems().add(new SeparatorMenuItem());
+ view.setOnShowing(event -> {
+ view.getItems().clear();
+ view.getItems().addAll(
+ factory.createCheckMenuItem(webSearch.getToggleAction(), webSearch.getToggleCommand(), sidePaneManager.isComponentVisible(SidePaneType.WEB_SEARCH)),
+ factory.createCheckMenuItem(groups.getToggleAction(), groups.getToggleCommand(), sidePaneManager.isComponentVisible(SidePaneType.GROUPS)),
+ factory.createCheckMenuItem(openOffice.getToggleAction(), openOffice.getToggleCommand(), sidePaneManager.isComponentVisible(SidePaneType.OPEN_OFFICE)),
+
+ 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)),
+
+ 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))
+ );
+ });
+
options.getItems().addAll(
factory.createMenuItem(StandardActions.SHOW_PREFS, new ShowPreferencesAction(this, Globals.TASK_EXECUTOR)),
@@ -937,13 +920,15 @@ private MenuBar createMenu() {
factory.createMenuItem(StandardActions.MANAGE_EXTERNAL_FILETYPES, new EditExternalFileTypesAction()),
factory.createMenuItem(StandardActions.MANAGE_JOURNALS, new ManageJournalsAction()),
factory.createMenuItem(StandardActions.CUSTOMIZE_KEYBINDING, new CustomizeKeyBindingAction()),
- factory.createMenuItem(StandardActions.MANAGE_PROTECTED_TERMS, new ManageProtectedTermsAction(this, Globals.protectedTermsLoader)),
+ factory.createMenuItem(StandardActions.MANAGE_PROTECTED_TERMS, new ManageProtectedTermsAction()),
new SeparatorMenuItem(),
factory.createMenuItem(StandardActions.MANAGE_CONTENT_SELECTORS, new ManageContentSelectorAction(this)),
- factory.createMenuItem(StandardActions.CUSTOMIZE_ENTRY_TYPES, new CustomizeEntryAction(this)),
- factory.createMenuItem(StandardActions.MANAGE_CITE_KEY_PATTERNS, new BibtexKeyPatternAction(this)));
+ // TODO: Reenable customize entry types feature (https://github.com/JabRef/jabref/issues/4719)
+ //factory.createMenuItem(StandardActions.CUSTOMIZE_ENTRY_TYPES, new CustomizeEntryAction(this)),
+ factory.createMenuItem(StandardActions.MANAGE_CITE_KEY_PATTERNS, new BibtexKeyPatternAction(this))
+ );
help.getItems().addAll(
factory.createMenuItem(StandardActions.HELP, HelpAction.getMainHelpPageCommand()),
@@ -975,6 +960,7 @@ private MenuBar createMenu() {
),
factory.createMenuItem(StandardActions.ABOUT, new AboutAction())
);
+
//@formatter:on
MenuBar menu = new MenuBar();
menu.getStyleClass().add("mainMenu");
diff --git a/src/main/java/org/jabref/gui/WrapLayout.java b/src/main/java/org/jabref/gui/WrapLayout.java
deleted file mode 100644
index 999c7abd3f0..00000000000
--- a/src/main/java/org/jabref/gui/WrapLayout.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.jabref.gui;
-
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.Insets;
-
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
-/**
- * FlowLayout subclass that fully supports wrapping of components.
- */
-public class WrapLayout extends FlowLayout {
- /**
- * Constructs a new WrapLayout
with a left
- * alignment and a default 5-unit horizontal and vertical gap.
- */
- public WrapLayout() {
- super();
- }
-
- /**
- * Constructs a new FlowLayout
with the specified
- * alignment and a default 5-unit horizontal and vertical gap.
- * The value of the alignment argument must be one of
- * WrapLayout
, WrapLayout
,
- * or WrapLayout
.
- * @param align the alignment value
- */
- public WrapLayout(int align) {
- super(align);
- }
-
- /**
- * Creates a new flow layout manager with the indicated alignment
- * and the indicated horizontal and vertical gaps.
- *
- * The value of the alignment argument must be one of
- * WrapLayout
, WrapLayout
,
- * or WrapLayout
.
- * @param align the alignment value
- * @param hgap the horizontal gap between components
- * @param vgap the vertical gap between components
- */
- public WrapLayout(int align, int hgap, int vgap) {
- super(align, hgap, vgap);
- }
-
- /**
- * Returns the preferred dimensions for this layout given the
- * visible components in the specified target container.
- * @param target the component which needs to be laid out
- * @return the preferred dimensions to lay out the
- * subcomponents of the specified container
- */
- @Override
- public Dimension preferredLayoutSize(Container target) {
- return layoutSize(target, true);
- }
-
- /**
- * Returns the minimum dimensions needed to layout the visible
- * components contained in the specified target container.
- * @param target the component which needs to be laid out
- * @return the minimum dimensions to lay out the
- * subcomponents of the specified container
- */
- @Override
- public Dimension minimumLayoutSize(Container target) {
- Dimension minimum = layoutSize(target, false);
- minimum.width -= (getHgap() + 1);
- return minimum;
- }
-
- /**
- * Returns the minimum or preferred dimension needed to layout the target
- * container.
- *
- * @param target target to get layout size for
- * @param preferred should preferred size be calculated
- * @return the dimension to layout the target container
- */
- private Dimension layoutSize(Container target, boolean preferred) {
- synchronized (target.getTreeLock()) {
- // Each row must fit with the width allocated to the container.
- // When the container width = 0, the preferred width of the container
- // has not yet been calculated so lets ask for the maximum.
-
- int targetWidth = target.getSize().width;
-
- if (targetWidth == 0) {
- targetWidth = Integer.MAX_VALUE;
- }
-
- int hgap = getHgap();
- int vgap = getVgap();
- Insets insets = target.getInsets();
- int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
- int maxWidth = targetWidth - horizontalInsetsAndGap;
-
- // Fit components into the allowed width
-
- Dimension dim = new Dimension(0, 0);
- int rowWidth = 0;
- int rowHeight = 0;
-
- int nmembers = target.getComponentCount();
-
- for (int i = 0; i < nmembers; i++) {
- Component m = target.getComponent(i);
-
- if (m.isVisible()) {
- Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
-
- if (d != null) {
- // Can't add the component to current row. Start a new row.
-
- if ((rowWidth + d.width) > maxWidth) {
- addRow(dim, rowWidth, rowHeight);
- rowWidth = 0;
- rowHeight = 0;
- }
-
- // Add a horizontal gap for all components after the first
-
- if (rowWidth != 0) {
- rowWidth += hgap;
- }
-
- rowWidth += d.width;
- rowHeight = Math.max(rowHeight, d.height);
- }
- }
- }
-
- addRow(dim, rowWidth, rowHeight);
-
- dim.width += horizontalInsetsAndGap;
- dim.height += insets.top + insets.bottom + (vgap * 2);
-
- // When using a scroll pane or the DecoratedLookAndFeel we need to
- // make sure the preferred size is less than the size of the
- // target container so shrinking the container size works
- // correctly. Removing the horizontal gap is an easy way to do this.
-
- Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
-
- if (scrollPane != null) {
- dim.width -= (hgap + 1);
- }
-
- return dim;
- }
- }
-
- /*
- * A new row has been completed. Use the dimensions of this row
- * to update the preferred size for the container.
- *
- * @param dim update the width and height when appropriate
- * @param rowWidth the width of the row to add
- * @param rowHeight the height of the row to add
- */
- private void addRow(Dimension dim, int rowWidth, int rowHeight) {
- dim.width = Math.max(dim.width, rowWidth);
-
- if (dim.height > 0) {
- dim.height += getVgap();
- }
-
- dim.height += rowHeight;
- }
-}
diff --git a/src/main/java/org/jabref/gui/actions/ActionFactory.java b/src/main/java/org/jabref/gui/actions/ActionFactory.java
index 51c77f1f8d2..69c5531db65 100644
--- a/src/main/java/org/jabref/gui/actions/ActionFactory.java
+++ b/src/main/java/org/jabref/gui/actions/ActionFactory.java
@@ -5,6 +5,7 @@
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBase;
+import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
@@ -43,6 +44,14 @@ public MenuItem createMenuItem(Action action, Command command) {
return menuItem;
}
+ public CheckMenuItem createCheckMenuItem(Action action, Command command, boolean selected) {
+ CheckMenuItem checkMenuItem = ActionUtils.createCheckMenuItem(new JabRefAction(action, command, keyBindingRepository));
+ checkMenuItem.setSelected(selected);
+ setGraphic(checkMenuItem, action);
+
+ return checkMenuItem;
+ }
+
public Menu createMenu(Action action) {
Menu menu = ActionUtils.createMenu(new JabRefAction(action, keyBindingRepository));
diff --git a/src/main/java/org/jabref/gui/actions/ManageKeywordsAction.java b/src/main/java/org/jabref/gui/actions/ManageKeywordsAction.java
deleted file mode 100644
index 0af7a02f91c..00000000000
--- a/src/main/java/org/jabref/gui/actions/ManageKeywordsAction.java
+++ /dev/null
@@ -1,356 +0,0 @@
-package org.jabref.gui.actions;
-
-import java.awt.BorderLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.ActionMap;
-import javax.swing.BorderFactory;
-import javax.swing.ButtonGroup;
-import javax.swing.DefaultListModel;
-import javax.swing.InputMap;
-import javax.swing.JButton;
-import javax.swing.JComponent;
-import javax.swing.JDialog;
-import javax.swing.JFrame;
-import javax.swing.JList;
-import javax.swing.JRadioButton;
-import javax.swing.JScrollPane;
-import javax.swing.JTextField;
-
-import org.jabref.Globals;
-import org.jabref.gui.BasePanel;
-import org.jabref.gui.JabRefFrame;
-import org.jabref.gui.keyboard.KeyBinding;
-import org.jabref.gui.undo.NamedCompound;
-import org.jabref.gui.undo.UndoableFieldChange;
-import org.jabref.logic.l10n.Localization;
-import org.jabref.logic.specialfields.SpecialFieldsUtils;
-import org.jabref.model.FieldChange;
-import org.jabref.model.entry.BibEntry;
-import org.jabref.model.entry.Keyword;
-import org.jabref.model.entry.KeywordList;
-import org.jabref.model.strings.StringUtil;
-
-import com.jgoodies.forms.builder.ButtonBarBuilder;
-import com.jgoodies.forms.builder.FormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-/**
- * An Action for launching keyword managing dialog
- *
- */
-public class ManageKeywordsAction extends SimpleCommand {
-
- private final JabRefFrame frame;
- private final KeywordList sortedKeywordsOfAllEntriesBeforeUpdateByUser = new KeywordList();
- private JDialog diag;
- private DefaultListModel keywordListModel;
- private JRadioButton intersectKeywords;
- private JRadioButton mergeKeywords;
- private boolean canceled;
-
-
- public ManageKeywordsAction(JabRefFrame frame) {
- this.frame = frame;
- }
-
- private void createDialog() {
- if (diag != null) {
- return;
- }
- // keyword to add
- JTextField keyword = new JTextField();
-
- keywordListModel = new DefaultListModel<>();
- JList keywordList = new JList<>(keywordListModel);
- keywordList.setVisibleRowCount(8);
- JScrollPane kPane = new JScrollPane(keywordList);
-
- diag = new JDialog((JFrame) null, Localization.lang("Manage keywords"), true);
-
- JButton ok = new JButton(Localization.lang("OK"));
- JButton cancel = new JButton(Localization.lang("Cancel"));
- JButton add = new JButton(Localization.lang("Add"));
- JButton remove = new JButton(Localization.lang("Remove"));
- JButton replace = new JButton(Localization.lang("Replace"));
- JButton join = new JButton(Localization.lang("Join"));
-
- join.setToolTipText(Localization.lang("Joins selected keywords and deletes selected keywords."));
-
- keywordList.setVisibleRowCount(10);
-
- intersectKeywords = new JRadioButton(Localization.lang("Display keywords appearing in ALL entries"));
- mergeKeywords = new JRadioButton(Localization.lang("Display keywords appearing in ANY entry"));
- ButtonGroup group = new ButtonGroup();
- group.add(intersectKeywords);
- group.add(mergeKeywords);
- ActionListener stateChanged = e -> fillKeyWordList();
- intersectKeywords.addActionListener(stateChanged);
- mergeKeywords.addActionListener(stateChanged);
- intersectKeywords.setSelected(true);
-
- FormBuilder builder = FormBuilder.create().layout(new FormLayout("fill:200dlu:grow, pref, fill:pref",
- "pref, 2dlu, pref, 1dlu, pref, 2dlu, fill:100dlu:grow, 4dlu, pref, 4dlu, pref, "));
-
- builder.addSeparator(Localization.lang("Keywords of selected entries")).xyw(1, 1, 3);
- builder.add(intersectKeywords).xyw(1, 3, 3);
- builder.add(mergeKeywords).xyw(1, 5, 3);
- builder.add(kPane).xywh(1, 7, 1, 3);
- builder.add(join).xy(2,9);
- builder.add(replace).xy(3, 9);
- builder.add(keyword).xy(1, 11);
- builder.add(add).xy(2, 11);
- builder.add(remove).xy(3, 11);
-
- ButtonBarBuilder bb = new ButtonBarBuilder();
- bb.addGlue();
- bb.addButton(ok);
- bb.addButton(cancel);
- bb.addGlue();
- builder.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
- bb.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-
- ok.addActionListener(e -> {
- canceled = false;
- diag.dispose();
- });
-
- Action cancelAction = new AbstractAction() {
- @Override
- public void actionPerformed(ActionEvent e) {
- canceled = true;
- diag.dispose();
- }
- };
- cancel.addActionListener(cancelAction);
-
- final ActionListener addActionListener = arg0 -> addButtonActionListener(keyword);
-
- add.addActionListener(addActionListener);
-
- final ActionListener removeActionListener = arg0 -> {
- // keywordList.getSelectedIndices(); does not work, therefore we operate on the values
- List values = keywordList.getSelectedValuesList();
-
- for (Keyword val : values) {
- keywordListModel.removeElement(val);
- }
- };
-
- remove.addActionListener(removeActionListener);
-
- final ActionListener joinActionListener = arg0 -> {
- List values = keywordList.getSelectedValuesList();
- String joinedKeyword = values.stream().map(currentKeyword -> currentKeyword.get()).collect(Collectors.joining(" "));
- this.addKeywordToKeywordListModel(joinedKeyword);
-
- for (Keyword val : values) {
- this.keywordListModel.removeElement(val);
- }
- };
-
- join.addActionListener(joinActionListener);
-
- final ActionListener replaceActionListener = arg0 -> {
- List values = keywordList.getSelectedValuesList();
-
- for (Keyword val : values) {
- keywordListModel.removeElement(val);
- }
- addButtonActionListener(keyword);
- };
-
- replace.addActionListener(replaceActionListener);
-
- //enable a user to press Delete to delete a keyword
- keywordList.addKeyListener(new KeyAdapter() {
-
- @Override
- public void keyPressed(KeyEvent arg0) {
- if (arg0.getKeyCode() == KeyEvent.VK_DELETE) {
- removeActionListener.actionPerformed(null);
- }
- }
- });
-
- //enable a user to press Enter to add a keyword
- keyword.addKeyListener(new KeyAdapter() {
-
- @Override
- public void keyPressed(KeyEvent e) {
- if (e.getKeyCode() == KeyEvent.VK_ENTER) {
- addActionListener.actionPerformed(null);
- }
- }
- });
-
- // Key bindings:
- ActionMap am = builder.getPanel().getActionMap();
- InputMap im = builder.getPanel().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
- im.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE), "close");
- am.put("close", cancelAction);
-
- diag.getContentPane().add(builder.getPanel(), BorderLayout.CENTER);
- diag.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH);
- }
-
- private void addButtonActionListener(JTextField keywordTextField) {
- if (StringUtil.isBlank(keywordTextField.getText())) {
- return; // nothing to add
- }
- addKeywordToKeywordListModel(keywordTextField.getText());
- keywordTextField.setText(null);
- keywordTextField.requestFocusInWindow();
-
- }
-
- /**
- * Adds given keyword to the keyword list model
- */
- private void addKeywordToKeywordListModel(String keyword) {
- String keywordToAdd = Objects.requireNonNull(keyword).trim();
- Keyword newKeyword = new Keyword(keywordToAdd);
- if (keywordListModel.isEmpty()) {
- keywordListModel.addElement(newKeyword);
- } else {
- int idx = 0;
- Keyword element = keywordListModel.getElementAt(idx);
- while ((idx < keywordListModel.size()) && (element.compareTo(newKeyword) < 0)) {
- idx++;
- }
- if (idx == keywordListModel.size()) {
- // list is empty or word is greater than last word in list
- keywordListModel.addElement(newKeyword);
- } else if (element.compareTo(newKeyword) == 0) {
- // nothing to do, word already in table
- } else {
- keywordListModel.add(idx, newKeyword);
- }
- }
- }
-
- @Override
- public void execute() {
- BasePanel bp = frame.getCurrentBasePanel();
- if (bp == null) {
- return;
- }
- if (bp.getSelectedEntries().isEmpty()) {
- bp.output(Localization.lang("Select at least one entry to manage keywords."));
- return;
- }
-
- // Lazy creation of the dialog:
- createDialog();
-
- canceled = true;
-
- fillKeyWordList();
-
- diag.pack();
- diag.setVisible(true);
- if (canceled) {
- return;
- }
-
- KeywordList keywordsToAdd = new KeywordList();
- KeywordList userSelectedKeywords = new KeywordList();
- // build keywordsToAdd and userSelectedKeywords in parallel
- for (Enumeration keywords = keywordListModel.elements(); keywords.hasMoreElements();) {
- Keyword keyword = keywords.nextElement();
- userSelectedKeywords.add(keyword);
- if (!sortedKeywordsOfAllEntriesBeforeUpdateByUser.contains(keyword)) {
- keywordsToAdd.add(keyword);
- }
- }
-
- KeywordList keywordsToRemove = new KeywordList();
- for (Keyword kword : sortedKeywordsOfAllEntriesBeforeUpdateByUser) {
- if (!userSelectedKeywords.contains(kword)) {
- keywordsToRemove.add(kword);
- }
- }
-
- if (keywordsToAdd.isEmpty() && keywordsToRemove.isEmpty()) {
- // nothing to be done if nothing is new and nothing is obsolete
- return;
- }
-
- if (Globals.prefs.isKeywordSyncEnabled() && !keywordsToAdd.isEmpty()) {
- SpecialFieldsUtils.synchronizeSpecialFields(keywordsToAdd, keywordsToRemove);
- }
-
- NamedCompound ce = updateKeywords(bp.getSelectedEntries(), keywordsToAdd, keywordsToRemove);
- bp.getUndoManager().addEdit(ce);
- bp.markBaseChanged();
- }
-
- private NamedCompound updateKeywords(List entries, KeywordList keywordsToAdd,
- KeywordList keywordsToRemove) {
- NamedCompound ce = new NamedCompound(Localization.lang("Update keywords"));
- for (BibEntry entry : entries) {
- KeywordList keywords = entry.getKeywords(Globals.prefs.getKeywordDelimiter());
-
- // update keywords
- keywords.removeAll(keywordsToRemove);
- keywords.addAll(keywordsToAdd);
-
- // put keywords back
- Optional change = entry.putKeywords(keywords, Globals.prefs.getKeywordDelimiter());
- if (change.isPresent()) {
- ce.addEdit(new UndoableFieldChange(change.get()));
- }
-
- if (Globals.prefs.isKeywordSyncEnabled()) {
- SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, Globals.prefs.getKeywordDelimiter());
- }
- }
- ce.end();
- return ce;
- }
-
- private void fillKeyWordList() {
- BasePanel bp = frame.getCurrentBasePanel();
- List entries = bp.getSelectedEntries();
-
- // fill dialog with values
- keywordListModel.clear();
- sortedKeywordsOfAllEntriesBeforeUpdateByUser.clear();
-
- if (mergeKeywords.isSelected()) {
- for (BibEntry entry : entries) {
- KeywordList separatedKeywords = entry.getKeywords(Globals.prefs.getKeywordDelimiter());
- sortedKeywordsOfAllEntriesBeforeUpdateByUser.addAll(separatedKeywords);
- }
- } else {
- assert intersectKeywords.isSelected();
-
- // all keywords from first entry have to be added
- BibEntry firstEntry = entries.get(0);
- KeywordList separatedKeywords = firstEntry.getKeywords(Globals.prefs.getKeywordDelimiter());
- sortedKeywordsOfAllEntriesBeforeUpdateByUser.addAll(separatedKeywords);
-
- // for the remaining entries, intersection has to be used
- // this approach ensures that one empty keyword list leads to an empty set of common keywords
- for (int i = 1; i < entries.size(); i++) {
- BibEntry entry = entries.get(i);
- separatedKeywords = entry.getKeywords(Globals.prefs.getKeywordDelimiter());
- sortedKeywordsOfAllEntriesBeforeUpdateByUser.retainAll(separatedKeywords);
- }
- }
- for (Keyword keyword : sortedKeywordsOfAllEntriesBeforeUpdateByUser) {
- keywordListModel.addElement(keyword);
- }
- }
-
-}
diff --git a/src/main/java/org/jabref/gui/actions/ManageProtectedTermsAction.java b/src/main/java/org/jabref/gui/actions/ManageProtectedTermsAction.java
deleted file mode 100644
index c4f05f955cf..00000000000
--- a/src/main/java/org/jabref/gui/actions/ManageProtectedTermsAction.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.jabref.gui.actions;
-
-import org.jabref.gui.JabRefFrame;
-import org.jabref.gui.protectedterms.ProtectedTermsDialog;
-import org.jabref.logic.protectedterms.ProtectedTermsLoader;
-
-public class ManageProtectedTermsAction extends SimpleCommand {
-
- private final JabRefFrame jabRefFrame;
- private final ProtectedTermsLoader termsLoader;
-
- public ManageProtectedTermsAction(JabRefFrame jabRefFrame, ProtectedTermsLoader termsLoader) {
- this.jabRefFrame = jabRefFrame;
- this.termsLoader = termsLoader;
- }
- @Override
- public void execute() {
- ProtectedTermsDialog protectTermsDialog = new ProtectedTermsDialog(jabRefFrame);
- protectTermsDialog.setVisible(true);
-
- }
-
-}
diff --git a/src/main/java/org/jabref/gui/actions/StandardActions.java b/src/main/java/org/jabref/gui/actions/StandardActions.java
index 69321ed5766..b3b10e3aeaa 100644
--- a/src/main/java/org/jabref/gui/actions/StandardActions.java
+++ b/src/main/java/org/jabref/gui/actions/StandardActions.java
@@ -60,10 +60,12 @@ public enum StandardActions implements Action {
SKIMMED(Localization.lang("Set read status to skimmed"), IconTheme.JabRefIcons.READ_STATUS_SKIMMED),
RELEVANCE(Localization.lang("Relevance"), IconTheme.JabRefIcons.RELEVANCE),
RELEVANT(Localization.lang("Toggle relevance"), IconTheme.JabRefIcons.RELEVANCE),
- NEW_LIBRARY_BIBTEX(Localization.lang("New %0 library", BibDatabaseMode.BIBTEX.getFormattedName()), IconTheme.JabRefIcons.NEW),
- NEW_LIBRARY_BIBLATEX(Localization.lang("New %0 library", BibDatabaseMode.BIBLATEX.getFormattedName()), IconTheme.JabRefIcons.NEW),
+ NEW_LIBRARY(Localization.lang("New library"), IconTheme.JabRefIcons.NEW),
+ NEW_LIBRARY_BIBTEX(Localization.lang("New %0 library", BibDatabaseMode.BIBTEX.getFormattedName())),
+ NEW_LIBRARY_BIBLATEX(Localization.lang("New %0 library", BibDatabaseMode.BIBLATEX.getFormattedName())),
OPEN_LIBRARY(Localization.lang("Open library"), IconTheme.JabRefIcons.OPEN, KeyBinding.OPEN_DATABASE),
- IMPORT_EXPORT(Localization.lang("Import & Export"), IconTheme.JabRefIcons.IMPORT_EXPORT),
+ IMPORT(Localization.lang("Import"), IconTheme.JabRefIcons.IMPORT),
+ EXPORT(Localization.lang("Export"), IconTheme.JabRefIcons.EXPORT),
MERGE_DATABASE(Localization.lang("Append library"), Localization.lang("Append contents from a BibTeX library into the currently viewed library")),
SAVE_LIBRARY(Localization.lang("Save library"), IconTheme.JabRefIcons.SAVE, KeyBinding.SAVE_DATABASE),
SAVE_LIBRARY_AS(Localization.lang("Save library as..."), KeyBinding.SAVE_DATABASE_AS),
@@ -71,19 +73,19 @@ public enum StandardActions implements Action {
SAVE_ALL(Localization.lang("Save all"), Localization.lang("Save all open libraries"), IconTheme.JabRefIcons.SAVE_ALL, KeyBinding.SAVE_ALL),
IMPORT_INTO_NEW_LIBRARY(Localization.lang("Import into new library"), KeyBinding.IMPORT_INTO_NEW_DATABASE),
IMPORT_INTO_CURRENT_LIBRARY(Localization.lang("Import into current library"), KeyBinding.IMPORT_INTO_CURRENT_DATABASE),
- EXPORT_ALL(Localization.lang("Export")),
+ EXPORT_ALL(Localization.lang("Export all entries")),
EXPORT_SELECTED(Localization.lang("Export selected entries")),
- CONNECT_TO_SHARED_DB(Localization.lang("Connect to shared database")),
- PULL_CHANGES_FROM_SHARED_DB(Localization.lang("Pull changes from shared database"), IconTheme.JabRefIcons.PULL, KeyBinding.PULL_CHANGES_FROM_SHARED_DATABASE),
+ CONNECT_TO_SHARED_DB(Localization.lang("Connect to shared database"), IconTheme.JabRefIcons.CONNECT_DB),
+ PULL_CHANGES_FROM_SHARED_DB(Localization.lang("Pull changes from shared database"), KeyBinding.PULL_CHANGES_FROM_SHARED_DATABASE),
CLOSE_LIBRARY(Localization.lang("Close library"), Localization.lang("Close the current library"), IconTheme.JabRefIcons.CLOSE, KeyBinding.CLOSE_DATABASE),
QUIT(Localization.lang("Quit"), Localization.lang("Quit JabRef"), IconTheme.JabRefIcons.CLOSE_JABREF, KeyBinding.QUIT_JABREF),
UNDO(Localization.lang("Undo"), IconTheme.JabRefIcons.UNDO, KeyBinding.UNDO),
REDO(Localization.lang("Redo"), IconTheme.JabRefIcons.REDO, KeyBinding.REDO),
- REPLACE_ALL(Localization.lang("Replace string"), KeyBinding.REPLACE_STRING),
+ REPLACE_ALL(Localization.lang("Find and replace"), KeyBinding.REPLACE_STRING),
MANAGE_KEYWORDS(Localization.lang("Manage keywords")),
- MASS_SET_FIELDS(Localization.lang("Set/clear/append/rename fields")),
- TOGGLE_GROUPS(Localization.lang("Toggle groups interface"), IconTheme.JabRefIcons.TOGGLE_GROUPS, KeyBinding.TOGGLE_GROUPS_INTERFACE),
- TOOGLE_OO(Localization.lang("OpenOffice/LibreOffice connection"), IconTheme.JabRefIcons.FILE_OPENOFFICE, KeyBinding.OPEN_OPEN_OFFICE_LIBRE_OFFICE_CONNECTION),
+ MASS_SET_FIELDS(Localization.lang("Manage field names & content")),
+ TOGGLE_GROUPS(Localization.lang("Groups interface"), IconTheme.JabRefIcons.TOGGLE_GROUPS, KeyBinding.TOGGLE_GROUPS_INTERFACE),
+ TOOGLE_OO(Localization.lang("OpenOffice/LibreOffice"), IconTheme.JabRefIcons.FILE_OPENOFFICE, KeyBinding.OPEN_OPEN_OFFICE_LIBRE_OFFICE_CONNECTION),
TOGGLE_WEB_SEARCH(Localization.lang("Web search"), Localization.lang("Toggle web search interface"), IconTheme.JabRefIcons.WWW, KeyBinding.WEB_SEARCH),
NEW_SUB_LIBRARY_FROM_AUX(Localization.lang("New sublibrary based on AUX file") + "...", Localization.lang("New BibTeX sublibrary") + Localization.lang("This feature generates a new library based on which entries are needed in an existing LaTeX document."), IconTheme.JabRefIcons.NEW),
@@ -92,8 +94,9 @@ public enum StandardActions implements Action {
OPEN_FILE(Localization.lang("Open file"), Localization.lang("Open file"), IconTheme.JabRefIcons.FILE, KeyBinding.OPEN_FILE),
OPEN_CONSOLE(Localization.lang("Open terminal here"), Localization.lang("Open terminal here"), IconTheme.JabRefIcons.CONSOLE, KeyBinding.OPEN_CONSOLE),
COPY_LINKED_FILES(Localization.lang("Copy linked files to folder...")),
- ABBREVIATE_ISO(Localization.lang("Abbreviate journal names (ISO)"), Localization.lang("Abbreviate journal names of the selected entries (ISO abbreviation)"), KeyBinding.ABBREVIATE),
- ABBREVIATE_MEDLINE(Localization.lang("Abbreviate journal names (MEDLINE)"), Localization.lang("Abbreviate journal names of the selected entries (MEDLINE abbreviation)")),
+ ABBREVIATE(Localization.lang("Abbreviate journal names")),
+ ABBREVIATE_ISO("ISO", Localization.lang("Abbreviate journal names of the selected entries (ISO abbreviation)"), KeyBinding.ABBREVIATE),
+ ABBREVIATE_MEDLINE("MEDLINE", Localization.lang("Abbreviate journal names of the selected entries (MEDLINE abbreviation)")),
UNABBREVIATE(Localization.lang("Unabbreviate journal names"), Localization.lang("Unabbreviate journal names of the selected entries"), KeyBinding.UNABBREVIATE),
MANAGE_CUSTOM_EXPORTS(Localization.lang("Manage custom exports")),
@@ -109,11 +112,11 @@ public enum StandardActions implements Action {
MANAGE_CONTENT_SELECTORS(Localization.lang("Manage content selectors"), IconTheme.JabRefIcons.PREFERENCES),
MANAGE_CITE_KEY_PATTERNS(Localization.lang("BibTeX key patterns")),
- TOGGLE_PREVIEW(Localization.lang("Toggle entry preview"), IconTheme.JabRefIcons.TOGGLE_ENTRY_PREVIEW, KeyBinding.TOGGLE_ENTRY_PREVIEW),
- EDIT_ENTRY(Localization.lang("Edit entry"), IconTheme.JabRefIcons.EDIT_ENTRY, KeyBinding.EDIT_ENTRY),
- SHOW_PDV_VIEWER(Localization.lang("Show document viewer"), IconTheme.JabRefIcons.PDF_FILE),
- NEXT_PREVIEW_STYLE(Localization.lang("Next preview layout"), KeyBinding.NEXT_PREVIEW_LAYOUT),
- PREVIOUS_PREVIEW_STYLE(Localization.lang("Previous preview layout"), KeyBinding.PREVIOUS_PREVIEW_LAYOUT),
+ EDIT_ENTRY(Localization.lang("Open entry editor"), IconTheme.JabRefIcons.EDIT_ENTRY, KeyBinding.EDIT_ENTRY),
+ SHOW_PDF_VIEWER(Localization.lang("Open document viewer"), IconTheme.JabRefIcons.PDF_FILE),
+ TOGGLE_PREVIEW(Localization.lang("Entry preview"), IconTheme.JabRefIcons.TOGGLE_ENTRY_PREVIEW, KeyBinding.TOGGLE_ENTRY_PREVIEW),
+ NEXT_PREVIEW_STYLE(Localization.lang("Next citation style"), KeyBinding.NEXT_PREVIEW_LAYOUT),
+ PREVIOUS_PREVIEW_STYLE(Localization.lang("Previous citation style"), KeyBinding.PREVIOUS_PREVIEW_LAYOUT),
SELECT_ALL(Localization.lang("Select all"), KeyBinding.SELECT_ALL),
NEW_ENTRY(Localization.lang("New entry"), IconTheme.JabRefIcons.ADD_ENTRY, KeyBinding.NEW_ENTRY),
@@ -121,21 +124,21 @@ public enum StandardActions implements Action {
NEW_ENTRY_FROM_PLAINTEX(Localization.lang("New entry from plain text"), KeyBinding.NEW_FROM_PLAIN_TEXT),
LIBRARY_PROPERTIES(Localization.lang("Library properties")),
EDIT_PREAMBLE(Localization.lang("Edit preamble")),
- EDIT_STRINGS(Localization.lang("Edit strings"), IconTheme.JabRefIcons.EDIT_STRINGS, KeyBinding.EDIT_STRINGS),
+ EDIT_STRINGS(Localization.lang("Edit string constants"), IconTheme.JabRefIcons.EDIT_STRINGS, KeyBinding.EDIT_STRINGS),
FIND_DUPLICATES(Localization.lang("Find duplicates"), IconTheme.JabRefIcons.FIND_DUPLICATES),
MERGE_ENTRIES(Localization.lang("Merge entries"), IconTheme.JabRefIcons.MERGE_ENTRIES),
RESOLVE_DUPLICATE_KEYS(Localization.lang("Resolve duplicate BibTeX keys"), Localization.lang("Find and remove duplicate BibTeX keys"), KeyBinding.RESOLVE_DUPLICATE_BIBTEX_KEYS),
CHECK_INTEGRITY(Localization.lang("Check integrity"), KeyBinding.CHECK_INTEGRITY),
- FIND_UNLINKED_FILES(Localization.lang("Find unlinked files"), Localization.lang("Searches for unlinked PDF files on the file system"), KeyBinding.FIND_UNLINKED_FILES),
+ FIND_UNLINKED_FILES(Localization.lang("Search for unlinked local files"), IconTheme.JabRefIcons.SEARCH, KeyBinding.FIND_UNLINKED_FILES),
AUTO_LINK_FILES(Localization.lang("Automatically set file links"), IconTheme.JabRefIcons.AUTO_FILE_LINK, KeyBinding.AUTOMATICALLY_LINK_FILES),
- LOOKUP_DOC_IDENTIFIER(Localization.lang("Look up document identifier")),
- LOOKUP_FULLTEXT(Localization.lang("Look up full text documents"), KeyBinding.DOWNLOAD_FULL_TEXT),
+ LOOKUP_DOC_IDENTIFIER(Localization.lang("Search document identifier online")),
+ LOOKUP_FULLTEXT(Localization.lang("Search full text documents online"), IconTheme.JabRefIcons.FILE_SEARCH, KeyBinding.DOWNLOAD_FULL_TEXT),
GENERATE_CITE_KEY(Localization.lang("Generate BibTeX key"), IconTheme.JabRefIcons.MAKE_KEY, KeyBinding.AUTOGENERATE_BIBTEX_KEYS),
- GENERATE_CITE_KEYS(Localization.lang("Autogenerate BibTeX keys"), IconTheme.JabRefIcons.MAKE_KEY, KeyBinding.AUTOGENERATE_BIBTEX_KEYS),
- DOWNLOAD_FULL_TEXT(Localization.lang("Look up full text documents"), KeyBinding.DOWNLOAD_FULL_TEXT),
+ GENERATE_CITE_KEYS(Localization.lang("Generate BibTeX keys"), IconTheme.JabRefIcons.MAKE_KEY, KeyBinding.AUTOGENERATE_BIBTEX_KEYS),
+ DOWNLOAD_FULL_TEXT(Localization.lang("Search full text documents online"), IconTheme.JabRefIcons.FILE_SEARCH, KeyBinding.DOWNLOAD_FULL_TEXT),
CLEANUP_ENTRIES(Localization.lang("Cleanup entries"), IconTheme.JabRefIcons.CLEANUP_ENTRIES, KeyBinding.CLEANUP),
- SET_FILE_LINKS(Localization.lang("Automatically set file links"), IconTheme.JabRefIcons.AUTO_FILE_LINK, KeyBinding.AUTOMATICALLY_LINK_FILES),
+ SET_FILE_LINKS(Localization.lang("Automatically set file links"), KeyBinding.AUTOMATICALLY_LINK_FILES),
HELP(Localization.lang("Online help"), IconTheme.JabRefIcons.HELP, KeyBinding.HELP),
WEB_MENU(Localization.lang("JabRef resources")),
diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java
index 994452e5efa..e3796c623ee 100644
--- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java
+++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java
@@ -15,6 +15,8 @@
import org.jabref.Globals;
import org.jabref.gui.BasePanel;
+import org.jabref.gui.actions.ActionFactory;
+import org.jabref.gui.actions.StandardActions;
import org.jabref.gui.help.HelpAction;
import org.jabref.logic.help.HelpFile;
import org.jabref.logic.l10n.Localization;
@@ -34,7 +36,6 @@ public class BibtexKeyPatternPanel extends Pane {
// default pattern
protected final TextField defaultPat = new TextField();
- private final HelpAction help;
private final int COLUMNS = 2;
@@ -45,7 +46,6 @@ public class BibtexKeyPatternPanel extends Pane {
public BibtexKeyPatternPanel(BasePanel panel) {
this.panel = panel;
- help = new HelpAction(Localization.lang("Help on key patterns"), HelpFile.BIBTEX_KEY_PATTERN);
gridPane.setHgap(10);
gridPane.setVgap(5);
buildGUI();
@@ -93,7 +93,7 @@ private void buildGUI() {
textFields.put(type.getName().toLowerCase(Locale.ROOT), textField);
- if (columnIndex == COLUMNS - 1) {
+ if (columnIndex == (COLUMNS - 1)) {
columnIndex = 0;
rowIndex++;
} else {
@@ -103,9 +103,9 @@ private void buildGUI() {
rowIndex++;
- Button help1 = new Button("?");
- help1.setOnAction(e -> new HelpAction(Localization.lang("Help on key patterns"), HelpFile.BIBTEX_KEY_PATTERN).getHelpButton().doClick());
- gridPane.add(help1, 1, rowIndex);
+ ActionFactory factory = new ActionFactory(Globals.prefs.getKeyBindingRepository());
+ Button help = factory.createIconButton(StandardActions.HELP, new HelpAction(Localization.lang("Help on key patterns"), HelpFile.BIBTEX_KEY_PATTERN).getCommand());
+ gridPane.add(help, 1, rowIndex);
Button btnDefaultAll1 = new Button(Localization.lang("Reset all"));
btnDefaultAll1.setOnAction(e -> {
@@ -118,7 +118,6 @@ private void buildGUI() {
gridPane.add(btnDefaultAll1, 2, rowIndex);
}
-
/**
* fill the given LabelPattern by values generated from the text fields
*/
@@ -140,8 +139,7 @@ private void fillPatternUsingPanelData(AbstractBibtexKeyPattern keypatterns) {
protected GlobalBibtexKeyPattern getKeyPatternAsGlobalBibtexKeyPattern() {
GlobalBibtexKeyPattern res = GlobalBibtexKeyPattern.fromPattern(
- JabRefPreferences.getInstance().get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN)
- );
+ JabRefPreferences.getInstance().get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN));
fillPatternUsingPanelData(res);
return res;
}
@@ -162,7 +160,7 @@ public void setValues(AbstractBibtexKeyPattern keyPattern) {
setValue(entry.getValue(), entry.getKey(), keyPattern);
}
- if (keyPattern.getDefaultValue() == null || keyPattern.getDefaultValue().isEmpty()) {
+ if ((keyPattern.getDefaultValue() == null) || keyPattern.getDefaultValue().isEmpty()) {
defaultPat.setText("");
} else {
defaultPat.setText(keyPattern.getDefaultValue().get(0));
diff --git a/src/main/java/org/jabref/gui/actions/CustomizeEntryAction.java b/src/main/java/org/jabref/gui/customentrytypes/CustomizeEntryAction.java
similarity index 54%
rename from src/main/java/org/jabref/gui/actions/CustomizeEntryAction.java
rename to src/main/java/org/jabref/gui/customentrytypes/CustomizeEntryAction.java
index b8ea7ee567b..3fb6a635a53 100644
--- a/src/main/java/org/jabref/gui/actions/CustomizeEntryAction.java
+++ b/src/main/java/org/jabref/gui/customentrytypes/CustomizeEntryAction.java
@@ -1,9 +1,7 @@
-package org.jabref.gui.actions;
-
-import javax.swing.JDialog;
+package org.jabref.gui.customentrytypes;
import org.jabref.gui.JabRefFrame;
-import org.jabref.gui.customentrytypes.EntryTypeCustomizationDialog;
+import org.jabref.gui.actions.SimpleCommand;
public class CustomizeEntryAction extends SimpleCommand {
@@ -15,7 +13,7 @@ public CustomizeEntryAction(JabRefFrame frame) {
@Override
public void execute() {
- JDialog dialog = new EntryTypeCustomizationDialog(frame);
- dialog.setVisible(true);
+ EntryTypeCustomizationDialog dialog = new EntryTypeCustomizationDialog();
+ dialog.showAndWait();
}
}
diff --git a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java
index 0361f3013a1..cf0439125d1 100644
--- a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java
+++ b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java
@@ -1,56 +1,11 @@
package org.jabref.gui.customentrytypes;
-import java.awt.BorderLayout;
-import java.awt.Container;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import javax.swing.AbstractAction;
-import javax.swing.ActionMap;
-import javax.swing.BorderFactory;
-import javax.swing.InputMap;
-import javax.swing.JButton;
-import javax.swing.JComponent;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.ListSelectionModel;
-import javax.swing.event.ListDataEvent;
-import javax.swing.event.ListDataListener;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-
-import org.jabref.Globals;
-import org.jabref.gui.BasePanel;
-import org.jabref.gui.JabRefDialog;
-import org.jabref.gui.JabRefFrame;
-import org.jabref.gui.keyboard.KeyBinding;
-import org.jabref.logic.l10n.Localization;
-import org.jabref.model.EntryTypes;
-import org.jabref.model.database.BibDatabaseMode;
-import org.jabref.model.entry.BibEntry;
-import org.jabref.model.entry.CustomEntryType;
-import org.jabref.model.entry.EntryType;
-import org.jabref.model.entry.InternalBibtexFields;
-import org.jabref.model.strings.StringUtil;
-
-import com.jgoodies.forms.builder.ButtonBarBuilder;
-
-public class EntryTypeCustomizationDialog extends JabRefDialog implements ListSelectionListener {
+import org.jabref.gui.util.BaseDialog;
+public class EntryTypeCustomizationDialog extends BaseDialog {
+
+ // TODO: Re-implement customize entry types feature (https://github.com/JabRef/jabref/issues/4719)
+ /*
protected GridBagLayout gbl = new GridBagLayout();
protected GridBagConstraints con = new GridBagConstraints();
protected JButton delete;
@@ -70,9 +25,6 @@ public class EntryTypeCustomizationDialog extends JabRefDialog implements ListSe
private boolean biblatexMode;
private BibDatabaseMode bibDatabaseMode;
- /**
- * Creates a new instance of EntryTypeCustomizationDialog
- */
public EntryTypeCustomizationDialog(JabRefFrame frame) {
super(Localization.lang("Customize entry types"), false, EntryTypeCustomizationDialog.class);
@@ -419,6 +371,7 @@ private void record() {
changed.add(lastSelected);
typeComp.enable(lastSelected, true);
}
-
}
+
+ */
}
diff --git a/src/main/java/org/jabref/gui/edit/ManageKeywordsAction.java b/src/main/java/org/jabref/gui/edit/ManageKeywordsAction.java
new file mode 100644
index 00000000000..333e206cd02
--- /dev/null
+++ b/src/main/java/org/jabref/gui/edit/ManageKeywordsAction.java
@@ -0,0 +1,34 @@
+package org.jabref.gui.edit;
+
+import org.jabref.gui.BasePanel;
+import org.jabref.gui.JabRefFrame;
+import org.jabref.gui.actions.SimpleCommand;
+import org.jabref.logic.l10n.Localization;
+
+/**
+ * An Action for launching keyword managing dialog
+ *
+ */
+public class ManageKeywordsAction extends SimpleCommand {
+
+ private final JabRefFrame frame;
+
+ public ManageKeywordsAction(JabRefFrame frame) {
+ this.frame = frame;
+ }
+
+ @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());
+ dialog.showAndWait();
+ }
+}
diff --git a/src/main/java/org/jabref/gui/edit/ManageKeywordsDialog.fxml b/src/main/java/org/jabref/gui/edit/ManageKeywordsDialog.fxml
new file mode 100644
index 00000000000..609c6655bb9
--- /dev/null
+++ b/src/main/java/org/jabref/gui/edit/ManageKeywordsDialog.fxml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/jabref/gui/edit/ManageKeywordsDialog.java b/src/main/java/org/jabref/gui/edit/ManageKeywordsDialog.java
new file mode 100644
index 00000000000..2b1201fd24e
--- /dev/null
+++ b/src/main/java/org/jabref/gui/edit/ManageKeywordsDialog.java
@@ -0,0 +1,83 @@
+package org.jabref.gui.edit;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.ToggleGroup;
+import javafx.scene.control.cell.TextFieldTableCell;
+
+import org.jabref.gui.icon.IconTheme;
+import org.jabref.gui.util.BaseDialog;
+import org.jabref.gui.util.BindingsHelper;
+import org.jabref.gui.util.ValueTableCellFactory;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.model.entry.BibEntry;
+import org.jabref.preferences.PreferencesService;
+
+import com.airhacks.afterburner.views.ViewLoader;
+import org.fxmisc.easybind.EasyBind;
+
+public class ManageKeywordsDialog extends BaseDialog {
+ private final List entries;
+ @FXML private TableColumn keywordsTableMainColumn;
+ @FXML private TableColumn keywordsTableEditColumn;
+ @FXML private TableColumn keywordsTableDeleteColumn;
+ @FXML private TableView keywordsTable;
+ @FXML private ToggleGroup displayType;
+ @Inject private PreferencesService preferences;
+ private ManageKeywordsViewModel viewModel;
+
+ public ManageKeywordsDialog(List entries) {
+ this.entries = entries;
+ this.setTitle(Localization.lang("Manage keywords"));
+
+ ViewLoader.view(this)
+ .load()
+ .setAsDialogPane(this);
+
+ setResultConverter(button -> {
+ if (button == ButtonType.APPLY) {
+ viewModel.saveChanges();
+ }
+ return null;
+ });
+ }
+
+ @FXML
+ public void initialize() {
+ viewModel = new ManageKeywordsViewModel(preferences, entries);
+
+ viewModel.displayTypeProperty().bind(
+ EasyBind.map(displayType.selectedToggleProperty(), toggle -> {
+ if (toggle != null) {
+ return (ManageKeywordsDisplayType) toggle.getUserData();
+ } else {
+ return ManageKeywordsDisplayType.CONTAINED_IN_ALL_ENTRIES;
+ }
+ })
+ );
+
+ keywordsTable.setItems(viewModel.getKeywords());
+ keywordsTableMainColumn.setCellValueFactory(data -> BindingsHelper.constantOf(data.getValue()));
+ keywordsTableMainColumn.setOnEditCommit(event -> {
+ // Poor mans reverse databinding (necessary because we use a constant value above)
+ viewModel.getKeywords().set(event.getTablePosition().getRow(), event.getNewValue());
+ });
+ keywordsTableMainColumn.setCellFactory(TextFieldTableCell.forTableColumn());
+ keywordsTableEditColumn.setCellValueFactory(data -> BindingsHelper.constantOf(true));
+ keywordsTableDeleteColumn.setCellValueFactory(data -> BindingsHelper.constantOf(true));
+ new ValueTableCellFactory()
+ .withGraphic(none -> IconTheme.JabRefIcons.EDIT.getGraphicNode())
+ .withOnMouseClickedEvent(none -> event -> keywordsTable.edit(keywordsTable.getFocusModel().getFocusedIndex(), keywordsTableMainColumn))
+ .install(keywordsTableEditColumn);
+ new ValueTableCellFactory()
+ .withGraphic(none -> IconTheme.JabRefIcons.REMOVE.getGraphicNode())
+ .withOnMouseClickedEvent((keyword, none) -> event -> viewModel.removeKeyword(keyword))
+ .install(keywordsTableDeleteColumn);
+ }
+}
diff --git a/src/main/java/org/jabref/gui/edit/ManageKeywordsDisplayType.java b/src/main/java/org/jabref/gui/edit/ManageKeywordsDisplayType.java
new file mode 100644
index 00000000000..0af51af0734
--- /dev/null
+++ b/src/main/java/org/jabref/gui/edit/ManageKeywordsDisplayType.java
@@ -0,0 +1,6 @@
+package org.jabref.gui.edit;
+
+public enum ManageKeywordsDisplayType {
+ CONTAINED_IN_ALL_ENTRIES,
+ CONTAINED_IN_ANY_ENTRY,
+}
diff --git a/src/main/java/org/jabref/gui/edit/ManageKeywordsViewModel.java b/src/main/java/org/jabref/gui/edit/ManageKeywordsViewModel.java
new file mode 100644
index 00000000000..c071e652033
--- /dev/null
+++ b/src/main/java/org/jabref/gui/edit/ManageKeywordsViewModel.java
@@ -0,0 +1,139 @@
+package org.jabref.gui.edit;
+
+import java.util.List;
+import java.util.Optional;
+
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import org.jabref.gui.undo.NamedCompound;
+import org.jabref.gui.undo.UndoableFieldChange;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.logic.specialfields.SpecialFieldsUtils;
+import org.jabref.model.FieldChange;
+import org.jabref.model.entry.BibEntry;
+import org.jabref.model.entry.Keyword;
+import org.jabref.model.entry.KeywordList;
+import org.jabref.preferences.PreferencesService;
+
+import org.fxmisc.easybind.EasyBind;
+
+public class ManageKeywordsViewModel {
+
+ private final List entries;
+ private final KeywordList sortedKeywordsOfAllEntriesBeforeUpdateByUser = new KeywordList();
+ private final PreferencesService preferences;
+ private final ObjectProperty displayType = new SimpleObjectProperty<>(ManageKeywordsDisplayType.CONTAINED_IN_ALL_ENTRIES);
+ private final ObservableList keywords;
+
+ public ManageKeywordsViewModel(PreferencesService preferences, List entries) {
+ this.preferences = preferences;
+ this.entries = entries;
+ this.keywords = FXCollections.observableArrayList();
+
+ EasyBind.subscribe(displayType, this::fillKeywordsList);
+ }
+
+ public ManageKeywordsDisplayType getDisplayType() {
+ return displayType.get();
+ }
+
+ public ObjectProperty displayTypeProperty() {
+ return displayType;
+ }
+
+ private void fillKeywordsList(ManageKeywordsDisplayType type) {
+ keywords.clear();
+ sortedKeywordsOfAllEntriesBeforeUpdateByUser.clear();
+
+ if (type == ManageKeywordsDisplayType.CONTAINED_IN_ALL_ENTRIES) {
+ for (BibEntry entry : entries) {
+ KeywordList separatedKeywords = entry.getKeywords(preferences.getKeywordDelimiter());
+ sortedKeywordsOfAllEntriesBeforeUpdateByUser.addAll(separatedKeywords);
+ }
+ } else if (type == ManageKeywordsDisplayType.CONTAINED_IN_ANY_ENTRY) {
+
+ // all keywords from first entry have to be added
+ BibEntry firstEntry = entries.get(0);
+ KeywordList separatedKeywords = firstEntry.getKeywords(preferences.getKeywordDelimiter());
+ sortedKeywordsOfAllEntriesBeforeUpdateByUser.addAll(separatedKeywords);
+
+ // for the remaining entries, intersection has to be used
+ // this approach ensures that one empty keyword list leads to an empty set of common keywords
+ for (BibEntry entry : entries) {
+ separatedKeywords = entry.getKeywords(preferences.getKeywordDelimiter());
+ sortedKeywordsOfAllEntriesBeforeUpdateByUser.retainAll(separatedKeywords);
+ }
+ } else {
+ throw new IllegalStateException("DisplayType " + type + " not handled");
+ }
+ for (Keyword keyword : sortedKeywordsOfAllEntriesBeforeUpdateByUser) {
+ keywords.add(keyword.get());
+ }
+ }
+
+ public ObservableList getKeywords() {
+ return keywords;
+ }
+
+ public void removeKeyword(String keyword) {
+ keywords.remove(keyword);
+ }
+
+ public void saveChanges() {
+ KeywordList keywordsToAdd = new KeywordList();
+ KeywordList userSelectedKeywords = new KeywordList();
+ // build keywordsToAdd and userSelectedKeywords in parallel
+ for (String keyword : keywords) {
+ userSelectedKeywords.add(keyword);
+ if (!sortedKeywordsOfAllEntriesBeforeUpdateByUser.contains(keyword)) {
+ keywordsToAdd.add(keyword);
+ }
+ }
+
+ KeywordList keywordsToRemove = new KeywordList();
+ for (Keyword kword : sortedKeywordsOfAllEntriesBeforeUpdateByUser) {
+ if (!userSelectedKeywords.contains(kword)) {
+ keywordsToRemove.add(kword);
+ }
+ }
+
+ if (keywordsToAdd.isEmpty() && keywordsToRemove.isEmpty()) {
+ // nothing to be done if nothing is new and nothing is obsolete
+ return;
+ }
+
+ if (preferences.isKeywordSyncEnabled() && !keywordsToAdd.isEmpty()) {
+ SpecialFieldsUtils.synchronizeSpecialFields(keywordsToAdd, keywordsToRemove);
+ }
+
+ NamedCompound ce = updateKeywords(entries, keywordsToAdd, keywordsToRemove);
+ //TODO: bp.getUndoManager().addEdit(ce);
+ }
+
+ private NamedCompound updateKeywords(List entries, KeywordList keywordsToAdd,
+ KeywordList keywordsToRemove) {
+ NamedCompound ce = new NamedCompound(Localization.lang("Update keywords"));
+ for (BibEntry entry : entries) {
+ KeywordList keywords = entry.getKeywords(preferences.getKeywordDelimiter());
+
+ // update keywords
+ keywords.removeAll(keywordsToRemove);
+ keywords.addAll(keywordsToAdd);
+
+ // put keywords back
+ Optional change = entry.putKeywords(keywords, preferences.getKeywordDelimiter());
+ if (change.isPresent()) {
+ ce.addEdit(new UndoableFieldChange(change.get()));
+ }
+
+ if (preferences.isKeywordSyncEnabled()) {
+ SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, preferences.getKeywordDelimiter());
+ }
+ }
+ ce.end();
+ return ce;
+ }
+}
diff --git a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java
index 4af7fec8023..85bd758232d 100644
--- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java
+++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java
@@ -3,16 +3,12 @@
import java.util.List;
import java.util.stream.Collectors;
-import javax.swing.SwingUtilities;
-
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TextInputControl;
import org.jabref.Globals;
-import org.jabref.JabRefGUI;
-import org.jabref.gui.protectedterms.NewProtectedTermsFileDialog;
import org.jabref.logic.formatter.casechanger.ProtectTermsFormatter;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.protectedterms.ProtectedTermsList;
@@ -65,21 +61,5 @@ private void updateFiles() {
externalFiles.getItems().add(fileItem);
}
externalFiles.getItems().add(new SeparatorMenuItem());
- MenuItem addToNewFileItem = new MenuItem(Localization.lang("New") + "...");
- addToNewFileItem.setOnAction(event -> {
- NewProtectedTermsFileDialog dialog = new NewProtectedTermsFileDialog(JabRefGUI.getMainFrame().getDialogService(),
- loader);
-
- SwingUtilities.invokeLater(() -> {
- dialog.setVisible(true);
-
- if (dialog.isOKPressed()) {
- // Update preferences with new list
- Globals.prefs.setProtectedTermsPreferences(loader);
- this.updateFiles();
- }
- });
- });
- externalFiles.getItems().add(addToNewFileItem);
}
}
diff --git a/src/main/java/org/jabref/gui/help/HelpAction.java b/src/main/java/org/jabref/gui/help/HelpAction.java
index ab7ae84e027..e8d410de343 100644
--- a/src/main/java/org/jabref/gui/help/HelpAction.java
+++ b/src/main/java/org/jabref/gui/help/HelpAction.java
@@ -1,11 +1,7 @@
package org.jabref.gui.help;
-import java.awt.Color;
-import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
@@ -14,7 +10,6 @@
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
-import javax.swing.JLabel;
import javax.swing.KeyStroke;
import org.jabref.Globals;
@@ -91,20 +86,6 @@ public void setHelpFile(HelpFile urlPart) {
this.helpPage = urlPart;
}
- public JLabel getHelpLabel(String labelText) {
- JLabel helpLabel = new JLabel("" + labelText + "");
- helpLabel.setForeground(Color.BLUE);
- helpLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
- helpLabel.addMouseListener(new MouseAdapter() {
-
- @Override
- public void mouseClicked(MouseEvent e) {
- openHelpPage(helpPage);
- }
- });
- return helpLabel;
- }
-
@Override
public void actionPerformed(ActionEvent e) {
openHelpPage(helpPage);
diff --git a/src/main/java/org/jabref/gui/icon/IconTheme.java b/src/main/java/org/jabref/gui/icon/IconTheme.java
index 5c0510f862a..49cfe8ba53a 100644
--- a/src/main/java/org/jabref/gui/icon/IconTheme.java
+++ b/src/main/java/org/jabref/gui/icon/IconTheme.java
@@ -205,6 +205,7 @@ public enum JabRefIcons implements JabRefIcon {
REFRESH(MaterialDesignIcon.REFRESH),
DELETE_ENTRY(MaterialDesignIcon.DELETE),
SEARCH(MaterialDesignIcon.MAGNIFY),
+ FILE_SEARCH(MaterialDesignIcon.FILE_FIND),
ADVANCED_SEARCH(Color.CYAN, MaterialDesignIcon.MAGNIFY),
PREFERENCES(MaterialDesignIcon.SETTINGS),
HELP(MaterialDesignIcon.HELP_CIRCLE),
@@ -238,7 +239,7 @@ public enum JabRefIcons implements JabRefIcon {
AUTO_FILE_LINK(MaterialDesignIcon.FILE_FIND) /*css: file-find */,
QUALITY_ASSURED(MaterialDesignIcon.CERTIFICATE), /*css: certificate */
QUALITY(MaterialDesignIcon.CERTIFICATE),/*css: certificate */
- OPEN(MaterialDesignIcon.FOLDER) /*css: folder */,
+ OPEN(MaterialDesignIcon.FOLDER_OUTLINE) /*css: folder-outline */,
ADD_ROW(MaterialDesignIcon.SERVER_PLUS) /* css: server-plus*/,
REMOVE_ROW(MaterialDesignIcon.SERVER_MINUS) /*css: server-minus */,
PICTURE(MaterialDesignIcon.FILE_IMAGE) /*css: file-image */,
@@ -276,7 +277,7 @@ public enum JabRefIcons implements JabRefIcon {
APPLICATION_WINEDT(JabRefMaterialDesignIcon.WINEDT),
KEY_BINDINGS(MaterialDesignIcon.KEYBOARD), /*css: keyboard */
FIND_DUPLICATES(MaterialDesignIcon.CODE_EQUAL), /*css: code-equal */
- PULL(MaterialDesignIcon.SOURCE_PULL), /*source-pull*/
+ CONNECT_DB(MaterialDesignIcon.CLOUD_UPLOAD), /*cloud-upload*/
SUCCESS(MaterialDesignIcon.CHECK_CIRCLE),
WARNING(MaterialDesignIcon.ALERT),
ERROR(MaterialDesignIcon.ALERT_CIRCLE),
@@ -293,7 +294,8 @@ public enum JabRefIcons implements JabRefIcon {
DEFAULT_GROUP_ICON_COLORED(MaterialDesignIcon.PLAY),
DEFAULT_GROUP_ICON(MaterialDesignIcon.LABEL_OUTLINE),
ALL_ENTRIES_GROUP_ICON(DefaultGroupsFactory.ALL_ENTRIES_GROUP_DEFAULT_ICON),
- IMPORT_EXPORT(MaterialDesignIcon.SWAP_VERTICAL),
+ IMPORT(MaterialDesignIcon.CALL_RECEIVED),
+ EXPORT(MaterialDesignIcon.CALL_MADE),
PREVIOUS_LEFT(MaterialDesignIcon.CHEVRON_LEFT),
PREVIOUS_UP(MaterialDesignIcon.CHEVRON_UP),
NEXT_RIGHT(MaterialDesignIcon.CHEVRON_RIGHT),
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 9a87333b386..67bd022cbc0 100644
--- a/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java
+++ b/src/main/java/org/jabref/gui/importer/actions/OpenDatabaseAction.java
@@ -35,7 +35,6 @@
import org.jabref.logic.shared.exception.InvalidDBMSConnectionPropertiesException;
import org.jabref.logic.shared.exception.NotASharedDatabaseException;
import org.jabref.logic.util.StandardFileType;
-import org.jabref.migrations.FileLinksUpgradeWarning;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.database.shared.DatabaseNotSupportedException;
import org.jabref.preferences.JabRefPreferences;
@@ -53,9 +52,6 @@ public class OpenDatabaseAction extends SimpleCommand {
// Migrations:
// Warning for migrating the Review into the Comment field
new MergeReviewIntoCommentAction(),
- // External file handling system in version 2.3:
- new FileLinksUpgradeWarning(),
-
// Check for new custom entry types loaded from the BIB file:
new CheckForNewEntryTypesAction()
);
diff --git a/src/main/java/org/jabref/gui/journals/JournalAbbreviationsUtil.java b/src/main/java/org/jabref/gui/journals/JournalAbbreviationsUtil.java
deleted file mode 100644
index 86a284cd78f..00000000000
--- a/src/main/java/org/jabref/gui/journals/JournalAbbreviationsUtil.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.jabref.gui.journals;
-
-import java.util.Collection;
-
-import javax.swing.table.DefaultTableModel;
-import javax.swing.table.TableModel;
-
-import org.jabref.logic.journals.Abbreviation;
-import org.jabref.logic.l10n.Localization;
-
-public class JournalAbbreviationsUtil {
-
- private JournalAbbreviationsUtil() {
- }
-
- public static TableModel getTableModel(Collection abbreviations) {
- Object[][] cells = new Object[abbreviations.size()][2];
- int row = 0;
- for (Abbreviation abbreviation : abbreviations) {
- cells[row][0] = abbreviation.getName();
- cells[row][1] = abbreviation.getIsoAbbreviation();
- row++;
- }
-
- return new DefaultTableModel(cells, new Object[] {Localization.lang("Full name"),
- Localization.lang("Abbreviation")}) {
-
- @Override
- public boolean isCellEditable(int row1, int column) {
- return false;
- }
- };
- }
-}
diff --git a/src/main/java/org/jabref/gui/preferences/AdvancedTab.java b/src/main/java/org/jabref/gui/preferences/AdvancedTab.java
index 3fcd0516ce5..4a8dbf0a075 100644
--- a/src/main/java/org/jabref/gui/preferences/AdvancedTab.java
+++ b/src/main/java/org/jabref/gui/preferences/AdvancedTab.java
@@ -15,6 +15,8 @@
import org.jabref.Globals;
import org.jabref.gui.DialogService;
+import org.jabref.gui.actions.ActionFactory;
+import org.jabref.gui.actions.StandardActions;
import org.jabref.gui.help.HelpAction;
import org.jabref.gui.remote.JabRefMessageHandler;
import org.jabref.gui.util.DefaultTaskExecutor;
@@ -76,9 +78,11 @@ public AdvancedTab(DialogService dialogService, JabRefPreferences prefs) {
HBox p = new HBox();
p.getChildren().add(useRemoteServer);
p.getChildren().add(remoteServerPort);
- Button helpButton = new Button("?");
- helpButton.setOnAction(event -> new HelpAction(HelpFile.REMOTE).getHelpButton().doClick());
- p.getChildren().add(helpButton);
+
+ ActionFactory factory = new ActionFactory(preferences.getKeyBindingRepository());
+ Button help = factory.createIconButton(StandardActions.HELP, new HelpAction(HelpFile.REMOTE).getCommand());
+ help.setMaxWidth(Double.MAX_VALUE);
+ p.getChildren().add(help);
builder.add(p, 2, 9);
builder.add(new Label(""), 1, 10);
diff --git a/src/main/java/org/jabref/gui/preferences/ExternalTab.java b/src/main/java/org/jabref/gui/preferences/ExternalTab.java
index 782a14fa11d..0328eaf4e1b 100644
--- a/src/main/java/org/jabref/gui/preferences/ExternalTab.java
+++ b/src/main/java/org/jabref/gui/preferences/ExternalTab.java
@@ -1,13 +1,6 @@
package org.jabref.gui.preferences;
-import java.awt.BorderLayout;
-
-import javax.swing.JFileChooser;
-import javax.swing.JPanel;
-
-import javafx.embed.swing.JFXPanel;
import javafx.scene.Node;
-import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
@@ -17,18 +10,19 @@
import javafx.scene.layout.GridPane;
import org.jabref.Globals;
+import org.jabref.gui.DialogService;
import org.jabref.gui.JabRefFrame;
-import org.jabref.gui.customjfx.CustomJFXPanel;
import org.jabref.gui.externalfiletype.ExternalFileTypeEditor;
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.util.FileDialogConfiguration;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.util.OS;
import org.jabref.preferences.JabRefPreferences;
-class ExternalTab extends JPanel implements PrefsTab {
+class ExternalTab implements PrefsTab {
private final JabRefPreferences prefs;
private final TextField emailSubject;
@@ -45,12 +39,15 @@ class ExternalTab extends JPanel implements PrefsTab {
private final TextField adobeAcrobatReaderPath;
private final TextField sumatraReaderPath;
private final GridPane builder = new GridPane();
+ private final DialogService dialogService;
+ private final FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder().build();
public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPreferences prefs) {
this.prefs = prefs;
+ dialogService = frame.getDialogService();
Button editFileTypes = new Button(Localization.lang("Manage external file types"));
citeCommand = new TextField();
- editFileTypes.setOnAction(e->ExternalFileTypeEditor.getAction());
+ editFileTypes.setOnAction(e -> ExternalFileTypeEditor.getAction());
defaultConsole = new RadioButton(Localization.lang("Use default terminal emulator"));
executeConsole = new RadioButton(Localization.lang("Execute command") + ":");
consoleCommand = new TextField();
@@ -73,25 +70,25 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere
final ToggleGroup consoleGroup = new ToggleGroup();
defaultConsole.setToggleGroup(consoleGroup);
executeConsole.setToggleGroup(consoleGroup);
- consoleOptionPanel.add(defaultConsole, 1, 1);
- consoleOptionPanel.add(executeConsole, 1, 2);
- consoleOptionPanel.add(consoleCommand, 2, 2);
- consoleOptionPanel.add(browseButton, 3, 2);
- consoleOptionPanel.add(commandDescription, 2, 3);
+ consoleOptionPanel.add(defaultConsole, 1, 1);
+ consoleOptionPanel.add(executeConsole, 1, 2);
+ consoleOptionPanel.add(consoleCommand, 2, 2);
+ consoleOptionPanel.add(browseButton, 3, 2);
+ consoleOptionPanel.add(commandDescription, 2, 3);
GridPane pdfOptionPanel = new GridPane();
final ToggleGroup pdfReaderGroup = new ToggleGroup();
- pdfOptionPanel.add(adobeAcrobatReader, 1, 1);
- pdfOptionPanel.add(adobeAcrobatReaderPath, 2, 1);
+ pdfOptionPanel.add(adobeAcrobatReader, 1, 1);
+ pdfOptionPanel.add(adobeAcrobatReaderPath, 2, 1);
adobeAcrobatReader.setToggleGroup(pdfReaderGroup);
- pdfOptionPanel.add(browseAdobeAcrobatReader, 3, 1);
+ pdfOptionPanel.add(browseAdobeAcrobatReader, 3, 1);
if (OS.WINDOWS) {
browseSumatraReader.setOnAction(e -> showSumatraChooser());
- pdfOptionPanel.add(sumatraReader, 1, 2);
+ pdfOptionPanel.add(sumatraReader, 1, 2);
sumatraReader.setToggleGroup(pdfReaderGroup);
- pdfOptionPanel.add(sumatraReaderPath, 2, 2);
- pdfOptionPanel.add(browseSumatraReader, 3, 2);
+ pdfOptionPanel.add(sumatraReaderPath, 2, 2);
+ pdfOptionPanel.add(browseSumatraReader, 3, 2);
}
Label sendingOfEmails = new Label(Localization.lang("Sending of emails"));
@@ -132,14 +129,13 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere
Label openPdf = new Label(Localization.lang("Open PDF"));
openPdf.getStyleClass().add("sectionHeader");
- builder.add(openPdf, 1, 12);
+ builder.add(openPdf, 1, 12);
builder.add(pdfOptionPanel, 1, 13);
- JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder));
- setLayout(new BorderLayout());
- add(panel, BorderLayout.CENTER);
+
}
+ @Override
public Node getBuilder() {
return builder;
}
@@ -149,10 +145,10 @@ private void addSettingsButton(final PushToApplication application, GridPane pan
Button button = new Button(Localization.lang("Settings for %0", application.getApplicationName()));
button.setPrefSize(150, 20);
button.setOnAction(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, settings, index));
- if (index % 2 == 0) {
- panel.add(button, 1, index / 2 + 1);
+ if ((index % 2) == 0) {
+ panel.add(button, 1, (index / 2) + 1);
} else {
- panel.add(button, 2, index / 2 + 1);
+ panel.add(button, 2, (index / 2) + 1);
}
}
@@ -213,27 +209,15 @@ private void updateExecuteConsoleButtonAndFieldEnabledState() {
}
private void showConsoleChooser() {
- JFileChooser consoleChooser = new JFileChooser();
- int answer = consoleChooser.showOpenDialog(ExternalTab.this);
- if (answer == JFileChooser.APPROVE_OPTION) {
- consoleCommand.setText(consoleChooser.getSelectedFile().getAbsolutePath());
- }
+ dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(file -> consoleCommand.setText(file.toAbsolutePath().toString()));
}
private void showAdobeChooser() {
- JFileChooser adobeChooser = new JFileChooser();
- int answer = adobeChooser.showOpenDialog(ExternalTab.this);
- if (answer == JFileChooser.APPROVE_OPTION) {
- adobeAcrobatReaderPath.setText(adobeChooser.getSelectedFile().getAbsolutePath());
- }
+ dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(file -> adobeAcrobatReaderPath.setText(file.toAbsolutePath().toString()));
}
private void showSumatraChooser() {
- JFileChooser adobeChooser = new JFileChooser();
- int answer = adobeChooser.showOpenDialog(ExternalTab.this);
- if (answer == JFileChooser.APPROVE_OPTION) {
- sumatraReaderPath.setText(adobeChooser.getSelectedFile().getAbsolutePath());
- }
+ dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(file -> sumatraReaderPath.setText(file.toAbsolutePath().toString()));
}
private void readerSelected() {
diff --git a/src/main/java/org/jabref/gui/preferences/FileTab.java b/src/main/java/org/jabref/gui/preferences/FileTab.java
index 55e599e67ae..3bbc387f130 100644
--- a/src/main/java/org/jabref/gui/preferences/FileTab.java
+++ b/src/main/java/org/jabref/gui/preferences/FileTab.java
@@ -211,7 +211,7 @@ public void storeSettings() {
}
String newline;
- switch (newlineSeparator.getPromptText()) {
+ switch (newlineSeparator.getValue()) {
case "CR":
newline = "\r";
break;
diff --git a/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsAction.java b/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsAction.java
new file mode 100644
index 00000000000..34f4ff3f116
--- /dev/null
+++ b/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsAction.java
@@ -0,0 +1,12 @@
+package org.jabref.gui.protectedterms;
+
+import org.jabref.gui.actions.SimpleCommand;
+
+public class ManageProtectedTermsAction extends SimpleCommand {
+
+ @Override
+ public void execute() {
+ ManageProtectedTermsDialog protectTermsDialog = new ManageProtectedTermsDialog();
+ protectTermsDialog.showAndWait();
+ }
+}
diff --git a/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsDialog.fxml b/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsDialog.fxml
new file mode 100644
index 00000000000..0b23bc0ccaf
--- /dev/null
+++ b/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsDialog.fxml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsDialog.java b/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsDialog.java
new file mode 100644
index 00000000000..474304d2383
--- /dev/null
+++ b/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsDialog.java
@@ -0,0 +1,128 @@
+package org.jabref.gui.protectedterms;
+
+import javax.inject.Inject;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.cell.CheckBoxTableCell;
+
+import org.jabref.gui.DialogService;
+import org.jabref.gui.icon.IconTheme;
+import org.jabref.gui.util.BaseDialog;
+import org.jabref.gui.util.BindingsHelper;
+import org.jabref.gui.util.ValueTableCellFactory;
+import org.jabref.gui.util.ViewModelTableRowFactory;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.logic.protectedterms.ProtectedTermsList;
+import org.jabref.logic.protectedterms.ProtectedTermsLoader;
+import org.jabref.preferences.PreferencesService;
+
+import com.airhacks.afterburner.views.ViewLoader;
+
+/**
+ * Dialog for managing term list files.
+ */
+public class ManageProtectedTermsDialog extends BaseDialog {
+
+ @FXML private TableView filesTable;
+ @FXML private TableColumn filesTableEnabledColumn;
+ @FXML private TableColumn filesTableDescriptionColumn;
+ @FXML private TableColumn filesTableFileColumn;
+ @FXML private TableColumn filesTableEditColumn;
+ @FXML private TableColumn filesTableDeleteColumn;
+
+ @Inject private ProtectedTermsLoader termsLoader;
+ @Inject private DialogService dialogService;
+ @Inject private PreferencesService preferences;
+ private ManageProtectedTermsViewModel viewModel;
+
+ public ManageProtectedTermsDialog() {
+ this.setTitle(Localization.lang("Manage protected terms files"));
+
+ ViewLoader.view(this)
+ .load()
+ .setAsDialogPane(this);
+
+ setResultConverter(button -> {
+ if (button == ButtonType.APPLY) {
+ viewModel.save();
+ }
+ return null;
+ });
+ }
+
+ @FXML
+ public void initialize() {
+ viewModel = new ManageProtectedTermsViewModel(termsLoader, dialogService, preferences);
+
+ filesTable.setItems(viewModel.getTermsFiles());
+ new ViewModelTableRowFactory()
+ .withContextMenu(this::createContextMenu)
+ .install(filesTable);
+ filesTableEnabledColumn.setCellValueFactory(data -> BindingsHelper.constantOf(data.getValue().isEnabled()));
+ filesTableEnabledColumn.setCellFactory(CheckBoxTableCell.forTableColumn(filesTableEnabledColumn));
+ filesTableDescriptionColumn.setCellValueFactory(data -> BindingsHelper.constantOf(data.getValue().getDescription()));
+ filesTableFileColumn.setCellValueFactory(data -> {
+ ProtectedTermsList list = data.getValue();
+ if (list.isInternalList()) {
+ return BindingsHelper.constantOf(Localization.lang("Internal list"));
+ } else {
+ return BindingsHelper.constantOf(data.getValue().getLocation());
+ }
+ });
+ filesTableEditColumn.setCellValueFactory(data -> BindingsHelper.constantOf(true));
+ filesTableDeleteColumn.setCellValueFactory(data -> BindingsHelper.constantOf(true));
+
+ new ValueTableCellFactory()
+ .withGraphic(none -> IconTheme.JabRefIcons.EDIT.getGraphicNode())
+ .withOnMouseClickedEvent((file, none) -> event -> viewModel.edit(file))
+ .install(filesTableEditColumn);
+ new ValueTableCellFactory()
+ .withGraphic(none -> IconTheme.JabRefIcons.REMOVE.getGraphicNode())
+ .withTooltip(none -> Localization.lang("Remove protected terms file"))
+ .withOnMouseClickedEvent((file, none) -> event -> viewModel.removeFile(file))
+ .install(filesTableDeleteColumn);
+ }
+
+ private ContextMenu createContextMenu(ProtectedTermsList file) {
+ MenuItem edit = new MenuItem(Localization.lang("Edit"));
+ edit.setOnAction(event -> viewModel.edit(file));
+ MenuItem show = new MenuItem(Localization.lang("View"));
+ show.setOnAction(event -> viewModel.displayContent(file));
+ MenuItem remove = new MenuItem(Localization.lang("Remove"));
+ remove.setOnAction(event -> viewModel.removeFile(file));
+ MenuItem reload = new MenuItem(Localization.lang("Reload"));
+ reload.setOnAction(event -> viewModel.reloadFile(file));
+
+ // Enable/disable context menu items
+ if (file.isInternalList()) {
+ edit.setDisable(true);
+ show.setDisable(false);
+ remove.setDisable(true);
+ reload.setDisable(true);
+ } else {
+ edit.setDisable(false);
+ show.setDisable(false);
+ remove.setDisable(false);
+ reload.setDisable(false);
+ }
+
+ final ContextMenu contextMenu = new ContextMenu();
+ contextMenu.getItems().addAll(edit, show, remove, reload);
+ return contextMenu;
+ }
+
+ @FXML
+ private void addFile() {
+ viewModel.addFile();
+ }
+
+ @FXML
+ private void createNewFile() {
+ viewModel.createNewFile();
+ }
+}
diff --git a/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsViewModel.java b/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsViewModel.java
new file mode 100644
index 00000000000..3fca8b6e63b
--- /dev/null
+++ b/src/main/java/org/jabref/gui/protectedterms/ManageProtectedTermsViewModel.java
@@ -0,0 +1,99 @@
+package org.jabref.gui.protectedterms;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import org.jabref.gui.DialogService;
+import org.jabref.gui.desktop.JabRefDesktop;
+import org.jabref.gui.externalfiletype.ExternalFileType;
+import org.jabref.gui.externalfiletype.ExternalFileTypes;
+import org.jabref.gui.util.FileDialogConfiguration;
+import org.jabref.logic.l10n.Localization;
+import org.jabref.logic.protectedterms.ProtectedTermsList;
+import org.jabref.logic.protectedterms.ProtectedTermsLoader;
+import org.jabref.logic.util.StandardFileType;
+import org.jabref.model.database.BibDatabaseContext;
+import org.jabref.model.util.OptionalUtil;
+import org.jabref.preferences.PreferencesService;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ManageProtectedTermsViewModel {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ManageProtectedTermsViewModel.class);
+
+ private final ProtectedTermsLoader termsLoader;
+ private final ObservableList termsFiles;
+ private final PreferencesService preferences;
+ private final DialogService dialogService;
+
+ public ManageProtectedTermsViewModel(ProtectedTermsLoader termsLoader, DialogService dialogService, PreferencesService preferences) {
+ this.termsLoader = termsLoader;
+ this.dialogService = dialogService;
+ this.termsFiles = FXCollections.observableArrayList(termsLoader.getProtectedTermsLists());
+ this.preferences = preferences;
+ }
+
+ public ObservableList getTermsFiles() {
+ return termsFiles;
+ }
+
+ public void save() {
+ preferences.setProtectedTermsPreferences(termsLoader);
+ }
+
+ public void addFile() {
+ FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
+ .addExtensionFilter(Localization.lang("Protected terms file"), StandardFileType.TERMS)
+ .withDefaultExtension(Localization.lang("Protected terms file"), StandardFileType.TERMS)
+ .withInitialDirectory(preferences.getWorkingDir())
+ .build();
+
+ dialogService.showFileOpenDialog(fileDialogConfiguration)
+ .ifPresent(file -> termsLoader.addProtectedTermsListFromFile(file.toAbsolutePath().toString(), true));
+ }
+
+ public void removeFile(ProtectedTermsList list) {
+ if (!list.isInternalList() && dialogService.showConfirmationDialogAndWait(Localization.lang("Remove protected terms file"),
+ Localization.lang("Are you sure you want to remove the protected terms file?"),
+ Localization.lang("Remove protected terms file"),
+ Localization.lang("Cancel"))) {
+ if (!termsLoader.removeProtectedTermsList(list)) {
+ LOGGER.info("Problem removing protected terms file");
+ }
+ }
+ }
+
+ public void createNewFile() {
+ NewProtectedTermsFileDialog newDialog = new NewProtectedTermsFileDialog(termsLoader, dialogService);
+ newDialog.showAndWait();
+ }
+
+ public void edit(ProtectedTermsList file) {
+ Optional termsFileType = OptionalUtil.orElse(
+ ExternalFileTypes.getInstance().getExternalFileTypeByExt("terms"),
+ ExternalFileTypes.getInstance().getExternalFileTypeByExt("txt")
+ );
+
+ String fileName = file.getLocation();
+ try {
+ JabRefDesktop.openExternalFileAnyFormat(new BibDatabaseContext(), fileName, termsFileType);
+ } catch (IOException e) {
+ LOGGER.warn("Problem open protected terms file editor", e);
+ }
+ }
+
+ public void displayContent(ProtectedTermsList list) {
+ dialogService.showInformationDialogAndWait(
+ list.getDescription() + " - " + list.getLocation(),
+ list.getTermListing()
+ );
+ }
+
+ public void reloadFile(ProtectedTermsList file) {
+ termsLoader.reloadProtectedTermsList(file);
+ }
+}
diff --git a/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java b/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java
index b0bd76d7276..d97e6ccc9fb 100644
--- a/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java
+++ b/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java
@@ -1,61 +1,30 @@
package org.jabref.gui.protectedterms;
-import java.awt.BorderLayout;
-import java.awt.event.ActionEvent;
-import java.nio.file.Path;
-import java.util.Optional;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.BorderFactory;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComponent;
-import javax.swing.JDialog;
-import javax.swing.JTextField;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
import org.jabref.Globals;
import org.jabref.gui.DialogService;
-import org.jabref.gui.JabRefDialog;
-import org.jabref.gui.keyboard.KeyBinding;
-import org.jabref.gui.util.DefaultTaskExecutor;
+import org.jabref.gui.util.BaseDialog;
import org.jabref.gui.util.FileDialogConfiguration;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.protectedterms.ProtectedTermsLoader;
import org.jabref.logic.util.StandardFileType;
import org.jabref.preferences.JabRefPreferences;
-import com.jgoodies.forms.builder.ButtonBarBuilder;
-import com.jgoodies.forms.builder.FormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-public class NewProtectedTermsFileDialog extends JabRefDialog {
+public class NewProtectedTermsFileDialog extends BaseDialog {
- private final JTextField newFile = new JTextField();
- private final JTextField newDescription = new JTextField();
- private final JCheckBox enabled = new JCheckBox(Localization.lang("Enabled"));
- private boolean addOKPressed;
- private final ProtectedTermsLoader loader;
+ private final TextField newFile = new TextField();
private final DialogService dialogService;
- public NewProtectedTermsFileDialog(JDialog parent, ProtectedTermsLoader loader, DialogService dialogService) {
- super(parent, Localization.lang("New protected terms file"), true, NewProtectedTermsFileDialog.class);
- this.loader = loader;
- this.dialogService = dialogService;
-
- setupDialog();
- setLocationRelativeTo(parent);
- }
-
- public NewProtectedTermsFileDialog(DialogService dialogService, ProtectedTermsLoader loader) {
- super(Localization.lang("New protected terms file"), true, NewProtectedTermsFileDialog.class);
- this.loader = loader;
+ public NewProtectedTermsFileDialog(ProtectedTermsLoader termsLoader, DialogService dialogService) {
this.dialogService = dialogService;
- setupDialog();
- }
- private void setupDialog() {
- JButton browse = new JButton(Localization.lang("Browse"));
+ this.setTitle(Localization.lang("New protected terms file"));
FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
.addExtensionFilter(Localization.lang("Protected terms file"), StandardFileType.TERMS)
@@ -63,61 +32,29 @@ private void setupDialog() {
.withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY))
.build();
- browse.addActionListener(e -> {
- Optional file = DefaultTaskExecutor
- .runInJavaFXThread(() -> dialogService.showFileSaveDialog(fileDialogConfiguration));
- file.ifPresent(f -> newFile.setText(f.toAbsolutePath().toString()));
- });
-
- // Build content panel
- FormBuilder builder = FormBuilder.create();
- builder.layout(new FormLayout("left:pref, 4dlu, fill:100dlu:grow, 4dlu, pref", "p, 4dlu, p, 4dlu, p"));
- builder.add(Localization.lang("Description")).xy(1, 1);
- builder.add(newDescription).xyw(3, 1, 3);
- builder.add(Localization.lang("File")).xy(1, 3);
- builder.add(newFile).xy(3, 3);
- builder.add(browse).xy(5, 3);
- builder.add(enabled).xyw(1, 5, 5);
- enabled.setSelected(true);
- builder.padding("10dlu, 10dlu, 10dlu, 10dlu");
- getContentPane().add(builder.build(), BorderLayout.CENTER);
-
- // Buttons
- ButtonBarBuilder bb = new ButtonBarBuilder();
- JButton addOKButton = new JButton(Localization.lang("OK"));
- JButton addCancelButton = new JButton(Localization.lang("Cancel"));
- bb.addGlue();
- bb.addButton(addOKButton);
- bb.addButton(addCancelButton);
- bb.addGlue();
- bb.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
- getContentPane().add(bb.getPanel(), BorderLayout.SOUTH);
- addOKButton.addActionListener(e -> {
- addOKPressed = true;
- loader.addNewProtectedTermsList(newDescription.getText(), newFile.getText(),
- enabled.isSelected());
- dispose();
+ Button browse = new Button(Localization.lang("Browse"));
+ browse.setOnAction(event -> {
+ this.dialogService.showFileSaveDialog(fileDialogConfiguration)
+ .ifPresent(file -> newFile.setText(file.toAbsolutePath().toString()));
});
- Action cancelAction = new AbstractAction() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- addOKPressed = false;
- dispose();
+ TextField newDescription = new TextField();
+ VBox container = new VBox(10,
+ new VBox(5, new Label(Localization.lang("Description")), newDescription),
+ new VBox(5, new Label(Localization.lang("File")), new HBox(10, newFile, browse))
+ );
+ getDialogPane().setContent(container);
+
+ getDialogPane().getButtonTypes().setAll(
+ ButtonType.OK,
+ ButtonType.CANCEL
+ );
+
+ setResultConverter(button -> {
+ if (button == ButtonType.OK) {
+ termsLoader.addNewProtectedTermsList(newDescription.getText(), newFile.getText(), true);
}
- };
- addCancelButton.addActionListener(cancelAction);
-
- // Key bindings:
- bb.getPanel().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
- .put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE), "close");
- bb.getPanel().getActionMap().put("close", cancelAction);
- pack();
- }
-
- public boolean isOKPressed() {
- return addOKPressed;
+ return null;
+ });
}
-
}
diff --git a/src/main/java/org/jabref/gui/protectedterms/ProtectedTermsDialog.java b/src/main/java/org/jabref/gui/protectedterms/ProtectedTermsDialog.java
deleted file mode 100644
index cef0db50b0d..00000000000
--- a/src/main/java/org/jabref/gui/protectedterms/ProtectedTermsDialog.java
+++ /dev/null
@@ -1,489 +0,0 @@
-package org.jabref.gui.protectedterms;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Objects;
-import java.util.Optional;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.ActionMap;
-import javax.swing.BorderFactory;
-import javax.swing.InputMap;
-import javax.swing.JButton;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JComponent;
-import javax.swing.JDialog;
-import javax.swing.JFrame;
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import javax.swing.KeyStroke;
-import javax.swing.ListSelectionModel;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import javax.swing.table.DefaultTableModel;
-import javax.swing.table.TableColumnModel;
-
-import org.jabref.Globals;
-import org.jabref.gui.JabRefDialog;
-import org.jabref.gui.JabRefFrame;
-import org.jabref.gui.desktop.JabRefDesktop;
-import org.jabref.gui.externalfiletype.ExternalFileType;
-import org.jabref.gui.externalfiletype.ExternalFileTypes;
-import org.jabref.gui.icon.IconTheme;
-import org.jabref.gui.keyboard.KeyBinding;
-import org.jabref.gui.util.DefaultTaskExecutor;
-import org.jabref.gui.util.FileDialogConfiguration;
-import org.jabref.gui.util.WindowLocation;
-import org.jabref.logic.l10n.Localization;
-import org.jabref.logic.protectedterms.ProtectedTermsList;
-import org.jabref.logic.protectedterms.ProtectedTermsLoader;
-import org.jabref.logic.util.StandardFileType;
-import org.jabref.model.database.BibDatabaseContext;
-import org.jabref.preferences.JabRefPreferences;
-
-import com.jgoodies.forms.builder.ButtonBarBuilder;
-import com.jgoodies.forms.builder.FormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class produces a dialog box for managing term list files.
- */
-public class ProtectedTermsDialog {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ProtectedTermsDialog.class);
-
- private final JabRefFrame frame;
- private JDialog diag;
- private JTable table;
- private DefaultTableModel tableModel;
- private final JPopupMenu popup = new JPopupMenu();
- private final JMenuItem edit = new JMenuItem(Localization.lang("Edit"));
- private final JMenuItem show = new JMenuItem(Localization.lang("View"));
- private final JMenuItem remove = new JMenuItem(Localization.lang("Remove"));
- private final JMenuItem reload = new JMenuItem(Localization.lang("Reload"));
- private final JMenuItem enabled = new JCheckBoxMenuItem(Localization.lang("Enabled"));
- private final JButton loadButton = new JButton(IconTheme.JabRefIcons.OPEN.getIcon());
- private final JButton removeButton = new JButton(IconTheme.JabRefIcons.DELETE_ENTRY.getIcon());
- private final JButton newButton = new JButton(IconTheme.JabRefIcons.NEW.getIcon());
- private ActionListener removeAction;
-
- private final JButton ok = new JButton(Localization.lang("OK"));
- private final JButton cancel = new JButton(Localization.lang("Cancel"));
-
- private boolean okPressed;
- private final ProtectedTermsLoader loader;
-
- public ProtectedTermsDialog(JabRefFrame frame) {
-
- this.frame = Objects.requireNonNull(frame);
- this.loader = Globals.protectedTermsLoader;
- init();
-
- }
-
- private void init() {
- setupPopupMenu();
-
- loadButton.addActionListener(actionEvent -> {
- AddFileDialog addDialog = new AddFileDialog();
- addDialog.setVisible(true);
- addDialog.getFileName().ifPresent(fileName -> loader.addProtectedTermsListFromFile(fileName, true));
- tableModel.fireTableDataChanged();
- });
- loadButton.setToolTipText(Localization.lang("Add protected terms file"));
-
- removeButton.addActionListener(removeAction);
- removeButton.setToolTipText(Localization.lang("Remove protected terms file"));
-
- newButton.addActionListener(actionEvent -> {
- NewProtectedTermsFileDialog newDialog = new NewProtectedTermsFileDialog(diag, loader, frame.getDialogService());
- newDialog.setVisible(true);
- tableModel.fireTableDataChanged();
- });
- newButton.setToolTipText(Localization.lang("New protected terms file"));
-
- setupTable();
-
- // Build dialog
- diag = new JDialog((JFrame) null, Localization.lang("Manage protected terms files"), true);
-
- FormBuilder builder = FormBuilder.create();
- builder.layout(new FormLayout("fill:pref:grow, 4dlu, left:pref, 4dlu, left:pref, 4dlu, left:pref",
- "100dlu:grow, 4dlu, pref"));
- builder.add(new JScrollPane(table)).xyw(1, 1, 7);
- builder.add(newButton).xy(3, 3);
- builder.add(loadButton).xy(5, 3);
- builder.add(removeButton).xy(7, 3);
- builder.padding("5dlu, 5dlu, 5dlu, 5dlu");
-
- diag.add(builder.getPanel(), BorderLayout.CENTER);
-
- AbstractAction okListener = new AbstractAction() {
-
- @Override
- public void actionPerformed(ActionEvent event) {
- // Write changes to preferences
- storePreferences();
- diag.dispose();
- }
- };
- ok.addActionListener(okListener);
-
- Action cancelListener = new AbstractAction() {
-
- @Override
- public void actionPerformed(ActionEvent event) {
- // Restore from preferences
- loader.update(Globals.prefs.getProtectedTermsPreferences());
- diag.dispose();
- }
- };
- cancel.addActionListener(cancelListener);
-
- ButtonBarBuilder bb = new ButtonBarBuilder();
- bb.addGlue();
- bb.addButton(ok);
- bb.addButton(cancel);
- bb.addGlue();
- bb.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
- diag.add(bb.getPanel(), BorderLayout.SOUTH);
-
- ActionMap am = bb.getPanel().getActionMap();
- InputMap im = bb.getPanel().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
- im.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE), "close");
- am.put("close", cancelListener);
- im.put(KeyStroke.getKeyStroke("ENTER"), "enterOk");
- am.put("enterOk", okListener);
-
- diag.pack();
-
- WindowLocation pw = new WindowLocation(diag, JabRefPreferences.TERMS_POS_X, JabRefPreferences.TERMS_POS_Y,
- JabRefPreferences.TERMS_SIZE_X, JabRefPreferences.TERMS_SIZE_Y);
- pw.displayWindowAtStoredLocation();
- }
-
- private void setupTable() {
- tableModel = new TermTableModel();
- table = new JTable(tableModel);
- TableColumnModel cm = table.getColumnModel();
- cm.getColumn(0).setMinWidth((cm.getColumn(0).getPreferredWidth() * 11) / 10);
- cm.getColumn(0).setMaxWidth((cm.getColumn(0).getPreferredWidth() * 11) / 10);
- cm.getColumn(1).setPreferredWidth(100);
- cm.getColumn(2).setPreferredWidth(100);
-
- table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- table.addMouseListener(new MouseAdapter() {
-
- @Override
- public void mousePressed(MouseEvent mouseEvent) {
- if (mouseEvent.isPopupTrigger()) {
- tablePopup(mouseEvent);
- }
- }
-
- @Override
- public void mouseReleased(MouseEvent mouseEvent) {
- if (mouseEvent.isPopupTrigger()) {
- tablePopup(mouseEvent);
- }
- }
-
- @Override
- public void mouseClicked(MouseEvent mouseEvent) {
- if (mouseEvent.getClickCount() == 2) {
- getSelectedTermsList().ifPresent(list -> list.setEnabled(!list.isEnabled()));
- tableModel.fireTableDataChanged();
- }
- }
- });
-
- table.getSelectionModel().addListSelectionListener(new EntrySelectionListener());
- }
-
- private void setupPopupMenu() {
- popup.add(edit);
- popup.add(show);
- popup.add(remove);
- popup.add(reload);
- popup.addSeparator();
- popup.add(enabled);
-
- // Add action listener to "Edit" menu item, which is supposed to open the term file in an external editor:
- edit.addActionListener(actionEvent -> getSelectedTermsList().ifPresent(term -> {
- Optional type = ExternalFileTypes.getInstance().getExternalFileTypeByExt("terms");
- String fileName = term.getLocation();
- try {
- if (type.isPresent()) {
- JabRefDesktop.openExternalFileAnyFormat(new BibDatabaseContext(), fileName, type);
- } else {
- // Fall back to ".txt"
- Optional txtType = ExternalFileTypes.getInstance()
- .getExternalFileTypeByExt("txt");
- JabRefDesktop.openExternalFileAnyFormat(new BibDatabaseContext(), fileName, type);
-
- }
- } catch (IOException e) {
- LOGGER.warn("Problem open protected terms file editor", e);
- }
- }));
-
- // Add action listener to "Show" menu item, which is supposed to open the term file in a dialog:
- show.addActionListener(actionEvent -> getSelectedTermsList().ifPresent(this::displayTerms));
-
- // Create action listener for removing a term file, also used for the remove button
- removeAction = actionEvent -> getSelectedTermsList().ifPresent(list -> {
-
- if (!list.isInternalList() && frame.getDialogService().showConfirmationDialogAndWait(Localization.lang("Remove protected terms file"),
- Localization.lang("Are you sure you want to remove the protected terms file?"),
- Localization.lang("Remove protected terms file"),
- Localization.lang("Cancel"))) {
- if (!loader.removeProtectedTermsList(list)) {
- LOGGER.info("Problem removing protected terms file");
- }
- tableModel.fireTableDataChanged();
- }
- });
- // Add it to the remove menu item
- remove.addActionListener(removeAction);
-
- // Add action listener to the "Reload" menu item, which is supposed to reload an external term file
- reload.addActionListener(actionEvent -> {
- getSelectedTermsList().ifPresent(loader::reloadProtectedTermsList);
- });
-
- enabled.addActionListener(actionEvent -> getSelectedTermsList().ifPresent(list -> {
- list.setEnabled(enabled.isSelected());
- }));
-
- }
-
- public void setVisible(boolean visible) {
- okPressed = false;
- diag.setVisible(visible);
- }
-
- /**
- * Get the currently selected term list.
- * @return the selected term list, or empty if no term list is selected.
- */
- private Optional getSelectedTermsList() {
- if (table.getSelectedRow() != -1) {
- return Optional.of(loader.getProtectedTermsLists().get(table.getSelectedRow()));
- }
- return Optional.empty();
- }
-
- class TermTableModel extends DefaultTableModel {
-
- @Override
- public int getColumnCount() {
- return 3;
- }
-
- @Override
- public int getRowCount() {
- return loader.getProtectedTermsLists().size();
- }
-
- @Override
- public String getColumnName(int i) {
- switch (i) {
- case 0:
- return Localization.lang("Enabled");
- case 1:
- return Localization.lang("Description");
- case 2:
- return Localization.lang("File");
- default:
- return "";
- }
- }
-
- @Override
- public Object getValueAt(int row, int column) {
- switch (column) {
- case 0:
- return loader.getProtectedTermsLists().get(row).isEnabled();
- case 1:
- return loader.getProtectedTermsLists().get(row).getDescription();
- case 2:
- ProtectedTermsList list = loader.getProtectedTermsLists().get(row);
- return list.isInternalList() ? Localization.lang("Internal list") + " - " + list.getLocation() : list
- .getLocation();
- default:
- return "";
- }
- }
-
- @Override
- public boolean isCellEditable(int row, int column) {
- return column == 0;
- }
-
- @Override
- public Class> getColumnClass(int column) {
- switch (column) {
- case 0:
- return Boolean.class;
- case 1:
- return String.class;
- case 2:
- return String.class;
- default:
- return String.class;
- }
- }
-
- @Override
- public void setValueAt(Object cell, int row, int column) {
- if (column == 0) {
- ProtectedTermsList list = loader.getProtectedTermsLists().get(row);
- list.setEnabled(!list.isEnabled());
- this.fireTableCellUpdated(row, column);
- }
- }
-
- }
-
- public boolean isOkPressed() {
- return okPressed;
- }
-
- private void tablePopup(MouseEvent e) {
- popup.show(e.getComponent(), e.getX(), e.getY());
- }
-
- private void displayTerms(ProtectedTermsList list) {
- // Make a dialog box to display the contents:
- final JDialog dd = new JDialog(diag, list.getDescription() + " - " + list.getLocation(), true);
-
- JTextArea ta = new JTextArea(list.getTermListing());
- ta.setEditable(false);
- JScrollPane sp = new JScrollPane(ta);
- sp.setPreferredSize(new Dimension(700, 500));
- dd.getContentPane().add(sp, BorderLayout.CENTER);
- JButton okButton = new JButton(Localization.lang("OK"));
- ButtonBarBuilder bb = new ButtonBarBuilder();
- bb.addGlue();
- bb.addButton(okButton);
- bb.addGlue();
- bb.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
- dd.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH);
- okButton.addActionListener(actionEvent -> dd.dispose());
- dd.pack();
- dd.setLocationRelativeTo(diag);
- dd.setVisible(true);
- }
-
- /**
- * The listener for the table monitoring the current selection.
- */
- private class EntrySelectionListener implements ListSelectionListener {
-
- @Override
- public void valueChanged(ListSelectionEvent listEvent) {
- getSelectedTermsList().ifPresent(list -> {
- // Enable/disable popup menu items and buttons
- if (list.isInternalList()) {
- remove.setEnabled(false);
- edit.setEnabled(false);
- reload.setEnabled(false);
- removeButton.setEnabled(false);
- } else {
- remove.setEnabled(true);
- edit.setEnabled(true);
- reload.setEnabled(true);
- removeButton.setEnabled(true);
- }
- enabled.setSelected(list.isEnabled());
- });
- }
- }
-
- private class AddFileDialog extends JabRefDialog {
-
- private final JTextField newFile = new JTextField();
- private boolean addOKPressed;
-
- public AddFileDialog() {
- super(diag, Localization.lang("Add protected terms file"), true, AddFileDialog.class);
-
- JButton browse = new JButton(Localization.lang("Browse"));
- FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
- .addExtensionFilter(Localization.lang("Protected terms file"), StandardFileType.TERMS)
- .withDefaultExtension(Localization.lang("Protected terms file"), StandardFileType.TERMS)
- .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build();
-
- browse.addActionListener(e -> {
- Optional file = DefaultTaskExecutor.runInJavaFXThread(() -> frame.getDialogService().showFileOpenDialog(fileDialogConfiguration));
- file.ifPresent(f -> newFile.setText(f.toAbsolutePath().toString()));
- });
-
- // Build content panel
- FormBuilder builder = FormBuilder.create();
- builder.layout(new FormLayout("left:pref, 4dlu, fill:100dlu:grow, 4dlu, pref", "p"));
- builder.add(Localization.lang("File")).xy(1, 1);
- builder.add(newFile).xy(3, 1);
- builder.add(browse).xy(5, 1);
- builder.padding("10dlu, 10dlu, 10dlu, 10dlu");
- getContentPane().add(builder.build(), BorderLayout.CENTER);
-
- // Buttons
- ButtonBarBuilder bb = new ButtonBarBuilder();
- JButton addOKButton = new JButton(Localization.lang("OK"));
- JButton addCancelButton = new JButton(Localization.lang("Cancel"));
- bb.addGlue();
- bb.addButton(addOKButton);
- bb.addButton(addCancelButton);
- bb.addGlue();
- bb.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
- getContentPane().add(bb.getPanel(), BorderLayout.SOUTH);
- addOKButton.addActionListener(e -> {
- addOKPressed = true;
- dispose();
- });
-
- Action cancelAction = new AbstractAction() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- addOKPressed = false;
- dispose();
- }
- };
- addCancelButton.addActionListener(cancelAction);
-
- // Key bindings:
- bb.getPanel().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
- .put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE), "close");
- bb.getPanel().getActionMap().put("close", cancelAction);
- pack();
- setLocationRelativeTo(diag);
- }
-
- public Optional getFileName() {
- if (addOKPressed && (newFile.getText() != null) && !newFile.getText().isEmpty()) {
- return Optional.of(newFile.getText());
- }
- return Optional.empty();
- }
-
- }
-
- private void storePreferences() {
- Globals.prefs.setProtectedTermsPreferences(loader);
- }
-}
diff --git a/src/main/java/org/jabref/gui/util/BindingsHelper.java b/src/main/java/org/jabref/gui/util/BindingsHelper.java
index 162fb210065..af0fafd441b 100644
--- a/src/main/java/org/jabref/gui/util/BindingsHelper.java
+++ b/src/main/java/org/jabref/gui/util/BindingsHelper.java
@@ -8,6 +8,7 @@
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
+import javafx.beans.binding.ObjectBinding;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.ListProperty;
import javafx.beans.property.Property;
@@ -148,7 +149,16 @@ public static void bindContentBidirectional(ObservableMap proper
updateB);
}
- public static ObservableValue extends Boolean> constantOf(boolean value) {
+ public static ObservableValue constantOf(T value) {
+ return new ObjectBinding() {
+ @Override
+ protected T computeValue() {
+ return value;
+ }
+ };
+ }
+
+ public static ObservableValue constantOf(boolean value) {
return new BooleanBinding() {
@Override
protected boolean computeValue() {
diff --git a/src/main/java/org/jabref/logic/citationstyle/CSLAdapter.java b/src/main/java/org/jabref/logic/citationstyle/CSLAdapter.java
index cda929568d2..0de338a1f0f 100644
--- a/src/main/java/org/jabref/logic/citationstyle/CSLAdapter.java
+++ b/src/main/java/org/jabref/logic/citationstyle/CSLAdapter.java
@@ -31,9 +31,9 @@
* same style. Changing the output format is cheap.
* @implNote The main function {@link #makeBibliography} will enforce
* synchronized calling. The main CSL engine under the hood is not thread-safe. Since this class is usually called from
- * a SwingWorker, the only other option would be to create several CSL instances which is wasting a lot of resources and very slow.
+ * a BackgroundTakk, the only other option would be to create several CSL instances which is wasting a lot of resources and very slow.
* In the current scheme, {@link #makeBibliography} can be called as usual
- * SwingWorker task and to the best of my knowledge, concurrent calls will pile up and processed sequentially.
+ * background task and to the best of my knowledge, concurrent calls will pile up and processed sequentially.
*/
public class CSLAdapter {
@@ -63,7 +63,7 @@ public synchronized List makeBibliography(List bibEntries, Str
* @throws IOException An error occurred in the underlying JavaScript framework
*/
private void initialize(String newStyle, CitationStyleOutputFormat newFormat) throws IOException {
- if (cslInstance == null || !Objects.equals(newStyle, style)) {
+ if ((cslInstance == null) || !Objects.equals(newStyle, style)) {
// lang and forceLang are set to the default values of other CSL constructors
cslInstance = new CSL(dataProvider, new JabRefLocaleProvider(), newStyle, "en-US", false);
style = newStyle;
@@ -81,7 +81,7 @@ private void initialize(String newStyle, CitationStyleOutputFormat newFormat) th
*/
private static class JabRefItemDataProvider implements ItemDataProvider {
- private ArrayList data = new ArrayList<>();
+ private final ArrayList data = new ArrayList<>();
/**
* Converts the {@link BibEntry} into {@link CSLItemData}.
diff --git a/src/main/java/org/jabref/logic/formatter/Formatters.java b/src/main/java/org/jabref/logic/formatter/Formatters.java
index 4e1d25f968f..9e867ac23ed 100644
--- a/src/main/java/org/jabref/logic/formatter/Formatters.java
+++ b/src/main/java/org/jabref/logic/formatter/Formatters.java
@@ -87,6 +87,12 @@ public static Optional getFormatterForModifier(String modifier) {
return Optional.of(new LowerCaseFormatter());
case "upper":
return Optional.of(new UpperCaseFormatter());
+ case "capitalize":
+ return Optional.of(new CapitalizeFormatter());
+ case "titlecase":
+ return Optional.of(new TitleCaseFormatter());
+ case "sentencecase":
+ return Optional.of(new SentenceCaseFormatter());
}
if (modifier.startsWith(RegexFormatter.KEY)) {
diff --git a/src/main/java/org/jabref/logic/msbib/MsBibAuthor.java b/src/main/java/org/jabref/logic/msbib/MsBibAuthor.java
index caad384ec22..8da1d4e49ca 100644
--- a/src/main/java/org/jabref/logic/msbib/MsBibAuthor.java
+++ b/src/main/java/org/jabref/logic/msbib/MsBibAuthor.java
@@ -48,7 +48,7 @@ public String getMiddleName() {
}
public String getLastName() {
- return author.getLast().orElse(null);
+ return author.getLastOnly();
}
public String getFirstLast() {
diff --git a/src/main/java/org/jabref/migrations/FileLinksUpgradeWarning.java b/src/main/java/org/jabref/migrations/FileLinksUpgradeWarning.java
deleted file mode 100644
index eed9497457e..00000000000
--- a/src/main/java/org/jabref/migrations/FileLinksUpgradeWarning.java
+++ /dev/null
@@ -1,256 +0,0 @@
-package org.jabref.migrations;
-
-import java.util.List;
-
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-import org.jabref.Globals;
-import org.jabref.gui.BasePanel;
-import org.jabref.gui.DialogService;
-import org.jabref.gui.FXDialogService;
-import org.jabref.gui.importer.actions.GUIPostOpenAction;
-import org.jabref.gui.undo.NamedCompound;
-import org.jabref.gui.undo.UndoableFieldChange;
-import org.jabref.gui.util.DefaultTaskExecutor;
-import org.jabref.gui.util.FileDialogConfiguration;
-import org.jabref.logic.cleanup.UpgradePdfPsToFileCleanup;
-import org.jabref.logic.importer.ParserResult;
-import org.jabref.logic.l10n.Localization;
-import org.jabref.model.FieldChange;
-import org.jabref.model.database.BibDatabase;
-import org.jabref.model.entry.BibEntry;
-import org.jabref.model.entry.FieldName;
-import org.jabref.model.metadata.FilePreferences;
-import org.jabref.preferences.JabRefPreferences;
-
-import com.jgoodies.forms.builder.FormBuilder;
-import com.jgoodies.forms.layout.FormLayout;
-
-/**
- * This class defines the warning that can be offered when opening a pre-2.3
- * JabRef file into a later version. This warning mentions the new external file
- * link system in this version of JabRef, and offers to:
- *
- * * upgrade old-style PDF/PS links into the "file" field
- * * modify General fields to show "file" instead of "pdf" / "ps"
- * * modify table column settings to show "file" instead of "pdf" / "ps"
- */
-public class FileLinksUpgradeWarning implements GUIPostOpenAction {
-
- private static final String[] FIELDS_TO_LOOK_FOR = new String[]{FieldName.PDF, FieldName.PS};
-
- private boolean offerChangeSettings;
-
- private boolean offerChangeDatabase;
-
- private boolean offerSetFileDir;
-
- /**
- * Collect file links from the given set of fields, and add them to the list contained in the field
- * GUIGlobals.FILE_FIELD.
- *
- * @param database The database to modify.
- * @return A CompoundEdit specifying the undo operation for the whole operation.
- */
- private static NamedCompound upgradePdfPsToFile(BibDatabase database) {
- NamedCompound ce = new NamedCompound(Localization.lang("Move external links to 'file' field"));
-
- UpgradePdfPsToFileCleanup cleanupJob = new UpgradePdfPsToFileCleanup();
- for (BibEntry entry : database.getEntries()) {
- List changes = cleanupJob.cleanup(entry);
-
- for (FieldChange change : changes) {
- ce.addEdit(new UndoableFieldChange(change));
- }
- }
-
- ce.end();
- return ce;
- }
-
- /**
- * This method should be performed if the major/minor versions recorded in the ParserResult
- * are less than or equal to 2.2.
- *
- * @return true if the file was written by a jabref version <=2.2
- */
- @Override
- public boolean isActionNecessary(ParserResult pr) {
- // Find out which actions should be offered:
- // Only offer to change Preferences if file column is not already visible:
- offerChangeSettings = !Globals.prefs.getBoolean(JabRefPreferences.FILE_COLUMN) || !showsFileInGenFields();
- // Only offer to upgrade links if the pdf/ps fields are used:
- offerChangeDatabase = linksFound(pr.getDatabase(), FileLinksUpgradeWarning.FIELDS_TO_LOOK_FOR);
- // If the "file" directory is not set, offer to migrate pdf/ps dir:
- offerSetFileDir = !Globals.prefs.hasKey(FieldName.FILE + FilePreferences.DIR_SUFFIX)
- && (Globals.prefs.hasKey(FieldName.PDF + FilePreferences.DIR_SUFFIX)
- || Globals.prefs.hasKey(FieldName.PS + FilePreferences.DIR_SUFFIX));
-
- // First check if this warning is disabled:
- return Globals.prefs.getBoolean(JabRefPreferences.SHOW_FILE_LINKS_UPGRADE_WARNING)
- && isThereSomethingToBeDone();
- }
-
- /*
- * This method presents a dialog box explaining and offering to make the
- * changes. If the user confirms, the changes are performed.
- */
- @Override
- public void performAction(BasePanel panel, ParserResult parserResult) {
-
- if (!isThereSomethingToBeDone()) {
- return; // Nothing to do, just return.
- }
-
- JCheckBox changeSettings = new JCheckBox(
- Localization.lang("Change table column and General fields settings to use the new feature"),
- offerChangeSettings);
- JCheckBox changeDatabase = new JCheckBox(
- Localization.lang("Upgrade old external file links to use the new feature"),
- offerChangeDatabase);
- JCheckBox setFileDir = new JCheckBox(Localization.lang("Set main external file directory") + ":",
- offerSetFileDir);
- JTextField fileDir = new JTextField(30);
- JCheckBox doNotShowDialog = new JCheckBox(Localization.lang("Do not show these options in the future"),
- false);
-
- JPanel message = new JPanel();
- FormBuilder formBuilder = FormBuilder.create().layout(new FormLayout("left:pref", "p"));
- // Keep the formatting of these lines. Otherwise, strings have to be translated again.
- // See updated JabRef_en.properties modifications by python syncLang.py -s -u
- int row = 1;
- formBuilder.add(new JLabel("" + Localization.lang("This library uses outdated file links.") + "
"
- + Localization
- .lang("JabRef no longer supports 'ps' or 'pdf' fields.
File links are now stored in the 'file' field and files are stored in an external file directory.
To make use of this feature, JabRef needs to upgrade file links.
")
- + ""
- + Localization.lang("Do you want JabRef to do the following operations?") + "")).xy(1, row);
-
- if (offerChangeSettings) {
- formBuilder.appendRows("2dlu, p");
- row += 2;
- formBuilder.add(changeSettings).xy(1, row);
- }
- if (offerChangeDatabase) {
- formBuilder.appendRows("2dlu, p");
- row += 2;
- formBuilder.add(changeDatabase).xy(1, row);
- }
- if (offerSetFileDir) {
- if (Globals.prefs.hasKey(FieldName.PDF + FilePreferences.DIR_SUFFIX)) {
- fileDir.setText(Globals.prefs.get(FieldName.PDF + FilePreferences.DIR_SUFFIX));
- } else {
- fileDir.setText(Globals.prefs.get(FieldName.PS + FilePreferences.DIR_SUFFIX));
- }
- JPanel builderPanel = new JPanel();
- builderPanel.add(setFileDir);
- builderPanel.add(fileDir);
- JButton browse = new JButton(Localization.lang("Browse"));
-
- FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
- .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build();
- DialogService ds = new FXDialogService();
-
- browse.addActionListener(
- e -> DefaultTaskExecutor.runInJavaFXThread(() -> ds.showFileOpenDialog(fileDialogConfiguration)
- .ifPresent(f -> fileDir.setText(f.toAbsolutePath().toString()))));
- builderPanel.add(browse);
- formBuilder.appendRows("2dlu, p");
- row += 2;
- formBuilder.add(builderPanel).xy(1, row);
- }
- formBuilder.appendRows("6dlu, p");
- formBuilder.add(doNotShowDialog).xy(1, row + 2);
-
- message.add(formBuilder.build());
-
- int answer = JOptionPane.showConfirmDialog(null,
- message, Localization.lang("Upgrade file"), JOptionPane.YES_NO_OPTION);
- if (doNotShowDialog.isSelected()) {
- Globals.prefs.putBoolean(JabRefPreferences.SHOW_FILE_LINKS_UPGRADE_WARNING, false);
- }
-
- if (answer == JOptionPane.YES_OPTION) {
- makeChanges(panel, parserResult, changeSettings.isSelected(), changeDatabase.isSelected(),
- setFileDir.isSelected() ? fileDir.getText() : null);
- }
- }
-
- private boolean isThereSomethingToBeDone() {
- return offerChangeSettings || offerChangeDatabase || offerSetFileDir;
- }
-
- /**
- * Check the database to find out whether any of a set of fields are used
- * for any of the entries.
- *
- * @param database The BIB database.
- * @param fields The set of fields to look for.
- * @return true if at least one of the given fields is set in at least one entry,
- * false otherwise.
- */
- private boolean linksFound(BibDatabase database, String[] fields) {
- for (BibEntry entry : database.getEntries()) {
- for (String field : fields) {
- if (entry.hasField(field)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * This method performs the actual changes.
- *
- * @param fileDir The path to the file directory to set, or null if it should not be set.
- */
- private void makeChanges(BasePanel panel, ParserResult pr, boolean upgradePrefs,
- boolean upgradeDatabase, String fileDir) {
-
- if (upgradeDatabase) {
- // Update file links links in the database:
- NamedCompound ce = upgradePdfPsToFile(pr.getDatabase());
- panel.getUndoManager().addEdit(ce);
- panel.markBaseChanged();
- }
-
- if (fileDir != null) {
- Globals.prefs.put(FieldName.FILE + FilePreferences.DIR_SUFFIX, fileDir);
- }
-
- if (upgradePrefs) {
- // Exchange table columns:
- Globals.prefs.putBoolean(JabRefPreferences.FILE_COLUMN, Boolean.TRUE);
-
- // Modify General fields if necessary:
- // If we don't find the file field, insert it at the bottom of the first tab:
- if (!showsFileInGenFields()) {
- String gfs = Globals.prefs.get(JabRefPreferences.CUSTOM_TAB_FIELDS + "0");
- StringBuilder sb = new StringBuilder(gfs);
- if (!gfs.isEmpty()) {
- sb.append(';');
- }
- sb.append(FieldName.FILE);
- Globals.prefs.put(JabRefPreferences.CUSTOM_TAB_FIELDS + "0", sb.toString());
- Globals.prefs.updateEntryEditorTabList();
- }
- panel.frame().setupAllTables();
- }
- }
-
- private boolean showsFileInGenFields() {
- for (List fields : Globals.prefs.getEntryEditorTabList().values()) {
- for (String field : fields) {
- if (field.equals(FieldName.FILE)) {
- return true;
- }
- }
- }
- return false;
- }
-}
diff --git a/src/main/java/org/jabref/model/entry/KeywordList.java b/src/main/java/org/jabref/model/entry/KeywordList.java
index 2e13ce4c63f..aad112c7e87 100644
--- a/src/main/java/org/jabref/model/entry/KeywordList.java
+++ b/src/main/java/org/jabref/model/entry/KeywordList.java
@@ -137,6 +137,10 @@ public boolean contains(Keyword o) {
return keywordChains.contains(o);
}
+ public boolean contains(String keywordString) {
+ return contains(new Keyword(keywordString));
+ }
+
public boolean remove(Keyword o) {
return keywordChains.remove(o);
}
diff --git a/src/main/java/org/jabref/model/util/OptionalUtil.java b/src/main/java/org/jabref/model/util/OptionalUtil.java
index 525477f415e..6d127c4e5ce 100644
--- a/src/main/java/org/jabref/model/util/OptionalUtil.java
+++ b/src/main/java/org/jabref/model/util/OptionalUtil.java
@@ -59,4 +59,12 @@ public static Optional combine(Optional valueOne, Optional va
return Optional.empty();
}
}
+
+ public static Optional orElse(Optional valueOne, Optional valueTwo) {
+ if (valueOne.isPresent()) {
+ return valueOne;
+ } else {
+ return valueTwo;
+ }
+ }
}
diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java
index c3070474954..a5aaf265c09 100644
--- a/src/main/java/org/jabref/preferences/JabRefPreferences.java
+++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java
@@ -183,10 +183,6 @@ public class JabRefPreferences implements PreferencesService {
public static final String PREAMBLE_SIZE_X = "preambleSizeX";
public static final String PREAMBLE_POS_Y = "preamblePosY";
public static final String PREAMBLE_POS_X = "preamblePosX";
- public static final String TERMS_SIZE_Y = "termsSizeY";
- public static final String TERMS_SIZE_X = "termsSizeX";
- public static final String TERMS_POS_Y = "termsPosY";
- public static final String TERMS_POS_X = "termsPosX";
public static final String SEARCH_DIALOG_HEIGHT = "searchDialogHeight";
public static final String SEARCH_DIALOG_WIDTH = "searchDialogWidth";
public static final String IMPORT_INSPECTION_DIALOG_HEIGHT = "importInspectionDialogHeight";
@@ -563,10 +559,6 @@ private JabRefPreferences() {
defaults.put(PREAMBLE_POS_Y, 0);
defaults.put(PREAMBLE_SIZE_X, 600);
defaults.put(PREAMBLE_SIZE_Y, 400);
- defaults.put(TERMS_POS_X, 0);
- defaults.put(TERMS_POS_Y, 0);
- defaults.put(TERMS_SIZE_X, 500);
- defaults.put(TERMS_SIZE_Y, 500);
defaults.put(DEFAULT_SHOW_SOURCE, Boolean.FALSE);
defaults.put(DEFAULT_AUTO_SORT, Boolean.FALSE);
@@ -1455,9 +1447,10 @@ public FieldContentParserPreferences getFieldContentParserPreferences() {
return new FieldContentParserPreferences(getStringList(NON_WRAPPABLE_FIELDS));
}
+ @Override
public boolean isKeywordSyncEnabled() {
return getBoolean(JabRefPreferences.SPECIALFIELDSENABLED)
- && getBoolean(JabRefPreferences.AUTOSYNCSPECIALFIELDSTOKEYWORDS);
+ && getBoolean(JabRefPreferences.AUTOSYNCSPECIALFIELDSTOKEYWORDS);
}
public ImportFormatPreferences getImportFormatPreferences() {
@@ -1631,6 +1624,7 @@ public ProtectedTermsPreferences getProtectedTermsPreferences() {
getStringList(PROTECTED_TERMS_DISABLED_EXTERNAL));
}
+ @Override
public void setProtectedTermsPreferences(ProtectedTermsLoader loader) {
List enabledExternalList = new ArrayList<>();
List disabledExternalList = new ArrayList<>();
@@ -1657,7 +1651,6 @@ public void setProtectedTermsPreferences(ProtectedTermsLoader loader) {
putStringList(PROTECTED_TERMS_DISABLED_EXTERNAL, disabledExternalList);
putStringList(PROTECTED_TERMS_ENABLED_INTERNAL, enabledInternalList);
putStringList(PROTECTED_TERMS_DISABLED_INTERNAL, disabledInternalList);
-
}
@Override
@@ -1733,6 +1726,7 @@ public SaveOrderConfig loadExportSaveOrder() {
);
}
+ @Override
public Character getKeywordDelimiter() {
return get(KEYWORD_SEPARATOR).charAt(0);
}
diff --git a/src/main/java/org/jabref/preferences/PreferencesService.java b/src/main/java/org/jabref/preferences/PreferencesService.java
index 47ec943c9c4..21550d547cb 100644
--- a/src/main/java/org/jabref/preferences/PreferencesService.java
+++ b/src/main/java/org/jabref/preferences/PreferencesService.java
@@ -11,12 +11,17 @@
import org.jabref.logic.journals.JournalAbbreviationPreferences;
import org.jabref.logic.layout.LayoutFormatterPreferences;
import org.jabref.logic.openoffice.OpenOfficePreferences;
+import org.jabref.logic.protectedterms.ProtectedTermsLoader;
import org.jabref.model.metadata.FilePreferences;
public interface PreferencesService {
+ void setProtectedTermsPreferences(ProtectedTermsLoader loader);
+
JournalAbbreviationPreferences getJournalAbbreviationPreferences();
+ Character getKeywordDelimiter();
+
void storeKeyBindingRepository(KeyBindingRepository keyBindingRepository);
KeyBindingRepository getKeyBindingRepository();
@@ -53,6 +58,8 @@ public interface PreferencesService {
LayoutFormatterPreferences getLayoutFormatterPreferences(JournalAbbreviationLoader loader);
+ boolean isKeywordSyncEnabled();
+
SavePreferences loadForExportFromPreferences();
String getExportWorkingDirectory();
diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties
index e38d7c151da..b7f8e0dd5ea 100644
--- a/src/main/resources/l10n/JabRef_en.properties
+++ b/src/main/resources/l10n/JabRef_en.properties
@@ -137,8 +137,6 @@ Change\ of\ Grouping\ Method=Change of Grouping Method
change\ preamble=change preamble
-Change\ table\ column\ and\ General\ fields\ settings\ to\ use\ the\ new\ feature=Change table column and General fields settings to use the new feature
-
Changed\ language\ settings=Changed language settings
Changed\ preamble=Changed preamble
@@ -283,13 +281,10 @@ Do\ not\ import\ entry=Do not import entry
Do\ not\ open\ any\ files\ at\ startup=Do not open any files at startup
Do\ not\ overwrite\ existing\ keys=Do not overwrite existing keys
-Do\ not\ show\ these\ options\ in\ the\ future=Do not show these options in the future
Do\ not\ wrap\ the\ following\ fields\ when\ saving=Do not wrap the following fields when saving
Do\ not\ write\ the\ following\ fields\ to\ XMP\ Metadata\:=Do not write the following fields to XMP Metadata:
-Do\ you\ want\ JabRef\ to\ do\ the\ following\ operations?=Do you want JabRef to do the following operations?
-
Donate\ to\ JabRef=Donate to JabRef
Down=Down
@@ -439,8 +434,6 @@ Formatter\ name=Formatter name
found\ in\ AUX\ file=found in AUX file
-Full\ name=Full name
-
Further\ information\ about\ Mr\ DLib.\ for\ JabRef\ users.=Further information about Mr DLib. for JabRef users.
General=General
@@ -558,10 +551,6 @@ JabRef\ preferences=JabRef preferences
JabRef\ requests\ recommendations\ from\ Mr.\ DLib,\ which\ is\ an\ external\ service.\ To\ enable\ Mr.\ DLib\ to\ calculate\ recommendations,\ some\ of\ your\ data\ must\ be\ shared\ with\ Mr.\ DLib.\ Generally,\ the\ more\ data\ is\ shared\ the\ better\ recommendations\ can\ be\ calculated.\ However,\ we\ understand\ that\ some\ of\ your\ data\ in\ JabRef\ is\ sensitive,\ and\ you\ may\ not\ want\ to\ share\ it.\ Therefore,\ Mr.\ DLib\ offers\ a\ choice\ of\ which\ data\ you\ would\ like\ to\ share.=JabRef requests recommendations from Mr. DLib, which is an external service. To enable Mr. DLib to calculate recommendations, some of your data must be shared with Mr. DLib. Generally, the more data is shared the better recommendations can be calculated. However, we understand that some of your data in JabRef is sensitive, and you may not want to share it. Therefore, Mr. DLib offers a choice of which data you would like to share.
JabRef\ Version\ (Required\ to\ ensure\ backwards\ compatibility\ with\ Mr.\ DLib's\ Web\ Service)=JabRef Version (Required to ensure backwards compatibility with Mr. DLib's Web Service)
-Join=Join
-
-Joins\ selected\ keywords\ and\ deletes\ selected\ keywords.=Joins selected keywords and deletes selected keywords.
-
Journal\ abbreviations=Journal abbreviations
Keep=Keep
@@ -623,8 +612,6 @@ Modify=Modify
Move\ down=Move down
-Move\ external\ links\ to\ 'file'\ field=Move external links to 'file' field
-
move\ group=move group
Move\ up=Move up
@@ -637,9 +624,6 @@ Name\ formatter=Name formatter
Natbib\ style=Natbib style
nested\ AUX\ files=nested AUX files
-
-New=New
-
new=new
New\ BibTeX\ sublibrary=New BibTeX sublibrary
@@ -925,8 +909,6 @@ Set\ fields=Set fields
Set\ General\ Fields=Set General Fields
-Set\ main\ external\ file\ directory=Set main external file directory
-
Settings=Settings
Shortcut=Shortcut
@@ -1069,8 +1051,6 @@ untitled=untitled
Up=Up
Upgrade\ external\ PDF/PS\ links\ to\ use\ the\ '%0'\ field.=Upgrade external PDF/PS links to use the '%0' field.
-Upgrade\ file=Upgrade file
-Upgrade\ old\ external\ file\ links\ to\ use\ the\ new\ feature=Upgrade old external file links to use the new feature
usage=usage
Use\ autocompletion\ for\ the\ following\ fields=Use autocompletion for the following fields
@@ -1167,7 +1147,6 @@ No\ full\ text\ document\ found=No full text document found
Update\ to\ current\ column\ order=Update to current column order
Download\ from\ URL=Download from URL
Rename\ field=Rename field
-Set/clear/append/rename\ fields=Set/clear/append/rename fields
Append\ field=Append field
Append\ to\ fields=Append to fields
Rename\ field\ to=Rename field to
@@ -1300,7 +1279,6 @@ No\ valid\ style\ file\ defined=No valid style file defined
Choose\ pattern=Choose pattern
Use\ the\ BIB\ file\ location\ as\ primary\ file\ directory=Use the BIB file location as primary file directory
Could\ not\ run\ the\ gnuclient/emacsclient\ program.\ Make\ sure\ you\ have\ the\ emacsclient/gnuclient\ program\ installed\ and\ available\ in\ the\ PATH.=Could not run the gnuclient/emacsclient program. Make sure you have the emacsclient/gnuclient program installed and available in the PATH.
-OpenOffice/LibreOffice\ connection=OpenOffice/LibreOffice connection
You\ must\ select\ either\ a\ valid\ style\ file,\ or\ use\ one\ of\ the\ default\ styles.=You must select either a valid style file, or use one of the default styles.
This\ is\ a\ simple\ copy\ and\ paste\ dialog.\ First\ load\ or\ paste\ some\ text\ into\ the\ text\ input\ area.
After\ that,\ you\ can\ mark\ text\ and\ assign\ it\ to\ a\ BibTeX\ field.=This is a simple copy and paste dialog. First load or paste some text into the text input area.
After that, you can mark text and assign it to a BibTeX field.
@@ -1450,7 +1428,6 @@ Rebind\ C-a,\ too=Rebind C-a, too
Rebind\ C-f,\ too=Rebind C-f, too
Open\ folder=Open folder
-Searches\ for\ unlinked\ PDF\ files\ on\ the\ file\ system=Searches for unlinked PDF files on the file system
Export\ entries\ ordered\ as\ specified=Export entries ordered as specified
Export\ sort\ order=Export sort order
Export\ sorting=Export sorting
@@ -1563,8 +1540,6 @@ This\ search\ contains\ entries\ in\ which\ any\ field\ contains\ the\ term\
This\ search\ contains\ entries\ in\ which=This search contains entries in which
Unable\ to\ autodetect\ OpenOffice/LibreOffice\ installation.\ Please\ choose\ the\ installation\ directory\ manually.=Unable to autodetect OpenOffice/LibreOffice installation. Please choose the installation directory manually.
-JabRef\ no\ longer\ supports\ 'ps'\ or\ 'pdf'\ fields.
File\ links\ are\ now\ stored\ in\ the\ 'file'\ field\ and\ files\ are\ stored\ in\ an\ external\ file\ directory.
To\ make\ use\ of\ this\ feature,\ JabRef\ needs\ to\ upgrade\ file\ links.
=JabRef no longer supports 'ps' or 'pdf' fields.
File links are now stored in the 'file' field and files are stored in an external file directory.
To make use of this feature, JabRef needs to upgrade file links.
-This\ library\ uses\ outdated\ file\ links.=This library uses outdated file links.
Close\ library=Close library
Decrease\ table\ font\ size=Decrease table font size
@@ -2010,7 +1985,6 @@ Next\ page=Next page
Document\ viewer=Document viewer
Live=Live
Locked=Locked
-Show\ document\ viewer=Show document viewer
Show\ the\ document\ of\ the\ currently\ selected\ entry.=Show the document of the currently selected entry.
Show\ this\ document\ until\ unlocked.=Show this document until unlocked.
Set\ current\ user\ name\ as\ owner.=Set current user name as owner.
@@ -2067,8 +2041,6 @@ No\ linked\ files\ found\ for\ export.=No linked files found for export.
No\ full\ text\ document\ found\ for\ entry\ %0.=No full text document found for entry %0.
Delete\ Entry=Delete Entry
-Import\ &\ Export=Import & Export
-Look\ up\ document\ identifier=Look up document identifier
Next\ library=Next library
Previous\ library=Previous library
add\ group=add group
@@ -2108,8 +2080,6 @@ Toggle\ intersection=Toggle intersection
Toggle\ union=Toggle union
Jump\ to\ entry=Jump to entry
The\ group\ name\ contains\ the\ keyword\ separator\ "%0"\ and\ thus\ probably\ does\ not\ work\ as\ expected.=The group name contains the keyword separator "%0" and thus probably does not work as expected.
-Abbreviate\ journal\ names\ (ISO)=Abbreviate journal names (ISO)
-Abbreviate\ journal\ names\ (MEDLINE)=Abbreviate journal names (MEDLINE)
Blog=Blog
Check\ integrity=Check integrity
Cleanup\ URL\ link=Cleanup URL link
@@ -2184,3 +2154,19 @@ Keyword\:=Keyword:
Keyword\ \"%0\"\ already\ exists=Keyword "%0" already exists
Remove\ keyword=Remove keyword
Are\ you\ sure\ you\ want\ to\ remove\ keyword\:\ \"%0\"?=Are you sure you want to remove keyword: "%0"?
+
+Edit\ string\ constants=Edit string constants
+Export\ all\ entries=Export all entries
+Generate\ BibTeX\ keys=Generate BibTeX keys
+Groups\ interface=Groups interface
+Manage\ field\ names\ &\ content=Manage field names & content
+New\ library=New library
+Next\ citation\ style=Next citation style
+OpenOffice/LibreOffice=OpenOffice/LibreOffice
+Open\ document\ viewer=Open document viewer
+Open\ entry\ editor=Open entry editor
+Previous\ citation\ style=Previous citation style
+Search\ document\ identifier\ online=Search document identifier online
+Search\ for\ unlinked\ local\ files=Search for unlinked local files
+Search\ full\ text\ documents\ online=Search full text documents online
+Find\ and\ replace=Find and replace
\ No newline at end of file
diff --git a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGeneratorTest.java b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGeneratorTest.java
index 4ed5b5bb728..f09b091fb7e 100644
--- a/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGeneratorTest.java
+++ b/src/test/java/org/jabref/logic/bibtexkeypattern/BibtexKeyGeneratorTest.java
@@ -1007,4 +1007,58 @@ public void generateKeyWithTwoModifiers() throws Exception {
entry.setField("title", "The Interesting Title");
assertEquals("theinterestingtitle", BibtexKeyGenerator.generateKey(entry, "title:lower:(_)"));
}
+
+ @Test
+ public void generateKeyWithTitleCapitalizeModifier() throws Exception {
+ BibEntry entry = new BibEntry();
+ entry.setField("title", "the InTeresting title longer than THREE words");
+ assertEquals("TheInterestingTitleLongerThanThreeWords", BibtexKeyGenerator.generateKey(entry, "title:capitalize"));
+ }
+
+ @Test
+ public void generateKeyWithShortTitleCapitalizeModifier() throws Exception {
+ BibEntry entry = new BibEntry();
+ entry.setField("title", "the InTeresting title longer than THREE words");
+ assertEquals("InterestingTitleLonger", BibtexKeyGenerator.generateKey(entry, "shorttitle:capitalize"));
+ }
+
+ @Test
+ public void generateKeyWithTitleTitleCaseModifier() throws Exception {
+ BibEntry entry = new BibEntry();
+ entry.setField("title", "A title WITH some of The key words");
+ assertEquals("ATitlewithSomeoftheKeyWords", BibtexKeyGenerator.generateKey(entry, "title:titlecase"));
+ }
+
+ @Test
+ public void generateKeyWithShortTitleTitleCaseModifier() throws Exception {
+ BibEntry entry = new BibEntry();
+ entry.setField("title", "the InTeresting title longer than THREE words");
+ assertEquals("InterestingTitleLonger", BibtexKeyGenerator.generateKey(entry, "shorttitle:titlecase"));
+ }
+
+ @Test
+ public void generateKeyWithTitleSentenceCaseModifier() throws Exception {
+ BibEntry entry = new BibEntry();
+ entry.setField("title", "A title WITH some of The key words");
+ assertEquals("Atitlewithsomeofthekeywords", BibtexKeyGenerator.generateKey(entry, "title:sentencecase"));
+ }
+
+ @Test
+ public void generateKeyWithAuthUpperYearShortTitleCapitalizeModifier() throws Exception {
+ BibEntry entry = new BibEntry();
+ entry.setField("author", AUTHOR_STRING_FIRSTNAME_FULL_LASTNAME_FULL_COUNT_1);
+ entry.setField("year", "2019");
+ entry.setField("title", "the InTeresting title longer than THREE words");
+ assertEquals("NEWTON2019InterestingTitleLonger", BibtexKeyGenerator.generateKey(entry, "[auth:upper][year][shorttitle:capitalize]"));
+ }
+
+ @Test
+ public void generateKeyWithYearAuthUpperTitleSentenceCaseModifier() throws Exception {
+ BibEntry entry = new BibEntry();
+ entry.setField("author", AUTHOR_STRING_FIRSTNAME_FULL_LASTNAME_FULL_COUNT_3);
+ entry.setField("year", "2019");
+ entry.setField("title", "the InTeresting title longer than THREE words");
+ assertEquals("NewtonMaxwellEtAl_2019_TheInterestingTitleLongerThanThreeWords", BibtexKeyGenerator.generateKey(entry, "[authors2]_[year]_[title:capitalize]"));
+ }
+
}
diff --git a/src/test/java/org/jabref/logic/msbib/MsBibAuthorTest.java b/src/test/java/org/jabref/logic/msbib/MsBibAuthorTest.java
index cbb37c47408..8736b6542e1 100644
--- a/src/test/java/org/jabref/logic/msbib/MsBibAuthorTest.java
+++ b/src/test/java/org/jabref/logic/msbib/MsBibAuthorTest.java
@@ -44,4 +44,11 @@ public void testGetLastName() {
MsBibAuthor msBibAuthor = new MsBibAuthor(author);
assertEquals("Bach", msBibAuthor.getLastName());
}
+
+ @Test
+ public void testGetVonAndLastName() {
+ Author author = new Author("John", null, "von", "Neumann", null);
+ MsBibAuthor msBibAuthor = new MsBibAuthor(author);
+ assertEquals("von Neumann", msBibAuthor.getLastName());
+ }
}