From 97cd767a3b562b8469069b17c6da130e6a5bafad Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Tue, 31 Jul 2018 00:08:38 +0800 Subject: [PATCH 01/58] Convert swing dialog to JavaFx --- CHANGELOG.md | 9 +- src/main/java/org/jabref/JabRefGUI.java | 4 - .../org/jabref/cli/ArgumentProcessor.java | 61 ++-- src/main/java/org/jabref/gui/BasePanel.java | 8 +- .../jabref/gui/DuplicateResolverDialog.java | 3 +- .../java/org/jabref/gui/EntryTypeDialog.java | 28 +- .../jabref/gui/FindUnlinkedFilesDialog.java | 5 +- .../org/jabref/gui/GenFieldsCustomizer.java | 3 +- .../java/org/jabref/gui/JabRefDialog.java | 43 ++- src/main/java/org/jabref/gui/JabRefFrame.java | 11 +- src/main/java/org/jabref/gui/MergeDialog.java | 3 +- .../org/jabref/gui/ReplaceStringDialog.java | 3 +- .../jabref/gui/SaveOrderConfigDisplay.java | 128 +++++--- .../java/org/jabref/gui/SidePaneManager.java | 8 +- .../java/org/jabref/gui/StringDialog.java | 2 +- .../java/org/jabref/gui/actions/Actions.java | 2 - .../gui/actions/DatabasePropertiesAction.java | 2 +- .../gui/actions/FindUnlinkedFilesAction.java | 2 +- .../jabref/gui/actions/NewEntryAction.java | 20 +- .../gui/actions/NewSubLibraryAction.java | 24 +- .../jabref/gui/actions/WriteXMPAction.java | 8 +- .../jabref/gui/auximport/FromAuxDialog.java | 3 +- .../BibtexKeyPatternDialog.java | 3 +- .../BibtexKeyPatternPanel.java | 99 +++++-- .../gui/collab/ChangeDisplayDialog.java | 8 +- .../org/jabref/gui/collab/ChangeScanner.java | 2 +- .../ContentSelectorDialog.java | 6 +- .../EntryTypeCustomizationDialog.java | 3 +- .../jabref/gui/customjfx/CustomJFXPanel.java | 2 +- .../DatabasePropertiesDialog.java | 5 +- .../org/jabref/gui/desktop/JabRefDesktop.java | 15 +- .../gui/entryeditor/FieldsEditorTab.java | 5 +- .../gui/exporter/CustomExportDialog.java | 3 +- .../exporter/ExportCustomizationDialog.java | 3 +- .../gui/fieldeditors/ContextMenuAddable.java | 15 + .../gui/fieldeditors/EditorTextArea.java | 12 +- .../gui/fieldeditors/EditorTextField.java | 65 ++++ .../gui/fieldeditors/EditorValidator.java | 6 +- .../jabref/gui/fieldeditors/FieldEditors.java | 29 +- .../gui/fieldeditors/JournalEditor.java | 6 +- .../fieldeditors/JournalEditorViewModel.java | 15 +- .../gui/fieldeditors/LinkedFileViewModel.java | 37 +-- .../gui/fieldeditors/LinkedFilesEditor.java | 6 +- .../gui/fieldeditors/PersonsEditor.java | 27 +- .../jabref/gui/fieldeditors/SimpleEditor.java | 31 +- .../fieldeditors/contextmenu/ClearField.java | 4 +- .../fieldeditors/contextmenu/EditorMenus.java | 21 +- .../contextmenu/ProtectedTermsMenu.java | 6 +- .../jabref/gui/filelist/AttachFileAction.java | 10 +- .../LinkedFilesEditDialogViewModel.java | 9 +- .../org/jabref/gui/groups/GroupDialog.java | 3 +- .../java/org/jabref/gui/help/HelpAction.java | 15 +- .../org/jabref/gui/help/NewVersionDialog.java | 7 +- .../importer/ImportCustomizationDialog.java | 3 +- .../gui/importer/ImportInspectionDialog.java | 39 +-- .../gui/importer/fetcher/WebSearchPane.java | 107 +++++++ .../fetcher/WebSearchPaneViewModel.java | 117 ++++++++ .../jabref/gui/mergeentries/MergeEntries.java | 11 +- .../gui/mergeentries/MergeEntriesDialog.java | 3 +- .../mergeentries/MergeFetchedEntryDialog.java | 3 +- .../gui/plaintextimport/TextInputDialog.java | 2 +- .../org/jabref/gui/preftabs/AdvancedTab.java | 125 ++++---- .../gui/preftabs/AppearancePrefsTab.java | 89 +++--- .../gui/preftabs/BibtexKeyPatternPrefTab.java | 112 +++---- .../gui/preftabs/EntryEditorPrefsTab.java | 198 ++++++------- .../gui/preftabs/ExportSortingPrefsTab.java | 80 +++-- .../org/jabref/gui/preftabs/ExternalTab.java | 222 ++++++-------- .../java/org/jabref/gui/preftabs/FileTab.java | 262 ++++++++--------- .../org/jabref/gui/preftabs/GeneralTab.java | 257 ++++++++-------- .../jabref/gui/preftabs/GroupsPrefsTab.java | 121 +++----- .../gui/preftabs/ImportSettingsTab.java | 149 ++++------ .../jabref/gui/preftabs/NameFormatterTab.java | 2 + .../org/jabref/gui/preftabs/NetworkTab.java | 128 ++++---- .../gui/preftabs/PreferencesDialog.java | 2 +- .../gui/preftabs/PreferencesFilterDialog.java | 5 +- .../jabref/gui/preftabs/TablePrefsTab.java | 277 ++++++++---------- .../NewProtectedTermsFileDialog.java | 3 +- .../gui/push/PushToApplicationSettings.java | 36 +++ .../jabref/gui/push/PushToEmacsSettings.java | 7 + .../jabref/gui/search/GlobalSearchBar.java | 2 +- .../jabref/gui/search/SearchTextField.java | 4 +- .../shared/ConnectToSharedDatabaseDialog.java | 3 +- .../org/jabref/gui/util/ControlHelper.java | 18 ++ .../java/org/jabref/gui/util/ThemeLoader.java | 3 + .../gui/util/ViewModelListCellFactory.java | 6 + .../org/jabref/gui/worker/VersionWorker.java | 2 +- .../logic/exporter/FileSaveSession.java | 1 - .../importer/EntryBasedParserFetcher.java | 2 +- .../logic/importer/FulltextFetchers.java | 17 +- .../logic/importer/IdBasedParserFetcher.java | 16 +- .../org/jabref/logic/importer/Parser.java | 5 + .../importer/SearchBasedParserFetcher.java | 2 +- .../org/jabref/logic/importer/WebFetcher.java | 6 +- .../jabref/logic/importer/WebFetchers.java | 5 +- .../importer/fetcher/ACMPortalFetcher.java | 5 +- .../importer/fetcher/AbstractIsbnFetcher.java | 6 +- .../jabref/logic/importer/fetcher/ArXiv.java | 48 +-- .../fetcher/AstrophysicsDataSystem.java | 5 +- .../logic/importer/fetcher/CiteSeer.java | 95 ++++++ .../logic/importer/fetcher/DBLPFetcher.java | 5 +- .../logic/importer/fetcher/DOAJFetcher.java | 123 +++++++- .../jabref/logic/importer/fetcher/DiVA.java | 5 +- .../logic/importer/fetcher/DoiFetcher.java | 4 +- .../logic/importer/fetcher/GoogleScholar.java | 4 +- .../logic/importer/fetcher/GvkFetcher.java | 5 +- .../jabref/logic/importer/fetcher/IEEE.java | 131 ++++++++- .../importer/fetcher/INSPIREFetcher.java | 5 +- .../importer/fetcher/MedlineFetcher.java | 5 +- .../logic/importer/fetcher/RfcFetcher.java | 5 +- .../importer/fetcher/SpringerFetcher.java | 118 +++++++- .../logic/importer/fetcher/TitleFetcher.java | 4 +- .../importer/fileformat/BibtexParser.java | 5 - .../importer/fileformat/CoinsParser.java | 78 +++++ .../importer/fileformat/ModsImporter.java | 2 +- .../jabref/logic/net/ProgressInputStream.java | 6 +- .../org/jabref/logic/net/URLDownload.java | 25 +- .../jabref/logic/util/io/FileBasedLock.java | 9 +- .../migrations/PreferencesMigrations.java | 25 -- .../model/entry/InternalBibtexFields.java | 8 + .../entry/identifier/ArXivIdentifier.java | 13 +- .../jabref/preferences/JabRefPreferences.java | 34 ++- src/main/resources/l10n/JabRef_en.properties | 15 +- src/main/resources/l10n/JabRef_zh.properties | 10 +- .../fieldeditors/LinkedFileViewModelTest.java | 2 +- ...nageJournalAbbreviationsViewModelTest.java | 2 +- .../fetcher/ACMPortalFetcherTest.java | 2 + .../logic/importer/fetcher/ACSTest.java | 2 +- .../logic/importer/fetcher/ArXivTest.java | 5 +- .../fetcher/AstrophysicsDataSystemTest.java | 5 +- .../logic/importer/fetcher/CiteSeerTest.java | 50 ++++ .../logic/importer/fetcher/CrossRefTest.java | 14 +- .../importer/fetcher/DBLPFetcherTest.java | 11 +- .../importer/fetcher/DOAJFetcherTest.java | 31 +- .../logic/importer/fetcher/DiVATest.java | 7 +- .../importer/fetcher/DoiFetcherTest.java | 2 +- .../importer/fetcher/GvkFetcherTest.java | 2 +- .../logic/importer/fetcher/GvkParserTest.java | 3 +- .../logic/importer/fetcher/IEEETest.java | 47 ++- .../importer/fetcher/INSPIREFetcherTest.java | 2 + .../importer/fetcher/IsbnFetcherTest.java | 2 +- .../fetcher/IsbnViaChimboriFetcherTest.java | 6 +- .../fetcher/IsbnViaEbookDeFetcherTest.java | 16 +- .../fetcher/LibraryOfCongressTest.java | 24 +- .../importer/fetcher/MathSciNetTest.java | 2 +- .../importer/fetcher/MedlineFetcherTest.java | 2 +- .../importer/fetcher/OpenAccessDoiTest.java | 5 +- .../importer/fetcher/RfcFetcherTest.java | 9 +- .../importer/fetcher/SpringerFetcherTest.java | 34 ++- .../importer/fetcher/TitleFetcherTest.java | 2 +- src/test/resources/log4j2-test.xml | 13 + 150 files changed, 2671 insertions(+), 1744 deletions(-) create mode 100644 src/main/java/org/jabref/gui/fieldeditors/ContextMenuAddable.java create mode 100644 src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java create mode 100644 src/main/java/org/jabref/gui/importer/fetcher/WebSearchPane.java create mode 100644 src/main/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModel.java create mode 100644 src/main/java/org/jabref/logic/importer/fetcher/CiteSeer.java create mode 100644 src/main/java/org/jabref/logic/importer/fileformat/CoinsParser.java create mode 100644 src/test/java/org/jabref/logic/importer/fetcher/CiteSeerTest.java create mode 100644 src/test/resources/log4j2-test.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 61cf25bc5be..c9c02b1e1aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +<<<<<<< HEAD +# Changelog All notable changes to this project will be documented in this file. This project **does not** adhere to [Semantic Versioning](http://semver.org/). This file tries to follow the conventions proposed by [keepachangelog.com](http://keepachangelog.com/). Here, the categories "Changed" for added and changed functionality, "Fixed" for fixed functionality, and "Removed" for removed functionality are used. We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#NUM`. ## [Unreleased] ### Changed - We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) - Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) - We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) - The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. - We added a button in the tab header which allows you to close the database with one click. https://github.com/JabRef/jabref/issues/494 - Sorting in the main table now takes information from cross-referenced entries into account. https://github.com/JabRef/jabref/issues/2808 - If a group has a color specified, then entries matched by this group have a small colored bar in front of them in the main table. - Change default icon for groups to a circle because a colored version of the old icon was hard to distinguish from its black counterpart. - In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) - We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. - We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). - We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. - Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. - Window state is saved on close and restored on start. - We streamlined the process to rename and move files by removing the confirmation dialogs. - We convert some of the Swing Dialogs to javaFX. https://github.com/JabRef/jabref/issues/3861 ### Fixed - We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) - Italic text is now rendered correctly. https://github.com/JabRef/jabref/issues/3356 - The entry editor no longer gets corrupted after using the source tab. https://github.com/JabRef/jabref/issues/3532 https://github.com/JabRef/jabref/issues/3608 https://github.com/JabRef/jabref/issues/3616 - We fixed multiple issues where entries did not show up after import if a search was active. https://github.com/JabRef/jabref/issues/1513 https://github.com/JabRef/jabref/issues/3219 - We fixed an issue where the group tree was not updated correctly after an entry was changed. https://github.com/JabRef/jabref/issues/3618 - We fixed an issue where a right-click in the main table selected a wrong entry. https://github.com/JabRef/jabref/issues/3267 - We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 - We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 - We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 - We fixed an issue where commands followed by `-` didn't work. [#3805](https://github.com/JabRef/jabref/issues/3805) - We fixed an issue where some journal names were wrongly marked as abbreviated. [#4115](https://github.com/JabRef/jabref/issues/4115) - We fixed an issue where the custom file column were sorted incorrectly. https://github.com/JabRef/jabref/issues/3119 - We fixed an issues where the entry losses focus when a field is edited and at the same time used for sorting. https://github.com/JabRef/jabref/issues/3373 - We fixed an issue where the menu on Mac OS was not displayed in the usual Mac-specific way. https://github.com/JabRef/jabref/issues/3146 - We fixed an issue where the order of fields in customized entry types was not saved correctly. [#4033](http://github.com/JabRef/jabref/issues/4033) - We fixed an issue where the groups tree of the last database was still shown even after the database was already closed. - We fixed an issue where the "Open file dialog" may disappear behind other windows. https://github.com/JabRef/jabref/issues/3410 - We fixed an issue where the default icon of a group was not colored correctly. - We fixed an issue where the first field in entry editor was not focused when adding a new entry. [#4024](https://github.com/JabRef/jabref/issues/4024) - We reworked the "Edit file" dialog to make it resizeable and improved the workflow for adding and editing files https://github.com/JabRef/jabref/issues/2970 - We fixed an issue where the month was not shown in the preview https://github.com/JabRef/jabref/issues/3239. - Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) - We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) - We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) - We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) ### Removed - The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. - The number column was removed. - We removed the coloring of cells in the maintable according to whether the field is optional/required. - We removed a few commands from the right-click menu that are not needed often and thus don't need to be placed that prominently: - Print entry preview: available through entry preview - All commands related to marking: marking is not yet reimplemented - Set/clear/append/rename fields: available through Edit menu - Manage keywords: available through Edit menu - Copy linked files to folder: available through File menu ## Older versions The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). [Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD [4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 [4.2]: https://github.com/JabRef/jabref/compare/v4.1...v4.2 [4.1]: https://github.com/JabRef/jabref/compare/v4.0...v4.1 [4.0]: https://github.com/JabRef/jabref/compare/v4.0-beta3...v4.0 [4.0-beta3]: https://github.com/JabRef/jabref/compare/v4.0-beta2...v4.0-beta3 [4.0-beta2]: https://github.com/JabRef/jabref/compare/v4.0-beta...v4.0-beta2 [4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta [2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 [JavaFX]: https://en.wikipedia.org/wiki/JavaFX +======= # Changelog All notable changes to this project will be documented in this file. This project **does not** adhere to [Semantic Versioning](http://semver.org/). @@ -11,6 +14,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# ## [Unreleased] ### Changed +- We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) - Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) - We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) - The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. @@ -24,6 +28,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. - Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. - Window state is saved on close and restored on start. +- Files without a defined external file type are now directly opened with the default aplication of the operating system +- We streamlined the process to rename and move files by removing the confirmation dialogs. @@ -57,7 +63,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) - We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) - We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) - +- We fixed an issue where filles added via the "Attach file" contextmenu of an entry were not made relative. [#4201](https://github.com/JabRef/jabref/issues/4201) @@ -124,3 +130,4 @@ The changelog of JabRef 2.11 and all previous versions is available as [text fil [4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta [2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 [JavaFX]: https://en.wikipedia.org/wiki/JavaFX +>>>>>>> 077fdacc2ddc7beb7d22ba96ead8b400c91b3631 diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index 9ab00359919..f6074c34725 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -35,10 +35,6 @@ public class JabRefGUI { - private static final String NIMBUS_LOOK_AND_FEEL = "javax.swing.plaf.nimbus.NimbusLookAndFeel"; - private static final String WINDOWS_LOOK_AND_FEEL = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; - private static final String OSX_AQUA_LOOK_AND_FEEL = "apple.laf.AquaLookAndFeel"; - private static final Logger LOGGER = LoggerFactory.getLogger(JabRefGUI.class); private static JabRefFrame mainFrame; diff --git a/src/main/java/org/jabref/cli/ArgumentProcessor.java b/src/main/java/org/jabref/cli/ArgumentProcessor.java index 7df241a209d..4bf16b3fe85 100644 --- a/src/main/java/org/jabref/cli/ArgumentProcessor.java +++ b/src/main/java/org/jabref/cli/ArgumentProcessor.java @@ -5,7 +5,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -16,8 +15,6 @@ import org.jabref.Globals; import org.jabref.JabRefException; import org.jabref.gui.externalfiles.AutoSetLinks; -import org.jabref.gui.importer.fetcher.EntryFetcher; -import org.jabref.gui.importer.fetcher.EntryFetchers; import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator; import org.jabref.logic.exporter.BibDatabaseWriter; import org.jabref.logic.exporter.BibtexDatabaseWriter; @@ -28,12 +25,15 @@ import org.jabref.logic.exporter.SavePreferences; import org.jabref.logic.exporter.SaveSession; import org.jabref.logic.exporter.TemplateExporter; +import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.ImportException; import org.jabref.logic.importer.ImportFormatReader; import org.jabref.logic.importer.OpenDatabase; import org.jabref.logic.importer.OutputPrinter; import org.jabref.logic.importer.ParseException; import org.jabref.logic.importer.ParserResult; +import org.jabref.logic.importer.SearchBasedFetcher; +import org.jabref.logic.importer.WebFetchers; import org.jabref.logic.importer.fileformat.BibtexParser; import org.jabref.logic.l10n.Localization; import org.jabref.logic.layout.LayoutFormatterPreferences; @@ -538,15 +538,12 @@ private void regenerateBibtexKeys(List loaded) { /** * Run an entry fetcher from the command line. - *

- * Note that this only works headlessly if the EntryFetcher does not show any GUI. * - * @param fetchCommand A string containing both the fetcher to use (id of EntryFetcherExtension minus Fetcher) and + * @param fetchCommand A string containing both the name of the fetcher to use and * the search query, separated by a : * @return A parser result containing the entries fetched or null if an error occurred. */ private Optional fetch(String fetchCommand) { - if ((fetchCommand == null) || !fetchCommand.contains(":") || (fetchCommand.split(":").length != 2)) { System.out.println(Localization.lang("Expected syntax for --fetch=':'")); System.out.println(Localization.lang("The following fetchers are available:")); @@ -555,38 +552,36 @@ private Optional fetch(String fetchCommand) { String[] split = fetchCommand.split(":"); String engine = split[0]; + String query = split[1]; - EntryFetchers fetchers = new EntryFetchers(Globals.journalAbbreviationLoader); - EntryFetcher fetcher = null; - for (EntryFetcher e : fetchers.getEntryFetchers()) { - if (engine.equalsIgnoreCase(e.getClass().getSimpleName().replace("Fetcher", ""))) { - fetcher = e; - } - } - - if (fetcher == null) { + List fetchers = WebFetchers.getSearchBasedFetchers(Globals.prefs.getImportFormatPreferences()); + Optional selectedFetcher = fetchers.stream() + .filter(fetcher -> fetcher.getName().equalsIgnoreCase(engine)) + .findFirst(); + if (!selectedFetcher.isPresent()) { System.out.println(Localization.lang("Could not find fetcher '%0'", engine)); - System.out.println(Localization.lang("The following fetchers are available:")); - - for (EntryFetcher e : fetchers.getEntryFetchers()) { - System.out.println( - " " + e.getClass().getSimpleName().replace("Fetcher", "").toLowerCase(Locale.ENGLISH)); - } - return Optional.empty(); - } - String query = split[1]; - System.out.println(Localization.lang("Running query '%0' with fetcher '%1'.", query, engine) + " " - + Localization.lang("Please wait...")); - Collection result = new ImportInspectionCommandLine().query(query, fetcher); + System.out.println(Localization.lang("The following fetchers are available:")); + fetchers.forEach(fetcher -> System.out.println(" " + fetcher.getName())); - if (result.isEmpty()) { - System.out.println( - Localization.lang("Query '%0' with fetcher '%1' did not return any results.", query, engine)); return Optional.empty(); + } else { + System.out.println(Localization.lang("Running query '%0' with fetcher '%1'.", query, engine)); + System.out.print(Localization.lang("Please wait...")); + try { + List matches = selectedFetcher.get().performSearch(query); + if (matches.isEmpty()) { + System.out.println("\r" + Localization.lang("No results found.")); + return Optional.empty(); + } else { + System.out.println("\r" + Localization.lang("Found %0 results.", String.valueOf(matches.size()))); + return Optional.of(new ParserResult(matches)); + } + } catch (FetcherException e) { + LOGGER.error("Error while fetching", e); + return Optional.empty(); + } } - - return Optional.of(new ParserResult(result)); } public boolean isBlank() { diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index e23a6a27e3f..52167a8b624 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -62,6 +62,7 @@ import org.jabref.gui.filelist.FileListEntry; import org.jabref.gui.filelist.FileListTableModel; import org.jabref.gui.groups.GroupAddRemoveDialog; +import org.jabref.gui.icon.JabRefIcon; import org.jabref.gui.importer.actions.AppendDatabaseAction; import org.jabref.gui.journals.AbbreviateAction; import org.jabref.gui.journals.UnabbreviateAction; @@ -345,9 +346,6 @@ private void setupActions() { actions.put(Actions.MERGE_ENTRIES, () -> new MergeEntriesDialog(BasePanel.this, dialogService)); - actions.put(Actions.SEARCH, frame.getGlobalSearchBar()::focus); - actions.put(Actions.GLOBAL_SEARCH, frame.getGlobalSearchBar()::performGlobalSearch); - // The action for copying the selected entry's key. actions.put(Actions.COPY_KEY, this::copyKey); @@ -458,7 +456,7 @@ private void setupActions() { actions.put(Actions.PREVIOUS_PREVIEW_STYLE, this::previousPreviewStyle); actions.put(Actions.MANAGE_SELECTORS, () -> { - ContentSelectorDialog csd = new ContentSelectorDialog(null, frame, BasePanel.this, false, null); + ContentSelectorDialog csd = new ContentSelectorDialog(frame, BasePanel.this, false, null); csd.setVisible(true); }); @@ -677,7 +675,7 @@ private void openExternalFile() { return; } FileListEntry flEntry = fileListTableModel.getEntry(0); - ExternalFileMenuItem item = new ExternalFileMenuItem(frame(), "", flEntry.getLink(), flEntry.getType().get().getIcon().getSmallIcon(), bibDatabaseContext, flEntry.getType()); + ExternalFileMenuItem item = new ExternalFileMenuItem(frame(), "", flEntry.getLink(), flEntry.getType().map(ExternalFileType::getIcon).map(JabRefIcon::getSmallIcon).orElse(null), bibDatabaseContext, flEntry.getType()); item.doClick(); }); } diff --git a/src/main/java/org/jabref/gui/DuplicateResolverDialog.java b/src/main/java/org/jabref/gui/DuplicateResolverDialog.java index 2151be6eaa3..c7d939cbd87 100644 --- a/src/main/java/org/jabref/gui/DuplicateResolverDialog.java +++ b/src/main/java/org/jabref/gui/DuplicateResolverDialog.java @@ -6,7 +6,6 @@ import javax.swing.Box; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JPanel; import org.jabref.gui.help.HelpAction; @@ -46,7 +45,7 @@ public enum DuplicateResolverResult { private MergeEntries me; public DuplicateResolverDialog(JabRefFrame frame, BibEntry one, BibEntry two, DuplicateResolverType type) { - super((JFrame) null, Localization.lang("Possible duplicate entries"), true, DuplicateResolverDialog.class); + super(Localization.lang("Possible duplicate entries"), true, DuplicateResolverDialog.class); this.frame = frame; init(one, two, type); } diff --git a/src/main/java/org/jabref/gui/EntryTypeDialog.java b/src/main/java/org/jabref/gui/EntryTypeDialog.java index d37d398420a..93cc5a73a3d 100644 --- a/src/main/java/org/jabref/gui/EntryTypeDialog.java +++ b/src/main/java/org/jabref/gui/EntryTypeDialog.java @@ -9,6 +9,7 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutionException; @@ -28,6 +29,7 @@ import org.jabref.Globals; import org.jabref.gui.importer.ImportInspectionDialog; import org.jabref.gui.keyboard.KeyBinding; +import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.bibtex.DuplicateCheck; import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator; import org.jabref.logic.importer.FetcherException; @@ -65,7 +67,7 @@ public class EntryTypeDialog extends JabRefDialog implements ActionListener { public EntryTypeDialog(JabRefFrame frame) { // modal dialog - super(null, true, EntryTypeDialog.class); + super(true, EntryTypeDialog.class); this.frame = frame; @@ -315,7 +317,7 @@ protected void done() { final BasePanel panel = frame.getCurrentBasePanel(); ImportInspectionDialog diag = new ImportInspectionDialog(frame, panel, Localization.lang("Import"), false); - diag.addEntry(bibEntry); + diag.addEntries(Collections.singletonList(bibEntry)); diag.entryListComplete(); diag.setVisible(true); diag.toFront(); @@ -326,18 +328,28 @@ protected void done() { if (Globals.prefs.getTimestampPreferences().includeCreatedTimestamp()) { bibEntry.setField(Globals.prefs.getTimestampPreferences().getTimestampField(), Globals.prefs.getTimestampPreferences().now()); } - frame.getCurrentBasePanel().insertEntry(bibEntry); + DefaultTaskExecutor.runInJavaFXThread(() -> frame.getCurrentBasePanel().insertEntry(bibEntry)); } dispose(); } else if (searchID.trim().isEmpty()) { - frame.getDialogService().showWarningDialogAndWait(Localization.lang("Empty search ID"), - Localization.lang("The given search ID was empty.")); + DefaultTaskExecutor.runInJavaFXThread(() -> { + frame.getDialogService().showWarningDialogAndWait( + Localization.lang("Empty search ID"), + Localization.lang("The given search ID was empty.")); + }); } else if (!fetcherException) { - frame.getDialogService().showErrorDialogAndWait(Localization.lang("No files found.", - Localization.lang("Fetcher '%0' did not find an entry for id '%1'.", fetcher.getName(), searchID) + "\n" + fetcherExceptionMessage)); + DefaultTaskExecutor.runInJavaFXThread(() -> { + frame.getDialogService().showErrorDialogAndWait( + Localization.lang("No files found."), + Localization.lang("Fetcher '%0' did not find an entry for id '%1'.", fetcher.getName(), searchID) + "\n" + fetcherExceptionMessage); + }); } else { - frame.getDialogService().showErrorDialogAndWait(Localization.lang("Error"), Localization.lang("Error while fetching from %0", fetcher.getName()) + "." + "\n" + fetcherExceptionMessage); + DefaultTaskExecutor.runInJavaFXThread(() -> { + frame.getDialogService().showErrorDialogAndWait( + Localization.lang("Error"), + Localization.lang("Error while fetching from %0", fetcher.getName()) + "." + "\n" + fetcherExceptionMessage); + }); } fetcherWorker = new FetcherWorker(); SwingUtilities.invokeLater(() -> { diff --git a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java index 7d2a77b38bf..e41f30dc616 100644 --- a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java +++ b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java @@ -3,7 +3,6 @@ import java.awt.Component; import java.awt.Container; import java.awt.Dimension; -import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -158,8 +157,8 @@ public class FindUnlinkedFilesDialog extends JabRefDialog { private boolean checkBoxWhyIsThereNoGetSelectedStupidSwing; - public FindUnlinkedFilesDialog(Frame owner, JabRefFrame frame) { - super(owner, Localization.lang("Find unlinked files"), true, FindUnlinkedFilesDialog.class); + public FindUnlinkedFilesDialog(JabRefFrame frame) { + super(Localization.lang("Find unlinked files"), true, FindUnlinkedFilesDialog.class); this.frame = frame; restoreSizeOfDialog(); diff --git a/src/main/java/org/jabref/gui/GenFieldsCustomizer.java b/src/main/java/org/jabref/gui/GenFieldsCustomizer.java index 6bff3e65d56..f913bbe5cc8 100644 --- a/src/main/java/org/jabref/gui/GenFieldsCustomizer.java +++ b/src/main/java/org/jabref/gui/GenFieldsCustomizer.java @@ -16,7 +16,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -51,7 +50,7 @@ public class GenFieldsCustomizer extends JabRefDialog { private final JButton revert = new JButton(); public GenFieldsCustomizer(JabRefFrame frame) { - super((JFrame) null, Localization.lang("Set general fields"), false, GenFieldsCustomizer.class); + super(Localization.lang("Set general fields"), false, GenFieldsCustomizer.class); helpBut = new HelpAction(HelpFile.GENERAL_FIELDS).getHelpButton(); jbInit(); setSize(new Dimension(650, 300)); diff --git a/src/main/java/org/jabref/gui/JabRefDialog.java b/src/main/java/org/jabref/gui/JabRefDialog.java index 3a70de1a368..3221956a393 100644 --- a/src/main/java/org/jabref/gui/JabRefDialog.java +++ b/src/main/java/org/jabref/gui/JabRefDialog.java @@ -1,7 +1,6 @@ package org.jabref.gui; import java.awt.Frame; -import java.awt.Window; import javax.swing.JDialog; @@ -9,30 +8,20 @@ public class JabRefDialog extends JDialog { - public JabRefDialog(Frame owner, boolean modal, Class clazz) { - super(owner, modal); - - trackDialogOpening(clazz); + public JabRefDialog(boolean modal, Class clazz) { + this("JabRef", modal, clazz); } public JabRefDialog(Class clazz) { - super(); - - trackDialogOpening(clazz); + this(true, clazz); } - public JabRefDialog(Frame owner, Class clazz) { - super(owner); - - trackDialogOpening(clazz); + public JabRefDialog(String title, Class clazz) { + this(title, true, clazz); } - public JabRefDialog(Frame owner, String title, Class clazz) { - this(owner, title, true, clazz); - } - - public JabRefDialog(Frame owner, String title, boolean modal, Class clazz) { - super(owner, title, modal); + public JabRefDialog(String title, boolean modal, Class clazz) { + super((Frame) null, title, modal); trackDialogOpening(clazz); } @@ -47,13 +36,19 @@ public JabRefDialog(java.awt.Dialog owner, String titl trackDialogOpening(clazz); } - public JabRefDialog(Window owner, String title, Class clazz) { - super(owner, title); - - trackDialogOpening(clazz); - } - private void trackDialogOpening(Class clazz) { Globals.getTelemetryClient().ifPresent(client -> client.trackPageView(clazz.getName())); } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + + if (visible) { + // FIXME: Ugly hack to ensure that new dialogs are not hidden behind the main window + setAlwaysOnTop(true); + requestFocus(); + setAlwaysOnTop(false); + } + } } diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 1eed35d9bfa..2776ed0d70a 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -254,7 +254,7 @@ private void init() { // groupSidePane.getToggleCommand().setSelected(sidePaneManager.isComponentVisible(GroupSidePane.class)); //previewToggle.setSelected(Globals.prefs.getPreviewPreferences().isPreviewPanelEnabled()); - //generalFetcher.getToggleCommand().setSelected(sidePaneManager.isComponentVisible(GeneralFetcher.class)); + //generalFetcher.getToggleCommand().setSelected(sidePaneManager.isComponentVisible(WebSearchPane.class)); //openOfficePanel.getToggleCommand().setSelected(sidePaneManager.isComponentVisible(OpenOfficeSidePanel.class)); // TODO: Can't notify focus listener since it is expecting a swing component //Globals.getFocusListener().setFocused(currentBasePanel.getMainTable()); @@ -278,7 +278,6 @@ private void init() { } initShowTrackingNotification(); - } private void initKeyBindings() { @@ -310,6 +309,9 @@ private void initKeyBindings() { setDefaultTableFontSize(); event.consume(); break; + case SEARCH: + getGlobalSearchBar().focus(); + break; default: } } @@ -395,7 +397,7 @@ public void openAction(String filePath) { * The MacAdapter calls this method when "About" is selected from the application menu. */ public void about() { - HelpAction.getCommand().execute(); + HelpAction.getMainHelpPageCommand().execute(); } public JabRefPreferences prefs() { @@ -922,7 +924,7 @@ private MenuBar createMenu() { ); help.getItems().addAll( - factory.createMenuItem(StandardActions.HELP, HelpAction.getCommand()), + factory.createMenuItem(StandardActions.HELP, HelpAction.getMainHelpPageCommand()), factory.createMenuItem(StandardActions.OPEN_FORUM, new OpenBrowserAction("http://discourse.jabref.org/")), new SeparatorMenuItem(), @@ -1419,7 +1421,6 @@ public EditAction(Actions command) { @Override public void execute() { - LOGGER.debug(Globals.getFocusListener().getFocused().toString()); JComponent source = Globals.getFocusListener().getFocused(); Action action = source.getActionMap().get(command); if (action != null) { diff --git a/src/main/java/org/jabref/gui/MergeDialog.java b/src/main/java/org/jabref/gui/MergeDialog.java index 8129da56e1b..09ddfb6677d 100644 --- a/src/main/java/org/jabref/gui/MergeDialog.java +++ b/src/main/java/org/jabref/gui/MergeDialog.java @@ -13,7 +13,6 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JPanel; import org.jabref.Globals; @@ -41,7 +40,7 @@ public class MergeDialog extends JabRefDialog { private boolean okPressed; public MergeDialog(JabRefFrame frame, String title, boolean modal) { - super((JFrame) null, title, modal, MergeDialog.class); + super(title, modal, MergeDialog.class); jbInit(); pack(); } diff --git a/src/main/java/org/jabref/gui/ReplaceStringDialog.java b/src/main/java/org/jabref/gui/ReplaceStringDialog.java index 10fd5ccc1cf..4c493260c00 100644 --- a/src/main/java/org/jabref/gui/ReplaceStringDialog.java +++ b/src/main/java/org/jabref/gui/ReplaceStringDialog.java @@ -16,7 +16,6 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; @@ -48,7 +47,7 @@ class ReplaceStringDialog extends JabRefDialog { public ReplaceStringDialog(JabRefFrame parent) { - super((JFrame) null, Localization.lang("Replace string"), true, ReplaceStringDialog.class); + super(Localization.lang("Replace string"), true, ReplaceStringDialog.class); ButtonGroup bg = new ButtonGroup(); bg.add(allFi); diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index a2d8d023174..420cc70c474 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -1,32 +1,42 @@ package org.jabref.gui; -import java.awt.Component; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JPanel; - +import com.jgoodies.forms.builder.FormBuilder; +import com.jgoodies.forms.layout.FormLayout; +import javafx.collections.FXCollections; +import javafx.scene.Node; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.layout.GridPane; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; import org.jabref.model.metadata.SaveOrderConfig; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; public class SaveOrderConfigDisplay { - private JPanel panel; - private JComboBox savePriSort; - private JComboBox saveSecSort; - private JComboBox saveTerSort; - private JCheckBox savePriDesc; - private JCheckBox saveSecDesc; - private JCheckBox saveTerDesc; + private GridPane panel; + private JPanel jPanel; + private ComboBox savePriSort; + private ComboBox saveSecSort; + private ComboBox saveTerSort; + private CheckBox savePriDesc; + private CheckBox saveSecDesc; + private CheckBox saveTerDesc; + + private JComboBox savePriSort1; + private JComboBox saveSecSort1; + private JComboBox saveTerSort1; + private JCheckBox savePriDesc1; + private JCheckBox saveSecDesc1; + private JCheckBox saveTerDesc1; public SaveOrderConfigDisplay() { @@ -38,56 +48,80 @@ private void init() { fieldNames.add(BibEntry.KEY_FIELD); Collections.sort(fieldNames); String[] allPlusKey = fieldNames.toArray(new String[fieldNames.size()]); - savePriSort = new JComboBox<>(allPlusKey); + savePriSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); savePriSort.setEditable(true); - saveSecSort = new JComboBox<>(allPlusKey); + saveSecSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); saveSecSort.setEditable(true); - saveTerSort = new JComboBox<>(allPlusKey); + saveTerSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); saveTerSort.setEditable(true); - savePriDesc = new JCheckBox(Localization.lang("Descending")); - saveSecDesc = new JCheckBox(Localization.lang("Descending")); - saveTerDesc = new JCheckBox(Localization.lang("Descending")); - + savePriDesc = new CheckBox(Localization.lang("Descending")); + saveSecDesc = new CheckBox(Localization.lang("Descending")); + saveTerDesc = new CheckBox(Localization.lang("Descending")); + + GridPane builder = new GridPane(); + builder.add(new Label(Localization.lang(" Primary sort criterion ")),1,1); + builder.add(savePriSort,2,1); + builder.add(savePriDesc,3,1); + + builder.add(new Label(Localization.lang("Secondary sort criterion ")),1,2); + builder.add(saveSecSort,2,2); + builder.add(saveSecDesc,3,2); + + builder.add(new Label(Localization.lang(" Tertiary sort criterion ")),1, 3); + builder.add(saveTerSort,2,3); + builder.add(saveTerDesc,3,3); + panel = builder; + + savePriSort1 = new JComboBox<>(allPlusKey); + savePriSort1.setEditable(true); + saveSecSort1 = new JComboBox<>(allPlusKey); + saveSecSort1.setEditable(true); + saveTerSort1 = new JComboBox<>(allPlusKey); + saveTerSort1.setEditable(true); + savePriDesc1 = new JCheckBox(Localization.lang("Descending")); + saveSecDesc1 = new JCheckBox(Localization.lang("Descending")); + saveTerDesc1 = new JCheckBox(Localization.lang("Descending")); FormLayout layout = new FormLayout("right:pref, 8dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, left:pref", "pref, 2dlu, pref, 2dlu, pref"); - FormBuilder builder = FormBuilder.create().layout(layout); - builder.add(Localization.lang("Primary sort criterion")).xy(1, 1); - builder.add(savePriSort).xy(3, 1); - builder.add(savePriDesc).xy(5, 1); - - builder.add(Localization.lang("Secondary sort criterion")).xy(1, 3); - builder.add(saveSecSort).xy(3, 3); - builder.add(saveSecDesc).xy(5, 3); - - builder.add(Localization.lang("Tertiary sort criterion")).xy(1, 5); - builder.add(saveTerSort).xy(3, 5); - builder.add(saveTerDesc).xy(5, 5); - - panel = builder.build(); + FormBuilder builder1 = FormBuilder.create().layout(layout); + builder1.add(Localization.lang("Primary sort criterion")).xy(1, 1); + builder1.add(savePriSort1).xy(3, 1); + builder1.add(savePriDesc1).xy(5, 1); + builder1.add(Localization.lang("Secondary sort criterion")).xy(1, 3); + builder1.add(saveSecSort1).xy(3, 3); + builder1.add(saveSecDesc1).xy(5, 3); + builder1.add(Localization.lang("Tertiary sort criterion")).xy(1, 5); + builder1.add(saveTerSort1).xy(3, 5); + builder1.add(saveTerDesc1).xy(5, 5); + jPanel = builder1.build(); } - public Component getPanel() { + public Node getJFXPanel() { return panel; } + public JPanel getPanel() { + return jPanel; + } + public void setEnabled(boolean enabled) { - savePriSort.setEnabled(enabled); - savePriDesc.setEnabled(enabled); - saveSecSort.setEnabled(enabled); - saveSecDesc.setEnabled(enabled); - saveTerSort.setEnabled(enabled); - saveTerDesc.setEnabled(enabled); + savePriSort.setDisable(!enabled); + savePriDesc.setDisable(!enabled); + saveSecSort.setDisable(!enabled); + saveSecDesc.setDisable(!enabled); + saveTerSort.setDisable(!enabled); + saveTerDesc.setDisable(!enabled); } public void setSaveOrderConfig(SaveOrderConfig saveOrderConfig) { Objects.requireNonNull(saveOrderConfig); - savePriSort.setSelectedItem(saveOrderConfig.sortCriteria[0].field); + savePriSort.setValue(saveOrderConfig.sortCriteria[0].field); savePriDesc.setSelected(saveOrderConfig.sortCriteria[0].descending); - saveSecSort.setSelectedItem(saveOrderConfig.sortCriteria[1].field); + saveSecSort.setValue(saveOrderConfig.sortCriteria[1].field); saveSecDesc.setSelected(saveOrderConfig.sortCriteria[1].descending); - saveTerSort.setSelectedItem(saveOrderConfig.sortCriteria[2].field); + saveTerSort.setValue(saveOrderConfig.sortCriteria[2].field); saveTerDesc.setSelected(saveOrderConfig.sortCriteria[2].descending); } @@ -104,7 +138,7 @@ public SaveOrderConfig getSaveOrderConfig() { return saveOrderConfig; } - private String getSelectedItemAsLowerCaseTrim(JComboBox sortBox) { - return sortBox.getSelectedItem().toString().toLowerCase(Locale.ROOT).trim(); + private String getSelectedItemAsLowerCaseTrim(ComboBox sortBox) { + return sortBox.getValue().toLowerCase(Locale.ROOT).trim(); } } diff --git a/src/main/java/org/jabref/gui/SidePaneManager.java b/src/main/java/org/jabref/gui/SidePaneManager.java index ca122c86a71..5a09bdcd1ab 100644 --- a/src/main/java/org/jabref/gui/SidePaneManager.java +++ b/src/main/java/org/jabref/gui/SidePaneManager.java @@ -10,7 +10,7 @@ import org.jabref.Globals; import org.jabref.gui.collab.FileUpdatePanel; import org.jabref.gui.groups.GroupSidePane; -import org.jabref.gui.importer.fetcher.GeneralFetcher; +import org.jabref.gui.importer.fetcher.WebSearchPane; import org.jabref.gui.openoffice.OpenOfficeSidePanel; import org.jabref.logic.openoffice.OpenOfficePreferences; import org.jabref.preferences.JabRefPreferences; @@ -33,7 +33,7 @@ public SidePaneManager(JabRefPreferences preferences, JabRefFrame frame) { Stream.of( new FileUpdatePanel(this), new GroupSidePane(this, preferences, frame.getDialogService()), - new GeneralFetcher(this, preferences, frame), + new WebSearchPane(this, preferences, frame), new OpenOfficeSidePanel(this, openOfficePreferences, frame)) .forEach(pane -> components.put(pane.getType(), pane)); @@ -45,6 +45,10 @@ public SidePaneManager(JabRefPreferences preferences, JabRefFrame frame) { show(SidePaneType.OPEN_OFFICE); } + if (preferences.getBoolean(JabRefPreferences.WEB_SEARCH_VISIBLE)) { + show(SidePaneType.WEB_SEARCH); + } + updateView(); } diff --git a/src/main/java/org/jabref/gui/StringDialog.java b/src/main/java/org/jabref/gui/StringDialog.java index 796a557dbec..1169b1f7dce 100644 --- a/src/main/java/org/jabref/gui/StringDialog.java +++ b/src/main/java/org/jabref/gui/StringDialog.java @@ -66,7 +66,7 @@ class StringDialog extends JabRefDialog { public StringDialog(JabRefFrame frame, BasePanel panel, BibDatabase base) { - super(null, StringDialog.class); + super(StringDialog.class); this.panel = panel; this.base = base; diff --git a/src/main/java/org/jabref/gui/actions/Actions.java b/src/main/java/org/jabref/gui/actions/Actions.java index 3f5522e095e..4a72f33a45f 100644 --- a/src/main/java/org/jabref/gui/actions/Actions.java +++ b/src/main/java/org/jabref/gui/actions/Actions.java @@ -49,8 +49,6 @@ public enum Actions { SAVE, SAVE_AS, SAVE_SELECTED_AS_PLAIN, - SEARCH, - GLOBAL_SEARCH, SELECT_ALL, SEND_AS_EMAIL, TOGGLE_GROUPS, diff --git a/src/main/java/org/jabref/gui/actions/DatabasePropertiesAction.java b/src/main/java/org/jabref/gui/actions/DatabasePropertiesAction.java index d7b3ffe35bf..564b6c5cc2f 100644 --- a/src/main/java/org/jabref/gui/actions/DatabasePropertiesAction.java +++ b/src/main/java/org/jabref/gui/actions/DatabasePropertiesAction.java @@ -13,7 +13,7 @@ public DatabasePropertiesAction(JabRefFrame frame) { @Override public void execute() { - DatabasePropertiesDialog propertiesDialog = new DatabasePropertiesDialog(null, frame.getCurrentBasePanel()); + DatabasePropertiesDialog propertiesDialog = new DatabasePropertiesDialog(frame.getCurrentBasePanel()); propertiesDialog.updateEnableStatus(); propertiesDialog.setVisible(true); } diff --git a/src/main/java/org/jabref/gui/actions/FindUnlinkedFilesAction.java b/src/main/java/org/jabref/gui/actions/FindUnlinkedFilesAction.java index 9e3f32dc8f2..d1a193857eb 100644 --- a/src/main/java/org/jabref/gui/actions/FindUnlinkedFilesAction.java +++ b/src/main/java/org/jabref/gui/actions/FindUnlinkedFilesAction.java @@ -13,7 +13,7 @@ public FindUnlinkedFilesAction(JabRefFrame jabRefFrame) { @Override public void execute() { - FindUnlinkedFilesDialog dlg = new FindUnlinkedFilesDialog(null, jabRefFrame); + FindUnlinkedFilesDialog dlg = new FindUnlinkedFilesDialog(jabRefFrame); dlg.setVisible(true); } diff --git a/src/main/java/org/jabref/gui/actions/NewEntryAction.java b/src/main/java/org/jabref/gui/actions/NewEntryAction.java index 72e657e2fb8..dd8c0add054 100644 --- a/src/main/java/org/jabref/gui/actions/NewEntryAction.java +++ b/src/main/java/org/jabref/gui/actions/NewEntryAction.java @@ -4,6 +4,8 @@ import java.util.Map; import java.util.Optional; +import javax.swing.SwingUtilities; + import org.jabref.Globals; import org.jabref.gui.EntryTypeDialog; import org.jabref.gui.JabRefFrame; @@ -42,15 +44,17 @@ public void execute() { if (type.isPresent()) { jabRefFrame.getCurrentBasePanel().newEntry(type.get()); } else { - EntryTypeDialog typeChoiceDialog = new EntryTypeDialog(jabRefFrame); - typeChoiceDialog.setVisible(true); - EntryType selectedType = typeChoiceDialog.getChoice(); - if (selectedType == null) { - return; - } + SwingUtilities.invokeLater(() -> { + EntryTypeDialog typeChoiceDialog = new EntryTypeDialog(jabRefFrame); + typeChoiceDialog.setVisible(true); + EntryType selectedType = typeChoiceDialog.getChoice(); + if (selectedType == null) { + return; + } - trackNewEntry(selectedType); - jabRefFrame.getCurrentBasePanel().newEntry(selectedType); + trackNewEntry(selectedType); + jabRefFrame.getCurrentBasePanel().newEntry(selectedType); + }); } } diff --git a/src/main/java/org/jabref/gui/actions/NewSubLibraryAction.java b/src/main/java/org/jabref/gui/actions/NewSubLibraryAction.java index 368fe9975ff..bf25ffea34a 100644 --- a/src/main/java/org/jabref/gui/actions/NewSubLibraryAction.java +++ b/src/main/java/org/jabref/gui/actions/NewSubLibraryAction.java @@ -1,5 +1,7 @@ package org.jabref.gui.actions; +import javax.swing.SwingUtilities; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.BasePanelPreferences; @@ -23,16 +25,18 @@ public NewSubLibraryAction(JabRefFrame jabRefFrame) { @Override public void execute() { - FromAuxDialog dialog = new FromAuxDialog(jabRefFrame, "", true, jabRefFrame.getTabbedPane()); - - dialog.setVisible(true); - - if (dialog.generatePressed()) { - Defaults defaults = new Defaults(Globals.prefs.getDefaultBibDatabaseMode()); - BasePanel bp = new BasePanel(jabRefFrame, BasePanelPreferences.from(Globals.prefs), new BibDatabaseContext(dialog.getGenerateDB(), defaults), ExternalFileTypes.getInstance()); - jabRefFrame.addTab(bp, true); - jabRefFrame.output(Localization.lang("New library created.")); - } + SwingUtilities.invokeLater(() -> { + FromAuxDialog dialog = new FromAuxDialog(jabRefFrame, "", true, jabRefFrame.getTabbedPane()); + + dialog.setVisible(true); + + if (dialog.generatePressed()) { + Defaults defaults = new Defaults(Globals.prefs.getDefaultBibDatabaseMode()); + BasePanel bp = new BasePanel(jabRefFrame, BasePanelPreferences.from(Globals.prefs), new BibDatabaseContext(dialog.getGenerateDB(), defaults), ExternalFileTypes.getInstance()); + jabRefFrame.addTab(bp, true); + jabRefFrame.output(Localization.lang("New library created.")); + } + }); } } diff --git a/src/main/java/org/jabref/gui/actions/WriteXMPAction.java b/src/main/java/org/jabref/gui/actions/WriteXMPAction.java index 74ebc86949c..e2d549e2c4e 100644 --- a/src/main/java/org/jabref/gui/actions/WriteXMPAction.java +++ b/src/main/java/org/jabref/gui/actions/WriteXMPAction.java @@ -17,7 +17,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; @@ -95,7 +94,7 @@ public void init() { errors = entriesChanged = skipped = 0; if (optionsDialog == null) { - optionsDialog = new OptionsDialog(null); + optionsDialog = new OptionsDialog(); } optionsDialog.open(); @@ -182,9 +181,8 @@ class OptionsDialog extends JabRefDialog { private final JTextArea progressArea; - - public OptionsDialog(JFrame parent) { - super(parent, Localization.lang("Writing XMP-metadata for selected entries..."), false, WriteXMPAction.OptionsDialog.class); + public OptionsDialog() { + super(Localization.lang("Writing XMP-metadata for selected entries..."), false, WriteXMPAction.OptionsDialog.class); okButton.setEnabled(false); okButton.addActionListener(e -> dispose()); diff --git a/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java b/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java index 265ba9fc994..8cc7b0e144e 100644 --- a/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java +++ b/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java @@ -13,7 +13,6 @@ import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; @@ -69,7 +68,7 @@ public class FromAuxDialog extends JabRefDialog { private final JabRefFrame parentFrame; public FromAuxDialog(JabRefFrame frame, String title, boolean modal, TabPane viewedDBs) { - super((JFrame) null, title, modal, FromAuxDialog.class); + super(title, modal, FromAuxDialog.class); parentTabbedPane = viewedDBs; parentFrame = frame; diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java index 3897f74042b..9b04361a327 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternDialog.java @@ -10,7 +10,6 @@ import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JDialog; -import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.WindowConstants; @@ -31,7 +30,7 @@ public class BibtexKeyPatternDialog extends JabRefDialog { private final BibtexKeyPatternPanel bibtexKeyPatternPanel; public BibtexKeyPatternDialog(BasePanel panel) { - super((JFrame) null, Localization.lang("BibTeX key patterns"), true, BibtexKeyPatternDialog.class); + super(Localization.lang("BibTeX key patterns"), true, BibtexKeyPatternDialog.class); this.bibtexKeyPatternPanel = new BibtexKeyPatternPanel(panel); this.panel = panel; this.metaData = panel.getBibDatabaseContext().getMetaData(); diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java index 5d92dce5e62..d1d0411d844 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java @@ -1,22 +1,9 @@ package org.jabref.gui.bibtexkeypattern; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextField; - +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.help.HelpAction; @@ -31,6 +18,12 @@ import org.jabref.model.entry.EntryType; import org.jabref.preferences.JabRefPreferences; +import javax.swing.*; +import java.awt.*; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + public class BibtexKeyPatternPanel extends JPanel { // used by both BibtexKeyPatternPanel and TabLabelPAttern @@ -39,12 +32,15 @@ public class BibtexKeyPatternPanel extends JPanel { // default pattern protected final JTextField defaultPat = new JTextField(); + private final TextField textField = new TextField(); private final HelpAction help; // one field for each type private final Map textFields = new HashMap<>(); + private final TextField[] textFieldArray = new TextField[19]; private final BasePanel panel; + private final GridPane gridPane = new GridPane(); public BibtexKeyPatternPanel(BasePanel panel) { @@ -60,8 +56,11 @@ private void buildGUI() { sp.setBorder(BorderFactory.createEmptyBorder()); pan.setLayout(gbl); setLayout(gbl); + // The header - can be removed JLabel lblEntryType = new JLabel(Localization.lang("Entry type")); + Label label= new Label(Localization.lang("Entry type")); + gridPane.add(label,1,1); Font f = new Font("plain", Font.BOLD, 12); lblEntryType.setFont(f); con.gridx = 0; @@ -75,6 +74,8 @@ private void buildGUI() { pan.add(lblEntryType); JLabel lblKeyPattern = new JLabel(Localization.lang("Key pattern")); + Label label1 = new Label(Localization.lang("Key pattern")); + gridPane.add(label1,2,1); lblKeyPattern.setFont(f); con.gridx = 1; con.gridy = 0; @@ -88,6 +89,9 @@ private void buildGUI() { con.gridy = 1; con.gridx = 0; JLabel lab = new JLabel(Localization.lang("Default pattern")); + Label label2 = new Label(Localization.lang("Default pattern")); + gridPane.add(label2, 1,2); + gridPane.add(textField,2,2); gbl.setConstraints(lab, con); pan.add(lab); con.gridx = 1; @@ -97,6 +101,10 @@ private void buildGUI() { JButton btnDefault = new JButton(Localization.lang("Default")); btnDefault.addActionListener( e -> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); + + Button button = new Button("Default"); + button.setOnAction(e-> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); + gridPane.add(button,3,2); con.gridx = 2; int y = 2; gbl.setConstraints(btnDefault, con); @@ -110,6 +118,7 @@ private void buildGUI() { // use preferences value if no DB is open mode = Globals.prefs.getDefaultBibDatabaseMode(); } + addExtraText(); for (EntryType type : EntryTypes.getAllValues(mode)) { textFields.put(type.getName().toLowerCase(Locale.ROOT), addEntryType(pan, type, y)); @@ -136,6 +145,11 @@ private void buildGUI() { con.anchor = GridBagConstraints.SOUTHEAST; con.insets = new Insets(0, 5, 0, 5); JButton hlb = new JButton(IconTheme.JabRefIcons.HELP.getSmallIcon()); + + 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,24); + hlb.setToolTipText(Localization.lang("Help on key patterns")); gbl.setConstraints(hlb, con); add(hlb); @@ -153,14 +167,58 @@ private void buildGUI() { gbl.setConstraints(btnDefaultAll, con); btnDefaultAll.addActionListener(e -> { // reset all fields - for (JTextField field : textFields.values()) { - field.setText(""); + for (TextField textField : textFieldArray) { + textField.setText(""); } // also reset the default pattern defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN)); }); add(btnDefaultAll); + + Button btnDefaultAll1 = new Button(Localization.lang("Reset all")); + btnDefaultAll1.setOnAction(e-> { + // reset all fields + for (JTextField field : textFields.values()) { + field.setText(""); + } + textField.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN)); + }); + gridPane.add(btnDefaultAll1,2,24); + } + + private void addExtraText(){ + Label []label = new Label[19]; + Button []button = new Button[19]; + for(int i=0; i<=18; i++){ + textFieldArray[i] = new TextField(); + button[i] = new Button("Default"); + button[i].setOnAction(e-> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); + } + label[0] = new Label("Article"); + label[1] = new Label("Book"); + label[2] = new Label("Booklet"); + label[3] = new Label("Conference"); + label[4] = new Label("Electronic"); + label[5] = new Label("IEEEtranBSTCTI"); + label[6] = new Label("InBook"); + label[7] = new Label("InCollection"); + label[8] = new Label("InProceedings"); + label[9] = new Label("Manual"); + label[10] = new Label("MasterThesis"); + label[11] = new Label("Misc"); + label[12] = new Label("Patent"); + label[13] = new Label("Periodical"); + label[14] = new Label("PhdThesis"); + label[15] = new Label("Proceedings"); + label[16] = new Label("Standard"); + label[17] = new Label("TechReport"); + label[18] = new Label("Unpublished"); + for(int i=0 ;i<=18; i++){ + gridPane.add(label[i],1,i+3); + gridPane.add(textFieldArray[i],2,i+3); + gridPane.add(button[i],3,i+3); + } } private JTextField addEntryType(Container c, EntryType type, int y) { @@ -263,4 +321,7 @@ private static void setValue(JTextField tf, String fieldName, AbstractBibtexKeyP } } + public GridPane getPanel() { + return gridPane; + } } diff --git a/src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java b/src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java index 1bf8978f1f0..ff67d3e19bb 100644 --- a/src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java +++ b/src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java @@ -9,7 +9,6 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -35,10 +34,9 @@ class ChangeDisplayDialog extends JabRefDialog implements TreeSelectionListener private JComponent infoShown; private boolean okPressed; - - public ChangeDisplayDialog(JFrame owner, final BasePanel panel, - BibDatabase secondary, final DefaultMutableTreeNode root) { - super(owner, Localization.lang("External changes"), true, ChangeDisplayDialog.class); + public ChangeDisplayDialog(final BasePanel panel, + BibDatabase secondary, final DefaultMutableTreeNode root) { + super(Localization.lang("External changes"), true, ChangeDisplayDialog.class); BibDatabase localSecondary; // Just to be sure, put in an empty secondary base if none is given: diff --git a/src/main/java/org/jabref/gui/collab/ChangeScanner.java b/src/main/java/org/jabref/gui/collab/ChangeScanner.java index b7f6ab06d70..553d17cb3a2 100644 --- a/src/main/java/org/jabref/gui/collab/ChangeScanner.java +++ b/src/main/java/org/jabref/gui/collab/ChangeScanner.java @@ -81,7 +81,7 @@ private static BibEntry bestFit(BibEntry targetEntry, List entries) { public void displayResult(final DisplayResultCallback fup) { if (changes.getChildCount() > 0) { SwingUtilities.invokeLater(() -> { - ChangeDisplayDialog changeDialog = new ChangeDisplayDialog(null, panel, databaseInTemp.getDatabase(), changes); + ChangeDisplayDialog changeDialog = new ChangeDisplayDialog(panel, databaseInTemp.getDatabase(), changes); changeDialog.setVisible(true); fup.scanResultsResolved(changeDialog.isOkPressed()); if (changeDialog.isOkPressed()) { diff --git a/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.java b/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.java index 1a180891503..a188c1fca8a 100644 --- a/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.java +++ b/src/main/java/org/jabref/gui/contentselector/ContentSelectorDialog.java @@ -3,7 +3,6 @@ import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; -import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; @@ -82,14 +81,13 @@ public class ContentSelectorDialog extends JabRefDialog { /** * - * @param owner the parent Window (Dialog or Frame) * @param frame the JabRef Frame * @param panel the currently selected BasePanel * @param modal should this dialog be modal? * @param fieldName the field this selector is initialized for. May be null. */ - public ContentSelectorDialog(Window owner, JabRefFrame frame, BasePanel panel, boolean modal, String fieldName) { - super(owner, Localization.lang("Manage content selectors"), ContentSelectorDialog.class); + public ContentSelectorDialog(JabRefFrame frame, BasePanel panel, boolean modal, String fieldName) { + super(Localization.lang("Manage content selectors"), ContentSelectorDialog.class); this.setModal(modal); this.metaData = panel.getBibDatabaseContext().getMetaData(); this.frame = frame; diff --git a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java index a9dc764366c..0361f3013a1 100644 --- a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java +++ b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeCustomizationDialog.java @@ -25,7 +25,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListSelectionModel; @@ -75,7 +74,7 @@ public class EntryTypeCustomizationDialog extends JabRefDialog implements ListSe * Creates a new instance of EntryTypeCustomizationDialog */ public EntryTypeCustomizationDialog(JabRefFrame frame) { - super((JFrame) null, Localization.lang("Customize entry types"), false, EntryTypeCustomizationDialog.class); + super(Localization.lang("Customize entry types"), false, EntryTypeCustomizationDialog.class); this.frame = frame; initGui(); diff --git a/src/main/java/org/jabref/gui/customjfx/CustomJFXPanel.java b/src/main/java/org/jabref/gui/customjfx/CustomJFXPanel.java index b9dfaf7e58b..1cb3e07b106 100644 --- a/src/main/java/org/jabref/gui/customjfx/CustomJFXPanel.java +++ b/src/main/java/org/jabref/gui/customjfx/CustomJFXPanel.java @@ -7,7 +7,7 @@ import org.jabref.gui.util.DefaultTaskExecutor; /** - * Remove as soon as possible + * TODO: Remove as soon as possible */ public class CustomJFXPanel { diff --git a/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java b/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java index 8667f8cf49e..24cdaae3aee 100644 --- a/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java +++ b/src/main/java/org/jabref/gui/dbproperties/DatabasePropertiesDialog.java @@ -16,7 +16,6 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JRadioButton; import javax.swing.JTextField; @@ -69,8 +68,8 @@ public class DatabasePropertiesDialog extends JabRefDialog { private FieldFormatterCleanupsPanel fieldFormatterCleanupsPanel; - public DatabasePropertiesDialog(JFrame parent, BasePanel panel) { - super(parent, Localization.lang("Library properties"), true, DatabasePropertiesDialog.class); + public DatabasePropertiesDialog(BasePanel panel) { + super(Localization.lang("Library properties"), true, DatabasePropertiesDialog.class); encoding = new JComboBox<>(); encoding.setModel(new DefaultComboBoxModel<>(Encodings.ENCODINGS)); ok = new JButton(Localization.lang("OK")); diff --git a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java index cfff8fb441c..c9c1a515aa4 100644 --- a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java +++ b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java @@ -129,20 +129,15 @@ public static boolean openExternalFileAnyFormat(final BibDatabaseContext databas } Optional file = FileHelper.expandFilename(databaseContext, link, Globals.prefs.getFileDirectoryPreferences()); - if (file.isPresent() && Files.exists(file.get()) && (type.isPresent())) { + if (file.isPresent() && Files.exists(file.get())) { // Open the file: String filePath = file.get().toString(); openExternalFilePlatformIndependent(type, filePath); return true; } else { // No file matched the name, try to open it directly using the given app - if (type.isPresent()) { - openExternalFilePlatformIndependent(type, link); - return true; - } - - // Run out of ideas what to do... - return false; + openExternalFilePlatformIndependent(type, link); + return true; } } @@ -160,6 +155,10 @@ private static void openExternalFilePlatformIndependent(Optional { Path layoutFileDir = Paths.get(layoutFile.getText()).getParent(); diff --git a/src/main/java/org/jabref/gui/exporter/ExportCustomizationDialog.java b/src/main/java/org/jabref/gui/exporter/ExportCustomizationDialog.java index a06b75d29f3..4348c4c1956 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportCustomizationDialog.java +++ b/src/main/java/org/jabref/gui/exporter/ExportCustomizationDialog.java @@ -13,7 +13,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -44,7 +43,7 @@ public class ExportCustomizationDialog extends JabRefDialog { public ExportCustomizationDialog(final JabRefFrame frame) { - super((JFrame) null, Localization.lang("Manage custom exports"), false, ExportCustomizationDialog.class); + super(Localization.lang("Manage custom exports"), false, ExportCustomizationDialog.class); DefaultEventTableModel> tableModel = new DefaultEventTableModel<>( Globals.prefs.customExports.getSortedList(), new ExportTableFormat()); JTable table = new JTable(tableModel); diff --git a/src/main/java/org/jabref/gui/fieldeditors/ContextMenuAddable.java b/src/main/java/org/jabref/gui/fieldeditors/ContextMenuAddable.java new file mode 100644 index 00000000000..9f9bff69e41 --- /dev/null +++ b/src/main/java/org/jabref/gui/fieldeditors/ContextMenuAddable.java @@ -0,0 +1,15 @@ +package org.jabref.gui.fieldeditors; + +import java.util.List; +import java.util.function.Supplier; + +import javafx.scene.control.MenuItem; + +public interface ContextMenuAddable { + /** + * Adds the given list of menu items to the context menu. The usage of {@link Supplier} prevents that the menus need + * to be instantiated at this point. They are populated when the user needs them which prevents many unnecessary + * allocations when the main table is just scrolled with the entry editor open. + */ + void addToContextMenu(final Supplier> items); +} diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java b/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java index 6f783e05d06..1783e9f1396 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java +++ b/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java @@ -13,13 +13,13 @@ import com.sun.javafx.scene.control.skin.TextAreaSkin; -public class EditorTextArea extends javafx.scene.control.TextArea implements Initializable { +public class EditorTextArea extends javafx.scene.control.TextArea implements Initializable, ContextMenuAddable { public EditorTextArea() { this(""); } - public EditorTextArea(String text) { + public EditorTextArea(final String text) { super(text); setMinHeight(1); @@ -49,12 +49,8 @@ public EditorTextArea(String text) { }); } - /** - * Adds the given list of menu items to the context menu. The usage of {@link Supplier} prevents that the menus need - * to be instantiated at this point. They are populated when the user needs them which prevents many unnecessary - * allocations when the main table is just scrolled with the entry editor open. - */ - public void addToContextMenu(Supplier> items) { + @Override + public void addToContextMenu(final Supplier> items) { TextAreaSkin customContextSkin = new TextAreaSkin(this) { @Override public void populateContextMenu(ContextMenu contextMenu) { diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java b/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java new file mode 100644 index 00000000000..26c23006a88 --- /dev/null +++ b/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java @@ -0,0 +1,65 @@ +package org.jabref.gui.fieldeditors; + +import java.net.URL; +import java.util.List; +import java.util.ResourceBundle; +import java.util.function.Supplier; + +import javafx.fxml.Initializable; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.MenuItem; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; + +import com.sun.javafx.scene.control.skin.TextFieldSkin; + +public class EditorTextField extends javafx.scene.control.TextField implements Initializable, ContextMenuAddable { + + public EditorTextField() { + this(""); + } + + public EditorTextField(final String text) { + super(text); + + setMinHeight(1); + setMinWidth(200); + + // Should behave as a normal text field with respect to TAB behaviour + addEventFilter(KeyEvent.KEY_PRESSED, event -> { + if (event.getCode() == KeyCode.TAB) { + TextFieldSkin skin = (TextFieldSkin) getSkin(); + if (event.isShiftDown()) { + // Shift + Tab > previous text area + skin.getBehavior().traversePrevious(); + } else { + if (event.isControlDown()) { + // Ctrl + Tab > insert tab + skin.getBehavior().callAction("InsertTab"); + } else { + // Tab > next text area + skin.getBehavior().traverseNext(); + } + } + event.consume(); + } + }); + } + + @Override + public void addToContextMenu(final Supplier> items) { + TextFieldSkin customContextSkin = new TextFieldSkin(this) { + @Override + public void populateContextMenu(ContextMenu contextMenu) { + super.populateContextMenu(contextMenu); + contextMenu.getItems().addAll(0, items.get()); + } + }; + setSkin(customContextSkin); + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + // not needed + } +} diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorValidator.java b/src/main/java/org/jabref/gui/fieldeditors/EditorValidator.java index af3c8791a0d..626626ad468 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/EditorValidator.java +++ b/src/main/java/org/jabref/gui/fieldeditors/EditorValidator.java @@ -1,5 +1,7 @@ package org.jabref.gui.fieldeditors; +import javafx.scene.control.TextInputControl; + import org.jabref.gui.util.IconValidationDecorator; import org.jabref.preferences.JabRefPreferences; @@ -14,11 +16,11 @@ public EditorValidator(JabRefPreferences preferences) { this.preferences = preferences; } - public void configureValidation(ValidationStatus status, EditorTextArea area) { + public void configureValidation(final ValidationStatus status, final TextInputControl textInput) { if (preferences.getBoolean(JabRefPreferences.VALIDATE_IN_ENTRY_EDITOR)) { ControlsFxVisualizer validationVisualizer = new ControlsFxVisualizer(); validationVisualizer.setDecoration(new IconValidationDecorator()); - validationVisualizer.initVisualization(status, area); + validationVisualizer.initVisualization(status, textInput); } } } diff --git a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java index ef0db377b85..cff53232371 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java +++ b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java @@ -13,8 +13,7 @@ import org.jabref.gui.autocompleter.SuggestionProviders; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.integrity.FieldCheckers; -import org.jabref.logic.journals.JournalAbbreviationLoader; -import org.jabref.logic.journals.JournalAbbreviationPreferences; +import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.FieldName; import org.jabref.model.entry.FieldProperty; @@ -29,12 +28,26 @@ public class FieldEditors { private static final Logger LOGGER = LoggerFactory.getLogger(FieldEditors.class); - public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecutor, DialogService dialogService, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences, JabRefPreferences preferences, BibDatabaseContext databaseContext, String entryType, SuggestionProviders suggestionProviders, UndoManager undoManager) { + public static FieldEditorFX getForField(final String fieldName, + final TaskExecutor taskExecutor, + final DialogService dialogService, + final JournalAbbreviationRepository journalAbbreviationRepository, + final JabRefPreferences preferences, + final BibDatabaseContext databaseContext, + final String entryType, + final SuggestionProviders suggestionProviders, + final UndoManager undoManager) { final Set fieldExtras = InternalBibtexFields.getFieldProperties(fieldName); - AutoCompleteSuggestionProvider suggestionProvider = getSuggestionProvider(fieldName, suggestionProviders, databaseContext.getMetaData()); + final AutoCompleteSuggestionProvider suggestionProvider = getSuggestionProvider(fieldName, suggestionProviders, databaseContext.getMetaData()); - FieldCheckers fieldCheckers = new FieldCheckers(databaseContext, preferences.getFileDirectoryPreferences(), journalAbbreviationLoader.getRepository(journalAbbreviationPreferences), preferences.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); + final FieldCheckers fieldCheckers = new FieldCheckers( + databaseContext, + preferences.getFileDirectoryPreferences(), + journalAbbreviationRepository, + preferences.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); + + final boolean isSingleLine = InternalBibtexFields.isSingleLineField(fieldName); if (preferences.getTimestampPreferences().getTimestampField().equals(fieldName) || fieldExtras.contains(FieldProperty.DATE)) { if (fieldExtras.contains(FieldProperty.ISO_DATE)) { @@ -45,7 +58,7 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu } else if (fieldExtras.contains(FieldProperty.EXTERNAL)) { return new UrlEditor(fieldName, dialogService, suggestionProvider, fieldCheckers, preferences); } else if (fieldExtras.contains(FieldProperty.JOURNAL_NAME)) { - return new JournalEditor(fieldName, journalAbbreviationLoader, preferences, suggestionProvider, fieldCheckers); + return new JournalEditor(fieldName, journalAbbreviationRepository, preferences, suggestionProvider, fieldCheckers); } else if (fieldExtras.contains(FieldProperty.DOI) || fieldExtras.contains(FieldProperty.EPRINT) || fieldExtras.contains(FieldProperty.ISBN)) { return new IdentifierEditor(fieldName, taskExecutor, dialogService, suggestionProvider, fieldCheckers, preferences); } else if (fieldExtras.contains(FieldProperty.OWNER)) { @@ -71,7 +84,7 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu } else if (fieldExtras.contains(FieldProperty.SINGLE_ENTRY_LINK) || fieldExtras.contains(FieldProperty.MULTIPLE_ENTRY_LINK)) { return new LinkedEntriesEditor(fieldName, databaseContext, suggestionProvider, fieldCheckers); } else if (fieldExtras.contains(FieldProperty.PERSON_NAMES)) { - return new PersonsEditor(fieldName, suggestionProvider, preferences, fieldCheckers); + return new PersonsEditor(fieldName, suggestionProvider, preferences, fieldCheckers, isSingleLine); } else if (FieldName.KEYWORDS.equals(fieldName)) { return new KeywordsEditor(fieldName, suggestionProvider, fieldCheckers, preferences); } else if (fieldExtras.contains(FieldProperty.MULTILINE_TEXT)) { @@ -81,7 +94,7 @@ public static FieldEditorFX getForField(String fieldName, TaskExecutor taskExecu } // default - return new SimpleEditor(fieldName, suggestionProvider, fieldCheckers, preferences); + return new SimpleEditor(fieldName, suggestionProvider, fieldCheckers, preferences, isSingleLine); } @SuppressWarnings("unchecked") diff --git a/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java b/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java index af338ef26fa..ad00729bab3 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/JournalEditor.java @@ -8,7 +8,7 @@ import org.jabref.gui.autocompleter.AutoCompletionTextInputBinding; import org.jabref.gui.fieldeditors.contextmenu.EditorMenus; import org.jabref.logic.integrity.FieldCheckers; -import org.jabref.logic.journals.JournalAbbreviationLoader; +import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.model.entry.BibEntry; import org.jabref.preferences.JabRefPreferences; @@ -19,8 +19,8 @@ public class JournalEditor extends HBox implements FieldEditorFX { @FXML private JournalEditorViewModel viewModel; @FXML private EditorTextArea textArea; - public JournalEditor(String fieldName, JournalAbbreviationLoader journalAbbreviationLoader, JabRefPreferences preferences, AutoCompleteSuggestionProvider suggestionProvider, FieldCheckers fieldCheckers) { - this.viewModel = new JournalEditorViewModel(fieldName, suggestionProvider, journalAbbreviationLoader, preferences.getJournalAbbreviationPreferences(), fieldCheckers); + public JournalEditor(String fieldName, JournalAbbreviationRepository journalAbbreviationRepository, JabRefPreferences preferences, AutoCompleteSuggestionProvider suggestionProvider, FieldCheckers fieldCheckers) { + this.viewModel = new JournalEditorViewModel(fieldName, suggestionProvider, journalAbbreviationRepository, fieldCheckers); ViewLoader.view(this) .root(this) diff --git a/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java index e59d1305efc..2cf93f8bbec 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/JournalEditorViewModel.java @@ -4,20 +4,16 @@ import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider; import org.jabref.logic.integrity.FieldCheckers; -import org.jabref.logic.journals.JournalAbbreviationLoader; -import org.jabref.logic.journals.JournalAbbreviationPreferences; import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.model.strings.StringUtil; public class JournalEditorViewModel extends AbstractEditorViewModel { - private final JournalAbbreviationLoader journalAbbreviationLoader; - private final JournalAbbreviationPreferences journalAbbreviationPreferences; + private final JournalAbbreviationRepository journalAbbreviationRepository; - public JournalEditorViewModel(String fieldName, AutoCompleteSuggestionProvider suggestionProvider, JournalAbbreviationLoader journalAbbreviationLoader, JournalAbbreviationPreferences journalAbbreviationPreferences, FieldCheckers fieldCheckers) { + public JournalEditorViewModel(String fieldName, AutoCompleteSuggestionProvider suggestionProvider, JournalAbbreviationRepository journalAbbreviationRepository, FieldCheckers fieldCheckers) { super(fieldName, suggestionProvider, fieldCheckers); - this.journalAbbreviationLoader = journalAbbreviationLoader; - this.journalAbbreviationPreferences = journalAbbreviationPreferences; + this.journalAbbreviationRepository = journalAbbreviationRepository; } public void toggleAbbreviation() { @@ -25,9 +21,8 @@ public void toggleAbbreviation() { return; } - JournalAbbreviationRepository abbreviationRepository = journalAbbreviationLoader.getRepository(journalAbbreviationPreferences); - if (abbreviationRepository.isKnownName(text.get())) { - Optional nextAbbreviation = abbreviationRepository.getNextAbbreviation(text.get()); + if (journalAbbreviationRepository.isKnownName(text.get())) { + Optional nextAbbreviation = journalAbbreviationRepository.getNextAbbreviation(text.get()); if (nextAbbreviation.isPresent()) { text.set(nextAbbreviation.get()); diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java index e1480c08688..ee0a04e5b4f 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java @@ -201,34 +201,19 @@ public void rename() { // Cannot rename remote links return; } - Optional fileDir = databaseContext.getFirstExistingFileDir(fileDirectoryPreferences); - if (!fileDir.isPresent()) { - dialogService.showErrorDialogAndWait(Localization.lang("Rename file"), Localization.lang("File directory is not set or does not exist!")); - return; - } Optional file = linkedFile.findIn(databaseContext, fileDirectoryPreferences); if ((file.isPresent()) && Files.exists(file.get())) { RenamePdfCleanup pdfCleanup = new RenamePdfCleanup(false, databaseContext, fileDirPattern, fileDirectoryPreferences, linkedFile); - - String targetFileName = pdfCleanup.getTargetFileName(linkedFile, entry); - - boolean confirm = dialogService.showConfirmationDialogAndWait(Localization.lang("Rename file"), - Localization.lang("Rename file to") + " " + targetFileName, - Localization.lang("Rename file"), - Localization.lang("Cancel")); - - if (confirm) { - Optional fileConflictCheck = pdfCleanup.findExistingFile(linkedFile, entry); - performRenameWithConflictCheck(file, pdfCleanup, targetFileName, fileConflictCheck); - } + performRenameWithConflictCheck(file.get(), pdfCleanup); } else { dialogService.showErrorDialogAndWait(Localization.lang("File not found"), Localization.lang("Could not find file '%0'.", linkedFile.getLink())); } } - private void performRenameWithConflictCheck(Optional file, RenamePdfCleanup pdfCleanup, String targetFileName, Optional fileConflictCheck) { + private void performRenameWithConflictCheck(Path file, RenamePdfCleanup pdfCleanup) { boolean confirm; + Optional fileConflictCheck = pdfCleanup.findExistingFile(linkedFile, entry); if (!fileConflictCheck.isPresent()) { try { pdfCleanup.cleanupWithException(entry); @@ -236,6 +221,7 @@ private void performRenameWithConflictCheck(Optional file, RenamePdfCleanu dialogService.showErrorDialogAndWait(Localization.lang("Rename failed"), Localization.lang("JabRef cannot access the file because it is being used by another process.")); } } else { + String targetFileName = pdfCleanup.getTargetFileName(linkedFile, entry); confirm = dialogService.showConfirmationDialogAndWait(Localization.lang("File exists"), Localization.lang("'%0' exists. Overwrite file?", targetFileName), Localization.lang("Overwrite"), @@ -243,7 +229,7 @@ private void performRenameWithConflictCheck(Optional file, RenamePdfCleanu if (confirm) { try { - FileUtil.renameFileWithException(fileConflictCheck.get(), file.get(), true); + FileUtil.renameFileWithException(fileConflictCheck.get(), file, true); pdfCleanup.cleanupWithException(entry); } catch (IOException e) { dialogService.showErrorDialogAndWait(Localization.lang("Rename failed"), @@ -268,19 +254,20 @@ public void moveToDefaultDirectory() { Optional file = linkedFile.findIn(databaseContext, fileDirectoryPreferences); if ((file.isPresent()) && Files.exists(file.get())) { - // Linked file exists, so move it + // Found the linked file, so move it MoveFilesCleanup moveFiles = new MoveFilesCleanup(databaseContext, fileDirPattern, fileDirectoryPreferences, linkedFile); - - boolean confirm = dialogService.showConfirmationDialogAndWait(Localization.lang("Move file"), Localization.lang("Move file to file directory?") + " " + fileDir.get(), Localization.lang("Move file"), Localization.lang("Cancel")); - if (confirm) { - moveFiles.cleanup(entry); - } + moveFiles.cleanup(entry); } else { // File doesn't exist, so we can't move it. dialogService.showErrorDialogAndWait(Localization.lang("File not found"), Localization.lang("Could not find file '%0'.", linkedFile.getLink())); } } + public void moveToDefaultDirectoryAndRename() { + moveToDefaultDirectory(); + rename(); + } + public boolean delete(FileDirectoryPreferences prefs) { Optional file = linkedFile.findIn(databaseContext, prefs); diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java index 2758f5583cd..153caee75a1 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java @@ -259,6 +259,10 @@ private ContextMenu createContextMenuForFile(LinkedFileViewModel linkedFile) { moveFile.setOnAction(event -> linkedFile.moveToDefaultDirectory()); moveFile.setDisable(linkedFile.getFile().isOnlineLink()); + MenuItem renameAndMoveFile = new MenuItem(Localization.lang("Move file to file directory and rename file")); + renameAndMoveFile.setOnAction(event -> linkedFile.moveToDefaultDirectoryAndRename()); + renameAndMoveFile.setDisable(linkedFile.getFile().isOnlineLink()); + MenuItem deleteFile = new MenuItem(Localization.lang("Permanently delete local file")); deleteFile.setOnAction(event -> viewModel.deleteFile(linkedFile)); deleteFile.setDisable(linkedFile.getFile().isOnlineLink()); @@ -273,7 +277,7 @@ private ContextMenu createContextMenuForFile(LinkedFileViewModel linkedFile) { if (linkedFile.getFile().isOnlineLink()) { menu.getItems().add(download); } - menu.getItems().addAll(renameFile, moveFile, deleteLink, deleteFile); + menu.getItems().addAll(renameFile, moveFile, renameAndMoveFile, deleteLink, deleteFile); return menu; } diff --git a/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java b/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java index 01f5dccc8b9..f72a5cf23fe 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/PersonsEditor.java @@ -2,6 +2,7 @@ import javafx.fxml.FXML; import javafx.scene.Parent; +import javafx.scene.control.TextInputControl; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; @@ -16,20 +17,26 @@ public class PersonsEditor extends HBox implements FieldEditorFX { @FXML private final PersonsEditorViewModel viewModel; - private EditorTextArea textArea; + private TextInputControl textInput; - public PersonsEditor(String fieldName, AutoCompleteSuggestionProvider suggestionProvider, JabRefPreferences preferences, FieldCheckers fieldCheckers) { + public PersonsEditor(final String fieldName, + final AutoCompleteSuggestionProvider suggestionProvider, + final JabRefPreferences preferences, + final FieldCheckers fieldCheckers, + final boolean isSingleLine) { this.viewModel = new PersonsEditorViewModel(fieldName, suggestionProvider, preferences.getAutoCompletePreferences(), fieldCheckers); - textArea = new EditorTextArea(); - HBox.setHgrow(textArea, Priority.ALWAYS); - textArea.textProperty().bindBidirectional(viewModel.textProperty()); - textArea.addToContextMenu(EditorMenus.getNameMenu(textArea)); - this.getChildren().add(textArea); + textInput = isSingleLine + ? new EditorTextField() + : new EditorTextArea(); + HBox.setHgrow(textInput, Priority.ALWAYS); + textInput.textProperty().bindBidirectional(viewModel.textProperty()); + ((ContextMenuAddable) textInput).addToContextMenu(EditorMenus.getNameMenu(textInput)); + this.getChildren().add(textInput); - AutoCompletionTextInputBinding.autoComplete(textArea, viewModel::complete, viewModel.getAutoCompletionConverter(), viewModel.getAutoCompletionStrategy()); + AutoCompletionTextInputBinding.autoComplete(textInput, viewModel::complete, viewModel.getAutoCompletionConverter(), viewModel.getAutoCompletionStrategy()); - new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textArea); + new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textInput); } @Override @@ -44,7 +51,7 @@ public Parent getNode() { @Override public void requestFocus() { - textArea.requestFocus(); + textInput.requestFocus(); } } diff --git a/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java b/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java index 00e0e991183..de42b9e0d73 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/SimpleEditor.java @@ -2,6 +2,7 @@ import javafx.fxml.FXML; import javafx.scene.Parent; +import javafx.scene.control.TextInputControl; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; @@ -17,22 +18,36 @@ public class SimpleEditor extends HBox implements FieldEditorFX { @FXML private final SimpleEditorViewModel viewModel; - public SimpleEditor(String fieldName, AutoCompleteSuggestionProvider suggestionProvider, FieldCheckers fieldCheckers, JabRefPreferences preferences) { + public SimpleEditor(final String fieldName, + final AutoCompleteSuggestionProvider suggestionProvider, + final FieldCheckers fieldCheckers, + final JabRefPreferences preferences, + final boolean isSingleLine) { this.viewModel = new SimpleEditorViewModel(fieldName, suggestionProvider, fieldCheckers); - EditorTextArea textArea = new EditorTextArea(); - HBox.setHgrow(textArea, Priority.ALWAYS); - textArea.textProperty().bindBidirectional(viewModel.textProperty()); - textArea.addToContextMenu(EditorMenus.getDefaultMenu(textArea)); - this.getChildren().add(textArea); + TextInputControl textInput = isSingleLine + ? new EditorTextField() + : new EditorTextArea(); + HBox.setHgrow(textInput, Priority.ALWAYS); + textInput.textProperty().bindBidirectional(viewModel.textProperty()); + ((ContextMenuAddable) textInput).addToContextMenu(EditorMenus.getDefaultMenu(textInput)); + this.getChildren().add(textInput); - AutoCompletionTextInputBinding autoCompleter = AutoCompletionTextInputBinding.autoComplete(textArea, viewModel::complete, viewModel.getAutoCompletionStrategy()); + AutoCompletionTextInputBinding autoCompleter = AutoCompletionTextInputBinding.autoComplete(textInput, viewModel::complete, viewModel.getAutoCompletionStrategy()); if (suggestionProvider instanceof ContentSelectorSuggestionProvider) { // If content selector values are present, then we want to show the auto complete suggestions immediately on focus autoCompleter.setShowOnFocus(true); } - new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textArea); + new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textInput); + } + + + public SimpleEditor(final String fieldName, + final AutoCompleteSuggestionProvider suggestionProvider, + final FieldCheckers fieldCheckers, + final JabRefPreferences preferences) { + this(fieldName, suggestionProvider, fieldCheckers, preferences, false); } @Override diff --git a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ClearField.java b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ClearField.java index 52ef77f1a8c..22b846f44e2 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ClearField.java +++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ClearField.java @@ -1,13 +1,13 @@ package org.jabref.gui.fieldeditors.contextmenu; import javafx.scene.control.MenuItem; -import javafx.scene.control.TextArea; +import javafx.scene.control.TextInputControl; import org.jabref.logic.l10n.Localization; class ClearField extends MenuItem { - public ClearField(TextArea opener) { + public ClearField(TextInputControl opener) { super(Localization.lang("Clear")); setOnAction(event -> opener.setText("")); } diff --git a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java index 12e6382a3b1..179a1cfb9b7 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java +++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java @@ -12,6 +12,7 @@ import javafx.scene.control.MenuItem; import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.TextArea; +import javafx.scene.control.TextInputControl; import javafx.scene.control.Tooltip; import org.jabref.gui.actions.CopyDoiUrlAction; @@ -29,18 +30,18 @@ public class EditorMenus { /** * The default menu that contains functions for changing the case of text and doing several conversions. * - * @param textArea text-area that this menu will be connected to + * @param textInput text-input-control that this menu will be connected to * @return default context menu available for most text fields */ - public static Supplier> getDefaultMenu(TextArea textArea) { + public static Supplier> getDefaultMenu(final TextInputControl textInput) { return () -> { List menuItems = new ArrayList<>(6); - menuItems.add(new CaseChangeMenu(textArea.textProperty())); - menuItems.add(new ConversionMenu(textArea.textProperty())); + menuItems.add(new CaseChangeMenu(textInput.textProperty())); + menuItems.add(new ConversionMenu(textInput.textProperty())); menuItems.add(new SeparatorMenuItem()); - menuItems.add(new ProtectedTermsMenu(textArea)); + menuItems.add(new ProtectedTermsMenu(textInput)); menuItems.add(new SeparatorMenuItem()); - menuItems.add(new ClearField(textArea)); + menuItems.add(new ClearField(textInput)); return menuItems; }; } @@ -48,18 +49,18 @@ public static Supplier> getDefaultMenu(TextArea textArea) { /** * The default context menu with a specific menu for normalizing person names regarding to BibTex rules. * - * @param textArea text-area that this menu will be connected to + * @param textInput text-input-control that this menu will be connected to * @return menu containing items of the default menu and an item for normalizing person names */ - public static Supplier> getNameMenu(TextArea textArea) { + public static Supplier> getNameMenu(final TextInputControl textInput) { return () -> { CustomMenuItem normalizeNames = new CustomMenuItem(new Label(Localization.lang("Normalize to BibTeX name format"))); - normalizeNames.setOnAction(event -> textArea.setText(new NormalizeNamesFormatter().format(textArea.getText()))); + normalizeNames.setOnAction(event -> textInput.setText(new NormalizeNamesFormatter().format(textInput.getText()))); Tooltip toolTip = new Tooltip(Localization.lang("If possible, normalize this list of names to conform to standard BibTeX name formatting")); Tooltip.install(normalizeNames.getContent(), toolTip); List menuItems = new ArrayList<>(6); menuItems.add(normalizeNames); - menuItems.addAll(getDefaultMenu(textArea).get()); + menuItems.addAll(getDefaultMenu(textInput).get()); return menuItems; }; } 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 3ede64f1fea..4af7fec8023 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java +++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java @@ -8,7 +8,7 @@ import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javafx.scene.control.SeparatorMenuItem; -import javafx.scene.control.TextArea; +import javafx.scene.control.TextInputControl; import org.jabref.Globals; import org.jabref.JabRefGUI; @@ -23,9 +23,9 @@ class ProtectedTermsMenu extends Menu { private static final Formatter FORMATTER = new ProtectTermsFormatter(Globals.protectedTermsLoader); private final Menu externalFiles; - private final TextArea opener; + private final TextInputControl opener; - public ProtectedTermsMenu(TextArea opener) { + public ProtectedTermsMenu(final TextInputControl opener) { super(Localization.lang("Protect terms")); this.opener = opener; MenuItem protectItem = new MenuItem(Localization.lang("Add {} around selected text")); diff --git a/src/main/java/org/jabref/gui/filelist/AttachFileAction.java b/src/main/java/org/jabref/gui/filelist/AttachFileAction.java index eac832389f7..47e89416858 100644 --- a/src/main/java/org/jabref/gui/filelist/AttachFileAction.java +++ b/src/main/java/org/jabref/gui/filelist/AttachFileAction.java @@ -6,6 +6,7 @@ import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.actions.SimpleCommand; +import org.jabref.gui.fieldeditors.LinkedFilesEditorViewModel; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.logic.l10n.Localization; @@ -32,13 +33,14 @@ public void execute() { } BibEntry entry = panel.getSelectedEntries().get(0); FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() - .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)) - .build(); + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)) + .build(); dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(newFile -> { - LinkedFile newLinkedFile = new LinkedFile("", newFile.toString(), ""); - LinkedFileEditDialogView dialog = new LinkedFileEditDialogView(newLinkedFile); + LinkedFile linkedFile = LinkedFilesEditorViewModel.fromFile(newFile, panel.getBibDatabaseContext().getFileDirectoriesAsPaths(Globals.prefs.getFileDirectoryPreferences())); + + LinkedFileEditDialogView dialog = new LinkedFileEditDialogView(linkedFile); dialog.showAndWait() .ifPresent(editedLinkedFile -> { diff --git a/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java b/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java index 5a24ba38822..492cda62592 100644 --- a/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java +++ b/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java @@ -26,6 +26,9 @@ import org.jabref.model.util.FileHelper; import org.jabref.preferences.PreferencesService; +import org.fxmisc.easybind.EasyBind; +import org.fxmisc.easybind.monadic.MonadicObservableValue; + public class LinkedFilesEditDialogViewModel extends AbstractViewModel { private static final Pattern REMOTE_LINK_PATTERN = Pattern.compile("[a-z]+://.*"); @@ -33,6 +36,7 @@ public class LinkedFilesEditDialogViewModel extends AbstractViewModel { private final StringProperty description = new SimpleStringProperty(""); private final ListProperty allExternalFileTypes = new SimpleListProperty<>(FXCollections.emptyObservableList()); private final ObjectProperty selectedExternalFileType = new SimpleObjectProperty<>(); + private final MonadicObservableValue monadicSelectedExternalFileType; private final BibDatabaseContext database; private final DialogService dialogService; private final PreferencesService preferences; @@ -44,6 +48,8 @@ public LinkedFilesEditDialogViewModel(LinkedFile linkedFile, BibDatabaseContext this.preferences = preferences; this.externalFileTypes = externalFileTypes; allExternalFileTypes.set(FXCollections.observableArrayList(externalFileTypes.getExternalFileTypeSelection())); + + monadicSelectedExternalFileType = EasyBind.monadic(selectedExternalFileType); setValues(linkedFile); } @@ -119,8 +125,7 @@ public ObjectProperty selectedExternalFileTypeProperty() { } public LinkedFile getNewLinkedFile() { - return new LinkedFile(description.getValue(), link.getValue(), selectedExternalFileType.getValue().toString()); - + return new LinkedFile(description.getValue(), link.getValue(), monadicSelectedExternalFileType.map(ExternalFileType::toString).getOrElse("")); } } diff --git a/src/main/java/org/jabref/gui/groups/GroupDialog.java b/src/main/java/org/jabref/gui/groups/GroupDialog.java index 4abd8d6ac83..043ee954af1 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialog.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialog.java @@ -20,7 +20,6 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; @@ -149,7 +148,7 @@ public Dimension getPreferredSize() { * created. */ public GroupDialog(JabRefFrame jabrefFrame, AbstractGroup editedGroup) { - super((JFrame) null, Localization.lang("Edit group"), true, GroupDialog.class); + super(Localization.lang("Edit group"), true, GroupDialog.class); // set default values (overwritten if editedGroup != null) keywordGroupSearchField.setText(jabrefFrame.prefs().get(JabRefPreferences.GROUPS_DEFAULT_FIELD)); diff --git a/src/main/java/org/jabref/gui/help/HelpAction.java b/src/main/java/org/jabref/gui/help/HelpAction.java index 402d8900a13..70fdc69f5d9 100644 --- a/src/main/java/org/jabref/gui/help/HelpAction.java +++ b/src/main/java/org/jabref/gui/help/HelpAction.java @@ -17,6 +17,10 @@ import javax.swing.JLabel; import javax.swing.KeyStroke; +import com.sun.star.presentation.ClickAction; +import javafx.event.EventHandler; +import javafx.scene.control.Button; +import javafx.scene.control.Tooltip; import org.jabref.Globals; import org.jabref.gui.actions.MnemonicAwareAction; import org.jabref.gui.actions.SimpleCommand; @@ -110,7 +114,7 @@ public void actionPerformed(ActionEvent e) { openHelpPage(helpPage); } - public static SimpleCommand getCommand() { + public static SimpleCommand getMainHelpPageCommand() { return new SimpleCommand() { @Override public void execute() { @@ -118,4 +122,13 @@ public void execute() { } }; } + + public SimpleCommand getCommand() { + return new SimpleCommand() { + @Override + public void execute() { + openHelpPage(helpPage); + } + }; + } } diff --git a/src/main/java/org/jabref/gui/help/NewVersionDialog.java b/src/main/java/org/jabref/gui/help/NewVersionDialog.java index 9c64e2a64a7..51bff518ca6 100644 --- a/src/main/java/org/jabref/gui/help/NewVersionDialog.java +++ b/src/main/java/org/jabref/gui/help/NewVersionDialog.java @@ -7,7 +7,6 @@ import java.awt.event.MouseEvent; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.event.MouseInputAdapter; @@ -21,8 +20,8 @@ public class NewVersionDialog extends JabRefDialog { - public NewVersionDialog(JFrame frame, Version currentVersion, Version latestVersion) { - super(frame, NewVersionDialog.class); + public NewVersionDialog(Version currentVersion, Version latestVersion) { + super(NewVersionDialog.class); setTitle(Localization.lang("New version available")); JLabel lblTitle = new JLabel(Localization.lang("A new version of JabRef has been released.")); @@ -87,8 +86,6 @@ public void mouseClicked(MouseEvent e) { add(panel); pack(); - setLocationRelativeTo(frame); - setModalityType(ModalityType.APPLICATION_MODAL); setVisible(true); } diff --git a/src/main/java/org/jabref/gui/importer/ImportCustomizationDialog.java b/src/main/java/org/jabref/gui/importer/ImportCustomizationDialog.java index 80031214d9a..3cbfa285a47 100644 --- a/src/main/java/org/jabref/gui/importer/ImportCustomizationDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportCustomizationDialog.java @@ -16,7 +16,6 @@ import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -60,7 +59,7 @@ public class ImportCustomizationDialog extends JabRefDialog { private final JTable customImporterTable; public ImportCustomizationDialog(final JabRefFrame frame) { - super((JFrame) null, Localization.lang("Manage custom imports"), false, ImportCustomizationDialog.class); + super(Localization.lang("Manage custom imports"), false, ImportCustomizationDialog.class); DialogService dialogService = frame.getDialogService(); diff --git a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java index 3366019169c..84fcef65d67 100644 --- a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java @@ -84,7 +84,6 @@ import org.jabref.logic.bibtex.comparator.FieldComparator; import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator; import org.jabref.logic.help.HelpFile; -import org.jabref.logic.importer.ImportInspector; import org.jabref.logic.importer.OutputPrinter; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.UpdateField; @@ -144,7 +143,7 @@ * receiving this call). */ -public class ImportInspectionDialog extends JabRefDialog implements ImportInspector, OutputPrinter { +public class ImportInspectionDialog extends JabRefDialog implements OutputPrinter { private static final Logger LOGGER = LoggerFactory.getLogger(ImportInspectionDialog.class); private static final List INSPECTION_FIELDS = Arrays.asList(FieldName.AUTHOR, FieldName.TITLE, FieldName.YEAR, BibEntry.KEY_FIELD); @@ -168,7 +167,6 @@ public class ImportInspectionDialog extends JabRefDialog implements ImportInspec */ private final List entriesToDelete = new ArrayList<>(); private final String undoName; - private final List callBacks = new ArrayList<>(); private final boolean newDatabase; private final JPopupMenu popup = new JPopupMenu(); private final JButton deselectAllDuplicates = new JButton(Localization.lang("Deselect all duplicates")); @@ -193,7 +191,7 @@ public class ImportInspectionDialog extends JabRefDialog implements ImportInspec * @param panel */ public ImportInspectionDialog(JabRefFrame frame, BasePanel panel, String undoName, boolean newDatabase) { - super(null, ImportInspectionDialog.class); + super(ImportInspectionDialog.class); this.frame = frame; this.panel = panel; this.bibDatabaseContext = (panel == null) ? null : panel.getBibDatabaseContext(); @@ -286,7 +284,6 @@ public ImportInspectionDialog(JabRefFrame frame, BasePanel panel, String undoNam generate.setEnabled(false); ok.addActionListener(new OkListener()); cancel.addActionListener(e -> { - signalStopFetching(); dispose(); frame.output(Localization.lang("Import canceled by user")); }); @@ -297,7 +294,6 @@ public ImportInspectionDialog(JabRefFrame frame, BasePanel panel, String undoNam generateKeys(); // Generate the keys. }); stop.addActionListener(e -> { - signalStopFetching(); entryListComplete(); }); selectAll.addActionListener(new SelectionButton(true)); @@ -345,29 +341,6 @@ public void actionPerformed(ActionEvent e) { } - /* (non-Javadoc) - * @see package org.jabref.logic.importer.ImportInspector#setProgress(int, int) - */ - @Override - public void setProgress(int current, int max) { - SwingUtilities.invokeLater(() -> { - progressBar.setIndeterminate(false); - progressBar.setMinimum(0); - progressBar.setMaximum(max); - progressBar.setValue(current); - }); - } - - /* (non-Javadoc) - * @see package org.jabref.logic.importer.ImportInspector#addEntry(org.jabref.model.entry.BibEntry) - */ - @Override - public void addEntry(BibEntry entry) { - List list = new ArrayList<>(); - list.add(entry); - addEntries(list); - } - public void addEntries(Collection entriesToAdd) { for (BibEntry entry : entriesToAdd) { @@ -559,14 +532,6 @@ private AbstractAction getAction(GroupTreeNode node) { return action; } - public void addCallBack(CallBack cb) { - callBacks.add(cb); - } - - private void signalStopFetching() { - callBacks.forEach(CallBack::stopFetching); - } - private void setWidths() { TableColumnModel cm = glTable.getColumnModel(); cm.getColumn(0).setPreferredWidth(55); diff --git a/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPane.java b/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPane.java new file mode 100644 index 00000000000..1f9c0d637d6 --- /dev/null +++ b/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPane.java @@ -0,0 +1,107 @@ +package org.jabref.gui.importer.fetcher; + +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.TextField; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; + +import org.jabref.gui.JabRefFrame; +import org.jabref.gui.SidePaneComponent; +import org.jabref.gui.SidePaneManager; +import org.jabref.gui.SidePaneType; +import org.jabref.gui.actions.Action; +import org.jabref.gui.actions.ActionFactory; +import org.jabref.gui.actions.StandardActions; +import org.jabref.gui.help.HelpAction; +import org.jabref.gui.icon.IconTheme; +import org.jabref.gui.search.SearchTextField; +import org.jabref.gui.util.ViewModelListCellFactory; +import org.jabref.logic.importer.SearchBasedFetcher; +import org.jabref.logic.l10n.Localization; +import org.jabref.preferences.JabRefPreferences; + +import org.fxmisc.easybind.EasyBind; + +public class WebSearchPane extends SidePaneComponent { + + private final JabRefPreferences preferences; + private final WebSearchPaneViewModel viewModel; + + public WebSearchPane(SidePaneManager sidePaneManager, JabRefPreferences preferences, JabRefFrame frame) { + super(sidePaneManager, IconTheme.JabRefIcons.WWW, Localization.lang("Web search")); + this.preferences = preferences; + this.viewModel = new WebSearchPaneViewModel(preferences.getImportFormatPreferences(), frame, preferences); + } + + @Override + public Action getToggleAction() { + return StandardActions.TOGGLE_WEB_SEARCH; + } + + @Override + protected Node createContentPane() { + // Setup combo box for fetchers + ComboBox fetchers = new ComboBox<>(); + new ViewModelListCellFactory() + .withText(SearchBasedFetcher::getName) + .install(fetchers); + fetchers.itemsProperty().bind(viewModel.fetchersProperty()); + fetchers.valueProperty().bindBidirectional(viewModel.selectedFetcherProperty()); + fetchers.setMaxWidth(Double.POSITIVE_INFINITY); + + // Create help button for currently selected fetcher + StackPane helpButtonContainer = new StackPane(); + ActionFactory factory = new ActionFactory(preferences.getKeyBindingRepository()); + EasyBind.subscribe(viewModel.selectedFetcherProperty(), fetcher -> { + if ((fetcher != null) && fetcher.getHelpPage().isPresent()) { + HelpAction helpCommand = new HelpAction(fetcher.getHelpPage().get()); + Button helpButton = factory.createIconButton(StandardActions.HELP, helpCommand.getCommand()); + helpButtonContainer.getChildren().setAll(helpButton); + } else { + helpButtonContainer.getChildren().clear(); + } + }); + HBox fetcherContainer = new HBox(fetchers, helpButtonContainer); + HBox.setHgrow(fetchers, Priority.ALWAYS); + + // Create text field for query input + TextField query = SearchTextField.create(); + viewModel.queryProperty().bind(query.textProperty()); + + // Create button that triggers search + Button search = new Button(Localization.lang("Search")); + search.setDefaultButton(true); + search.setOnAction(event -> viewModel.search()); + + // Put everything together + VBox container = new VBox(); + container.setAlignment(Pos.CENTER); + container.getChildren().addAll(fetcherContainer, query, search); + return container; + } + + @Override + public SidePaneType getType() { + return SidePaneType.WEB_SEARCH; + } + + @Override + public void beforeClosing() { + preferences.putBoolean(JabRefPreferences.WEB_SEARCH_VISIBLE, Boolean.FALSE); + } + + @Override + public void afterOpening() { + preferences.putBoolean(JabRefPreferences.WEB_SEARCH_VISIBLE, Boolean.TRUE); + } + + @Override + public Priority getResizePolicy() { + return Priority.NEVER; + } +} diff --git a/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModel.java b/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModel.java new file mode 100644 index 00000000000..984b11025d9 --- /dev/null +++ b/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModel.java @@ -0,0 +1,117 @@ +package org.jabref.gui.importer.fetcher; + +import java.util.Comparator; +import java.util.List; + +import javax.swing.SwingUtilities; + +import javafx.beans.property.ListProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; + +import org.jabref.JabRefExecutorService; +import org.jabref.gui.JabRefFrame; +import org.jabref.gui.importer.ImportInspectionDialog; +import org.jabref.logic.importer.FetcherException; +import org.jabref.logic.importer.ImportFormatPreferences; +import org.jabref.logic.importer.SearchBasedFetcher; +import org.jabref.logic.importer.WebFetcher; +import org.jabref.logic.importer.WebFetchers; +import org.jabref.logic.l10n.Localization; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.strings.StringUtil; +import org.jabref.preferences.JabRefPreferences; + +import org.fxmisc.easybind.EasyBind; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WebSearchPaneViewModel { + + private static final Logger LOGGER = LoggerFactory.getLogger(WebSearchPaneViewModel.class); + + private final ObjectProperty selectedFetcher = new SimpleObjectProperty<>(); + private final ListProperty fetchers = new SimpleListProperty<>(FXCollections.observableArrayList()); + private final StringProperty query = new SimpleStringProperty(); + private final JabRefFrame frame; + + public WebSearchPaneViewModel(ImportFormatPreferences importPreferences, JabRefFrame frame, JabRefPreferences preferences) { + // TODO: Rework so that we don't rely on JabRefFrame and not the complete preferences + this.frame = frame; + + List allFetchers = WebFetchers.getSearchBasedFetchers(importPreferences); + allFetchers.sort(Comparator.comparing(WebFetcher::getName)); + fetchers.setAll(allFetchers); + + // Choose last-selected fetcher as default + int defaultFetcherIndex = preferences.getInt(JabRefPreferences.SELECTED_FETCHER_INDEX); + if ((defaultFetcherIndex <= 0) || (defaultFetcherIndex >= fetchers.size())) { + selectedFetcherProperty().setValue(fetchers.get(0)); + } else { + selectedFetcherProperty().setValue(fetchers.get(defaultFetcherIndex)); + } + EasyBind.subscribe(selectedFetcherProperty(), newFetcher -> { + int newIndex = fetchers.indexOf(newFetcher); + preferences.putInt(JabRefPreferences.SELECTED_FETCHER_INDEX, newIndex); + }); + } + + public ObservableList getFetchers() { + return fetchers.get(); + } + + public ListProperty fetchersProperty() { + return fetchers; + } + + public SearchBasedFetcher getSelectedFetcher() { + return selectedFetcher.get(); + } + + public ObjectProperty selectedFetcherProperty() { + return selectedFetcher; + } + + public String getQuery() { + return query.get(); + } + + public StringProperty queryProperty() { + return query; + } + + public void search() { + if (StringUtil.isBlank(getQuery())) { + frame.output(Localization.lang("Please enter a search string")); + return; + } + + if (frame.getCurrentBasePanel() == null) { + frame.output(Localization.lang("Please open or start a new library before searching")); + return; + } + + SearchBasedFetcher activeFetcher = getSelectedFetcher(); + final ImportInspectionDialog dialog = new ImportInspectionDialog(frame, frame.getCurrentBasePanel(), + activeFetcher.getName(), false); + + SwingUtilities.invokeLater(() -> dialog.setVisible(true)); + + JabRefExecutorService.INSTANCE.execute(() -> { + dialog.setStatus(Localization.lang("Processing %0", getQuery())); + try { + List matches = activeFetcher.performSearch(getQuery().trim()); + dialog.addEntries(matches); + dialog.entryListComplete(); + } catch (FetcherException e) { + LOGGER.error("Error while fetching from " + activeFetcher.getName(), e); + dialog.showErrorMessage(activeFetcher.getName(), e.getLocalizedMessage()); + } + }); + } +} diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeEntries.java b/src/main/java/org/jabref/gui/mergeentries/MergeEntries.java index 2bc9c4d90bd..661f5ae8004 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeEntries.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeEntries.java @@ -34,6 +34,7 @@ import org.jabref.gui.FXDialogService; import org.jabref.gui.PreviewPanel; import org.jabref.gui.customjfx.CustomJFXPanel; +import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.component.DiffHighlightingTextPane; import org.jabref.logic.bibtex.BibEntryWriter; import org.jabref.logic.bibtex.LatexFieldFormatter; @@ -178,10 +179,12 @@ private void initialize() { // Setup a PreviewPanel and a Bibtex source box for the merged entry mainPanel.add(boldFontLabel(Localization.lang("Merged entry")), CELL_CONSTRAINTS.xyw(1, 6, 6)); - entryPreview = new PreviewPanel(null, null, Globals.getKeyPrefs(), Globals.prefs.getPreviewPreferences(), new FXDialogService()); - entryPreview.setEntry(mergedEntry); - JFXPanel container = CustomJFXPanel.wrap(new Scene(entryPreview)); - mainPanel.add(container, CELL_CONSTRAINTS.xyw(1, 8, 6)); + DefaultTaskExecutor.runInJavaFXThread(() -> { + entryPreview = new PreviewPanel(null, null, Globals.getKeyPrefs(), Globals.prefs.getPreviewPreferences(), new FXDialogService()); + entryPreview.setEntry(mergedEntry); + JFXPanel container = CustomJFXPanel.wrap(new Scene(entryPreview)); + mainPanel.add(container, CELL_CONSTRAINTS.xyw(1, 8, 6)); + }); mainPanel.add(boldFontLabel(Localization.lang("Merged BibTeX source code")), CELL_CONSTRAINTS.xyw(8, 6, 4)); diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java index e88a3c139b7..39a9e6f789b 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java @@ -3,7 +3,6 @@ import java.util.List; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JSeparator; import org.jabref.gui.BasePanel; @@ -33,7 +32,7 @@ public class MergeEntriesDialog extends JabRefDialog { private final DialogService dialogService; public MergeEntriesDialog(BasePanel panel, DialogService dialogService) { - super((JFrame) null, MERGE_ENTRIES, true, MergeEntriesDialog.class); + super(MERGE_ENTRIES, true, MergeEntriesDialog.class); this.dialogService = dialogService; this.panel = panel; diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeFetchedEntryDialog.java b/src/main/java/org/jabref/gui/mergeentries/MergeFetchedEntryDialog.java index 1b54098bec5..516f59f98b9 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeFetchedEntryDialog.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeFetchedEntryDialog.java @@ -8,7 +8,6 @@ import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JSeparator; import org.jabref.gui.BasePanel; @@ -44,7 +43,7 @@ public class MergeFetchedEntryDialog extends JabRefDialog { public MergeFetchedEntryDialog(BasePanel panel, BibEntry originalEntry, BibEntry fetchedEntry, String type) { - super((JFrame) null, Localization.lang("Merge entry with %0 information", type), true, MergeFetchedEntryDialog.class); + super(Localization.lang("Merge entry with %0 information", type), true, MergeFetchedEntryDialog.class); this.panel = panel; this.originalEntry = originalEntry; diff --git a/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java b/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java index c5b9468ff0a..f2aee0e94fa 100644 --- a/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java +++ b/src/main/java/org/jabref/gui/plaintextimport/TextInputDialog.java @@ -134,7 +134,7 @@ public class TextInputDialog extends JabRefDialog { public TextInputDialog(JabRefFrame frame, BibEntry bibEntry) { - super(null, true, TextInputDialog.class); + super(true, TextInputDialog.class); this.frame = Objects.requireNonNull(frame); diff --git a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java index ba94be7d18c..46dad750895 100644 --- a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java @@ -1,16 +1,18 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.util.Optional; - -import javax.swing.BorderFactory; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextField; - +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.shape.Line; import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.gui.remote.JabRefMessageHandler; import org.jabref.gui.util.DefaultTaskExecutor; @@ -21,18 +23,18 @@ import org.jabref.logic.remote.RemoteUtil; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; +import java.awt.*; +import java.util.Optional; class AdvancedTab extends JPanel implements PrefsTab { private final JabRefPreferences preferences; - private final JCheckBox useRemoteServer; - private final JCheckBox useIEEEAbrv; - private final JTextField remoteServerPort; - - private final JCheckBox useCaseKeeperOnSearch; - private final JCheckBox useUnitFormatterOnSearch; + private final CheckBox useRemoteServer; + private final CheckBox useIEEEAbrv; + private final TextField remoteServerPort; + private final CheckBox useCaseKeeperOnSearch; + private final CheckBox useUnitFormatterOnSearch; private final RemotePreferences remotePreferences; private final DialogService dialogService; @@ -41,55 +43,48 @@ public AdvancedTab(DialogService dialogService, JabRefPreferences prefs) { preferences = prefs; remotePreferences = prefs.getRemotePreferences(); - useRemoteServer = new JCheckBox(Localization.lang("Listen for remote operation on port") + ':'); - useIEEEAbrv = new JCheckBox(Localization.lang("Use IEEE LaTeX abbreviations")); - remoteServerPort = new JTextField(); - useCaseKeeperOnSearch = new JCheckBox(Localization.lang("Add {} to specified title words on search to keep the correct case")); - useUnitFormatterOnSearch = new JCheckBox(Localization.lang("Format units by adding non-breaking separators and keeping the correct case on search")); - - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:3dlu", //, 4dlu, fill:pref",// 4dlu, left:pref, 4dlu", - ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JPanel pan = new JPanel(); - - builder.appendSeparator(Localization.lang("Remote operation")); - builder.nextLine(); - builder.append(new JPanel()); - builder.append(new JLabel("" - + Localization.lang("This feature lets new files be opened or imported into an " - + "already running instance of JabRef
instead of opening a new instance. For instance, this " - + "is useful when you open a file in JabRef
from your web browser." - + "
Note that this will prevent you from running more than one instance of JabRef at a time.") - + "")); - builder.nextLine(); - builder.append(new JPanel()); - - JPanel p = new JPanel(); - p.add(useRemoteServer); - p.add(remoteServerPort); - p.add(new HelpAction(HelpFile.REMOTE).getHelpButton()); - builder.append(p); - - // IEEE - builder.nextLine(); - builder.appendSeparator(Localization.lang("Search %0", "IEEEXplore")); - builder.nextLine(); - builder.append(new JPanel()); - builder.append(useIEEEAbrv); - - builder.nextLine(); - builder.appendSeparator(Localization.lang("Import conversions")); - builder.nextLine(); - builder.append(pan); - builder.append(useCaseKeeperOnSearch); - builder.nextLine(); - builder.append(pan); - builder.append(useUnitFormatterOnSearch); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + useRemoteServer = new CheckBox(Localization.lang("Listen for remote operation on port") + ':'); + useIEEEAbrv = new CheckBox(Localization.lang("Use IEEE LaTeX abbreviations")); + remoteServerPort = new TextField(); + useCaseKeeperOnSearch = new CheckBox(Localization.lang("Add {} to specified title words on search to keep the correct case")); + useUnitFormatterOnSearch = new CheckBox(Localization.lang("Format units by adding non-breaking separators and keeping the correct case on search")); + + GridPane builder = new GridPane(); + builder.add(new Label(Localization.lang("Remote operation")),1,1); + builder.add(new Separator(),2,1); + builder.add(new Pane(),1,2); + builder.add(new Label(Localization.lang("This feature lets new files be opened or imported into an already running instance of JabRef instead of opening a new instance. For")),2,3); + builder.add(new Label(Localization.lang( "instance, this is useful when you open a file in JabRef from your web browser. ")),2,4); + builder.add(new Label(Localization.lang("Note that this will prevent you from running more than one instance of JabRef at a time.")),2,5); + builder.add(new Line(),2,6); + builder.add(new Pane(),2,7); + + HBox p = new HBox(); + p.getChildren().add(useRemoteServer); + p.getChildren().add(remoteServerPort); + Button button = new Button("?"); + button.setOnAction(event -> new HelpAction(HelpFile.REMOTE).getHelpButton().doClick()); + p.getChildren().add(button); + + builder.add(p,2,9); + + builder.add(new Line(),2,10); + builder.add(new Label((Localization.lang("Search %0", "IEEEXplore"))),1,11); + builder.add(new Separator(),2,11); + builder.add(new Pane(),2,12); + builder.add(useIEEEAbrv,2,13); + + builder.add(new Line(),2,16); + builder.add(new Label(Localization.lang("Import conversions")),1,17); + builder.add(new Separator(),2,17); + + builder.add(useCaseKeeperOnSearch,2,19); + builder.add(new Pane(),2,20); + builder.add(useUnitFormatterOnSearch,2,21); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); setLayout(new BorderLayout()); - add(pan, BorderLayout.CENTER); + add(panel, BorderLayout.CENTER); } diff --git a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java index 46e4879f5aa..9f65eb85c3c 100644 --- a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java @@ -1,20 +1,25 @@ package org.jabref.gui.preftabs; import java.awt.BorderLayout; -import java.awt.Font; -import java.awt.GridBagLayout; import javax.swing.BorderFactory; -import javax.swing.JCheckBox; import javax.swing.JPanel; +import javafx.embed.swing.JFXPanel; +import javafx.geometry.Insets; +import javafx.scene.Scene; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; + import org.jabref.gui.DialogService; -import org.jabref.gui.GUIGlobals; +import org.jabref.gui.customjfx.CustomJFXPanel; +import org.jabref.gui.util.ControlHelper; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,8 +29,9 @@ class AppearancePrefsTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; - private final Font usedFont = GUIGlobals.currentFont; - private final JCheckBox fxFontTweaksLAF; + private final CheckBox fontTweaksLAF; + private final TextField fontSize; + private final CheckBox overrideFonts; private final DialogService dialogService; @@ -39,53 +45,46 @@ public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) this.prefs = prefs; setLayout(new BorderLayout()); - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, fill:pref", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - - fxFontTweaksLAF = new JCheckBox(Localization.lang("Tweak font rendering for entry editor on Linux")); - // Only list L&F which are available - - // only the default L&F shows the OSX specific first drop-down menu - - builder.append(fxFontTweaksLAF); - builder.nextLine(); - - builder.leadingColumnOffset(2); - - JPanel upper = new JPanel(); - JPanel sort = new JPanel(); - JPanel namesp = new JPanel(); - JPanel iconCol = new JPanel(); - GridBagLayout gbl = new GridBagLayout(); - upper.setLayout(gbl); - sort.setLayout(gbl); - namesp.setLayout(gbl); - iconCol.setLayout(gbl); - - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + overrideFonts = new CheckBox(Localization.lang("Override default font settings")); + fontSize = new TextField(); + fontSize.setTextFormatter(ControlHelper.getIntegerTextFormatter()); + Label fontSizeLabel = new Label(Localization.lang("Font size:")); + HBox fontSizeContainer = new HBox(fontSizeLabel, fontSize); + VBox.setMargin(fontSizeContainer, new Insets(0, 0, 0, 35)); + fontSizeContainer.disableProperty().bind(overrideFonts.selectedProperty().not()); + fontTweaksLAF = new CheckBox(Localization.lang("Tweak font rendering for entry editor on Linux")); + + VBox container = new VBox(); + container.getChildren().addAll(overrideFonts, fontSizeContainer, fontTweaksLAF); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(container)); + panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + add(panel, BorderLayout.CENTER); } @Override public void setValues() { - fxFontTweaksLAF.setSelected(prefs.getBoolean(JabRefPreferences.FX_FONT_RENDERING_TWEAK)); + fontTweaksLAF.setSelected(prefs.getBoolean(JabRefPreferences.FX_FONT_RENDERING_TWEAK)); + overrideFonts.setSelected(prefs.getBoolean(JabRefPreferences.OVERRIDE_DEFAULT_FONT_SIZE)); + fontSize.setText(String.valueOf(prefs.getInt(JabRefPreferences.MAIN_FONT_SIZE))); } @Override public void storeSettings() { - boolean isRestartRequired = false; - // Java FX font rendering tweak final boolean oldFxTweakValue = prefs.getBoolean(JabRefPreferences.FX_FONT_RENDERING_TWEAK); - prefs.putBoolean(JabRefPreferences.FX_FONT_RENDERING_TWEAK, fxFontTweaksLAF.isSelected()); - isRestartRequired |= oldFxTweakValue != fxFontTweaksLAF.isSelected(); - - prefs.put(JabRefPreferences.FONT_FAMILY, usedFont.getFamily()); - prefs.putInt(JabRefPreferences.FONT_STYLE, usedFont.getStyle()); - prefs.putInt(JabRefPreferences.FONT_SIZE, usedFont.getSize()); - GUIGlobals.currentFont = usedFont; - + prefs.putBoolean(JabRefPreferences.FX_FONT_RENDERING_TWEAK, fontTweaksLAF.isSelected()); + + final boolean oldOverrideDefaultFontSize = prefs.getBoolean(JabRefPreferences.OVERRIDE_DEFAULT_FONT_SIZE); + final int oldFontSize = prefs.getInt(JabRefPreferences.MAIN_FONT_SIZE); + prefs.putBoolean(JabRefPreferences.OVERRIDE_DEFAULT_FONT_SIZE, overrideFonts.isSelected()); + int newFontSize = Integer.parseInt(fontSize.getText()); + prefs.putInt(JabRefPreferences.MAIN_FONT_SIZE, newFontSize); + + boolean isRestartRequired = + oldFxTweakValue != fontTweaksLAF.isSelected() + || oldOverrideDefaultFontSize != overrideFonts.isSelected() + || oldFontSize != newFontSize; if (isRestartRequired) { dialogService.showWarningDialogAndWait(Localization.lang("Settings"), Localization.lang("Some appearance settings you changed require to restart JabRef to come into effect.")); diff --git a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java index 1d353967c07..5cd1f3a54c5 100644 --- a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java +++ b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java @@ -1,23 +1,21 @@ package org.jabref.gui.preftabs; -import java.awt.GridBagConstraints; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; - +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.bibtexkeypattern.BibtexKeyPatternPanel; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.model.bibtexkeypattern.GlobalBibtexKeyPattern; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import java.awt.*; /** * The Preferences panel for key generation. @@ -25,22 +23,23 @@ class BibtexKeyPatternPrefTab extends BibtexKeyPatternPanel implements PrefsTab { private final JabRefPreferences prefs; + private final GridPane builder = new GridPane(); + private final CheckBox dontOverwrite = new CheckBox(Localization.lang("Do not overwrite existing keys")); + private final CheckBox warnBeforeOverwriting = new CheckBox(Localization.lang("Warn before overwriting existing keys")); + private final CheckBox generateOnSave = new CheckBox(Localization.lang("Generate keys before saving (for entries without a key)")); + private final CheckBox autoGenerateOnImport = new CheckBox(Localization.lang("Generate keys for imported entries")); - private final JCheckBox dontOverwrite = new JCheckBox(Localization.lang("Do not overwrite existing keys")); - private final JCheckBox warnBeforeOverwriting = new JCheckBox(Localization.lang("Warn before overwriting existing keys")); - private final JCheckBox generateOnSave = new JCheckBox(Localization.lang("Generate keys before saving (for entries without a key)")); - private final JCheckBox autoGenerateOnImport = new JCheckBox(Localization.lang("Generate keys for imported entries")); - - private final JRadioButton letterStartA = new JRadioButton(Localization.lang("Ensure unique keys using letters (a, b, ...)")); - private final JRadioButton letterStartB = new JRadioButton(Localization.lang("Ensure unique keys using letters (b, c, ...)")); - private final JRadioButton alwaysAddLetter = new JRadioButton(Localization.lang("Always add letter (a, b, ...) to generated keys")); + private final RadioButton letterStartA = new RadioButton(Localization.lang("Ensure unique keys using letters (a, b, ...)")); + private final RadioButton letterStartB = new RadioButton(Localization.lang("Ensure unique keys using letters (b, c, ...)")); + private final RadioButton alwaysAddLetter = new RadioButton(Localization.lang("Always add letter (a, b, ...) to generated keys")); - private final JTextField keyPatternRegex = new JTextField(20); - private final JTextField keyPatternReplacement = new JTextField(20); + private final TextField keyPatternRegex = new TextField(); + private final TextField keyPatternReplacement = new TextField(); public BibtexKeyPatternPrefTab(JabRefPreferences prefs, BasePanel panel) { super(panel); + builder.add(super.getPanel(),1,1); this.prefs = prefs; appendKeyGeneratorSettings(); } @@ -81,55 +80,32 @@ public void storeSettings() { } private void appendKeyGeneratorSettings() { - ButtonGroup bg = new ButtonGroup(); - bg.add(letterStartA); - bg.add(letterStartB); - bg.add(alwaysAddLetter); + // Build a panel for checkbox settings: - FormLayout layout = new FormLayout - ("1dlu, 8dlu, left:pref, 8dlu, left:pref", ""); - JPanel pan = new JPanel(); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.appendSeparator(Localization.lang("Key generator settings")); - - builder.nextLine(); - builder.append(pan); - builder.append(autoGenerateOnImport); - builder.append(letterStartA); - builder.nextLine(); - builder.append(pan); - builder.append(warnBeforeOverwriting); - builder.append(letterStartB); - builder.nextLine(); - builder.append(pan); - builder.append(dontOverwrite); - builder.append(alwaysAddLetter); - builder.nextLine(); - builder.append(pan); - builder.append(generateOnSave); - builder.nextLine(); - builder.append(pan); - builder.append(Localization.lang("Replace (regular expression)") + ':'); - builder.append(Localization.lang("by") + ':'); - - builder.nextLine(); - builder.append(pan); - builder.append(keyPatternRegex); - builder.append(keyPatternReplacement); - - builder.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - con.gridx = 1; - con.gridy = 3; - con.gridwidth = GridBagConstraints.REMAINDER; - con.weightx = 1; - con.fill = GridBagConstraints.BOTH; - gbl.setConstraints(builder.getPanel(), con); - add(builder.getPanel()); - - dontOverwrite.addChangeListener(e -> + + builder.add(new Label(Localization.lang("Key generator settings")),1,10); + builder.add(autoGenerateOnImport,1,11); + builder.add(letterStartA,2,11); + builder.add(warnBeforeOverwriting,1,12); + builder.add(letterStartB,2,12); + builder.add(dontOverwrite,1,13); + builder.add(alwaysAddLetter,2,13); + builder.add(generateOnSave,1,14); + + builder.add((new Label(Localization.lang("Replace (regular expression)") + ':')),1,15); + builder.add(new Label(Localization.lang("by") + ':'),2,15); + + builder.add(keyPatternRegex,1,16); + builder.add(keyPatternReplacement,2,16); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); + + dontOverwrite.setOnAction(e -> // Warning before overwriting is only relevant if overwriting can happen: - warnBeforeOverwriting.setEnabled(!dontOverwrite.isSelected())); + warnBeforeOverwriting.setDisable(dontOverwrite.isSelected())); } @Override @@ -157,7 +133,7 @@ public void setValues() { } // Warning before overwriting is only relevant if overwriting can happen: - warnBeforeOverwriting.setEnabled(!dontOverwrite.isSelected()); + warnBeforeOverwriting.setDisable(dontOverwrite.isSelected()); keyPatternRegex.setText(Globals.prefs.get(JabRefPreferences.KEY_PATTERN_REGEX)); keyPatternReplacement.setText(Globals.prefs.get(JabRefPreferences.KEY_PATTERN_REPLACEMENT)); diff --git a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java index 332ebc84de6..4bb29b27710 100644 --- a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java @@ -1,47 +1,42 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Insets; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; - +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import org.jabref.gui.autocompleter.AutoCompleteFirstNameMode; import org.jabref.gui.autocompleter.AutoCompletePreferences; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.keyboard.EmacsKeyBindings; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.CellConstraints; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; +import java.awt.*; import static org.jabref.gui.autocompleter.AutoCompleteFirstNameMode.ONLY_ABBREVIATED; import static org.jabref.gui.autocompleter.AutoCompleteFirstNameMode.ONLY_FULL; class EntryEditorPrefsTab extends JPanel implements PrefsTab { - private final JCheckBox autoOpenForm; - private final JCheckBox defSource; - private final JCheckBox emacsMode; - private final JCheckBox emacsRebindCtrlA; - private final JCheckBox emacsRebindCtrlF; - private final JCheckBox autoComplete; - private final JCheckBox recommendations; - private final JCheckBox validation; - private final JRadioButton autoCompBoth; - private final JRadioButton autoCompFF; - private final JRadioButton autoCompLF; - private final JRadioButton firstNameModeFull; - private final JRadioButton firstNameModeAbbr; - private final JRadioButton firstNameModeBoth; - - private final JTextField autoCompFields; + private final CheckBox autoOpenForm; + private final CheckBox defSource; + private final CheckBox emacsMode; + private final CheckBox emacsRebindCtrlA; + private final CheckBox emacsRebindCtrlF; + private final CheckBox autoComplete; + private final CheckBox recommendations; + private final CheckBox validation; + private final RadioButton autoCompBoth; + private final RadioButton autoCompFF; + private final RadioButton autoCompLF; + private final RadioButton firstNameModeFull; + private final RadioButton firstNameModeAbbr; + private final RadioButton firstNameModeBoth; + + private final TextField autoCompFields; private final JabRefPreferences prefs; private final AutoCompletePreferences autoCompletePreferences; @@ -51,102 +46,81 @@ public EntryEditorPrefsTab(JabRefPreferences prefs) { autoCompletePreferences = prefs.getAutoCompletePreferences(); setLayout(new BorderLayout()); - autoOpenForm = new JCheckBox(Localization.lang("Open editor when a new entry is created")); - defSource = new JCheckBox(Localization.lang("Show BibTeX source by default")); - emacsMode = new JCheckBox(Localization.lang("Use Emacs key bindings")); - emacsRebindCtrlA = new JCheckBox(Localization.lang("Rebind C-a, too")); - emacsRebindCtrlF = new JCheckBox(Localization.lang("Rebind C-f, too")); - autoComplete = new JCheckBox(Localization.lang("Enable word/name autocompletion")); - recommendations = new JCheckBox(Localization.lang("Show 'Related Articles' tab")); - validation = new JCheckBox(Localization.lang("Show validation messages")); + autoOpenForm = new CheckBox(Localization.lang("Open editor when a new entry is created")); + defSource = new CheckBox(Localization.lang("Show BibTeX source by default")); + emacsMode = new CheckBox(Localization.lang("Use Emacs key bindings")); + emacsRebindCtrlA = new CheckBox(Localization.lang("Rebind C-a, too")); + emacsRebindCtrlF = new CheckBox(Localization.lang("Rebind C-f, too")); + autoComplete = new CheckBox(Localization.lang("Enable word/name autocompletion")); + recommendations = new CheckBox(Localization.lang("Show 'Related Articles' tab")); + validation = new CheckBox(Localization.lang("Show validation messages")); // allowed name formats - autoCompFF = new JRadioButton(Localization.lang("Autocomplete names in 'Firstname Lastname' format only")); - autoCompLF = new JRadioButton(Localization.lang("Autocomplete names in 'Lastname, Firstname' format only")); - autoCompBoth = new JRadioButton(Localization.lang("Autocomplete names in both formats")); - ButtonGroup buttonGroup = new ButtonGroup(); - buttonGroup.add(autoCompLF); - buttonGroup.add(autoCompFF); - buttonGroup.add(autoCompBoth); + autoCompFF = new RadioButton(Localization.lang("Autocomplete names in 'Firstname Lastname' format only")); + autoCompLF = new RadioButton(Localization.lang("Autocomplete names in 'Lastname, Firstname' format only")); + autoCompBoth = new RadioButton(Localization.lang("Autocomplete names in both formats")); - // treatment of first name - firstNameModeFull = new JRadioButton(Localization.lang("Use full firstname whenever possible")); - firstNameModeAbbr = new JRadioButton(Localization.lang("Use abbreviated firstname whenever possible")); - firstNameModeBoth = new JRadioButton(Localization.lang("Use abbreviated and full firstname")); - ButtonGroup firstNameModeButtonGroup = new ButtonGroup(); - firstNameModeButtonGroup.add(firstNameModeFull); - firstNameModeButtonGroup.add(firstNameModeAbbr); - firstNameModeButtonGroup.add(firstNameModeBoth); - Insets marg = new Insets(0, 20, 3, 0); + // treatment of first name + firstNameModeFull = new RadioButton(Localization.lang("Use full firstname whenever possible")); + firstNameModeAbbr = new RadioButton(Localization.lang("Use abbreviated firstname whenever possible")); + firstNameModeBoth = new RadioButton(Localization.lang("Use abbreviated and full firstname")); - emacsRebindCtrlA.setMargin(marg); // We need a listener on showSource to enable and disable the source panel-related choices: - emacsMode.addChangeListener(event -> emacsRebindCtrlA.setEnabled(emacsMode.isSelected())); + emacsMode.setOnAction(event -> emacsRebindCtrlA.setDisable(!emacsMode.isSelected())); - emacsRebindCtrlF.setMargin(marg); // We need a listener on showSource to enable and disable the source panel-related choices: - emacsMode.addChangeListener(event -> emacsRebindCtrlF.setEnabled(emacsMode.isSelected())); + emacsMode.setOnAction(event -> emacsRebindCtrlF.setDisable(!emacsMode.isSelected())); - autoCompFields = new JTextField(40); + autoCompFields = new TextField(); // We need a listener on autoComplete to enable and disable the // autoCompFields text field: - autoComplete.addChangeListener(event -> setAutoCompleteElementsEnabled(autoComplete.isSelected())); - - FormLayout layout = new FormLayout - (// columns - "8dlu, left:pref, 8dlu, fill:150dlu, 4dlu, fill:pref", // 4dlu, left:pref, 4dlu", - // rows 1 to 10 - "pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu," + - // rows 11 to 16 - "pref, 6dlu, pref, 6dlu, pref, 6dlu, " + - // rows 17 to 27 - "pref, 6dlu, pref, pref, pref, pref, 6dlu, pref, pref, pref, pref, pref"); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - CellConstraints cc = new CellConstraints(); - builder.addSeparator(Localization.lang("Editor options"), cc.xyw(1, 1, 5)); - builder.add(autoOpenForm, cc.xy(2, 3)); - builder.add(defSource, cc.xy(2, 5)); - builder.add(emacsMode, cc.xy(2, 7)); - builder.add(emacsRebindCtrlA, cc.xy(2, 9)); - builder.add(emacsRebindCtrlF, cc.xy(2, 11)); - builder.add(recommendations, cc.xy(2,13)); - builder.add(validation, cc.xy(2,15)); - - builder.addSeparator(Localization.lang("Autocompletion options"), cc.xyw(1, 17, 5)); - builder.add(autoComplete, cc.xy(2, 19)); - - DefaultFormBuilder builder3 = new DefaultFormBuilder(new FormLayout("left:pref, 4dlu, fill:150dlu","")); - JLabel label = new JLabel(Localization.lang("Use autocompletion for the following fields") + ":"); - - builder3.append(label); - builder3.append(autoCompFields); - builder.add(builder3.getPanel(), cc.xyw(2, 21, 3)); - - builder.addSeparator(Localization.lang("Name format used for autocompletion"), cc.xyw(2, 23, 4)); - builder.add(autoCompFF, cc.xy(2, 24)); - builder.add(autoCompLF, cc.xy(2, 25)); - builder.add(autoCompBoth, cc.xy(2, 26)); - - builder.addSeparator(Localization.lang("Treatment of first names"), cc.xyw(2, 29, 4)); - builder.add(firstNameModeAbbr, cc.xy(2, 30)); - builder.add(firstNameModeFull, cc.xy(2, 31)); - builder.add(firstNameModeBoth, cc.xy(2, 32)); - - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + autoComplete.setOnAction(event -> setAutoCompleteElementsEnabled(autoComplete.isSelected())); + + GridPane builder = new GridPane(); + + builder.add(new Label(Localization.lang("Editor options")),1,1); + builder.add(new Separator(),2,1); + builder.add(autoOpenForm, 2,2); + builder.add(defSource, 2,3); + builder.add(emacsMode,2,4); + builder.add(emacsRebindCtrlA,2,5); + builder.add(emacsRebindCtrlF, 2,6); + builder.add(recommendations, 2,7); + builder.add(validation, 2,8); + + builder.add(new Label(Localization.lang("Autocompletion options")),1,9); + builder.add(autoComplete, 2,10); + + Label label = new Label(Localization.lang("Use autocompletion for the following fields") + ":"); + + builder.add(label,2,11); + builder.add(autoCompFields,3,11); + + builder.add(new Label(Localization.lang("Name format used for autocompletion")),1,14); + builder.add(autoCompFF,2,15); + builder.add(autoCompLF, 2,16); + builder.add(autoCompBoth, 2,17); + + builder.add(new Label(Localization.lang("Treatment of first names")),1,18); + builder.add(firstNameModeAbbr, 2,19); + builder.add(firstNameModeFull,2,30); + builder.add(firstNameModeBoth, 2,31); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); } private void setAutoCompleteElementsEnabled(boolean enabled) { - autoCompFields.setEnabled(enabled); - autoCompLF.setEnabled(enabled); - autoCompFF.setEnabled(enabled); - autoCompBoth.setEnabled(enabled); - firstNameModeAbbr.setEnabled(enabled); - firstNameModeFull.setEnabled(enabled); - firstNameModeBoth.setEnabled(enabled); + autoCompFields.setDisable(!enabled); + autoCompLF.setDisable(!enabled); + autoCompFF.setDisable(!enabled); + autoCompBoth.setDisable(!enabled); + firstNameModeAbbr.setDisable(!enabled); + firstNameModeFull.setDisable(!enabled); + firstNameModeBoth.setDisable(!enabled); } @Override @@ -181,7 +155,7 @@ public void setValues() { } // similar for emacs CTRL-a and emacs mode - emacsRebindCtrlA.setEnabled(emacsMode.isSelected()); + emacsRebindCtrlA.setDisable(!emacsMode.isSelected()); // Autocomplete fields is only enabled when autocompletion is selected setAutoCompleteElementsEnabled(autoComplete.isSelected()); diff --git a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java index 9fa67b99c12..400b994a096 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java @@ -1,20 +1,21 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JPanel; -import javax.swing.JRadioButton; - +import javafx.embed.swing.JFXPanel; +import javafx.event.EventHandler; +import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.Separator; +import javafx.scene.layout.GridPane; +import javafx.scene.shape.Line; import org.jabref.gui.SaveOrderConfigDisplay; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; /** * Preference tab for file sorting options. @@ -23,59 +24,52 @@ class ExportSortingPrefsTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; - private final JRadioButton exportInOriginalOrder; - private final JRadioButton exportInTableOrder; - private final JRadioButton exportInSpecifiedOrder; + private final RadioButton exportInOriginalOrder; + private final RadioButton exportInTableOrder; + private final RadioButton exportInSpecifiedOrder; private final SaveOrderConfigDisplay exportOrderPanel; public ExportSortingPrefsTab(JabRefPreferences prefs) { this.prefs = prefs; - FormLayout layout = new FormLayout("4dlu, left:pref, 4dlu, fill:pref", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.leadingColumnOffset(1); + GridPane builder = new GridPane(); // EXPORT SORT ORDER // create Components - exportInOriginalOrder = new JRadioButton(Localization.lang("Export entries in their original order")); - exportInTableOrder = new JRadioButton(Localization.lang("Export in current table sort order")); - exportInSpecifiedOrder = new JRadioButton(Localization.lang("Export entries ordered as specified")); - - ButtonGroup buttonGroup = new ButtonGroup(); - buttonGroup.add(exportInOriginalOrder); - buttonGroup.add(exportInTableOrder); - buttonGroup.add(exportInSpecifiedOrder); + exportInOriginalOrder = new RadioButton(Localization.lang("Export entries in their original order")); + exportInTableOrder = new RadioButton(Localization.lang("Export in current table sort order")); + exportInSpecifiedOrder = new RadioButton(Localization.lang("Export entries ordered as specified")); - ActionListener listener = new ActionListener() { + EventHandler listener = new EventHandler() { @Override - public void actionPerformed(ActionEvent e) { - boolean selected = e.getSource() == exportInSpecifiedOrder; + public void handle(javafx.event.ActionEvent event) { + boolean selected = event.getSource() == exportInSpecifiedOrder; exportOrderPanel.setEnabled(selected); } }; - exportInOriginalOrder.addActionListener(listener); - exportInTableOrder.addActionListener(listener); - exportInSpecifiedOrder.addActionListener(listener); + exportInOriginalOrder.setOnAction(listener); + exportInTableOrder.setOnAction(listener); + exportInSpecifiedOrder.setOnAction(listener); // create GUI - builder.appendSeparator(Localization.lang("Export sort order")); - builder.append(exportInOriginalOrder, 1); - builder.nextLine(); - builder.append(exportInTableOrder, 1); - builder.nextLine(); - builder.append(exportInSpecifiedOrder, 1); - builder.nextLine(); + builder.add(new Label(Localization.lang("Export sort order")),1,1); + builder.add(new Separator(),2,1); + builder.add(exportInOriginalOrder, 1,2); + builder.add(new Line(),2,3); + builder.add(exportInTableOrder, 1,4); + builder.add(new Line(),2,5); + builder.add(exportInSpecifiedOrder, 1,6); + builder.add(new Line(),2,7); exportOrderPanel = new SaveOrderConfigDisplay(); - builder.append(exportOrderPanel.getPanel()); - builder.nextLine(); + builder.add(exportOrderPanel.getJFXPanel(),2,8); + builder.add(new Line(),2,9); // COMBINE EVERYTHING - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); setLayout(new BorderLayout()); - add(pan, BorderLayout.CENTER); + add(panel, BorderLayout.CENTER); } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java index b8cab7e7e72..6ef60d1e6a3 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java @@ -16,8 +16,14 @@ import javax.swing.JRadioButton; import javax.swing.JTextField; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.layout.GridPane; import org.jabref.Globals; 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; @@ -34,175 +40,121 @@ class ExternalTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; - private final JTextField emailSubject; - private final JTextField citeCommand; - private final JCheckBox openFoldersOfAttachedFiles; + private final TextField emailSubject; + private final TextField citeCommand; + private final CheckBox openFoldersOfAttachedFiles; - private final JRadioButton defaultConsole; - private final JRadioButton executeConsole; - private final JTextField consoleCommand; - private final JButton browseButton; + private final RadioButton defaultConsole; + private final RadioButton executeConsole; + private final TextField consoleCommand; + private final Button browseButton; - private final JRadioButton adobeAcrobatReader; - private final JRadioButton sumatraReader; - private final JTextField adobeAcrobatReaderPath; - private final JTextField sumatraReaderPath; - private final JButton browseAdobeAcrobatReader; - private final JButton browseSumatraReader; + private final RadioButton adobeAcrobatReader; + private final RadioButton sumatraReader; + private final TextField adobeAcrobatReaderPath; + private final TextField sumatraReaderPath; + private final Button browseAdobeAcrobatReader; + private final Button browseSumatraReader; public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPreferences prefs) { this.prefs = prefs; setLayout(new BorderLayout()); - JButton editFileTypes = new JButton(Localization.lang("Manage external file types")); - citeCommand = new JTextField(25); - editFileTypes.addActionListener(ExternalFileTypeEditor.getAction()); + Button editFileTypes = new Button(Localization.lang("Manage external file types")); + citeCommand = new TextField(); + editFileTypes.setOnAction(e->ExternalFileTypeEditor.getAction()); - defaultConsole = new JRadioButton(Localization.lang("Use default terminal emulator")); - executeConsole = new JRadioButton(Localization.lang("Execute command") + ":"); - consoleCommand = new JTextField(); - browseButton = new JButton(Localization.lang("Browse")); + defaultConsole = new RadioButton(Localization.lang("Use default terminal emulator")); + executeConsole = new RadioButton(Localization.lang("Execute command") + ":"); + consoleCommand = new TextField(); + browseButton = new Button(Localization.lang("Browse")); - adobeAcrobatReader = new JRadioButton(Localization.lang("Adobe Acrobat Reader")); - adobeAcrobatReaderPath = new JTextField(); - browseAdobeAcrobatReader = new JButton(Localization.lang("Browse")); + adobeAcrobatReader = new RadioButton(Localization.lang("Adobe Acrobat Reader")); + adobeAcrobatReaderPath = new TextField(); + browseAdobeAcrobatReader = new Button(Localization.lang("Browse")); - sumatraReader = new JRadioButton(Localization.lang("Sumatra Reader")); - sumatraReaderPath = new JTextField(); - browseSumatraReader = new JButton(Localization.lang("Browse")); + sumatraReader = new RadioButton(Localization.lang("Sumatra Reader")); + sumatraReaderPath = new TextField(); + browseSumatraReader = new Button(Localization.lang("Browse")); - JLabel commandDescription = new JLabel(Localization.lang("Note: Use the placeholder %0 for the location of the opened library file.", "%DIR")); + Label commandDescription = new Label(Localization.lang("Note: Use the placeholder %0 for the location of the opened library file.", "%DIR")); - ButtonGroup consoleOptions = new ButtonGroup(); - consoleOptions.add(defaultConsole); - consoleOptions.add(executeConsole); + defaultConsole.setOnAction(e -> updateExecuteConsoleButtonAndFieldEnabledState()); + executeConsole.setOnAction(e -> updateExecuteConsoleButtonAndFieldEnabledState()); + browseButton.setOnAction(e -> showConsoleChooser()); - ButtonGroup readerOptions = new ButtonGroup(); - readerOptions.add(adobeAcrobatReader); + browseAdobeAcrobatReader.setOnAction(e -> showAdobeChooser()); - JPanel pdfOptionPanel = new JPanel(new GridBagLayout()); - GridBagConstraints pdfLayoutConstrains = new GridBagConstraints(); + GridPane consoleOptionPanel = new GridPane(); + 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); - JPanel consoleOptionPanel = new JPanel(new GridBagLayout()); - GridBagConstraints layoutConstraints = new GridBagConstraints(); + GridPane pdfOptionPanel = new GridPane(); + pdfOptionPanel.add(adobeAcrobatReader, 1,1); + pdfOptionPanel.add(adobeAcrobatReaderPath, 2,1); + pdfOptionPanel.add(browseAdobeAcrobatReader, 3,1); - defaultConsole.addActionListener(e -> updateExecuteConsoleButtonAndFieldEnabledState()); - executeConsole.addActionListener(e -> updateExecuteConsoleButtonAndFieldEnabledState()); - browseButton.addActionListener(e -> showConsoleChooser()); + if (OS.WINDOWS) { + browseSumatraReader.setOnAction(e -> showSumatraChooser()); + pdfOptionPanel.add(sumatraReader, 1,2); + pdfOptionPanel.add(sumatraReaderPath, 2,2); + pdfOptionPanel.add(browseSumatraReader, 3,2); + } - browseAdobeAcrobatReader.addActionListener(e -> showAdobeChooser()); + GridPane builder = new GridPane(); - layoutConstraints.fill = GridBagConstraints.HORIZONTAL; + builder.add(new Label(Localization.lang("Sending of emails")),1,1); + Label lab = new Label(Localization.lang(" Subject for sending an email with references").concat(":")); + builder.add(lab,1,2); + emailSubject = new TextField(); + builder.add(emailSubject,2,2); + openFoldersOfAttachedFiles = new CheckBox(Localization.lang("Automatically open folders of attached files")); + builder.add(openFoldersOfAttachedFiles,1,3); - pdfLayoutConstrains.fill = GridBagConstraints.HORIZONTAL; - layoutConstraints.gridx = 0; - layoutConstraints.gridy = 0; - layoutConstraints.insets = new Insets(0, 0, 6, 0); - consoleOptionPanel.add(defaultConsole, layoutConstraints); + builder.add(new Label(Localization.lang("External programs")),1,4); - layoutConstraints.gridy = 1; - consoleOptionPanel.add(executeConsole, layoutConstraints); - layoutConstraints.gridx = 1; - consoleOptionPanel.add(consoleCommand, layoutConstraints); + GridPane butpan = new GridPane(); + int index = 0; + for (PushToApplication pushToApplication : frame.getPushApplications().getApplications()){ + addSettingsButton(pushToApplication, butpan, index); + index++; + } - layoutConstraints.gridx = 2; - layoutConstraints.insets = new Insets(0, 4, 6, 0); - consoleOptionPanel.add(browseButton, layoutConstraints); + builder.add(butpan,1,5); - layoutConstraints.gridx = 1; - layoutConstraints.gridy = 2; - consoleOptionPanel.add(commandDescription, layoutConstraints); - pdfLayoutConstrains.gridx = 0; - pdfLayoutConstrains.gridy = 0; - pdfLayoutConstrains.insets = new Insets(0, 0, 6, 0); - pdfOptionPanel.add(adobeAcrobatReader, pdfLayoutConstrains); + lab = new Label(Localization.lang("Cite command") + ':'); + builder.add(lab,1,6); + builder.add(citeCommand,2,6); - pdfLayoutConstrains.gridx = 1; - pdfOptionPanel.add(adobeAcrobatReaderPath, pdfLayoutConstrains); - pdfLayoutConstrains.gridx = 2; - pdfOptionPanel.add(browseAdobeAcrobatReader, pdfLayoutConstrains); + builder.add(editFileTypes,1,7); - if (OS.WINDOWS) { - readerOptions.add(sumatraReader); - browseSumatraReader.addActionListener(e -> showSumatraChooser()); - pdfLayoutConstrains.gridy = 1; - pdfLayoutConstrains.gridx = 0; - pdfOptionPanel.add(sumatraReader, pdfLayoutConstrains); + builder.add(new Label(Localization.lang("Open console")),1,8); - pdfLayoutConstrains.gridx = 1; - pdfOptionPanel.add(sumatraReaderPath, pdfLayoutConstrains); + builder.add(consoleOptionPanel,1,9); - pdfLayoutConstrains.gridx = 2; - pdfOptionPanel.add(browseSumatraReader, pdfLayoutConstrains); - } - FormLayout layout = new FormLayout( - "1dlu, 8dlu, left:pref, 4dlu, fill:150dlu, 4dlu, fill:pref", ""); - - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - - builder.appendSeparator(Localization.lang("Sending of emails")); - builder.append(new JPanel()); - JLabel lab = new JLabel(Localization.lang("Subject for sending an email with references").concat(":")); - builder.append(lab); - emailSubject = new JTextField(25); - builder.append(emailSubject); - builder.nextLine(); - builder.append(new JPanel()); - openFoldersOfAttachedFiles = new JCheckBox(Localization.lang("Automatically open folders of attached files")); - builder.append(openFoldersOfAttachedFiles); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("External programs")); - builder.nextLine(); - - JPanel butpan = new JPanel(); - butpan.setLayout(new GridLayout(3, 3)); - for (PushToApplication pushToApplication : frame.getPushApplications().getApplications()) { - addSettingsButton(pushToApplication, butpan); - } - builder.append(new JPanel()); - builder.append(butpan, 3); - - builder.nextLine(); - lab = new JLabel(Localization.lang("Cite command") + ':'); - JPanel pan = new JPanel(); - builder.append(pan); - builder.append(lab); - builder.append(citeCommand); - - builder.nextLine(); - builder.append(pan); - builder.append(editFileTypes); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Open console")); - builder.nextLine(); - builder.append(new JPanel()); - builder.append(consoleOptionPanel); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Open PDF")); - builder.nextLine(); - builder.append(new JPanel()); - builder.append(pdfOptionPanel); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + builder.add(new Label(Localization.lang("Open PDF")),1,10); + builder.add(pdfOptionPanel,1,11); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); } - private void addSettingsButton(final PushToApplication application, JPanel panel) { + private void addSettingsButton(final PushToApplication application, GridPane panel, int index) { PushToApplicationSettings settings = PushToApplications.getSettings(application); - JButton button = new JButton(Localization.lang("Settings for %0", application.getApplicationName()), application.getIcon().getIcon()); - button.addActionListener(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, settings)); - panel.add(button); + Button button = new Button(Localization.lang("Settings for %0", application.getApplicationName())); + button.setOnAction(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, settings)); + panel.add(button,index%2==0?1:2,index/2+1); } @Override @@ -257,8 +209,8 @@ public String getTabName() { } private void updateExecuteConsoleButtonAndFieldEnabledState() { - browseButton.setEnabled(executeConsole.isSelected()); - consoleCommand.setEnabled(executeConsole.isSelected()); + browseButton.setDisable(!executeConsole.isSelected()); + consoleCommand.setDisable(!executeConsole.isSelected()); } private void showConsoleChooser() { diff --git a/src/main/java/org/jabref/gui/preftabs/FileTab.java b/src/main/java/org/jabref/gui/preftabs/FileTab.java index 7bee312c92e..d6cc6adb4a4 100644 --- a/src/main/java/org/jabref/gui/preftabs/FileTab.java +++ b/src/main/java/org/jabref/gui/preftabs/FileTab.java @@ -1,23 +1,15 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ItemListener; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; - +import javafx.collections.FXCollections; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import org.jabref.gui.DialogService; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.DirectoryDialogConfiguration; @@ -28,8 +20,11 @@ import org.jabref.model.metadata.FileDirectoryPreferences; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; +import java.awt.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; /** * Preferences tab for file options. These options were moved out from GeneralTab to @@ -40,101 +35,90 @@ class FileTab extends JPanel implements PrefsTab { private final DialogService dialogService; private final JabRefPreferences prefs; - private final JCheckBox backup; - private final JCheckBox localAutoSave; - private final JCheckBox openLast; - private final JComboBox newlineSeparator; - private final JCheckBox reformatFileOnSaveAndExport; - private final JRadioButton resolveStringsStandard; - private final JRadioButton resolveStringsAll; - private final JTextField nonWrappableFields; - private final JTextField doNotResolveStringsFor; - - private final JTextField fileDir; - private final JCheckBox bibLocAsPrimaryDir; - private final JCheckBox runAutoFileSearch; - private final JCheckBox allowFileAutoOpenBrowse; - private final JRadioButton useRegExpComboBox; - private final JRadioButton matchExactKeyOnly = new JRadioButton( + private final CheckBox backup; + private final CheckBox localAutoSave; + private final CheckBox openLast; + private final ComboBox newlineSeparator; + private final CheckBox reformatFileOnSaveAndExport; + private final RadioButton resolveStringsStandard; + private final RadioButton resolveStringsAll; + private final TextField nonWrappableFields; + private final TextField doNotResolveStringsFor; + + private final TextField fileDir; + private final CheckBox bibLocAsPrimaryDir; + private final CheckBox runAutoFileSearch; + private final CheckBox allowFileAutoOpenBrowse; + private final RadioButton useRegExpComboBox; + private final RadioButton matchExactKeyOnly = new RadioButton( Localization.lang("Autolink only files that match the BibTeX key")); - private final JRadioButton matchStartsWithKey = new JRadioButton( + private final RadioButton matchStartsWithKey = new RadioButton( Localization.lang("Autolink files with names starting with the BibTeX key")); - private final JTextField regExpTextField; + private final TextField regExpTextField; public FileTab(DialogService dialogService, JabRefPreferences prefs) { this.dialogService = dialogService; this.prefs = prefs; - fileDir = new JTextField(25); - bibLocAsPrimaryDir = new JCheckBox(Localization.lang("Use the BIB file location as primary file directory")); - bibLocAsPrimaryDir.setToolTipText(Localization.lang("When downloading files, or moving linked files to the " + fileDir = new TextField(); + bibLocAsPrimaryDir = new CheckBox(Localization.lang("Use the BIB file location as primary file directory")); + bibLocAsPrimaryDir.setText(Localization.lang("When downloading files, or moving linked files to the " + "file directory, prefer the BIB file location rather than the file directory set above")); - runAutoFileSearch = new JCheckBox( + runAutoFileSearch = new CheckBox( Localization.lang("When opening file link, search for matching file if no link is defined")); - allowFileAutoOpenBrowse = new JCheckBox( + allowFileAutoOpenBrowse = new CheckBox( Localization.lang("Automatically open browse dialog when creating new file link")); - regExpTextField = new JTextField(25); - useRegExpComboBox = new JRadioButton(Localization.lang("Use regular expression search")); - ItemListener regExpListener = e -> regExpTextField.setEditable(useRegExpComboBox.isSelected()); - useRegExpComboBox.addItemListener(regExpListener); - ButtonGroup buttonGroup = new ButtonGroup(); - buttonGroup.add(matchExactKeyOnly); - buttonGroup.add(matchStartsWithKey); - buttonGroup.add(useRegExpComboBox); - - openLast = new JCheckBox(Localization.lang("Open last edited libraries at startup")); - backup = new JCheckBox(Localization.lang("Backup old file when saving")); - localAutoSave = new JCheckBox(Localization.lang("Autosave local libraries")); - resolveStringsAll = new JRadioButton(Localization.lang("Resolve strings for all fields except") + ":"); - resolveStringsStandard = new JRadioButton(Localization.lang("Resolve strings for standard BibTeX fields only")); - ButtonGroup bg = new ButtonGroup(); - bg.add(resolveStringsAll); - bg.add(resolveStringsStandard); + regExpTextField = new TextField(); + useRegExpComboBox = new RadioButton(Localization.lang("Use regular expression search")); + useRegExpComboBox.setOnAction(e -> regExpTextField.setEditable(useRegExpComboBox.isSelected())); + + + openLast = new CheckBox(Localization.lang("Open last edited libraries at startup")); + backup = new CheckBox(Localization.lang("Backup old file when saving")); + localAutoSave = new CheckBox(Localization.lang("Autosave local libraries")); + resolveStringsAll = new RadioButton(Localization.lang("Resolve strings for all fields except") + ":"); + resolveStringsStandard = new RadioButton(Localization.lang("Resolve strings for standard BibTeX fields only")); // This is sort of a quick hack - newlineSeparator = new JComboBox<>(new String[] {"CR", "CR/LF", "LF"}); - - reformatFileOnSaveAndExport = new JCheckBox(Localization.lang("Always reformat BIB file on save and export")); - - nonWrappableFields = new JTextField(25); - doNotResolveStringsFor = new JTextField(30); - - FormLayout layout = new FormLayout("left:pref, 4dlu, fill:150dlu, 4dlu, fill:pref", ""); // left:pref, 4dlu, fill:pref - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - - builder.appendSeparator(Localization.lang("General")); - builder.nextLine(); - builder.append(openLast, 3); - builder.nextLine(); - builder.append(backup, 3); - builder.nextLine(); - - JLabel label = new JLabel(Localization.lang("Do not wrap the following fields when saving") + ":"); - builder.append(label); - builder.append(nonWrappableFields); - builder.nextLine(); - builder.append(resolveStringsStandard, 3); - builder.nextLine(); - builder.append(resolveStringsAll); - builder.append(doNotResolveStringsFor); - builder.nextLine(); - - JLabel lab = new JLabel(Localization.lang("Newline separator") + ":"); - builder.append(lab); - builder.append(newlineSeparator); - builder.nextLine(); - - builder.append(reformatFileOnSaveAndExport, 3); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("External file links")); - builder.nextLine(); - lab = new JLabel(Localization.lang("Main file directory") + ':'); - builder.append(lab); - builder.append(fileDir); - - JButton browse = new JButton(Localization.lang("Browse")); - browse.addActionListener(e -> { + newlineSeparator = new ComboBox<>(FXCollections.observableArrayList("CR", "CR/LF", "LF")); + + reformatFileOnSaveAndExport = new CheckBox(Localization.lang("Always reformat BIB file on save and export")); + + nonWrappableFields = new TextField(); + doNotResolveStringsFor = new TextField(); + + GridPane builder = new GridPane(); + + builder.add(new Label(Localization.lang("General")),1,1); + builder.add(openLast, 1,2); + builder.add(backup,1, 3); + + + Label label = new Label(Localization.lang("Do not wrap the following fields when saving") + ":"); + builder.add(label,1,4); + builder.add(nonWrappableFields,2,4); + + builder.add(resolveStringsStandard, 1,5); + builder.add(resolveStringsAll,1,6); + builder.add(doNotResolveStringsFor,2,6); + + + Label lab = new Label(Localization.lang("Newline separator") + ":"); + builder.add(lab,1,7); + builder.add(newlineSeparator,2,7); + + + builder.add(reformatFileOnSaveAndExport, 1,8); + + + builder.add(new Label(Localization.lang("External file links")),1,10); + + lab = new Label(Localization.lang("Main file directory") + ':'); + builder.add(lab,1,11); + builder.add(fileDir,2,11); + + Button browse = new Button(Localization.lang("Browse")); + browse.setOnAction(e -> { DirectoryDialogConfiguration dirDialogConfiguration = new DirectoryDialogConfiguration.Builder() .withInitialDirectory(Paths.get(fileDir.getText())).build(); @@ -143,41 +127,35 @@ public FileTab(DialogService dialogService, JabRefPreferences prefs) { .ifPresent(f -> fileDir.setText(f.toString())); }); - builder.append(browse); - - builder.nextLine(); - builder.append(bibLocAsPrimaryDir, 3); - builder.nextLine(); - builder.append(matchStartsWithKey, 3); - builder.nextLine(); - builder.append(matchExactKeyOnly, 3); - builder.nextLine(); - builder.append(useRegExpComboBox); - builder.append(regExpTextField); - - builder.append(new HelpAction(Localization.lang("Help on regular expression search"), - HelpFile.REGEX_SEARCH) - .getHelpButton()); - builder.nextLine(); - builder.append(runAutoFileSearch, 3); - builder.nextLine(); - builder.append(allowFileAutoOpenBrowse); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Autosave")); - builder.append(localAutoSave, 1); - JButton help = new HelpAction(HelpFile.AUTOSAVE).getHelpButton(); - help.setPreferredSize(new Dimension(24, 24)); - JPanel hPan = new JPanel(); - hPan.setLayout(new BorderLayout()); - hPan.add(help, BorderLayout.EAST); - builder.append(hPan); - builder.nextLine(); - - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + builder.add(browse,3,11); + + + builder.add(bibLocAsPrimaryDir, 1,12); + builder.add(matchStartsWithKey, 1,13); + builder.add(matchExactKeyOnly, 1,14); + builder.add(useRegExpComboBox,1,15); + builder.add(regExpTextField,2,15); + + Button help = new Button("?"); + help.setOnAction(event -> new HelpAction(Localization.lang("Help on regular expression search"), + HelpFile.REGEX_SEARCH).getHelpButton().doClick()); + + builder.add(help,3,15); + + builder.add(runAutoFileSearch, 1,16); + builder.add(allowFileAutoOpenBrowse,1,17); + + + builder.add(new Label(Localization.lang("Autosave")),1,18); + builder.add(localAutoSave, 1,19); + Button help1 = new Button("?"); + help1.setOnAction(event -> new HelpAction(HelpFile.AUTOSAVE).getHelpButton().doClick()); + builder.add(help1,2,19); + + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); setLayout(new BorderLayout()); - add(pan, BorderLayout.CENTER); + add(panel, BorderLayout.CENTER); } @Override @@ -200,12 +178,12 @@ public void setValues() { String newline = prefs.get(JabRefPreferences.NEWLINE); if ("\r".equals(newline)) { - newlineSeparator.setSelectedIndex(0); + newlineSeparator.setValue("CR"); } else if ("\n".equals(newline)) { - newlineSeparator.setSelectedIndex(2); + newlineSeparator.setValue("LF"); } else { // fallback: windows standard - newlineSeparator.setSelectedIndex(1); + newlineSeparator.setValue("CR/LF"); } reformatFileOnSaveAndExport.setSelected(prefs.getBoolean(JabRefPreferences.REFORMAT_FILE_ON_SAVE_AND_EXPORT)); @@ -230,11 +208,11 @@ public void storeSettings() { } String newline; - switch (newlineSeparator.getSelectedIndex()) { - case 0: + switch (newlineSeparator.getPromptText()) { + case "CR": newline = "\r"; break; - case 2: + case "LF": newline = "\n"; break; default: diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index 705b35a7de5..99c1691410d 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -1,23 +1,18 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Component; -import java.nio.charset.Charset; -import java.time.format.DateTimeFormatter; - -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListCellRenderer; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JTextField; - +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.shape.Line; import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.help.HelpFile; @@ -27,135 +22,121 @@ import org.jabref.model.entry.InternalBibtexFields; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; +import java.awt.*; +import java.nio.charset.Charset; +import java.time.format.DateTimeFormatter; import static org.jabref.logic.l10n.Languages.LANGUAGES; class GeneralTab extends JPanel implements PrefsTab { - private final JCheckBox useOwner; - private final JCheckBox overwriteOwner; - private final JCheckBox enforceLegalKeys; - private final JCheckBox shouldCollectTelemetry; - private final JCheckBox confirmDelete; - private final JCheckBox memoryStick; - private final JCheckBox inspectionWarnDupli; - private final JCheckBox useTimeStamp; - private final JCheckBox updateTimeStamp; - private final JCheckBox overwriteTimeStamp; - private final JTextField defOwnerField; - - private final JTextField timeStampFormat; - private final JTextField timeStampField; - private final JabRefPreferences prefs; - private final JComboBox language = new JComboBox<>(LANGUAGES.keySet().toArray(new String[LANGUAGES.keySet().size()])); - private final JComboBox encodings; - private final JComboBox biblatexMode; - private final DialogService dialogService; - public class DefaultBibModeRenderer extends DefaultListCellRenderer { + private final CheckBox useOwner; + private final CheckBox overwriteOwner; + private final CheckBox enforceLegalKeys; + private final CheckBox shouldCollectTelemetry; + private final CheckBox confirmDelete; + private final CheckBox memoryStick; + private final CheckBox inspectionWarnDupli; + private final CheckBox useTimeStamp; + private final CheckBox updateTimeStamp; + private final CheckBox overwriteTimeStamp; + private final TextField defOwnerField; + + private final TextField timeStampFormat; + private final TextField timeStampField; + private final JabRefPreferences prefs; - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, - boolean cellHasFocus) { - super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - setText(((BibDatabaseMode) value).getFormattedName()); - return this; - } - } + private ObservableList options = FXCollections.observableArrayList(LANGUAGES.keySet().toArray(new String[LANGUAGES.keySet().size()])); + private final ComboBox language = new ComboBox<>(options); + private final ComboBox encodings; + private final ComboBox biblatexMode; + private final DialogService dialogService; public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { this.prefs = prefs; this.dialogService = dialogService; setLayout(new BorderLayout()); - biblatexMode = new JComboBox<>(BibDatabaseMode.values()); - biblatexMode.setRenderer(new DefaultBibModeRenderer()); + biblatexMode = new ComboBox<>(FXCollections.observableArrayList(BibDatabaseMode.values())); - memoryStick = new JCheckBox(Localization.lang("Load and Save preferences from/to jabref.xml on start-up (memory stick mode)")); - useOwner = new JCheckBox(Localization.lang("Mark new entries with owner name") + ':'); - updateTimeStamp = new JCheckBox(Localization.lang("Update timestamp on modification")); - useTimeStamp = new JCheckBox(Localization.lang("Mark new entries with addition date") + ". " + + memoryStick = new CheckBox(Localization.lang("Load and Save preferences from/to jabref.xml on start-up (memory stick mode)")); + useOwner = new CheckBox(Localization.lang("Mark new entries with owner name") + ':'); + updateTimeStamp = new CheckBox(Localization.lang("Update timestamp on modification")); + useTimeStamp = new CheckBox(Localization.lang("Mark new entries with addition date") + ". " + Localization.lang("Date format") + ':'); - useTimeStamp.addChangeListener(e -> updateTimeStamp.setEnabled(useTimeStamp.isSelected())); - overwriteOwner = new JCheckBox(Localization.lang("Overwrite")); - overwriteTimeStamp = new JCheckBox(Localization.lang("Overwrite")); - overwriteOwner.setToolTipText(Localization.lang("If a pasted or imported entry already has " - + "the field set, overwrite.")); - overwriteTimeStamp.setToolTipText(Localization.lang("If a pasted or imported entry already has " - + "the field set, overwrite.")); - enforceLegalKeys = new JCheckBox(Localization.lang("Enforce legal characters in BibTeX keys")); - confirmDelete = new JCheckBox(Localization.lang("Show confirmation dialog when deleting entries")); - - defOwnerField = new JTextField(); - timeStampFormat = new JTextField(); - timeStampField = new JTextField(); - inspectionWarnDupli = new JCheckBox(Localization.lang("Warn about unresolved duplicates when closing inspection window")); - - shouldCollectTelemetry = new JCheckBox(Localization.lang("Collect and share telemetry data to help improve JabRef.")); - - encodings = new JComboBox<>(); - encodings.setModel(new DefaultComboBoxModel<>(Encodings.ENCODINGS)); - - FormLayout layout = new FormLayout( - "8dlu, 1dlu, left:pref:grow, 4dlu, fill:pref, 4dlu, fill:pref, 4dlu, left:pref, 1dlu, left:pref, 4dlu, left:pref", - ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - - builder.appendSeparator(Localization.lang("General")); - builder.nextLine(); - builder.append(inspectionWarnDupli, 13); - builder.nextLine(); - builder.append(confirmDelete, 13); - builder.nextLine(); - builder.append(enforceLegalKeys, 13); - builder.nextLine(); - builder.append(memoryStick, 13); + useTimeStamp.setOnAction(e->updateTimeStamp.setDisable(!useTimeStamp.isSelected())); + overwriteOwner = new CheckBox(Localization.lang("Overwrite")); + overwriteTimeStamp = new CheckBox(Localization.lang("Overwrite")); + enforceLegalKeys = new CheckBox(Localization.lang("Enforce legal characters in BibTeX keys")); + confirmDelete = new CheckBox(Localization.lang("Show confirmation dialog when deleting entries")); + + defOwnerField = new TextField(); + timeStampFormat = new TextField(); + timeStampField = new TextField(); + inspectionWarnDupli = new CheckBox(Localization.lang("Warn about unresolved duplicates when closing inspection window")); + + shouldCollectTelemetry = new CheckBox(Localization.lang("Collect and share telemetry data to help improve JabRef.")); + + encodings = new ComboBox<>(FXCollections.observableArrayList(Encodings.ENCODINGS)); + + + GridPane builder = new GridPane(); + builder.add(new Label(Localization.lang("General")),1,1); + builder.add(new Separator(),2,1); + builder.add(new Line(),2,2); + builder.add(inspectionWarnDupli, 2,3); + builder.add(new Line(),2,4); + builder.add(confirmDelete, 2,5); + builder.add(new Line(),2,6); + builder.add(enforceLegalKeys, 2,7); + builder.add(new Line(),2,8); + builder.add(memoryStick, 2,9); // Create a new panel with its own FormLayout for the last items: - builder.append(useOwner, 3); - builder.append(defOwnerField); - builder.append(overwriteOwner); - builder.append(new JPanel(), 3); - - JButton help = new HelpAction(HelpFile.OWNER).getHelpButton(); - builder.append(help); - builder.nextLine(); - - builder.append(useTimeStamp, 3); - builder.append(timeStampFormat); - builder.append(overwriteTimeStamp); - builder.append(Localization.lang("Field name") + ':'); - builder.append(timeStampField); - - help = new HelpAction(HelpFile.TIMESTAMP).getHelpButton(); - builder.append(help); - builder.nextLine(); - - builder.append(new JPanel()); - builder.append(updateTimeStamp, 11); - builder.nextLine(); - - builder.append(shouldCollectTelemetry, 13); - builder.nextLine(); - JLabel lab; - lab = new JLabel(Localization.lang("Language") + ':'); - builder.append(lab, 3); - builder.append(language); - builder.nextLine(); - lab = new JLabel(Localization.lang("Default encoding") + ':'); - builder.append(lab, 3); - builder.append(encodings); - - builder.nextLine(); - builder.appendSeparator(Localization.lang("Default bibliography mode")); - builder.append(new JPanel()); - builder.append(biblatexMode); - - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + builder.add(useOwner, 2,10); + builder.add(defOwnerField,3,10); + builder.add(overwriteOwner,4,10); + + Button help = new Button("Help"); + help.setOnAction(event -> new HelpAction(HelpFile.OWNER).getHelpButton().doClick()); + builder.add(help,5,10); + + + builder.add(useTimeStamp, 2,13); + builder.add(timeStampFormat,3,13); + builder.add(overwriteTimeStamp,4,13); + builder.add(new Label(Localization.lang("Field name") + ':'),6,13); + builder.add(timeStampField,7,13); + + Button help1 = new Button("?"); + help1.setOnAction(event -> new HelpAction(HelpFile.TIMESTAMP).getHelpButton().doClick()); + builder.add(help1,8,13); + + + builder.add(updateTimeStamp, 2,14); + builder.add(new Line(),2,15); + + builder.add(shouldCollectTelemetry,2,15); + builder.add(new Line(),2,16); + Label lab; + lab = new Label(Localization.lang("Language") + ':'); + builder.add(lab, 1,17); + builder.add(language,2,17); + builder.add(new Line(),2,18); + lab = new Label(Localization.lang("Default encoding") + ':'); + builder.add(lab, 1,19); + builder.add(encodings,2,19); + + builder.add(new Label(Localization.lang("Default bibliography mode")),1,20); + + builder.add(biblatexMode,2,21); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); } @@ -166,7 +147,7 @@ public void setValues() { useTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP)); overwriteTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP)); updateTimeStamp.setSelected(prefs.getBoolean(JabRefPreferences.UPDATE_TIMESTAMP)); - updateTimeStamp.setEnabled(useTimeStamp.isSelected()); + updateTimeStamp.setSelected(useTimeStamp.isSelected()); enforceLegalKeys.setSelected(prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); shouldCollectTelemetry.setSelected(prefs.shouldCollectTelemetry()); memoryStick.setSelected(prefs.getBoolean(JabRefPreferences.MEMORY_STICK_MODE)); @@ -176,13 +157,13 @@ public void setValues() { timeStampField.setText(prefs.get(JabRefPreferences.TIME_STAMP_FIELD)); inspectionWarnDupli.setSelected(prefs.getBoolean(JabRefPreferences.WARN_ABOUT_DUPLICATES_IN_INSPECTION)); if (Globals.prefs.getBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE)) { - biblatexMode.setSelectedItem(BibDatabaseMode.BIBLATEX); + biblatexMode.setValue(BibDatabaseMode.BIBLATEX); } else { - biblatexMode.setSelectedItem(BibDatabaseMode.BIBTEX); + biblatexMode.setValue(BibDatabaseMode.BIBTEX); } Charset enc = Globals.prefs.getDefaultEncoding(); - encodings.setSelectedItem(enc); + encodings.setValue(enc); String oldLan = prefs.get(JabRefPreferences.LANGUAGE); @@ -190,7 +171,7 @@ public void setValues() { int ilk = 0; for (String lan : LANGUAGES.values()) { if (lan.equals(oldLan)) { - language.setSelectedIndex(ilk); + language.setVisibleRowCount(ilk); } ilk++; } @@ -221,12 +202,12 @@ public void storeSettings() { prefs.put(JabRefPreferences.TIME_STAMP_FIELD, timeStampField.getText().trim()); // Update name of the time stamp field based on preferences InternalBibtexFields.updateTimeStampField(Globals.prefs.get(JabRefPreferences.TIME_STAMP_FIELD)); - prefs.setDefaultEncoding((Charset) encodings.getSelectedItem()); - prefs.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, biblatexMode.getSelectedItem() == BibDatabaseMode.BIBLATEX); + prefs.setDefaultEncoding((Charset) encodings.getItems()); + prefs.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, biblatexMode.getItems().equals(BibDatabaseMode.BIBLATEX)); - if (!LANGUAGES.get(language.getSelectedItem()).equals(prefs.get(JabRefPreferences.LANGUAGE))) { - prefs.put(JabRefPreferences.LANGUAGE, LANGUAGES.get(language.getSelectedItem())); - Localization.setLanguage(LANGUAGES.get(language.getSelectedItem())); + if (!LANGUAGES.get(language.getItems()).equals(prefs.get(JabRefPreferences.LANGUAGE))) { + prefs.put(JabRefPreferences.LANGUAGE, LANGUAGES.get(language.getItems())); + Localization.setLanguage(LANGUAGES.get(language.getItems())); // Update any defaults that might be language dependent: Globals.prefs.setLanguageDependentDefaultValues(); // Warn about restart needed: diff --git a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java index aa071674220..e7307d8f3b4 100644 --- a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java @@ -1,107 +1,66 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; - +import javafx.embed.swing.JFXPanel; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.Scene; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.groups.GroupViewMode; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; +import java.awt.*; class GroupsPrefsTab extends JPanel implements PrefsTab { - private final JCheckBox hideNonHits = new JCheckBox(Localization.lang("Hide non-hits")); - private final JCheckBox grayOut = new JCheckBox(Localization.lang("Gray out non-hits")); - private final JCheckBox autoAssignGroup = new JCheckBox(Localization.lang("Automatically assign new entry to selected groups")); - private final JRadioButton multiSelectionModeIntersection = new JRadioButton(Localization.lang("Intersection")); - private final JRadioButton multiSelectionModeUnion = new JRadioButton(Localization.lang("Union")); + private final CheckBox hideNonHits = new CheckBox(Localization.lang("Hide non-hits")); + private final CheckBox grayOut = new CheckBox(Localization.lang("Gray out non-hits")); + private final CheckBox autoAssignGroup = new CheckBox(Localization.lang("Automatically assign new entry to selected groups")); + private final RadioButton multiSelectionModeIntersection = new RadioButton(Localization.lang("Intersection")); + private final RadioButton multiSelectionModeUnion = new RadioButton(Localization.lang("Union")); - private final JTextField groupingField = new JTextField(20); - private final JTextField keywordSeparator = new JTextField(2); + private final TextField groupingField = new TextField(); + private final TextField keywordSeparator = new TextField(); private final JabRefPreferences prefs; public GroupsPrefsTab(JabRefPreferences prefs) { this.prefs = prefs; - keywordSeparator.addFocusListener(new FocusListener() { - + keywordSeparator.setOnAction(new EventHandler() { @Override - public void focusGained(FocusEvent e) { + public void handle(ActionEvent event) { keywordSeparator.selectAll(); } - - @Override - public void focusLost(FocusEvent e) { - // deselection is automatic - } }); - ButtonGroup hideMode = new ButtonGroup(); - hideMode.add(grayOut); - hideMode.add(hideNonHits); - - ButtonGroup multiSelectionMode = new ButtonGroup(); - multiSelectionMode.add(multiSelectionModeIntersection); - multiSelectionMode.add(multiSelectionModeUnion); - multiSelectionModeIntersection.setToolTipText(Localization.lang("Display only entries belonging to all selected groups.")); - multiSelectionModeUnion.setToolTipText(Localization.lang("Display all entries belonging to one or more of the selected groups.")); - - FormLayout layout = new FormLayout("9dlu, pref", //500px", - "p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p"); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.appendSeparator(Localization.lang("View")); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(hideNonHits); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(grayOut); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(multiSelectionModeIntersection); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(multiSelectionModeUnion); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - builder.append(autoAssignGroup); - builder.nextLine(); - builder.nextLine(); - builder.appendSeparator(Localization.lang("Dynamic groups")); - builder.nextLine(); - builder.nextLine(); - builder.nextColumn(); - // build subcomponent - FormLayout layout2 = new FormLayout("left:pref, 2dlu, left:pref", "p, 3dlu, p"); - DefaultFormBuilder builder2 = new DefaultFormBuilder(layout2); - builder2.append(new JLabel(Localization.lang("Default grouping field") + ":")); - builder2.append(groupingField); - builder2.nextLine(); - builder2.nextLine(); - builder2.append(new JLabel(Localization.lang("When adding/removing keywords, separate them by") + ":")); - builder2.append(keywordSeparator); - builder.append(builder2.getPanel()); + multiSelectionModeIntersection.setText(Localization.lang("Display only entries belonging to all selected groups.")); + multiSelectionModeUnion.setText(Localization.lang("Display all entries belonging to one or more of the selected groups.")); + + GridPane builder = new GridPane(); + + builder.add(new Label(Localization.lang("View")),1,1); + builder.add(hideNonHits,2,2); + builder.add(grayOut,2,3); + builder.add(multiSelectionModeIntersection,2,4); + builder.add(multiSelectionModeUnion,2,5); + builder.add(autoAssignGroup,2,6); + builder.add(new Label(Localization.lang("Dynamic groups")),1,7); + + builder.add(new Label(Localization.lang(" Default grouping field") + ":"),1,8); + builder.add(groupingField,2,8); + builder.add(new Label(Localization.lang(" When adding/removing keywords, separate them by") + ":"),1,9); + builder.add(keywordSeparator,2,9); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); setLayout(new BorderLayout()); - JPanel panel = builder.getPanel(); - panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(panel, BorderLayout.CENTER); } diff --git a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java index 1aea509991f..9218b0e753d 100644 --- a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java @@ -1,26 +1,22 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; +import java.awt.*; import java.util.Objects; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JMenuItem; import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JRadioButton; -import javax.swing.JTextField; +import javafx.collections.FXCollections; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.pdfimport.ImportDialog; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - public class ImportSettingsTab extends JPanel implements PrefsTab { public static final String[] DEFAULT_FILENAMEPATTERNS = new String[] {"[bibtexkey]", @@ -30,84 +26,63 @@ public class ImportSettingsTab extends JPanel implements PrefsTab { private static final String[] DEFAULT_FILENAMEPATTERNS_DISPLAY = new String[] {"bibtexkey", "bibtexkey - title",}; private final JabRefPreferences prefs; - private final JRadioButton radioButtonXmp; - private final JRadioButton radioButtonPDFcontent; - private final JRadioButton radioButtonNoMeta; - private final JRadioButton radioButtononlyAttachPDF; - private final JCheckBox useDefaultPDFImportStyle; + private final RadioButton radioButtonXmp; + private final RadioButton radioButtonPDFcontent; + private final RadioButton radioButtonNoMeta; + private final RadioButton radioButtononlyAttachPDF; + private final CheckBox useDefaultPDFImportStyle; + + private final TextField fileNamePattern; + private final ComboBox selectFileNamePattern; - private final JTextField fileNamePattern; - private final JButton selectFileNamePattern; - private final JTextField fileDirPattern; + private final TextField fileDirPattern; public ImportSettingsTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); setLayout(new BorderLayout()); - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:3dlu"); - radioButtonNoMeta = new JRadioButton(Localization.lang("Create blank entry linking the PDF")); - radioButtonXmp = new JRadioButton(Localization.lang("Create entry based on XMP-metadata")); - radioButtonPDFcontent = new JRadioButton(Localization.lang("Create entry based on content")); - radioButtononlyAttachPDF = new JRadioButton(Localization.lang("Only attach PDF")); - ButtonGroup bg = new ButtonGroup(); - bg.add(radioButtonNoMeta); - bg.add(radioButtonXmp); - bg.add(radioButtonPDFcontent); - bg.add(radioButtononlyAttachPDF); - - useDefaultPDFImportStyle = new JCheckBox( + + radioButtonNoMeta = new RadioButton(Localization.lang("Create blank entry linking the PDF")); + radioButtonXmp = new RadioButton(Localization.lang("Create entry based on XMP-metadata")); + radioButtonPDFcontent = new RadioButton(Localization.lang("Create entry based on content")); + radioButtononlyAttachPDF = new RadioButton(Localization.lang("Only attach PDF")); + + + useDefaultPDFImportStyle = new CheckBox( Localization.lang("Always use this PDF import style (and do not ask for each import)")); - fileNamePattern = new JTextField(50); - fileDirPattern = new JTextField(50); - selectFileNamePattern = new JButton(Localization.lang("Choose pattern")); - selectFileNamePattern.addActionListener(e -> openFilePatternMenu()); - - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JPanel pan = new JPanel(); - - builder.appendSeparator(Localization.lang("Default import style for drag and drop of PDFs")); - builder.nextLine(); - builder.append(pan); - builder.append(radioButtonNoMeta); - builder.nextLine(); - builder.append(pan); - builder.append(radioButtonXmp); - builder.nextLine(); - builder.append(pan); - builder.append(radioButtonPDFcontent); - builder.nextLine(); - builder.append(pan); - builder.append(radioButtononlyAttachPDF); - builder.nextLine(); - builder.append(pan); - builder.append(useDefaultPDFImportStyle); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Default PDF file link action")); - builder.nextLine(); - builder.append(pan); - - JPanel pan2 = new JPanel(); - JLabel lab = new JLabel(Localization.lang("Filename format pattern").concat(":")); - pan2.add(lab); - pan2.add(fileNamePattern); - pan2.add(selectFileNamePattern); - builder.append(pan2); - - JPanel pan3 = new JPanel(); - JLabel lbfileDirPattern = new JLabel(Localization.lang("File directory pattern").concat(":")); - pan3.add(lbfileDirPattern); - pan3.add(fileDirPattern); - - builder.nextLine(); - builder.append(pan); - builder.append(pan3); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + fileNamePattern = new TextField(); + fileDirPattern = new TextField(); + selectFileNamePattern = new ComboBox<>(); + selectFileNamePattern.getItems().addAll(FXCollections.observableArrayList(DEFAULT_FILENAMEPATTERNS_DISPLAY)); + selectFileNamePattern.setValue("Choose pattern"); + selectFileNamePattern.setOnAction(e -> { + fileNamePattern.setText(selectFileNamePattern.getValue()); + }); + GridPane builder = new GridPane(); + builder.add(new Label(Localization.lang("Default import style for drag and drop of PDFs")),1,1); + builder.add(new Separator(),2,1); + builder.add(radioButtonNoMeta,2,2); + builder.add(radioButtonXmp,2,3); + builder.add(radioButtonPDFcontent,2,4); + builder.add(radioButtononlyAttachPDF,2,5); + builder.add(useDefaultPDFImportStyle,2,6); + builder.add(new Label(Localization.lang("Default PDF file link action")),1,7); + + + Label lab = new Label(Localization.lang(" Filename format pattern").concat(":")); + builder.add(lab,1,8); + builder.add(fileNamePattern,2,8); + builder.add(selectFileNamePattern,3,8); + + Label lbfileDirPattern = new Label(Localization.lang(" File directory pattern").concat(":")); + builder.add(lbfileDirPattern,1,9); + builder.add(fileDirPattern,2,9); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); } @Override @@ -165,14 +140,4 @@ public String getTabName() { return Localization.lang("Import"); } - private void openFilePatternMenu() { - JPopupMenu popup = new JPopupMenu(); - for (int i = 0; i < ImportSettingsTab.DEFAULT_FILENAMEPATTERNS.length; i++) { - final JMenuItem item = new JMenuItem(ImportSettingsTab.DEFAULT_FILENAMEPATTERNS_DISPLAY[i]); - final String toSet = ImportSettingsTab.DEFAULT_FILENAMEPATTERNS[i]; - item.addActionListener(e -> fileNamePattern.setText(toSet)); - popup.add(item); - } - popup.show(selectFileNamePattern, 0, selectFileNamePattern.getHeight()); - } } diff --git a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java index 21491994a99..f9b9ebabe19 100644 --- a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java @@ -88,6 +88,8 @@ public NameFormatterTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); setLayout(new BorderLayout()); + + TableModel tableModel = new AbstractTableModel() { @Override diff --git a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java index fbff70a1b18..7f3d31a206b 100644 --- a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java @@ -1,34 +1,31 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Insets; - -import javax.swing.BorderFactory; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JTextField; - +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.paint.Paint; import org.jabref.gui.DialogService; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.l10n.Localization; import org.jabref.logic.net.ProxyPreferences; import org.jabref.logic.net.ProxyRegisterer; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; +import java.awt.*; public class NetworkTab extends JPanel implements PrefsTab { - private final JCheckBox useProxyCheckBox; - private final JTextField hostnameTextField; - private final JTextField portTextField; - private final JCheckBox useAuthenticationCheckBox; - private final JTextField usernameTextField; - private final JPasswordField passwordTextField; + private final CheckBox useProxyCheckBox; + private final TextField hostnameTextField; + private final TextField portTextField; + private final CheckBox useAuthenticationCheckBox; + private final TextField usernameTextField; + private final PasswordField passwordTextField; private final JabRefPreferences preferences; private ProxyPreferences oldProxyPreferences; private final DialogService dialogService; @@ -39,62 +36,57 @@ public NetworkTab(DialogService dialogService, JabRefPreferences preferences) { setLayout(new BorderLayout()); - useProxyCheckBox = new JCheckBox(Localization.lang("Use custom proxy configuration")); + useProxyCheckBox = new CheckBox(Localization.lang("Use custom proxy configuration")); - hostnameTextField = new JTextField(); - hostnameTextField.setEnabled(false); - portTextField = new JTextField(); - portTextField.setEnabled(false); + hostnameTextField = new TextField(); + hostnameTextField.setDisable(true); + portTextField = new TextField(); + portTextField.setDisable(true); - useAuthenticationCheckBox = new JCheckBox(Localization.lang("Proxy requires authentication")); - useAuthenticationCheckBox.setEnabled(false); + useAuthenticationCheckBox = new CheckBox(Localization.lang("Proxy requires authentication")); + useAuthenticationCheckBox.setDisable(true); - usernameTextField = new JTextField(); - usernameTextField.setEnabled(false); - passwordTextField = new JPasswordField(); - passwordTextField.setEnabled(false); - JLabel passwordWarningLabel = new JLabel(Localization.lang("Attention: Password is stored in plain text!")); - passwordWarningLabel.setEnabled(false); - passwordWarningLabel.setForeground(Color.RED); + usernameTextField = new TextField(); + usernameTextField.setDisable(true); + passwordTextField = new PasswordField(); + passwordTextField.setDisable(true); + Label passwordWarningLabel = new Label(Localization.lang("Attention: Password is stored in plain text!")); + passwordWarningLabel.setDisable(true); + passwordWarningLabel.setTextFill(Paint.valueOf("Red")); - Insets margin = new Insets(0, 12, 3, 0); - useProxyCheckBox.setMargin(margin); - portTextField.setMargin(margin); - useAuthenticationCheckBox.setMargin(margin); // Listener on useProxyCheckBox to enable and disable the proxy related settings; - useProxyCheckBox.addChangeListener(event -> { - hostnameTextField.setEnabled(useProxyCheckBox.isSelected()); - portTextField.setEnabled(useProxyCheckBox.isSelected()); - useAuthenticationCheckBox.setEnabled(useProxyCheckBox.isSelected()); + useProxyCheckBox.setOnAction(event -> { + hostnameTextField.setDisable(!useProxyCheckBox.isSelected()); + portTextField.setDisable(!useProxyCheckBox.isSelected()); + useAuthenticationCheckBox.setDisable(!useProxyCheckBox.isSelected()); }); - useAuthenticationCheckBox.addChangeListener(event -> { - usernameTextField.setEnabled(useProxyCheckBox.isSelected() && useAuthenticationCheckBox.isSelected()); - passwordTextField.setEnabled(useProxyCheckBox.isSelected() && useAuthenticationCheckBox.isSelected()); - passwordWarningLabel.setEnabled(useProxyCheckBox.isSelected() && useAuthenticationCheckBox.isSelected()); + useAuthenticationCheckBox.setOnAction(event -> { + usernameTextField.setDisable(!useProxyCheckBox.isSelected() || !useAuthenticationCheckBox.isSelected()); + passwordTextField.setDisable(!useProxyCheckBox.isSelected() || !useAuthenticationCheckBox.isSelected()); + passwordWarningLabel.setDisable(!useProxyCheckBox.isSelected() || !useAuthenticationCheckBox.isSelected()); }); - FormLayout layout = new FormLayout("8dlu, left:pref, 4dlu, left:pref, 4dlu, fill:150dlu", - "p, 2dlu, p, 2dlu, p, 2dlu, p, 2dlu, p, 2dlu, p, 2dlu, p, p"); - FormBuilder builder = FormBuilder.create().layout(layout); - - builder.addSeparator(Localization.lang("Network")).xyw(1, 1, 6); - builder.add(useProxyCheckBox).xyw(2, 3, 5); - builder.add(Localization.lang("Hostname") + ':').xy(2, 5); - builder.add(hostnameTextField).xyw(4, 5, 3); - builder.add(Localization.lang("Port") + ':').xy(2, 7); - builder.add(portTextField).xyw(4, 7, 3); - builder.add(useAuthenticationCheckBox).xyw(4, 9, 3); - builder.add(Localization.lang("Username") + ':').xy(4, 11); - builder.add(usernameTextField).xy(6, 11); - builder.add(Localization.lang("Password") + ':').xy(4, 13); - builder.add(passwordTextField).xy(6, 13); - builder.add(passwordWarningLabel).xy(6, 14); - - JPanel pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + GridPane builder = new GridPane(); + + builder.add(new Label(Localization.lang("Network")),1,1); + builder.add(new Separator(),2,1); + builder.add(useProxyCheckBox,2,2); + builder.add(new Label(Localization.lang(" Hostname") + ':'),1,3); + builder.add(hostnameTextField,2,3); + builder.add(new Label(Localization.lang(" Port") + ':'),1,4); + builder.add(portTextField,2,4); + builder.add(useAuthenticationCheckBox,2,5); + builder.add(new Label(Localization.lang("Username") + ':'),2,6); + builder.add(usernameTextField,3,6); + builder.add(new Label(Localization.lang("Password") + ':'),2,7); + builder.add(passwordTextField,3,7); + builder.add(passwordWarningLabel,3,8); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); } @Override @@ -118,7 +110,7 @@ public void storeSettings() { String port = portTextField.getText().trim(); Boolean useAuthentication = useAuthenticationCheckBox.isSelected(); String username = usernameTextField.getText().trim(); - String password = new String(passwordTextField.getPassword()); + String password = passwordTextField.getText(); ProxyPreferences proxyPreferences = new ProxyPreferences(useProxy, hostname, port, useAuthentication, username, password); if (!proxyPreferences.equals(oldProxyPreferences)) { @@ -147,9 +139,9 @@ public boolean validateSettings() { } if (useAuthenticationCheckBox.isSelected()) { String userName = usernameTextField.getText(); - char[] password = passwordTextField.getPassword(); + char[] password = passwordTextField.getText().toCharArray(); // no empty proxy passwords currently supported (they make no sense in this case anyway) - if ((userName == null) || userName.trim().isEmpty() || (password == null) || (password.length == 0)) { + if ((userName == null) || userName.trim().isEmpty() || (password.length == 0)) { validAuthenticationSetting = false; validSetting = false; } else { diff --git a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java index 44ee6297960..61b497f8c8d 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java +++ b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java @@ -188,7 +188,7 @@ private JComponent constructSwingContent() { }); showPreferences.addActionListener( - e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs), null).setVisible(true)); + e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs)).setVisible(true)); resetPreferences.addActionListener(e -> { boolean resetPreferencesClicked = DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showConfirmationDialogAndWait(Localization.lang("Reset preferences"), diff --git a/src/main/java/org/jabref/gui/preftabs/PreferencesFilterDialog.java b/src/main/java/org/jabref/gui/preftabs/PreferencesFilterDialog.java index 050a2cb619f..fb3bbdc6b86 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreferencesFilterDialog.java +++ b/src/main/java/org/jabref/gui/preftabs/PreferencesFilterDialog.java @@ -7,7 +7,6 @@ import java.util.Objects; import javax.swing.JCheckBox; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -27,8 +26,8 @@ class PreferencesFilterDialog extends JabRefDialog { private final JCheckBox showOnlyDeviatingPreferenceOptions; private final JLabel count; - public PreferencesFilterDialog(JabRefPreferencesFilter preferencesFilter, JFrame frame) { - super(frame, true, PreferencesFilterDialog.class); // is modal + public PreferencesFilterDialog(JabRefPreferencesFilter preferencesFilter) { + super(true, PreferencesFilterDialog.class); this.preferencesFilter = Objects.requireNonNull(preferencesFilter); diff --git a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java index acbee5be563..8667581a2a6 100644 --- a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java @@ -1,53 +1,50 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Objects; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; - +import javafx.collections.FXCollections; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import org.jabref.Globals; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; +import java.awt.*; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Objects; class TablePrefsTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; - private final JCheckBox autoResizeMode; - private final JCheckBox priDesc; - private final JCheckBox secDesc; - private final JCheckBox terDesc; + private final CheckBox autoResizeMode; + private final CheckBox priDesc; + private final CheckBox secDesc; + private final CheckBox terDesc; - private final JRadioButton namesAsIs; - private final JRadioButton namesFf; - private final JRadioButton namesFl; - private final JRadioButton namesNatbib; - private final JRadioButton abbrNames; - private final JRadioButton noAbbrNames; - private final JRadioButton lastNamesOnly; + private final RadioButton namesAsIs; + private final RadioButton namesFf; + private final RadioButton namesFl; + private final RadioButton namesNatbib; + private final RadioButton abbrNames; + private final RadioButton noAbbrNames; + private final RadioButton lastNamesOnly; - private final JTextField priField; - private final JTextField secField; - private final JTextField terField; - private final JTextField numericFields; - private final JComboBox priSort; - private final JComboBox secSort; - private final JComboBox terSort; + private final TextField priField; + private final TextField secField; + private final TextField terField; + private final TextField numericFields; + private final ComboBox priSort; + private final ComboBox secSort; + private final ComboBox terSort; /** @@ -71,131 +68,97 @@ public TablePrefsTab(JabRefPreferences prefs) { fieldNames.add(BibEntry.KEY_FIELD); Collections.sort(fieldNames); String[] allPlusKey = fieldNames.toArray(new String[fieldNames.size()]); - priSort = new JComboBox<>(allPlusKey); - secSort = new JComboBox<>(allPlusKey); - terSort = new JComboBox<>(allPlusKey); - - autoResizeMode = new JCheckBox(Localization.lang("Fit table horizontally on screen")); - - namesAsIs = new JRadioButton(Localization.lang("Show names unchanged")); - namesFf = new JRadioButton(Localization.lang("Show 'Firstname Lastname'")); - namesFl = new JRadioButton(Localization.lang("Show 'Lastname, Firstname'")); - namesNatbib = new JRadioButton(Localization.lang("Natbib style")); - noAbbrNames = new JRadioButton(Localization.lang("Do not abbreviate names")); - abbrNames = new JRadioButton(Localization.lang("Abbreviate names")); - lastNamesOnly = new JRadioButton(Localization.lang("Show last names only")); - - priField = new JTextField(10); - secField = new JTextField(10); - terField = new JTextField(10); - - numericFields = new JTextField(30); - - priSort.insertItemAt(Localization.lang(""), 0); - terSort.insertItemAt(Localization.lang(""); + secSort.setValue(""); + + priSort.setOnAction(e -> { + if (priSort.getBaselineOffset() > 0) { + priField.setText(priSort.getItems().toString()); } }); - secSort.addActionListener(e -> { - if (secSort.getSelectedIndex() > 0) { - secField.setText(secSort.getSelectedItem().toString()); - secSort.setSelectedIndex(0); + secSort.setOnAction(e -> { + if (secSort.getBaselineOffset() > 0) { + secField.setText(secSort.getItems().toString()); } }); - terSort.addActionListener(e -> { - if (terSort.getSelectedIndex() > 0) { - terField.setText(terSort.getSelectedItem().toString()); - terSort.setSelectedIndex(0); + terSort.setOnAction(e -> { + if (terSort.getBaselineOffset() > 0) { + terField.setText(terSort.getItems().toString()); } }); - ButtonGroup nameStyle = new ButtonGroup(); - nameStyle.add(namesAsIs); - nameStyle.add(namesNatbib); - nameStyle.add(namesFf); - nameStyle.add(namesFl); - ButtonGroup nameAbbrev = new ButtonGroup(); - nameAbbrev.add(lastNamesOnly); - nameAbbrev.add(abbrNames); - nameAbbrev.add(noAbbrNames); - priDesc = new JCheckBox(Localization.lang("Descending")); - secDesc = new JCheckBox(Localization.lang("Descending")); - terDesc = new JCheckBox(Localization.lang("Descending")); - - FormLayout layout = new FormLayout( - "1dlu, 8dlu, left:pref, 4dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, fill:pref", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JLabel lab; - JPanel pan = new JPanel(); - - builder.appendSeparator(Localization.lang("Format of author and editor names")); - DefaultFormBuilder nameBuilder = new DefaultFormBuilder(new FormLayout( - "left:pref, 8dlu, left:pref", "")); - - nameBuilder.append(namesAsIs); - nameBuilder.append(noAbbrNames); - nameBuilder.nextLine(); - nameBuilder.append(namesFf); - nameBuilder.append(abbrNames); - nameBuilder.nextLine(); - nameBuilder.append(namesFl); - nameBuilder.append(lastNamesOnly); - nameBuilder.nextLine(); - nameBuilder.append(namesNatbib); - builder.append(pan); - builder.append(nameBuilder.getPanel()); - builder.nextLine(); - - builder.appendSeparator(Localization.lang("Default sort criteria")); + priDesc = new CheckBox(Localization.lang("Descending")); + secDesc = new CheckBox(Localization.lang("Descending")); + terDesc = new CheckBox(Localization.lang("Descending")); + + GridPane builder = new GridPane(); + builder.add(new Label(Localization.lang("Format of author and editor name:")),1,1); + builder.add(namesAsIs,1,2); + builder.add(noAbbrNames,2,2); + builder.add(namesFf,1,3); + builder.add(abbrNames,2,3); + builder.add(namesFl,1,4); + builder.add(lastNamesOnly,2,4); + + builder.add(namesNatbib,1,5); + + + builder.add(new Label(Localization.lang("Default sort criteria")),1,6); // Create a new panel with its own FormLayout for these items: - FormLayout layout2 = new FormLayout( - "left:pref, 8dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, left:pref", ""); - DefaultFormBuilder builder2 = new DefaultFormBuilder(layout2); - lab = new JLabel(Localization.lang("Primary sort criterion")); - builder2.append(lab); - builder2.append(priSort); - builder2.append(priField); - builder2.append(priDesc); - builder2.nextLine(); - lab = new JLabel(Localization.lang("Secondary sort criterion")); - builder2.append(lab); - builder2.append(secSort); - builder2.append(secField); - builder2.append(secDesc); - builder2.nextLine(); - lab = new JLabel(Localization.lang("Tertiary sort criterion")); - builder2.append(lab); - builder2.append(terSort); - builder2.append(terField); - builder2.append(terDesc); - builder.nextLine(); - builder.append(pan); - builder.append(builder2.getPanel()); - builder.nextLine(); - builder.append(pan); - builder2 = new DefaultFormBuilder(new FormLayout("left:pref, 8dlu, fill:pref", "")); - builder2.append(Localization.lang("Sort the following fields as numeric fields") + ':'); - builder2.append(numericFields); - builder.append(builder2.getPanel(), 5); - builder.nextLine(); - builder.appendSeparator(Localization.lang("General")); - builder.append(pan); - builder.append(autoResizeMode); - builder.nextLine(); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); - - namesNatbib.addChangeListener(e -> { - abbrNames.setEnabled(!namesNatbib.isSelected()); - lastNamesOnly.setEnabled(!namesNatbib.isSelected()); - noAbbrNames.setEnabled(!namesNatbib.isSelected()); + Label lab = new Label(); + lab = new Label(Localization.lang(" Primary sort criterion")); + builder.add(lab,1,7); + builder.add(priSort,2,7); + builder.add(priField,3,7); + builder.add(priDesc,4,7); + + lab = new Label(Localization.lang(" Secondary sort criterion")); + builder.add(lab,1,8); + builder.add(secSort,2,8); + builder.add(secField,3,8); + builder.add(secDesc,4,8); + + lab = new Label(Localization.lang(" Tertiary sort criterion")); + builder.add(lab,1,9); + builder.add(terSort,2,9); + builder.add(terField,3,9); + builder.add(terDesc,4,9); + + + builder.add(new Label(Localization.lang(" Sort the following fields as numeric fields") + ':'),1,10); + builder.add(numericFields,2,10); + + builder.add(new Label(Localization.lang("General")),1,11); + builder.add(autoResizeMode,1,12); + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); + + namesNatbib.setOnAction(e -> { + abbrNames.setDisable(namesNatbib.isSelected()); + lastNamesOnly.setDisable(namesNatbib.isSelected()); + noAbbrNames.setDisable(namesNatbib.isSelected()); }); } @@ -206,9 +169,7 @@ public void setValues() { priField.setText(prefs.get(JabRefPreferences.TABLE_PRIMARY_SORT_FIELD)); secField.setText(prefs.get(JabRefPreferences.TABLE_SECONDARY_SORT_FIELD)); terField.setText(prefs.get(JabRefPreferences.TABLE_TERTIARY_SORT_FIELD)); - priSort.setSelectedIndex(0); - secSort.setSelectedIndex(0); - terSort.setSelectedIndex(0); + if (prefs.getBoolean(JabRefPreferences.NAMES_AS_IS)) { namesAsIs.setSelected(true); @@ -230,9 +191,9 @@ public void setValues() { secDesc.setSelected(prefs.getBoolean(JabRefPreferences.TABLE_SECONDARY_SORT_DESCENDING)); terDesc.setSelected(prefs.getBoolean(JabRefPreferences.TABLE_TERTIARY_SORT_DESCENDING)); - abbrNames.setEnabled(!namesNatbib.isSelected()); - lastNamesOnly.setEnabled(!namesNatbib.isSelected()); - noAbbrNames.setEnabled(!namesNatbib.isSelected()); + abbrNames.setDisable(namesNatbib.isSelected()); + lastNamesOnly.setDisable(namesNatbib.isSelected()); + noAbbrNames.setDisable(namesNatbib.isSelected()); String numF = prefs.get(JabRefPreferences.NUMERIC_FIELDS); if (numF == null) { diff --git a/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java b/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java index d2a286f7071..b0bd76d7276 100644 --- a/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java +++ b/src/main/java/org/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java @@ -12,7 +12,6 @@ import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFrame; import javax.swing.JTextField; import org.jabref.Globals; @@ -49,7 +48,7 @@ public NewProtectedTermsFileDialog(JDialog parent, ProtectedTermsLoader loader, } public NewProtectedTermsFileDialog(DialogService dialogService, ProtectedTermsLoader loader) { - super((JFrame) null, Localization.lang("New protected terms file"), true, NewProtectedTermsFileDialog.class); + super(Localization.lang("New protected terms file"), true, NewProtectedTermsFileDialog.class); this.loader = loader; this.dialogService = dialogService; setupDialog(); diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java index 30c1faf65d9..43bcb520cd5 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java @@ -4,6 +4,10 @@ import javax.swing.JPanel; import javax.swing.JTextField; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.util.DefaultTaskExecutor; @@ -16,7 +20,9 @@ public class PushToApplicationSettings { protected final JTextField path = new JTextField(30); + protected final TextField path1 = new TextField(); protected JPanel settings; + protected GridPane jfxSettings; protected FormBuilder builder; protected AbstractPushToApplication application; private DialogService dialogService; @@ -39,6 +45,15 @@ public JPanel getSettingsPanel() { return settings; } + public GridPane getJFXSettingPane(){ + application.initParameters(); + String commandPath = Globals.prefs.get(application.commandPathPreferenceKey); + if(jfxSettings == null){ + initJFXSettingsPanel(); + } + path1.setText(commandPath); + return jfxSettings; + } /** * Create a FormBuilder, fill it with a textbox for the path and store the JPanel in settings */ @@ -66,6 +81,27 @@ protected void initSettingsPanel() { settings = builder.build(); } + protected void initJFXSettingsPanel() { + jfxSettings = new GridPane(); + StringBuilder label = new StringBuilder(Localization.lang("Path to %0", application.getApplicationName())); + // In case the application name and the actual command is not the same, add the command in brackets + if (application.getCommandName() == null) { + label.append(':'); + } else { + label.append(" (").append(application.getCommandName()).append("):"); + } + jfxSettings.add(new Label(label.toString()),1,1); + jfxSettings.add(path1,2, 1); + Button browse = new Button(Localization.lang("Browse")); + + FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); + + browse.setOnAction( + e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)) + .ifPresent(f -> path.setText(f.toAbsolutePath().toString()))); + jfxSettings.add(browse,3, 1); + } /** * This method is called to indicate that the settings panel returned from the getSettingsPanel() method has been * shown to the user and that the user has indicated that the settings should be stored. This method must store the diff --git a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java index 3f0665b5a81..77eea7247f5 100644 --- a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java @@ -3,6 +3,7 @@ import javax.swing.JPanel; import javax.swing.JTextField; +import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -17,6 +18,12 @@ public JPanel getSettingsPanel() { return super.getSettingsPanel(); } + @Override + public GridPane getJFXSettingPane(){ + additionalParams.setText(Globals.prefs.get(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS)); + return super.getJFXSettingPane(); + } + @Override public void storeSettings() { super.storeSettings(); diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index 04fc40e2bdc..d69733a48d5 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -196,7 +196,7 @@ public GlobalSearchBar(JabRefFrame frame) { this.setAlignment(Pos.CENTER_LEFT); } - public void performGlobalSearch() { + private void performGlobalSearch() { BasePanel currentBasePanel = frame.getCurrentBasePanel(); if ((currentBasePanel == null) || validateSearchResultFrame(true)) { return; diff --git a/src/main/java/org/jabref/gui/search/SearchTextField.java b/src/main/java/org/jabref/gui/search/SearchTextField.java index b752b744ccf..cbb8ef0e650 100644 --- a/src/main/java/org/jabref/gui/search/SearchTextField.java +++ b/src/main/java/org/jabref/gui/search/SearchTextField.java @@ -1,7 +1,5 @@ package org.jabref.gui.search; -import javafx.scene.control.TextField; - import org.jabref.gui.icon.IconTheme; import org.jabref.logic.l10n.Localization; @@ -10,7 +8,7 @@ public class SearchTextField { - public static TextField create() { + public static CustomTextField create() { CustomTextField textField = (CustomTextField) TextFields.createClearableTextField(); textField.setPromptText(Localization.lang("Search") + "..."); textField.setLeft(IconTheme.JabRefIcons.SEARCH.getGraphicNode()); diff --git a/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java b/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java index 86d7a6429b4..9dd594d2418 100644 --- a/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java +++ b/src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java @@ -24,7 +24,6 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; @@ -102,7 +101,7 @@ public class ConnectToSharedDatabaseDialog extends JabRefDialog { * @param frame the JabRef Frame */ public ConnectToSharedDatabaseDialog(JabRefFrame frame) { - super((JFrame) null, Localization.lang("Connect to shared database"), ConnectToSharedDatabaseDialog.class); + super(Localization.lang("Connect to shared database"), ConnectToSharedDatabaseDialog.class); this.frame = frame; initLayout(); updateEnableState(); diff --git a/src/main/java/org/jabref/gui/util/ControlHelper.java b/src/main/java/org/jabref/gui/util/ControlHelper.java index db6ae5e9d4c..88d03df9bdb 100644 --- a/src/main/java/org/jabref/gui/util/ControlHelper.java +++ b/src/main/java/org/jabref/gui/util/ControlHelper.java @@ -1,6 +1,7 @@ package org.jabref.gui.util; import java.util.function.Consumer; +import java.util.function.UnaryOperator; import javax.swing.JComponent; @@ -11,6 +12,7 @@ import javafx.scene.control.Button; import javafx.scene.control.ButtonType; import javafx.scene.control.DialogPane; +import javafx.scene.control.TextFormatter; public class ControlHelper { @@ -39,4 +41,20 @@ public static boolean childIsFocused(Parent node) { } }); } + + /** + * Returns a text formatter that restricts input to integers + */ + public static TextFormatter getIntegerTextFormatter() { + UnaryOperator filter = change -> { + String text = change.getText(); + + if (text.matches("[0-9]*")) { + return change; + } + + return null; + }; + return new TextFormatter<>(filter); + } } diff --git a/src/main/java/org/jabref/gui/util/ThemeLoader.java b/src/main/java/org/jabref/gui/util/ThemeLoader.java index 4ec89571d4d..208b808ec31 100644 --- a/src/main/java/org/jabref/gui/util/ThemeLoader.java +++ b/src/main/java/org/jabref/gui/util/ThemeLoader.java @@ -11,6 +11,7 @@ import javafx.scene.Parent; import javafx.scene.Scene; +import org.jabref.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.model.strings.StringUtil; import org.jabref.model.util.FileUpdateMonitor; @@ -58,6 +59,8 @@ public void installBaseCss(Scene scene) { addAndWatchForChanges(scene, cssUrl, 1); } } + + Globals.prefs.getFontSize().ifPresent(size -> scene.getRoot().setStyle("-fx-font-size: " + size + "pt;")); } private void addAndWatchForChanges(Scene scene, String cssUrl, int index) { diff --git a/src/main/java/org/jabref/gui/util/ViewModelListCellFactory.java b/src/main/java/org/jabref/gui/util/ViewModelListCellFactory.java index e33bd4cbccc..e628e1c371e 100644 --- a/src/main/java/org/jabref/gui/util/ViewModelListCellFactory.java +++ b/src/main/java/org/jabref/gui/util/ViewModelListCellFactory.java @@ -3,6 +3,7 @@ import java.util.function.BiConsumer; import javafx.scene.Node; +import javafx.scene.control.ComboBox; import javafx.scene.control.ContextMenu; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; @@ -107,6 +108,11 @@ public ViewModelListCellFactory setOnDragOver(BiConsumer comboBox) { + comboBox.setButtonCell(this.call(null)); + comboBox.setCellFactory(this); + } + @Override public ListCell call(ListView param) { diff --git a/src/main/java/org/jabref/gui/worker/VersionWorker.java b/src/main/java/org/jabref/gui/worker/VersionWorker.java index 21d47599359..a761066d18c 100644 --- a/src/main/java/org/jabref/gui/worker/VersionWorker.java +++ b/src/main/java/org/jabref/gui/worker/VersionWorker.java @@ -112,7 +112,7 @@ private void showUpdateInfo(List availableVersions) { } else { // notify the user about a newer version - new NewVersionDialog(null, installedVersion, newerVersion.get()); + new NewVersionDialog(installedVersion, newerVersion.get()); } } diff --git a/src/main/java/org/jabref/logic/exporter/FileSaveSession.java b/src/main/java/org/jabref/logic/exporter/FileSaveSession.java index fa92e96c3ea..697c319c69b 100644 --- a/src/main/java/org/jabref/logic/exporter/FileSaveSession.java +++ b/src/main/java/org/jabref/logic/exporter/FileSaveSession.java @@ -29,7 +29,6 @@ * If committing fails, the temporary file will not be deleted. */ public class FileSaveSession extends SaveSession { - private static final Logger LOGGER = LoggerFactory.getLogger(FileSaveSession.class); // Filenames. diff --git a/src/main/java/org/jabref/logic/importer/EntryBasedParserFetcher.java b/src/main/java/org/jabref/logic/importer/EntryBasedParserFetcher.java index 7bfea57a6d6..e6927dd2b50 100644 --- a/src/main/java/org/jabref/logic/importer/EntryBasedParserFetcher.java +++ b/src/main/java/org/jabref/logic/importer/EntryBasedParserFetcher.java @@ -63,7 +63,7 @@ default List performSearch(BibEntry entry) throws FetcherException { throw new FetcherException("Search URI is malformed", e); } catch (IOException e) { // TODO: Catch HTTP Response 401 errors and report that user has no rights to access resource - throw new FetcherException("An I/O exception occurred", e); + throw new FetcherException("A network error occurred", e); } catch (ParseException e) { throw new FetcherException("An internal parser error occurred", e); } diff --git a/src/main/java/org/jabref/logic/importer/FulltextFetchers.java b/src/main/java/org/jabref/logic/importer/FulltextFetchers.java index fb57fd53145..99f0693db2b 100644 --- a/src/main/java/org/jabref/logic/importer/FulltextFetchers.java +++ b/src/main/java/org/jabref/logic/importer/FulltextFetchers.java @@ -62,17 +62,16 @@ public Optional findFullTextPDF(BibEntry entry) { findDoiForEntry(clonedEntry); } - List>> result = new ArrayList<>(); - result = JabRefExecutorService.INSTANCE.executeAll(getCallables(clonedEntry, finders), FETCHER_TIMEOUT, TimeUnit.SECONDS); + List>> result = JabRefExecutorService.INSTANCE.executeAll(getCallables(clonedEntry, finders), FETCHER_TIMEOUT, TimeUnit.SECONDS); return result.stream() - .map(FulltextFetchers::getResults) - .filter(Optional::isPresent) - .map(Optional::get) - .filter(res -> Objects.nonNull(res.getSource())) - .sorted(Comparator.comparingInt((FetcherResult res) -> res.getTrust().getTrustScore()).reversed()) - .map(res -> res.getSource()) - .findFirst(); + .map(FulltextFetchers::getResults) + .filter(Optional::isPresent) + .map(Optional::get) + .filter(res -> Objects.nonNull(res.getSource())) + .sorted(Comparator.comparingInt((FetcherResult res) -> res.getTrust().getTrustScore()).reversed()) + .map(FetcherResult::getSource) + .findFirst(); } private void findDoiForEntry(BibEntry clonedEntry) { diff --git a/src/main/java/org/jabref/logic/importer/IdBasedParserFetcher.java b/src/main/java/org/jabref/logic/importer/IdBasedParserFetcher.java index c63fb1fee59..29c1ded0e05 100644 --- a/src/main/java/org/jabref/logic/importer/IdBasedParserFetcher.java +++ b/src/main/java/org/jabref/logic/importer/IdBasedParserFetcher.java @@ -1,20 +1,17 @@ package org.jabref.logic.importer; -import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; -import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Optional; +import org.jabref.logic.net.URLDownload; import org.jabref.model.cleanup.Formatter; import org.jabref.model.entry.BibEntry; -import com.mashape.unirest.http.HttpResponse; -import com.mashape.unirest.http.Unirest; -import com.mashape.unirest.http.exceptions.UnirestException; import org.jsoup.helper.StringUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,9 +60,8 @@ default Optional performSearchById(String identifier) throws FetcherEx return Optional.empty(); } - try { - HttpResponse response = Unirest.get(getURLForID(identifier).toString()).asString(); - List fetchedEntries = getParser().parseEntries(new ByteArrayInputStream(response.getBody().getBytes(StandardCharsets.UTF_8))); + try (InputStream stream = new URLDownload(getURLForID(identifier)).asInputStream()) { + List fetchedEntries = getParser().parseEntries(stream); if (fetchedEntries.isEmpty()) { return Optional.empty(); @@ -86,11 +82,9 @@ default Optional performSearchById(String identifier) throws FetcherEx throw new FetcherException("Search URI is malformed", e); } catch (IOException e) { // TODO: Catch HTTP Response 401 errors and report that user has no rights to access resource - throw new FetcherException("An I/O exception occurred", e); + throw new FetcherException("A network error occurred", e); } catch (ParseException e) { throw new FetcherException("An internal parser error occurred", e); - } catch (UnirestException e) { - throw new FetcherException("An internal parser error occurred", e); } } } diff --git a/src/main/java/org/jabref/logic/importer/Parser.java b/src/main/java/org/jabref/logic/importer/Parser.java index 3279906d534..4b9c77c3783 100644 --- a/src/main/java/org/jabref/logic/importer/Parser.java +++ b/src/main/java/org/jabref/logic/importer/Parser.java @@ -1,5 +1,6 @@ package org.jabref.logic.importer; +import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.List; @@ -11,4 +12,8 @@ public interface Parser { List parseEntries(InputStream inputStream) throws ParseException; + + default List parseEntries(String dataString) throws ParseException { + return parseEntries(new ByteArrayInputStream(dataString.getBytes())); + } } diff --git a/src/main/java/org/jabref/logic/importer/SearchBasedParserFetcher.java b/src/main/java/org/jabref/logic/importer/SearchBasedParserFetcher.java index 04532e3e7d6..4d1cf696ae6 100644 --- a/src/main/java/org/jabref/logic/importer/SearchBasedParserFetcher.java +++ b/src/main/java/org/jabref/logic/importer/SearchBasedParserFetcher.java @@ -67,7 +67,7 @@ default List performSearch(String query) throws FetcherException { throw new FetcherException("Search URI is malformed", e); } catch (IOException e) { // TODO: Catch HTTP Response 401/403 errors and report that user has no rights to access resource - throw new FetcherException("An I/O exception occurred", e); + throw new FetcherException("A network error occurred", e); } catch (ParseException e) { throw new FetcherException("An internal parser error occurred", e); } diff --git a/src/main/java/org/jabref/logic/importer/WebFetcher.java b/src/main/java/org/jabref/logic/importer/WebFetcher.java index c33531ac5eb..6f300d67df2 100644 --- a/src/main/java/org/jabref/logic/importer/WebFetcher.java +++ b/src/main/java/org/jabref/logic/importer/WebFetcher.java @@ -1,5 +1,7 @@ package org.jabref.logic.importer; +import java.util.Optional; + import org.jabref.logic.help.HelpFile; /** @@ -20,7 +22,7 @@ public interface WebFetcher { * * @return the {@link HelpFile} enum constant for the help page */ - default HelpFile getHelpPage() { - return null; // no help page by default + default Optional getHelpPage() { + return Optional.empty(); // no help page by default } } diff --git a/src/main/java/org/jabref/logic/importer/WebFetchers.java b/src/main/java/org/jabref/logic/importer/WebFetchers.java index e882279111b..3329a6215f2 100644 --- a/src/main/java/org/jabref/logic/importer/WebFetchers.java +++ b/src/main/java/org/jabref/logic/importer/WebFetchers.java @@ -9,6 +9,7 @@ import org.jabref.logic.importer.fetcher.ACS; import org.jabref.logic.importer.fetcher.ArXiv; import org.jabref.logic.importer.fetcher.AstrophysicsDataSystem; +import org.jabref.logic.importer.fetcher.CiteSeer; import org.jabref.logic.importer.fetcher.CrossRef; import org.jabref.logic.importer.fetcher.DBLPFetcher; import org.jabref.logic.importer.fetcher.DOAJFetcher; @@ -89,7 +90,9 @@ public static List getSearchBasedFetchers(ImportFormatPrefer list.add(new DBLPFetcher(importFormatPreferences)); list.add(new SpringerFetcher()); list.add(new CrossRef()); + list.add(new CiteSeer()); list.add(new DOAJFetcher(importFormatPreferences)); + list.add(new IEEE(importFormatPreferences)); list.sort(Comparator.comparing(WebFetcher::getName)); return list; } @@ -139,7 +142,7 @@ public static List getFullTextFetchers(ImportFormatPreferences fetchers.add(new SpringerLink()); fetchers.add(new ACS()); fetchers.add(new ArXiv(importFormatPreferences)); - fetchers.add(new IEEE()); + fetchers.add(new IEEE(importFormatPreferences)); // Meta search fetchers.add(new GoogleScholar(importFormatPreferences)); fetchers.add(new OpenAccessDoi()); diff --git a/src/main/java/org/jabref/logic/importer/fetcher/ACMPortalFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/ACMPortalFetcher.java index 059fcbaff21..e36f730366b 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/ACMPortalFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/ACMPortalFetcher.java @@ -4,6 +4,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.util.Objects; +import java.util.Optional; import org.jabref.logic.help.HelpFile; import org.jabref.logic.importer.FetcherException; @@ -31,8 +32,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_ACM; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_ACM); } private static String createQueryString(String query) { diff --git a/src/main/java/org/jabref/logic/importer/fetcher/AbstractIsbnFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/AbstractIsbnFetcher.java index 52a252f69e2..c70a9e1b34f 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/AbstractIsbnFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/AbstractIsbnFetcher.java @@ -1,5 +1,7 @@ package org.jabref.logic.importer.fetcher; +import java.util.Optional; + import org.jabref.logic.help.HelpFile; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.IdBasedParserFetcher; @@ -19,8 +21,8 @@ public AbstractIsbnFetcher(ImportFormatPreferences importFormatPreferences) { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_ISBN; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_ISBN); } protected void ensureThatIsbnIsValid(String identifier) throws FetcherException { diff --git a/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java b/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java index 7f7edf703ca..bab25ab4aa7 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/ArXiv.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.xml.parsers.DocumentBuilder; @@ -53,9 +55,12 @@ * dspace-portalmec */ public class ArXiv implements FulltextFetcher, SearchBasedFetcher, IdBasedFetcher, IdFetcher { + private static final Logger LOGGER = LoggerFactory.getLogger(ArXiv.class); private static final String API_URL = "https://export.arxiv.org/api/query"; + private static final String ARXIV_URL_PREFIX_FOR_ID = "(https?://arxiv.org/abs/)"; + private static final Pattern URL_PATTERN = Pattern.compile(ARXIV_URL_PREFIX_FOR_ID); private final ImportFormatPreferences importFormatPreferences; @@ -69,10 +74,10 @@ public Optional findFullText(BibEntry entry) throws IOException { try { Optional pdfUrl = searchForEntries(entry).stream() - .map(ArXivEntry::getPdfUrl) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst(); + .map(ArXivEntry::getPdfUrl) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst(); if (pdfUrl.isPresent()) { LOGGER.info("Fulltext PDF found @ arXiv."); @@ -159,7 +164,7 @@ private List searchForEntries(String searchQuery) throws FetcherExce } private List queryApi(String searchQuery, List ids, int start, int maxResults) - throws FetcherException { + throws FetcherException { Document result = callApi(searchQuery, ids, start, maxResults); List entries = XMLUtil.asList(result.getElementsByTagName("entry")); @@ -195,7 +200,7 @@ private Document callApi(String searchQuery, List ids, int star } if (!ids.isEmpty()) { uriBuilder.addParameter("id_list", - ids.stream().map(ArXivIdentifier::getNormalized).collect(Collectors.joining(","))); + ids.stream().map(ArXivIdentifier::getNormalized).collect(Collectors.joining(","))); } uriBuilder.addParameter("start", String.valueOf(start)); uriBuilder.addParameter("max_results", String.valueOf(maxResults)); @@ -245,14 +250,15 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_OAI2_ARXIV; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_OAI2_ARXIV); } @Override public List performSearch(String query) throws FetcherException { return searchForEntries(query).stream().map( - (arXivEntry) -> arXivEntry.toBibEntry(importFormatPreferences.getKeywordSeparator())).collect(Collectors.toList()); + (arXivEntry) -> arXivEntry.toBibEntry(importFormatPreferences.getKeywordSeparator())) + .collect(Collectors.toList()); } @Override @@ -266,10 +272,10 @@ public Optional performSearchById(String identifier) throws FetcherExc @Override public Optional findIdentifier(BibEntry entry) throws FetcherException { return searchForEntries(entry).stream() - .map(ArXivEntry::getId) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst(); + .map(ArXivEntry::getId) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst(); } @Override @@ -290,7 +296,6 @@ private static class ArXivEntry { private final Optional journalReferenceText; private final Optional primaryCategory; - public ArXivEntry(Node item) { // see https://arxiv.org/help/api/user-manual#_details_of_atom_results_returned @@ -347,7 +352,7 @@ public ArXivEntry(Node item) { // Primary category // Ex: primaryCategory = XMLUtil.getNode(item, "arxiv:primary_category") - .flatMap(node -> XMLUtil.getAttributeContent(node, "term")); + .flatMap(node -> XMLUtil.getAttributeContent(node, "term")); } public static String correctLineBreaks(String s) { @@ -367,14 +372,16 @@ public Optional getPdfUrl() { * Returns the arXiv identifier */ public Optional getIdString() { - // remove leading https://arxiv.org/abs/ from abstract url to get arXiv ID - String prefix = "https://arxiv.org/abs/"; + return urlAbstractPage.map(abstractUrl -> { - if (abstractUrl.startsWith(prefix)) { - return abstractUrl.substring(prefix.length()); + Matcher matcher = URL_PATTERN.matcher(abstractUrl); + if (matcher.find()) { + // remove leading http(s)://arxiv.org/abs/ from abstract url to get arXiv ID + return abstractUrl.substring(matcher.group(1).length()); } else { return abstractUrl; } + }); } @@ -409,8 +416,7 @@ public BibEntry toBibEntry(Character keywordDelimiter) { getDate().ifPresent(date -> bibEntry.setField(FieldName.DATE, date)); primaryCategory.ifPresent(category -> bibEntry.setField(FieldName.EPRINTCLASS, category)); journalReferenceText.ifPresent(journal -> bibEntry.setField(FieldName.JOURNALTITLE, journal)); - getPdfUrl().ifPresent(url -> bibEntry - .setFiles(Collections.singletonList(new LinkedFile(url, "PDF")))); + getPdfUrl().ifPresent(url -> bibEntry.setFiles(Collections.singletonList(new LinkedFile(url, "PDF")))); return bibEntry; } } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystem.java b/src/main/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystem.java index 1ff7a6d7c89..6b99f420526 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystem.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystem.java @@ -9,6 +9,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Optional; import org.jabref.logic.cleanup.MoveFieldCleanup; import org.jabref.logic.formatter.bibtexfields.ClearFormatter; @@ -115,8 +116,8 @@ public URL getURLForID(String identifier) throws URISyntaxException, MalformedUR } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_ADS; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_ADS); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/CiteSeer.java b/src/main/java/org/jabref/logic/importer/fetcher/CiteSeer.java new file mode 100644 index 00000000000..56777a8809c --- /dev/null +++ b/src/main/java/org/jabref/logic/importer/fetcher/CiteSeer.java @@ -0,0 +1,95 @@ +package org.jabref.logic.importer.fetcher; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.jabref.logic.formatter.bibtexfields.HtmlToUnicodeFormatter; +import org.jabref.logic.formatter.casechanger.TitleCaseFormatter; +import org.jabref.logic.help.HelpFile; +import org.jabref.logic.importer.FetcherException; +import org.jabref.logic.importer.Parser; +import org.jabref.logic.importer.SearchBasedParserFetcher; +import org.jabref.logic.importer.fileformat.CoinsParser; +import org.jabref.logic.util.OS; +import org.jabref.model.cleanup.FieldFormatterCleanup; +import org.jabref.model.cleanup.Formatter; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FieldName; + +import org.apache.http.client.utils.URIBuilder; + +public class CiteSeer implements SearchBasedParserFetcher { + + public CiteSeer() { + } + + @Override + public String getName() { + return "CiteSeerX"; + } + + @Override + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_CITESEERX); + } + + @Override + public URL getURLForQuery(String query) throws URISyntaxException, MalformedURLException, FetcherException { + URIBuilder uriBuilder = new URIBuilder("https://citeseer.ist.psu.edu/search"); + uriBuilder.addParameter("sort", "rlv"); // Sort by relevance + uriBuilder.addParameter("q", query); // Query + uriBuilder.addParameter("t", "doc"); // Type: documents + //uriBuilder.addParameter("start", "0"); // Start index (not supported at the moment) + return uriBuilder.build().toURL(); + } + + @Override + public Parser getParser() { + // MathSciNet returns COinS result embedded in HTML + // So we extract the data string from the tags and pass the content to the COinS parser + return inputStream -> { + String response = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining(OS.NEWLINE)); + + List entries = new ArrayList<>(); + CoinsParser parser = new CoinsParser(); + Pattern pattern = Pattern.compile(""); + Matcher matcher = pattern.matcher(response); + while (matcher.find()) { + String encodedDataString = matcher.group(1); + entries.addAll(parser.parseEntries(encodedDataString)); + } + return entries; + }; + } + + @Override + public void doPostCleanup(BibEntry entry) { + // CiteSeer escapes some characters in a way that is not recognized by the normal html to unicode formatter + // We, of course, also want to convert these special characters + Formatter extendedHtmlFormatter = new HtmlToUnicodeFormatter() { + @Override + public String format(String fieldText) { + String formatted = super.format(fieldText); + formatted = formatted.replaceAll("%3A", ":"); + formatted = formatted.replaceAll("%3Cem%3", ""); + formatted = formatted.replaceAll("%3C%2Fem%3E", ""); + formatted = formatted.replaceAll("%2C\\+", " "); + formatted = formatted.replaceAll("\\+", " "); + return formatted; + } + }; + new FieldFormatterCleanup(FieldName.INTERNAL_ALL_FIELD, extendedHtmlFormatter).cleanup(entry); + + // Many titles in the CiteSeer database have all-capital titles, for convenience we convert them to title case + new FieldFormatterCleanup(FieldName.TITLE, new TitleCaseFormatter()).cleanup(entry); + } +} diff --git a/src/main/java/org/jabref/logic/importer/fetcher/DBLPFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/DBLPFetcher.java index c422a9c28ca..57937051561 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/DBLPFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/DBLPFetcher.java @@ -4,6 +4,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.util.Objects; +import java.util.Optional; import org.jabref.logic.cleanup.DoiCleanup; import org.jabref.logic.formatter.bibtexfields.ClearFormatter; @@ -71,8 +72,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_DBLP; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_DBLP); } } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/DOAJFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/DOAJFetcher.java index 213be8c220d..67bc0dc97ac 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/DOAJFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/DOAJFetcher.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import org.jabref.logic.help.HelpFile; @@ -15,14 +16,16 @@ import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.logic.importer.Parser; import org.jabref.logic.importer.SearchBasedParserFetcher; -import org.jabref.logic.importer.util.JSONEntryParser; import org.jabref.logic.net.URLUtil; import org.jabref.logic.util.OS; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FieldName; import org.apache.http.client.utils.URIBuilder; import org.json.JSONArray; import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Fetches data from the Directory of Open Access Journals (DOAJ) @@ -31,6 +34,8 @@ */ public class DOAJFetcher implements SearchBasedParserFetcher { + private static final Logger LOGGER = LoggerFactory.getLogger(DOAJFetcher.class); + private static final String SEARCH_URL = "https://doaj.org/api/v1/search/articles/"; private final ImportFormatPreferences preferences; @@ -38,14 +43,123 @@ public DOAJFetcher(ImportFormatPreferences preferences) { this.preferences = Objects.requireNonNull(preferences); } + /** + * Convert a JSONObject containing a bibJSON entry to a BibEntry + * + * @param bibJsonEntry The JSONObject to convert + * @return the converted BibEntry + */ + public static BibEntry parseBibJSONtoBibtex(JSONObject bibJsonEntry, Character keywordSeparator) { + // Fields that are directly accessible at the top level BibJson object + String[] singleFieldStrings = {FieldName.YEAR, FieldName.TITLE, FieldName.ABSTRACT, FieldName.MONTH}; + + // Fields that are accessible in the journal part of the BibJson object + String[] journalSingleFieldStrings = {FieldName.PUBLISHER, FieldName.NUMBER, FieldName.VOLUME}; + + BibEntry entry = new BibEntry(); + entry.setType("article"); + + // Authors + if (bibJsonEntry.has("author")) { + JSONArray authors = bibJsonEntry.getJSONArray("author"); + List authorList = new ArrayList<>(); + for (int i = 0; i < authors.length(); i++) { + if (authors.getJSONObject(i).has("name")) { + authorList.add(authors.getJSONObject(i).getString("name")); + } else { + LOGGER.info("Empty author name."); + } + } + entry.setField(FieldName.AUTHOR, String.join(" and ", authorList)); + } else { + LOGGER.info("No author found."); + } + + // Direct accessible fields + for (String field : singleFieldStrings) { + if (bibJsonEntry.has(field)) { + entry.setField(field, bibJsonEntry.getString(field)); + } + } + + // Page numbers + if (bibJsonEntry.has("start_page")) { + if (bibJsonEntry.has("end_page")) { + entry.setField(FieldName.PAGES, + bibJsonEntry.getString("start_page") + "--" + bibJsonEntry.getString("end_page")); + } else { + entry.setField(FieldName.PAGES, bibJsonEntry.getString("start_page")); + } + } + + // Journal + if (bibJsonEntry.has("journal")) { + JSONObject journal = bibJsonEntry.getJSONObject("journal"); + // Journal title + if (journal.has("title")) { + entry.setField(FieldName.JOURNAL, journal.getString("title").trim()); + } else { + LOGGER.info("No journal title found."); + } + // Other journal related fields + for (String field : journalSingleFieldStrings) { + if (journal.has(field)) { + entry.setField(field, journal.getString(field)); + } + } + } else { + LOGGER.info("No journal information found."); + } + + // Keywords + if (bibJsonEntry.has("keywords")) { + JSONArray keywords = bibJsonEntry.getJSONArray("keywords"); + for (int i = 0; i < keywords.length(); i++) { + if (!keywords.isNull(i)) { + entry.addKeyword(keywords.getString(i).trim(), keywordSeparator); + } + } + } + + // Identifiers + if (bibJsonEntry.has("identifier")) { + JSONArray identifiers = bibJsonEntry.getJSONArray("identifier"); + for (int i = 0; i < identifiers.length(); i++) { + String type = identifiers.getJSONObject(i).getString("type"); + if ("doi".equals(type)) { + entry.setField(FieldName.DOI, identifiers.getJSONObject(i).getString("id")); + } else if ("pissn".equals(type)) { + entry.setField(FieldName.ISSN, identifiers.getJSONObject(i).getString("id")); + } else if ("eissn".equals(type)) { + entry.setField(FieldName.ISSN, identifiers.getJSONObject(i).getString("id")); + } + } + } + + // Links + if (bibJsonEntry.has("link")) { + JSONArray links = bibJsonEntry.getJSONArray("link"); + for (int i = 0; i < links.length(); i++) { + if (links.getJSONObject(i).has("type")) { + String type = links.getJSONObject(i).getString("type"); + if ("fulltext".equals(type) && links.getJSONObject(i).has("url")) { + entry.setField(FieldName.URL, links.getJSONObject(i).getString("url")); + } + } + } + } + + return entry; + } + @Override public String getName() { return "DOAJ"; } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_DOAJ; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_DOAJ); } @Override @@ -60,7 +174,6 @@ public URL getURLForQuery(String query) throws URISyntaxException, MalformedURLE @Override public Parser getParser() { return inputStream -> { - JSONEntryParser jsonConverter = new JSONEntryParser(); String response = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining(OS.NEWLINE)); JSONObject jsonObject = new JSONObject(response); @@ -69,7 +182,7 @@ public Parser getParser() { JSONArray results = jsonObject.getJSONArray("results"); for (int i = 0; i < results.length(); i++) { JSONObject bibJsonEntry = results.getJSONObject(i).getJSONObject("bibjson"); - BibEntry entry = jsonConverter.parseBibJSONtoBibtex(bibJsonEntry, preferences.getKeywordSeparator()); + BibEntry entry = parseBibJSONtoBibtex(bibJsonEntry, preferences.getKeywordSeparator()); entries.add(entry); } } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/DiVA.java b/src/main/java/org/jabref/logic/importer/fetcher/DiVA.java index d3c56712371..5a876fd9ff8 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/DiVA.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/DiVA.java @@ -3,6 +3,7 @@ import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.util.Optional; import org.jabref.logic.help.HelpFile; import org.jabref.logic.importer.FetcherException; @@ -32,8 +33,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_DIVA; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_DIVA); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/DoiFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/DoiFetcher.java index 766f2570164..0deb118292e 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/DoiFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/DoiFetcher.java @@ -38,8 +38,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_DOI; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_DOI); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/GoogleScholar.java b/src/main/java/org/jabref/logic/importer/fetcher/GoogleScholar.java index 466d0259f29..24a061a26b5 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/GoogleScholar.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/GoogleScholar.java @@ -117,8 +117,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_GOOGLE_SCHOLAR; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_GOOGLE_SCHOLAR); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/GvkFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/GvkFetcher.java index 963ff5ab5e4..67b9879ec35 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/GvkFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/GvkFetcher.java @@ -8,6 +8,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import org.jabref.logic.help.HelpFile; @@ -34,8 +35,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_GVK; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_GVK); } private String getSearchQueryStringForComplexQuery(List queryList) { diff --git a/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java b/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java index 838de0932aa..ac8192a2360 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/IEEE.java @@ -1,18 +1,36 @@ package org.jabref.logic.importer.fetcher; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.jabref.logic.help.HelpFile; +import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.FulltextFetcher; +import org.jabref.logic.importer.ImportFormatPreferences; +import org.jabref.logic.importer.Parser; +import org.jabref.logic.importer.SearchBasedParserFetcher; import org.jabref.logic.net.URLDownload; +import org.jabref.logic.util.OS; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BiblatexEntryTypes; import org.jabref.model.entry.FieldName; +import org.jabref.model.entry.LinkedFile; import org.jabref.model.entry.identifier.DOI; +import org.apache.http.client.utils.URIBuilder; +import org.json.JSONArray; +import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,8 +38,10 @@ * Class for finding PDF URLs for entries on IEEE * Will first look for URLs of the type https://ieeexplore.ieee.org/stamp/stamp.jsp?[tp=&]arnumber=... * If not found, will resolve the DOI, if it starts with 10.1109, and try to find a similar link on the HTML page + * + * @implNote API documentation */ -public class IEEE implements FulltextFetcher { +public class IEEE implements FulltextFetcher, SearchBasedParserFetcher { private static final Logger LOGGER = LoggerFactory.getLogger(IEEE.class); private static final String STAMP_BASE_STRING_DOCUMENT = "/stamp/stamp.jsp?tp=&arnumber="; @@ -32,6 +52,75 @@ public class IEEE implements FulltextFetcher { private static final String IEEE_DOI = "10.1109"; private static final String BASE_URL = "https://ieeexplore.ieee.org"; + private final ImportFormatPreferences preferences; + + public IEEE(ImportFormatPreferences preferences) { + this.preferences = Objects.requireNonNull(preferences); + } + + /** + * @implNote documentation + */ + private static BibEntry parseJsonRespone(JSONObject jsonEntry, Character keywordSeparator) { + BibEntry entry = new BibEntry(); + + switch (jsonEntry.optString("content_type")) { + case "Books": + entry.setType(BiblatexEntryTypes.BOOK); + break; + case "Conferences": + entry.setType(BiblatexEntryTypes.INPROCEEDINGS); + break; + case "Courses": + entry.setType(BiblatexEntryTypes.MISC); + break; + default: + entry.setType(BiblatexEntryTypes.ARTICLE); + break; + } + + entry.setField(FieldName.ABSTRACT, jsonEntry.optString("abstract")); + //entry.setField(FieldName.IEEE_ID, jsonEntry.optString("article_number")); + + final List authors = new ArrayList<>(); + JSONObject authorsContainer = jsonEntry.optJSONObject("authors"); + authorsContainer.getJSONArray("authors").forEach(authorPure -> { + JSONObject author = (JSONObject) authorPure; + authors.add(author.optString("full_name")); + } + ); + entry.setField(FieldName.AUTHOR, authors.stream().collect(Collectors.joining(" and "))); + entry.setField(FieldName.LOCATION, jsonEntry.optString("conference_location")); + entry.setField(FieldName.DOI, jsonEntry.optString("doi")); + entry.setField(FieldName.PAGES, jsonEntry.optString("start_page") + "--" + jsonEntry.optString("end_page")); + + JSONObject keywordsContainer = jsonEntry.optJSONObject("index_terms"); + if (keywordsContainer != null) { + keywordsContainer.getJSONObject("ieee_terms").getJSONArray("terms").forEach(data -> { + String keyword = (String) data; + entry.addKeyword(keyword, keywordSeparator); + }); + keywordsContainer.getJSONObject("author_terms").getJSONArray("terms").forEach(data -> { + String keyword = (String) data; + entry.addKeyword(keyword, keywordSeparator); + }); + } + + entry.setField(FieldName.ISBN, jsonEntry.optString("isbn")); + entry.setField(FieldName.ISSN, jsonEntry.optString("issn")); + entry.setField(FieldName.ISSUE, jsonEntry.optString("issue")); + entry.addFile(new LinkedFile("", jsonEntry.optString("pdf_url"), "PDF")); + entry.setField(FieldName.JOURNALTITLE, jsonEntry.optString("publication_title")); + entry.setField(FieldName.DATE, jsonEntry.optString("publication_date")); + entry.setField(FieldName.EVENTTITLEADDON, jsonEntry.optString("conference_location")); + entry.setField(FieldName.EVENTDATE, jsonEntry.optString("conference_dates")); + entry.setField(FieldName.PUBLISHER, jsonEntry.optString("publisher")); + entry.setField(FieldName.TITLE, jsonEntry.optString("title")); + entry.setField(FieldName.VOLUME, jsonEntry.optString("volume")); + + return entry; + } + @Override public Optional findFullText(BibEntry entry) throws IOException { Objects.requireNonNull(entry); @@ -102,4 +191,44 @@ public TrustLevel getTrustLevel() { return TrustLevel.PUBLISHER; } + @Override + public URL getURLForQuery(String query) throws URISyntaxException, MalformedURLException, FetcherException { + URIBuilder uriBuilder = new URIBuilder("https://ieeexploreapi.ieee.org/api/v1/search/articles"); + uriBuilder.addParameter("apikey", "86wnawtvtc986d3wtnqynm8c"); + uriBuilder.addParameter("querytext", query); + + URLDownload.bypassSSLVerification(); + + return uriBuilder.build().toURL(); + } + + @Override + public Parser getParser() { + return inputStream -> { + String response = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining(OS.NEWLINE)); + JSONObject jsonObject = new JSONObject(response); + + List entries = new ArrayList<>(); + if (jsonObject.has("articles")) { + JSONArray results = jsonObject.getJSONArray("articles"); + for (int i = 0; i < results.length(); i++) { + JSONObject jsonEntry = results.getJSONObject(i); + BibEntry entry = parseJsonRespone(jsonEntry, preferences.getKeywordSeparator()); + entries.add(entry); + } + } + + return entries; + }; + } + + @Override + public String getName() { + return "IEEEXplore"; + } + + @Override + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_IEEEXPLORE); + } } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/INSPIREFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/INSPIREFetcher.java index 761a59e72ef..2229d752d66 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/INSPIREFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/INSPIREFetcher.java @@ -7,6 +7,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -48,8 +49,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_INSPIRE; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_INSPIRE); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/MedlineFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/MedlineFetcher.java index 11e8420955c..0b8ace85d7d 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/MedlineFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/MedlineFetcher.java @@ -12,6 +12,7 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.Optional; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; @@ -127,8 +128,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_MEDLINE; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_MEDLINE); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/RfcFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/RfcFetcher.java index 5840c25cc15..19f6128e708 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/RfcFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/RfcFetcher.java @@ -3,6 +3,7 @@ import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.util.Optional; import org.jabref.logic.help.HelpFile; import org.jabref.logic.importer.FetcherException; @@ -33,8 +34,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_RFC; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_RFC); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fetcher/SpringerFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/SpringerFetcher.java index 6b6e8f60527..213fe7c79ac 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/SpringerFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/SpringerFetcher.java @@ -7,19 +7,24 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.jabref.logic.help.HelpFile; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.Parser; import org.jabref.logic.importer.SearchBasedParserFetcher; -import org.jabref.logic.importer.util.JSONEntryParser; import org.jabref.logic.util.OS; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.FieldName; +import org.jabref.model.entry.LinkedFile; +import org.jabref.model.entry.Month; import org.apache.http.client.utils.URIBuilder; import org.json.JSONArray; import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Fetches data from the Springer @@ -28,17 +33,122 @@ */ public class SpringerFetcher implements SearchBasedParserFetcher { + private static final Logger LOGGER = LoggerFactory.getLogger(SpringerFetcher.class); + private static final String API_URL = "http://api.springernature.com/meta/v1/json?q="; private static final String API_KEY = "b0c7151179b3d9c1119cf325bca8460d"; + /** + * Convert a JSONObject obtained from http://api.springer.com/metadata/json to a BibEntry + * + * @param springerJsonEntry the JSONObject from search results + * @return the converted BibEntry + */ + public static BibEntry parseSpringerJSONtoBibtex(JSONObject springerJsonEntry) { + // Fields that are directly accessible at the top level Json object + String[] singleFieldStrings = {FieldName.ISSN, FieldName.VOLUME, FieldName.ABSTRACT, FieldName.DOI, FieldName.TITLE, FieldName.NUMBER, + FieldName.PUBLISHER}; + + BibEntry entry = new BibEntry(); + String nametype; + + // Guess publication type + String isbn = springerJsonEntry.optString("isbn"); + if (com.google.common.base.Strings.isNullOrEmpty(isbn)) { + // Probably article + entry.setType("article"); + nametype = FieldName.JOURNAL; + } else { + // Probably book chapter or from proceeding, go for book chapter + entry.setType("incollection"); + nametype = FieldName.BOOKTITLE; + entry.setField(FieldName.ISBN, isbn); + } + + // Authors + if (springerJsonEntry.has("creators")) { + JSONArray authors = springerJsonEntry.getJSONArray("creators"); + List authorList = new ArrayList<>(); + for (int i = 0; i < authors.length(); i++) { + if (authors.getJSONObject(i).has("creator")) { + authorList.add(authors.getJSONObject(i).getString("creator")); + } else { + LOGGER.info("Empty author name."); + } + } + entry.setField(FieldName.AUTHOR, String.join(" and ", authorList)); + } else { + LOGGER.info("No author found."); + } + + // Direct accessible fields + for (String field : singleFieldStrings) { + if (springerJsonEntry.has(field)) { + String text = springerJsonEntry.getString(field); + if (!text.isEmpty()) { + entry.setField(field, text); + } + } + } + + // Page numbers + if (springerJsonEntry.has("startingPage") && !(springerJsonEntry.getString("startingPage").isEmpty())) { + if (springerJsonEntry.has("endingPage") && !(springerJsonEntry.getString("endingPage").isEmpty())) { + entry.setField(FieldName.PAGES, + springerJsonEntry.getString("startingPage") + "--" + springerJsonEntry.getString("endingPage")); + } else { + entry.setField(FieldName.PAGES, springerJsonEntry.getString("startingPage")); + } + } + + // Journal + if (springerJsonEntry.has("publicationName")) { + entry.setField(nametype, springerJsonEntry.getString("publicationName")); + } + + // Online file + if (springerJsonEntry.has("url")) { + JSONArray urls = springerJsonEntry.optJSONArray("url"); + if (urls == null) { + entry.setField(FieldName.URL, springerJsonEntry.optString("url")); + } else { + urls.forEach(data -> { + JSONObject url = (JSONObject) data; + if (url.optString("format").equalsIgnoreCase("pdf")) { + entry.addFile(new LinkedFile("online", url.optString("value"), "PDF")); + } + }); + } + } + + // Date + if (springerJsonEntry.has("publicationDate")) { + String date = springerJsonEntry.getString("publicationDate"); + entry.setField(FieldName.DATE, date); // For biblatex + String[] dateparts = date.split("-"); + entry.setField(FieldName.YEAR, dateparts[0]); + Optional month = Month.getMonthByNumber(Integer.parseInt(dateparts[1])); + month.ifPresent(entry::setMonth); + } + + // Clean up abstract (often starting with Abstract) + entry.getField(FieldName.ABSTRACT).ifPresent(abstractContents -> { + if (abstractContents.startsWith("Abstract")) { + entry.setField(FieldName.ABSTRACT, abstractContents.substring(8)); + } + }); + + return entry; + } + @Override public String getName() { return "Springer"; } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_SPRINGER; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_SPRINGER); } @Override @@ -62,7 +172,7 @@ public Parser getParser() { JSONArray results = jsonObject.getJSONArray("records"); for (int i = 0; i < results.length(); i++) { JSONObject jsonEntry = results.getJSONObject(i); - BibEntry entry = JSONEntryParser.parseSpringerJSONtoBibtex(jsonEntry); + BibEntry entry = parseSpringerJSONtoBibtex(jsonEntry); entries.add(entry); } } diff --git a/src/main/java/org/jabref/logic/importer/fetcher/TitleFetcher.java b/src/main/java/org/jabref/logic/importer/fetcher/TitleFetcher.java index 881b738edde..5fea61c0e8f 100644 --- a/src/main/java/org/jabref/logic/importer/fetcher/TitleFetcher.java +++ b/src/main/java/org/jabref/logic/importer/fetcher/TitleFetcher.java @@ -25,8 +25,8 @@ public String getName() { } @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_TITLE; + public Optional getHelpPage() { + return Optional.of(HelpFile.FETCHER_TITLE); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java b/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java index d9e3f5d4e83..16093dca0b3 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java @@ -6,7 +6,6 @@ import java.io.InputStreamReader; import java.io.PushbackReader; import java.io.Reader; -import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.Deque; @@ -110,10 +109,6 @@ public List parseEntries(Reader reader) throws ParseException { } } - public List parseEntries(String bibtexString) throws ParseException { - return parseEntries(new StringReader(bibtexString)); - } - public Optional parseSingleEntry(String bibtexString) throws ParseException { return parseEntries(bibtexString).stream().findFirst(); } diff --git a/src/main/java/org/jabref/logic/importer/fileformat/CoinsParser.java b/src/main/java/org/jabref/logic/importer/fileformat/CoinsParser.java new file mode 100644 index 00000000000..156dc551b5e --- /dev/null +++ b/src/main/java/org/jabref/logic/importer/fileformat/CoinsParser.java @@ -0,0 +1,78 @@ +package org.jabref.logic.importer.fileformat; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.jabref.logic.importer.ParseException; +import org.jabref.logic.importer.Parser; +import org.jabref.logic.util.OS; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BiblatexEntryTypes; +import org.jabref.model.entry.FieldName; + +/** + * @implNote implemented by reverse-engineering the implementation by CiteSeerX + */ +public class CoinsParser implements Parser { + + private final Pattern DOI = Pattern.compile("%3Fdoi%3D([^&]+)"); + private final Pattern TITLE = Pattern.compile("&rft.atitle=([^&]+)"); + private final Pattern JOURNAL = Pattern.compile("&rft.jtitle=([^&]+)"); + private final Pattern YEAR = Pattern.compile("&rft.date=([^&]+)"); + private final Pattern VOLUME = Pattern.compile("&rft.volume=([^&]+)"); + private final Pattern PAGES = Pattern.compile("&rft.pages=([^&]+)"); + private final Pattern ISSUE = Pattern.compile("&rft.issue=([^&]+)"); + private final Pattern TYPE = Pattern.compile("&rft.genre=([^&]+)"); + private final Pattern AUTHOR = Pattern.compile("&rft.au=([^&]+)"); + + @Override + public List parseEntries(InputStream inputStream) throws ParseException { + String data = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining(OS.NEWLINE)); + BibEntry entry = new BibEntry(); + + appendData(data, entry, DOI, FieldName.DOI); + appendData(data, entry, TITLE, FieldName.TITLE); + appendData(data, entry, JOURNAL, FieldName.JOURNALTITLE); + appendData(data, entry, YEAR, FieldName.YEAR); + appendData(data, entry, VOLUME, FieldName.VOLUME); + appendData(data, entry, PAGES, FieldName.PAGES); + appendData(data, entry, ISSUE, FieldName.ISSUE); + + Matcher matcherType = TYPE.matcher(data); + if (matcherType.find()) { + switch (matcherType.group(1)) { + case "article": + entry.setType(BiblatexEntryTypes.ARTICLE); + break; + case "unknown": + default: + entry.setType(BiblatexEntryTypes.MISC); + break; + } + } + + List authors = new ArrayList<>(); + Matcher matcherAuthors = AUTHOR.matcher(data); + while (matcherAuthors.find()) { + String author = matcherAuthors.group(1); + authors.add(author); + } + entry.setField(FieldName.AUTHOR, authors.stream().collect(Collectors.joining(" and "))); + + return Collections.singletonList(entry); + } + + private void appendData(String data, BibEntry entry, Pattern pattern, String fieldName) { + Matcher matcher = pattern.matcher(data); + if (matcher.find()) { + entry.setField(fieldName, matcher.group(1)); + } + } +} diff --git a/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java index ffc3469a567..19f4f52b636 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java @@ -416,7 +416,7 @@ private void putDate(Map fields, String elementName, DateDefinit private void putIfListIsNotEmpty(Map fields, List list, String key, String separator) { if (!list.isEmpty()) { - fields.put(key, Joiner.on(separator).join(list)); + fields.put(key, list.stream().collect(Collectors.joining(separator))); } } diff --git a/src/main/java/org/jabref/logic/net/ProgressInputStream.java b/src/main/java/org/jabref/logic/net/ProgressInputStream.java index 57d23907ff4..d114cbbe6cb 100644 --- a/src/main/java/org/jabref/logic/net/ProgressInputStream.java +++ b/src/main/java/org/jabref/logic/net/ProgressInputStream.java @@ -12,16 +12,18 @@ * Code based on http://stackoverflow.com/a/1339589/873661, but converted to use JavaFX properties instead of listeners */ public class ProgressInputStream extends FilterInputStream { + private final long maxNumBytes; private final LongProperty totalNumBytesRead; private final LongProperty progress; public ProgressInputStream(InputStream in, long maxNumBytes) { super(in); - this.maxNumBytes = maxNumBytes; this.totalNumBytesRead = new SimpleLongProperty(0); this.progress = new SimpleLongProperty(0); - this.progress.bind(totalNumBytesRead.divide(maxNumBytes)); + + this.maxNumBytes = maxNumBytes <= 0 ? 1 : maxNumBytes; + this.progress.bind(totalNumBytesRead.divide(this.maxNumBytes)); } public long getTotalNumBytesRead() { diff --git a/src/main/java/org/jabref/logic/net/URLDownload.java b/src/main/java/org/jabref/logic/net/URLDownload.java index 3f60aa8b9b7..5ae3f915c02 100644 --- a/src/main/java/org/jabref/logic/net/URLDownload.java +++ b/src/main/java/org/jabref/logic/net/URLDownload.java @@ -2,6 +2,7 @@ import java.io.BufferedInputStream; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; @@ -31,6 +32,7 @@ import java.util.Map; import java.util.Map.Entry; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; @@ -88,13 +90,14 @@ public URLDownload(URL source) { * We will fix this issue by accepting all (!) certificates. This is ugly; but as JabRef does not rely on * security-relevant information this is kind of OK (no, actually it is not...). * - * Taken from http://stackoverflow.com/a/6055903/873661 + * Taken from http://stackoverflow.com/a/6055903/873661 and https://stackoverflow.com/a/19542614/873661 */ public static void bypassSSLVerification() { LOGGER.warn("Fix SSL exceptions by accepting ALL certificates"); // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = {new X509TrustManager() { + @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @@ -109,11 +112,15 @@ public X509Certificate[] getAcceptedIssuers() { } }}; - // Install the all-trusting trust manager try { + // Install all-trusting trust manager SSLContext context = SSLContext.getInstance("TLS"); context.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); + + // Install all-trusting host verifier + HostnameVerifier allHostsValid = (hostname, session) -> true; + HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); } catch (Exception e) { LOGGER.error("A problem occurred when bypassing SSL verification", e); } @@ -244,8 +251,14 @@ public void toFile(Path destination) throws IOException { * Takes the web resource as the source for a monitored input stream. */ public ProgressInputStream asInputStream() throws IOException { - URLConnection urlConnection = this.openConnection(); - long fileSize = urlConnection.getContentLength(); + HttpURLConnection urlConnection = (HttpURLConnection) this.openConnection(); + + if ((urlConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) || (urlConnection.getResponseCode() == HttpURLConnection.HTTP_BAD_REQUEST)) + { + LOGGER.error("Response message {} returned for url {}", urlConnection.getResponseMessage(), urlConnection.getURL()); + return new ProgressInputStream(new ByteArrayInputStream(new byte[0]), 0); + } + long fileSize = urlConnection.getContentLengthLong(); return new ProgressInputStream(new BufferedInputStream(urlConnection.getInputStream()), fileSize); } @@ -306,8 +319,8 @@ private URLConnection openConnection() throws IOException { int status = ((HttpURLConnection) connection).getResponseCode(); if (status != HttpURLConnection.HTTP_OK) { if ((status == HttpURLConnection.HTTP_MOVED_TEMP) - || (status == HttpURLConnection.HTTP_MOVED_PERM) - || (status == HttpURLConnection.HTTP_SEE_OTHER)) { + || (status == HttpURLConnection.HTTP_MOVED_PERM) + || (status == HttpURLConnection.HTTP_SEE_OTHER)) { // get redirect url from "location" header field String newUrl = connection.getHeaderField("Location"); // open the new connnection again diff --git a/src/main/java/org/jabref/logic/util/io/FileBasedLock.java b/src/main/java/org/jabref/logic/util/io/FileBasedLock.java index 5c1bf0a3a64..a271879d184 100644 --- a/src/main/java/org/jabref/logic/util/io/FileBasedLock.java +++ b/src/main/java/org/jabref/logic/util/io/FileBasedLock.java @@ -12,14 +12,13 @@ public class FileBasedLock { /** - * The age in ms of a lockfile before JabRef will offer to "steal" the locked file. + * The age in ms of a lock file before JabRef will offer to "steal" the locked file. */ public static final long LOCKFILE_CRITICAL_AGE = 60000; - private static final Logger LOGGER = LoggerFactory.getLogger(FileBasedLock.class); private static final String LOCKFILE_SUFFIX = ".lock"; - // default retry count for aquiring file lock + // default retry count for acquiring file lock private static final int AQUIRE_LOCK_RETRY = 10; private FileBasedLock() { @@ -30,7 +29,7 @@ private FileBasedLock() { * there is, it waits for 500 ms. This is repeated until the lock is gone * or we have waited the maximum number of times. * - * @param file The file to check the lock for. + * @param file The file to check the lock for. * @param maxWaitCount The maximum number of times to wait. * @return true if the lock file is gone, false if it is still there. */ @@ -57,6 +56,7 @@ public static boolean waitForFileLock(Path file) { /** * Check whether a lock file exists for this file. + * * @param file The file to check. * @return true if a lock file exists, false otherwise. */ @@ -67,6 +67,7 @@ public static boolean hasLockFile(Path file) { /** * Find the lock file's last modified time, if it has a lock file. + * * @param file The file to check. * @return the last modified time if lock file exists, empty optional otherwise. */ diff --git a/src/main/java/org/jabref/migrations/PreferencesMigrations.java b/src/main/java/org/jabref/migrations/PreferencesMigrations.java index c7bf596d458..f0923915177 100644 --- a/src/main/java/org/jabref/migrations/PreferencesMigrations.java +++ b/src/main/java/org/jabref/migrations/PreferencesMigrations.java @@ -9,11 +9,9 @@ import java.util.function.UnaryOperator; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; -import java.util.stream.Stream; import org.jabref.Globals; import org.jabref.JabRefMain; -import org.jabref.logic.util.OS; import org.jabref.model.bibtexkeypattern.GlobalBibtexKeyPattern; import org.jabref.model.entry.FieldName; import org.jabref.preferences.JabRefPreferences; @@ -43,7 +41,6 @@ public static void runMigrations() { upgradeStoredCustomEntryTypes(Globals.prefs, mainPrefsNode); upgradeKeyBindingsToJavaFX(Globals.prefs); addCrossRefRelatedFieldsForAutoComplete(Globals.prefs); - upgradeObsoleteLookAndFeels(Globals.prefs); upgradePreviewStyleFromReviewToComment(Globals.prefs); } @@ -285,28 +282,6 @@ private static void migrateTypedKeyPrefs(JabRefPreferences prefs, Preferences ol prefs.putKeyPattern(keyPattern); } - private static void upgradeObsoleteLookAndFeels(JabRefPreferences prefs) { - - String currentLandF = prefs.getLookAndFeel(); - - Stream.of("com.jgoodies.looks.windows.WindowsLookAndFeel", "com.jgoodies.looks.plastic.PlasticLookAndFeel", - "com.jgoodies.looks.plastic.Plastic3DLookAndFeel", "com.jgoodies.looks.plastic.PlasticXPLookAndFeel", - "com.sun.java.swing.plaf.gtk.GTKLookAndFeel") - .filter(style -> style.equals(currentLandF)) - .findAny() - .ifPresent(loolAndFeel -> { - if (OS.WINDOWS) { - String windowsLandF = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; - prefs.setLookAndFeel(windowsLandF); - LOGGER.info("Switched from obsolete look and feel " + currentLandF + " to " + windowsLandF); - } else { - String nimbusLandF = "javax.swing.plaf.nimbus.NimbusLookAndFeel"; - prefs.setLookAndFeel(nimbusLandF); - LOGGER.info("Switched from obsolete look and feel " + currentLandF + " to " + nimbusLandF); - } - }); - } - static void upgradePreviewStyleFromReviewToComment(JabRefPreferences prefs) { String currentPreviewStyle = prefs.getPreviewStyle(); String migratedStyle = currentPreviewStyle.replace("\\begin{review}

Review: \\format[HTMLChars]{\\review} \\end{review}", "\\begin{comment}

Comment: \\format[HTMLChars]{\\comment} \\end{comment}"); diff --git a/src/main/java/org/jabref/model/entry/InternalBibtexFields.java b/src/main/java/org/jabref/model/entry/InternalBibtexFields.java index dfc7e097dd7..d33e73abdf8 100644 --- a/src/main/java/org/jabref/model/entry/InternalBibtexFields.java +++ b/src/main/java/org/jabref/model/entry/InternalBibtexFields.java @@ -93,6 +93,10 @@ public class InternalBibtexFields { SpecialField.RELEVANCE.getFieldName() ); + private static final Set SINGLE_LINE_FIELDS = Collections.unmodifiableSet(new HashSet<>( + Arrays.asList(FieldName.TITLE, FieldName.AUTHOR, FieldName.YEAR, FieldName.INSTITUTION) + )); + // singleton instance private static InternalBibtexFields RUNTIME = new InternalBibtexFields(); @@ -475,4 +479,8 @@ public static List getIEEETranBSTctlYesNoFields() { private void add(BibtexSingleField field) { fieldSet.put(field.getName(), field); } + + public static boolean isSingleLineField(final String fieldName) { + return SINGLE_LINE_FIELDS.contains(fieldName.toLowerCase()); + } } diff --git a/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java b/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java index ba3e428f9ca..8b9287d3e2b 100644 --- a/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java +++ b/src/main/java/org/jabref/model/entry/identifier/ArXivIdentifier.java @@ -22,8 +22,12 @@ public static Optional parse(String value) { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if ((o == null) || (getClass() != o.getClass())) { + return false; + } ArXivIdentifier that = (ArXivIdentifier) o; @@ -45,6 +49,11 @@ public String getNormalized() { return identifier; } + @Override + public String toString() { + return "ArXivIdentifier [identifier=" + identifier + "]"; + } + @Override public Optional getExternalURI() { try { diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index b4a3116d47f..a6b4b65d800 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -34,8 +34,6 @@ import java.util.prefs.Preferences; import java.util.stream.Collectors; -import javax.swing.UIManager; - import org.jabref.Globals; import org.jabref.JabRefException; import org.jabref.JabRefMain; @@ -115,7 +113,6 @@ public class JabRefPreferences implements PreferencesService { public static final String LYXPIPE = "lyxpipe"; public static final String EXTERNAL_FILE_TYPES = "externalFileTypes"; public static final String FONT_FAMILY = "fontFamily"; - public static final String WIN_LOOK_AND_FEEL = "lookAndFeel"; public static final String FX_FONT_RENDERING_TWEAK = "fxFontRenderingTweak"; public static final String LANGUAGE = "language"; public static final String NAMES_LAST_ONLY = "namesLastOnly"; @@ -217,6 +214,8 @@ public class JabRefPreferences implements PreferencesService { public static final String ICON_ENABLED_COLOR = "iconEnabledColor"; public static final String ICON_DISABLED_COLOR = "iconDisabledColor"; public static final String FONT_SIZE = "fontSize"; + public static final String OVERRIDE_DEFAULT_FONT_SIZE = "overrideDefaultFontSize"; + public static final String MAIN_FONT_SIZE = "mainFontSize"; public static final String FONT_STYLE = "fontStyle"; public static final String RECENT_DATABASES = "recentDatabases"; public static final String RENAME_ON_MOVE_FILE_TO_FILE_DIR = "renameOnMoveFileToFileDir"; @@ -459,15 +458,12 @@ private JabRefPreferences() { if (OS.OS_X) { defaults.put(FONT_FAMILY, "SansSerif"); - defaults.put(WIN_LOOK_AND_FEEL, UIManager.getSystemLookAndFeelClassName()); defaults.put(EMACS_PATH, "emacsclient"); } else if (OS.WINDOWS) { - defaults.put(WIN_LOOK_AND_FEEL, "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); defaults.put(EMACS_PATH, "emacsclient.exe"); } else { // Linux defaults.put(FONT_FAMILY, "SansSerif"); - defaults.put(WIN_LOOK_AND_FEEL, "javax.swing.plaf.nimbus.NimbusLookAndFeel"); defaults.put(EMACS_PATH, "emacsclient"); } @@ -688,6 +684,9 @@ private JabRefPreferences() { defaults.put(LAST_USED_EXPORT, ""); defaults.put(SIDE_PANE_WIDTH, 0.15); + defaults.put(MAIN_FONT_SIZE, 9); + defaults.put(OVERRIDE_DEFAULT_FONT_SIZE, false); + defaults.put(IMPORT_INSPECTION_DIALOG_WIDTH, 650); defaults.put(IMPORT_INSPECTION_DIALOG_HEIGHT, 650); defaults.put(SHOW_FILE_LINKS_UPGRADE_WARNING, Boolean.TRUE); @@ -703,8 +702,8 @@ private JabRefPreferences() { defaults.put(EMAIL_SUBJECT, Localization.lang("References")); defaults.put(OPEN_FOLDERS_OF_ATTACHED_FILES, Boolean.FALSE); defaults.put(ALLOW_FILE_AUTO_OPEN_BROWSE, Boolean.TRUE); - defaults.put(WEB_SEARCH_VISIBLE, Boolean.FALSE); - defaults.put(GROUP_SIDEPANE_VISIBLE, Boolean.FALSE); + defaults.put(WEB_SEARCH_VISIBLE, Boolean.TRUE); + defaults.put(GROUP_SIDEPANE_VISIBLE, Boolean.TRUE); defaults.put(SELECTED_FETCHER_INDEX, 0); defaults.put(BIB_LOC_AS_PRIMARY_DIR, Boolean.FALSE); defaults.put(DB_CONNECT_SERVER_TYPE, "MySQL"); @@ -1036,6 +1035,10 @@ public void putInt(String key, int value) { prefs.putInt(key, value); } + public void putInt(String key, Number value) { + prefs.putInt(key, value.intValue()); + } + public void putDouble(String key, double value) { prefs.putDouble(key, value); } @@ -1894,14 +1897,6 @@ public void setGroupViewMode(GroupViewMode mode) { put(GROUP_INTERSECT_UNION_VIEW_MODE, mode.name()); } - public String getLookAndFeel() { - return get(WIN_LOOK_AND_FEEL); - } - - public void setLookAndFeel(String lookAndFeelClassName) { - put(WIN_LOOK_AND_FEEL, lookAndFeelClassName); - } - public void setPreviewStyle(String previewStyle) { put(PREVIEW_STYLE, previewStyle); } @@ -1910,4 +1905,11 @@ public String getPreviewStyle() { return get(PREVIEW_STYLE); } + public Optional getFontSize() { + if (getBoolean(OVERRIDE_DEFAULT_FONT_SIZE)) { + return Optional.of(getInt(MAIN_FONT_SIZE)); + } else { + return Optional.empty(); + } + } } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index f6e11f2fa8e..d2de9afd87d 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -416,8 +416,6 @@ External\ programs=External programs External\ viewer\ called=External viewer called -Fetch=Fetch - Field=Field field=field @@ -568,7 +566,6 @@ Importing=Importing Importing\ in\ unknown\ format=Importing in unknown format -Include\ abstracts=Include abstracts Include\ entries=Include entries Include\ subgroups\:\ When\ selected,\ view\ entries\ contained\ in\ this\ group\ or\ its\ subgroups=Include subgroups: When selected, view entries contained in this group or its subgroups @@ -710,9 +707,6 @@ no\ library\ generated=no library generated No\ entries\ found.\ Please\ make\ sure\ you\ are\ using\ the\ correct\ import\ filter.=No entries found. Please make sure you are using the correct import filter. - -No\ entries\ found\ for\ the\ search\ string\ '%0'=No entries found for the search string '%0' - No\ entries\ imported.=No entries imported. No\ files\ found.=No files found. @@ -1176,7 +1170,6 @@ XMP-metadata=XMP-metadata XMP-metadata\ found\ in\ PDF\:\ %0=XMP-metadata found in PDF: %0 You\ must\ restart\ JabRef\ for\ this\ to\ come\ into\ effect.=You must restart JabRef for this to come into effect. You\ have\ changed\ the\ language\ setting.=You have changed the language setting. -You\ have\ entered\ an\ invalid\ search\ '%0'.=You have entered an invalid search '%0'. You\ must\ restart\ JabRef\ for\ the\ new\ key\ bindings\ to\ work\ properly.=You must restart JabRef for the new key bindings to work properly. @@ -1185,23 +1178,22 @@ Your\ new\ key\ bindings\ have\ been\ stored.=Your new key bindings have been st The\ following\ fetchers\ are\ available\:=The following fetchers are available: Could\ not\ find\ fetcher\ '%0'=Could not find fetcher '%0' Running\ query\ '%0'\ with\ fetcher\ '%1'.=Running query '%0' with fetcher '%1'. -Query\ '%0'\ with\ fetcher\ '%1'\ did\ not\ return\ any\ results.=Query '%0' with fetcher '%1' did not return any results. Move\ file=Move file Rename\ file=Rename file +Move\ file\ to\ file\ directory\ and\ rename\ file=Move file to file directory and rename file + Move\ file\ failed=Move file failed Could\ not\ move\ file\ '%0'.=Could not move file '%0'. Could\ not\ find\ file\ '%0'.=Could not find file '%0'. Number\ of\ entries\ successfully\ imported=Number of entries successfully imported Import\ canceled\ by\ user=Import canceled by user -Progress\:\ %0\ of\ %1=Progress: %0 of %1 Error\ while\ fetching\ from\ %0=Error while fetching from %0 Show\ search\ results\ in\ a\ window=Show search results in a window Show\ global\ search\ results\ in\ a\ window=Show global search results in a window Search\ in\ all\ open\ libraries=Search in all open libraries -Move\ file\ to\ file\ directory?=Move file to file directory? Library\ is\ protected.\ Cannot\ save\ until\ external\ changes\ have\ been\ reviewed.=Library is protected. Cannot save until external changes have been reviewed. Protected\ library=Protected library @@ -1488,7 +1480,6 @@ Toggle\ print\ status=Toggle print status Update\ keywords=Update keywords Write\ values\ of\ special\ fields\ as\ separate\ fields\ to\ BibTeX=Write values of special fields as separate fields to BibTeX You\ have\ changed\ settings\ for\ special\ fields.=You have changed settings for special fields. -%0\ entries\ found.\ To\ reduce\ server\ load,\ only\ %1\ will\ be\ downloaded.=%0 entries found. To reduce server load, only %1 will be downloaded. A\ string\ with\ that\ label\ already\ exists=A string with that label already exists Connection\ to\ OpenOffice/LibreOffice\ has\ been\ lost.\ Please\ make\ sure\ OpenOffice/LibreOffice\ is\ running,\ and\ try\ to\ reconnect.=Connection to OpenOffice/LibreOffice has been lost. Please make sure OpenOffice/LibreOffice is running, and try to reconnect. JabRef\ will\ send\ at\ least\ one\ request\ per\ entry\ to\ a\ publisher.=JabRef will send at least one request per entry to a publisher. @@ -2257,3 +2248,5 @@ View\ change\ log=View change log View\ event\ log=View event log Website=Website Write\ XMP-metadata\ to\ PDFs=Write XMP-metadata to PDFs +Font\ size\:=Font size\: +Override\ default\ font\ settings=Override default font settings diff --git a/src/main/resources/l10n/JabRef_zh.properties b/src/main/resources/l10n/JabRef_zh.properties index 9d3de79901d..0cefa1dd0a5 100644 --- a/src/main/resources/l10n/JabRef_zh.properties +++ b/src/main/resources/l10n/JabRef_zh.properties @@ -196,7 +196,7 @@ Copied\ keys=已复制 BibTeX 键 Copy=复制 Copy\ BibTeX\ key=复制 BibTeX 键 -Copy\ file\ to\ file\ directory=拷贝文件到文件目录。 +Copy\ file\ to\ file\ directory=拷贝文件到文件目录 Copy\ to\ clipboard=复制到剪贴板 @@ -1181,8 +1181,10 @@ Could\ not\ find\ fetcher\ '%0'=无法找到抓取器 '%0' Running\ query\ '%0'\ with\ fetcher\ '%1'.=使用抓取器'%1'执行请求'%0' Query\ '%0'\ with\ fetcher\ '%1'\ did\ not\ return\ any\ results.=使用抓取器'%1'请求'%0'未返回任何结果。 -Move\ file=移动 文件 -Rename\ file=重命名 文件 +Move\ file=移动文件 +Rename\ file=重命名文件 + +Move\ file\ to\ file\ directory\ and\ rename\ file=移动文件到文件目录重命名文件 Move\ file\ failed=移动文件失败 Could\ not\ move\ file\ '%0'.=无法移动文件 '%0' @@ -1262,7 +1264,7 @@ Enforce\ legal\ characters\ in\ BibTeX\ keys=强制在 BibTeX 键值中使用合 Save\ without\ backup?=保存但不备份? Unable\ to\ create\ backup=无法创建备份 -Move\ file\ to\ file\ directory=移动文件到文件目录。 +Move\ file\ to\ file\ directory=移动文件到文件目录 Rename\ file\ to=将文件更名为 All\ Entries\ (this\ group\ cannot\ be\ edited\ or\ removed)=所有记录(此分组无法被编辑或者删除) static\ group=静态分组 diff --git a/src/test/java/org/jabref/gui/fieldeditors/LinkedFileViewModelTest.java b/src/test/java/org/jabref/gui/fieldeditors/LinkedFileViewModelTest.java index 87d0b9e8d33..52fa4d54c32 100644 --- a/src/test/java/org/jabref/gui/fieldeditors/LinkedFileViewModelTest.java +++ b/src/test/java/org/jabref/gui/fieldeditors/LinkedFileViewModelTest.java @@ -15,10 +15,10 @@ import org.jabref.model.metadata.FileDirectoryPreferences; import org.jabref.preferences.JabRefPreferences; -import org.junit$pioneer.jupiter.TempDirectory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junitpioneer.jupiter.TempDirectory; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/org/jabref/gui/journals/ManageJournalAbbreviationsViewModelTest.java b/src/test/java/org/jabref/gui/journals/ManageJournalAbbreviationsViewModelTest.java index 08a1c212fff..5c47dec695e 100644 --- a/src/test/java/org/jabref/gui/journals/ManageJournalAbbreviationsViewModelTest.java +++ b/src/test/java/org/jabref/gui/journals/ManageJournalAbbreviationsViewModelTest.java @@ -21,10 +21,10 @@ import org.jabref.logic.journals.JournalAbbreviationPreferences; import org.jabref.preferences.PreferencesService; -import org.junit$pioneer.jupiter.TempDirectory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junitpioneer.jupiter.TempDirectory; import static org.jabref.logic.util.OS.NEWLINE; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/jabref/logic/importer/fetcher/ACMPortalFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/ACMPortalFetcherTest.java index 4bd9848ab4d..df85c30857f 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/ACMPortalFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/ACMPortalFetcherTest.java @@ -7,6 +7,7 @@ import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibtexEntryTypes; +import org.jabref.testutils.category.FetcherTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -15,6 +16,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +@FetcherTest class ACMPortalFetcherTest { ACMPortalFetcher fetcher; diff --git a/src/test/java/org/jabref/logic/importer/fetcher/ACSTest.java b/src/test/java/org/jabref/logic/importer/fetcher/ACSTest.java index 01d1f31bb77..c11b94cb2bb 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/ACSTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/ACSTest.java @@ -31,7 +31,7 @@ void findByDOI() throws IOException { entry.setField("doi", "10.1021/bk-2006-STYG.ch014"); assertEquals( - Optional.of(new URL("http://pubs.acs.org/doi/pdf/10.1021/bk-2006-STYG.ch014")), + Optional.of(new URL("https://pubs.acs.org/doi/pdf/10.1021/bk-2006-STYG.ch014")), finder.findFullText(entry) ); } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java b/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java index 3a438659b31..4c3fd88b745 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/ArXivTest.java @@ -191,5 +191,8 @@ public void searchIdentifierForSlicePaper() throws Exception { assertEquals(ArXivIdentifier.parse("1405.2249v1"), finder.findIdentifier(sliceTheoremPaper)); } - + @Test + public void searchEmptyId() throws Exception { + assertEquals(Optional.empty(), finder.performSearchById("")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystemTest.java b/src/test/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystemTest.java index 5afe8a6c208..2aedc5c0473 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystemTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/AstrophysicsDataSystemTest.java @@ -136,7 +136,7 @@ public void setUp() throws Exception { @Test public void testHelpPage() { - assertEquals("ADS", fetcher.getHelpPage().getPageName()); + assertEquals("ADS", fetcher.getHelpPage().get().getPageName()); } @Test @@ -176,8 +176,7 @@ public void testPerformSearchByIdEmptyDOI() throws Exception { @Test public void testPerformSearchByIdInvalidDoi() throws Exception { - Optional fetchedEntry = fetcher.performSearchById("this.doi.will.fail"); - assertEquals(Optional.empty(), fetchedEntry); + assertEquals(Optional.empty(), fetcher.performSearchById("this.doi.will.fail")); } @Test diff --git a/src/test/java/org/jabref/logic/importer/fetcher/CiteSeerTest.java b/src/test/java/org/jabref/logic/importer/fetcher/CiteSeerTest.java new file mode 100644 index 00000000000..5460e4d3abb --- /dev/null +++ b/src/test/java/org/jabref/logic/importer/fetcher/CiteSeerTest.java @@ -0,0 +1,50 @@ +package org.jabref.logic.importer.fetcher; + +import java.util.Collections; +import java.util.List; + +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibtexEntryTypes; +import org.jabref.testutils.category.FetcherTest; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@FetcherTest +class CiteSeerTest { + + CiteSeer fetcher; + + @BeforeEach + void setUp() throws Exception { + fetcher = new CiteSeer(); + } + + @Test + void searchByQueryFindsEntry() throws Exception { + BibEntry expected = new BibEntry(); + expected.setType(BibtexEntryTypes.MISC); + expected.setField("author", "Wang Wei and Zhang Pingwen and Zhang Zhifei"); + expected.setField("title", "Rigorous Derivation from Landau-de Gennes Theory to Eericksen-leslie Theory"); + expected.setField("doi", "10.1.1.744.5780"); + + List fetchedEntries = fetcher.performSearch("title:Ericksen-Leslie AND venue:q AND ncites:[10 TO 15000]"); + assertEquals(Collections.singletonList(expected), fetchedEntries); + } + + @Test + void searchByQueryFindsEntry2() throws Exception { + BibEntry expected = new BibEntry(); + expected.setType(BibtexEntryTypes.MISC); + expected.setField("author", "Lazarus Richard S."); + expected.setField("title", "Coping Theory and Research: Past Present and Future"); + expected.setField("doi", "10.1.1.115.9665"); + expected.setField("year", "1993"); + expected.setField("journaltitle", "PSYCHOSOMATIC MEDICINE"); + + List fetchedEntries = fetcher.performSearch("JabRef"); + assertEquals(expected, fetchedEntries.get(4)); + } +} diff --git a/src/test/java/org/jabref/logic/importer/fetcher/CrossRefTest.java b/src/test/java/org/jabref/logic/importer/fetcher/CrossRefTest.java index cb98379e242..6c9406e6e71 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/CrossRefTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/CrossRefTest.java @@ -1,9 +1,11 @@ package org.jabref.logic.importer.fetcher; +import java.util.Collections; import java.util.Locale; import java.util.Optional; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibtexEntryTypes; import org.jabref.testutils.category.FetcherTest; import org.junit.jupiter.api.BeforeEach; @@ -115,7 +117,7 @@ public void findByEntry() throws Exception { @Test public void performSearchByIdFindsPaperWithoutTitle() throws Exception { - BibEntry entry = new BibEntry("article"); + BibEntry entry = new BibEntry(BibtexEntryTypes.ARTICLE); entry.setField("author", "Dominik Wujastyk"); entry.setField("doi", "10.1023/a:1003473214310"); entry.setField("issn", "0019-7246"); @@ -125,4 +127,14 @@ public void performSearchByIdFindsPaperWithoutTitle() throws Exception { assertEquals(Optional.of(entry), fetcher.performSearchById("10.1023/a:1003473214310")); } + + @Test + public void performSearchByEmptyId() throws Exception { + assertEquals(Optional.empty(), fetcher.performSearchById("")); + } + + @Test + public void performSearchByEmptyQuery() throws Exception { + assertEquals(Collections.emptyList(), fetcher.performSearch("")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/DBLPFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/DBLPFetcherTest.java index 1bbdb7eb249..51e1ba7ad97 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/DBLPFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/DBLPFetcherTest.java @@ -28,21 +28,21 @@ public class DBLPFetcherTest { public void setUp() { ImportFormatPreferences importFormatPreferences = mock(ImportFormatPreferences.class); when(importFormatPreferences.getFieldContentParserPreferences()) - .thenReturn(mock(FieldContentParserPreferences.class)); + .thenReturn(mock(FieldContentParserPreferences.class)); dblpFetcher = new DBLPFetcher(importFormatPreferences); entry = new BibEntry(); entry.setType(BibtexEntryTypes.ARTICLE.getName()); entry.setCiteKey("DBLP:journals/stt/GeigerHL16"); entry.setField(FieldName.TITLE, - "Process Engine Benchmarking with Betsy in the Context of {ISO/IEC} Quality Standards"); + "Process Engine Benchmarking with Betsy in the Context of {ISO/IEC} Quality Standards"); entry.setField(FieldName.AUTHOR, "Matthias Geiger and Simon Harrer and J{\\\"{o}}rg Lenhard"); entry.setField(FieldName.JOURNAL, "Softwaretechnik-Trends"); entry.setField(FieldName.VOLUME, "36"); entry.setField(FieldName.NUMBER, "2"); entry.setField(FieldName.YEAR, "2016"); entry.setField(FieldName.URL, - "http://pi.informatik.uni-siegen.de/stt/36_2/./03_Technische_Beitraege/ZEUS2016/beitrag_2.pdf"); + "http://pi.informatik.uni-siegen.de/stt/36_2/./03_Technische_Beitraege/ZEUS2016/beitrag_2.pdf"); entry.setField("biburl", "https://dblp.org/rec/bib/journals/stt/GeigerHL16"); entry.setField("bibsource", "dblp computer science bibliography, https://dblp.org"); @@ -64,4 +64,9 @@ public void findSingleEntryUsingComplexOperators() throws FetcherException { assertEquals(Collections.singletonList(entry), result); } + @Test + public void findNothing() throws Exception { + assertEquals(Collections.emptyList(), dblpFetcher.performSearch("")); + } + } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/DOAJFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/DOAJFetcherTest.java index e9c06a4a0e8..77a0a20b925 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/DOAJFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/DOAJFetcherTest.java @@ -2,12 +2,14 @@ import java.util.Collections; import java.util.List; +import java.util.Optional; import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibtexEntryTypes; import org.jabref.testutils.category.FetcherTest; +import org.json.JSONObject; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -29,7 +31,7 @@ void setUp() { @Test void searchByQueryFindsEntry() throws Exception { - BibEntry expected = new BibEntry(BibtexEntryTypes.ARTICLE.getName()); + BibEntry expected = new BibEntry(BibtexEntryTypes.ARTICLE); expected.setField("author", "Wei Wang and Yun He and Tong Li and Jiajun Zhu and Jinzhuo Liu"); expected.setField("doi", "10.1155/2018/5913634"); expected.setField("issn", "1875-919X"); @@ -44,4 +46,31 @@ void searchByQueryFindsEntry() throws Exception { List fetchedEntries = fetcher.performSearch("JabRef impact"); assertEquals(Collections.singletonList(expected), fetchedEntries); } + + @Test + void testBibJSONConverter() { + String jsonString = "{\n\"title\": \"Design of Finite Word Length Linear-Phase FIR Filters in the Logarithmic Number System Domain\",\n" + + "\"journal\": {\n\"publisher\": \"Hindawi Publishing Corporation\",\n\"language\": [" + + "\"English\"],\n\"title\": \"VLSI Design\",\"country\": \"US\",\"volume\": \"2014\"" + + "},\"author\":[{\"name\": \"Syed Asad Alam\"},{\"name\": \"Oscar Gustafsson\"" + + "}\n],\n\"link\":[{\"url\": \"http://dx.doi.org/10.1155/2014/217495\"," + + "\"type\": \"fulltext\"}],\"year\":\"2014\",\"identifier\":[{" + + "\"type\": \"pissn\",\"id\": \"1065-514X\"},\n{\"type\": \"eissn\"," + + "\"id\": \"1563-5171\"},{\"type\": \"doi\",\"id\": \"10.1155/2014/217495\"" + + "}],\"created_date\":\"2014-05-09T19:38:31Z\"}\""; + JSONObject jsonObject = new JSONObject(jsonString); + BibEntry bibEntry = DOAJFetcher.parseBibJSONtoBibtex(jsonObject, ','); + + assertEquals("article", bibEntry.getType()); + assertEquals(Optional.of("VLSI Design"), bibEntry.getField("journal")); + assertEquals(Optional.of("10.1155/2014/217495"), bibEntry.getField("doi")); + assertEquals(Optional.of("Syed Asad Alam and Oscar Gustafsson"), bibEntry.getField("author")); + assertEquals(Optional.of("Design of Finite Word Length Linear-Phase FIR Filters in the Logarithmic Number System Domain"), bibEntry.getField("title")); + assertEquals(Optional.of("2014"), bibEntry.getField("year")); + } + + @Test + public void searchByEmptyQuery() throws Exception { + assertEquals(Collections.emptyList(), fetcher.performSearch("")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/DiVATest.java b/src/test/java/org/jabref/logic/importer/fetcher/DiVATest.java index 9b7b6d2d86e..fa76e65b9b4 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/DiVATest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/DiVATest.java @@ -44,7 +44,7 @@ public void testPerformSearchById() throws Exception { entry.setField("institution", "Linköping University, The Institute of Technology"); entry.setCiteKey("Gustafsson260746"); entry.setField("journal", - "IEEE transactions on circuits and systems. 2, Analog and digital signal processing (Print)"); + "IEEE transactions on circuits and systems. 2, Analog and digital signal processing (Print)"); entry.setField("number", "11"); entry.setField("pages", "974--978"); entry.setField("title", "Lower bounds for constant multiplication problems"); @@ -65,4 +65,9 @@ public void testValidIdentifier() { public void testInvalidIdentifier() { assertFalse(fetcher.isValidId("banana")); } + + @Test + public void testEmptyId() throws Exception { + assertEquals(Optional.empty(), fetcher.performSearchById("")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/DoiFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/DoiFetcherTest.java index 177d48b7123..d6411540e39 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/DoiFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/DoiFetcherTest.java @@ -56,7 +56,7 @@ public void testGetName() { @Test public void testGetHelpPage() { - assertEquals("DOItoBibTeX", fetcher.getHelpPage().getPageName()); + assertEquals("DOItoBibTeX", fetcher.getHelpPage().get().getPageName()); } @Test diff --git a/src/test/java/org/jabref/logic/importer/fetcher/GvkFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/GvkFetcherTest.java index 7701d92504d..fc8f1c7e12d 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/GvkFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/GvkFetcherTest.java @@ -63,7 +63,7 @@ public void testGetName() { @Test public void testGetHelpPage() { - assertEquals("GVK", fetcher.getHelpPage().getPageName()); + assertEquals("GVK", fetcher.getHelpPage().get().getPageName()); } @Test diff --git a/src/test/java/org/jabref/logic/importer/fetcher/GvkParserTest.java b/src/test/java/org/jabref/logic/importer/fetcher/GvkParserTest.java index 443b46be140..5e650d3378b 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/GvkParserTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/GvkParserTest.java @@ -9,13 +9,14 @@ import org.jabref.logic.bibtex.BibEntryAssert; import org.jabref.logic.importer.fileformat.GvkParser; import org.jabref.model.entry.BibEntry; +import org.jabref.testutils.category.FetcherTest; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; - +@FetcherTest public class GvkParserTest { private void doTest(String xmlName, int expectedSize, List resourceNames) throws Exception { diff --git a/src/test/java/org/jabref/logic/importer/fetcher/IEEETest.java b/src/test/java/org/jabref/logic/importer/fetcher/IEEETest.java index 33698085eb1..775218df1e1 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/IEEETest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/IEEETest.java @@ -2,9 +2,13 @@ import java.io.IOException; import java.net.URL; +import java.util.Collections; +import java.util.List; import java.util.Optional; +import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibtexEntryTypes; import org.jabref.support.DisabledOnCIServer; import org.jabref.testutils.category.FetcherTest; @@ -12,16 +16,21 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @FetcherTest class IEEETest { - private IEEE finder; + private IEEE fetcher; private BibEntry entry; @BeforeEach void setUp() { - finder = new IEEE(); + ImportFormatPreferences importFormatPreferences = mock(ImportFormatPreferences.class); + when(importFormatPreferences.getKeywordSeparator()).thenReturn(','); + fetcher = new IEEE(importFormatPreferences); + entry = new BibEntry(); } @@ -32,7 +41,7 @@ void findByDOI() throws IOException { assertEquals( Optional.of( new URL("https://ieeexplore.ieee.org/ielx7/6287639/7419931/07421926.pdf?tp=&arnumber=7421926&isnumber=7419931")), - finder.findFullText(entry)); + fetcher.findFullText(entry)); } @Test @@ -41,7 +50,7 @@ void findByDocumentUrl() throws IOException { assertEquals( Optional.of( new URL("https://ieeexplore.ieee.org/ielx7/6287639/7419931/07421926.pdf?tp=&arnumber=7421926&isnumber=7419931")), - finder.findFullText(entry)); + fetcher.findFullText(entry)); } @Test @@ -51,7 +60,7 @@ void findByURL() throws IOException { assertEquals( Optional.of( new URL("https://ieeexplore.ieee.org/ielx7/6287639/7419931/07421926.pdf?tp=&arnumber=7421926&isnumber=7419931")), - finder.findFullText(entry)); + fetcher.findFullText(entry)); } @Test @@ -61,7 +70,7 @@ void findByOldURL() throws IOException { assertEquals( Optional.of( new URL("https://ieeexplore.ieee.org/ielx7/6287639/7419931/07421926.pdf?tp=&arnumber=7421926&isnumber=7419931")), - finder.findFullText(entry)); + fetcher.findFullText(entry)); } @Test @@ -72,7 +81,7 @@ void findByDOIButNotURL() throws IOException { assertEquals( Optional.of( new URL("https://ieeexplore.ieee.org/ielx7/6287639/7419931/07421926.pdf?tp=&arnumber=7421926&isnumber=7419931")), - finder.findFullText(entry)); + fetcher.findFullText(entry)); } @Test @@ -80,13 +89,33 @@ void findByDOIButNotURL() throws IOException { void notFoundByURL() throws IOException { entry.setField("url", "http://dx.doi.org/10.1109/ACCESS.2016.2535486"); - assertEquals(Optional.empty(), finder.findFullText(entry)); + assertEquals(Optional.empty(), fetcher.findFullText(entry)); } @Test void notFoundByDOI() throws IOException { entry.setField("doi", "10.1021/bk-2006-WWW.ch014"); - assertEquals(Optional.empty(), finder.findFullText(entry)); + assertEquals(Optional.empty(), fetcher.findFullText(entry)); + } + + @Test + void searchByQueryFindsEntry() throws Exception { + BibEntry expected = new BibEntry(BibtexEntryTypes.INPROCEEDINGS); + expected.setField("author", "Igor Steinmacher and Tayana Uchoa Conte and Christoph Treude and Marco Aurélio Gerosa"); + expected.setField("eventdate", "14-22 May 2016"); + expected.setField("eventtitleaddon", "Austin, TX"); + expected.setField("location", "Austin, TX"); + expected.setField("doi", "10.1145/2884781.2884806"); + expected.setField("isbn", "New-2005_Electronic_978-1-4503-3900-1"); + expected.setField("journaltitle", "2016 IEEE/ACM 38th International Conference on Software Engineering (ICSE)"); + expected.setField("pages", "273--284"); + expected.setField("publisher", "IEEE"); + expected.setField("keywords", "Computer bugs, Documentation, Industries, Joining processes, Open source software, Portals, Barriers, Beginners, Joining Process, Newbies, Newcomers, Novices, Obstacles, Onboarding, Open Source Software"); + expected.setField("title", "Overcoming Open Source Project Entry Barriers with a Portal for Newcomers"); + expected.setField("file", ":https\\://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=7886910:PDF"); + expected.setField("abstract", "Community-based Open Source Software (OSS) projects are usually self-organized and dynamic, receiving contributions from distributed volunteers. Newcomer are important to the survival, long-term success, and continuity of these communities. However, newcomers face many barriers when making their first contribution to an OSS project, leading in many cases to dropouts. Therefore, a major challenge for OSS projects is to provide ways to support newcomers during their first contribution. In this paper, we propose and evaluate FLOSScoach, a portal created to support newcomers to OSS projects. FLOSScoach was designed based on a conceptual model of barriers created in our previous work. To evaluate the portal, we conducted a study with 65 students, relying on qualitative data from diaries, self-efficacy questionnaires, and the Technology Acceptance Model. The results indicate that FLOSScoach played an important role in guiding newcomers and in lowering barriers related to the orientation and contribution process, whereas it was not effective in lowering technical barriers. We also found that FLOSScoach is useful, easy to use, and increased newcomers' confidence to contribute. Our results can help project maintainers on deciding the points that need more attention in order to help OSS project newcomers overcome entry barriers."); + List fetchedEntries = fetcher.performSearch("JabRef Social Barriers Steinmacher Redmiles Austin"); + assertEquals(Collections.singletonList(expected), fetchedEntries); } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/INSPIREFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/INSPIREFetcherTest.java index 5f436313d5a..d919f96ce1d 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/INSPIREFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/INSPIREFetcherTest.java @@ -7,6 +7,7 @@ import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibtexEntryTypes; +import org.jabref.testutils.category.FetcherTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -15,6 +16,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +@FetcherTest class INSPIREFetcherTest { private INSPIREFetcher fetcher; diff --git a/src/test/java/org/jabref/logic/importer/fetcher/IsbnFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/IsbnFetcherTest.java index 6567c692f96..a8a6f0fd40a 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/IsbnFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/IsbnFetcherTest.java @@ -48,7 +48,7 @@ public void testName() { @Test public void testHelpPage() { - assertEquals("ISBNtoBibTeX", fetcher.getHelpPage().getPageName()); + assertEquals("ISBNtoBibTeX", fetcher.getHelpPage().get().getPageName()); } @Test diff --git a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaChimboriFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaChimboriFetcherTest.java index 658099683a7..7371043febc 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaChimboriFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaChimboriFetcherTest.java @@ -30,7 +30,7 @@ public void setUp() { bibEntry.setField("author", "Joshua Bloch"); bibEntry.setField("isbn", "978-0321356680"); bibEntry.setField("url", - "https://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683?SubscriptionId=0JYN1NVW651KCA56C102&tag=techkie-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=0321356683"); + "https://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683?SubscriptionId=AKIAIOBINVZYXZQZ2U3A&tag=chimbori05-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=0321356683"); fetcher = new IsbnViaChimboriFetcher(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS)); } @@ -44,7 +44,7 @@ public void testName() { @Test @Override public void testHelpPage() { - assertEquals("ISBNtoBibTeX", fetcher.getHelpPage().getPageName()); + assertEquals("ISBNtoBibTeX", fetcher.getHelpPage().get().getPageName()); } @Test @@ -77,7 +77,7 @@ public void authorsAreCorrectlyFormatted() throws Exception { bibEntry.setField("author", "Marlon Dumas and Marcello La Rosa and Jan Mendling and Hajo A. Reijers"); bibEntry.setField("isbn", "3642434738"); bibEntry.setField("url", - "https://www.amazon.com/Fundamentals-Business-Process-Management-Marlon/dp/3642434738?SubscriptionId=0JYN1NVW651KCA56C102&tag=techkie-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=3642434738"); + "https://www.amazon.com/Fundamentals-Business-Process-Management-Marlon/dp/3642434738?SubscriptionId=AKIAIOBINVZYXZQZ2U3A&tag=chimbori05-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=3642434738"); Optional fetchedEntry = fetcher.performSearchById("3642434738"); assertEquals(Optional.of(bibEntry), fetchedEntry); diff --git a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java index cd88c970e6b..a20318709b1 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/IsbnViaEbookDeFetcherTest.java @@ -44,7 +44,7 @@ public void testName() { @Test @Override public void testHelpPage() { - assertEquals("ISBNtoBibTeX", fetcher.getHelpPage().getPageName()); + assertEquals("ISBNtoBibTeX", fetcher.getHelpPage().get().getPageName()); } @Test @@ -66,18 +66,16 @@ public void searchByIdSuccessfulWithLongISBN() throws FetcherException { public void authorsAreCorrectlyFormatted() throws Exception { BibEntry bibEntry = new BibEntry(); bibEntry.setType(BiblatexEntryTypes.BOOK); - bibEntry.setField("bibtexkey", "9783642434730"); + bibEntry.setField("bibtexkey", "9783662565094"); bibEntry.setField("title", "Fundamentals of Business Process Management"); bibEntry.setField("publisher", "Springer Berlin Heidelberg"); - bibEntry.setField("year", "2015"); + bibEntry.setField("year", "2018"); bibEntry.setField("author", "Dumas, Marlon and Rosa, Marcello La and Mendling, Jan and Reijers, Hajo A."); - bibEntry.setField("date", "2015-04-12"); - bibEntry.setField("ean", "9783642434730"); - bibEntry.setField("isbn", "3642434738"); - bibEntry.setField("pagetotal", "428"); - bibEntry.setField("url", "https://www.ebook.de/de/product/23955263/marlon_dumas_marcello_la_rosa_jan_mendling_hajo_a_reijers_fundamentals_of_business_process_management.html"); + bibEntry.setField("date", "2018-03-23"); + bibEntry.setField("ean", "9783662565094"); + bibEntry.setField("url", "https://www.ebook.de/de/product/33399253/marlon_dumas_marcello_la_rosa_jan_mendling_hajo_a_reijers_fundamentals_of_business_process_management.html"); - Optional fetchedEntry = fetcher.performSearchById("3642434738"); + Optional fetchedEntry = fetcher.performSearchById("978-3-662-56509-4"); assertEquals(Optional.of(bibEntry), fetchedEntry); } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/LibraryOfCongressTest.java b/src/test/java/org/jabref/logic/importer/fetcher/LibraryOfCongressTest.java index 59f23a88b72..837e7607f6c 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/LibraryOfCongressTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/LibraryOfCongressTest.java @@ -6,16 +6,24 @@ import org.jabref.model.entry.BibEntry; import org.jabref.testutils.category.FetcherTest; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.Answers; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @FetcherTest public class LibraryOfCongressTest { - private final LibraryOfCongress fetcher = new LibraryOfCongress(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS)); + private LibraryOfCongress fetcher; + + @BeforeEach + public void setUp() { + ImportFormatPreferences prefs = mock(ImportFormatPreferences.class); + when(prefs.getKeywordSeparator()).thenReturn(','); + fetcher = new LibraryOfCongress(prefs); + } @Test public void performSearchById() throws Exception { @@ -24,7 +32,7 @@ public void performSearchById() throws Exception { expected.setField("author", "West, Matthew"); expected.setField("isbn", "0123751063 (pbk.)"); expected.setField("issuance", "monographic"); - expected.setField("keywords", "Database design Data structures (Computer science)"); + expected.setField("keywords", "Database design, Data structures (Computer science)"); expected.setField("language", "eng"); expected.setField("lccn", "2010045158"); expected.setField("note", "Matthew West., Includes index."); @@ -36,4 +44,14 @@ public void performSearchById() throws Exception { assertEquals(Optional.of(expected), fetcher.performSearchById("2010045158")); } + + @Test + public void performSearchByEmptyId() throws Exception { + assertEquals(Optional.empty(), fetcher.performSearchById("")); + } + + @Test + public void performSearchByInvalidId() throws Exception { + assertEquals(Optional.empty(), fetcher.performSearchById("xxx")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java b/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java index e66d81f0948..5c2f2787854 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/MathSciNetTest.java @@ -28,7 +28,7 @@ class MathSciNetTest { void setUp() throws Exception { ImportFormatPreferences importFormatPreferences = mock(ImportFormatPreferences.class); when(importFormatPreferences.getFieldContentParserPreferences()).thenReturn( - mock(FieldContentParserPreferences.class)); + mock(FieldContentParserPreferences.class)); fetcher = new MathSciNet(importFormatPreferences); ratiuEntry = new BibEntry(); diff --git a/src/test/java/org/jabref/logic/importer/fetcher/MedlineFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/MedlineFetcherTest.java index 289aeecf698..54e7ac3944a 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/MedlineFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/MedlineFetcherTest.java @@ -128,7 +128,7 @@ public void testGetName() { @Test public void testGetHelpPage() { - assertEquals("Medline", fetcher.getHelpPage().getPageName()); + assertEquals("Medline", fetcher.getHelpPage().get().getPageName()); } @Test diff --git a/src/test/java/org/jabref/logic/importer/fetcher/OpenAccessDoiTest.java b/src/test/java/org/jabref/logic/importer/fetcher/OpenAccessDoiTest.java index 9bb675fb340..0e060cc825a 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/OpenAccessDoiTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/OpenAccessDoiTest.java @@ -28,10 +28,7 @@ void setUp() { void findByDOI() throws IOException { entry.setField("doi", "10.1038/nature12373"); - assertEquals( - Optional.of(new URL("https://dash.harvard.edu/bitstream/handle/1/12285462/Nanometer-Scale%20Thermometry.pdf?sequence=1")), - finder.findFullText(entry) - ); + assertEquals(Optional.of(new URL("https://dash.harvard.edu/bitstream/handle/1/12285462/Nanometer-Scale%20Thermometry.pdf?sequence=1")), finder.findFullText(entry)); } @Test diff --git a/src/test/java/org/jabref/logic/importer/fetcher/RfcFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/RfcFetcherTest.java index dbb02f25610..146be5a7e35 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/RfcFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/RfcFetcherTest.java @@ -1,16 +1,17 @@ package org.jabref.logic.importer.fetcher; +import java.util.Optional; + import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BiblatexEntryTypes; import org.jabref.testutils.category.FetcherTest; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Answers; -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; @FetcherTest @@ -47,7 +48,7 @@ public void getNameReturnsEqualIdName() { @Test public void getHelpPageReturnsEqualHelpPage() { - assertEquals("RFCtoBibTeX", fetcher.getHelpPage().getPageName()); + assertEquals("RFCtoBibTeX", fetcher.getHelpPage().get().getPageName()); } @Test diff --git a/src/test/java/org/jabref/logic/importer/fetcher/SpringerFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/SpringerFetcherTest.java index fe985e23761..9c250666750 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/SpringerFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/SpringerFetcherTest.java @@ -2,15 +2,19 @@ import java.util.Collections; import java.util.List; +import java.util.Optional; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibtexEntryTypes; +import org.jabref.testutils.category.FetcherTest; +import org.json.JSONObject; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +@FetcherTest class SpringerFetcherTest { SpringerFetcher fetcher; @@ -22,7 +26,7 @@ void setUp() { @Test void searchByQueryFindsEntry() throws Exception { - BibEntry expected = new BibEntry(BibtexEntryTypes.ARTICLE.getName()); + BibEntry expected = new BibEntry(BibtexEntryTypes.ARTICLE); expected.setField("author", "Steinmacher, Igor and Gerosa, Marco and Conte, Tayana U. and Redmiles, David F."); expected.setField("date", "2018-06-14"); expected.setField("doi", "10.1007/s10606-018-9335-z"); @@ -39,4 +43,32 @@ void searchByQueryFindsEntry() throws Exception { List fetchedEntries = fetcher.performSearch("JabRef Social Barriers Steinmacher"); assertEquals(Collections.singletonList(expected), fetchedEntries); } + + @Test + void testSpringerJSONToBibtex() { + String jsonString = "{\r\n" + " \"identifier\":\"doi:10.1007/BF01201962\",\r\n" + + " \"title\":\"Book reviews\",\r\n" + + " \"publicationName\":\"World Journal of Microbiology & Biotechnology\",\r\n" + + " \"issn\":\"1573-0972\",\r\n" + " \"isbn\":\"\",\r\n" + + " \"doi\":\"10.1007/BF01201962\",\r\n" + " \"publisher\":\"Springer\",\r\n" + + " \"publicationDate\":\"1992-09-01\",\r\n" + " \"volume\":\"8\",\r\n" + + " \"number\":\"5\",\r\n" + " \"startingPage\":\"550\",\r\n" + + " \"url\":\"http://dx.doi.org/10.1007/BF01201962\",\"copyright\":\"©1992 Rapid Communications of Oxford Ltd.\"\r\n" + + " }"; + + JSONObject jsonObject = new JSONObject(jsonString); + BibEntry bibEntry = SpringerFetcher.parseSpringerJSONtoBibtex(jsonObject); + assertEquals(Optional.of("1992"), bibEntry.getField("year")); + assertEquals(Optional.of("5"), bibEntry.getField("number")); + assertEquals(Optional.of("#sep#"), bibEntry.getField("month")); + assertEquals(Optional.of("10.1007/BF01201962"), bibEntry.getField("doi")); + assertEquals(Optional.of("8"), bibEntry.getField("volume")); + assertEquals(Optional.of("Springer"), bibEntry.getField("publisher")); + assertEquals(Optional.of("1992-09-01"), bibEntry.getField("date")); + } + + @Test + void searchByEmptyQueryFindsNothing() throws Exception { + assertEquals(Collections.emptyList(), fetcher.performSearch("")); + } } diff --git a/src/test/java/org/jabref/logic/importer/fetcher/TitleFetcherTest.java b/src/test/java/org/jabref/logic/importer/fetcher/TitleFetcherTest.java index d4b37535b8f..728ef5de1b9 100644 --- a/src/test/java/org/jabref/logic/importer/fetcher/TitleFetcherTest.java +++ b/src/test/java/org/jabref/logic/importer/fetcher/TitleFetcherTest.java @@ -43,7 +43,7 @@ public void testGetName() { @Test public void testGetHelpPage() { - assertEquals("TitleToBibTeX", fetcher.getHelpPage().getPageName()); + assertEquals("TitleToBibTeX", fetcher.getHelpPage().get().getPageName()); } @Test diff --git a/src/test/resources/log4j2-test.xml b/src/test/resources/log4j2-test.xml new file mode 100644 index 00000000000..0422d0bd80d --- /dev/null +++ b/src/test/resources/log4j2-test.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + From 1868304fc1f2fd24bc2228f38b62718824a0a107 Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Tue, 7 Aug 2018 13:50:01 +0800 Subject: [PATCH 02/58] convert the swing dialog to javafx --- LICENSE.md | 2 +- build.gradle | 28 +- gradle/wrapper/gradle-wrapper.jar | Bin 54413 -> 54417 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- .../cli/ImportInspectionCommandLine.java | 38 - .../BibtexKeyPatternPanel.java | 2 +- .../importer/fetcher/CiteSeerXFetcher.java | 162 ----- .../gui/importer/fetcher/EntryFetcher.java | 72 -- .../gui/importer/fetcher/EntryFetchers.java | 27 - .../gui/importer/fetcher/GeneralFetcher.java | 216 ------ .../importer/fetcher/IEEEXploreFetcher.java | 489 ------------- .../fetcher/SearchBasedEntryFetcher.java | 67 -- .../org/jabref/gui/preftabs/GeneralTab.java | 13 +- .../jabref/gui/preftabs/NameFormatterTab.java | 324 +++------ .../jabref/gui/preftabs/TableColumnsTab.java | 684 +++++++----------- .../org/jabref/gui/preftabs/XmpPrefsTab.java | 219 ++---- .../logic/importer/ImportInspector.java | 36 - .../logic/importer/util/JSONEntryParser.java | 232 ------ .../importer/util/JSONEntryParserTest.java | 65 -- src/test/resources/log4j2.xml | 13 - 20 files changed, 454 insertions(+), 2237 deletions(-) delete mode 100644 src/main/java/org/jabref/cli/ImportInspectionCommandLine.java delete mode 100644 src/main/java/org/jabref/gui/importer/fetcher/CiteSeerXFetcher.java delete mode 100644 src/main/java/org/jabref/gui/importer/fetcher/EntryFetcher.java delete mode 100644 src/main/java/org/jabref/gui/importer/fetcher/EntryFetchers.java delete mode 100644 src/main/java/org/jabref/gui/importer/fetcher/GeneralFetcher.java delete mode 100644 src/main/java/org/jabref/gui/importer/fetcher/IEEEXploreFetcher.java delete mode 100644 src/main/java/org/jabref/gui/importer/fetcher/SearchBasedEntryFetcher.java delete mode 100644 src/main/java/org/jabref/logic/importer/ImportInspector.java delete mode 100644 src/main/java/org/jabref/logic/importer/util/JSONEntryParser.java delete mode 100644 src/test/java/org/jabref/logic/importer/util/JSONEntryParserTest.java delete mode 100644 src/test/resources/log4j2.xml diff --git a/LICENSE.md b/LICENSE.md index 8ae99528256..150d62db659 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright © 2003-2016 [JabRef Authors](https://github.com/JabRef/jabref/blob/master/AUTHORS) +Copyright © 2003-2018 [JabRef Authors](https://github.com/JabRef/jabref/blob/master/AUTHORS) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/build.gradle b/build.gradle index b6344cf38dd..2daa628c683 100644 --- a/build.gradle +++ b/build.gradle @@ -15,13 +15,13 @@ buildscript { } plugins { - id 'com.gradle.build-scan' version '1.14' + id 'com.gradle.build-scan' version '1.15.1' id 'com.install4j.gradle' version '7.0.6' id 'com.github.johnrengelman.shadow' version '2.0.4' id "de.sebastianboegl.shadow.transformer.log4j" version "2.1.1" id "com.simonharrer.modernizer" version '1.6.0-1' - id 'me.champeau.gradle.jmh' version '0.4.6' - id 'net.ltgt.errorprone' version '0.0.14' + id 'me.champeau.gradle.jmh' version '0.4.7' + id 'net.ltgt.errorprone' version '0.0.15' id 'com.github.ben-manes.versions' version '0.20.0' } @@ -87,12 +87,12 @@ dependencies { compile 'com.jgoodies:jgoodies-common:1.8.1' compile 'com.jgoodies:jgoodies-forms:1.9.0' - compile 'org.apache.pdfbox:pdfbox:2.0.10' - compile 'org.apache.pdfbox:fontbox:2.0.10' - compile 'org.apache.pdfbox:xmpbox:2.0.10' + compile 'org.apache.pdfbox:pdfbox:2.0.11' + compile 'org.apache.pdfbox:fontbox:2.0.11' + compile 'org.apache.pdfbox:xmpbox:2.0.11' // required for reading write-protected PDFs - see https://github.com/JabRef/jabref/pull/942#issuecomment-209252635 - compile 'org.bouncycastle:bcprov-jdk15on:1.59' + compile 'org.bouncycastle:bcprov-jdk15on:1.60' compile 'commons-cli:commons-cli:1.4' @@ -113,7 +113,7 @@ dependencies { // VersionEye states that 6.0.5 is the most recent version, but http://dev.mysql.com/downloads/connector/j/ shows that as "Development Release" compile 'mysql:mysql-connector-java:5.1.46' - compile 'org.postgresql:postgresql:42.2.2' + compile 'org.postgresql:postgresql:42.2.4' compile 'net.java.dev.glazedlists:glazedlists_java15:1.9.1' @@ -125,7 +125,7 @@ dependencies { compile 'de.saxsys:mvvmfx:1.7.0' compile 'org.fxmisc.easybind:easybind:1.0.3' compile 'org.fxmisc.flowless:flowless:0.6.1' - compile 'org.fxmisc.richtext:richtextfx:0.9.0' + compile 'org.fxmisc.richtext:richtextfx:0.9.1' compile 'com.sibvisions.external.jvxfx:dndtabpane:0.1' compile 'javax.inject:javax.inject:1' @@ -157,20 +157,20 @@ dependencies { testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.2.0' testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.2.0' testCompile 'org.junit.platform:junit-platform-launcher:1.2.0' - testCompile 'org.junit-pioneer:junit-pioneer:0.1-SNAPSHOT' + testCompile 'org.junit-pioneer:junit-pioneer:0.1.2' testRuntime 'org.apache.logging.log4j:log4j-core:2.11.0' testRuntime 'org.apache.logging.log4j:log4j-jul:2.11.0' - testCompile 'org.mockito:mockito-core:2.19.0' + testCompile 'org.mockito:mockito-core:2.20.0' testCompile 'com.github.tomakehurst:wiremock:2.18.0' testCompile 'org.assertj:assertj-swing-junit:3.8.0' testCompile 'org.reflections:reflections:0.9.11' testCompile 'org.xmlunit:xmlunit-core:2.6.0' testCompile 'org.xmlunit:xmlunit-matchers:2.6.0' - testCompile 'com.tngtech.archunit:archunit-junit:0.8.2' + testCompile 'com.tngtech.archunit:archunit-junit:0.8.3' testCompile "org.testfx:testfx-core:4.0.+" testCompile "org.testfx:testfx-junit5:4.0.+" - checkstyle 'com.puppycrawl.tools:checkstyle:8.10.1' + checkstyle 'com.puppycrawl.tools:checkstyle:8.11' } jacoco { @@ -188,7 +188,7 @@ dependencyUpdates.revision = 'integration' dependencyUpdates.resolutionStrategy = { componentSelection { rules -> rules.all { ComponentSelection selection -> - if ( selection.candidate.module != "junit-pioneer" && selection.candidate.module!="javax.inject" && selection.candidate.version ==~ /[0-9].*SNAPSHOT/ ) { + if ( selection.candidate.module!="javax.inject" && selection.candidate.version ==~ /[0-9].*SNAPSHOT/ ) { selection.reject("Ignore SNAPSHOT releases") } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1948b9074f1016d15d505d185bc3f73deb82d8c8..758de960ec7947253b058ff79c88ce51f3abe08a 100644 GIT binary patch delta 674 zcmYk)T}V@590u^ce`_BwX^}IxS%%_;lVr!`V#{7~K>D!@P~?^<`NH4(Ing@BclV!#Ts#S?=kqkqXuP zh4b|_GMTK^ZEaC})BWsS?`2rD8(zFT^*$$2zD;)0rchoVsqNJAp+Rb5f&VDlMi zQYES(UnQk?Z>@gyS?N=rh)4VlG+4lCz=!dlOI4&Q6MV!u zbVzV*se)1`1TBHXk#o* z@F>~s=(iW+T*%107!Fxz!;Wl6Iev$X)Yr|aLv6T;iY{T%osXGt4SR+4a4YGYqG)!i z`5iSFi0EnGRbCZgAz~)AORzt>9ZfDROi?2}zLBXcG2Lu~p&2;mQ;Ja8o z&D|9&iPzEWJo%MhBBI8q!mjTBtLejW3~kI;=@+WB53YI_yQbRgiv}qBG>*=Lks5M@W{k@qjwY?(f zS!iTsc)DD{+0fmNusGX{HjdIewVoXyAt= tp=w2D5tvtQun|08=_Y#s4+0fvSd~gMf5wu3Us&AV entries = new LinkedList<>(); - - private final OutputPrinter status = new SystemOutputPrinter(); - - @Override - public void addEntry(BibEntry entry) { - entries.add(entry); - } - - @Override - public void setProgress(int current, int max) { - status.setStatus(Localization.lang("Progress: %0 of %1", String.valueOf(current), String - .valueOf(max))); - } - - public Collection query(String query, EntryFetcher fetcher) { - entries.clear(); - if (fetcher.processQuery(query, ImportInspectionCommandLine.this, status)) { - return entries; - } - return Collections.emptyList(); - } -} diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java index d1d0411d844..9fa6a93bbcf 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java @@ -146,7 +146,7 @@ private void buildGUI() { con.insets = new Insets(0, 5, 0, 5); JButton hlb = new JButton(IconTheme.JabRefIcons.HELP.getSmallIcon()); - Button help1 = new Button("?"); + Button help1 = new Button("Help"); help1.setOnAction(e->new HelpAction(Localization.lang("Help on key patterns"), HelpFile.BIBTEX_KEY_PATTERN).getHelpButton().doClick()); gridPane.add(help1,1,24); diff --git a/src/main/java/org/jabref/gui/importer/fetcher/CiteSeerXFetcher.java b/src/main/java/org/jabref/gui/importer/fetcher/CiteSeerXFetcher.java deleted file mode 100644 index 78ca7062d55..00000000000 --- a/src/main/java/org/jabref/gui/importer/fetcher/CiteSeerXFetcher.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.jabref.gui.importer.fetcher; - -import java.io.IOException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.swing.JPanel; - -import org.jabref.Globals; -import org.jabref.gui.importer.ImportInspectionDialog; -import org.jabref.logic.formatter.bibtexfields.NormalizeNamesFormatter; -import org.jabref.logic.help.HelpFile; -import org.jabref.logic.importer.ImportInspector; -import org.jabref.logic.importer.OutputPrinter; -import org.jabref.logic.net.URLDownload; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.FieldName; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CiteSeerXFetcher implements EntryFetcher { - - private static final int MAX_PAGES_TO_LOAD = 8; - private static final String QUERY_MARKER = "___QUERY___"; - private static final String URL_START = "http://citeseer.ist.psu.edu"; - private static final String SEARCH_URL = CiteSeerXFetcher.URL_START + "/search?q=" + CiteSeerXFetcher.QUERY_MARKER - + "&submit=Search&sort=rlv&t=doc"; - private static final Pattern CITE_LINK_PATTERN = Pattern.compile(""); - - private static final String BASE_PATTERN = ""; - private static final Pattern TITLE_PATTERN = Pattern - .compile(CiteSeerXFetcher.BASE_PATTERN.replace(CiteSeerXFetcher.QUERY_MARKER, "citation_title")); - private static final Pattern AUTHOR_PATTERN = Pattern - .compile(CiteSeerXFetcher.BASE_PATTERN.replace(CiteSeerXFetcher.QUERY_MARKER, "citation_authors")); - private static final Pattern YEAR_PATTERN = Pattern - .compile(CiteSeerXFetcher.BASE_PATTERN.replace(CiteSeerXFetcher.QUERY_MARKER, "citation_year")); - private static final Pattern ABSTRACT_PATTERN = Pattern.compile("

Abstract

\\s*

(.*)

"); - - private static final Logger LOGGER = LoggerFactory.getLogger(CiteSeerXFetcher.class); - - private boolean stopFetching; - - @Override - public boolean processQuery(String query, ImportInspector inspector, OutputPrinter status) { - stopFetching = false; - try { - List citations = getCitations(query); - for (String citation : citations) { - if (stopFetching) { - break; - } - BibEntry entry = getSingleCitation(citation); - if (entry != null) { - inspector.addEntry(entry); - } - } - - return true; - } catch (IOException e) { - LOGGER.error("Error while fetching from " + getTitle(), e); - ((ImportInspectionDialog)inspector).showErrorMessage(this.getTitle(), e.getLocalizedMessage()); - return false; - } - } - - @Override - public String getTitle() { - return "CiteSeerX"; - } - - @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_CITESEERX; - } - - @Override - public JPanel getOptionsPanel() { - return null; - } - - @Override - public void stopFetching() { - stopFetching = true; - } - - /** - * - * @param query - * The search term to query JStor for. - * @return a list of IDs - * @throws java.io.IOException - */ - private List getCitations(String query) throws IOException { - String urlQuery; - List ids = new ArrayList<>(); - urlQuery = CiteSeerXFetcher.SEARCH_URL.replace(CiteSeerXFetcher.QUERY_MARKER, - URLEncoder.encode(query, StandardCharsets.UTF_8.name())); - int count = 1; - String nextPage; - while (((nextPage = getCitationsFromUrl(urlQuery, ids)) != null) - && (count < CiteSeerXFetcher.MAX_PAGES_TO_LOAD)) { - urlQuery = nextPage; - count++; - if (stopFetching) { - break; - } - } - return ids; - } - - private static String getCitationsFromUrl(String urlQuery, List ids) throws IOException { - String cont = new URLDownload(urlQuery).asString(Globals.prefs.getDefaultEncoding()); - Matcher m = CiteSeerXFetcher.CITE_LINK_PATTERN.matcher(cont); - while (m.find()) { - ids.add(CiteSeerXFetcher.URL_START + m.group(1)); - } - - return null; - } - - private static BibEntry getSingleCitation(String urlString) throws IOException { - String cont = new URLDownload(urlString).asString(); - - // Find title, and create entry if we do. Otherwise assume we did not get an entry: - Matcher m = CiteSeerXFetcher.TITLE_PATTERN.matcher(cont); - if (m.find()) { - BibEntry entry = new BibEntry(); - entry.setField(FieldName.TITLE, m.group(1)); - - // Find authors: - m = CiteSeerXFetcher.AUTHOR_PATTERN.matcher(cont); - if (m.find()) { - String authors = m.group(1); - entry.setField(FieldName.AUTHOR, new NormalizeNamesFormatter().format(authors)); - } - - // Find year: - m = CiteSeerXFetcher.YEAR_PATTERN.matcher(cont); - if (m.find()) { - entry.setField(FieldName.YEAR, m.group(1)); - } - - // Find abstract: - m = CiteSeerXFetcher.ABSTRACT_PATTERN.matcher(cont); - if (m.find()) { - entry.setField(FieldName.ABSTRACT, m.group(1)); - } - - return entry; - } else { - return null; - } - - } - -} diff --git a/src/main/java/org/jabref/gui/importer/fetcher/EntryFetcher.java b/src/main/java/org/jabref/gui/importer/fetcher/EntryFetcher.java deleted file mode 100644 index f2470d68fb3..00000000000 --- a/src/main/java/org/jabref/gui/importer/fetcher/EntryFetcher.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.jabref.gui.importer.fetcher; - -import javax.swing.JPanel; - -import org.jabref.gui.importer.ImportInspectionDialog; -import org.jabref.logic.help.HelpFile; -import org.jabref.logic.importer.ImportInspector; -import org.jabref.logic.importer.OutputPrinter; - -/** - * @Deprecated - * Use {@link SearchBasedEntryFetcher} instead
- * Implement this interface to add another activeFetcher (something that grabs records - * from the Web for JabRef). Have a look at the existing implemenations - * IEEEXploreFetcher, JStorFetcher and - * CiteSeerEntryFetcher. - * - * Note: You also need to implement the method stopFetching from - * ImportInspectionDialog.Callback - * - * A Fetcher should not execute any GUI Operations, because it might be run in - * headless mode, but rather use the OutputPrinter for talking to the user. - */ -@Deprecated -public interface EntryFetcher extends ImportInspectionDialog.CallBack { - - /** - * Handle a query entered by the user. - * - * The method is expected to block the caller until all entries have been - * reported to the inspector. - * - * @param query - * The query text. - * @param inspector - * The dialog to add imported entries to. - * @param status - * An OutputPrinter passed to the activeFetcher for reporting about the - * status of the fetching. - * - * @return True if the query was completed successfully, false if an error - * occurred. - */ - boolean processQuery(String query, ImportInspector inspector, OutputPrinter status); - - /** - * The title for this activeFetcher, displayed in the menu and in the side pane. - * - * @return The title - */ - String getTitle(); - - /** - * Get the name of the help page for this activeFetcher. - * - * If given, a question mark is displayed in the side pane which leads to - * the help page. - * - * @return The {@link HelpFile} enum constant for the help page - */ - HelpFile getHelpPage(); - - /** - * If this activeFetcher requires additional options, a panel for setting up these - * should be returned in a JPanel by this method. This JPanel will be added - * to the side pane component automatically. - * - * @return Options panel for this activeFetcher or null if this activeFetcher does not - * have any options. - */ - JPanel getOptionsPanel(); -} diff --git a/src/main/java/org/jabref/gui/importer/fetcher/EntryFetchers.java b/src/main/java/org/jabref/gui/importer/fetcher/EntryFetchers.java deleted file mode 100644 index 0b48c288b6b..00000000000 --- a/src/main/java/org/jabref/gui/importer/fetcher/EntryFetchers.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.jabref.gui.importer.fetcher; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -import org.jabref.Globals; -import org.jabref.logic.importer.WebFetchers; -import org.jabref.logic.journals.JournalAbbreviationLoader; - -public class EntryFetchers { - - private final List entryFetchers = new LinkedList<>(); - - public EntryFetchers(JournalAbbreviationLoader abbreviationLoader) { - entryFetchers.add(new CiteSeerXFetcher()); - entryFetchers.add(new IEEEXploreFetcher(abbreviationLoader)); - - WebFetchers.getSearchBasedFetchers(Globals.prefs.getImportFormatPreferences()).stream() - .map(SearchBasedEntryFetcher::new) - .forEach(entryFetchers::add); - } - - public List getEntryFetchers() { - return Collections.unmodifiableList(this.entryFetchers); - } -} diff --git a/src/main/java/org/jabref/gui/importer/fetcher/GeneralFetcher.java b/src/main/java/org/jabref/gui/importer/fetcher/GeneralFetcher.java deleted file mode 100644 index a5bdd0696e3..00000000000 --- a/src/main/java/org/jabref/gui/importer/fetcher/GeneralFetcher.java +++ /dev/null @@ -1,216 +0,0 @@ -package org.jabref.gui.importer.fetcher; - -import java.awt.BorderLayout; -import java.awt.CardLayout; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JPanel; -import javax.swing.JTextField; -import javax.swing.SwingUtilities; - -import javafx.embed.swing.SwingNode; -import javafx.scene.Node; -import javafx.scene.layout.Priority; - -import org.jabref.Globals; -import org.jabref.JabRefExecutorService; -import org.jabref.gui.JabRefFrame; -import org.jabref.gui.SidePaneComponent; -import org.jabref.gui.SidePaneManager; -import org.jabref.gui.SidePaneType; -import org.jabref.gui.actions.Action; -import org.jabref.gui.actions.StandardActions; -import org.jabref.gui.help.HelpAction; -import org.jabref.gui.icon.IconTheme; -import org.jabref.gui.importer.ImportInspectionDialog; -import org.jabref.logic.l10n.Localization; -import org.jabref.logic.util.OS; -import org.jabref.preferences.JabRefPreferences; - -public class GeneralFetcher extends SidePaneComponent implements ActionListener { - - private final JTextField tf = new JTextField(); - - private final CardLayout optionsCards = new CardLayout(); - private final JPanel optionsPanel = new JPanel(optionsCards); - private final JPanel optPanel = new JPanel(new BorderLayout()); - - private final JabRefFrame frame; - private final JabRefPreferences preferences; - private EntryFetcher activeFetcher; - - public GeneralFetcher(SidePaneManager sidePaneManager, JabRefPreferences preferences, JabRefFrame frame) { - super(sidePaneManager, IconTheme.JabRefIcons.WWW, Localization.lang("Web search")); - this.frame = frame; - this.preferences = preferences; - } - - @Override - public Action getToggleAction() { - return StandardActions.TOGGLE_WEB_SEARCH; - } - - @Override - protected Node createContentPane() { - List fetchers = new EntryFetchers(Globals.journalAbbreviationLoader).getEntryFetchers(); - EntryFetcher[] fetcherArray = fetchers.toArray(new EntryFetcher[fetchers.size()]); - Arrays.sort(fetcherArray, new EntryFetcherComparator()); - String[] choices = new String[fetcherArray.length]; - for (int i = 0; i < fetcherArray.length; i++) { - choices[i] = fetcherArray[i].getTitle(); - } - JComboBox fetcherChoice = new JComboBox<>(choices); - int defaultFetcher = preferences.getInt(JabRefPreferences.SELECTED_FETCHER_INDEX); - if (defaultFetcher >= fetcherArray.length) { - defaultFetcher = 0; - } - this.activeFetcher = fetcherArray[defaultFetcher]; - fetcherChoice.setSelectedIndex(defaultFetcher); - if (this.activeFetcher.getOptionsPanel() != null) { - optPanel.add(this.activeFetcher.getOptionsPanel(), BorderLayout.CENTER); - } - HelpAction help = new HelpAction(activeFetcher.getHelpPage()); - JButton helpBut = help.getHelpButton(); - helpBut.setEnabled(activeFetcher.getHelpPage() != null); - - fetcherChoice.addActionListener(actionEvent -> { - activeFetcher = fetcherArray[fetcherChoice.getSelectedIndex()]; - preferences.putInt(JabRefPreferences.SELECTED_FETCHER_INDEX, fetcherChoice.getSelectedIndex()); - if (activeFetcher.getHelpPage() == null) { - helpBut.setEnabled(false); - } else { - help.setHelpFile(activeFetcher.getHelpPage()); - helpBut.setEnabled(true); - } - optionsCards.show(optionsPanel, String.valueOf(fetcherChoice.getSelectedIndex())); - optPanel.removeAll(); - if (activeFetcher.getOptionsPanel() != null) { - optPanel.add(activeFetcher.getOptionsPanel(), BorderLayout.CENTER); - } - }); - - helpBut.setMargin(new Insets(0, 0, 0, 0)); - tf.setPreferredSize(new Dimension(1, tf.getPreferredSize().height)); - if (OS.OS_X) { - tf.putClientProperty("JTextField.variant", "search"); - } - - tf.setName("tf"); - // add action to reset-button. resets tf and requests focus - JButton reset = new JButton(Localization.lang("Reset")); - reset.addActionListener(event -> { - tf.setText(""); - tf.requestFocus(); - }); - - JPanel main = new JPanel(); - GridBagLayout gbl = new GridBagLayout(); - main.setLayout(gbl); - GridBagConstraints con = new GridBagConstraints(); - con.fill = GridBagConstraints.BOTH; - con.insets = new Insets(0, 0, 2, 0); - con.gridwidth = GridBagConstraints.REMAINDER; - con.weightx = 1; - con.weighty = 1; - con.insets = new Insets(1, 0, 1, 0); - con.fill = GridBagConstraints.BOTH; - gbl.setConstraints(fetcherChoice, con); - main.add(fetcherChoice); - con.insets = new Insets(0, 0, 0, 0); - gbl.setConstraints(tf, con); - main.add(tf); - - // Go Button - con.weighty = 0; - con.gridwidth = 1; - JButton go = new JButton(Localization.lang("Fetch")); - gbl.setConstraints(go, con); - main.add(go); - - // Reset Button - reset.setName("reset"); - gbl.setConstraints(reset, con); - main.add(reset); - - // Help Button - con.gridwidth = GridBagConstraints.REMAINDER; - gbl.setConstraints(helpBut, con); - main.add(helpBut); - - gbl.setConstraints(optPanel, con); - main.add(optPanel); - - main.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); - go.addActionListener(this); - tf.addActionListener(this); - - SwingNode swingNode = new SwingNode(); - SwingUtilities.invokeLater(() -> swingNode.setContent(main)); - return swingNode; - } - - @Override - public SidePaneType getType() { - return SidePaneType.WEB_SEARCH; - } - - @Override - public void actionPerformed(ActionEvent e) { - if (tf.getText().trim().isEmpty()) { - frame.output(Localization.lang("Please enter a search string")); - return; - } - - if (frame.getCurrentBasePanel() == null) { - frame.output(Localization.lang("Please open or start a new library before searching")); - return; - } - - final ImportInspectionDialog dialog = new ImportInspectionDialog(frame, frame.getCurrentBasePanel(), - activeFetcher.getTitle(), false); - dialog.addCallBack(activeFetcher); - dialog.setVisible(true); - - JabRefExecutorService.INSTANCE.execute(() -> { - if (activeFetcher.processQuery(tf.getText().trim(), dialog, dialog)) { - dialog.entryListComplete(); - } else { - dialog.dispose(); - } - }); - } - - @Override - public void beforeClosing() { - preferences.putBoolean(JabRefPreferences.WEB_SEARCH_VISIBLE, Boolean.FALSE); - } - - @Override - public void afterOpening() { - preferences.putBoolean(JabRefPreferences.WEB_SEARCH_VISIBLE, Boolean.TRUE); - } - - @Override - public Priority getResizePolicy() { - return Priority.NEVER; - } - - private static class EntryFetcherComparator implements Comparator { - - @Override - public int compare(EntryFetcher entryFetcher, EntryFetcher entryFetcher1) { - return entryFetcher.getTitle().compareTo(entryFetcher1.getTitle()); - } - } -} diff --git a/src/main/java/org/jabref/gui/importer/fetcher/IEEEXploreFetcher.java b/src/main/java/org/jabref/gui/importer/fetcher/IEEEXploreFetcher.java deleted file mode 100644 index 08a3feed17f..00000000000 --- a/src/main/java/org/jabref/gui/importer/fetcher/IEEEXploreFetcher.java +++ /dev/null @@ -1,489 +0,0 @@ -package org.jabref.gui.importer.fetcher; - -import java.awt.BorderLayout; -import java.io.IOException; -import java.net.CookieHandler; -import java.net.CookieManager; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.swing.JCheckBox; -import javax.swing.JOptionPane; -import javax.swing.JPanel; - -import org.jabref.Globals; -import org.jabref.gui.importer.ImportInspectionDialog; -import org.jabref.logic.formatter.bibtexfields.HtmlToLatexFormatter; -import org.jabref.logic.formatter.bibtexfields.UnitsToLatexFormatter; -import org.jabref.logic.formatter.casechanger.ProtectTermsFormatter; -import org.jabref.logic.help.HelpFile; -import org.jabref.logic.importer.ImportInspector; -import org.jabref.logic.importer.OutputPrinter; -import org.jabref.logic.importer.ParseException; -import org.jabref.logic.importer.fileformat.BibtexParser; -import org.jabref.logic.journals.JournalAbbreviationLoader; -import org.jabref.logic.journals.JournalAbbreviationPreferences; -import org.jabref.logic.l10n.Localization; -import org.jabref.logic.net.URLDownload; -import org.jabref.model.cleanup.Formatter; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.FieldName; -import org.jabref.preferences.JabRefPreferences; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class IEEEXploreFetcher implements EntryFetcher { - - private static final Logger LOGGER = LoggerFactory.getLogger(IEEEXploreFetcher.class); - private static final String URL_SEARCH = "https://ieeexplore.ieee.org/rest/search?reload=true"; - private static final String URL_BIBTEX_START = "https://ieeexplore.ieee.org/xpl/downloadCitations?reload=true&recordIds="; - private static final String URL_BIBTEX_END = "&download-format=download-bibtex&x=0&y=0"; - private static final String DIALOG_TITLE = Localization.lang("Search %0", "IEEEXplore"); - private static final int MAX_FETCH = 100; - - private static final Pattern PUBLICATION_PATTERN = Pattern.compile("(.*), \\d*\\.*\\s?(.*)"); - private static final Pattern PROCEEDINGS_PATTERN = Pattern.compile("(.*?)\\.?\\s?Proceedings\\s?(.*)"); - private static final Pattern MONTH_PATTERN = Pattern.compile("(\\d*+)\\s*([a-z]*+)-*(\\d*+)\\s*([a-z]*+)"); - - private static final Pattern PREPROCESSING_PATTERN = Pattern.compile("(? IEEEXploreFetcher.MAX_FETCH) { - status.showMessage( - Localization.lang("%0 entries found. To reduce server load, only %1 will be downloaded.", - String.valueOf(hits), String.valueOf(IEEEXploreFetcher.MAX_FETCH)), - DIALOG_TITLE, JOptionPane.INFORMATION_MESSAGE); - } - - //fetch the raw Bibtex results from IEEEXplore - String bibtexPage = new URLDownload(createBibtexQueryURL(searchResultsJson)) - .asString(Globals.prefs.getDefaultEncoding()); - - //preprocess the result (eg. convert HTML escaped characters to latex and do other formatting not performed by BibtexParser) - bibtexPage = preprocessBibtexResultsPage(bibtexPage); - - //parse the page into Bibtex entries - Collection parsedBibtexCollection = new BibtexParser(Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()) - .parseEntries(bibtexPage); - int nEntries = parsedBibtexCollection.size(); - Iterator parsedBibtexCollectionIterator = parsedBibtexCollection.iterator(); - while (parsedBibtexCollectionIterator.hasNext() && shouldContinue) { - dialog.addEntry(cleanup(parsedBibtexCollectionIterator.next())); - dialog.setProgress(parsed, nEntries); - parsed++; - } - - return true; - - } catch (ParseException | IOException | JSONException e) { - LOGGER.error("Error while fetching from " + getTitle(), e); - ((ImportInspectionDialog)dialog).showErrorMessage(this.getTitle(), e.getLocalizedMessage()); - } - - return false; - } - - @Override - public String getTitle() { - return "IEEEXplore"; - } - - @Override - public HelpFile getHelpPage() { - return HelpFile.FETCHER_IEEEXPLORE; - } - - /** - * This method is called by the dialog when the user has canceled the import. - */ - @Override - public void stopFetching() { - shouldContinue = false; - } - - private String makeSearchPostRequestPayload(int startIndex, String terms) { - return "{\"queryText\":" + JSONObject.quote(terms) + ",\"refinements\":[],\"pageNumber\":\"" + startIndex - + "\",\"searchWithin\":[],\"newsearch\":\"true\",\"searchField\":\"Search_All\",\"rowsPerPage\":\"100\"}"; - } - - private String createBibtexQueryURL(JSONObject searchResultsJson) { - - //buffer to use for building the URL for fetching the bibtex data from IEEEXplore - StringBuilder bibtexQueryURLStringBuf = new StringBuilder(); - bibtexQueryURLStringBuf.append(URL_BIBTEX_START); - - //loop over each record and create a comma-separate list of article numbers which will be used to download the raw Bibtex - JSONArray recordsJsonArray = searchResultsJson.getJSONArray("records"); - for (int n = 0; n < recordsJsonArray.length(); n++) { - if (!recordsJsonArray.getJSONObject(n).isNull("articleNumber")) { - bibtexQueryURLStringBuf.append(recordsJsonArray.getJSONObject(n).getString("articleNumber")) - .append(','); - } - } - //delete the last comma - bibtexQueryURLStringBuf.deleteCharAt(bibtexQueryURLStringBuf.length() - 1); - - //add the abstract setting - boolean includeAbstract = absCheckBox.isSelected(); - if (includeAbstract) { - bibtexQueryURLStringBuf.append("&citations-format=citation-abstract"); - } else { - bibtexQueryURLStringBuf.append("&citations-format=citation-only"); - } - - //append the remaining URL - bibtexQueryURLStringBuf.append(URL_BIBTEX_END); - - return bibtexQueryURLStringBuf.toString(); - } - - private String preprocessBibtexResultsPage(String bibtexPage) { - //for some reason, the escaped HTML characters in the titles are in the format "#xNNNN" (they are missing the ampersand) - //add the ampersands back in before passing to the HTML formatter so they can be properly converted - //TODO: Maybe edit the HTMLconverter to also recognize escaped characters even when the & is missing? - String result = PREPROCESSING_PATTERN.matcher(bibtexPage).replaceAll("&$1"); - - //Also, percent signs are not escaped by the IEEEXplore Bibtex output nor, it would appear, the subsequent processing in JabRef - //TODO: Maybe find a better spot for this if it applies more universally - result = result.replaceAll("(? { - // USe the alt-text and replace image links - String title = dirtyTitle.replaceAll("[ ]?img src=[^ ]+ alt=\"([^\"]+)\">[ ]?", "\\$$1\\$"); - // Try to sort out most of the /spl / conversions - // Deal with this specific nested type first - title = title.replaceAll("/sub /spl infin//", "\\$_\\\\infty\\$"); - title = title.replaceAll("/sup /spl infin//", "\\$\\^\\\\infty\\$"); - // Replace general expressions - title = title.replaceAll("/[sS]pl ([^/]+)/", "\\$\\\\$1\\$"); - // Deal with subscripts and superscripts - title = SUPER_DETECTION_1.matcher(title).replaceAll(SUPER_TEXT_RESULT); - title = SUB_DETECTION_1.matcher(title).replaceAll(SUB_TEXT_RESULT); - title = SUPER_DETECTION_2.matcher(title).replaceAll(SUPER_TEXT_RESULT); - title = SUB_DETECTION_2.matcher(title).replaceAll(SUB_TEXT_RESULT); - - // Replace \infin with \infty - title = title.replaceAll("\\\\infin", "\\\\infty"); - - // Unit formatting - if (Globals.prefs.getBoolean(JabRefPreferences.USE_UNIT_FORMATTER_ON_SEARCH)) { - title = unitsToLatexFormatter.format(title); - } - - // Automatic case keeping - if (Globals.prefs.getBoolean(JabRefPreferences.USE_CASE_KEEPER_ON_SEARCH)) { - title = protectTermsFormatter.format(title); - } - // Write back - entry.setField(FieldName.TITLE, title); - }); - - // clean up author - entry.getField(FieldName.AUTHOR).ifPresent(dirtyAuthor -> { - String author = dirtyAuthor.replaceAll("\\s+", " "); - - //reorder the "Jr." "Sr." etc to the correct ordering - String[] authorSplit = author.split("(^\\s*|\\s*$|\\s+and\\s+)"); - List authorResult = new ArrayList<>(); - for (String authorSplitPart : authorSplit) { - authorResult.add(authorSplitPart.replaceAll("(.+?),(.+?),(.+)", "$1,$3,$2")); - } - author = String.join(" and ", authorResult); - - author = author.replace(".", ". ").replace(" ", " ").replace(". -", ".-").replace("; ", " and ") - .replace(" ,", ",").replace(" ", " "); - author = author.replaceAll("[ ,;]+$", ""); - //TODO: remove trailing commas - entry.setField(FieldName.AUTHOR, author); - }); - - // clean up month - entry.getField(FieldName.MONTH).filter(month -> !month.isEmpty()).ifPresent(dirtyMonth -> { - String month = dirtyMonth.replace(".", ""); - month = month.toLowerCase(Locale.ROOT); - - Matcher mm = MONTH_PATTERN.matcher(month); - StringBuilder date = new StringBuilder(month); - if (mm.find()) { - if (mm.group(3).isEmpty()) { - if (mm.group(2).isEmpty()) { - date = new StringBuilder().append(mm.group(1)).append(','); - } else { - date = new StringBuilder().append('#').append(mm.group(2).substring(0, 3)).append('#'); - if (!mm.group(1).isEmpty()) { - date.append(' ').append(mm.group(1)).append(','); - } - } - } else if (mm.group(2).isEmpty()) { - if (mm.group(4).isEmpty()) { - date.append(','); - } else { - date = new StringBuilder().append('#').append(mm.group(4).substring(0, 3)).append('#') - .append(mm.group(1)).append("--").append(mm.group(3)).append(','); - } - } else { - date = new StringBuilder().append('#').append(mm.group(2).substring(0, 3)).append('#') - .append(mm.group(1)).append("--#").append(mm.group(4).substring(0, 3)).append('#') - .append(mm.group(3)).append(','); - } - } - entry.setField(FieldName.MONTH, date.toString()); - }); - - // clean up pages - entry.getField(FieldName.PAGES).ifPresent(pages -> { - String[] pageNumbers = pages.split("-"); - if (pageNumbers.length == 2) { - if (pageNumbers[0].equals(pageNumbers[1])) { // single page - entry.setField(FieldName.PAGES, pageNumbers[0]); - } else { - entry.setField(FieldName.PAGES, pages.replace("-", "--")); - } - } - }); - - // clean up publication field - String type = entry.getType(); - String sourceField = ""; - if ("article".equals(type)) { - sourceField = FieldName.JOURNAL; - entry.clearField(FieldName.BOOKTITLE); - } else if ("inproceedings".equals(type)) { - sourceField = FieldName.BOOKTITLE; - } - if (entry.hasField(sourceField)) { - String fullName = entry.getField(sourceField).get(); - if ("article".equals(type)) { - int ind = fullName.indexOf(": Accepted for future publication"); - if (ind > 0) { - fullName = fullName.substring(0, ind); - entry.setField(FieldName.YEAR, "to be published"); - entry.clearField(FieldName.MONTH); - entry.clearField(FieldName.PAGES); - entry.clearField(FieldName.NUMBER); - } - String[] parts = fullName.split("[\\[\\]]"); //[see also...], [legacy...] - fullName = parts[0]; - if (parts.length == 3) { - fullName += parts[2]; - } - entry.getField(FieldName.NOTE).filter(note -> "Early Access".equals(note)).ifPresent(note -> { - entry.setField(FieldName.YEAR, "to be published"); - entry.clearField(FieldName.MONTH); - entry.clearField(FieldName.PAGES); - entry.clearField(FieldName.NUMBER); - }); - } else { - fullName = fullName.replace("Conference Proceedings", "Proceedings") - .replace("Proceedings of", "Proceedings").replace("Proceedings.", "Proceedings"); - fullName = fullName.replace("International", "Int."); - fullName = fullName.replace("Symposium", "Symp."); - fullName = fullName.replace("Conference", "Conf."); - fullName = fullName.replace(" on", " ").replace(" ", " "); - } - - Matcher m1 = PUBLICATION_PATTERN.matcher(fullName); - String abrvPattern = ".*[^,] '?\\d+\\)?"; - if (m1.find()) { - String prefix = m1.group(2).trim(); - String postfix = m1.group(1).trim(); - String abrv = ""; - String[] parts = prefix.split("\\. ", 2); - if (parts.length == 2) { - if (parts[0].matches(abrvPattern)) { - prefix = parts[1]; - abrv = parts[0]; - } else { - prefix = parts[0]; - abrv = parts[1]; - } - } - if (prefix.matches(abrvPattern)) { - fullName = postfix + " " + prefix; - } else { - fullName = prefix + " " + postfix + " " + abrv; - fullName = fullName.trim(); - } - } - if ("article".equals(type)) { - fullName = fullName.replace(" - ", "-"); //IEE Proceedings- - - fullName = fullName.trim(); - JournalAbbreviationPreferences journalAbbreviationPreferences = Globals.prefs.getJournalAbbreviationPreferences(); - if (journalAbbreviationPreferences.useIEEEAbbreviations()) { - fullName = abbreviationLoader - .getRepository(journalAbbreviationPreferences) - .getMedlineAbbreviation(fullName) - .orElse(fullName); - } - } - if ("inproceedings".equals(type)) { - Matcher m2 = PROCEEDINGS_PATTERN.matcher(fullName); - if (m2.find()) { - String prefix = m2.group(2); - String postfix = m2.group(1).replaceAll("\\.$", ""); - if (prefix.matches(abrvPattern)) { - fullName = postfix.trim() + " " + prefix.trim(); - } else { - String abrv = ""; - - String[] parts = postfix.split("\\. ", 2); - if (parts.length == 2) { - if (parts[0].matches(abrvPattern)) { - postfix = parts[1]; - abrv = parts[0]; - } else { - postfix = parts[0]; - abrv = parts[1]; - } - } - fullName = prefix.trim() + " " + postfix.trim() + " " + abrv; - - } - - } - - fullName = fullName.trim(); - - fullName = fullName.replaceAll("^[tT]he ", "").replaceAll("^\\d{4} ", "").replaceAll("[,.]$", ""); - Optional year = entry.getField(FieldName.YEAR); - if (year.isPresent()) { - fullName = fullName.replaceAll(", " + year.get() + "\\.?", ""); - } - - if (!fullName.contains("Abstract") && !fullName.contains("Summaries") - && !fullName.contains("Conference Record")) { - fullName = "Proc. " + fullName; - } - } - entry.setField(sourceField, fullName); - } - - // clean up abstract - entry.getField(FieldName.ABSTRACT).ifPresent(dirtyAbstr -> { - // Try to sort out most of the /spl / conversions - // Deal with this specific nested type first - String abstr = dirtyAbstr.replaceAll("/sub /spl infin//", "\\$_\\\\infty\\$"); - abstr = abstr.replaceAll("/sup /spl infin//", "\\$\\^\\\\infty\\$"); - // Replace general expressions - abstr = abstr.replaceAll("/[sS]pl ([^/]+)/", "\\$\\\\$1\\$"); - // Deal with subscripts and superscripts - abstr = SUPER_DETECTION_1.matcher(abstr).replaceAll(SUPER_TEXT_RESULT); - abstr = SUB_DETECTION_1.matcher(abstr).replaceAll(SUB_TEXT_RESULT); - abstr = SUPER_DETECTION_2.matcher(abstr).replaceAll(SUPER_TEXT_RESULT); - abstr = SUB_DETECTION_2.matcher(abstr).replaceAll(SUB_TEXT_RESULT); - // Replace \infin with \infty - abstr = abstr.replace("\\infin", "\\infty"); - // Write back - entry.setField(FieldName.ABSTRACT, abstr); - }); - - // Clean up url - entry.getField(FieldName.URL) - .ifPresent(url -> entry.setField(FieldName.URL, "https://ieeexplore.ieee.org" + url.replace("tp=&", ""))); - - // Replace ; as keyword separator - entry.getField(FieldName.KEYWORDS).ifPresent(keys -> entry.setField(FieldName.KEYWORDS, - keys.replace(";", Globals.prefs.get(JabRefPreferences.KEYWORD_SEPARATOR)))); - return entry; - } - -} diff --git a/src/main/java/org/jabref/gui/importer/fetcher/SearchBasedEntryFetcher.java b/src/main/java/org/jabref/gui/importer/fetcher/SearchBasedEntryFetcher.java deleted file mode 100644 index b5d3f398a28..00000000000 --- a/src/main/java/org/jabref/gui/importer/fetcher/SearchBasedEntryFetcher.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.jabref.gui.importer.fetcher; - -import java.util.List; -import java.util.Objects; - -import javax.swing.JPanel; - -import org.jabref.gui.importer.ImportInspectionDialog; -import org.jabref.logic.help.HelpFile; -import org.jabref.logic.importer.FetcherException; -import org.jabref.logic.importer.ImportInspector; -import org.jabref.logic.importer.OutputPrinter; -import org.jabref.logic.importer.SearchBasedFetcher; -import org.jabref.logic.l10n.Localization; -import org.jabref.model.entry.BibEntry; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Wrapper around {@link SearchBasedFetcher} which implements the old {@link EntryFetcher} interface. - */ -public class SearchBasedEntryFetcher implements EntryFetcher { - - private static final Logger LOGGER = LoggerFactory.getLogger(SearchBasedEntryFetcher.class); - private final SearchBasedFetcher fetcher; - - public SearchBasedEntryFetcher(SearchBasedFetcher fetcher) { - this.fetcher = Objects.requireNonNull(fetcher); - } - - @Override - public boolean processQuery(String query, ImportInspector inspector, OutputPrinter status) { - status.setStatus(Localization.lang("Processing %0", query)); - try { - List matches = fetcher.performSearch(query); - matches.forEach(inspector::addEntry); - return !matches.isEmpty(); - } catch (FetcherException e) { - LOGGER.error("Error while fetching from " + getTitle(), e); - ((ImportInspectionDialog)inspector).showErrorMessage(this.getTitle(), e.getLocalizedMessage()); - } - - return false; - } - - @Override - public String getTitle() { - return fetcher.getName(); - } - - @Override - public HelpFile getHelpPage() { - return fetcher.getHelpPage(); - } - - @Override - public JPanel getOptionsPanel() { - // not supported - return null; - } - - @Override - public void stopFetching() { - // not supported - } -} diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index 99c1691410d..8db668a6ba7 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -64,9 +64,12 @@ public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { memoryStick = new CheckBox(Localization.lang("Load and Save preferences from/to jabref.xml on start-up (memory stick mode)")); useOwner = new CheckBox(Localization.lang("Mark new entries with owner name") + ':'); - updateTimeStamp = new CheckBox(Localization.lang("Update timestamp on modification")); + updateTimeStamp = new CheckBox(Localization.lang(" Update timestamp on modification")); useTimeStamp = new CheckBox(Localization.lang("Mark new entries with addition date") + ". " + Localization.lang("Date format") + ':'); + if(!useTimeStamp.isSelected()){ + updateTimeStamp.setDisable(true); + } useTimeStamp.setOnAction(e->updateTimeStamp.setDisable(!useTimeStamp.isSelected())); overwriteOwner = new CheckBox(Localization.lang("Overwrite")); overwriteTimeStamp = new CheckBox(Localization.lang("Overwrite")); @@ -111,7 +114,7 @@ public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { builder.add(new Label(Localization.lang("Field name") + ':'),6,13); builder.add(timeStampField,7,13); - Button help1 = new Button("?"); + Button help1 = new Button("Help"); help1.setOnAction(event -> new HelpAction(HelpFile.TIMESTAMP).getHelpButton().doClick()); builder.add(help1,8,13); @@ -205,9 +208,9 @@ public void storeSettings() { prefs.setDefaultEncoding((Charset) encodings.getItems()); prefs.putBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE, biblatexMode.getItems().equals(BibDatabaseMode.BIBLATEX)); - if (!LANGUAGES.get(language.getItems()).equals(prefs.get(JabRefPreferences.LANGUAGE))) { - prefs.put(JabRefPreferences.LANGUAGE, LANGUAGES.get(language.getItems())); - Localization.setLanguage(LANGUAGES.get(language.getItems())); + if (!LANGUAGES.get(language.getItems().toString()).equals(prefs.get(JabRefPreferences.LANGUAGE))) { + prefs.put(JabRefPreferences.LANGUAGE, LANGUAGES.get(language.getItems().toString())); + Localization.setLanguage(LANGUAGES.get(language.getItems().toString())); // Update any defaults that might be language dependent: Globals.prefs.setLanguageDependentDefaultValues(); // Warn about restart needed: diff --git a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java index f9b9ebabe19..5d2f72dac45 100644 --- a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java @@ -1,84 +1,79 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JToolBar; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingConstants; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumnModel; -import javax.swing.table.TableModel; - -import org.jabref.gui.OSXCompatibleToolbar; +import javafx.beans.property.SimpleStringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.*; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; -import org.jabref.gui.icon.IconTheme; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; import org.jabref.logic.layout.format.NameFormatter; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; public class NameFormatterTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; private boolean tableChanged; - private final JTable table; + private final TableView table; private int rowCount = -1; private final List tableRows = new ArrayList<>(10); - static class TableRow { - - private String name; + public static class TableRow { - private String format; + private SimpleStringProperty name; + private SimpleStringProperty format; - - public TableRow() { + TableRow() { this(""); } - public TableRow(String name) { + TableRow(String name) { this(name, NameFormatter.DEFAULT_FORMAT); } - public TableRow(String name, String format) { - this.name = name; - this.format = format; + TableRow(String name, String format) { + this.name = new SimpleStringProperty(name); + this.format = new SimpleStringProperty(format); } public String getName() { - return name; + return name.get(); } public void setName(String name) { - this.name = name; + this.name.set(name); } public String getFormat() { - return format; + return format.get(); } public void setFormat(String format) { - this.format = format; + this.format.set(format); } } - + private final ObservableList data = FXCollections.observableArrayList(); /** * Tab to create custom Name Formatters @@ -88,112 +83,83 @@ public NameFormatterTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); setLayout(new BorderLayout()); - - - TableModel tableModel = new AbstractTableModel() { - - @Override - public int getRowCount() { - return rowCount; - } - - @Override - public int getColumnCount() { - return 2; - } - - @Override - public Object getValueAt(int row, int column) { - if (row >= tableRows.size()) { - return ""; - } - TableRow tr = tableRows.get(row); - if (tr == null) { - return ""; - } - // Only two columns - if (column == 0) { - return tr.getName(); - } else { - return tr.getFormat(); - } - } - - @Override - public String getColumnName(int col) { - return col == 0 ? Localization.lang("Formatter name") : - Localization.lang("Format string"); - } - - @Override - public Class getColumnClass(int column) { - return String.class; - } - - @Override - public boolean isCellEditable(int row, int col) { - return true; - } - - @Override - public void setValueAt(Object value, int row, int col) { + TableColumn firstCol = new TableColumn<>("Formatter name"); + TableColumn lastCol = new TableColumn<>("Format string"); + table = new TableView(); + table.setEditable(true); + firstCol.setCellValueFactory(new PropertyValueFactory<>("name")); + firstCol.setCellFactory(TextFieldTableCell.forTableColumn()); + firstCol.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setName(t.getNewValue()); + }); + lastCol.setCellValueFactory(new PropertyValueFactory<>("format")); + lastCol.setCellFactory(TextFieldTableCell.forTableColumn()); + lastCol.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setFormat(t.getNewValue()); + }); + firstCol.setPrefWidth(140); + lastCol.setPrefWidth(200); + table.setItems(data); + table.getColumns().addAll(firstCol,lastCol); + final TextField addName = new TextField(); + addName.setPromptText("name"); + addName.setMaxWidth(firstCol.getPrefWidth()); + final TextField addLast = new TextField(); + addLast.setMaxWidth(lastCol.getPrefWidth()); + addLast.setPromptText("format"); + + GridPane builder = new GridPane(); + BorderPane tabPanel = new BorderPane(); + ScrollPane scrollPane = new ScrollPane(); + scrollPane.setMaxHeight(400); + scrollPane.setMaxWidth(400); + scrollPane.setContent(table); + tabPanel.setCenter(scrollPane); + + Button add = new Button("Add"); + add.setOnAction(e-> { + if (!addName.getText().isEmpty() && !addLast.getText().isEmpty()) { + TableRow tableRow = new TableRow(addName.getText(), addLast.getText()); + addName.clear(); + addLast.clear(); + data.add(tableRow); + tableRows.add(tableRow); + rowCount++; + table.setItems(data); tableChanged = true; - - // Make sure the vector is long enough. - while (row >= tableRows.size()) { - tableRows.add(new TableRow()); - } - - TableRow rowContent = tableRows.get(row); - - if (col == 0) { - rowContent.setName(value.toString()); - } else { - rowContent.setFormat(value.toString()); - } + table.refresh(); } - }; - - table = new JTable(tableModel); - - TableColumnModel columnModel = table.getColumnModel(); - columnModel.getColumn(0).setPreferredWidth(140); - columnModel.getColumn(1).setPreferredWidth(400); - - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref", ""); - - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - - JPanel pan = new JPanel(); - - JPanel tabPanel = new JPanel(); - tabPanel.setLayout(new BorderLayout()); - JScrollPane scrollPane = new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - table.setPreferredScrollableViewportSize(new Dimension(250, 200)); - scrollPane.setMinimumSize(new Dimension(250, 300)); - scrollPane.setPreferredSize(new Dimension(600, 300)); - tabPanel.add(scrollPane, BorderLayout.CENTER); - - JToolBar toolBar = new OSXCompatibleToolbar(SwingConstants.VERTICAL); - toolBar.setFloatable(false); - toolBar.setBorder(null); - toolBar.add(new AddRowAction()); - toolBar.add(new DeleteRowAction()); - toolBar.add(new HelpAction(Localization.lang("Help on Name Formatting"), - HelpFile.CUSTOM_EXPORTS_NAME_FORMATTER).getHelpButton()); - - tabPanel.add(toolBar, BorderLayout.EAST); - - builder.appendSeparator(Localization.lang("Special name formatters")); - builder.nextLine(); - builder.append(pan); - builder.append(tabPanel); - builder.nextLine(); - - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + }); + Button delete = new Button("Delete"); + delete.setOnAction(e->{if (table.getFocusModel() != null && table.getFocusModel().getFocusedIndex()!= -1) { + tableChanged = true; + int row = table.getFocusModel().getFocusedIndex(); + TableRow tableRow = tableRows.get(row); + tableRows.remove(tableRow); + data.remove(tableRow); + table.setItems(data); + rowCount--; + table.refresh(); + }}); + Button help = new Button("Help"); + help.setOnAction(e-> new HelpAction(Localization.lang("Help on Name Formatting"), + HelpFile.CUSTOM_EXPORTS_NAME_FORMATTER).getHelpButton().doClick()); + HBox toolbar = new HBox(); + toolbar.getChildren().addAll(addName, addLast,add,delete,help); + tabPanel.setBottom(toolbar); + + builder.add(new Label(Localization.lang("Special name formatters")),1,1); + builder.add(tabPanel,1,2); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); } @Override @@ -212,70 +178,6 @@ public void setValues() { rowCount = tableRows.size() + 5; } - class DeleteRowAction extends AbstractAction { - - public DeleteRowAction() { - super("Delete row", IconTheme.JabRefIcons.REMOVE_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Delete rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - tableChanged = true; - - int[] selectedRows = table.getSelectedRows(); - - int numberDeleted = 0; - - for (int i = selectedRows.length - 1; i >= 0; i--) { - if (selectedRows[i] < tableRows.size()) { - tableRows.remove(selectedRows[i]); - numberDeleted++; - } - } - - rowCount -= numberDeleted; - - if (selectedRows.length > 1) { - table.clearSelection(); - } - - table.revalidate(); - table.repaint(); - } - } - - class AddRowAction extends AbstractAction { - - public AddRowAction() { - super("Add row", IconTheme.JabRefIcons.ADD_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Insert rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = table.getSelectedRows(); - if (rows.length == 0) { - // No rows selected, so we just add one at the end. - rowCount++; - table.revalidate(); - table.repaint(); - return; - } - for (int i = 0; i < rows.length; i++) { - if (((rows[i] + i) - 1) < tableRows.size()) { - tableRows.add(Math.max(0, (rows[i] + i) - 1), new TableRow()); - } - } - rowCount += rows.length; - if (rows.length > 1) { - table.clearSelection(); - } - table.revalidate(); - table.repaint(); - tableChanged = true; - } - } /** @@ -286,12 +188,6 @@ public void actionPerformed(ActionEvent e) { @Override public void storeSettings() { - if (table.isEditing()) { - int col = table.getEditingColumn(); - int row = table.getEditingRow(); - table.getCellEditor(row, col).stopCellEditing(); - } - // Now we need to make sense of the contents the user has made to the // table setup table. if (tableChanged) { diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index b68b94710fe..f1c28a49733 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -1,85 +1,73 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; - -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.Icon; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JToolBar; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingConstants; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumnModel; -import javax.swing.table.TableModel; - +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; import org.jabref.gui.BasePanel; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.OSXCompatibleToolbar; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.help.HelpAction; -import org.jabref.gui.icon.IconTheme; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibtexSingleField; import org.jabref.preferences.JabRefPreferences; - -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.CellConstraints; -import com.jgoodies.forms.layout.FormLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.util.*; +import java.util.List; + class TableColumnsTab extends JPanel implements PrefsTab { private static final Logger LOGGER = LoggerFactory.getLogger(TableColumnsTab.class); private final JabRefPreferences prefs; private boolean tableChanged; - private final JTable colSetup; + private final TableView colSetup; private int rowCount = -1; private final List tableRows = new ArrayList<>(10); private final JabRefFrame frame; - private final JCheckBox urlColumn; - private final JCheckBox fileColumn; - private final JCheckBox arxivColumn; - - private final JCheckBox extraFileColumns; - private final JList listOfFileColumns; + private final CheckBox urlColumn; + private final CheckBox fileColumn; + private final CheckBox arxivColumn; - private final JRadioButton preferUrl; - private final JRadioButton preferDoi; + private final CheckBox extraFileColumns; + private final ListView listOfFileColumns; + private final RadioButton preferUrl; + private final RadioButton preferDoi; + private int lastIndex; /*** begin: special fields ***/ - private final JCheckBox specialFieldsEnabled; - private final JCheckBox rankingColumn; - private final JCheckBox qualityColumn; - private final JCheckBox priorityColumn; - private final JCheckBox relevanceColumn; - private final JCheckBox printedColumn; - private final JCheckBox readStatusColumn; - private final JRadioButton syncKeywords; - private final JRadioButton writeSpecialFields; + private final CheckBox specialFieldsEnabled; + private final CheckBox rankingColumn; + private final CheckBox qualityColumn; + private final CheckBox priorityColumn; + private final CheckBox relevanceColumn; + private final CheckBox printedColumn; + private final CheckBox readStatusColumn; + private final RadioButton syncKeywords; + private final RadioButton writeSpecialFields; private boolean oldSpecialFieldsEnabled; private boolean oldRankingColumn; private boolean oldQualityColumn; @@ -89,7 +77,8 @@ class TableColumnsTab extends JPanel implements PrefsTab { private boolean oldReadStatusColumn; private boolean oldSyncKeyWords; private boolean oldWriteSpecialFields; - + private final VBox listOfFileColumnsVBox; + private final ObservableList data; /** * Customization of external program paths. * @@ -98,126 +87,130 @@ class TableColumnsTab extends JPanel implements PrefsTab { public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { this.prefs = prefs; this.frame = frame; - setLayout(new BorderLayout()); - - TableModel tm = new AbstractTableModel() { - - @Override - public int getRowCount() { - return rowCount; - } - - @Override - public int getColumnCount() { - return 2; + this.data = FXCollections.observableArrayList( + new TableRow("entrytype",75), + new TableRow("author/editor",300), + new TableRow("title",470), + new TableRow("year",60), + new TableRow("journal",130), + new TableRow("bibtexkey",100)); + + colSetup = new TableView<>(); + TableColumn field= new TableColumn<>("Field name"); + TableColumn column = new TableColumn<>("Column width"); + field.setPrefWidth(400); + column.setPrefWidth(240); + field.setCellValueFactory(new PropertyValueFactory<>("name")); + field.setCellFactory(TextFieldTableCell.forTableColumn()); + field.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setName(t.getNewValue()); + }); + column.setCellValueFactory(new PropertyValueFactory<>("length")); + column.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setLength(t.getNewValue()); + }); + + colSetup.setItems(data); + colSetup.getColumns().addAll(field,column); + final TextField addName = new TextField(); + addName.setPromptText("name"); + addName.setMaxWidth(field.getPrefWidth()); + final TextField addLast = new TextField(); + addLast.setMaxWidth(column.getPrefWidth()); + addLast.setPromptText("width"); + GridPane builder = new GridPane(); + BorderPane tabPanel = new BorderPane(); + ScrollPane sp = new ScrollPane(); + sp.setContent(colSetup); + tabPanel.setCenter(sp); + + HBox toolBar = new HBox(); + Button addRow = new Button("Add"); + addRow.setOnAction( e ->{ + if (!addLast.getText().isEmpty()) { + TableRow tableRow = addLast.getText().matches("[1-9][0-9]+(.)?[0-9]+")? new TableRow(addName.getText(), Integer.valueOf(addLast.getText())):new TableRow(addName.getText()); + addName.clear(); + addLast.clear(); + data.add(tableRow); + tableRows.clear(); + tableRows.addAll(data); + rowCount++; + colSetup.setItems(data); + tableChanged = true; + colSetup.refresh(); } + }); - @Override - public Object getValueAt(int row, int column) { - int internalRow = row; - internalRow--; - if ((internalRow == -1) || (internalRow >= tableRows.size())) { - return ""; - } - - TableRow rowContent = tableRows.get(internalRow); - if (rowContent == null) { - return ""; - } - // Only two columns - if (column == 0) { - return rowContent.getName(); - } else { - return rowContent.getLength() > 0 ? Double.toString(rowContent.getLength()) : ""; + Button deleteRow = new Button("Delete"); + deleteRow.setOnAction(e->{if (colSetup.getFocusModel() != null && colSetup.getFocusModel().getFocusedIndex()!= -1) { + tableChanged = true; + int row = colSetup.getFocusModel().getFocusedIndex(); + TableRow tableRow = data.get(row); + data.remove(tableRow); + tableRows.clear(); + tableRows.addAll(data); + colSetup.setItems(data); + rowCount--; + colSetup.refresh(); + }}); + Button up = new Button("Up"); + up.setOnAction(e->{ + if(colSetup.getFocusModel()!=null) { + int row = colSetup.getFocusModel().getFocusedIndex(); + if (row > data.size() || row == 0) { + return; } + TableRow tableRow1 = data.get(row); + TableRow tableRow2 = data.get(row - 1); + data.set(row - 1, tableRow1); + data.set(row, tableRow2); + tableRows.clear(); + tableRows.addAll(data); + colSetup.setItems(data); + colSetup.refresh(); + }else { + return; } - - @Override - public String getColumnName(int col) { - return col == 0 ? Localization.lang("Field name") : Localization.lang("Column width"); - } - - @Override - public Class getColumnClass(int column) { - if (column == 0) { - return String.class; + }); + Button down = new Button("Down"); + down.setOnAction(e->{ + if(colSetup.getFocusModel()!=null) { + int row = colSetup.getFocusModel().getFocusedIndex(); + if (row + 1 > data.size()) { + return; } - return Integer.class; - } - - @Override - public boolean isCellEditable(int row, int col) { - return !((row == 0) && (col == 0)); + TableRow tableRow1 = data.get(row); + TableRow tableRow2 = data.get(row + 1); + data.set(row + 1, tableRow1); + data.set(row, tableRow2); + tableRows.clear(); + tableRows.addAll(data); + lastIndex = row + 1; + colSetup.setItems(data); + colSetup.refresh(); + }else { + return; } + }); + toolBar.getChildren().addAll(addName,addLast,addRow,deleteRow,up,down); + tabPanel.setBottom(toolBar); - @Override - public void setValueAt(Object value, int row, int col) { - tableChanged = true; - // Make sure the vector is long enough. - while (row >= tableRows.size()) { - tableRows.add(new TableRow("", -1)); - } - - TableRow rowContent = tableRows.get(row - 1); - - if (col == 0) { - rowContent.setName(value.toString()); - if ("".equals(getValueAt(row, 1))) { - setValueAt(String.valueOf(BibtexSingleField.DEFAULT_FIELD_LENGTH), row, 1); - } - } else { - if (value == null) { - rowContent.setLength(-1); - } else { - rowContent.setLength(Integer.parseInt(value.toString())); - } - } - } + fileColumn = new CheckBox(Localization.lang("Show file column")); + urlColumn = new CheckBox(Localization.lang("Show URL/DOI column")); + preferUrl = new RadioButton(Localization.lang(" Show URL first")); + preferDoi = new RadioButton(Localization.lang(" Show DOI first")); - }; - - colSetup = new JTable(tm); - TableColumnModel cm = colSetup.getColumnModel(); - cm.getColumn(0).setPreferredWidth(140); - cm.getColumn(1).setPreferredWidth(80); - - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JPanel pan = new JPanel(); - JPanel tabPanel = new JPanel(); - tabPanel.setLayout(new BorderLayout()); - JScrollPane sp = new JScrollPane(colSetup, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - colSetup.setPreferredScrollableViewportSize(new Dimension(250, 200)); - sp.setMinimumSize(new Dimension(250, 300)); - tabPanel.add(sp, BorderLayout.CENTER); - JToolBar toolBar = new OSXCompatibleToolbar(SwingConstants.VERTICAL); - toolBar.setFloatable(false); - AddRowAction addRow = new AddRowAction(); - DeleteRowAction deleteRow = new DeleteRowAction(); - MoveRowUpAction moveUp = new MoveRowUpAction(); - MoveRowDownAction moveDown = new MoveRowDownAction(); - toolBar.setBorder(null); - toolBar.add(addRow); - toolBar.add(deleteRow); - toolBar.addSeparator(); - toolBar.add(moveUp); - toolBar.add(moveDown); - tabPanel.add(toolBar, BorderLayout.EAST); - - fileColumn = new JCheckBox(Localization.lang("Show file column")); - urlColumn = new JCheckBox(Localization.lang("Show URL/DOI column")); - preferUrl = new JRadioButton(Localization.lang("Show URL first")); - preferDoi = new JRadioButton(Localization.lang("Show DOI first")); - ButtonGroup preferUrlDoiGroup = new ButtonGroup(); - preferUrlDoiGroup.add(preferUrl); - preferUrlDoiGroup.add(preferDoi); - - urlColumn.addChangeListener(arg0 -> { - preferUrl.setEnabled(urlColumn.isSelected()); - preferDoi.setEnabled(urlColumn.isSelected()); + urlColumn.setOnAction(arg0 -> { + preferUrl.setDisable(!urlColumn.isSelected()); + preferDoi.setDisable(!urlColumn.isSelected()); }); - arxivColumn = new JCheckBox(Localization.lang("Show ArXiv column")); + arxivColumn = new CheckBox(Localization.lang("Show ArXiv column")); Collection fileTypes = ExternalFileTypes.getInstance().getExternalFileTypeSelection(); String[] fileTypeNames = new String[fileTypes.size()]; @@ -225,97 +218,91 @@ public void setValueAt(Object value, int row, int col) { for (ExternalFileType fileType : fileTypes) { fileTypeNames[i++] = fileType.getName(); } - listOfFileColumns = new JList<>(fileTypeNames); - JScrollPane listOfFileColumnsScrollPane = new JScrollPane(listOfFileColumns); - listOfFileColumns.setVisibleRowCount(3); - extraFileColumns = new JCheckBox(Localization.lang("Show extra columns")); - extraFileColumns.addChangeListener(arg0 -> listOfFileColumns.setEnabled(extraFileColumns.isSelected())); + listOfFileColumns = new ListView<>(FXCollections.observableArrayList(fileTypeNames)); + listOfFileColumnsVBox = new VBox(); + listOfFileColumnsVBox.getChildren().add(listOfFileColumns); + ScrollPane listOfFileColumnsScrollPane = new ScrollPane(); + listOfFileColumnsScrollPane.setMaxHeight(80); + listOfFileColumnsScrollPane.setContent(listOfFileColumnsVBox); + extraFileColumns = new CheckBox(Localization.lang("Show extra columns")); + if(!extraFileColumns.isSelected()){ + listOfFileColumnsVBox.setDisable(true); + } + extraFileColumns.setOnAction(arg0 -> listOfFileColumnsVBox.setDisable(!extraFileColumns.isSelected())); /*** begin: special table columns and special fields ***/ - JButton helpButton = new HelpAction(Localization.lang("Help on special fields"), - HelpFile.SPECIAL_FIELDS).getHelpButton(); + Button helpButton = new Button("Help"); + helpButton.setOnAction(e->new HelpAction(Localization.lang("Help on special fields"), + HelpFile.SPECIAL_FIELDS).getHelpButton().doClick()); - rankingColumn = new JCheckBox(Localization.lang("Show rank")); - qualityColumn = new JCheckBox(Localization.lang("Show quality")); - priorityColumn = new JCheckBox(Localization.lang("Show priority")); - relevanceColumn = new JCheckBox(Localization.lang("Show relevance")); - printedColumn = new JCheckBox(Localization.lang("Show printed status")); - readStatusColumn = new JCheckBox(Localization.lang("Show read status")); + rankingColumn = new CheckBox(Localization.lang(" Show rank")); + qualityColumn = new CheckBox(Localization.lang(" Show quality")); + priorityColumn = new CheckBox(Localization.lang(" Show priority")); + relevanceColumn = new CheckBox(Localization.lang(" Show relevance")); + printedColumn = new CheckBox(Localization.lang(" Show printed status")); + readStatusColumn = new CheckBox(Localization.lang(" Show read status")); // "sync keywords" and "write special" fields may be configured mutually exclusive only // The implementation supports all combinations (TRUE+TRUE and FALSE+FALSE, even if the latter does not make sense) // To avoid confusion, we opted to make the setting mutually exclusive - syncKeywords = new JRadioButton(Localization.lang("Synchronize with keywords")); - writeSpecialFields = new JRadioButton(Localization.lang("Write values of special fields as separate fields to BibTeX")); - ButtonGroup group = new ButtonGroup(); - group.add(syncKeywords); - group.add(writeSpecialFields); - - specialFieldsEnabled = new JCheckBox(Localization.lang("Enable special fields")); - specialFieldsEnabled.addChangeListener(event -> { + syncKeywords = new RadioButton(Localization.lang(" Synchronize with keywords")); + writeSpecialFields = new RadioButton(Localization.lang(" Write values of special fields as separate fields to BibTeX")); + + specialFieldsEnabled = new CheckBox(Localization.lang("Enable special fields")); + specialFieldsEnabled.setOnAction(event -> { boolean isEnabled = specialFieldsEnabled.isSelected(); - rankingColumn.setEnabled(isEnabled); - qualityColumn.setEnabled(isEnabled); - priorityColumn.setEnabled(isEnabled); - relevanceColumn.setEnabled(isEnabled); - printedColumn.setEnabled(isEnabled); - readStatusColumn.setEnabled(isEnabled); - syncKeywords.setEnabled(isEnabled); - writeSpecialFields.setEnabled(isEnabled); + rankingColumn.setDisable(!isEnabled); + qualityColumn.setDisable(!isEnabled); + priorityColumn.setDisable(!isEnabled); + relevanceColumn.setDisable(!isEnabled); + printedColumn.setDisable(!isEnabled); + readStatusColumn.setDisable(!isEnabled); + syncKeywords.setDisable(!isEnabled); + writeSpecialFields.setDisable(!isEnabled); }); - builder.appendSeparator(Localization.lang("Special table columns")); - builder.nextLine(); - builder.append(pan); - - DefaultFormBuilder specialTableColumnsBuilder = new DefaultFormBuilder(new FormLayout( - "8dlu, 8dlu, 8cm, 8dlu, 8dlu, left:pref:grow", "pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref")); - CellConstraints cc = new CellConstraints(); - - specialTableColumnsBuilder.add(specialFieldsEnabled, cc.xyw(1, 1, 3)); - specialTableColumnsBuilder.add(rankingColumn, cc.xyw(2, 2, 2)); - specialTableColumnsBuilder.add(relevanceColumn, cc.xyw(2, 3, 2)); - specialTableColumnsBuilder.add(qualityColumn, cc.xyw(2, 4, 2)); - specialTableColumnsBuilder.add(priorityColumn, cc.xyw(2, 5, 2)); - specialTableColumnsBuilder.add(printedColumn, cc.xyw(2, 6, 2)); - specialTableColumnsBuilder.add(readStatusColumn, cc.xyw(2, 7, 2)); - specialTableColumnsBuilder.add(syncKeywords, cc.xyw(2, 10, 2)); - specialTableColumnsBuilder.add(writeSpecialFields, cc.xyw(2, 11, 2)); - specialTableColumnsBuilder.add(helpButton, cc.xyw(1, 12, 2)); - - specialTableColumnsBuilder.add(fileColumn, cc.xyw(5, 1, 2)); - specialTableColumnsBuilder.add(urlColumn, cc.xyw(5, 2, 2)); - specialTableColumnsBuilder.add(preferUrl, cc.xy(6, 3)); - specialTableColumnsBuilder.add(preferDoi, cc.xy(6, 4)); - specialTableColumnsBuilder.add(arxivColumn, cc.xyw(5, 5, 2)); - - specialTableColumnsBuilder.add(extraFileColumns, cc.xyw(5, 6, 2)); - specialTableColumnsBuilder.add(listOfFileColumnsScrollPane, cc.xywh(5, 7, 2, 6)); - - builder.append(specialTableColumnsBuilder.getPanel()); - builder.nextLine(); + builder.add(new Label(Localization.lang("Special table columns")),1,1); + + GridPane specialTableColumnsBuilder = new GridPane(); + specialTableColumnsBuilder.add(specialFieldsEnabled,1,1); + specialTableColumnsBuilder.add(rankingColumn,1,2); + specialTableColumnsBuilder.add(relevanceColumn, 1,3); + specialTableColumnsBuilder.add(qualityColumn, 1,4); + specialTableColumnsBuilder.add(priorityColumn, 1,5); + specialTableColumnsBuilder.add(printedColumn, 1,6); + specialTableColumnsBuilder.add(readStatusColumn, 1,7); + specialTableColumnsBuilder.add(syncKeywords, 1,8); + specialTableColumnsBuilder.add(writeSpecialFields, 1,9); + specialTableColumnsBuilder.add(helpButton, 1,10); + + specialTableColumnsBuilder.add(fileColumn, 2,1); + specialTableColumnsBuilder.add(urlColumn, 2,2); + specialTableColumnsBuilder.add(preferUrl,2,3); + specialTableColumnsBuilder.add(preferDoi, 2,4); + specialTableColumnsBuilder.add(arxivColumn, 2,5); + + specialTableColumnsBuilder.add(extraFileColumns,2,6); + specialTableColumnsBuilder.add(listOfFileColumnsScrollPane, 2,10); + + builder.add(specialTableColumnsBuilder,1,2); + /*** end: special table columns and special fields ***/ - builder.appendSeparator(Localization.lang("Entry table columns")); - builder.nextLine(); - builder.append(pan); - builder.append(tabPanel); - builder.nextLine(); - builder.append(pan); - JButton buttonWidth = new JButton(new UpdateWidthsAction()); - JButton buttonOrder = new JButton(new UpdateOrderAction()); - builder.append(buttonWidth); - builder.nextLine(); - builder.append(pan); - builder.append(buttonOrder); - builder.nextLine(); - builder.append(pan); - builder.nextLine(); - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + builder.add(new Label(Localization.lang("Entry table columns")),1,3); + builder.add(tabPanel,1,4); + + Button buttonWidth = new Button("Update to current column widths"); + buttonWidth.setOnAction(e->new UpdateWidthsAction()); + Button buttonOrder = new Button("Update to current column order"); + buttonOrder.setOnAction(e->new UpdateOrderAction()); + builder.add(buttonWidth,1,5); + builder.add(buttonOrder,1,6); + + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); } @Override @@ -330,20 +317,23 @@ public void setValues() { extraFileColumns.setSelected(prefs.getBoolean(JabRefPreferences.EXTRA_FILE_COLUMNS)); if (extraFileColumns.isSelected()) { List desiredColumns = prefs.getStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS); - int listSize = listOfFileColumns.getModel().getSize(); + int listSize = listOfFileColumns.getSelectionModel().getSelectedIndex(); int[] indicesToSelect = new int[listSize]; for (int i = 0; i < listSize; i++) { indicesToSelect[i] = listSize + 1; for (String desiredColumn : desiredColumns) { - if (listOfFileColumns.getModel().getElementAt(i).equals(desiredColumn)) { + if (listOfFileColumns.getAccessibleText().equals(desiredColumn)) { indicesToSelect[i] = i; break; } } } - listOfFileColumns.setSelectedIndices(indicesToSelect); + for(int i=0; i lengths = prefs.getStringList(JabRefPreferences.COLUMN_WIDTHS); for (int i = 0; i < names.size(); i++) { if (i < lengths.size()) { - tableRows.add(new TableRow(names.get(i), Double.parseDouble(lengths.get(i)))); + tableRows.add(new TableRow(names.get(i), Integer.parseInt(lengths.get(i)))); } else { tableRows.add(new TableRow(names.get(i))); } @@ -394,189 +384,43 @@ public void setValues() { /*** end: special fields ***/ - static class TableRow { + public static class TableRow { - private String name; - private double length; + private SimpleStringProperty name; + private SimpleDoubleProperty length; public TableRow() { - name = ""; - length = BibtexSingleField.DEFAULT_FIELD_LENGTH; + name = new SimpleStringProperty(""); + length = new SimpleDoubleProperty(BibtexSingleField.DEFAULT_FIELD_LENGTH); } public TableRow(String name) { - this.name = name; - length = BibtexSingleField.DEFAULT_FIELD_LENGTH; + this.name = new SimpleStringProperty(name); + length = new SimpleDoubleProperty(BibtexSingleField.DEFAULT_FIELD_LENGTH); } public TableRow(String name, double length) { - this.name = name; - this.length = length; + this.name = new SimpleStringProperty(name); + this.length = new SimpleDoubleProperty(length); } public String getName() { - return name; + return name.get(); } public void setName(String name) { - this.name = name; + this.name.set(name); } public double getLength() { - return length; - } - - public void setLength(int length) { - this.length = length; - } - } - - class DeleteRowAction extends AbstractAction { - - public DeleteRowAction() { - super("Delete row", IconTheme.JabRefIcons.REMOVE_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Delete rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = colSetup.getSelectedRows(); - if (rows.length == 0) { - return; - } - int offs = 0; - for (int i = rows.length - 1; i >= 0; i--) { - if ((rows[i] <= tableRows.size()) && (rows[i] != 0)) { - tableRows.remove(rows[i] - 1); - offs++; - } - } - rowCount -= offs; - if (rows.length > 1) { - colSetup.clearSelection(); - } - colSetup.revalidate(); - colSetup.repaint(); - tableChanged = true; - } - } - - class AddRowAction extends AbstractAction { - - public AddRowAction() { - super("Add row", IconTheme.JabRefIcons.ADD_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Insert rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = colSetup.getSelectedRows(); - if (rows.length == 0) { - // No rows selected, so we just add one at the end. - rowCount++; - colSetup.revalidate(); - colSetup.repaint(); - return; - } - for (int i = 0; i < rows.length; i++) { - if (((rows[i] + i) - 1) < tableRows.size()) { - tableRows.add(Math.max(0, (rows[i] + i) - 1), new TableRow()); - } - } - rowCount += rows.length; - if (rows.length > 1) { - colSetup.clearSelection(); - } - colSetup.revalidate(); - colSetup.repaint(); - tableChanged = true; - } - } - - abstract class AbstractMoveRowAction extends AbstractAction { - - public AbstractMoveRowAction(String string, Icon image) { - super(string, image); - } - - public void swap(int i, int j) { - if ((i < 0) || (i >= tableRows.size())) { - return; - } - if ((j < 0) || (j >= tableRows.size())) { - return; - } - TableRow tmp = tableRows.get(i); - tableRows.set(i, tableRows.get(j)); - tableRows.set(j, tmp); - } - } - - class MoveRowUpAction extends AbstractMoveRowAction { - - public MoveRowUpAction() { - super("Up", IconTheme.JabRefIcons.UP.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Move up")); + return length.get(); } - @Override - public void actionPerformed(ActionEvent e) { - int[] selected = colSetup.getSelectedRows(); - Arrays.sort(selected); - // first element (#) not inside tableRows - // don't move if a selected element is at bounce - if ((selected.length > 0) && (selected[0] > 1)) { - boolean[] newSelected = new boolean[colSetup.getRowCount()]; - for (int i : selected) { - swap(i - 1, i - 2); - newSelected[i - 1] = true; - } - // select all and remove unselected - colSetup.setRowSelectionInterval(0, colSetup.getRowCount() - 1); - for (int i = 0; i < colSetup.getRowCount(); i++) { - if (!newSelected[i]) { - colSetup.removeRowSelectionInterval(i, i); - } - } - colSetup.revalidate(); - colSetup.repaint(); - tableChanged = true; - } + public void setLength(double length) { + this.length.set(length); } } - class MoveRowDownAction extends AbstractMoveRowAction { - - public MoveRowDownAction() { - super("Down", IconTheme.JabRefIcons.DOWN.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Down")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] selected = colSetup.getSelectedRows(); - Arrays.sort(selected); - final int last = selected.length - 1; - boolean[] newSelected = new boolean[colSetup.getRowCount()]; - // don't move if a selected element is at bounce - if ((selected.length > 0) && (selected[last] < tableRows.size())) { - for (int i = last; i >= 0; i--) { - swap(selected[i] - 1, selected[i]); - newSelected[selected[i] + 1] = true; - } - // select all and remove unselected - colSetup.setRowSelectionInterval(0, colSetup.getRowCount() - 1); - for (int i = 0; i < colSetup.getRowCount(); i++) { - if (!newSelected[i]) { - colSetup.removeRowSelectionInterval(i, i); - } - } - colSetup.revalidate(); - colSetup.repaint(); - tableChanged = true; - } - } - } class UpdateOrderAction extends AbstractAction { @@ -612,8 +456,10 @@ public void actionPerformed(ActionEvent e) { return n1.compareTo(n2); }); - colSetup.revalidate(); - colSetup.repaint(); + data.clear(); + data.addAll(tableRows); + colSetup.setItems(data); + colSetup.refresh(); tableChanged = true; } } @@ -671,11 +517,13 @@ public void storeSettings() { prefs.putBoolean(JabRefPreferences.ARXIV_COLUMN, arxivColumn.isSelected()); prefs.putBoolean(JabRefPreferences.EXTRA_FILE_COLUMNS, extraFileColumns.isSelected()); - if (extraFileColumns.isSelected() && !listOfFileColumns.isSelectionEmpty()) { - int numberSelected = listOfFileColumns.getSelectedIndices().length; + if (extraFileColumns.isSelected() && !listOfFileColumns.getSelectionModel().isEmpty()) { + int numberSelected = listOfFileColumns.getSelectionModel().getSelectedIndex(); List selections = new ArrayList<>(numberSelected); for (int i = 0; i < numberSelected; i++) { - selections.add(listOfFileColumns.getModel().getElementAt(listOfFileColumns.getSelectedIndices()[i])); + if(listOfFileColumnsVBox.getChildren().get(i).isFocused()){ + selections.add(listOfFileColumnsVBox.getChildren().get(i).getAccessibleText()); + } } prefs.putStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS, selections); } else { @@ -728,11 +576,11 @@ public void storeSettings() { /*** end: special fields ***/ - if (colSetup.isEditing()) { - int col = colSetup.getEditingColumn(); - int row = colSetup.getEditingRow(); - colSetup.getCellEditor(row, col).stopCellEditing(); - } +// if (colSetup.isEditing()) { +// int col = colSetup.getEditingColumn(); +// int row = colSetup.getEditingRow(); +// colSetup.getCellEditor(row, col).stopCellEditing(); +// } // Now we need to make sense of the contents the user has made to the // table setup table. diff --git a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java index aa78b4cd65b..6ad67775e8d 100644 --- a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java @@ -1,35 +1,28 @@ package org.jabref.gui.preftabs; import java.awt.BorderLayout; -import java.awt.Dimension; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import javax.swing.AbstractAction; import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.JCheckBox; import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JToolBar; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingConstants; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumnModel; -import javax.swing.table.TableModel; -import org.jabref.gui.OSXCompatibleToolbar; +import javafx.embed.swing.JFXPanel; +import javafx.geometry.Orientation; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.layout.Border; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; +import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.icon.IconTheme; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - /** * Preference Tab for XMP. * @@ -39,12 +32,11 @@ class XmpPrefsTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; private boolean tableChanged; - private int rowCount; - - private final JTable table; - - private final JCheckBox privacyFilterCheckBox = new JCheckBox( + private final Label label = new Label(" Field to filter"); + private final ArrayList textFields= new ArrayList<>(10); + private final VBox vBox = new VBox(); + private final CheckBox privacyFilterCheckBox = new CheckBox( Localization.lang("Do not write the following fields to XMP Metadata:")); private final List tableRows = new ArrayList<>(10); @@ -57,169 +49,71 @@ public XmpPrefsTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); setLayout(new BorderLayout()); - TableModel tableModel = new AbstractTableModel() { - - @Override - public int getRowCount() { - return rowCount; - } - - @Override - public int getColumnCount() { - return 1; - } - - @Override - public Object getValueAt(int row, int column) { - if (row >= tableRows.size()) { - return ""; - } - Object rowContent = tableRows.get(row); - if (rowContent == null) { - return ""; - } - return rowContent; - } - - @Override - public String getColumnName(int col) { - return Localization.lang("Field to filter"); - } - - @Override - public Class getColumnClass(int column) { - return String.class; - } - - @Override - public boolean isCellEditable(int row, int col) { - return true; - } - - @Override - public void setValueAt(Object value, int row, int col) { - tableChanged = true; - - if (tableRows.size() <= row) { - ((ArrayList) tableRows).ensureCapacity(row + 1); - } - - tableRows.set(row, value); - } - - }; + GridPane builder = new GridPane(); - table = new JTable(tableModel); + BorderPane tablePanel = new BorderPane(); + ScrollPane scrollPane = new ScrollPane(); + scrollPane.setMaxHeight(400); + scrollPane.setMaxWidth(170); + textFields.add(new TextField("pdf")); + vBox.getChildren().add(new Label("field to filter")); + vBox.getChildren().addAll(textFields); + scrollPane.setContent(vBox); + tablePanel.setCenter(scrollPane); - TableColumnModel columnModel = table.getColumnModel(); - columnModel.getColumn(0).setPreferredWidth(140); + Button add = new Button("+"); + add.setOnAction(e->new AddRowAction()); + Button delete = new Button("-"); + delete.setOnAction(e->new DeleteRowAction()); + VBox toolbar = new VBox(add,delete); + tablePanel.setRight(toolbar); - FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - JPanel pan = new JPanel(); - - JPanel tablePanel = new JPanel(); - tablePanel.setLayout(new BorderLayout()); - JScrollPane scrollPane = new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - table.setPreferredScrollableViewportSize(new Dimension(250, 200)); - scrollPane.setMinimumSize(new Dimension(250, 300)); - tablePanel.add(scrollPane, BorderLayout.CENTER); - - JToolBar toolbar = new OSXCompatibleToolbar(SwingConstants.VERTICAL); - toolbar.setFloatable(false); - toolbar.setBorder(null); - toolbar.add(new AddRowAction()); - toolbar.add(new DeleteRowAction()); - - tablePanel.add(toolbar, BorderLayout.EAST); // Build Prefs Tabs - builder.appendSeparator(Localization.lang("XMP export privacy settings")); - builder.nextLine(); + builder.add(new Label(Localization.lang("XMP export privacy settings")),1,1); - builder.append(pan); - builder.append(privacyFilterCheckBox); - builder.nextLine(); + builder.add(privacyFilterCheckBox,1,2); - builder.append(pan); - builder.append(tablePanel); - builder.nextLine(); + builder.add(tablePanel,1,3); - pan = builder.getPanel(); - pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(pan, BorderLayout.CENTER); + JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); } - class DeleteRowAction extends AbstractAction { - - public DeleteRowAction() { - super("Delete row", IconTheme.JabRefIcons.REMOVE_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Delete rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = table.getSelectedRows(); - if (rows.length == 0) { - return; - } - - for (int i = rows.length - 1; i >= 0; i--) { - if (rows[i] < tableRows.size()) { - tableRows.remove(rows[i]); - } - } - rowCount -= rows.length; - if (rows.length > 1) { - table.clearSelection(); - } - table.revalidate(); - table.repaint(); + class DeleteRowAction{ + public DeleteRowAction(){ + textFields.remove(textFields.get(textFields.size()-1)); + rowCount--; + vBox.getChildren().clear(); + vBox.getChildren().add(new Label("field to filter")); + vBox.getChildren().addAll(textFields); tableChanged = true; } } - class AddRowAction extends AbstractAction { + class AddRowAction{ public AddRowAction() { - super("Add row", IconTheme.JabRefIcons.ADD_NOBOX.getIcon()); - putValue(Action.SHORT_DESCRIPTION, Localization.lang("Insert rows")); - } - - @Override - public void actionPerformed(ActionEvent e) { - int[] rows = table.getSelectedRows(); - if (rows.length == 0) { - // No rows selected, so we just add one at the end. - rowCount++; - table.revalidate(); - table.repaint(); - return; - } - for (int i = 0; i < rows.length; i++) { - if ((rows[i] + i) < tableRows.size()) { - tableRows.add(rows[i] + i, ""); - } - } - rowCount += rows.length; - if (rows.length > 1) { - table.clearSelection(); - } - table.revalidate(); - table.repaint(); + rowCount++; + textFields.add(new TextField("")); + vBox.getChildren().clear(); + vBox.getChildren().add(new Label("field to filter")); + vBox.getChildren().addAll(textFields); tableChanged = true; } } - - /** * Load settings from the preferences and initialize the table. */ @Override public void setValues() { tableRows.clear(); - List names = JabRefPreferences.getInstance().getStringList(JabRefPreferences.XMP_PRIVACY_FILTERS); + //List names = JabRefPreferences.getInstance().getStringList(JabRefPreferences.XMP_PRIVACY_FILTERS); + Listnames = new ArrayList<>(); + for(TextField textField:textFields){ + names.add(textField.getText()); + } tableRows.addAll(names); rowCount = tableRows.size() + 5; @@ -234,13 +128,6 @@ public void setValues() { */ @Override public void storeSettings() { - - if (table.isEditing()) { - int col = table.getEditingColumn(); - int row = table.getEditingRow(); - table.getCellEditor(row, col).stopCellEditing(); - } - // Now we need to make sense of the contents the user has made to the // table setup table. This needs to be done either if changes were made, or // if the checkbox is checked and no field values have been stored previously: diff --git a/src/main/java/org/jabref/logic/importer/ImportInspector.java b/src/main/java/org/jabref/logic/importer/ImportInspector.java deleted file mode 100644 index 80ec91e9bb5..00000000000 --- a/src/main/java/org/jabref/logic/importer/ImportInspector.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.jabref.logic.importer; - -import org.jabref.model.entry.BibEntry; - -/** - * An ImportInspector can be passed to a EntryFetcher and will receive entries - * as they are fetched from somewhere. - * - * Currently there are two implementations: ImportInspectionDialog and - * ImportInspectionCommandLine - * - */ -public interface ImportInspector { - - /** - * Notify the ImportInspector about the progress of the operation. - * - * The Inspector for instance could display a progress bar with the given - * values. - * - * @param current - * A number that is related to the work already done. - * - * @param max - * A current estimate for the total amount of work to be done. - */ - void setProgress(int current, int max); - - /** - * Add the given entry to the list of entries managed by the inspector. - * - * @param entry - * The entry to add. - */ - void addEntry(BibEntry entry); -} diff --git a/src/main/java/org/jabref/logic/importer/util/JSONEntryParser.java b/src/main/java/org/jabref/logic/importer/util/JSONEntryParser.java deleted file mode 100644 index abb5037b70a..00000000000 --- a/src/main/java/org/jabref/logic/importer/util/JSONEntryParser.java +++ /dev/null @@ -1,232 +0,0 @@ -package org.jabref.logic.importer.util; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.FieldName; -import org.jabref.model.entry.LinkedFile; -import org.jabref.model.entry.Month; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class JSONEntryParser { - - private static final Logger LOGGER = LoggerFactory.getLogger(JSONEntryParser.class); - - /** - * Convert a JSONObject containing a bibJSON entry to a BibEntry - * - * @param bibJsonEntry The JSONObject to convert - * @return the converted BibEntry - */ - public BibEntry parseBibJSONtoBibtex(JSONObject bibJsonEntry, Character keywordSeparator) { - // Fields that are directly accessible at the top level BibJson object - String[] singleFieldStrings = {FieldName.YEAR, FieldName.TITLE, FieldName.ABSTRACT, FieldName.MONTH}; - - // Fields that are accessible in the journal part of the BibJson object - String[] journalSingleFieldStrings = {FieldName.PUBLISHER, FieldName.NUMBER, FieldName.VOLUME}; - - BibEntry entry = new BibEntry(); - entry.setType("article"); - - // Authors - if (bibJsonEntry.has("author")) { - JSONArray authors = bibJsonEntry.getJSONArray("author"); - List authorList = new ArrayList<>(); - for (int i = 0; i < authors.length(); i++) { - if (authors.getJSONObject(i).has("name")) { - authorList.add(authors.getJSONObject(i).getString("name")); - } else { - LOGGER.info("Empty author name."); - } - } - entry.setField(FieldName.AUTHOR, String.join(" and ", authorList)); - } else { - LOGGER.info("No author found."); - } - - // Direct accessible fields - for (String field : singleFieldStrings) { - if (bibJsonEntry.has(field)) { - entry.setField(field, bibJsonEntry.getString(field)); - } - } - - // Page numbers - if (bibJsonEntry.has("start_page")) { - if (bibJsonEntry.has("end_page")) { - entry.setField(FieldName.PAGES, - bibJsonEntry.getString("start_page") + "--" + bibJsonEntry.getString("end_page")); - } else { - entry.setField(FieldName.PAGES, bibJsonEntry.getString("start_page")); - } - } - - // Journal - if (bibJsonEntry.has("journal")) { - JSONObject journal = bibJsonEntry.getJSONObject("journal"); - // Journal title - if (journal.has("title")) { - entry.setField(FieldName.JOURNAL, journal.getString("title").trim()); - } else { - LOGGER.info("No journal title found."); - } - // Other journal related fields - for (String field : journalSingleFieldStrings) { - if (journal.has(field)) { - entry.setField(field, journal.getString(field)); - } - } - } else { - LOGGER.info("No journal information found."); - } - - // Keywords - if (bibJsonEntry.has("keywords")) { - JSONArray keywords = bibJsonEntry.getJSONArray("keywords"); - for (int i = 0; i < keywords.length(); i++) { - if (!keywords.isNull(i)) { - entry.addKeyword(keywords.getString(i).trim(), keywordSeparator); - } - } - } - - // Identifiers - if (bibJsonEntry.has("identifier")) { - JSONArray identifiers = bibJsonEntry.getJSONArray("identifier"); - for (int i = 0; i < identifiers.length(); i++) { - String type = identifiers.getJSONObject(i).getString("type"); - if ("doi".equals(type)) { - entry.setField(FieldName.DOI, identifiers.getJSONObject(i).getString("id")); - } else if ("pissn".equals(type)) { - entry.setField(FieldName.ISSN, identifiers.getJSONObject(i).getString("id")); - } else if ("eissn".equals(type)) { - entry.setField(FieldName.ISSN, identifiers.getJSONObject(i).getString("id")); - } - } - } - - // Links - if (bibJsonEntry.has("link")) { - JSONArray links = bibJsonEntry.getJSONArray("link"); - for (int i = 0; i < links.length(); i++) { - if (links.getJSONObject(i).has("type")) { - String type = links.getJSONObject(i).getString("type"); - if ("fulltext".equals(type) && links.getJSONObject(i).has("url")) { - entry.setField(FieldName.URL, links.getJSONObject(i).getString("url")); - } - } - } - } - - return entry; - } - - /** - * Convert a JSONObject obtained from http://api.springer.com/metadata/json to a BibEntry - * - * @param springerJsonEntry the JSONObject from search results - * @return the converted BibEntry - */ - public static BibEntry parseSpringerJSONtoBibtex(JSONObject springerJsonEntry) { - // Fields that are directly accessible at the top level Json object - String[] singleFieldStrings = {FieldName.ISSN, FieldName.VOLUME, FieldName.ABSTRACT, FieldName.DOI, FieldName.TITLE, FieldName.NUMBER, - FieldName.PUBLISHER}; - - BibEntry entry = new BibEntry(); - String nametype; - - // Guess publication type - String isbn = springerJsonEntry.optString("isbn"); - if (com.google.common.base.Strings.isNullOrEmpty(isbn)) { - // Probably article - entry.setType("article"); - nametype = FieldName.JOURNAL; - } else { - // Probably book chapter or from proceeding, go for book chapter - entry.setType("incollection"); - nametype = FieldName.BOOKTITLE; - entry.setField(FieldName.ISBN, isbn); - } - - // Authors - if (springerJsonEntry.has("creators")) { - JSONArray authors = springerJsonEntry.getJSONArray("creators"); - List authorList = new ArrayList<>(); - for (int i = 0; i < authors.length(); i++) { - if (authors.getJSONObject(i).has("creator")) { - authorList.add(authors.getJSONObject(i).getString("creator")); - } else { - LOGGER.info("Empty author name."); - } - } - entry.setField(FieldName.AUTHOR, String.join(" and ", authorList)); - } else { - LOGGER.info("No author found."); - } - - // Direct accessible fields - for (String field : singleFieldStrings) { - if (springerJsonEntry.has(field)) { - String text = springerJsonEntry.getString(field); - if (!text.isEmpty()) { - entry.setField(field, text); - } - } - } - - // Page numbers - if (springerJsonEntry.has("startingPage") && !(springerJsonEntry.getString("startingPage").isEmpty())) { - if (springerJsonEntry.has("endingPage") && !(springerJsonEntry.getString("endingPage").isEmpty())) { - entry.setField(FieldName.PAGES, - springerJsonEntry.getString("startingPage") + "--" + springerJsonEntry.getString("endingPage")); - } else { - entry.setField(FieldName.PAGES, springerJsonEntry.getString("startingPage")); - } - } - - // Journal - if (springerJsonEntry.has("publicationName")) { - entry.setField(nametype, springerJsonEntry.getString("publicationName")); - } - - // Online file - if (springerJsonEntry.has("url")) { - JSONArray urls = springerJsonEntry.optJSONArray("url"); - if (urls == null) { - entry.setField(FieldName.URL, springerJsonEntry.optString("url")); - } else { - urls.forEach(data -> { - JSONObject url = (JSONObject) data; - if (url.optString("format").equalsIgnoreCase("pdf")) { - entry.addFile(new LinkedFile("online", url.optString("value"), "PDF")); - } - }); - } - } - - // Date - if (springerJsonEntry.has("publicationDate")) { - String date = springerJsonEntry.getString("publicationDate"); - entry.setField(FieldName.DATE, date); // For biblatex - String[] dateparts = date.split("-"); - entry.setField(FieldName.YEAR, dateparts[0]); - Optional month = Month.getMonthByNumber(Integer.parseInt(dateparts[1])); - month.ifPresent(entry::setMonth); - } - - // Clean up abstract (often starting with Abstract) - entry.getField(FieldName.ABSTRACT).ifPresent(abstractContents -> { - if (abstractContents.startsWith("Abstract")) { - entry.setField(FieldName.ABSTRACT, abstractContents.substring(8)); - } - }); - - return entry; - } -} diff --git a/src/test/java/org/jabref/logic/importer/util/JSONEntryParserTest.java b/src/test/java/org/jabref/logic/importer/util/JSONEntryParserTest.java deleted file mode 100644 index 86b52f2449d..00000000000 --- a/src/test/java/org/jabref/logic/importer/util/JSONEntryParserTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.jabref.logic.importer.util; - -import java.util.Optional; - -import org.jabref.model.entry.BibEntry; - -import org.json.JSONObject; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class JSONEntryParserTest { - - private final JSONEntryParser jc = new JSONEntryParser(); - - - @Test - public void testBibJSONConverter() { - String jsonString = "{\n\"title\": \"Design of Finite Word Length Linear-Phase FIR Filters in the Logarithmic Number System Domain\",\n" - + "\"journal\": {\n\"publisher\": \"Hindawi Publishing Corporation\",\n\"language\": [" - + "\"English\"],\n\"title\": \"VLSI Design\",\"country\": \"US\",\"volume\": \"2014\"" - + "},\"author\":[{\"name\": \"Syed Asad Alam\"},{\"name\": \"Oscar Gustafsson\"" - + "}\n],\n\"link\":[{\"url\": \"http://dx.doi.org/10.1155/2014/217495\"," - + "\"type\": \"fulltext\"}],\"year\":\"2014\",\"identifier\":[{" - + "\"type\": \"pissn\",\"id\": \"1065-514X\"},\n{\"type\": \"eissn\"," - + "\"id\": \"1563-5171\"},{\"type\": \"doi\",\"id\": \"10.1155/2014/217495\"" - + "}],\"created_date\":\"2014-05-09T19:38:31Z\"}\""; - JSONObject jsonObject = new JSONObject(jsonString); - BibEntry bibEntry = jc.parseBibJSONtoBibtex(jsonObject, ','); - - assertEquals("article", bibEntry.getType()); - assertEquals(Optional.of("VLSI Design"), bibEntry.getField("journal")); - assertEquals(Optional.of("10.1155/2014/217495"), bibEntry.getField("doi")); - assertEquals(Optional.of("Syed Asad Alam and Oscar Gustafsson"), bibEntry.getField("author")); - assertEquals( - Optional.of( - "Design of Finite Word Length Linear-Phase FIR Filters in the Logarithmic Number System Domain"), - bibEntry.getField("title")); - assertEquals(Optional.of("2014"), bibEntry.getField("year")); - } - - @Test - public void testSpringerJSONToBibtex() { - String jsonString = "{\r\n" + " \"identifier\":\"doi:10.1007/BF01201962\",\r\n" - + " \"title\":\"Book reviews\",\r\n" - + " \"publicationName\":\"World Journal of Microbiology & Biotechnology\",\r\n" - + " \"issn\":\"1573-0972\",\r\n" + " \"isbn\":\"\",\r\n" - + " \"doi\":\"10.1007/BF01201962\",\r\n" + " \"publisher\":\"Springer\",\r\n" - + " \"publicationDate\":\"1992-09-01\",\r\n" + " \"volume\":\"8\",\r\n" - + " \"number\":\"5\",\r\n" + " \"startingPage\":\"550\",\r\n" - + " \"url\":\"http://dx.doi.org/10.1007/BF01201962\",\"copyright\":\"©1992 Rapid Communications of Oxford Ltd.\"\r\n" - + " }"; - - JSONObject jsonObject = new JSONObject(jsonString); - BibEntry bibEntry = JSONEntryParser.parseSpringerJSONtoBibtex(jsonObject); - assertEquals(Optional.of("1992"), bibEntry.getField("year")); - assertEquals(Optional.of("5"), bibEntry.getField("number")); - assertEquals(Optional.of("#sep#"), bibEntry.getField("month")); - assertEquals(Optional.of("10.1007/BF01201962"), bibEntry.getField("doi")); - assertEquals(Optional.of("8"), bibEntry.getField("volume")); - assertEquals(Optional.of("Springer"), bibEntry.getField("publisher")); - assertEquals(Optional.of("1992-09-01"), bibEntry.getField("date")); - } - -} diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml deleted file mode 100644 index 8c6a336420a..00000000000 --- a/src/test/resources/log4j2.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - From 99caee86f7b6d01e8bb42ef50eecd8320571b9c4 Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Tue, 7 Aug 2018 22:04:34 +0800 Subject: [PATCH 03/58] Change the code style to meet the standard --- .../BibtexKeyPatternPanel.java | 14 ++++- .../org/jabref/gui/preftabs/AdvancedTab.java | 13 ++-- .../gui/preftabs/BibtexKeyPatternPrefTab.java | 3 +- .../gui/preftabs/EntryEditorPrefsTab.java | 11 +++- .../gui/preftabs/ExportSortingPrefsTab.java | 8 ++- .../org/jabref/gui/preftabs/ExternalTab.java | 32 ++++------ .../java/org/jabref/gui/preftabs/FileTab.java | 18 +++--- .../org/jabref/gui/preftabs/GeneralTab.java | 18 ++++-- .../gui/preftabs/ImportSettingsTab.java | 12 ++-- .../jabref/gui/preftabs/NameFormatterTab.java | 31 +++++----- .../org/jabref/gui/preftabs/NetworkTab.java | 14 +++-- .../jabref/gui/preftabs/TableColumnsTab.java | 62 ++++++++++--------- .../jabref/gui/preftabs/TablePrefsTab.java | 24 ++++--- .../org/jabref/gui/preftabs/XmpPrefsTab.java | 27 ++++---- 14 files changed, 163 insertions(+), 124 deletions(-) diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java index 9fa6a93bbcf..9f80d4a6857 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java @@ -18,8 +18,18 @@ import org.jabref.model.entry.EntryType; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import java.awt.*; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.JScrollPane; import java.util.HashMap; import java.util.Locale; import java.util.Map; diff --git a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java index 46dad750895..7320b002346 100644 --- a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java @@ -1,15 +1,22 @@ package org.jabref.gui.preftabs; +import java.awt.BorderLayout; +import java.util.Optional; + import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.control.Button; -import javafx.scene.control.*; +import javafx.scene.control.CheckBox; import javafx.scene.control.Label; +import javafx.scene.control.Separator; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.shape.Line; + +import javax.swing.JPanel; + import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.customjfx.CustomJFXPanel; @@ -23,9 +30,7 @@ import org.jabref.logic.remote.RemoteUtil; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import java.awt.*; -import java.util.Optional; + class AdvancedTab extends JPanel implements PrefsTab { diff --git a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java index 5cd1f3a54c5..fbe33c9dad0 100644 --- a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java +++ b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java @@ -7,6 +7,7 @@ import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.bibtexkeypattern.BibtexKeyPatternPanel; @@ -15,7 +16,7 @@ import org.jabref.model.bibtexkeypattern.GlobalBibtexKeyPattern; import org.jabref.preferences.JabRefPreferences; -import java.awt.*; +import java.awt.BorderLayout; /** * The Preferences panel for key generation. diff --git a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java index 4bb29b27710..913684fd533 100644 --- a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java @@ -1,11 +1,18 @@ package org.jabref.gui.preftabs; +import java.awt.BorderLayout; + import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; -import javafx.scene.control.*; +import javafx.scene.control.CheckBox; import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.Separator; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; + +import javax.swing.JPanel; + import org.jabref.gui.autocompleter.AutoCompleteFirstNameMode; import org.jabref.gui.autocompleter.AutoCompletePreferences; import org.jabref.gui.customjfx.CustomJFXPanel; @@ -13,8 +20,6 @@ import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import java.awt.*; import static org.jabref.gui.autocompleter.AutoCompleteFirstNameMode.ONLY_ABBREVIATED; import static org.jabref.gui.autocompleter.AutoCompleteFirstNameMode.ONLY_FULL; diff --git a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java index 400b994a096..228c51f91f9 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java @@ -1,5 +1,7 @@ package org.jabref.gui.preftabs; +import java.awt.BorderLayout; + import javafx.embed.swing.JFXPanel; import javafx.event.EventHandler; import javafx.scene.Scene; @@ -8,14 +10,14 @@ import javafx.scene.control.Separator; import javafx.scene.layout.GridPane; import javafx.scene.shape.Line; + +import javax.swing.JPanel; + import org.jabref.gui.SaveOrderConfigDisplay; import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import javax.swing.border.Border; -import java.awt.*; /** * Preference tab for file sorting options. diff --git a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java index 6ef60d1e6a3..5434a020ed5 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java @@ -1,26 +1,19 @@ package org.jabref.gui.preftabs; import java.awt.BorderLayout; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.GridLayout; -import java.awt.Insets; - -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; import javafx.embed.swing.JFXPanel; -import javafx.scene.Node; import javafx.scene.Scene; -import javafx.scene.control.*; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; + +import javax.swing.JPanel; +import javax.swing.JFileChooser; + import org.jabref.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.customjfx.CustomJFXPanel; @@ -33,9 +26,6 @@ import org.jabref.logic.util.OS; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - class ExternalTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; @@ -121,7 +111,7 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere GridPane butpan = new GridPane(); int index = 0; - for (PushToApplication pushToApplication : frame.getPushApplications().getApplications()){ + for (PushToApplication pushToApplication : frame.getPushApplications().getApplications()) { addSettingsButton(pushToApplication, butpan, index); index++; } @@ -154,7 +144,7 @@ private void addSettingsButton(final PushToApplication application, GridPane pan PushToApplicationSettings settings = PushToApplications.getSettings(application); Button button = new Button(Localization.lang("Settings for %0", application.getApplicationName())); button.setOnAction(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, settings)); - panel.add(button,index%2==0?1:2,index/2+1); + panel.add(button,index % 2==0?1:2,index/2+1); } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/FileTab.java b/src/main/java/org/jabref/gui/preftabs/FileTab.java index d6cc6adb4a4..47bbceb0663 100644 --- a/src/main/java/org/jabref/gui/preftabs/FileTab.java +++ b/src/main/java/org/jabref/gui/preftabs/FileTab.java @@ -1,13 +1,23 @@ package org.jabref.gui.preftabs; +import java.awt.BorderLayout; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + import javafx.collections.FXCollections; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.control.Button; -import javafx.scene.control.*; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; + +import javax.swing.JPanel; + import org.jabref.gui.DialogService; import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; @@ -20,12 +30,6 @@ import org.jabref.model.metadata.FileDirectoryPreferences; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import java.awt.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - /** * Preferences tab for file options. These options were moved out from GeneralTab to * resolve the space issue. diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index 8db668a6ba7..675ea40df68 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -1,15 +1,24 @@ package org.jabref.gui.preftabs; +import java.awt.BorderLayout; +import java.nio.charset.Charset; +import java.time.format.DateTimeFormatter; + import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.control.Button; -import javafx.scene.control.*; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; import javafx.scene.control.Label; +import javafx.scene.control.Separator; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import javafx.scene.shape.Line; + +import javax.swing.JPanel; + import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.customjfx.CustomJFXPanel; @@ -22,10 +31,7 @@ import org.jabref.model.entry.InternalBibtexFields; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import java.awt.*; -import java.nio.charset.Charset; -import java.time.format.DateTimeFormatter; + import static org.jabref.logic.l10n.Languages.LANGUAGES; @@ -67,7 +73,7 @@ public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { updateTimeStamp = new CheckBox(Localization.lang(" Update timestamp on modification")); useTimeStamp = new CheckBox(Localization.lang("Mark new entries with addition date") + ". " + Localization.lang("Date format") + ':'); - if(!useTimeStamp.isSelected()){ + if (!useTimeStamp.isSelected()){ updateTimeStamp.setDisable(true); } useTimeStamp.setOnAction(e->updateTimeStamp.setDisable(!useTimeStamp.isSelected())); diff --git a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java index 9218b0e753d..00c0bf2a66d 100644 --- a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java @@ -1,17 +1,21 @@ package org.jabref.gui.preftabs; -import java.awt.*; +import java.awt.BorderLayout; import java.util.Objects; -import javax.swing.JPanel; - import javafx.collections.FXCollections; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; -import javafx.scene.control.*; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.RadioButton; +import javafx.scene.control.Separator; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; + +import javax.swing.JPanel; + import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.pdfimport.ImportDialog; diff --git a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java index 5d2f72dac45..9ca575b7a86 100644 --- a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java @@ -1,20 +1,29 @@ package org.jabref.gui.preftabs; +import java.util.ArrayList; +import java.awt.BorderLayout; +import java.util.List; +import java.util.Objects; + import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.Button; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; -import javafx.scene.control.*; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; import javafx.scene.control.TextField; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; +import javafx.scene.Scene; + +import javax.swing.JPanel; + import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.logic.help.HelpFile; @@ -22,22 +31,14 @@ import org.jabref.logic.layout.format.NameFormatter; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import java.awt.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - public class NameFormatterTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; private boolean tableChanged; - private final TableView table; - private int rowCount = -1; - private final List tableRows = new ArrayList<>(10); + private final ObservableList data = FXCollections.observableArrayList(); public static class TableRow { @@ -73,7 +74,7 @@ public void setFormat(String format) { this.format.set(format); } } - private final ObservableList data = FXCollections.observableArrayList(); + /** * Tab to create custom Name Formatters @@ -137,7 +138,7 @@ public NameFormatterTab(JabRefPreferences prefs) { } }); Button delete = new Button("Delete"); - delete.setOnAction(e->{if (table.getFocusModel() != null && table.getFocusModel().getFocusedIndex()!= -1) { + delete.setOnAction(e-> {if (table.getFocusModel() != null && table.getFocusModel().getFocusedIndex()!= -1) { tableChanged = true; int row = table.getFocusModel().getFocusedIndex(); TableRow tableRow = tableRows.get(row); diff --git a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java index 7f3d31a206b..32b0675d175 100644 --- a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java @@ -1,12 +1,19 @@ package org.jabref.gui.preftabs; +import java.awt.BorderLayout; + import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; -import javafx.scene.control.*; +import javafx.scene.control.CheckBox; import javafx.scene.control.Label; +import javafx.scene.control.PasswordField; +import javafx.scene.control.Separator; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import javafx.scene.paint.Paint; +import javafx.scene.Scene; + +import javax.swing.JPanel; + import org.jabref.gui.DialogService; import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.util.DefaultTaskExecutor; @@ -15,9 +22,6 @@ import org.jabref.logic.net.ProxyRegisterer; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import java.awt.*; - public class NetworkTab extends JPanel implements PrefsTab { private final CheckBox useProxyCheckBox; diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index f1c28a49733..8018f2e27f0 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -1,15 +1,28 @@ package org.jabref.gui.preftabs; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Locale; +import java.util.List; + import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.Button; -import javafx.scene.control.*; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ListView; import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableView; +import javafx.scene.control.TableColumn; import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.control.cell.TextFieldTableCell; @@ -17,6 +30,11 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; +import javafx.scene.Scene; + +import javax.swing.AbstractAction; +import javax.swing.JPanel; + import org.jabref.gui.BasePanel; import org.jabref.gui.JabRefFrame; import org.jabref.gui.customjfx.CustomJFXPanel; @@ -31,12 +49,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.util.*; -import java.util.List; - class TableColumnsTab extends JPanel implements PrefsTab { private static final Logger LOGGER = LoggerFactory.getLogger(TableColumnsTab.class); @@ -57,7 +69,6 @@ class TableColumnsTab extends JPanel implements PrefsTab { private final RadioButton preferUrl; private final RadioButton preferDoi; - private int lastIndex; /*** begin: special fields ***/ private final CheckBox specialFieldsEnabled; private final CheckBox rankingColumn; @@ -96,7 +107,7 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { new TableRow("bibtexkey",100)); colSetup = new TableView<>(); - TableColumn field= new TableColumn<>("Field name"); + TableColumn field = new TableColumn<>("Field name"); TableColumn column = new TableColumn<>("Column width"); field.setPrefWidth(400); column.setPrefWidth(240); @@ -132,9 +143,9 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { HBox toolBar = new HBox(); Button addRow = new Button("Add"); - addRow.setOnAction( e ->{ + addRow.setOnAction( e -> { if (!addLast.getText().isEmpty()) { - TableRow tableRow = addLast.getText().matches("[1-9][0-9]+(.)?[0-9]+")? new TableRow(addName.getText(), Integer.valueOf(addLast.getText())):new TableRow(addName.getText()); + TableRow tableRow = addLast.getText().matches("[1-9][0-9]+(.) ?[0-9]+")? new TableRow(addName.getText(), Integer.valueOf(addLast.getText())):new TableRow(addName.getText()); addName.clear(); addLast.clear(); data.add(tableRow); @@ -148,7 +159,7 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { }); Button deleteRow = new Button("Delete"); - deleteRow.setOnAction(e->{if (colSetup.getFocusModel() != null && colSetup.getFocusModel().getFocusedIndex()!= -1) { + deleteRow.setOnAction(e -> {if (colSetup.getFocusModel() != null && colSetup.getFocusModel().getFocusedIndex()!= -1) { tableChanged = true; int row = colSetup.getFocusModel().getFocusedIndex(); TableRow tableRow = data.get(row); @@ -160,8 +171,8 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { colSetup.refresh(); }}); Button up = new Button("Up"); - up.setOnAction(e->{ - if(colSetup.getFocusModel()!=null) { + up.setOnAction(e-> { + if (colSetup.getFocusModel()!=null) { int row = colSetup.getFocusModel().getFocusedIndex(); if (row > data.size() || row == 0) { return; @@ -174,13 +185,13 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { tableRows.addAll(data); colSetup.setItems(data); colSetup.refresh(); - }else { + } else { return; } }); Button down = new Button("Down"); - down.setOnAction(e->{ - if(colSetup.getFocusModel()!=null) { + down.setOnAction(e-> { + if (colSetup.getFocusModel()!=null) { int row = colSetup.getFocusModel().getFocusedIndex(); if (row + 1 > data.size()) { return; @@ -191,10 +202,9 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { data.set(row, tableRow2); tableRows.clear(); tableRows.addAll(data); - lastIndex = row + 1; colSetup.setItems(data); colSetup.refresh(); - }else { + } else { return; } }); @@ -225,7 +235,7 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { listOfFileColumnsScrollPane.setMaxHeight(80); listOfFileColumnsScrollPane.setContent(listOfFileColumnsVBox); extraFileColumns = new CheckBox(Localization.lang("Show extra columns")); - if(!extraFileColumns.isSelected()){ + if (!extraFileColumns.isSelected()){ listOfFileColumnsVBox.setDisable(true); } extraFileColumns.setOnAction(arg0 -> listOfFileColumnsVBox.setDisable(!extraFileColumns.isSelected())); @@ -328,7 +338,7 @@ public void setValues() { } } } - for(int i=0; i selections = new ArrayList<>(numberSelected); - for (int i = 0; i < numberSelected; i++) { - if(listOfFileColumnsVBox.getChildren().get(i).isFocused()){ - selections.add(listOfFileColumnsVBox.getChildren().get(i).getAccessibleText()); - } - } + ObservableList selections = listOfFileColumns.getSelectionModel().getSelectedItems(); prefs.putStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS, selections); } else { prefs.putStringList(JabRefPreferences.LIST_OF_FILE_COLUMNS, new ArrayList<>()); diff --git a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java index 8667581a2a6..dd8389215f1 100644 --- a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java @@ -1,12 +1,23 @@ package org.jabref.gui.preftabs; +import java.awt.BorderLayout; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Objects; + import javafx.collections.FXCollections; import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; -import javafx.scene.control.*; -import javafx.scene.control.Label; +import javafx.scene.control.CheckBox; +import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; import javafx.scene.layout.GridPane; +import javafx.scene.Scene; + +import javax.swing.JPanel; + import org.jabref.Globals; import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; @@ -14,13 +25,6 @@ import org.jabref.model.entry.InternalBibtexFields; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import java.awt.*; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Objects; - class TablePrefsTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; diff --git a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java index 6ad67775e8d..5c9f2f95619 100644 --- a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java @@ -1,25 +1,25 @@ package org.jabref.gui.preftabs; import java.awt.BorderLayout; -import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import javax.swing.Action; import javax.swing.JPanel; import javafx.embed.swing.JFXPanel; -import javafx.geometry.Orientation; -import javafx.scene.Scene; -import javafx.scene.control.*; -import javafx.scene.layout.Border; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; +import javafx.scene.Scene; + import org.jabref.gui.customjfx.CustomJFXPanel; -import org.jabref.gui.icon.IconTheme; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -33,8 +33,7 @@ class XmpPrefsTab extends JPanel implements PrefsTab { private final JabRefPreferences prefs; private boolean tableChanged; private int rowCount; - private final Label label = new Label(" Field to filter"); - private final ArrayList textFields= new ArrayList<>(10); + private final ArrayList textFields = new ArrayList<>(10); private final VBox vBox = new VBox(); private final CheckBox privacyFilterCheckBox = new CheckBox( Localization.lang("Do not write the following fields to XMP Metadata:")); @@ -81,9 +80,9 @@ public XmpPrefsTab(JabRefPreferences prefs) { add(panel, BorderLayout.CENTER); } - class DeleteRowAction{ - public DeleteRowAction(){ - textFields.remove(textFields.get(textFields.size()-1)); + class DeleteRowAction { + public DeleteRowAction() { + textFields.remove(textFields.get(textFields.size() - 1)); rowCount--; vBox.getChildren().clear(); vBox.getChildren().add(new Label("field to filter")); @@ -92,7 +91,7 @@ public DeleteRowAction(){ } } - class AddRowAction{ + class AddRowAction { public AddRowAction() { rowCount++; @@ -111,7 +110,7 @@ public void setValues() { tableRows.clear(); //List names = JabRefPreferences.getInstance().getStringList(JabRefPreferences.XMP_PRIVACY_FILTERS); Listnames = new ArrayList<>(); - for(TextField textField:textFields){ + for (TextField textField : textFields){ names.add(textField.getText()); } tableRows.addAll(names); From 70d304fb9fb579745c6983133e711ab40ac0bb46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?1160300311=E6=B1=A4=E5=98=89=E7=90=A6?= <36810099+1160300311@users.noreply.github.com> Date: Tue, 7 Aug 2018 22:21:41 +0800 Subject: [PATCH 04/58] Update CHANGELOG.md --- CHANGELOG.md | 393 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 260 insertions(+), 133 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9c02b1e1aa..ecfe75729ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,133 +1,260 @@ -<<<<<<< HEAD -# Changelog All notable changes to this project will be documented in this file. This project **does not** adhere to [Semantic Versioning](http://semver.org/). This file tries to follow the conventions proposed by [keepachangelog.com](http://keepachangelog.com/). Here, the categories "Changed" for added and changed functionality, "Fixed" for fixed functionality, and "Removed" for removed functionality are used. We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#NUM`. ## [Unreleased] ### Changed - We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) - Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) - We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) - The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. - We added a button in the tab header which allows you to close the database with one click. https://github.com/JabRef/jabref/issues/494 - Sorting in the main table now takes information from cross-referenced entries into account. https://github.com/JabRef/jabref/issues/2808 - If a group has a color specified, then entries matched by this group have a small colored bar in front of them in the main table. - Change default icon for groups to a circle because a colored version of the old icon was hard to distinguish from its black counterpart. - In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) - We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. - We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). - We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. - Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. - Window state is saved on close and restored on start. - We streamlined the process to rename and move files by removing the confirmation dialogs. - We convert some of the Swing Dialogs to javaFX. https://github.com/JabRef/jabref/issues/3861 ### Fixed - We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) - Italic text is now rendered correctly. https://github.com/JabRef/jabref/issues/3356 - The entry editor no longer gets corrupted after using the source tab. https://github.com/JabRef/jabref/issues/3532 https://github.com/JabRef/jabref/issues/3608 https://github.com/JabRef/jabref/issues/3616 - We fixed multiple issues where entries did not show up after import if a search was active. https://github.com/JabRef/jabref/issues/1513 https://github.com/JabRef/jabref/issues/3219 - We fixed an issue where the group tree was not updated correctly after an entry was changed. https://github.com/JabRef/jabref/issues/3618 - We fixed an issue where a right-click in the main table selected a wrong entry. https://github.com/JabRef/jabref/issues/3267 - We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 - We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 - We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 - We fixed an issue where commands followed by `-` didn't work. [#3805](https://github.com/JabRef/jabref/issues/3805) - We fixed an issue where some journal names were wrongly marked as abbreviated. [#4115](https://github.com/JabRef/jabref/issues/4115) - We fixed an issue where the custom file column were sorted incorrectly. https://github.com/JabRef/jabref/issues/3119 - We fixed an issues where the entry losses focus when a field is edited and at the same time used for sorting. https://github.com/JabRef/jabref/issues/3373 - We fixed an issue where the menu on Mac OS was not displayed in the usual Mac-specific way. https://github.com/JabRef/jabref/issues/3146 - We fixed an issue where the order of fields in customized entry types was not saved correctly. [#4033](http://github.com/JabRef/jabref/issues/4033) - We fixed an issue where the groups tree of the last database was still shown even after the database was already closed. - We fixed an issue where the "Open file dialog" may disappear behind other windows. https://github.com/JabRef/jabref/issues/3410 - We fixed an issue where the default icon of a group was not colored correctly. - We fixed an issue where the first field in entry editor was not focused when adding a new entry. [#4024](https://github.com/JabRef/jabref/issues/4024) - We reworked the "Edit file" dialog to make it resizeable and improved the workflow for adding and editing files https://github.com/JabRef/jabref/issues/2970 - We fixed an issue where the month was not shown in the preview https://github.com/JabRef/jabref/issues/3239. - Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) - We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) - We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) - We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) ### Removed - The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. - The number column was removed. - We removed the coloring of cells in the maintable according to whether the field is optional/required. - We removed a few commands from the right-click menu that are not needed often and thus don't need to be placed that prominently: - Print entry preview: available through entry preview - All commands related to marking: marking is not yet reimplemented - Set/clear/append/rename fields: available through Edit menu - Manage keywords: available through Edit menu - Copy linked files to folder: available through File menu ## Older versions The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). [Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD [4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 [4.2]: https://github.com/JabRef/jabref/compare/v4.1...v4.2 [4.1]: https://github.com/JabRef/jabref/compare/v4.0...v4.1 [4.0]: https://github.com/JabRef/jabref/compare/v4.0-beta3...v4.0 [4.0-beta3]: https://github.com/JabRef/jabref/compare/v4.0-beta2...v4.0-beta3 [4.0-beta2]: https://github.com/JabRef/jabref/compare/v4.0-beta...v4.0-beta2 [4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta [2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 [JavaFX]: https://en.wikipedia.org/wiki/JavaFX -======= -# Changelog -All notable changes to this project will be documented in this file. -This project **does not** adhere to [Semantic Versioning](http://semver.org/). -This file tries to follow the conventions proposed by [keepachangelog.com](http://keepachangelog.com/). -Here, the categories "Changed" for added and changed functionality, -"Fixed" for fixed functionality, and -"Removed" for removed functionality are used. - -We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#NUM`. - -## [Unreleased] - -### Changed -- We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) -- Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) -- We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) -- The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. -- We added a button in the tab header which allows you to close the database with one click. https://github.com/JabRef/jabref/issues/494 -- Sorting in the main table now takes information from cross-referenced entries into account. https://github.com/JabRef/jabref/issues/2808 -- If a group has a color specified, then entries matched by this group have a small colored bar in front of them in the main table. -- Change default icon for groups to a circle because a colored version of the old icon was hard to distinguish from its black counterpart. -- In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) -- We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. -- We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). -- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. -- Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. -- Window state is saved on close and restored on start. -- Files without a defined external file type are now directly opened with the default aplication of the operating system -- We streamlined the process to rename and move files by removing the confirmation dialogs. - - - - - - - -### Fixed -- We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) -- Italic text is now rendered correctly. https://github.com/JabRef/jabref/issues/3356 -- The entry editor no longer gets corrupted after using the source tab. https://github.com/JabRef/jabref/issues/3532 https://github.com/JabRef/jabref/issues/3608 https://github.com/JabRef/jabref/issues/3616 -- We fixed multiple issues where entries did not show up after import if a search was active. https://github.com/JabRef/jabref/issues/1513 https://github.com/JabRef/jabref/issues/3219 -- We fixed an issue where the group tree was not updated correctly after an entry was changed. https://github.com/JabRef/jabref/issues/3618 -- We fixed an issue where a right-click in the main table selected a wrong entry. https://github.com/JabRef/jabref/issues/3267 -- We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 -- We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 -- We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 -- We fixed an issue where commands followed by `-` didn't work. [#3805](https://github.com/JabRef/jabref/issues/3805) -- We fixed an issue where some journal names were wrongly marked as abbreviated. [#4115](https://github.com/JabRef/jabref/issues/4115) -- We fixed an issue where the custom file column were sorted incorrectly. https://github.com/JabRef/jabref/issues/3119 -- We fixed an issues where the entry losses focus when a field is edited and at the same time used for sorting. https://github.com/JabRef/jabref/issues/3373 -- We fixed an issue where the menu on Mac OS was not displayed in the usual Mac-specific way. https://github.com/JabRef/jabref/issues/3146 -- We fixed an issue where the order of fields in customized entry types was not saved correctly. [#4033](http://github.com/JabRef/jabref/issues/4033) -- We fixed an issue where the groups tree of the last database was still shown even after the database was already closed. -- We fixed an issue where the "Open file dialog" may disappear behind other windows. https://github.com/JabRef/jabref/issues/3410 -- We fixed an issue where the default icon of a group was not colored correctly. -- We fixed an issue where the first field in entry editor was not focused when adding a new entry. [#4024](https://github.com/JabRef/jabref/issues/4024) -- We reworked the "Edit file" dialog to make it resizeable and improved the workflow for adding and editing files https://github.com/JabRef/jabref/issues/2970 -- We fixed an issue where the month was not shown in the preview https://github.com/JabRef/jabref/issues/3239. -- Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) -- We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) -- We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) -- We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) -- We fixed an issue where filles added via the "Attach file" contextmenu of an entry were not made relative. [#4201](https://github.com/JabRef/jabref/issues/4201) - - - - - - - - - - -### Removed -- The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. -- The number column was removed. -- We removed the coloring of cells in the maintable according to whether the field is optional/required. -- We removed a few commands from the right-click menu that are not needed often and thus don't need to be placed that prominently: - - Print entry preview: available through entry preview - - All commands related to marking: marking is not yet reimplemented - - Set/clear/append/rename fields: available through Edit menu - - Manage keywords: available through Edit menu - - Copy linked files to folder: available through File menu - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## Older versions - -The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). -The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). -The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). - -[Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD -[4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 -[4.2]: https://github.com/JabRef/jabref/compare/v4.1...v4.2 -[4.1]: https://github.com/JabRef/jabref/compare/v4.0...v4.1 -[4.0]: https://github.com/JabRef/jabref/compare/v4.0-beta3...v4.0 -[4.0-beta3]: https://github.com/JabRef/jabref/compare/v4.0-beta2...v4.0-beta3 -[4.0-beta2]: https://github.com/JabRef/jabref/compare/v4.0-beta...v4.0-beta2 -[4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta -[2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 -[JavaFX]: https://en.wikipedia.org/wiki/JavaFX ->>>>>>> 077fdacc2ddc7beb7d22ba96ead8b400c91b3631 +<<<<<<< HEAD +# Changelog +All notable changes to this project will be documented in this file. +This project **does not** adhere to [Semantic Versioning](http://semver.org/). +This file tries to follow the conventions proposed by [keepachangelog.com](http://keepachangelog.com/). +Here, the categories "Changed" for added and changed functionality, +"Fixed" for fixed functionality, and +"Removed" for removed functionality are used. + +We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#NUM`. + +## [Unreleased] + +### Changed +- We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) +- Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) +- We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) +- The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. +- We added a button in the tab header which allows you to close the database with one click. https://github.com/JabRef/jabref/issues/494 +- Sorting in the main table now takes information from cross-referenced entries into account. https://github.com/JabRef/jabref/issues/2808 +- If a group has a color specified, then entries matched by this group have a small colored bar in front of them in the main table. +- Change default icon for groups to a circle because a colored version of the old icon was hard to distinguish from its black counterpart. +- In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) +- We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. +- We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). +- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. +- Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. +- Window state is saved on close and restored on start. +- We streamlined the process to rename and move files by removing the confirmation dialogs. + + + + + + +### Fixed +- We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) +- Italic text is now rendered correctly. https://github.com/JabRef/jabref/issues/3356 +- The entry editor no longer gets corrupted after using the source tab. https://github.com/JabRef/jabref/issues/3532 https://github.com/JabRef/jabref/issues/3608 https://github.com/JabRef/jabref/issues/3616 +- We fixed multiple issues where entries did not show up after import if a search was active. https://github.com/JabRef/jabref/issues/1513 https://github.com/JabRef/jabref/issues/3219 +- We fixed an issue where the group tree was not updated correctly after an entry was changed. https://github.com/JabRef/jabref/issues/3618 +- We fixed an issue where a right-click in the main table selected a wrong entry. https://github.com/JabRef/jabref/issues/3267 +- We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 +- We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 +- We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 +- We fixed an issue where commands followed by `-` didn't work. [#3805](https://github.com/JabRef/jabref/issues/3805) +- We fixed an issue where some journal names were wrongly marked as abbreviated. [#4115](https://github.com/JabRef/jabref/issues/4115) +- We fixed an issue where the custom file column were sorted incorrectly. https://github.com/JabRef/jabref/issues/3119 +- We fixed an issues where the entry losses focus when a field is edited and at the same time used for sorting. https://github.com/JabRef/jabref/issues/3373 +- We fixed an issue where the menu on Mac OS was not displayed in the usual Mac-specific way. https://github.com/JabRef/jabref/issues/3146 +- We fixed an issue where the order of fields in customized entry types was not saved correctly. [#4033](http://github.com/JabRef/jabref/issues/4033) +- We fixed an issue where the groups tree of the last database was still shown even after the database was already closed. +- We fixed an issue where the "Open file dialog" may disappear behind other windows. https://github.com/JabRef/jabref/issues/3410 +- We fixed an issue where the default icon of a group was not colored correctly. +- We fixed an issue where the first field in entry editor was not focused when adding a new entry. [#4024](https://github.com/JabRef/jabref/issues/4024) +- We reworked the "Edit file" dialog to make it resizeable and improved the workflow for adding and editing files https://github.com/JabRef/jabref/issues/2970 +- We fixed an issue where the month was not shown in the preview https://github.com/JabRef/jabref/issues/3239. +- Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) +- We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) +- We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) +- We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) + + + + + + + + + + + +### Removed +- The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. +- The number column was removed. +- We removed the coloring of cells in the maintable according to whether the field is optional/required. +- We removed a few commands from the right-click menu that are not needed often and thus don't need to be placed that prominently: + - Print entry preview: available through entry preview + - All commands related to marking: marking is not yet reimplemented + - Set/clear/append/rename fields: available through Edit menu + - Manage keywords: available through Edit menu + - Copy linked files to folder: available through File menu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Older versions + +The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). +The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). +The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). + +[Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD +[4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 +[4.2]: https://github.com/JabRef/jabref/compare/v4.1...v4.2 +[4.1]: https://github.com/JabRef/jabref/compare/v4.0...v4.1 +[4.0]: https://github.com/JabRef/jabref/compare/v4.0-beta3...v4.0 +[4.0-beta3]: https://github.com/JabRef/jabref/compare/v4.0-beta2...v4.0-beta3 +[4.0-beta2]: https://github.com/JabRef/jabref/compare/v4.0-beta...v4.0-beta2 +[4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta +[2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 +[JavaFX]: https://en.wikipedia.org/wiki/JavaFX + +======= +# Changelog +All notable changes to this project will be documented in this file. +This project **does not** adhere to [Semantic Versioning](http://semver.org/). +This file tries to follow the conventions proposed by [keepachangelog.com](http://keepachangelog.com/). +Here, the categories "Changed" for added and changed functionality, +"Fixed" for fixed functionality, and +"Removed" for removed functionality are used. + +We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#NUM`. + +## [Unreleased] + +### Changed +- We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) +- Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) +- We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) +- The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. +- We added a button in the tab header which allows you to close the database with one click. https://github.com/JabRef/jabref/issues/494 +- Sorting in the main table now takes information from cross-referenced entries into account. https://github.com/JabRef/jabref/issues/2808 +- If a group has a color specified, then entries matched by this group have a small colored bar in front of them in the main table. +- Change default icon for groups to a circle because a colored version of the old icon was hard to distinguish from its black counterpart. +- In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) +- We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. +- We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). +- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. +- Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. +- Window state is saved on close and restored on start. +- Files without a defined external file type are now directly opened with the default aplication of the operating system +- We streamlined the process to rename and move files by removing the confirmation dialogs. + + + + + + + +### Fixed +- We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) +- Italic text is now rendered correctly. https://github.com/JabRef/jabref/issues/3356 +- The entry editor no longer gets corrupted after using the source tab. https://github.com/JabRef/jabref/issues/3532 https://github.com/JabRef/jabref/issues/3608 https://github.com/JabRef/jabref/issues/3616 +- We fixed multiple issues where entries did not show up after import if a search was active. https://github.com/JabRef/jabref/issues/1513 https://github.com/JabRef/jabref/issues/3219 +- We fixed an issue where the group tree was not updated correctly after an entry was changed. https://github.com/JabRef/jabref/issues/3618 +- We fixed an issue where a right-click in the main table selected a wrong entry. https://github.com/JabRef/jabref/issues/3267 +- We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 +- We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 +- We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 +- We fixed an issue where commands followed by `-` didn't work. [#3805](https://github.com/JabRef/jabref/issues/3805) +- We fixed an issue where some journal names were wrongly marked as abbreviated. [#4115](https://github.com/JabRef/jabref/issues/4115) +- We fixed an issue where the custom file column were sorted incorrectly. https://github.com/JabRef/jabref/issues/3119 +- We fixed an issues where the entry losses focus when a field is edited and at the same time used for sorting. https://github.com/JabRef/jabref/issues/3373 +- We fixed an issue where the menu on Mac OS was not displayed in the usual Mac-specific way. https://github.com/JabRef/jabref/issues/3146 +- We fixed an issue where the order of fields in customized entry types was not saved correctly. [#4033](http://github.com/JabRef/jabref/issues/4033) +- We fixed an issue where the groups tree of the last database was still shown even after the database was already closed. +- We fixed an issue where the "Open file dialog" may disappear behind other windows. https://github.com/JabRef/jabref/issues/3410 +- We fixed an issue where the default icon of a group was not colored correctly. +- We fixed an issue where the first field in entry editor was not focused when adding a new entry. [#4024](https://github.com/JabRef/jabref/issues/4024) +- We reworked the "Edit file" dialog to make it resizeable and improved the workflow for adding and editing files https://github.com/JabRef/jabref/issues/2970 +- We fixed an issue where the month was not shown in the preview https://github.com/JabRef/jabref/issues/3239. +- Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) +- We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) +- We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) +- We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) +- We fixed an issue where filles added via the "Attach file" contextmenu of an entry were not made relative. [#4201](https://github.com/JabRef/jabref/issues/4201) + + + + + + + + + + +### Removed +- The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. +- The number column was removed. +- We removed the coloring of cells in the maintable according to whether the field is optional/required. +- We removed a few commands from the right-click menu that are not needed often and thus don't need to be placed that prominently: + - Print entry preview: available through entry preview + - All commands related to marking: marking is not yet reimplemented + - Set/clear/append/rename fields: available through Edit menu + - Manage keywords: available through Edit menu + - Copy linked files to folder: available through File menu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Older versions + +The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). +The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). +The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). + +[Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD +[4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 +[4.2]: https://github.com/JabRef/jabref/compare/v4.1...v4.2 +[4.1]: https://github.com/JabRef/jabref/compare/v4.0...v4.1 +[4.0]: https://github.com/JabRef/jabref/compare/v4.0-beta3...v4.0 +[4.0-beta3]: https://github.com/JabRef/jabref/compare/v4.0-beta2...v4.0-beta3 +[4.0-beta2]: https://github.com/JabRef/jabref/compare/v4.0-beta...v4.0-beta2 +[4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta +[2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 +[JavaFX]: https://en.wikipedia.org/wiki/JavaFX +>>>>>>> 077fdacc2ddc7beb7d22ba96ead8b400c91b3631 From 9f3b3b79d5423233763325b1e554a74c778c28b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?1160300311=E6=B1=A4=E5=98=89=E7=90=A6?= <36810099+1160300311@users.noreply.github.com> Date: Wed, 8 Aug 2018 11:52:00 +0800 Subject: [PATCH 05/58] Update SaveOrderConfigDisplay.java --- src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index 420cc70c474..67cf5110365 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -13,12 +13,16 @@ import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.layout.GridPane; + +import javax.swing.JPanel; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; + import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; import org.jabref.model.metadata.SaveOrderConfig; -import javax.swing.*; public class SaveOrderConfigDisplay { From ee486e739b69c3af3295b1c2a8cea948ea78eb4c Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Wed, 8 Aug 2018 19:39:37 +0800 Subject: [PATCH 06/58] Merge the latest commits --- .../jabref/gui/SaveOrderConfigDisplay.java | 126 ++++++------------ .../FileAnnotationTabView.java | 11 +- .../FileAnnotationViewModel.java | 9 +- .../java/org/jabref/gui/help/HelpAction.java | 4 - .../gui/push/PushToApplicationSettings.java | 36 ----- .../jabref/gui/push/PushToEmacsSettings.java | 7 - .../RemoveHyphenatedNewlinesFormatter.java | 2 +- .../bibtexfields/RemoveNewlinesFormatter.java | 2 +- .../importer/fileformat/MsBibImporter.java | 38 +++++- .../jabref/model/entry/AuthorListParser.java | 5 +- .../org/jabref/model/strings/StringUtil.java | 4 +- src/main/resources/l10n/JabRef_zh.properties | 1 + 12 files changed, 104 insertions(+), 141 deletions(-) diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index 67cf5110365..a2d8d023174 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -1,46 +1,32 @@ package org.jabref.gui; +import java.awt.Component; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; -import javafx.collections.FXCollections; -import javafx.scene.Node; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ComboBox; -import javafx.scene.control.Label; -import javafx.scene.layout.GridPane; - -import javax.swing.JPanel; import javax.swing.JCheckBox; import javax.swing.JComboBox; +import javax.swing.JPanel; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; import org.jabref.model.metadata.SaveOrderConfig; +import com.jgoodies.forms.builder.FormBuilder; +import com.jgoodies.forms.layout.FormLayout; public class SaveOrderConfigDisplay { - private GridPane panel; - private JPanel jPanel; - private ComboBox savePriSort; - private ComboBox saveSecSort; - private ComboBox saveTerSort; - private CheckBox savePriDesc; - private CheckBox saveSecDesc; - private CheckBox saveTerDesc; - - private JComboBox savePriSort1; - private JComboBox saveSecSort1; - private JComboBox saveTerSort1; - private JCheckBox savePriDesc1; - private JCheckBox saveSecDesc1; - private JCheckBox saveTerDesc1; + private JPanel panel; + private JComboBox savePriSort; + private JComboBox saveSecSort; + private JComboBox saveTerSort; + private JCheckBox savePriDesc; + private JCheckBox saveSecDesc; + private JCheckBox saveTerDesc; public SaveOrderConfigDisplay() { @@ -52,80 +38,56 @@ private void init() { fieldNames.add(BibEntry.KEY_FIELD); Collections.sort(fieldNames); String[] allPlusKey = fieldNames.toArray(new String[fieldNames.size()]); - savePriSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); + savePriSort = new JComboBox<>(allPlusKey); savePriSort.setEditable(true); - saveSecSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); + saveSecSort = new JComboBox<>(allPlusKey); saveSecSort.setEditable(true); - saveTerSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); + saveTerSort = new JComboBox<>(allPlusKey); saveTerSort.setEditable(true); - savePriDesc = new CheckBox(Localization.lang("Descending")); - saveSecDesc = new CheckBox(Localization.lang("Descending")); - saveTerDesc = new CheckBox(Localization.lang("Descending")); - - GridPane builder = new GridPane(); - builder.add(new Label(Localization.lang(" Primary sort criterion ")),1,1); - builder.add(savePriSort,2,1); - builder.add(savePriDesc,3,1); - - builder.add(new Label(Localization.lang("Secondary sort criterion ")),1,2); - builder.add(saveSecSort,2,2); - builder.add(saveSecDesc,3,2); - - builder.add(new Label(Localization.lang(" Tertiary sort criterion ")),1, 3); - builder.add(saveTerSort,2,3); - builder.add(saveTerDesc,3,3); - panel = builder; - - savePriSort1 = new JComboBox<>(allPlusKey); - savePriSort1.setEditable(true); - saveSecSort1 = new JComboBox<>(allPlusKey); - saveSecSort1.setEditable(true); - saveTerSort1 = new JComboBox<>(allPlusKey); - saveTerSort1.setEditable(true); - savePriDesc1 = new JCheckBox(Localization.lang("Descending")); - saveSecDesc1 = new JCheckBox(Localization.lang("Descending")); - saveTerDesc1 = new JCheckBox(Localization.lang("Descending")); + savePriDesc = new JCheckBox(Localization.lang("Descending")); + saveSecDesc = new JCheckBox(Localization.lang("Descending")); + saveTerDesc = new JCheckBox(Localization.lang("Descending")); + FormLayout layout = new FormLayout("right:pref, 8dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, left:pref", "pref, 2dlu, pref, 2dlu, pref"); - FormBuilder builder1 = FormBuilder.create().layout(layout); - builder1.add(Localization.lang("Primary sort criterion")).xy(1, 1); - builder1.add(savePriSort1).xy(3, 1); - builder1.add(savePriDesc1).xy(5, 1); - builder1.add(Localization.lang("Secondary sort criterion")).xy(1, 3); - builder1.add(saveSecSort1).xy(3, 3); - builder1.add(saveSecDesc1).xy(5, 3); - builder1.add(Localization.lang("Tertiary sort criterion")).xy(1, 5); - builder1.add(saveTerSort1).xy(3, 5); - builder1.add(saveTerDesc1).xy(5, 5); - jPanel = builder1.build(); - } + FormBuilder builder = FormBuilder.create().layout(layout); + builder.add(Localization.lang("Primary sort criterion")).xy(1, 1); + builder.add(savePriSort).xy(3, 1); + builder.add(savePriDesc).xy(5, 1); - public Node getJFXPanel() { - return panel; + builder.add(Localization.lang("Secondary sort criterion")).xy(1, 3); + builder.add(saveSecSort).xy(3, 3); + builder.add(saveSecDesc).xy(5, 3); + + builder.add(Localization.lang("Tertiary sort criterion")).xy(1, 5); + builder.add(saveTerSort).xy(3, 5); + builder.add(saveTerDesc).xy(5, 5); + + panel = builder.build(); } - public JPanel getPanel() { - return jPanel; + public Component getPanel() { + return panel; } public void setEnabled(boolean enabled) { - savePriSort.setDisable(!enabled); - savePriDesc.setDisable(!enabled); - saveSecSort.setDisable(!enabled); - saveSecDesc.setDisable(!enabled); - saveTerSort.setDisable(!enabled); - saveTerDesc.setDisable(!enabled); + savePriSort.setEnabled(enabled); + savePriDesc.setEnabled(enabled); + saveSecSort.setEnabled(enabled); + saveSecDesc.setEnabled(enabled); + saveTerSort.setEnabled(enabled); + saveTerDesc.setEnabled(enabled); } public void setSaveOrderConfig(SaveOrderConfig saveOrderConfig) { Objects.requireNonNull(saveOrderConfig); - savePriSort.setValue(saveOrderConfig.sortCriteria[0].field); + savePriSort.setSelectedItem(saveOrderConfig.sortCriteria[0].field); savePriDesc.setSelected(saveOrderConfig.sortCriteria[0].descending); - saveSecSort.setValue(saveOrderConfig.sortCriteria[1].field); + saveSecSort.setSelectedItem(saveOrderConfig.sortCriteria[1].field); saveSecDesc.setSelected(saveOrderConfig.sortCriteria[1].descending); - saveTerSort.setValue(saveOrderConfig.sortCriteria[2].field); + saveTerSort.setSelectedItem(saveOrderConfig.sortCriteria[2].field); saveTerDesc.setSelected(saveOrderConfig.sortCriteria[2].descending); } @@ -142,7 +104,7 @@ public SaveOrderConfig getSaveOrderConfig() { return saveOrderConfig; } - private String getSelectedItemAsLowerCaseTrim(ComboBox sortBox) { - return sortBox.getValue().toLowerCase(Locale.ROOT).trim(); + private String getSelectedItemAsLowerCaseTrim(JComboBox sortBox) { + return sortBox.getSelectedItem().toString().toLowerCase(Locale.ROOT).trim(); } } diff --git a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabView.java b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabView.java index f49edc1ace6..b95b1d36596 100644 --- a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabView.java +++ b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabView.java @@ -15,6 +15,7 @@ import javafx.scene.control.ListView; import javafx.scene.control.SelectionMode; import javafx.scene.control.TextArea; +import javafx.scene.control.Tooltip; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; @@ -63,7 +64,6 @@ public void initialize() { annotationList.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); annotationList.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> viewModel.notifyNewSelectedAnnotation(newValue)); ViewModelListCellFactory cellFactory = new ViewModelListCellFactory() - .withTooltip(FileAnnotationViewModel::getMarking) .withGraphic(this::createFileAnnotationNode); annotationList.setCellFactory(cellFactory); annotationList.setPlaceholder(new Label(Localization.lang("File has no attached annotations"))); @@ -94,12 +94,19 @@ private Node createFileAnnotationNode(FileAnnotationViewModel annotation) { Label date = new Label(annotation.getDate()); Label page = new Label(Localization.lang("Page") + ": " + annotation.getPage()); - marking.setStyle("-fx-font-weight: bold"); + marking.setStyle("-fx-font-size: 0.75em; -fx-font-weight: bold"); marking.setMaxHeight(30); + Tooltip markingTooltip = new Tooltip(annotation.getMarking()); + markingTooltip.setMaxWidth(800); + markingTooltip.setWrapText(true); + marking.setTooltip(markingTooltip); + // add alignment for text in the list marking.setTextAlignment(TextAlignment.LEFT); marking.setAlignment(Pos.TOP_LEFT); + marking.setMaxWidth(500); + marking.setWrapText(true); author.setTextAlignment(TextAlignment.LEFT); author.setAlignment(Pos.TOP_LEFT); date.setTextAlignment(TextAlignment.RIGHT); diff --git a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationViewModel.java b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationViewModel.java index 85ae94d5b42..6f90512195a 100644 --- a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationViewModel.java @@ -11,6 +11,7 @@ public class FileAnnotationViewModel { + private static final String NEWLINE = String.format("%n"); private final FileAnnotation annotation; private StringProperty author = new SimpleStringProperty(); private StringProperty page = new SimpleStringProperty(); @@ -31,7 +32,13 @@ private void setupContentProperties(FileAnnotation annotation) { this.content.set(annotation.getLinkedFileAnnotation().getContent()); String annotationContent = annotation.getContent(); String illegibleTextMessage = Localization.lang("The marked area does not contain any legible text!"); - this.marking.set(annotationContent.isEmpty() ? illegibleTextMessage : annotationContent); + String markingContent = (annotationContent.isEmpty() ? illegibleTextMessage : annotationContent); + // remove newlines && hyphens before linebreaks + markingContent = markingContent.replaceAll("-" + NEWLINE, ""); + new RemoveHyphenatedNewlinesFormatter().format(markingContent); + // remove new lines not preceded by '.' or ':' + markingContent = markingContent.replaceAll("(? DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)) - .ifPresent(f -> path.setText(f.toAbsolutePath().toString()))); - jfxSettings.add(browse,3, 1); - } /** * This method is called to indicate that the settings panel returned from the getSettingsPanel() method has been * shown to the user and that the user has indicated that the settings should be stored. This method must store the diff --git a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java index 77eea7247f5..3f0665b5a81 100644 --- a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java @@ -3,7 +3,6 @@ import javax.swing.JPanel; import javax.swing.JTextField; -import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -18,12 +17,6 @@ public JPanel getSettingsPanel() { return super.getSettingsPanel(); } - @Override - public GridPane getJFXSettingPane(){ - additionalParams.setText(Globals.prefs.get(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS)); - return super.getJFXSettingPane(); - } - @Override public void storeSettings() { super.storeSettings(); diff --git a/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveHyphenatedNewlinesFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveHyphenatedNewlinesFormatter.java index 2356c02cab0..c05786154cc 100644 --- a/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveHyphenatedNewlinesFormatter.java +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveHyphenatedNewlinesFormatter.java @@ -10,7 +10,7 @@ * Removes all hyphenated line breaks in the string. */ public class RemoveHyphenatedNewlinesFormatter extends Formatter { - private static final Pattern HYPHENATED_WORDS = Pattern.compile("(-\r\n|-\n|-\r)"); + private static final Pattern HYPHENATED_WORDS = Pattern.compile("-\\R"); @Override public String getName() { diff --git a/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveNewlinesFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveNewlinesFormatter.java index c6942bf51ea..b4a8dabc04f 100644 --- a/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveNewlinesFormatter.java +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveNewlinesFormatter.java @@ -10,7 +10,7 @@ * Removes all line breaks in the string. */ public class RemoveNewlinesFormatter extends Formatter { - private static final Pattern LINEBREAKS = Pattern.compile("(\r?\n|\r)"); + private static final Pattern LINEBREAKS = Pattern.compile("\\R"); @Override public String getName() { diff --git a/src/main/java/org/jabref/logic/importer/fileformat/MsBibImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/MsBibImporter.java index 500cec32b63..db68e7958b7 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/MsBibImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/MsBibImporter.java @@ -6,12 +6,15 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import org.jabref.logic.importer.Importer; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.msbib.MSBibDatabase; import org.jabref.logic.util.StandardFileType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; @@ -20,24 +23,27 @@ /** * Importer for the MS Office 2007 XML bibliography format - * By S. M. Mahbub Murshed * * ... */ public class MsBibImporter extends Importer { + private static final Logger LOGGER = LoggerFactory.getLogger(MsBibImporter.class); + private static final String DISABLEDTD = "http://apache.org/xml/features/disallow-doctype-decl"; + private static final String DISABLEEXTERNALDTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; + @Override public boolean isRecognizedFormat(BufferedReader reader) throws IOException { Objects.requireNonNull(reader); /* - The correct behaviour is to return false if it is certain that the file is + The correct behavior is to return false if it is certain that the file is not of the MsBib type, and true otherwise. Returning true is the safe choice if not certain. */ Document docin; try { - DocumentBuilder dbuild = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + DocumentBuilder dbuild = makeSafeDocBuilderFactory(DocumentBuilderFactory.newInstance()).newDocumentBuilder(); dbuild.setErrorHandler(new ErrorHandler() { @Override @@ -55,6 +61,7 @@ public void error(SAXParseException exception) throws SAXException { throw exception; } }); + docin = dbuild.parse(new InputSource(reader)); } catch (Exception e) { return false; @@ -85,4 +92,29 @@ public String getDescription() { return "Importer for the MS Office 2007 XML bibliography format."; } + /** + * DocumentBuilderFactory makes a XXE safe Builder factory from dBuild. If not supported by current + * XML then returns original builder given and logs error. + * @param dBuild | DocumentBuilderFactory to be made XXE safe. + * @return If supported, XXE safe DocumentBuilderFactory. Else, returns original builder given + */ + private DocumentBuilderFactory makeSafeDocBuilderFactory(DocumentBuilderFactory dBuild) { + String feature = null; + + try { + feature = DISABLEDTD; + dBuild.setFeature(feature, true); + + feature = DISABLEEXTERNALDTD; + dBuild.setFeature(feature, false); + + dBuild.setXIncludeAware(false); + dBuild.setExpandEntityReferences(false); + + } catch (ParserConfigurationException e) { + LOGGER.warn("Builder not fully configured. Feature:'{}' is probably not supported by current XML processor. {}", feature, e); + } + + return dBuild; + } } diff --git a/src/main/java/org/jabref/model/entry/AuthorListParser.java b/src/main/java/org/jabref/model/entry/AuthorListParser.java index bd9093b348c..5ebca30a8a0 100644 --- a/src/main/java/org/jabref/model/entry/AuthorListParser.java +++ b/src/main/java/org/jabref/model/entry/AuthorListParser.java @@ -264,7 +264,8 @@ private Optional getAuthor() { false); String jrPart = jrPartStart < 0 ? null : concatTokens(tokens, jrPartStart, jrPartEnd, OFFSET_TOKEN, false); - if ((firstPart != null) && (lastPart != null) && lastPart.equals(lastPart.toUpperCase(Locale.ROOT)) && (lastPart.length() < 5)) { + if ((firstPart != null) && (lastPart != null) && lastPart.equals(lastPart.toUpperCase(Locale.ROOT)) && (lastPart.length() < 5) + && (Character.UnicodeScript.of(lastPart.charAt(0)) != Character.UnicodeScript.HAN)) { // The last part is a small string in complete upper case, so interpret it as initial of the first name // This is the case for example in "Smith SH" which we think of as lastname=Smith and firstname=SH // The length < 5 constraint should allow for "Smith S.H." as input @@ -378,7 +379,7 @@ private int getToken() { } if (!firstLetterIsFound && (currentBackslash < 0) && Character.isLetter(c)) { if (bracesLevel == 0) { - tokenCase = Character.isUpperCase(c); + tokenCase = Character.isUpperCase(c) || (Character.UnicodeScript.of(c) == Character.UnicodeScript.HAN); } else { // If this is a particle in braces, always treat it as if it starts with // an upper case letter. Otherwise a name such as "{van den Bergen}, Hans" diff --git a/src/main/java/org/jabref/model/strings/StringUtil.java b/src/main/java/org/jabref/model/strings/StringUtil.java index 75b9518ec32..05674f51a5a 100644 --- a/src/main/java/org/jabref/model/strings/StringUtil.java +++ b/src/main/java/org/jabref/model/strings/StringUtil.java @@ -197,7 +197,7 @@ public static String wrap(String in, int wrapAmount, String newline) { String[] lines = in.split("\n"); StringBuilder result = new StringBuilder(); // remove all whitespace at the end of the string, this especially includes \r created when the field content has \r\n as line separator - addWrappedLine(result, CharMatcher.WHITESPACE.trimTrailingFrom(lines[0]), wrapAmount, newline); // See + addWrappedLine(result, CharMatcher.whitespace().trimTrailingFrom(lines[0]), wrapAmount, newline); // See for (int i = 1; i < lines.length; i++) { if (lines[i].trim().isEmpty()) { @@ -209,7 +209,7 @@ public static String wrap(String in, int wrapAmount, String newline) { result.append(newline); result.append('\t'); // remove all whitespace at the end of the string, this especially includes \r created when the field content has \r\n as line separator - String line = CharMatcher.WHITESPACE.trimTrailingFrom(lines[i]); + String line = CharMatcher.whitespace().trimTrailingFrom(lines[i]); addWrappedLine(result, line, wrapAmount, newline); } } diff --git a/src/main/resources/l10n/JabRef_zh.properties b/src/main/resources/l10n/JabRef_zh.properties index 0cefa1dd0a5..52fd0017aa7 100644 --- a/src/main/resources/l10n/JabRef_zh.properties +++ b/src/main/resources/l10n/JabRef_zh.properties @@ -1914,3 +1914,4 @@ View\ event\ log=查看事件日志 Website=网站 Write\ XMP-metadata\ to\ PDFs=将 XMP 元数据写入到 PDF 中 +Removes\ all\ line\ breaks\ in\ the\ field\ content.=删除字段内容中所有的换行。 \ No newline at end of file From ad651fae18b06637756ebed5b3520e2226840c64 Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Wed, 8 Aug 2018 19:40:46 +0800 Subject: [PATCH 07/58] Merge the latest commits --- .../jabref/gui/SaveOrderConfigDisplay.java | 126 ++++++++++++------ .../FileAnnotationTabView.java | 11 +- .../FileAnnotationViewModel.java | 9 +- 3 files changed, 85 insertions(+), 61 deletions(-) diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index a2d8d023174..67cf5110365 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -1,32 +1,46 @@ package org.jabref.gui; -import java.awt.Component; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; +import com.jgoodies.forms.builder.FormBuilder; +import com.jgoodies.forms.layout.FormLayout; +import javafx.collections.FXCollections; +import javafx.scene.Node; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.layout.GridPane; + +import javax.swing.JPanel; import javax.swing.JCheckBox; import javax.swing.JComboBox; -import javax.swing.JPanel; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; import org.jabref.model.metadata.SaveOrderConfig; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; public class SaveOrderConfigDisplay { - private JPanel panel; - private JComboBox savePriSort; - private JComboBox saveSecSort; - private JComboBox saveTerSort; - private JCheckBox savePriDesc; - private JCheckBox saveSecDesc; - private JCheckBox saveTerDesc; + private GridPane panel; + private JPanel jPanel; + private ComboBox savePriSort; + private ComboBox saveSecSort; + private ComboBox saveTerSort; + private CheckBox savePriDesc; + private CheckBox saveSecDesc; + private CheckBox saveTerDesc; + + private JComboBox savePriSort1; + private JComboBox saveSecSort1; + private JComboBox saveTerSort1; + private JCheckBox savePriDesc1; + private JCheckBox saveSecDesc1; + private JCheckBox saveTerDesc1; public SaveOrderConfigDisplay() { @@ -38,56 +52,80 @@ private void init() { fieldNames.add(BibEntry.KEY_FIELD); Collections.sort(fieldNames); String[] allPlusKey = fieldNames.toArray(new String[fieldNames.size()]); - savePriSort = new JComboBox<>(allPlusKey); + savePriSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); savePriSort.setEditable(true); - saveSecSort = new JComboBox<>(allPlusKey); + saveSecSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); saveSecSort.setEditable(true); - saveTerSort = new JComboBox<>(allPlusKey); + saveTerSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); saveTerSort.setEditable(true); - savePriDesc = new JCheckBox(Localization.lang("Descending")); - saveSecDesc = new JCheckBox(Localization.lang("Descending")); - saveTerDesc = new JCheckBox(Localization.lang("Descending")); - + savePriDesc = new CheckBox(Localization.lang("Descending")); + saveSecDesc = new CheckBox(Localization.lang("Descending")); + saveTerDesc = new CheckBox(Localization.lang("Descending")); + + GridPane builder = new GridPane(); + builder.add(new Label(Localization.lang(" Primary sort criterion ")),1,1); + builder.add(savePriSort,2,1); + builder.add(savePriDesc,3,1); + + builder.add(new Label(Localization.lang("Secondary sort criterion ")),1,2); + builder.add(saveSecSort,2,2); + builder.add(saveSecDesc,3,2); + + builder.add(new Label(Localization.lang(" Tertiary sort criterion ")),1, 3); + builder.add(saveTerSort,2,3); + builder.add(saveTerDesc,3,3); + panel = builder; + + savePriSort1 = new JComboBox<>(allPlusKey); + savePriSort1.setEditable(true); + saveSecSort1 = new JComboBox<>(allPlusKey); + saveSecSort1.setEditable(true); + saveTerSort1 = new JComboBox<>(allPlusKey); + saveTerSort1.setEditable(true); + savePriDesc1 = new JCheckBox(Localization.lang("Descending")); + saveSecDesc1 = new JCheckBox(Localization.lang("Descending")); + saveTerDesc1 = new JCheckBox(Localization.lang("Descending")); FormLayout layout = new FormLayout("right:pref, 8dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, left:pref", "pref, 2dlu, pref, 2dlu, pref"); - FormBuilder builder = FormBuilder.create().layout(layout); - builder.add(Localization.lang("Primary sort criterion")).xy(1, 1); - builder.add(savePriSort).xy(3, 1); - builder.add(savePriDesc).xy(5, 1); - - builder.add(Localization.lang("Secondary sort criterion")).xy(1, 3); - builder.add(saveSecSort).xy(3, 3); - builder.add(saveSecDesc).xy(5, 3); - - builder.add(Localization.lang("Tertiary sort criterion")).xy(1, 5); - builder.add(saveTerSort).xy(3, 5); - builder.add(saveTerDesc).xy(5, 5); - - panel = builder.build(); + FormBuilder builder1 = FormBuilder.create().layout(layout); + builder1.add(Localization.lang("Primary sort criterion")).xy(1, 1); + builder1.add(savePriSort1).xy(3, 1); + builder1.add(savePriDesc1).xy(5, 1); + builder1.add(Localization.lang("Secondary sort criterion")).xy(1, 3); + builder1.add(saveSecSort1).xy(3, 3); + builder1.add(saveSecDesc1).xy(5, 3); + builder1.add(Localization.lang("Tertiary sort criterion")).xy(1, 5); + builder1.add(saveTerSort1).xy(3, 5); + builder1.add(saveTerDesc1).xy(5, 5); + jPanel = builder1.build(); } - public Component getPanel() { + public Node getJFXPanel() { return panel; } + public JPanel getPanel() { + return jPanel; + } + public void setEnabled(boolean enabled) { - savePriSort.setEnabled(enabled); - savePriDesc.setEnabled(enabled); - saveSecSort.setEnabled(enabled); - saveSecDesc.setEnabled(enabled); - saveTerSort.setEnabled(enabled); - saveTerDesc.setEnabled(enabled); + savePriSort.setDisable(!enabled); + savePriDesc.setDisable(!enabled); + saveSecSort.setDisable(!enabled); + saveSecDesc.setDisable(!enabled); + saveTerSort.setDisable(!enabled); + saveTerDesc.setDisable(!enabled); } public void setSaveOrderConfig(SaveOrderConfig saveOrderConfig) { Objects.requireNonNull(saveOrderConfig); - savePriSort.setSelectedItem(saveOrderConfig.sortCriteria[0].field); + savePriSort.setValue(saveOrderConfig.sortCriteria[0].field); savePriDesc.setSelected(saveOrderConfig.sortCriteria[0].descending); - saveSecSort.setSelectedItem(saveOrderConfig.sortCriteria[1].field); + saveSecSort.setValue(saveOrderConfig.sortCriteria[1].field); saveSecDesc.setSelected(saveOrderConfig.sortCriteria[1].descending); - saveTerSort.setSelectedItem(saveOrderConfig.sortCriteria[2].field); + saveTerSort.setValue(saveOrderConfig.sortCriteria[2].field); saveTerDesc.setSelected(saveOrderConfig.sortCriteria[2].descending); } @@ -104,7 +142,7 @@ public SaveOrderConfig getSaveOrderConfig() { return saveOrderConfig; } - private String getSelectedItemAsLowerCaseTrim(JComboBox sortBox) { - return sortBox.getSelectedItem().toString().toLowerCase(Locale.ROOT).trim(); + private String getSelectedItemAsLowerCaseTrim(ComboBox sortBox) { + return sortBox.getValue().toLowerCase(Locale.ROOT).trim(); } } diff --git a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabView.java b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabView.java index b95b1d36596..f49edc1ace6 100644 --- a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabView.java +++ b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabView.java @@ -15,7 +15,6 @@ import javafx.scene.control.ListView; import javafx.scene.control.SelectionMode; import javafx.scene.control.TextArea; -import javafx.scene.control.Tooltip; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; @@ -64,6 +63,7 @@ public void initialize() { annotationList.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); annotationList.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> viewModel.notifyNewSelectedAnnotation(newValue)); ViewModelListCellFactory cellFactory = new ViewModelListCellFactory() + .withTooltip(FileAnnotationViewModel::getMarking) .withGraphic(this::createFileAnnotationNode); annotationList.setCellFactory(cellFactory); annotationList.setPlaceholder(new Label(Localization.lang("File has no attached annotations"))); @@ -94,19 +94,12 @@ private Node createFileAnnotationNode(FileAnnotationViewModel annotation) { Label date = new Label(annotation.getDate()); Label page = new Label(Localization.lang("Page") + ": " + annotation.getPage()); - marking.setStyle("-fx-font-size: 0.75em; -fx-font-weight: bold"); + marking.setStyle("-fx-font-weight: bold"); marking.setMaxHeight(30); - Tooltip markingTooltip = new Tooltip(annotation.getMarking()); - markingTooltip.setMaxWidth(800); - markingTooltip.setWrapText(true); - marking.setTooltip(markingTooltip); - // add alignment for text in the list marking.setTextAlignment(TextAlignment.LEFT); marking.setAlignment(Pos.TOP_LEFT); - marking.setMaxWidth(500); - marking.setWrapText(true); author.setTextAlignment(TextAlignment.LEFT); author.setAlignment(Pos.TOP_LEFT); date.setTextAlignment(TextAlignment.RIGHT); diff --git a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationViewModel.java b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationViewModel.java index 6f90512195a..85ae94d5b42 100644 --- a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationViewModel.java @@ -11,7 +11,6 @@ public class FileAnnotationViewModel { - private static final String NEWLINE = String.format("%n"); private final FileAnnotation annotation; private StringProperty author = new SimpleStringProperty(); private StringProperty page = new SimpleStringProperty(); @@ -32,13 +31,7 @@ private void setupContentProperties(FileAnnotation annotation) { this.content.set(annotation.getLinkedFileAnnotation().getContent()); String annotationContent = annotation.getContent(); String illegibleTextMessage = Localization.lang("The marked area does not contain any legible text!"); - String markingContent = (annotationContent.isEmpty() ? illegibleTextMessage : annotationContent); - // remove newlines && hyphens before linebreaks - markingContent = markingContent.replaceAll("-" + NEWLINE, ""); - new RemoveHyphenatedNewlinesFormatter().format(markingContent); - // remove new lines not preceded by '.' or ':' - markingContent = markingContent.replaceAll("(? Date: Wed, 8 Aug 2018 19:41:30 +0800 Subject: [PATCH 08/58] merge the latest commits --- .../java/org/jabref/gui/help/HelpAction.java | 4 ++ .../gui/push/PushToApplicationSettings.java | 36 ++++++++++++++++++ .../jabref/gui/push/PushToEmacsSettings.java | 7 ++++ .../RemoveHyphenatedNewlinesFormatter.java | 2 +- .../bibtexfields/RemoveNewlinesFormatter.java | 2 +- .../importer/fileformat/MsBibImporter.java | 38 ++----------------- .../jabref/model/entry/AuthorListParser.java | 5 +-- .../org/jabref/model/strings/StringUtil.java | 4 +- src/main/resources/l10n/JabRef_zh.properties | 1 - 9 files changed, 56 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/jabref/gui/help/HelpAction.java b/src/main/java/org/jabref/gui/help/HelpAction.java index ab7ae84e027..70fdc69f5d9 100644 --- a/src/main/java/org/jabref/gui/help/HelpAction.java +++ b/src/main/java/org/jabref/gui/help/HelpAction.java @@ -17,6 +17,10 @@ import javax.swing.JLabel; import javax.swing.KeyStroke; +import com.sun.star.presentation.ClickAction; +import javafx.event.EventHandler; +import javafx.scene.control.Button; +import javafx.scene.control.Tooltip; import org.jabref.Globals; import org.jabref.gui.actions.MnemonicAwareAction; import org.jabref.gui.actions.SimpleCommand; diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java index 30c1faf65d9..43bcb520cd5 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java @@ -4,6 +4,10 @@ import javax.swing.JPanel; import javax.swing.JTextField; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.util.DefaultTaskExecutor; @@ -16,7 +20,9 @@ public class PushToApplicationSettings { protected final JTextField path = new JTextField(30); + protected final TextField path1 = new TextField(); protected JPanel settings; + protected GridPane jfxSettings; protected FormBuilder builder; protected AbstractPushToApplication application; private DialogService dialogService; @@ -39,6 +45,15 @@ public JPanel getSettingsPanel() { return settings; } + public GridPane getJFXSettingPane(){ + application.initParameters(); + String commandPath = Globals.prefs.get(application.commandPathPreferenceKey); + if(jfxSettings == null){ + initJFXSettingsPanel(); + } + path1.setText(commandPath); + return jfxSettings; + } /** * Create a FormBuilder, fill it with a textbox for the path and store the JPanel in settings */ @@ -66,6 +81,27 @@ protected void initSettingsPanel() { settings = builder.build(); } + protected void initJFXSettingsPanel() { + jfxSettings = new GridPane(); + StringBuilder label = new StringBuilder(Localization.lang("Path to %0", application.getApplicationName())); + // In case the application name and the actual command is not the same, add the command in brackets + if (application.getCommandName() == null) { + label.append(':'); + } else { + label.append(" (").append(application.getCommandName()).append("):"); + } + jfxSettings.add(new Label(label.toString()),1,1); + jfxSettings.add(path1,2, 1); + Button browse = new Button(Localization.lang("Browse")); + + FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); + + browse.setOnAction( + e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration)) + .ifPresent(f -> path.setText(f.toAbsolutePath().toString()))); + jfxSettings.add(browse,3, 1); + } /** * This method is called to indicate that the settings panel returned from the getSettingsPanel() method has been * shown to the user and that the user has indicated that the settings should be stored. This method must store the diff --git a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java index 3f0665b5a81..77eea7247f5 100644 --- a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java @@ -3,6 +3,7 @@ import javax.swing.JPanel; import javax.swing.JTextField; +import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -17,6 +18,12 @@ public JPanel getSettingsPanel() { return super.getSettingsPanel(); } + @Override + public GridPane getJFXSettingPane(){ + additionalParams.setText(Globals.prefs.get(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS)); + return super.getJFXSettingPane(); + } + @Override public void storeSettings() { super.storeSettings(); diff --git a/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveHyphenatedNewlinesFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveHyphenatedNewlinesFormatter.java index c05786154cc..2356c02cab0 100644 --- a/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveHyphenatedNewlinesFormatter.java +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveHyphenatedNewlinesFormatter.java @@ -10,7 +10,7 @@ * Removes all hyphenated line breaks in the string. */ public class RemoveHyphenatedNewlinesFormatter extends Formatter { - private static final Pattern HYPHENATED_WORDS = Pattern.compile("-\\R"); + private static final Pattern HYPHENATED_WORDS = Pattern.compile("(-\r\n|-\n|-\r)"); @Override public String getName() { diff --git a/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveNewlinesFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveNewlinesFormatter.java index b4a8dabc04f..c6942bf51ea 100644 --- a/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveNewlinesFormatter.java +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/RemoveNewlinesFormatter.java @@ -10,7 +10,7 @@ * Removes all line breaks in the string. */ public class RemoveNewlinesFormatter extends Formatter { - private static final Pattern LINEBREAKS = Pattern.compile("\\R"); + private static final Pattern LINEBREAKS = Pattern.compile("(\r?\n|\r)"); @Override public String getName() { diff --git a/src/main/java/org/jabref/logic/importer/fileformat/MsBibImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/MsBibImporter.java index db68e7958b7..500cec32b63 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/MsBibImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/MsBibImporter.java @@ -6,15 +6,12 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import org.jabref.logic.importer.Importer; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.msbib.MSBibDatabase; import org.jabref.logic.util.StandardFileType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; @@ -23,27 +20,24 @@ /** * Importer for the MS Office 2007 XML bibliography format + * By S. M. Mahbub Murshed * * ... */ public class MsBibImporter extends Importer { - private static final Logger LOGGER = LoggerFactory.getLogger(MsBibImporter.class); - private static final String DISABLEDTD = "http://apache.org/xml/features/disallow-doctype-decl"; - private static final String DISABLEEXTERNALDTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; - @Override public boolean isRecognizedFormat(BufferedReader reader) throws IOException { Objects.requireNonNull(reader); /* - The correct behavior is to return false if it is certain that the file is + The correct behaviour is to return false if it is certain that the file is not of the MsBib type, and true otherwise. Returning true is the safe choice if not certain. */ Document docin; try { - DocumentBuilder dbuild = makeSafeDocBuilderFactory(DocumentBuilderFactory.newInstance()).newDocumentBuilder(); + DocumentBuilder dbuild = DocumentBuilderFactory.newInstance().newDocumentBuilder(); dbuild.setErrorHandler(new ErrorHandler() { @Override @@ -61,7 +55,6 @@ public void error(SAXParseException exception) throws SAXException { throw exception; } }); - docin = dbuild.parse(new InputSource(reader)); } catch (Exception e) { return false; @@ -92,29 +85,4 @@ public String getDescription() { return "Importer for the MS Office 2007 XML bibliography format."; } - /** - * DocumentBuilderFactory makes a XXE safe Builder factory from dBuild. If not supported by current - * XML then returns original builder given and logs error. - * @param dBuild | DocumentBuilderFactory to be made XXE safe. - * @return If supported, XXE safe DocumentBuilderFactory. Else, returns original builder given - */ - private DocumentBuilderFactory makeSafeDocBuilderFactory(DocumentBuilderFactory dBuild) { - String feature = null; - - try { - feature = DISABLEDTD; - dBuild.setFeature(feature, true); - - feature = DISABLEEXTERNALDTD; - dBuild.setFeature(feature, false); - - dBuild.setXIncludeAware(false); - dBuild.setExpandEntityReferences(false); - - } catch (ParserConfigurationException e) { - LOGGER.warn("Builder not fully configured. Feature:'{}' is probably not supported by current XML processor. {}", feature, e); - } - - return dBuild; - } } diff --git a/src/main/java/org/jabref/model/entry/AuthorListParser.java b/src/main/java/org/jabref/model/entry/AuthorListParser.java index 5ebca30a8a0..bd9093b348c 100644 --- a/src/main/java/org/jabref/model/entry/AuthorListParser.java +++ b/src/main/java/org/jabref/model/entry/AuthorListParser.java @@ -264,8 +264,7 @@ private Optional getAuthor() { false); String jrPart = jrPartStart < 0 ? null : concatTokens(tokens, jrPartStart, jrPartEnd, OFFSET_TOKEN, false); - if ((firstPart != null) && (lastPart != null) && lastPart.equals(lastPart.toUpperCase(Locale.ROOT)) && (lastPart.length() < 5) - && (Character.UnicodeScript.of(lastPart.charAt(0)) != Character.UnicodeScript.HAN)) { + if ((firstPart != null) && (lastPart != null) && lastPart.equals(lastPart.toUpperCase(Locale.ROOT)) && (lastPart.length() < 5)) { // The last part is a small string in complete upper case, so interpret it as initial of the first name // This is the case for example in "Smith SH" which we think of as lastname=Smith and firstname=SH // The length < 5 constraint should allow for "Smith S.H." as input @@ -379,7 +378,7 @@ private int getToken() { } if (!firstLetterIsFound && (currentBackslash < 0) && Character.isLetter(c)) { if (bracesLevel == 0) { - tokenCase = Character.isUpperCase(c) || (Character.UnicodeScript.of(c) == Character.UnicodeScript.HAN); + tokenCase = Character.isUpperCase(c); } else { // If this is a particle in braces, always treat it as if it starts with // an upper case letter. Otherwise a name such as "{van den Bergen}, Hans" diff --git a/src/main/java/org/jabref/model/strings/StringUtil.java b/src/main/java/org/jabref/model/strings/StringUtil.java index 05674f51a5a..75b9518ec32 100644 --- a/src/main/java/org/jabref/model/strings/StringUtil.java +++ b/src/main/java/org/jabref/model/strings/StringUtil.java @@ -197,7 +197,7 @@ public static String wrap(String in, int wrapAmount, String newline) { String[] lines = in.split("\n"); StringBuilder result = new StringBuilder(); // remove all whitespace at the end of the string, this especially includes \r created when the field content has \r\n as line separator - addWrappedLine(result, CharMatcher.whitespace().trimTrailingFrom(lines[0]), wrapAmount, newline); // See + addWrappedLine(result, CharMatcher.WHITESPACE.trimTrailingFrom(lines[0]), wrapAmount, newline); // See for (int i = 1; i < lines.length; i++) { if (lines[i].trim().isEmpty()) { @@ -209,7 +209,7 @@ public static String wrap(String in, int wrapAmount, String newline) { result.append(newline); result.append('\t'); // remove all whitespace at the end of the string, this especially includes \r created when the field content has \r\n as line separator - String line = CharMatcher.whitespace().trimTrailingFrom(lines[i]); + String line = CharMatcher.WHITESPACE.trimTrailingFrom(lines[i]); addWrappedLine(result, line, wrapAmount, newline); } } diff --git a/src/main/resources/l10n/JabRef_zh.properties b/src/main/resources/l10n/JabRef_zh.properties index 52fd0017aa7..0cefa1dd0a5 100644 --- a/src/main/resources/l10n/JabRef_zh.properties +++ b/src/main/resources/l10n/JabRef_zh.properties @@ -1914,4 +1914,3 @@ View\ event\ log=查看事件日志 Website=网站 Write\ XMP-metadata\ to\ PDFs=将 XMP 元数据写入到 PDF 中 -Removes\ all\ line\ breaks\ in\ the\ field\ content.=删除字段内容中所有的换行。 \ No newline at end of file From ee1c275d15772770592684d53c1e1b4c649f29cf Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 16:18:05 +0800 Subject: [PATCH 09/58] Polish the code style --- build.gradle | 30 ++++++++-------- .../jabref/gui/SaveOrderConfigDisplay.java | 25 +++++-------- .../BibtexKeyPatternPanel.java | 36 ++++++++++--------- .../java/org/jabref/gui/help/HelpAction.java | 4 --- .../gui/importer/ImportInspectionDialog.java | 3 +- .../gui/preftabs/BibtexKeyPatternPrefTab.java | 4 +-- .../org/jabref/gui/preftabs/ExternalTab.java | 14 ++++---- .../org/jabref/gui/preftabs/GeneralTab.java | 2 +- .../jabref/gui/preftabs/GroupsPrefsTab.java | 8 +++-- .../gui/preftabs/ImportSettingsTab.java | 2 +- .../jabref/gui/preftabs/NameFormatterTab.java | 10 +++--- .../org/jabref/gui/preftabs/NetworkTab.java | 2 +- .../jabref/gui/preftabs/TableColumnsTab.java | 20 +++++------ .../jabref/gui/preftabs/TablePrefsTab.java | 4 +-- .../org/jabref/gui/preftabs/XmpPrefsTab.java | 4 +-- .../gui/push/PushToApplicationSettings.java | 4 +-- .../jabref/gui/push/PushToEmacsSettings.java | 2 +- .../org/jabref/model/strings/StringUtil.java | 4 +-- 18 files changed, 86 insertions(+), 92 deletions(-) diff --git a/build.gradle b/build.gradle index 2daa628c683..e416e9e9970 100644 --- a/build.gradle +++ b/build.gradle @@ -194,12 +194,12 @@ dependencyUpdates.resolutionStrategy = { } rules.withModule("org.controlsfx:controlsfx") { ComponentSelection selection -> if (selection.candidate.version ==~ /9.*/) { // Reject version 9 or higher - selection.reject("Cannot be updated to 9.*.* until Jabref works with Java 9") + selection.reject("Cannot be updated to 9.*.* until Jabref works with Java 9") } } - rules.withModule("com.github.tomtung:latex2unicode_2.12") { ComponentSelection selection -> + rules.withModule("com.github.tomtung:latex2unicode_2.12") { ComponentSelection selection -> if (selection.candidate.version ==~ /0.2.2/) { // Reject version higher than 2.0.2 - selection.reject("Cannot be updated to 0.2.4 until JabRef is prepared for it") + selection.reject("Cannot be updated to 0.2.4 until JabRef is prepared for it") } } rules.withModule("de.jensd:fontawesomefx-materialdesignfont") { ComponentSelection selection -> @@ -212,7 +212,7 @@ dependencyUpdates.resolutionStrategy = { selection.reject("http://dev.mysql.com/downloads/connector/j/ lists the version 5.* as last stable version.") } } - + } } @@ -494,16 +494,16 @@ jmh { // Source: https://stackoverflow.com/a/44168582/873282 task downloadDependencies { - description "Pre-downloads *most* dependencies" - doLast { - configurations.getAsMap().each { name, config -> - println "Retrieving dependencies for $name" - try { - config.files - } catch (e) { - // some cannot be resolved, just log them - project.logger.info e.message - } + description "Pre-downloads *most* dependencies" + doLast { + configurations.getAsMap().each { name, config -> + println "Retrieving dependencies for $name" + try { + config.files + } catch (e) { + // some cannot be resolved, just log them + project.logger.info e.message + } + } } - } } diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index 67cf5110365..68e6d89161c 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -5,8 +5,6 @@ import java.util.Locale; import java.util.Objects; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; import javafx.collections.FXCollections; import javafx.scene.Node; import javafx.scene.control.CheckBox; @@ -14,15 +12,17 @@ import javafx.scene.control.Label; import javafx.scene.layout.GridPane; -import javax.swing.JPanel; import javax.swing.JCheckBox; import javax.swing.JComboBox; +import javax.swing.JPanel; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; import org.jabref.model.metadata.SaveOrderConfig; +import com.jgoodies.forms.builder.FormBuilder; +import com.jgoodies.forms.layout.FormLayout; public class SaveOrderConfigDisplay { @@ -35,13 +35,6 @@ public class SaveOrderConfigDisplay { private CheckBox saveSecDesc; private CheckBox saveTerDesc; - private JComboBox savePriSort1; - private JComboBox saveSecSort1; - private JComboBox saveTerSort1; - private JCheckBox savePriDesc1; - private JCheckBox saveSecDesc1; - private JCheckBox saveTerDesc1; - public SaveOrderConfigDisplay() { init(); @@ -77,15 +70,15 @@ private void init() { builder.add(saveTerDesc,3,3); panel = builder; - savePriSort1 = new JComboBox<>(allPlusKey); + JComboBox savePriSort1 = new JComboBox<>(allPlusKey); savePriSort1.setEditable(true); - saveSecSort1 = new JComboBox<>(allPlusKey); + JComboBox saveSecSort1 = new JComboBox<>(allPlusKey); saveSecSort1.setEditable(true); - saveTerSort1 = new JComboBox<>(allPlusKey); + JComboBox saveTerSort1 = new JComboBox<>(allPlusKey); saveTerSort1.setEditable(true); - savePriDesc1 = new JCheckBox(Localization.lang("Descending")); - saveSecDesc1 = new JCheckBox(Localization.lang("Descending")); - saveTerDesc1 = new JCheckBox(Localization.lang("Descending")); + JCheckBox savePriDesc1 = new JCheckBox(Localization.lang("Descending")); + JCheckBox saveSecDesc1 = new JCheckBox(Localization.lang("Descending")); + JCheckBox saveTerDesc1 = new JCheckBox(Localization.lang("Descending")); FormLayout layout = new FormLayout("right:pref, 8dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, left:pref", "pref, 2dlu, pref, 2dlu, pref"); FormBuilder builder1 = FormBuilder.create().layout(layout); diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java index 9f80d4a6857..3ad6b0f29af 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java @@ -1,9 +1,20 @@ package org.jabref.gui.bibtexkeypattern; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.help.HelpAction; @@ -18,21 +29,12 @@ import org.jabref.model.entry.EntryType; import org.jabref.preferences.JabRefPreferences; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; -import javax.swing.JTextField; import javax.swing.JScrollPane; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; +import javax.swing.JTextField; public class BibtexKeyPatternPanel extends JPanel { @@ -69,7 +71,7 @@ private void buildGUI() { // The header - can be removed JLabel lblEntryType = new JLabel(Localization.lang("Entry type")); - Label label= new Label(Localization.lang("Entry type")); + Label label = new Label(Localization.lang("Entry type")); gridPane.add(label,1,1); Font f = new Font("plain", Font.BOLD, 12); lblEntryType.setFont(f); @@ -197,10 +199,10 @@ private void buildGUI() { gridPane.add(btnDefaultAll1,2,24); } - private void addExtraText(){ + private void addExtraText() { Label []label = new Label[19]; Button []button = new Button[19]; - for(int i=0; i<=18; i++){ + for (int i = 0; i <= 18; i++) { textFieldArray[i] = new TextField(); button[i] = new Button("Default"); button[i].setOnAction(e-> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); @@ -224,10 +226,10 @@ private void addExtraText(){ label[16] = new Label("Standard"); label[17] = new Label("TechReport"); label[18] = new Label("Unpublished"); - for(int i=0 ;i<=18; i++){ - gridPane.add(label[i],1,i+3); - gridPane.add(textFieldArray[i],2,i+3); - gridPane.add(button[i],3,i+3); + for (int i=0; i <= 18; i++) { + gridPane.add(label[i],1,i + 3); + gridPane.add(textFieldArray[i],2,i + 3); + gridPane.add(button[i],3,i + 3); } } diff --git a/src/main/java/org/jabref/gui/help/HelpAction.java b/src/main/java/org/jabref/gui/help/HelpAction.java index 70fdc69f5d9..ab7ae84e027 100644 --- a/src/main/java/org/jabref/gui/help/HelpAction.java +++ b/src/main/java/org/jabref/gui/help/HelpAction.java @@ -17,10 +17,6 @@ import javax.swing.JLabel; import javax.swing.KeyStroke; -import com.sun.star.presentation.ClickAction; -import javafx.event.EventHandler; -import javafx.scene.control.Button; -import javafx.scene.control.Tooltip; import org.jabref.Globals; import org.jabref.gui.actions.MnemonicAwareAction; import org.jabref.gui.actions.SimpleCommand; diff --git a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java index 84fcef65d67..06c42fd7d32 100644 --- a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java @@ -143,7 +143,8 @@ * receiving this call). */ -public class ImportInspectionDialog extends JabRefDialog implements OutputPrinter { +public class ImportInspectionDialog extends JabRefDialog + implements OutputPrinter { private static final Logger LOGGER = LoggerFactory.getLogger(ImportInspectionDialog.class); private static final List INSPECTION_FIELDS = Arrays.asList(FieldName.AUTHOR, FieldName.TITLE, FieldName.YEAR, BibEntry.KEY_FIELD); diff --git a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java index fbe33c9dad0..83e6d50110a 100644 --- a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java +++ b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java @@ -1,5 +1,7 @@ package org.jabref.gui.preftabs; +import java.awt.BorderLayout; + import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.control.CheckBox; @@ -16,8 +18,6 @@ import org.jabref.model.bibtexkeypattern.GlobalBibtexKeyPattern; import org.jabref.preferences.JabRefPreferences; -import java.awt.BorderLayout; - /** * The Preferences panel for key generation. */ diff --git a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java index 5434a020ed5..db055e3c6de 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java @@ -11,8 +11,8 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; -import javax.swing.JPanel; import javax.swing.JFileChooser; +import javax.swing.JPanel; import org.jabref.Globals; import org.jabref.gui.JabRefFrame; @@ -43,8 +43,6 @@ class ExternalTab extends JPanel implements PrefsTab { private final RadioButton sumatraReader; private final TextField adobeAcrobatReaderPath; private final TextField sumatraReaderPath; - private final Button browseAdobeAcrobatReader; - private final Button browseSumatraReader; public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPreferences prefs) { this.prefs = prefs; @@ -62,11 +60,11 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere adobeAcrobatReader = new RadioButton(Localization.lang("Adobe Acrobat Reader")); adobeAcrobatReaderPath = new TextField(); - browseAdobeAcrobatReader = new Button(Localization.lang("Browse")); + Button browseAdobeAcrobatReader = new Button(Localization.lang("Browse")); sumatraReader = new RadioButton(Localization.lang("Sumatra Reader")); sumatraReaderPath = new TextField(); - browseSumatraReader = new Button(Localization.lang("Browse")); + Button browseSumatraReader = new Button(Localization.lang("Browse")); Label commandDescription = new Label(Localization.lang("Note: Use the placeholder %0 for the location of the opened library file.", "%DIR")); @@ -144,7 +142,11 @@ private void addSettingsButton(final PushToApplication application, GridPane pan PushToApplicationSettings settings = PushToApplications.getSettings(application); Button button = new Button(Localization.lang("Settings for %0", application.getApplicationName())); button.setOnAction(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, settings)); - panel.add(button,index % 2==0?1:2,index/2+1); + if (index % 2 == 0) { + panel.add(button,1, index / 2 + 1); + } else { + panel.add(button,2, index / 2 + 1); + } } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index 675ea40df68..f6156bca3f1 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -73,7 +73,7 @@ public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { updateTimeStamp = new CheckBox(Localization.lang(" Update timestamp on modification")); useTimeStamp = new CheckBox(Localization.lang("Mark new entries with addition date") + ". " + Localization.lang("Date format") + ':'); - if (!useTimeStamp.isSelected()){ + if (!useTimeStamp.isSelected()) { updateTimeStamp.setDisable(true); } useTimeStamp.setOnAction(e->updateTimeStamp.setDisable(!useTimeStamp.isSelected())); diff --git a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java index e7307d8f3b4..a051c556efa 100644 --- a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java @@ -1,5 +1,7 @@ package org.jabref.gui.preftabs; +import java.awt.BorderLayout; + import javafx.embed.swing.JFXPanel; import javafx.event.ActionEvent; import javafx.event.EventHandler; @@ -9,14 +11,14 @@ import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; + +import javax.swing.JPanel; + import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.groups.GroupViewMode; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -import javax.swing.*; -import java.awt.*; - class GroupsPrefsTab extends JPanel implements PrefsTab { private final CheckBox hideNonHits = new CheckBox(Localization.lang("Hide non-hits")); diff --git a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java index 00c0bf2a66d..4a5c09e4af9 100644 --- a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java @@ -8,9 +8,9 @@ import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.Separator; -import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; diff --git a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java index 9ca575b7a86..3e02b99ce57 100644 --- a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java @@ -1,7 +1,7 @@ package org.jabref.gui.preftabs; -import java.util.ArrayList; import java.awt.BorderLayout; +import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -9,18 +9,18 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; import javafx.scene.control.Button; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; -import javafx.scene.Scene; import javax.swing.JPanel; @@ -138,7 +138,7 @@ public NameFormatterTab(JabRefPreferences prefs) { } }); Button delete = new Button("Delete"); - delete.setOnAction(e-> {if (table.getFocusModel() != null && table.getFocusModel().getFocusedIndex()!= -1) { + delete.setOnAction(e-> {if (table.getFocusModel() != null && table.getFocusModel().getFocusedIndex() != -1) { tableChanged = true; int row = table.getFocusModel().getFocusedIndex(); TableRow tableRow = tableRows.get(row); diff --git a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java index 32b0675d175..c7b03a533de 100644 --- a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java @@ -3,6 +3,7 @@ import java.awt.BorderLayout; import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.PasswordField; @@ -10,7 +11,6 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import javafx.scene.paint.Paint; -import javafx.scene.Scene; import javax.swing.JPanel; diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index 8018f2e27f0..46b8c724fc1 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -1,28 +1,28 @@ package org.jabref.gui.preftabs; - import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.Locale; import java.util.List; +import java.util.Locale; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; -import javafx.scene.control.ListView; import javafx.scene.control.Label; +import javafx.scene.control.ListView; import javafx.scene.control.RadioButton; import javafx.scene.control.ScrollPane; -import javafx.scene.control.TableView; import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.control.cell.TextFieldTableCell; @@ -30,7 +30,6 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; -import javafx.scene.Scene; import javax.swing.AbstractAction; import javax.swing.JPanel; @@ -145,7 +144,7 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { Button addRow = new Button("Add"); addRow.setOnAction( e -> { if (!addLast.getText().isEmpty()) { - TableRow tableRow = addLast.getText().matches("[1-9][0-9]+(.) ?[0-9]+")? new TableRow(addName.getText(), Integer.valueOf(addLast.getText())):new TableRow(addName.getText()); + TableRow tableRow = addLast.getText().matches("[1-9][0-9]") ? new TableRow(addName.getText(), Integer.valueOf(addLast.getText())) : new TableRow(addName.getText()); addName.clear(); addLast.clear(); data.add(tableRow); @@ -159,7 +158,7 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { }); Button deleteRow = new Button("Delete"); - deleteRow.setOnAction(e -> {if (colSetup.getFocusModel() != null && colSetup.getFocusModel().getFocusedIndex()!= -1) { + deleteRow.setOnAction(e -> {if (colSetup.getFocusModel() != null && colSetup.getFocusModel().getFocusedIndex() != -1) { tableChanged = true; int row = colSetup.getFocusModel().getFocusedIndex(); TableRow tableRow = data.get(row); @@ -172,7 +171,7 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { }}); Button up = new Button("Up"); up.setOnAction(e-> { - if (colSetup.getFocusModel()!=null) { + if (colSetup.getFocusModel() != null) { int row = colSetup.getFocusModel().getFocusedIndex(); if (row > data.size() || row == 0) { return; @@ -235,7 +234,7 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { listOfFileColumnsScrollPane.setMaxHeight(80); listOfFileColumnsScrollPane.setContent(listOfFileColumnsVBox); extraFileColumns = new CheckBox(Localization.lang("Show extra columns")); - if (!extraFileColumns.isSelected()){ + if (!extraFileColumns.isSelected()) { listOfFileColumnsVBox.setDisable(true); } extraFileColumns.setOnAction(arg0 -> listOfFileColumnsVBox.setDisable(!extraFileColumns.isSelected())); @@ -338,8 +337,7 @@ public void setValues() { } } } - for (int i=0; i names = JabRefPreferences.getInstance().getStringList(JabRefPreferences.XMP_PRIVACY_FILTERS); Listnames = new ArrayList<>(); - for (TextField textField : textFields){ + for (TextField textField : textFields) { names.add(textField.getText()); } tableRows.addAll(names); diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java index 43bcb520cd5..8aba054632c 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java @@ -45,10 +45,10 @@ public JPanel getSettingsPanel() { return settings; } - public GridPane getJFXSettingPane(){ + public GridPane getJFXSettingPane() { application.initParameters(); String commandPath = Globals.prefs.get(application.commandPathPreferenceKey); - if(jfxSettings == null){ + if (jfxSettings == null) { initJFXSettingsPanel(); } path1.setText(commandPath); diff --git a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java index 77eea7247f5..53ac3825dd2 100644 --- a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java @@ -19,7 +19,7 @@ public JPanel getSettingsPanel() { } @Override - public GridPane getJFXSettingPane(){ + public GridPane getJFXSettingPane() { additionalParams.setText(Globals.prefs.get(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS)); return super.getJFXSettingPane(); } diff --git a/src/main/java/org/jabref/model/strings/StringUtil.java b/src/main/java/org/jabref/model/strings/StringUtil.java index 75b9518ec32..05674f51a5a 100644 --- a/src/main/java/org/jabref/model/strings/StringUtil.java +++ b/src/main/java/org/jabref/model/strings/StringUtil.java @@ -197,7 +197,7 @@ public static String wrap(String in, int wrapAmount, String newline) { String[] lines = in.split("\n"); StringBuilder result = new StringBuilder(); // remove all whitespace at the end of the string, this especially includes \r created when the field content has \r\n as line separator - addWrappedLine(result, CharMatcher.WHITESPACE.trimTrailingFrom(lines[0]), wrapAmount, newline); // See + addWrappedLine(result, CharMatcher.whitespace().trimTrailingFrom(lines[0]), wrapAmount, newline); // See for (int i = 1; i < lines.length; i++) { if (lines[i].trim().isEmpty()) { @@ -209,7 +209,7 @@ public static String wrap(String in, int wrapAmount, String newline) { result.append(newline); result.append('\t'); // remove all whitespace at the end of the string, this especially includes \r created when the field content has \r\n as line separator - String line = CharMatcher.WHITESPACE.trimTrailingFrom(lines[i]); + String line = CharMatcher.whitespace().trimTrailingFrom(lines[i]); addWrappedLine(result, line, wrapAmount, newline); } } From 58b52fa3525077200ee9a1aaa6695fc3a1eda9f6 Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 16:23:37 +0800 Subject: [PATCH 10/58] resolve the conficts --- .../java/org/jabref/gui/importer/ImportInspectionDialog.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java index 06c42fd7d32..84fcef65d67 100644 --- a/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java +++ b/src/main/java/org/jabref/gui/importer/ImportInspectionDialog.java @@ -143,8 +143,7 @@ * receiving this call). */ -public class ImportInspectionDialog extends JabRefDialog - implements OutputPrinter { +public class ImportInspectionDialog extends JabRefDialog implements OutputPrinter { private static final Logger LOGGER = LoggerFactory.getLogger(ImportInspectionDialog.class); private static final List INSPECTION_FIELDS = Arrays.asList(FieldName.AUTHOR, FieldName.TITLE, FieldName.YEAR, BibEntry.KEY_FIELD); From ab3f78ce8fe24099c3643642ff54077fab286426 Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 16:46:18 +0800 Subject: [PATCH 11/58] polish the code style --- CHANGELOG.md | 14 +++++++------- build.gradle | 4 ++-- .../bibtexkeypattern/BibtexKeyPatternPanel.java | 16 ++++++++-------- .../jabref/gui/preftabs/NameFormatterTab.java | 3 ++- .../org/jabref/gui/preftabs/TableColumnsTab.java | 5 +++-- .../org/jabref/gui/preftabs/TablePrefsTab.java | 2 +- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecfe75729ba..94d83392668 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. - Window state is saved on close and restored on start. - We streamlined the process to rename and move files by removing the confirmation dialogs. - +- We changed part of the dialog (Options->Preferences) to JavaFX. https://github.com/JabRef/jabref/issues/3861 @@ -112,9 +112,9 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# ## Older versions -The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). -The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). -The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). +The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). +The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). +The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). [Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD [4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 @@ -243,9 +243,9 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# ## Older versions -The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). -The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). -The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). +The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). +The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). +The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). [Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD [4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 diff --git a/build.gradle b/build.gradle index e416e9e9970..39db6f916e3 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ plugins { id "de.sebastianboegl.shadow.transformer.log4j" version "2.1.1" id "com.simonharrer.modernizer" version '1.6.0-1' id 'me.champeau.gradle.jmh' version '0.4.7' - id 'net.ltgt.errorprone' version '0.0.15' + id 'net.ltgt.errorprone' version '0.0.16' id 'com.github.ben-manes.versions' version '0.20.0' } @@ -160,7 +160,7 @@ dependencies { testCompile 'org.junit-pioneer:junit-pioneer:0.1.2' testRuntime 'org.apache.logging.log4j:log4j-core:2.11.0' testRuntime 'org.apache.logging.log4j:log4j-jul:2.11.0' - testCompile 'org.mockito:mockito-core:2.20.0' + testCompile 'org.mockito:mockito-core:2.21.0' testCompile 'com.github.tomakehurst:wiremock:2.18.0' testCompile 'org.assertj:assertj-swing-junit:3.8.0' testCompile 'org.reflections:reflections:0.9.11' diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java index 3ad6b0f29af..71495ba85ad 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java @@ -15,6 +15,13 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.help.HelpAction; @@ -29,13 +36,6 @@ import org.jabref.model.entry.EntryType; import org.jabref.preferences.JabRefPreferences; -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextField; - public class BibtexKeyPatternPanel extends JPanel { // used by both BibtexKeyPatternPanel and TabLabelPAttern @@ -226,7 +226,7 @@ private void addExtraText() { label[16] = new Label("Standard"); label[17] = new Label("TechReport"); label[18] = new Label("Unpublished"); - for (int i=0; i <= 18; i++) { + for (int i = 0; i <= 18; i++) { gridPane.add(label[i],1,i + 3); gridPane.add(textFieldArray[i],2,i + 3); gridPane.add(button[i],3,i + 3); diff --git a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java index 3e02b99ce57..fbe658f4550 100644 --- a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java @@ -138,7 +138,8 @@ public NameFormatterTab(JabRefPreferences prefs) { } }); Button delete = new Button("Delete"); - delete.setOnAction(e-> {if (table.getFocusModel() != null && table.getFocusModel().getFocusedIndex() != -1) { + delete.setOnAction(e-> { + if (table.getFocusModel() != null && table.getFocusModel().getFocusedIndex() != -1) { tableChanged = true; int row = table.getFocusModel().getFocusedIndex(); TableRow tableRow = tableRows.get(row); diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index 46b8c724fc1..99b95d5331e 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -158,7 +158,8 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { }); Button deleteRow = new Button("Delete"); - deleteRow.setOnAction(e -> {if (colSetup.getFocusModel() != null && colSetup.getFocusModel().getFocusedIndex() != -1) { + deleteRow.setOnAction(e -> { + if (colSetup.getFocusModel() != null && colSetup.getFocusModel().getFocusedIndex() != -1) { tableChanged = true; int row = colSetup.getFocusModel().getFocusedIndex(); TableRow tableRow = data.get(row); @@ -190,7 +191,7 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { }); Button down = new Button("Down"); down.setOnAction(e-> { - if (colSetup.getFocusModel()!=null) { + if (colSetup.getFocusModel() != null) { int row = colSetup.getFocusModel().getFocusedIndex(); if (row + 1 > data.size()) { return; diff --git a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java index c1ca5cf943d..903c36e5375 100644 --- a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java @@ -11,9 +11,9 @@ import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; -import javafx.scene.control.Label; import javafx.scene.layout.GridPane; import javax.swing.JPanel; From 4f1c8ca729b4ceb8ff0231e005b0f9563b53772c Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 16:54:03 +0800 Subject: [PATCH 12/58] reslove the conflicts --- CHANGELOG.md | 141 +++------------------------------------------------ 1 file changed, 6 insertions(+), 135 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94d83392668..dad2a071302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,133 +1,3 @@ -<<<<<<< HEAD -# Changelog -All notable changes to this project will be documented in this file. -This project **does not** adhere to [Semantic Versioning](http://semver.org/). -This file tries to follow the conventions proposed by [keepachangelog.com](http://keepachangelog.com/). -Here, the categories "Changed" for added and changed functionality, -"Fixed" for fixed functionality, and -"Removed" for removed functionality are used. - -We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#NUM`. - -## [Unreleased] - -### Changed -- We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) -- Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) -- We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) -- The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. -- We added a button in the tab header which allows you to close the database with one click. https://github.com/JabRef/jabref/issues/494 -- Sorting in the main table now takes information from cross-referenced entries into account. https://github.com/JabRef/jabref/issues/2808 -- If a group has a color specified, then entries matched by this group have a small colored bar in front of them in the main table. -- Change default icon for groups to a circle because a colored version of the old icon was hard to distinguish from its black counterpart. -- In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) -- We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. -- We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). -- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. -- Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. -- Window state is saved on close and restored on start. -- We streamlined the process to rename and move files by removing the confirmation dialogs. -- We changed part of the dialog (Options->Preferences) to JavaFX. https://github.com/JabRef/jabref/issues/3861 - - - - - -### Fixed -- We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) -- Italic text is now rendered correctly. https://github.com/JabRef/jabref/issues/3356 -- The entry editor no longer gets corrupted after using the source tab. https://github.com/JabRef/jabref/issues/3532 https://github.com/JabRef/jabref/issues/3608 https://github.com/JabRef/jabref/issues/3616 -- We fixed multiple issues where entries did not show up after import if a search was active. https://github.com/JabRef/jabref/issues/1513 https://github.com/JabRef/jabref/issues/3219 -- We fixed an issue where the group tree was not updated correctly after an entry was changed. https://github.com/JabRef/jabref/issues/3618 -- We fixed an issue where a right-click in the main table selected a wrong entry. https://github.com/JabRef/jabref/issues/3267 -- We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 -- We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 -- We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 -- We fixed an issue where commands followed by `-` didn't work. [#3805](https://github.com/JabRef/jabref/issues/3805) -- We fixed an issue where some journal names were wrongly marked as abbreviated. [#4115](https://github.com/JabRef/jabref/issues/4115) -- We fixed an issue where the custom file column were sorted incorrectly. https://github.com/JabRef/jabref/issues/3119 -- We fixed an issues where the entry losses focus when a field is edited and at the same time used for sorting. https://github.com/JabRef/jabref/issues/3373 -- We fixed an issue where the menu on Mac OS was not displayed in the usual Mac-specific way. https://github.com/JabRef/jabref/issues/3146 -- We fixed an issue where the order of fields in customized entry types was not saved correctly. [#4033](http://github.com/JabRef/jabref/issues/4033) -- We fixed an issue where the groups tree of the last database was still shown even after the database was already closed. -- We fixed an issue where the "Open file dialog" may disappear behind other windows. https://github.com/JabRef/jabref/issues/3410 -- We fixed an issue where the default icon of a group was not colored correctly. -- We fixed an issue where the first field in entry editor was not focused when adding a new entry. [#4024](https://github.com/JabRef/jabref/issues/4024) -- We reworked the "Edit file" dialog to make it resizeable and improved the workflow for adding and editing files https://github.com/JabRef/jabref/issues/2970 -- We fixed an issue where the month was not shown in the preview https://github.com/JabRef/jabref/issues/3239. -- Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) -- We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) -- We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) -- We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) - - - - - - - - - - - -### Removed -- The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. -- The number column was removed. -- We removed the coloring of cells in the maintable according to whether the field is optional/required. -- We removed a few commands from the right-click menu that are not needed often and thus don't need to be placed that prominently: - - Print entry preview: available through entry preview - - All commands related to marking: marking is not yet reimplemented - - Set/clear/append/rename fields: available through Edit menu - - Manage keywords: available through Edit menu - - Copy linked files to folder: available through File menu - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## Older versions - -The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). -The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). -The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). - -[Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD -[4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 -[4.2]: https://github.com/JabRef/jabref/compare/v4.1...v4.2 -[4.1]: https://github.com/JabRef/jabref/compare/v4.0...v4.1 -[4.0]: https://github.com/JabRef/jabref/compare/v4.0-beta3...v4.0 -[4.0-beta3]: https://github.com/JabRef/jabref/compare/v4.0-beta2...v4.0-beta3 -[4.0-beta2]: https://github.com/JabRef/jabref/compare/v4.0-beta...v4.0-beta2 -[4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta -[2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 -[JavaFX]: https://en.wikipedia.org/wiki/JavaFX - -======= # Changelog All notable changes to this project will be documented in this file. This project **does not** adhere to [Semantic Versioning](http://semver.org/). @@ -155,9 +25,10 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. - Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. - Window state is saved on close and restored on start. -- Files without a defined external file type are now directly opened with the default aplication of the operating system +- Files without a defined external file type are now directly opened with the default application of the operating system - We streamlined the process to rename and move files by removing the confirmation dialogs. - +- We removed the redundant new lines of markings and wrapped the summary in the File annotation tab. [#3823](https://github.com/JabRef/jabref/issues/3823) +- We changed part of the dialog (Options -> Preference) to javaFX. https://github.com/JabRef/jabref/issues/3861 @@ -190,8 +61,9 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) - We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) - We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) -- We fixed an issue where filles added via the "Attach file" contextmenu of an entry were not made relative. [#4201](https://github.com/JabRef/jabref/issues/4201) - +- We fixed an issue where users were vulnerable to XXE attacks during parsing [#4229](https://github.com/JabRef/jabref/issues/4229) +- We fixed an issue where files added via the "Attach file" contextmenu of an entry were not made relative. [#4201](https://github.com/JabRef/jabref/issues/4201) +- We fixed an issue where author list parser can't generate bibtex for Chinese author. [#4169](https://github.com/JabRef/jabref/issues/4169) @@ -257,4 +129,3 @@ The changelog of JabRef 2.11 and all previous versions is available as [text fil [4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta [2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 [JavaFX]: https://en.wikipedia.org/wiki/JavaFX ->>>>>>> 077fdacc2ddc7beb7d22ba96ead8b400c91b3631 From ab409da8dd291c7539563d4e20b187820e320467 Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 17:07:41 +0800 Subject: [PATCH 13/58] resolve the conflict --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dad2a071302..cbf643ae6f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Files without a defined external file type are now directly opened with the default application of the operating system - We streamlined the process to rename and move files by removing the confirmation dialogs. - We removed the redundant new lines of markings and wrapped the summary in the File annotation tab. [#3823](https://github.com/JabRef/jabref/issues/3823) -- We changed part of the dialog (Options -> Preference) to javaFX. https://github.com/JabRef/jabref/issues/3861 + From 278693bcbac27c4c86fa44d4028dda32520469ae Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 17:15:18 +0800 Subject: [PATCH 14/58] Change the CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbf643ae6f4..dad2a071302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Files without a defined external file type are now directly opened with the default application of the operating system - We streamlined the process to rename and move files by removing the confirmation dialogs. - We removed the redundant new lines of markings and wrapped the summary in the File annotation tab. [#3823](https://github.com/JabRef/jabref/issues/3823) - +- We changed part of the dialog (Options -> Preference) to javaFX. https://github.com/JabRef/jabref/issues/3861 From 0b5c0cf1c840c2462c0442d3870b9dd423d47608 Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 19:48:13 +0800 Subject: [PATCH 15/58] polish the code style --- src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java | 8 ++++---- src/main/java/org/jabref/gui/preftabs/AdvancedTab.java | 6 ++---- .../org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java | 2 -- .../java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java | 4 ++-- .../org/jabref/gui/preftabs/ExportSortingPrefsTab.java | 4 ++-- src/main/java/org/jabref/gui/preftabs/ExternalTab.java | 6 +++--- src/main/java/org/jabref/gui/preftabs/FileTab.java | 4 ++-- src/main/java/org/jabref/gui/preftabs/GeneralTab.java | 4 ++-- src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java | 4 ++-- .../java/org/jabref/gui/preftabs/ImportSettingsTab.java | 4 ++-- .../java/org/jabref/gui/preftabs/NameFormatterTab.java | 4 ++-- src/main/java/org/jabref/gui/preftabs/NetworkTab.java | 4 ++-- .../java/org/jabref/gui/preftabs/TableColumnsTab.java | 8 ++++---- src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java | 5 ++--- src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java | 1 + .../org/jabref/gui/push/PushToApplicationSettings.java | 3 +++ .../java/org/jabref/gui/push/PushToEmacsSettings.java | 1 + 17 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index 68e6d89161c..5ee3a866da3 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -5,6 +5,10 @@ import java.util.Locale; import java.util.Objects; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JPanel; + import javafx.collections.FXCollections; import javafx.scene.Node; import javafx.scene.control.CheckBox; @@ -12,10 +16,6 @@ import javafx.scene.control.Label; import javafx.scene.layout.GridPane; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JPanel; - import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; diff --git a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java index 7320b002346..ae7d707ba2e 100644 --- a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java @@ -3,6 +3,8 @@ import java.awt.BorderLayout; import java.util.Optional; +import javax.swing.JPanel; + import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.control.Button; @@ -15,8 +17,6 @@ import javafx.scene.layout.Pane; import javafx.scene.shape.Line; -import javax.swing.JPanel; - import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.customjfx.CustomJFXPanel; @@ -30,8 +30,6 @@ import org.jabref.logic.remote.RemoteUtil; import org.jabref.preferences.JabRefPreferences; - - class AdvancedTab extends JPanel implements PrefsTab { private final JabRefPreferences preferences; diff --git a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java index 83e6d50110a..840b05b31e6 100644 --- a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java +++ b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java @@ -81,8 +81,6 @@ public void storeSettings() { } private void appendKeyGeneratorSettings() { - - // Build a panel for checkbox settings: builder.add(new Label(Localization.lang("Key generator settings")),1,10); diff --git a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java index 913684fd533..85b15062fd4 100644 --- a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java @@ -2,6 +2,8 @@ import java.awt.BorderLayout; +import javax.swing.JPanel; + import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.control.CheckBox; @@ -11,8 +13,6 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; -import javax.swing.JPanel; - import org.jabref.gui.autocompleter.AutoCompleteFirstNameMode; import org.jabref.gui.autocompleter.AutoCompletePreferences; import org.jabref.gui.customjfx.CustomJFXPanel; diff --git a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java index 228c51f91f9..a5ff4d5b30c 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java @@ -2,6 +2,8 @@ import java.awt.BorderLayout; +import javax.swing.JPanel; + import javafx.embed.swing.JFXPanel; import javafx.event.EventHandler; import javafx.scene.Scene; @@ -11,8 +13,6 @@ import javafx.scene.layout.GridPane; import javafx.scene.shape.Line; -import javax.swing.JPanel; - import org.jabref.gui.SaveOrderConfigDisplay; import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; diff --git a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java index db055e3c6de..3c68cac72bb 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java @@ -2,6 +2,9 @@ import java.awt.BorderLayout; +import javax.swing.JFileChooser; +import javax.swing.JPanel; + import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.control.Button; @@ -11,9 +14,6 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; -import javax.swing.JFileChooser; -import javax.swing.JPanel; - import org.jabref.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.customjfx.CustomJFXPanel; diff --git a/src/main/java/org/jabref/gui/preftabs/FileTab.java b/src/main/java/org/jabref/gui/preftabs/FileTab.java index 47bbceb0663..991445ca644 100644 --- a/src/main/java/org/jabref/gui/preftabs/FileTab.java +++ b/src/main/java/org/jabref/gui/preftabs/FileTab.java @@ -5,6 +5,8 @@ import java.nio.file.Path; import java.nio.file.Paths; +import javax.swing.JPanel; + import javafx.collections.FXCollections; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; @@ -16,8 +18,6 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; -import javax.swing.JPanel; - import org.jabref.gui.DialogService; import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index f6156bca3f1..071bccb1242 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -4,6 +4,8 @@ import java.nio.charset.Charset; import java.time.format.DateTimeFormatter; +import javax.swing.JPanel; + import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.embed.swing.JFXPanel; @@ -17,8 +19,6 @@ import javafx.scene.layout.GridPane; import javafx.scene.shape.Line; -import javax.swing.JPanel; - import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.customjfx.CustomJFXPanel; diff --git a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java index a051c556efa..7be02079f7d 100644 --- a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java @@ -2,6 +2,8 @@ import java.awt.BorderLayout; +import javax.swing.JPanel; + import javafx.embed.swing.JFXPanel; import javafx.event.ActionEvent; import javafx.event.EventHandler; @@ -12,8 +14,6 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; -import javax.swing.JPanel; - import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.groups.GroupViewMode; import org.jabref.logic.l10n.Localization; diff --git a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java index 4a5c09e4af9..4fc55e9ae6a 100644 --- a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java @@ -3,6 +3,8 @@ import java.awt.BorderLayout; import java.util.Objects; +import javax.swing.JPanel; + import javafx.collections.FXCollections; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; @@ -14,8 +16,6 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; -import javax.swing.JPanel; - import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.pdfimport.ImportDialog; diff --git a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java index fbe658f4550..5461b1ce00e 100644 --- a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java @@ -5,6 +5,8 @@ import java.util.List; import java.util.Objects; +import javax.swing.JPanel; + import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -22,8 +24,6 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; -import javax.swing.JPanel; - import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.logic.help.HelpFile; diff --git a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java index c7b03a533de..134930ee726 100644 --- a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java @@ -2,6 +2,8 @@ import java.awt.BorderLayout; +import javax.swing.JPanel; + import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.control.CheckBox; @@ -12,8 +14,6 @@ import javafx.scene.layout.GridPane; import javafx.scene.paint.Paint; -import javax.swing.JPanel; - import org.jabref.gui.DialogService; import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.util.DefaultTaskExecutor; diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index 99b95d5331e..caa22b34cf8 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -9,6 +9,9 @@ import java.util.List; import java.util.Locale; +import javax.swing.AbstractAction; +import javax.swing.JPanel; + import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; @@ -31,9 +34,6 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; -import javax.swing.AbstractAction; -import javax.swing.JPanel; - import org.jabref.gui.BasePanel; import org.jabref.gui.JabRefFrame; import org.jabref.gui.customjfx.CustomJFXPanel; @@ -45,6 +45,7 @@ import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibtexSingleField; import org.jabref.preferences.JabRefPreferences; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -430,7 +431,6 @@ public void setLength(double length) { } } - class UpdateOrderAction extends AbstractAction { public UpdateOrderAction() { diff --git a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java index 903c36e5375..e0eb1bcf885 100644 --- a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java @@ -6,6 +6,8 @@ import java.util.Locale; import java.util.Objects; +import javax.swing.JPanel; + import javafx.collections.FXCollections; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; @@ -16,8 +18,6 @@ import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; -import javax.swing.JPanel; - import org.jabref.Globals; import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; @@ -174,7 +174,6 @@ public void setValues() { secField.setText(prefs.get(JabRefPreferences.TABLE_SECONDARY_SORT_FIELD)); terField.setText(prefs.get(JabRefPreferences.TABLE_TERTIARY_SORT_FIELD)); - if (prefs.getBoolean(JabRefPreferences.NAMES_AS_IS)) { namesAsIs.setSelected(true); } else if (prefs.getBoolean(JabRefPreferences.NAMES_FIRST_LAST)) { diff --git a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java index 3d83d220f58..1fa32f328f6 100644 --- a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java @@ -102,6 +102,7 @@ public AddRowAction() { tableChanged = true; } } + /** * Load settings from the preferences and initialize the table. */ diff --git a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java index 8aba054632c..3dbc5993c93 100644 --- a/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToApplicationSettings.java @@ -8,6 +8,7 @@ import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; + import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.util.DefaultTaskExecutor; @@ -54,6 +55,7 @@ public GridPane getJFXSettingPane() { path1.setText(commandPath); return jfxSettings; } + /** * Create a FormBuilder, fill it with a textbox for the path and store the JPanel in settings */ @@ -102,6 +104,7 @@ protected void initJFXSettingsPanel() { .ifPresent(f -> path.setText(f.toAbsolutePath().toString()))); jfxSettings.add(browse,3, 1); } + /** * This method is called to indicate that the settings panel returned from the getSettingsPanel() method has been * shown to the user and that the user has indicated that the settings should be stored. This method must store the diff --git a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java index 53ac3825dd2..155fe5f5daa 100644 --- a/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java +++ b/src/main/java/org/jabref/gui/push/PushToEmacsSettings.java @@ -4,6 +4,7 @@ import javax.swing.JTextField; import javafx.scene.layout.GridPane; + import org.jabref.Globals; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; From e72485e1f66b4cd5aeb53eaaa09baa4e7d72d68f Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 19:59:49 +0800 Subject: [PATCH 16/58] polish the code style --- .../gui/bibtexkeypattern/BibtexKeyPatternPanel.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java index 71495ba85ad..e16f9d776fb 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java @@ -10,11 +10,6 @@ import java.util.Locale; import java.util.Map; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import javafx.scene.layout.GridPane; - import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JLabel; @@ -22,6 +17,11 @@ import javax.swing.JScrollPane; import javax.swing.JTextField; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.help.HelpAction; From 848478e7f531b2f1e62b76b4f39f87d2acf6d6e0 Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 23:07:52 +0800 Subject: [PATCH 17/58] Modify the code to make test-suite pass --- .../jabref/gui/SaveOrderConfigDisplay.java | 6 +-- .../org/jabref/gui/preftabs/AdvancedTab.java | 18 ++++++--- .../org/jabref/gui/preftabs/ExternalTab.java | 2 +- .../org/jabref/gui/preftabs/GeneralTab.java | 4 +- .../jabref/gui/preftabs/GroupsPrefsTab.java | 4 +- .../gui/preftabs/ImportSettingsTab.java | 38 +++++++++---------- .../jabref/gui/preftabs/NameFormatterTab.java | 26 ++++++------- .../org/jabref/gui/preftabs/NetworkTab.java | 4 +- .../jabref/gui/preftabs/TableColumnsTab.java | 24 ++++++------ .../jabref/gui/preftabs/TablePrefsTab.java | 16 ++++---- .../org/jabref/gui/preftabs/XmpPrefsTab.java | 6 +-- src/main/resources/l10n/JabRef_zh.properties | 2 - 12 files changed, 77 insertions(+), 73 deletions(-) diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index 5ee3a866da3..461930ac880 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -57,15 +57,15 @@ private void init() { saveTerDesc = new CheckBox(Localization.lang("Descending")); GridPane builder = new GridPane(); - builder.add(new Label(Localization.lang(" Primary sort criterion ")),1,1); + builder.add(new Label(Localization.lang("Primary sort criterion")),1,1); builder.add(savePriSort,2,1); builder.add(savePriDesc,3,1); - builder.add(new Label(Localization.lang("Secondary sort criterion ")),1,2); + builder.add(new Label(Localization.lang("Secondary sort criterion")),1,2); builder.add(saveSecSort,2,2); builder.add(saveSecDesc,3,2); - builder.add(new Label(Localization.lang(" Tertiary sort criterion ")),1, 3); + builder.add(new Label(Localization.lang("Tertiary sort criterion")),1, 3); builder.add(saveTerSort,2,3); builder.add(saveTerDesc,3,3); panel = builder; diff --git a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java index ae7d707ba2e..e8b11b93627 100644 --- a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java @@ -56,16 +56,23 @@ public AdvancedTab(DialogService dialogService, JabRefPreferences prefs) { builder.add(new Label(Localization.lang("Remote operation")),1,1); builder.add(new Separator(),2,1); builder.add(new Pane(),1,2); - builder.add(new Label(Localization.lang("This feature lets new files be opened or imported into an already running instance of JabRef instead of opening a new instance. For")),2,3); - builder.add(new Label(Localization.lang( "instance, this is useful when you open a file in JabRef from your web browser. ")),2,4); - builder.add(new Label(Localization.lang("Note that this will prevent you from running more than one instance of JabRef at a time.")),2,5); + Label label = new Label(Localization.lang("This feature lets new files be opened or imported into an " + + + "already running instance of JabRef
instead of opening a new instance. For instance, this " + + + "is useful when you open a file in JabRef
from your web browser." + + + "
Note that this will prevent you from running more than one instance of JabRef at a time.")); + builder.add(new Label("This feature lets new files be opened or imported into an already running instance of JabRef instead of opening a new instance. For"),2,3); + builder.add(new Label("instance, this is useful when you open a file in JabRef from your web browser. "),2,4); + builder.add(new Label("Note that this will prevent you from running more than one instance of JabRef at a time."),2,5); builder.add(new Line(),2,6); builder.add(new Pane(),2,7); HBox p = new HBox(); p.getChildren().add(useRemoteServer); p.getChildren().add(remoteServerPort); - Button button = new Button("?"); + Button button = new Button("Help"); button.setOnAction(event -> new HelpAction(HelpFile.REMOTE).getHelpButton().doClick()); p.getChildren().add(button); @@ -158,7 +165,7 @@ public boolean validateSettings() { } } catch (NumberFormatException ex) { - DefaultTaskExecutor.runInJavaFXThread(()-> dialogService.showErrorDialogAndWait(Localization.lang("Remote server port"), + DefaultTaskExecutor.runInJavaFXThread(()-> dialogService.showErrorDialogAndWait(Localization.lang("Remote server port"), Localization.lang("You must enter an integer value in the interval 1025-65535 in the text field for") + " '" + Localization.lang("Remote server port") + '\'')); @@ -170,5 +177,4 @@ public boolean validateSettings() { public String getTabName() { return Localization.lang("Advanced"); } - } diff --git a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java index 3c68cac72bb..9fdd66cbadf 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java @@ -96,7 +96,7 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere GridPane builder = new GridPane(); builder.add(new Label(Localization.lang("Sending of emails")),1,1); - Label lab = new Label(Localization.lang(" Subject for sending an email with references").concat(":")); + Label lab = new Label(Localization.lang("Subject for sending an email with references").concat(":")); builder.add(lab,1,2); emailSubject = new TextField(); builder.add(emailSubject,2,2); diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index 071bccb1242..fe1181785ea 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -70,7 +70,7 @@ public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { memoryStick = new CheckBox(Localization.lang("Load and Save preferences from/to jabref.xml on start-up (memory stick mode)")); useOwner = new CheckBox(Localization.lang("Mark new entries with owner name") + ':'); - updateTimeStamp = new CheckBox(Localization.lang(" Update timestamp on modification")); + updateTimeStamp = new CheckBox(Localization.lang("Update timestamp on modification")); useTimeStamp = new CheckBox(Localization.lang("Mark new entries with addition date") + ". " + Localization.lang("Date format") + ':'); if (!useTimeStamp.isSelected()) { @@ -78,7 +78,7 @@ public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { } useTimeStamp.setOnAction(e->updateTimeStamp.setDisable(!useTimeStamp.isSelected())); overwriteOwner = new CheckBox(Localization.lang("Overwrite")); - overwriteTimeStamp = new CheckBox(Localization.lang("Overwrite")); + overwriteTimeStamp = new CheckBox(Localization.lang("If a pasted or imported entry already has the field set, overwrite.")); enforceLegalKeys = new CheckBox(Localization.lang("Enforce legal characters in BibTeX keys")); confirmDelete = new CheckBox(Localization.lang("Show confirmation dialog when deleting entries")); diff --git a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java index 7be02079f7d..acec8e0b8b1 100644 --- a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java @@ -56,9 +56,9 @@ public void handle(ActionEvent event) { builder.add(autoAssignGroup,2,6); builder.add(new Label(Localization.lang("Dynamic groups")),1,7); - builder.add(new Label(Localization.lang(" Default grouping field") + ":"),1,8); + builder.add(new Label(Localization.lang("Default grouping field") + ":"),1,8); builder.add(groupingField,2,8); - builder.add(new Label(Localization.lang(" When adding/removing keywords, separate them by") + ":"),1,9); + builder.add(new Label(Localization.lang("When adding/removing keywords, separate them by") + ":"),1,9); builder.add(keywordSeparator,2,9); JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); diff --git a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java index 4fc55e9ae6a..280483e2277 100644 --- a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java @@ -60,7 +60,7 @@ public ImportSettingsTab(JabRefPreferences prefs) { fileDirPattern = new TextField(); selectFileNamePattern = new ComboBox<>(); selectFileNamePattern.getItems().addAll(FXCollections.observableArrayList(DEFAULT_FILENAMEPATTERNS_DISPLAY)); - selectFileNamePattern.setValue("Choose pattern"); + selectFileNamePattern.setValue(Localization.lang("Choose pattern")); selectFileNamePattern.setOnAction(e -> { fileNamePattern.setText(selectFileNamePattern.getValue()); }); @@ -75,12 +75,12 @@ public ImportSettingsTab(JabRefPreferences prefs) { builder.add(new Label(Localization.lang("Default PDF file link action")),1,7); - Label lab = new Label(Localization.lang(" Filename format pattern").concat(":")); + Label lab = new Label(Localization.lang("Filename format pattern").concat(":")); builder.add(lab,1,8); builder.add(fileNamePattern,2,8); builder.add(selectFileNamePattern,3,8); - Label lbfileDirPattern = new Label(Localization.lang(" File directory pattern").concat(":")); + Label lbfileDirPattern = new Label(Localization.lang("File directory pattern").concat(":")); builder.add(lbfileDirPattern,1,9); builder.add(fileDirPattern,2,9); @@ -95,22 +95,22 @@ public void setValues() { useDefaultPDFImportStyle.setSelected(prefs.getBoolean(JabRefPreferences.IMPORT_ALWAYSUSE)); int style = prefs.getInt(JabRefPreferences.IMPORT_DEFAULT_PDF_IMPORT_STYLE); switch (style) { - case ImportDialog.NOMETA: - radioButtonNoMeta.setSelected(true); - break; - case ImportDialog.XMP: - radioButtonXmp.setSelected(true); - break; - case ImportDialog.CONTENT: - radioButtonPDFcontent.setSelected(true); - break; - case ImportDialog.ONLYATTACH: - radioButtononlyAttachPDF.setSelected(true); - break; - default: - // fallback - radioButtonPDFcontent.setSelected(true); - break; + case ImportDialog.NOMETA: + radioButtonNoMeta.setSelected(true); + break; + case ImportDialog.XMP: + radioButtonXmp.setSelected(true); + break; + case ImportDialog.CONTENT: + radioButtonPDFcontent.setSelected(true); + break; + case ImportDialog.ONLYATTACH: + radioButtononlyAttachPDF.setSelected(true); + break; + default: + // fallback + radioButtonPDFcontent.setSelected(true); + break; } fileNamePattern.setText(prefs.get(JabRefPreferences.IMPORT_FILENAMEPATTERN)); fileDirPattern.setText(prefs.get(JabRefPreferences.IMPORT_FILEDIRPATTERN)); diff --git a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java index 5461b1ce00e..c4bf2322d2f 100644 --- a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java @@ -84,8 +84,8 @@ public NameFormatterTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); setLayout(new BorderLayout()); - TableColumn firstCol = new TableColumn<>("Formatter name"); - TableColumn lastCol = new TableColumn<>("Format string"); + TableColumn firstCol = new TableColumn<>(Localization.lang("Formatter name")); + TableColumn lastCol = new TableColumn<>(Localization.lang("Format string")); table = new TableView(); table.setEditable(true); firstCol.setCellValueFactory(new PropertyValueFactory<>("name")); @@ -123,7 +123,7 @@ public NameFormatterTab(JabRefPreferences prefs) { scrollPane.setContent(table); tabPanel.setCenter(scrollPane); - Button add = new Button("Add"); + Button add = new Button(Localization.lang("Insert rows")); add.setOnAction(e-> { if (!addName.getText().isEmpty() && !addLast.getText().isEmpty()) { TableRow tableRow = new TableRow(addName.getText(), addLast.getText()); @@ -137,18 +137,18 @@ public NameFormatterTab(JabRefPreferences prefs) { table.refresh(); } }); - Button delete = new Button("Delete"); + Button delete = new Button(Localization.lang("Delete rows")); delete.setOnAction(e-> { if (table.getFocusModel() != null && table.getFocusModel().getFocusedIndex() != -1) { - tableChanged = true; - int row = table.getFocusModel().getFocusedIndex(); - TableRow tableRow = tableRows.get(row); - tableRows.remove(tableRow); - data.remove(tableRow); - table.setItems(data); - rowCount--; - table.refresh(); - }}); + tableChanged = true; + int row = table.getFocusModel().getFocusedIndex(); + TableRow tableRow = tableRows.get(row); + tableRows.remove(tableRow); + data.remove(tableRow); + table.setItems(data); + rowCount--; + table.refresh(); + }}); Button help = new Button("Help"); help.setOnAction(e-> new HelpAction(Localization.lang("Help on Name Formatting"), HelpFile.CUSTOM_EXPORTS_NAME_FORMATTER).getHelpButton().doClick()); diff --git a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java index 134930ee726..2d81e629932 100644 --- a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java @@ -77,9 +77,9 @@ public NetworkTab(DialogService dialogService, JabRefPreferences preferences) { builder.add(new Label(Localization.lang("Network")),1,1); builder.add(new Separator(),2,1); builder.add(useProxyCheckBox,2,2); - builder.add(new Label(Localization.lang(" Hostname") + ':'),1,3); + builder.add(new Label(Localization.lang("Hostname") + ':'),1,3); builder.add(hostnameTextField,2,3); - builder.add(new Label(Localization.lang(" Port") + ':'),1,4); + builder.add(new Label(Localization.lang("Port") + ':'),1,4); builder.add(portTextField,2,4); builder.add(useAuthenticationCheckBox,2,5); builder.add(new Label(Localization.lang("Username") + ':'),2,6); diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index caa22b34cf8..e3991783850 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -107,8 +107,8 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { new TableRow("bibtexkey",100)); colSetup = new TableView<>(); - TableColumn field = new TableColumn<>("Field name"); - TableColumn column = new TableColumn<>("Column width"); + TableColumn field = new TableColumn<>(Localization.lang("Field name")); + TableColumn column = new TableColumn<>(Localization.lang("Column width")); field.setPrefWidth(400); column.setPrefWidth(240); field.setCellValueFactory(new PropertyValueFactory<>("name")); @@ -214,8 +214,8 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { fileColumn = new CheckBox(Localization.lang("Show file column")); urlColumn = new CheckBox(Localization.lang("Show URL/DOI column")); - preferUrl = new RadioButton(Localization.lang(" Show URL first")); - preferDoi = new RadioButton(Localization.lang(" Show DOI first")); + preferUrl = new RadioButton(Localization.lang("Show URL first")); + preferDoi = new RadioButton(Localization.lang("Show DOI first")); urlColumn.setOnAction(arg0 -> { preferUrl.setDisable(!urlColumn.isSelected()); @@ -247,18 +247,18 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { helpButton.setOnAction(e->new HelpAction(Localization.lang("Help on special fields"), HelpFile.SPECIAL_FIELDS).getHelpButton().doClick()); - rankingColumn = new CheckBox(Localization.lang(" Show rank")); - qualityColumn = new CheckBox(Localization.lang(" Show quality")); - priorityColumn = new CheckBox(Localization.lang(" Show priority")); - relevanceColumn = new CheckBox(Localization.lang(" Show relevance")); - printedColumn = new CheckBox(Localization.lang(" Show printed status")); - readStatusColumn = new CheckBox(Localization.lang(" Show read status")); + rankingColumn = new CheckBox(Localization.lang("Show rank")); + qualityColumn = new CheckBox(Localization.lang("Show quality")); + priorityColumn = new CheckBox(Localization.lang("Show priority")); + relevanceColumn = new CheckBox(Localization.lang("Show relevance")); + printedColumn = new CheckBox(Localization.lang("Show printed status")); + readStatusColumn = new CheckBox(Localization.lang("Show read status")); // "sync keywords" and "write special" fields may be configured mutually exclusive only // The implementation supports all combinations (TRUE+TRUE and FALSE+FALSE, even if the latter does not make sense) // To avoid confusion, we opted to make the setting mutually exclusive - syncKeywords = new RadioButton(Localization.lang(" Synchronize with keywords")); - writeSpecialFields = new RadioButton(Localization.lang(" Write values of special fields as separate fields to BibTeX")); + syncKeywords = new RadioButton(Localization.lang("Synchronize with keywords")); + writeSpecialFields = new RadioButton(Localization.lang("Write values of special fields as separate fields to BibTeX")); specialFieldsEnabled = new CheckBox(Localization.lang("Enable special fields")); specialFieldsEnabled.setOnAction(event -> { diff --git a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java index e0eb1bcf885..53030172f13 100644 --- a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java @@ -92,9 +92,9 @@ public TablePrefsTab(JabRefPreferences prefs) { numericFields = new TextField(); - priSort.setValue(""); - terSort.setValue("")); + secSort.setValue(Localization.lang("")); priSort.setOnAction(e -> { if (priSort.getBaselineOffset() > 0) { @@ -117,7 +117,7 @@ public TablePrefsTab(JabRefPreferences prefs) { terDesc = new CheckBox(Localization.lang("Descending")); GridPane builder = new GridPane(); - builder.add(new Label(Localization.lang("Format of author and editor name:")),1,1); + builder.add(new Label(Localization.lang("Format of author and editor names")),1,1); builder.add(namesAsIs,1,2); builder.add(noAbbrNames,2,2); builder.add(namesFf,1,3); @@ -131,26 +131,26 @@ public TablePrefsTab(JabRefPreferences prefs) { builder.add(new Label(Localization.lang("Default sort criteria")),1,6); // Create a new panel with its own FormLayout for these items: Label lab = new Label(); - lab = new Label(Localization.lang(" Primary sort criterion")); + lab = new Label(Localization.lang("Primary sort criterion")); builder.add(lab,1,7); builder.add(priSort,2,7); builder.add(priField,3,7); builder.add(priDesc,4,7); - lab = new Label(Localization.lang(" Secondary sort criterion")); + lab = new Label(Localization.lang("Secondary sort criterion")); builder.add(lab,1,8); builder.add(secSort,2,8); builder.add(secField,3,8); builder.add(secDesc,4,8); - lab = new Label(Localization.lang(" Tertiary sort criterion")); + lab = new Label(Localization.lang("Tertiary sort criterion")); builder.add(lab,1,9); builder.add(terSort,2,9); builder.add(terField,3,9); builder.add(terDesc,4,9); - builder.add(new Label(Localization.lang(" Sort the following fields as numeric fields") + ':'),1,10); + builder.add(new Label(Localization.lang("Sort the following fields as numeric fields") + ':'),1,10); builder.add(numericFields,2,10); builder.add(new Label(Localization.lang("General")),1,11); diff --git a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java index 1fa32f328f6..c2bdbd37970 100644 --- a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java @@ -55,7 +55,7 @@ public XmpPrefsTab(JabRefPreferences prefs) { scrollPane.setMaxHeight(400); scrollPane.setMaxWidth(170); textFields.add(new TextField("pdf")); - vBox.getChildren().add(new Label("field to filter")); + vBox.getChildren().add(new Label("Field to filter")); vBox.getChildren().addAll(textFields); scrollPane.setContent(vBox); tablePanel.setCenter(scrollPane); @@ -85,7 +85,7 @@ public DeleteRowAction() { textFields.remove(textFields.get(textFields.size() - 1)); rowCount--; vBox.getChildren().clear(); - vBox.getChildren().add(new Label("field to filter")); + vBox.getChildren().add(new Label(Localization.lang("Field to filter"))); vBox.getChildren().addAll(textFields); tableChanged = true; } @@ -112,7 +112,7 @@ public void setValues() { //List names = JabRefPreferences.getInstance().getStringList(JabRefPreferences.XMP_PRIVACY_FILTERS); Listnames = new ArrayList<>(); for (TextField textField : textFields) { - names.add(textField.getText()); + names.add(textField.getText()); } tableRows.addAll(names); rowCount = tableRows.size() + 5; diff --git a/src/main/resources/l10n/JabRef_zh.properties b/src/main/resources/l10n/JabRef_zh.properties index 52fd0017aa7..3d49f0abcb2 100644 --- a/src/main/resources/l10n/JabRef_zh.properties +++ b/src/main/resources/l10n/JabRef_zh.properties @@ -1913,5 +1913,3 @@ View\ change\ log=查看变更记录 View\ event\ log=查看事件日志 Website=网站 Write\ XMP-metadata\ to\ PDFs=将 XMP 元数据写入到 PDF 中 - -Removes\ all\ line\ breaks\ in\ the\ field\ content.=删除字段内容中所有的换行。 \ No newline at end of file From afbcee08315addd3e53c7c6c7fb208a37d0d6a1c Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Thu, 9 Aug 2018 23:18:27 +0800 Subject: [PATCH 18/58] polish the code style --- src/main/java/org/jabref/gui/preftabs/AdvancedTab.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java index e8b11b93627..90e0103bf6f 100644 --- a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java @@ -63,6 +63,8 @@ public AdvancedTab(DialogService dialogService, JabRefPreferences prefs) { + "is useful when you open a file in JabRef
from your web browser." + "
Note that this will prevent you from running more than one instance of JabRef at a time.")); + label.setVisible(false); + builder.add(label,2,22); builder.add(new Label("This feature lets new files be opened or imported into an already running instance of JabRef instead of opening a new instance. For"),2,3); builder.add(new Label("instance, this is useful when you open a file in JabRef from your web browser. "),2,4); builder.add(new Label("Note that this will prevent you from running more than one instance of JabRef at a time."),2,5); From 760b837d833efd2d46ea52a79ccf9e40b41cfd0b Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Fri, 10 Aug 2018 18:02:13 +0800 Subject: [PATCH 19/58] Beautify the option panes --- CHANGELOG.md | 262 +++++++-------- .../jabref/gui/SaveOrderConfigDisplay.java | 14 +- .../gui/actions/ShowPreferencesAction.java | 2 +- .../BibtexKeyPatternPanel.java | 23 +- .../org/jabref/gui/preftabs/AdvancedTab.java | 63 ++-- .../gui/preftabs/AppearancePrefsTab.java | 22 +- .../gui/preftabs/BibtexKeyPatternPrefTab.java | 31 +- .../gui/preftabs/EntryEditorPrefsTab.java | 105 +++--- .../gui/preftabs/ExportSortingPrefsTab.java | 32 +- .../org/jabref/gui/preftabs/ExternalTab.java | 63 ++-- .../java/org/jabref/gui/preftabs/FileTab.java | 92 +++-- .../org/jabref/gui/preftabs/GeneralTab.java | 106 +++--- .../jabref/gui/preftabs/GroupsPrefsTab.java | 49 +-- .../gui/preftabs/ImportSettingsTab.java | 51 +-- .../jabref/gui/preftabs/NameFormatterTab.java | 27 +- .../org/jabref/gui/preftabs/NetworkTab.java | 48 +-- .../gui/preftabs/PreferencesDialog.java | 313 ++++++++++++------ .../jabref/gui/preftabs/PreviewPrefsTab.java | 186 +++++------ .../jabref/gui/preftabs/TableColumnsTab.java | 55 ++- .../jabref/gui/preftabs/TablePrefsTab.java | 87 +++-- .../org/jabref/gui/preftabs/XmpPrefsTab.java | 135 +++++--- 21 files changed, 1011 insertions(+), 755 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0cc9ec60c5..b113818ebfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,135 +1,135 @@ <<<<<<< HEAD -# Changelog -All notable changes to this project will be documented in this file. -This project **does not** adhere to [Semantic Versioning](http://semver.org/). -This file tries to follow the conventions proposed by [keepachangelog.com](http://keepachangelog.com/). -Here, the categories "Changed" for added and changed functionality, -"Fixed" for fixed functionality, and -"Removed" for removed functionality are used. - -We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#NUM`. - -## [Unreleased] - -### Changed -- We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) -- Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) -- We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) -- The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. -- We added a button in the tab header which allows you to close the database with one click. https://github.com/JabRef/jabref/issues/494 -- Sorting in the main table now takes information from cross-referenced entries into account. https://github.com/JabRef/jabref/issues/2808 -- If a group has a color specified, then entries matched by this group have a small colored bar in front of them in the main table. -- Change default icon for groups to a circle because a colored version of the old icon was hard to distinguish from its black counterpart. -- In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) -- We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. -- We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). -- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. -- Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. -- Window state is saved on close and restored on start. -- Files without a defined external file type are now directly opened with the default application of the operating system -- We streamlined the process to rename and move files by removing the confirmation dialogs. -- We removed the redundant new lines of markings and wrapped the summary in the File annotation tab. [#3823](https://github.com/JabRef/jabref/issues/3823) -- We changed part of the dialog (Options -> Preference) to javaFX. https://github.com/JabRef/jabref/issues/3861 - - - - - - -### Fixed -- We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) -- Italic text is now rendered correctly. https://github.com/JabRef/jabref/issues/3356 -- The entry editor no longer gets corrupted after using the source tab. https://github.com/JabRef/jabref/issues/3532 https://github.com/JabRef/jabref/issues/3608 https://github.com/JabRef/jabref/issues/3616 -- We fixed multiple issues where entries did not show up after import if a search was active. https://github.com/JabRef/jabref/issues/1513 https://github.com/JabRef/jabref/issues/3219 -- We fixed an issue where the group tree was not updated correctly after an entry was changed. https://github.com/JabRef/jabref/issues/3618 -- We fixed an issue where a right-click in the main table selected a wrong entry. https://github.com/JabRef/jabref/issues/3267 -- We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 -- We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 -- We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 -- We fixed an issue where commands followed by `-` didn't work. [#3805](https://github.com/JabRef/jabref/issues/3805) -- We fixed an issue where some journal names were wrongly marked as abbreviated. [#4115](https://github.com/JabRef/jabref/issues/4115) -- We fixed an issue where the custom file column were sorted incorrectly. https://github.com/JabRef/jabref/issues/3119 -- We fixed an issues where the entry losses focus when a field is edited and at the same time used for sorting. https://github.com/JabRef/jabref/issues/3373 -- We fixed an issue where the menu on Mac OS was not displayed in the usual Mac-specific way. https://github.com/JabRef/jabref/issues/3146 -- We fixed an issue where the order of fields in customized entry types was not saved correctly. [#4033](http://github.com/JabRef/jabref/issues/4033) -- We fixed an issue where the groups tree of the last database was still shown even after the database was already closed. -- We fixed an issue where the "Open file dialog" may disappear behind other windows. https://github.com/JabRef/jabref/issues/3410 -- We fixed an issue where the default icon of a group was not colored correctly. -- We fixed an issue where the first field in entry editor was not focused when adding a new entry. [#4024](https://github.com/JabRef/jabref/issues/4024) -- We reworked the "Edit file" dialog to make it resizeable and improved the workflow for adding and editing files https://github.com/JabRef/jabref/issues/2970 -- We fixed an issue where the month was not shown in the preview https://github.com/JabRef/jabref/issues/3239. -- Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) -- We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) -- We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) -- We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) -- We fixed an issue where users were vulnerable to XXE attacks during parsing [#4229](https://github.com/JabRef/jabref/issues/4229) -- We fixed an issue where files added via the "Attach file" contextmenu of an entry were not made relative. [#4201](https://github.com/JabRef/jabref/issues/4201) -- We fixed an issue where author list parser can't generate bibtex for Chinese author. [#4169](https://github.com/JabRef/jabref/issues/4169) - - - - - - - - - -### Removed -- The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. -- The number column was removed. -- We removed the coloring of cells in the maintable according to whether the field is optional/required. -- We removed a few commands from the right-click menu that are not needed often and thus don't need to be placed that prominently: - - Print entry preview: available through entry preview - - All commands related to marking: marking is not yet reimplemented - - Set/clear/append/rename fields: available through Edit menu - - Manage keywords: available through Edit menu - - Copy linked files to folder: available through File menu - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## Older versions - -The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). -The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). -The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). - -[Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD -[4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 -[4.2]: https://github.com/JabRef/jabref/compare/v4.1...v4.2 -[4.1]: https://github.com/JabRef/jabref/compare/v4.0...v4.1 -[4.0]: https://github.com/JabRef/jabref/compare/v4.0-beta3...v4.0 -[4.0-beta3]: https://github.com/JabRef/jabref/compare/v4.0-beta2...v4.0-beta3 -[4.0-beta2]: https://github.com/JabRef/jabref/compare/v4.0-beta...v4.0-beta2 -[4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta -[2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 -[JavaFX]: https://en.wikipedia.org/wiki/JavaFX +# Changelog +All notable changes to this project will be documented in this file. +This project **does not** adhere to [Semantic Versioning](http://semver.org/). +This file tries to follow the conventions proposed by [keepachangelog.com](http://keepachangelog.com/). +Here, the categories "Changed" for added and changed functionality, +"Fixed" for fixed functionality, and +"Removed" for removed functionality are used. + +We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#NUM`. + +## [Unreleased] + +### Changed +- We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) +- Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) +- We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [4093](https://github.com/JabRef/jabref/issues/4093) +- The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. +- We added a button in the tab header which allows you to close the database with one click. https://github.com/JabRef/jabref/issues/494 +- Sorting in the main table now takes information from cross-referenced entries into account. https://github.com/JabRef/jabref/issues/2808 +- If a group has a color specified, then entries matched by this group have a small colored bar in front of them in the main table. +- Change default icon for groups to a circle because a colored version of the old icon was hard to distinguish from its black counterpart. +- In the main table, the context menu appears now when you press the "context menu" button on the keyboard. [feature request in the forum](http://discourse.jabref.org/t/how-to-enable-keyboard-context-key-windows) +- We added icons to the group side panel to quickly switch between `union` and `intersection` group view mode https://github.com/JabRef/jabref/issues/3269. +- We use `https` for [fetching from most online bibliographic database](https://help.jabref.org/en/#-using-online-bibliographic-database). +- We changed the default keyboard shortcuts for moving between entries when the entry editor is active to ̀alt + up/down. +- Opening a new file now prompts the directory of the currently selected file, instead of the directory of the last opened file. +- Window state is saved on close and restored on start. +- Files without a defined external file type are now directly opened with the default application of the operating system +- We streamlined the process to rename and move files by removing the confirmation dialogs. +- We removed the redundant new lines of markings and wrapped the summary in the File annotation tab. [#3823](https://github.com/JabRef/jabref/issues/3823) +- We converted the dialog (Options -> Preference) to javaFX. https://github.com/JabRef/jabref/issues/3861 + + + + + + +### Fixed +- We fixed an issue where custom exports could not be selected in the 'Export (selected) entries' dialog [#4013](https://github.com/JabRef/jabref/issues/4013) +- Italic text is now rendered correctly. https://github.com/JabRef/jabref/issues/3356 +- The entry editor no longer gets corrupted after using the source tab. https://github.com/JabRef/jabref/issues/3532 https://github.com/JabRef/jabref/issues/3608 https://github.com/JabRef/jabref/issues/3616 +- We fixed multiple issues where entries did not show up after import if a search was active. https://github.com/JabRef/jabref/issues/1513 https://github.com/JabRef/jabref/issues/3219 +- We fixed an issue where the group tree was not updated correctly after an entry was changed. https://github.com/JabRef/jabref/issues/3618 +- We fixed an issue where a right-click in the main table selected a wrong entry. https://github.com/JabRef/jabref/issues/3267 +- We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 +- We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 +- We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 +- We fixed an issue where commands followed by `-` didn't work. [#3805](https://github.com/JabRef/jabref/issues/3805) +- We fixed an issue where some journal names were wrongly marked as abbreviated. [#4115](https://github.com/JabRef/jabref/issues/4115) +- We fixed an issue where the custom file column were sorted incorrectly. https://github.com/JabRef/jabref/issues/3119 +- We fixed an issues where the entry losses focus when a field is edited and at the same time used for sorting. https://github.com/JabRef/jabref/issues/3373 +- We fixed an issue where the menu on Mac OS was not displayed in the usual Mac-specific way. https://github.com/JabRef/jabref/issues/3146 +- We fixed an issue where the order of fields in customized entry types was not saved correctly. [#4033](http://github.com/JabRef/jabref/issues/4033) +- We fixed an issue where the groups tree of the last database was still shown even after the database was already closed. +- We fixed an issue where the "Open file dialog" may disappear behind other windows. https://github.com/JabRef/jabref/issues/3410 +- We fixed an issue where the default icon of a group was not colored correctly. +- We fixed an issue where the first field in entry editor was not focused when adding a new entry. [#4024](https://github.com/JabRef/jabref/issues/4024) +- We reworked the "Edit file" dialog to make it resizeable and improved the workflow for adding and editing files https://github.com/JabRef/jabref/issues/2970 +- We fixed an issue where the month was not shown in the preview https://github.com/JabRef/jabref/issues/3239. +- Rewritten logic to detect a second jabref instance. [#4023](https://github.com/JabRef/jabref/issues/4023) +- We fixed an issue where the "Convert to BibTeX-Cleanup" moved the content of the `file` field to the `pdf` field [#4120](https://github.com/JabRef/jabref/issues/4120) +- We fixed an issue where the preview pane in entry preview in preferences wasn't showing the citation style selected [#3849](https://github.com/JabRef/jabref/issues/3849) +- We fixed an issue where the default entry preview style still contained the field `review`. The field `review` in the style is now replaced with comment to be consistent with the entry editor [#4098](https://github.com/JabRef/jabref/issues/4098) +- We fixed an issue where users were vulnerable to XXE attacks during parsing [#4229](https://github.com/JabRef/jabref/issues/4229) +- We fixed an issue where files added via the "Attach file" contextmenu of an entry were not made relative. [#4201](https://github.com/JabRef/jabref/issues/4201) +- We fixed an issue where author list parser can't generate bibtex for Chinese author. [#4169](https://github.com/JabRef/jabref/issues/4169) + + + + + + + + + +### Removed +- The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. +- The number column was removed. +- We removed the coloring of cells in the maintable according to whether the field is optional/required. +- We removed a few commands from the right-click menu that are not needed often and thus don't need to be placed that prominently: + - Print entry preview: available through entry preview + - All commands related to marking: marking is not yet reimplemented + - Set/clear/append/rename fields: available through Edit menu + - Manage keywords: available through Edit menu + - Copy linked files to folder: available through File menu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Older versions + +The changelog of JabRef 4.x is available at the [v4.x branch](https://github.com/JabRef/jabref/blob/v4.x/CHANGELOG.md). +The changelog of JabRef 3.x is available at the [v3.8.2 tag](https://github.com/JabRef/jabref/blob/v3.8.2/CHANGELOG.md). +The changelog of JabRef 2.11 and all previous versions is available as [text file in the v2.11.1 tag](https://github.com/JabRef/jabref/blob/v2.11.1/CHANGELOG). + +[Unreleased]: https://github.com/JabRef/jabref/compare/v4.3...HEAD +[4.3]: https://github.com/JabRef/jabref/compare/v4.2...v4.3 +[4.2]: https://github.com/JabRef/jabref/compare/v4.1...v4.2 +[4.1]: https://github.com/JabRef/jabref/compare/v4.0...v4.1 +[4.0]: https://github.com/JabRef/jabref/compare/v4.0-beta3...v4.0 +[4.0-beta3]: https://github.com/JabRef/jabref/compare/v4.0-beta2...v4.0-beta3 +[4.0-beta2]: https://github.com/JabRef/jabref/compare/v4.0-beta...v4.0-beta2 +[4.0-beta]: https://github.com/JabRef/jabref/compare/v3.8.2...v4.0-beta +[2.11.1]: https://github.com/JabRef/jabref/compare/v2.11...v2.11.1 +[JavaFX]: https://en.wikipedia.org/wiki/JavaFX ======= # Changelog All notable changes to this project will be documented in this file. diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index 461930ac880..8727d6ce17d 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -16,6 +16,7 @@ import javafx.scene.control.Label; import javafx.scene.layout.GridPane; +import javafx.scene.text.Font; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; @@ -56,16 +57,23 @@ private void init() { saveSecDesc = new CheckBox(Localization.lang("Descending")); saveTerDesc = new CheckBox(Localization.lang("Descending")); + Font font = new Font(10); GridPane builder = new GridPane(); - builder.add(new Label(Localization.lang("Primary sort criterion")),1,1); + Label label = new Label(Localization.lang("Primary sort criterion")); + label.setFont(font); + builder.add(label,1,1); builder.add(savePriSort,2,1); builder.add(savePriDesc,3,1); - builder.add(new Label(Localization.lang("Secondary sort criterion")),1,2); + Label label1 = new Label(Localization.lang("Secondary sort criterion")); + label1.setFont(font); + builder.add(label1,1,2); builder.add(saveSecSort,2,2); builder.add(saveSecDesc,3,2); - builder.add(new Label(Localization.lang("Tertiary sort criterion")),1, 3); + Label label2 = new Label(Localization.lang("Tertiary sort criterion")); + label2.setFont(font); + builder.add(label2,1, 3); builder.add(saveTerSort,2,3); builder.add(saveTerDesc,3,3); panel = builder; diff --git a/src/main/java/org/jabref/gui/actions/ShowPreferencesAction.java b/src/main/java/org/jabref/gui/actions/ShowPreferencesAction.java index 7e80756495f..13c5bf9a0c6 100644 --- a/src/main/java/org/jabref/gui/actions/ShowPreferencesAction.java +++ b/src/main/java/org/jabref/gui/actions/ShowPreferencesAction.java @@ -17,7 +17,7 @@ public void execute() { if (prefsDialog == null) { prefsDialog = new PreferencesDialog(jabRefFrame); } else { - prefsDialog.setValues(); +// prefsDialog.setValues(); } prefsDialog.showAndWait(); diff --git a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java index e16f9d776fb..54135491151 100644 --- a/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/bibtexkeypattern/BibtexKeyPatternPanel.java @@ -68,10 +68,11 @@ private void buildGUI() { sp.setBorder(BorderFactory.createEmptyBorder()); pan.setLayout(gbl); setLayout(gbl); - + javafx.scene.text.Font font1 = new javafx.scene.text.Font(10); // The header - can be removed JLabel lblEntryType = new JLabel(Localization.lang("Entry type")); Label label = new Label(Localization.lang("Entry type")); + label.setFont(font1); gridPane.add(label,1,1); Font f = new Font("plain", Font.BOLD, 12); lblEntryType.setFont(f); @@ -87,7 +88,8 @@ private void buildGUI() { JLabel lblKeyPattern = new JLabel(Localization.lang("Key pattern")); Label label1 = new Label(Localization.lang("Key pattern")); - gridPane.add(label1,2,1); + label1.setFont(font1); + gridPane.add(label1,3,1); lblKeyPattern.setFont(f); con.gridx = 1; con.gridy = 0; @@ -102,8 +104,9 @@ private void buildGUI() { con.gridx = 0; JLabel lab = new JLabel(Localization.lang("Default pattern")); Label label2 = new Label(Localization.lang("Default pattern")); + label2.setFont(font1); gridPane.add(label2, 1,2); - gridPane.add(textField,2,2); + gridPane.add(textField,3,2); gbl.setConstraints(lab, con); pan.add(lab); con.gridx = 1; @@ -115,8 +118,9 @@ private void buildGUI() { e -> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); Button button = new Button("Default"); + button.setFont(font1); button.setOnAction(e-> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); - gridPane.add(button,3,2); + gridPane.add(button,4,2); con.gridx = 2; int y = 2; gbl.setConstraints(btnDefault, con); @@ -158,7 +162,7 @@ private void buildGUI() { con.insets = new Insets(0, 5, 0, 5); JButton hlb = new JButton(IconTheme.JabRefIcons.HELP.getSmallIcon()); - Button help1 = new Button("Help"); + 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,24); @@ -189,6 +193,7 @@ private void buildGUI() { add(btnDefaultAll); Button btnDefaultAll1 = new Button(Localization.lang("Reset all")); + btnDefaultAll1.setFont(font1); btnDefaultAll1.setOnAction(e-> { // reset all fields for (JTextField field : textFields.values()) { @@ -196,7 +201,7 @@ private void buildGUI() { } textField.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN)); }); - gridPane.add(btnDefaultAll1,2,24); + gridPane.add(btnDefaultAll1,3,24); } private void addExtraText() { @@ -205,6 +210,7 @@ private void addExtraText() { for (int i = 0; i <= 18; i++) { textFieldArray[i] = new TextField(); button[i] = new Button("Default"); + button[i].setFont(new javafx.scene.text.Font(10)); button[i].setOnAction(e-> defaultPat.setText((String) Globals.prefs.defaults.get(JabRefPreferences.DEFAULT_BIBTEX_KEY_PATTERN))); } label[0] = new Label("Article"); @@ -227,9 +233,10 @@ private void addExtraText() { label[17] = new Label("TechReport"); label[18] = new Label("Unpublished"); for (int i = 0; i <= 18; i++) { + label[i].setFont(new javafx.scene.text.Font(10)); gridPane.add(label[i],1,i + 3); - gridPane.add(textFieldArray[i],2,i + 3); - gridPane.add(button[i],3,i + 3); + gridPane.add(textFieldArray[i],3,i + 3); + gridPane.add(button[i],4,i + 3); } } diff --git a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java index 90e0103bf6f..4315e34e9a0 100644 --- a/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AdvancedTab.java @@ -1,12 +1,7 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.Optional; -import javax.swing.JPanel; - -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; @@ -16,10 +11,10 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.shape.Line; +import javafx.scene.text.Font; import org.jabref.Globals; import org.jabref.gui.DialogService; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.gui.remote.JabRefMessageHandler; import org.jabref.gui.util.DefaultTaskExecutor; @@ -30,7 +25,7 @@ import org.jabref.logic.remote.RemoteUtil; import org.jabref.preferences.JabRefPreferences; -class AdvancedTab extends JPanel implements PrefsTab { +class AdvancedTab extends Pane implements PrefsTab { private final JabRefPreferences preferences; private final CheckBox useRemoteServer; @@ -38,6 +33,8 @@ class AdvancedTab extends JPanel implements PrefsTab { private final TextField remoteServerPort; private final CheckBox useCaseKeeperOnSearch; private final CheckBox useUnitFormatterOnSearch; + private final GridPane builder = new GridPane(); + private final RemotePreferences remotePreferences; private final DialogService dialogService; @@ -46,58 +43,78 @@ public AdvancedTab(DialogService dialogService, JabRefPreferences prefs) { preferences = prefs; remotePreferences = prefs.getRemotePreferences(); + Font font = new Font(10); + Font font1 = new Font(14); + useRemoteServer = new CheckBox(Localization.lang("Listen for remote operation on port") + ':'); + useRemoteServer.setFont(font); useIEEEAbrv = new CheckBox(Localization.lang("Use IEEE LaTeX abbreviations")); + useIEEEAbrv.setFont(font); remoteServerPort = new TextField(); useCaseKeeperOnSearch = new CheckBox(Localization.lang("Add {} to specified title words on search to keep the correct case")); + useCaseKeeperOnSearch.setFont(font); useUnitFormatterOnSearch = new CheckBox(Localization.lang("Format units by adding non-breaking separators and keeping the correct case on search")); + useUnitFormatterOnSearch.setFont(font); - GridPane builder = new GridPane(); - builder.add(new Label(Localization.lang("Remote operation")),1,1); + Label label = new Label(Localization.lang("Remote operation") + " -----------------------------"); + label.setFont(font1); + builder.add(label,2,1); builder.add(new Separator(),2,1); builder.add(new Pane(),1,2); - Label label = new Label(Localization.lang("This feature lets new files be opened or imported into an " + Label label1 = new Label(Localization.lang("This feature lets new files be opened or imported into an " + "already running instance of JabRef
instead of opening a new instance. For instance, this " + "is useful when you open a file in JabRef
from your web browser." + "
Note that this will prevent you from running more than one instance of JabRef at a time.")); - label.setVisible(false); - builder.add(label,2,22); - builder.add(new Label("This feature lets new files be opened or imported into an already running instance of JabRef instead of opening a new instance. For"),2,3); - builder.add(new Label("instance, this is useful when you open a file in JabRef from your web browser. "),2,4); - builder.add(new Label("Note that this will prevent you from running more than one instance of JabRef at a time."),2,5); + label1.setVisible(false); + builder.add(label1,2,22); + + Label label2 = new Label(" This feature lets new files be opened or imported into an already running instance of JabRef instead of opening a new instance. For"); + label2.setFont(font); + builder.add(label2,2,3); + Label label3 = new Label("instance, this is useful when you open a file in JabRef from your web browser. "); + label3.setFont(font); + builder.add(label3,2,4); + Label label4 = new Label(" Note that this will prevent you from running more than one instance of JabRef at a time."); + label4.setFont(font); + builder.add(label4,2,5); builder.add(new Line(),2,6); builder.add(new Pane(),2,7); HBox p = new HBox(); p.getChildren().add(useRemoteServer); p.getChildren().add(remoteServerPort); - Button button = new Button("Help"); + Button button = new Button("?"); button.setOnAction(event -> new HelpAction(HelpFile.REMOTE).getHelpButton().doClick()); p.getChildren().add(button); builder.add(p,2,9); + builder.add(new Label(""),1,10); - builder.add(new Line(),2,10); - builder.add(new Label((Localization.lang("Search %0", "IEEEXplore"))),1,11); + Label label5 = new Label(Localization.lang("Search %0", "IEEEXplore") + " -----------------------------"); + label5.setFont(font1); + builder.add(label5,2,11); builder.add(new Separator(),2,11); builder.add(new Pane(),2,12); builder.add(useIEEEAbrv,2,13); builder.add(new Line(),2,16); - builder.add(new Label(Localization.lang("Import conversions")),1,17); - builder.add(new Separator(),2,17); + builder.add(new Label(""),1,17); + + Label label6 = new Label(Localization.lang("Import conversions") + " ----------------------------"); + label6.setFont(font1); + builder.add(label6,2,18); builder.add(useCaseKeeperOnSearch,2,19); builder.add(new Pane(),2,20); builder.add(useUnitFormatterOnSearch,2,21); - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + } + public GridPane getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java index 9f65eb85c3c..367cc572fa1 100644 --- a/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/AppearancePrefsTab.java @@ -1,21 +1,14 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; - -import javax.swing.BorderFactory; -import javax.swing.JPanel; - -import javafx.embed.swing.JFXPanel; import javafx.geometry.Insets; -import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import org.jabref.gui.DialogService; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.util.ControlHelper; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -23,7 +16,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class AppearancePrefsTab extends JPanel implements PrefsTab { +class AppearancePrefsTab extends Pane implements PrefsTab { private static final Logger LOGGER = LoggerFactory.getLogger(AppearancePrefsTab.class); @@ -32,7 +25,7 @@ class AppearancePrefsTab extends JPanel implements PrefsTab { private final CheckBox fontTweaksLAF; private final TextField fontSize; private final CheckBox overrideFonts; - + private final VBox container = new VBox(); private final DialogService dialogService; /** @@ -43,7 +36,6 @@ class AppearancePrefsTab extends JPanel implements PrefsTab { public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) { this.dialogService = dialogService; this.prefs = prefs; - setLayout(new BorderLayout()); overrideFonts = new CheckBox(Localization.lang("Override default font settings")); fontSize = new TextField(); @@ -54,12 +46,12 @@ public AppearancePrefsTab(DialogService dialogService, JabRefPreferences prefs) fontSizeContainer.disableProperty().bind(overrideFonts.selectedProperty().not()); fontTweaksLAF = new CheckBox(Localization.lang("Tweak font rendering for entry editor on Linux")); - VBox container = new VBox(); container.getChildren().addAll(overrideFonts, fontSizeContainer, fontTweaksLAF); - JFXPanel panel = CustomJFXPanel.wrap(new Scene(container)); - panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - add(panel, BorderLayout.CENTER); + } + + public VBox getContainer() { + return container; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java index 840b05b31e6..69ea645d089 100644 --- a/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java +++ b/src/main/java/org/jabref/gui/preftabs/BibtexKeyPatternPrefTab.java @@ -1,19 +1,15 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; - -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.text.Font; import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.bibtexkeypattern.BibtexKeyPatternPanel; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.model.bibtexkeypattern.GlobalBibtexKeyPattern; import org.jabref.preferences.JabRefPreferences; @@ -41,10 +37,12 @@ class BibtexKeyPatternPrefTab extends BibtexKeyPatternPanel implements PrefsTab public BibtexKeyPatternPrefTab(JabRefPreferences prefs, BasePanel panel) { super(panel); builder.add(super.getPanel(),1,1); + builder.add(new Label(""),1,2); this.prefs = prefs; appendKeyGeneratorSettings(); } + /** * Store changes to table preferences. This method is called when the user clicks Ok. * @@ -83,7 +81,20 @@ public void storeSettings() { private void appendKeyGeneratorSettings() { // Build a panel for checkbox settings: - builder.add(new Label(Localization.lang("Key generator settings")),1,10); + Font font = new Font(10); + Font font1 = new Font(14); + + autoGenerateOnImport.setFont(font); + letterStartA.setFont(font); + warnBeforeOverwriting.setFont(font); + letterStartB.setFont(font); + dontOverwrite.setFont(font); + alwaysAddLetter.setFont(font); + generateOnSave.setFont(font); + + Label label = new Label(Localization.lang("Key generator settings") + " --------------------------"); + label.setFont(font1); + builder.add(label,1,10); builder.add(autoGenerateOnImport,1,11); builder.add(letterStartA,2,11); builder.add(warnBeforeOverwriting,1,12); @@ -98,15 +109,15 @@ private void appendKeyGeneratorSettings() { builder.add(keyPatternRegex,1,16); builder.add(keyPatternReplacement,2,16); - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); - dontOverwrite.setOnAction(e -> // Warning before overwriting is only relevant if overwriting can happen: warnBeforeOverwriting.setDisable(dontOverwrite.isSelected())); } + public GridPane getBuilder() { + return builder; + } + @Override public boolean validateSettings() { return true; diff --git a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java index 85b15062fd4..adb2b54d887 100644 --- a/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/EntryEditorPrefsTab.java @@ -1,30 +1,24 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; - -import javax.swing.JPanel; - -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.Separator; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.text.Font; import org.jabref.gui.autocompleter.AutoCompleteFirstNameMode; import org.jabref.gui.autocompleter.AutoCompletePreferences; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.keyboard.EmacsKeyBindings; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; - import static org.jabref.gui.autocompleter.AutoCompleteFirstNameMode.ONLY_ABBREVIATED; import static org.jabref.gui.autocompleter.AutoCompleteFirstNameMode.ONLY_FULL; -class EntryEditorPrefsTab extends JPanel implements PrefsTab { +class EntryEditorPrefsTab extends Pane implements PrefsTab { private final CheckBox autoOpenForm; private final CheckBox defSource; @@ -40,6 +34,7 @@ class EntryEditorPrefsTab extends JPanel implements PrefsTab { private final RadioButton firstNameModeFull; private final RadioButton firstNameModeAbbr; private final RadioButton firstNameModeBoth; + private final GridPane builder = new GridPane(); private final TextField autoCompFields; private final JabRefPreferences prefs; @@ -49,27 +44,41 @@ class EntryEditorPrefsTab extends JPanel implements PrefsTab { public EntryEditorPrefsTab(JabRefPreferences prefs) { this.prefs = prefs; autoCompletePreferences = prefs.getAutoCompletePreferences(); - setLayout(new BorderLayout()); + Font font = new Font(10); + Font font1 = new Font(14); autoOpenForm = new CheckBox(Localization.lang("Open editor when a new entry is created")); + autoOpenForm.setFont(font); defSource = new CheckBox(Localization.lang("Show BibTeX source by default")); + defSource.setFont(font); emacsMode = new CheckBox(Localization.lang("Use Emacs key bindings")); + emacsMode.setFont(font); emacsRebindCtrlA = new CheckBox(Localization.lang("Rebind C-a, too")); + emacsRebindCtrlA.setFont(font); emacsRebindCtrlF = new CheckBox(Localization.lang("Rebind C-f, too")); + emacsRebindCtrlF.setFont(font); autoComplete = new CheckBox(Localization.lang("Enable word/name autocompletion")); + autoComplete.setFont(font); recommendations = new CheckBox(Localization.lang("Show 'Related Articles' tab")); + recommendations.setFont(font); validation = new CheckBox(Localization.lang("Show validation messages")); + validation.setFont(font); // allowed name formats autoCompFF = new RadioButton(Localization.lang("Autocomplete names in 'Firstname Lastname' format only")); + autoCompFF.setFont(font); autoCompLF = new RadioButton(Localization.lang("Autocomplete names in 'Lastname, Firstname' format only")); + autoCompLF.setFont(font); autoCompBoth = new RadioButton(Localization.lang("Autocomplete names in both formats")); - + autoCompBoth.setFont(font); // treatment of first name firstNameModeFull = new RadioButton(Localization.lang("Use full firstname whenever possible")); + firstNameModeFull.setFont(font); firstNameModeAbbr = new RadioButton(Localization.lang("Use abbreviated firstname whenever possible")); + firstNameModeAbbr.setFont(font); firstNameModeBoth = new RadioButton(Localization.lang("Use abbreviated and full firstname")); + firstNameModeBoth.setFont(font); // We need a listener on showSource to enable and disable the source panel-related choices: emacsMode.setOnAction(event -> emacsRebindCtrlA.setDisable(!emacsMode.isSelected())); @@ -83,39 +92,49 @@ public EntryEditorPrefsTab(JabRefPreferences prefs) { // autoCompFields text field: autoComplete.setOnAction(event -> setAutoCompleteElementsEnabled(autoComplete.isSelected())); - GridPane builder = new GridPane(); - - builder.add(new Label(Localization.lang("Editor options")),1,1); + Label label = new Label(Localization.lang("Editor options") + " -------------------------------------"); + label.setFont(font1); + builder.add(label,1,1); builder.add(new Separator(),2,1); - builder.add(autoOpenForm, 2,2); - builder.add(defSource, 2,3); - builder.add(emacsMode,2,4); - builder.add(emacsRebindCtrlA,2,5); - builder.add(emacsRebindCtrlF, 2,6); - builder.add(recommendations, 2,7); - builder.add(validation, 2,8); - - builder.add(new Label(Localization.lang("Autocompletion options")),1,9); - builder.add(autoComplete, 2,10); - - Label label = new Label(Localization.lang("Use autocompletion for the following fields") + ":"); - - builder.add(label,2,11); - builder.add(autoCompFields,3,11); - - builder.add(new Label(Localization.lang("Name format used for autocompletion")),1,14); - builder.add(autoCompFF,2,15); - builder.add(autoCompLF, 2,16); - builder.add(autoCompBoth, 2,17); - - builder.add(new Label(Localization.lang("Treatment of first names")),1,18); - builder.add(firstNameModeAbbr, 2,19); - builder.add(firstNameModeFull,2,30); - builder.add(firstNameModeBoth, 2,31); - - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + builder.add(autoOpenForm, 1,2); + builder.add(defSource, 1,3); + builder.add(emacsMode,1,4); + builder.add(emacsRebindCtrlA,1,5); + builder.add(emacsRebindCtrlF, 1,6); + builder.add(recommendations, 1,7); + builder.add(validation, 1,8); + builder.add(new Label(""),1,9); + + Label label1 = new Label(Localization.lang("Autocompletion options") + " --------------------------"); + label1.setFont(font1); + builder.add(label1,1,10); + builder.add(autoComplete, 1,11); + + Label label2 = new Label(" " + Localization.lang("Use autocompletion for the following fields") + ":"); + label2.setFont(font); + builder.add(label2,1,12); + builder.add(autoCompFields,2,12); + builder.add(new Label(""),1,13); + + Label label3 = new Label(Localization.lang("Name format used for autocompletion") + " ----------"); + label3.setFont(font1); + builder.add(label3,1,14); + builder.add(autoCompFF,1,15); + builder.add(autoCompLF, 1,16); + builder.add(autoCompBoth, 1,17); + builder.add(new Label(""),1,18); + + Label label4 = new Label(Localization.lang("Treatment of first names") + " --------------------------"); + label4.setFont(font1); + builder.add(label4,1,19); + builder.add(firstNameModeAbbr, 1,20); + builder.add(firstNameModeFull,1,21); + builder.add(firstNameModeBoth, 1,22); + + } + + public GridPane getBuilder() { + return builder; } private void setAutoCompleteElementsEnabled(boolean enabled) { diff --git a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java index a5ff4d5b30c..b75502eac31 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExportSortingPrefsTab.java @@ -1,20 +1,15 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; - -import javax.swing.JPanel; - -import javafx.embed.swing.JFXPanel; import javafx.event.EventHandler; -import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.Separator; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import javafx.scene.shape.Line; +import javafx.scene.text.Font; import org.jabref.gui.SaveOrderConfigDisplay; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -22,7 +17,7 @@ /** * Preference tab for file sorting options. */ -class ExportSortingPrefsTab extends JPanel implements PrefsTab { +class ExportSortingPrefsTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; @@ -30,17 +25,20 @@ class ExportSortingPrefsTab extends JPanel implements PrefsTab { private final RadioButton exportInTableOrder; private final RadioButton exportInSpecifiedOrder; private final SaveOrderConfigDisplay exportOrderPanel; - + private final GridPane builder = new GridPane(); public ExportSortingPrefsTab(JabRefPreferences prefs) { this.prefs = prefs; - GridPane builder = new GridPane(); + Font font = new Font(10); // EXPORT SORT ORDER // create Components exportInOriginalOrder = new RadioButton(Localization.lang("Export entries in their original order")); + exportInOriginalOrder.setFont(font); exportInTableOrder = new RadioButton(Localization.lang("Export in current table sort order")); + exportInTableOrder.setFont(font); exportInSpecifiedOrder = new RadioButton(Localization.lang("Export entries ordered as specified")); + exportInSpecifiedOrder.setFont(font); EventHandler listener = new EventHandler() { @@ -54,8 +52,10 @@ public void handle(javafx.event.ActionEvent event) { exportInTableOrder.setOnAction(listener); exportInSpecifiedOrder.setOnAction(listener); + Label label = new Label(Localization.lang("Export sort order") + " ------------------------"); + label.setFont(new Font(14)); // create GUI - builder.add(new Label(Localization.lang("Export sort order")),1,1); + builder.add(label,1,1); builder.add(new Separator(),2,1); builder.add(exportInOriginalOrder, 1,2); builder.add(new Line(),2,3); @@ -65,13 +65,13 @@ public void handle(javafx.event.ActionEvent event) { builder.add(new Line(),2,7); exportOrderPanel = new SaveOrderConfigDisplay(); - builder.add(exportOrderPanel.getJFXPanel(),2,8); + builder.add(exportOrderPanel.getJFXPanel(),1,8); builder.add(new Line(),2,9); - // COMBINE EVERYTHING - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + } + + public GridPane getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java index 9fdd66cbadf..4615ea8e26f 100644 --- a/src/main/java/org/jabref/gui/preftabs/ExternalTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ExternalTab.java @@ -13,6 +13,7 @@ import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.text.Font; import org.jabref.Globals; import org.jabref.gui.JabRefFrame; @@ -43,31 +44,38 @@ class ExternalTab extends JPanel implements PrefsTab { private final RadioButton sumatraReader; private final TextField adobeAcrobatReaderPath; private final TextField sumatraReaderPath; + private final GridPane builder = new GridPane(); public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPreferences prefs) { this.prefs = prefs; - setLayout(new BorderLayout()); - + Font font = new Font(10); + Font font1 = new Font(14); Button editFileTypes = new Button(Localization.lang("Manage external file types")); + editFileTypes.setFont(font); citeCommand = new TextField(); editFileTypes.setOnAction(e->ExternalFileTypeEditor.getAction()); defaultConsole = new RadioButton(Localization.lang("Use default terminal emulator")); + defaultConsole.setFont(font); executeConsole = new RadioButton(Localization.lang("Execute command") + ":"); + executeConsole.setFont(font); consoleCommand = new TextField(); browseButton = new Button(Localization.lang("Browse")); - + browseButton.setFont(font); adobeAcrobatReader = new RadioButton(Localization.lang("Adobe Acrobat Reader")); + adobeAcrobatReader.setFont(font); adobeAcrobatReaderPath = new TextField(); Button browseAdobeAcrobatReader = new Button(Localization.lang("Browse")); - + browseAdobeAcrobatReader.setFont(font); sumatraReader = new RadioButton(Localization.lang("Sumatra Reader")); + sumatraReader.setFont(font); sumatraReaderPath = new TextField(); Button browseSumatraReader = new Button(Localization.lang("Browse")); + browseSumatraReader.setFont(font); Label commandDescription = new Label(Localization.lang("Note: Use the placeholder %0 for the location of the opened library file.", "%DIR")); - + commandDescription.setFont(font); defaultConsole.setOnAction(e -> updateExecuteConsoleButtonAndFieldEnabledState()); executeConsole.setOnAction(e -> updateExecuteConsoleButtonAndFieldEnabledState()); browseButton.setOnAction(e -> showConsoleChooser()); @@ -93,18 +101,22 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere pdfOptionPanel.add(browseSumatraReader, 3,2); } - GridPane builder = new GridPane(); - - builder.add(new Label(Localization.lang("Sending of emails")),1,1); + Label label = new Label(Localization.lang("Sending of emails") + " ----------------------------"); + label.setFont(font1); + builder.add(label,1,1); Label lab = new Label(Localization.lang("Subject for sending an email with references").concat(":")); + lab.setFont(font); builder.add(lab,1,2); emailSubject = new TextField(); builder.add(emailSubject,2,2); openFoldersOfAttachedFiles = new CheckBox(Localization.lang("Automatically open folders of attached files")); + openFoldersOfAttachedFiles.setFont(font); builder.add(openFoldersOfAttachedFiles,1,3); - - builder.add(new Label(Localization.lang("External programs")),1,4); + builder.add(new Label(""),1,4); + Label label1 = new Label(Localization.lang("External programs") + " ----------------------------"); + label1.setFont(font1); + builder.add(label1,1,5); GridPane butpan = new GridPane(); @@ -114,30 +126,37 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere index++; } - builder.add(butpan,1,5); - + builder.add(butpan,1,6); lab = new Label(Localization.lang("Cite command") + ':'); - builder.add(lab,1,6); - builder.add(citeCommand,2,6); - - - builder.add(editFileTypes,1,7); + lab.setFont(font); + builder.add(lab,1,7); + builder.add(citeCommand,2,7); - builder.add(new Label(Localization.lang("Open console")),1,8); + builder.add(editFileTypes,1,8); - builder.add(consoleOptionPanel,1,9); + builder.add(new Label(""),1,9); + Label label2 = new Label(Localization.lang("Open console") + " ---------------------------------"); + label2.setFont(font1); + builder.add(label2,1,10); + builder.add(consoleOptionPanel,1,11); + builder.add(new Label(""),1,12); - builder.add(new Label(Localization.lang("Open PDF")),1,10); - - builder.add(pdfOptionPanel,1,11); + Label label3 = new Label(Localization.lang("Open PDF") + " -------------------------------------"); + label3.setFont(font1); + builder.add(label3, 1,12); + builder.add(pdfOptionPanel,1,13); JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); setLayout(new BorderLayout()); add(panel, BorderLayout.CENTER); } + public GridPane getBuilder() { + return builder; + } + private void addSettingsButton(final PushToApplication application, GridPane panel, int index) { PushToApplicationSettings settings = PushToApplications.getSettings(application); Button button = new Button(Localization.lang("Settings for %0", application.getApplicationName())); diff --git a/src/main/java/org/jabref/gui/preftabs/FileTab.java b/src/main/java/org/jabref/gui/preftabs/FileTab.java index 991445ca644..b1f919f6744 100644 --- a/src/main/java/org/jabref/gui/preftabs/FileTab.java +++ b/src/main/java/org/jabref/gui/preftabs/FileTab.java @@ -1,15 +1,10 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import javax.swing.JPanel; - import javafx.collections.FXCollections; -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; @@ -17,9 +12,10 @@ import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.text.Font; import org.jabref.gui.DialogService; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.DirectoryDialogConfiguration; @@ -34,7 +30,7 @@ * Preferences tab for file options. These options were moved out from GeneralTab to * resolve the space issue. */ -class FileTab extends JPanel implements PrefsTab { +class FileTab extends Pane implements PrefsTab { private final DialogService dialogService; private final JabRefPreferences prefs; @@ -48,6 +44,7 @@ class FileTab extends JPanel implements PrefsTab { private final RadioButton resolveStringsAll; private final TextField nonWrappableFields; private final TextField doNotResolveStringsFor; + private final GridPane builder = new GridPane(); private final TextField fileDir; private final CheckBox bibLocAsPrimaryDir; @@ -63,43 +60,59 @@ class FileTab extends JPanel implements PrefsTab { public FileTab(DialogService dialogService, JabRefPreferences prefs) { this.dialogService = dialogService; this.prefs = prefs; + Font font = new Font(10); + Font font1 = new Font(14); fileDir = new TextField(); bibLocAsPrimaryDir = new CheckBox(Localization.lang("Use the BIB file location as primary file directory")); - bibLocAsPrimaryDir.setText(Localization.lang("When downloading files, or moving linked files to the " + bibLocAsPrimaryDir.setFont(font); + bibLocAsPrimaryDir.setAccessibleText(Localization.lang("When downloading files, or moving linked files to the " + "file directory, prefer the BIB file location rather than the file directory set above")); runAutoFileSearch = new CheckBox( Localization.lang("When opening file link, search for matching file if no link is defined")); + runAutoFileSearch.setFont(font); allowFileAutoOpenBrowse = new CheckBox( Localization.lang("Automatically open browse dialog when creating new file link")); + allowFileAutoOpenBrowse.setFont(font); regExpTextField = new TextField(); useRegExpComboBox = new RadioButton(Localization.lang("Use regular expression search")); + useRegExpComboBox.setFont(font); useRegExpComboBox.setOnAction(e -> regExpTextField.setEditable(useRegExpComboBox.isSelected())); openLast = new CheckBox(Localization.lang("Open last edited libraries at startup")); + openLast.setFont(font); backup = new CheckBox(Localization.lang("Backup old file when saving")); + backup.setFont(font); localAutoSave = new CheckBox(Localization.lang("Autosave local libraries")); + localAutoSave.setFont(font); resolveStringsAll = new RadioButton(Localization.lang("Resolve strings for all fields except") + ":"); + resolveStringsAll.setFont(font); resolveStringsStandard = new RadioButton(Localization.lang("Resolve strings for standard BibTeX fields only")); + resolveStringsStandard.setFont(font); // This is sort of a quick hack newlineSeparator = new ComboBox<>(FXCollections.observableArrayList("CR", "CR/LF", "LF")); reformatFileOnSaveAndExport = new CheckBox(Localization.lang("Always reformat BIB file on save and export")); + reformatFileOnSaveAndExport.setFont(font); nonWrappableFields = new TextField(); doNotResolveStringsFor = new TextField(); + nonWrappableFields.setPrefSize(80,25); + doNotResolveStringsFor.setPrefSize(80,25); - GridPane builder = new GridPane(); - - builder.add(new Label(Localization.lang("General")),1,1); + builder.setPrefSize(800,600); + Label label = new Label(Localization.lang("General") + " ----------------------------------------------"); + label.setFont(font1); + builder.add(label,1,1); builder.add(openLast, 1,2); builder.add(backup,1, 3); - Label label = new Label(Localization.lang("Do not wrap the following fields when saving") + ":"); - builder.add(label,1,4); + Label label1 = new Label(Localization.lang("Do not wrap the following fields when saving") + ":"); + label1.setFont(font); + builder.add(label1,1,4); builder.add(nonWrappableFields,2,4); builder.add(resolveStringsStandard, 1,5); @@ -108,58 +121,61 @@ public FileTab(DialogService dialogService, JabRefPreferences prefs) { Label lab = new Label(Localization.lang("Newline separator") + ":"); + lab.setFont(font); builder.add(lab,1,7); builder.add(newlineSeparator,2,7); - builder.add(reformatFileOnSaveAndExport, 1,8); + Label invisible = new Label(""); + builder.add(invisible,1,9); - builder.add(new Label(Localization.lang("External file links")),1,10); + Label label2 = new Label(Localization.lang("External file links") + " ------------------------------------"); + label2.setFont(font1); + builder.add(label2,1,11); lab = new Label(Localization.lang("Main file directory") + ':'); - builder.add(lab,1,11); - builder.add(fileDir,2,11); + lab.setFont(font); + builder.add(lab,1,12); + builder.add(fileDir,2,12); Button browse = new Button(Localization.lang("Browse")); + browse.setFont(font); browse.setOnAction(e -> { - DirectoryDialogConfiguration dirDialogConfiguration = new DirectoryDialogConfiguration.Builder() .withInitialDirectory(Paths.get(fileDir.getText())).build(); - DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showDirectorySelectionDialog(dirDialogConfiguration)) .ifPresent(f -> fileDir.setText(f.toString())); - }); - builder.add(browse,3,11); + builder.add(browse,3,12); - builder.add(bibLocAsPrimaryDir, 1,12); - builder.add(matchStartsWithKey, 1,13); - builder.add(matchExactKeyOnly, 1,14); - builder.add(useRegExpComboBox,1,15); - builder.add(regExpTextField,2,15); + builder.add(bibLocAsPrimaryDir, 1,13); + builder.add(matchStartsWithKey, 1,14); + builder.add(matchExactKeyOnly, 1,15); + builder.add(useRegExpComboBox,1,16); + builder.add(regExpTextField,2,16); Button help = new Button("?"); help.setOnAction(event -> new HelpAction(Localization.lang("Help on regular expression search"), HelpFile.REGEX_SEARCH).getHelpButton().doClick()); - builder.add(help,3,15); + builder.add(help,3,16); - builder.add(runAutoFileSearch, 1,16); - builder.add(allowFileAutoOpenBrowse,1,17); + builder.add(runAutoFileSearch, 1,17); + builder.add(allowFileAutoOpenBrowse,1,18); + Label invisible1 = new Label(""); + builder.add(invisible1,1,19); - builder.add(new Label(Localization.lang("Autosave")),1,18); - builder.add(localAutoSave, 1,19); + Label label3 = new Label(Localization.lang("Autosave") + " ---------------------------------------------"); + label3.setFont(font1); + builder.add(label3,1,20); + builder.add(localAutoSave, 1,21); Button help1 = new Button("?"); help1.setOnAction(event -> new HelpAction(HelpFile.AUTOSAVE).getHelpButton().doClick()); - builder.add(help1,2,19); - + builder.add(help1,2,21); - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); } @Override @@ -199,6 +215,10 @@ public void setValues() { localAutoSave.setSelected(prefs.getBoolean(JabRefPreferences.LOCAL_AUTO_SAVE)); } + public GridPane getBuilder() { + return builder; + } + @Override public void storeSettings() { prefs.put(FieldName.FILE + FileDirectoryPreferences.DIR_SUFFIX, fileDir.getText()); diff --git a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java index fe1181785ea..b517e1ab426 100644 --- a/src/main/java/org/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GeneralTab.java @@ -1,27 +1,22 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.nio.charset.Charset; import java.time.format.DateTimeFormatter; -import javax.swing.JPanel; - import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; -import javafx.scene.control.Separator; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import javafx.scene.shape.Line; +import javafx.scene.text.Font; import org.jabref.Globals; import org.jabref.gui.DialogService; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.help.HelpFile; @@ -35,7 +30,7 @@ import static org.jabref.logic.l10n.Languages.LANGUAGES; -class GeneralTab extends JPanel implements PrefsTab { +class GeneralTab extends Pane implements PrefsTab { private final CheckBox useOwner; @@ -49,6 +44,7 @@ class GeneralTab extends JPanel implements PrefsTab { private final CheckBox updateTimeStamp; private final CheckBox overwriteTimeStamp; private final TextField defOwnerField; + private final GridPane builder = new GridPane(); private final TextField timeStampFormat; private final TextField timeStampField; @@ -63,90 +59,102 @@ class GeneralTab extends JPanel implements PrefsTab { public GeneralTab(DialogService dialogService, JabRefPreferences prefs) { this.prefs = prefs; this.dialogService = dialogService; - setLayout(new BorderLayout()); - + Font font = new Font("News Time Roman", 10); biblatexMode = new ComboBox<>(FXCollections.observableArrayList(BibDatabaseMode.values())); - memoryStick = new CheckBox(Localization.lang("Load and Save preferences from/to jabref.xml on start-up (memory stick mode)")); + memoryStick.setFont(font); useOwner = new CheckBox(Localization.lang("Mark new entries with owner name") + ':'); + useOwner.setFont(font); updateTimeStamp = new CheckBox(Localization.lang("Update timestamp on modification")); + updateTimeStamp.setFont(font); useTimeStamp = new CheckBox(Localization.lang("Mark new entries with addition date") + ". " + Localization.lang("Date format") + ':'); + useTimeStamp.setFont(font); if (!useTimeStamp.isSelected()) { updateTimeStamp.setDisable(true); } useTimeStamp.setOnAction(e->updateTimeStamp.setDisable(!useTimeStamp.isSelected())); overwriteOwner = new CheckBox(Localization.lang("Overwrite")); + overwriteOwner.setFont(font); overwriteTimeStamp = new CheckBox(Localization.lang("If a pasted or imported entry already has the field set, overwrite.")); + overwriteTimeStamp.setFont(font); enforceLegalKeys = new CheckBox(Localization.lang("Enforce legal characters in BibTeX keys")); + enforceLegalKeys.setFont(font); confirmDelete = new CheckBox(Localization.lang("Show confirmation dialog when deleting entries")); - + confirmDelete.setFont(font); defOwnerField = new TextField(); + defOwnerField.setPrefSize(80,20); timeStampFormat = new TextField(); + timeStampFormat.setPrefSize(80,20); timeStampField = new TextField(); + timeStampField.setPrefSize(80,20); inspectionWarnDupli = new CheckBox(Localization.lang("Warn about unresolved duplicates when closing inspection window")); - + inspectionWarnDupli.setFont(font); shouldCollectTelemetry = new CheckBox(Localization.lang("Collect and share telemetry data to help improve JabRef.")); - + shouldCollectTelemetry.setFont(font); encodings = new ComboBox<>(FXCollections.observableArrayList(Encodings.ENCODINGS)); - - GridPane builder = new GridPane(); - builder.add(new Label(Localization.lang("General")),1,1); - builder.add(new Separator(),2,1); - builder.add(new Line(),2,2); - builder.add(inspectionWarnDupli, 2,3); - builder.add(new Line(),2,4); - builder.add(confirmDelete, 2,5); - builder.add(new Line(),2,6); - builder.add(enforceLegalKeys, 2,7); - builder.add(new Line(),2,8); - builder.add(memoryStick, 2,9); + Label label1 = new Label(Localization.lang("General") + " -----------------------------------------------"); + Font font1 = new Font(14); + label1.setFont(font1); + builder.add(label1,1,1); + builder.add(new Line(),1,2); + builder.add(inspectionWarnDupli, 1,3); + builder.add(new Line(),1,4); + builder.add(confirmDelete, 1,5); + builder.add(new Line(),1,6); + builder.add(enforceLegalKeys, 1,7); + builder.add(new Line(),1,8); + builder.add(memoryStick, 1,9); // Create a new panel with its own FormLayout for the last items: - builder.add(useOwner, 2,10); - builder.add(defOwnerField,3,10); - builder.add(overwriteOwner,4,10); + builder.add(useOwner, 1,10); + builder.add(defOwnerField,2,10); + builder.add(overwriteOwner,3,10); - Button help = new Button("Help"); + Button help = new Button("?"); help.setOnAction(event -> new HelpAction(HelpFile.OWNER).getHelpButton().doClick()); - builder.add(help,5,10); - + builder.add(help,4,10); - builder.add(useTimeStamp, 2,13); - builder.add(timeStampFormat,3,13); - builder.add(overwriteTimeStamp,4,13); - builder.add(new Label(Localization.lang("Field name") + ':'),6,13); - builder.add(timeStampField,7,13); + builder.add(useTimeStamp, 1,13); + builder.add(timeStampFormat,2,13); + builder.add(overwriteTimeStamp,3,13); + Label label = new Label(Localization.lang("Field name") + ':'); + label.setFont(font); + builder.add(label,4,13); + builder.add(timeStampField,5,13); - Button help1 = new Button("Help"); + Button help1 = new Button("?"); help1.setOnAction(event -> new HelpAction(HelpFile.TIMESTAMP).getHelpButton().doClick()); - builder.add(help1,8,13); + builder.add(help1,6,13); - builder.add(updateTimeStamp, 2,14); - builder.add(new Line(),2,15); + builder.add(updateTimeStamp, 1,14); + builder.add(new Line(),1,15); - builder.add(shouldCollectTelemetry,2,15); - builder.add(new Line(),2,16); + builder.add(shouldCollectTelemetry,1,15); + builder.add(new Line(),1,16); Label lab; lab = new Label(Localization.lang("Language") + ':'); + lab.setFont(font); builder.add(lab, 1,17); builder.add(language,2,17); builder.add(new Line(),2,18); lab = new Label(Localization.lang("Default encoding") + ':'); + lab.setFont(font); builder.add(lab, 1,19); builder.add(encodings,2,19); + Label label2 = new Label(Localization.lang("Default bibliography mode")); + label2.setFont(font); + builder.add(label2,1,20); + builder.add(biblatexMode,2,20); - builder.add(new Label(Localization.lang("Default bibliography mode")),1,20); - builder.add(biblatexMode,2,21); - - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + } + public GridPane getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java index acec8e0b8b1..d9f05cb4153 100644 --- a/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/GroupsPrefsTab.java @@ -1,25 +1,20 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; - -import javax.swing.JPanel; - -import javafx.embed.swing.JFXPanel; import javafx.event.ActionEvent; import javafx.event.EventHandler; -import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.text.Font; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.groups.GroupViewMode; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; -class GroupsPrefsTab extends JPanel implements PrefsTab { +class GroupsPrefsTab extends Pane implements PrefsTab { private final CheckBox hideNonHits = new CheckBox(Localization.lang("Hide non-hits")); private final CheckBox grayOut = new CheckBox(Localization.lang("Gray out non-hits")); @@ -29,7 +24,7 @@ class GroupsPrefsTab extends JPanel implements PrefsTab { private final TextField groupingField = new TextField(); private final TextField keywordSeparator = new TextField(); - + private final GridPane builder = new GridPane(); private final JabRefPreferences prefs; public GroupsPrefsTab(JabRefPreferences prefs) { @@ -42,28 +37,40 @@ public void handle(ActionEvent event) { } }); + Font font = new Font(10); + Font font1 = new Font(14); multiSelectionModeIntersection.setText(Localization.lang("Display only entries belonging to all selected groups.")); + multiSelectionModeIntersection.setFont(font); multiSelectionModeUnion.setText(Localization.lang("Display all entries belonging to one or more of the selected groups.")); + multiSelectionModeUnion.setFont(font); - GridPane builder = new GridPane(); - - builder.add(new Label(Localization.lang("View")),1,1); + Label label = new Label(Localization.lang("View") + " ---------------------------------------"); + label.setFont(font1); + builder.add(label,1,1); builder.add(hideNonHits,2,2); builder.add(grayOut,2,3); builder.add(multiSelectionModeIntersection,2,4); builder.add(multiSelectionModeUnion,2,5); builder.add(autoAssignGroup,2,6); - builder.add(new Label(Localization.lang("Dynamic groups")),1,7); - - builder.add(new Label(Localization.lang("Default grouping field") + ":"),1,8); - builder.add(groupingField,2,8); - builder.add(new Label(Localization.lang("When adding/removing keywords, separate them by") + ":"),1,9); - builder.add(keywordSeparator,2,9); + builder.add(new Label(""),1,7); + + Label label1 = new Label(Localization.lang("Dynamic groups") + " --------------------------"); + label1.setFont(font1); + builder.add(label1,1,8); + + Label label2 = new Label(Localization.lang("Default grouping field") + ":"); + label2.setFont(font); + builder.add(label2,1,9); + builder.add(groupingField,2,9); + Label label3 = new Label(Localization.lang("When adding/removing keywords, separate them by") + ":"); + label3.setFont(font); + builder.add(label3,1,10); + builder.add(keywordSeparator,2,10); + } - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + public GridPane getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java index 280483e2277..9a7262ed416 100644 --- a/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/ImportSettingsTab.java @@ -1,13 +1,8 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.Objects; -import javax.swing.JPanel; - import javafx.collections.FXCollections; -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; @@ -15,13 +10,14 @@ import javafx.scene.control.Separator; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.text.Font; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.pdfimport.ImportDialog; import org.jabref.preferences.JabRefPreferences; -public class ImportSettingsTab extends JPanel implements PrefsTab { +public class ImportSettingsTab extends Pane implements PrefsTab { public static final String[] DEFAULT_FILENAMEPATTERNS = new String[] {"[bibtexkey]", "[bibtexkey] - [title]"}; @@ -35,7 +31,7 @@ public class ImportSettingsTab extends JPanel implements PrefsTab { private final RadioButton radioButtonNoMeta; private final RadioButton radioButtononlyAttachPDF; private final CheckBox useDefaultPDFImportStyle; - + private final GridPane builder = new GridPane(); private final TextField fileNamePattern; private final ComboBox selectFileNamePattern; @@ -45,16 +41,21 @@ public class ImportSettingsTab extends JPanel implements PrefsTab { public ImportSettingsTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); - setLayout(new BorderLayout()); + Font font = new Font(10); + Font font1 = new Font(14); radioButtonNoMeta = new RadioButton(Localization.lang("Create blank entry linking the PDF")); + radioButtonNoMeta.setFont(font); radioButtonXmp = new RadioButton(Localization.lang("Create entry based on XMP-metadata")); + radioButtonXmp.setFont(font); radioButtonPDFcontent = new RadioButton(Localization.lang("Create entry based on content")); + radioButtonPDFcontent.setFont(font); radioButtononlyAttachPDF = new RadioButton(Localization.lang("Only attach PDF")); - + radioButtononlyAttachPDF.setFont(font); useDefaultPDFImportStyle = new CheckBox( Localization.lang("Always use this PDF import style (and do not ask for each import)")); + useDefaultPDFImportStyle.setFont(font); fileNamePattern = new TextField(); fileDirPattern = new TextField(); @@ -64,29 +65,35 @@ public ImportSettingsTab(JabRefPreferences prefs) { selectFileNamePattern.setOnAction(e -> { fileNamePattern.setText(selectFileNamePattern.getValue()); }); - GridPane builder = new GridPane(); - builder.add(new Label(Localization.lang("Default import style for drag and drop of PDFs")),1,1); + + Label label = new Label(Localization.lang("Default import style for drag and drop of PDFs")); + label.setFont(font1); + builder.add(label,1,1); builder.add(new Separator(),2,1); builder.add(radioButtonNoMeta,2,2); builder.add(radioButtonXmp,2,3); builder.add(radioButtonPDFcontent,2,4); builder.add(radioButtononlyAttachPDF,2,5); builder.add(useDefaultPDFImportStyle,2,6); - builder.add(new Label(Localization.lang("Default PDF file link action")),1,7); - + builder.add(new Label(""),1,7); + Label label1 = new Label(Localization.lang("Default PDF file link action") + " ------------------------"); + label1.setFont(font1); + builder.add(label1,1,8); Label lab = new Label(Localization.lang("Filename format pattern").concat(":")); - builder.add(lab,1,8); - builder.add(fileNamePattern,2,8); - builder.add(selectFileNamePattern,3,8); + lab.setFont(font); + builder.add(lab,1,9); + builder.add(fileNamePattern,2,9); + builder.add(selectFileNamePattern,3,9); Label lbfileDirPattern = new Label(Localization.lang("File directory pattern").concat(":")); - builder.add(lbfileDirPattern,1,9); - builder.add(fileDirPattern,2,9); + lbfileDirPattern.setFont(font); + builder.add(lbfileDirPattern,1,10); + builder.add(fileDirPattern,2,10); + } - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + public GridPane getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java index c4bf2322d2f..299eac0a03b 100644 --- a/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NameFormatterTab.java @@ -1,17 +1,12 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import javax.swing.JPanel; - import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; @@ -23,19 +18,21 @@ import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.text.Font; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.help.HelpAction; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; import org.jabref.logic.layout.format.NameFormatter; import org.jabref.preferences.JabRefPreferences; -public class NameFormatterTab extends JPanel implements PrefsTab { +public class NameFormatterTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; private boolean tableChanged; private final TableView table; + private final GridPane builder = new GridPane(); private int rowCount = -1; private final List tableRows = new ArrayList<>(10); private final ObservableList data = FXCollections.observableArrayList(); @@ -75,14 +72,12 @@ public void setFormat(String format) { } } - /** * Tab to create custom Name Formatters * */ public NameFormatterTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); - setLayout(new BorderLayout()); TableColumn firstCol = new TableColumn<>(Localization.lang("Formatter name")); TableColumn lastCol = new TableColumn<>(Localization.lang("Format string")); @@ -115,7 +110,6 @@ public NameFormatterTab(JabRefPreferences prefs) { addLast.setMaxWidth(lastCol.getPrefWidth()); addLast.setPromptText("format"); - GridPane builder = new GridPane(); BorderPane tabPanel = new BorderPane(); ScrollPane scrollPane = new ScrollPane(); scrollPane.setMaxHeight(400); @@ -149,19 +143,22 @@ public NameFormatterTab(JabRefPreferences prefs) { rowCount--; table.refresh(); }}); - Button help = new Button("Help"); + Button help = new Button("?"); help.setOnAction(e-> new HelpAction(Localization.lang("Help on Name Formatting"), HelpFile.CUSTOM_EXPORTS_NAME_FORMATTER).getHelpButton().doClick()); HBox toolbar = new HBox(); toolbar.getChildren().addAll(addName, addLast,add,delete,help); tabPanel.setBottom(toolbar); - builder.add(new Label(Localization.lang("Special name formatters")),1,1); + Label label = new Label(Localization.lang("Special name formatters") + " ------------------------------------"); + label.setFont(new Font(14)); + builder.add(label,1,1); builder.add(tabPanel,1,2); - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + } + + public GridPane getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java index 2d81e629932..04fda1b536a 100644 --- a/src/main/java/org/jabref/gui/preftabs/NetworkTab.java +++ b/src/main/java/org/jabref/gui/preftabs/NetworkTab.java @@ -1,28 +1,23 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; - -import javax.swing.JPanel; - -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.PasswordField; import javafx.scene.control.Separator; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import javafx.scene.paint.Paint; +import javafx.scene.text.Font; import org.jabref.gui.DialogService; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.l10n.Localization; import org.jabref.logic.net.ProxyPreferences; import org.jabref.logic.net.ProxyRegisterer; import org.jabref.preferences.JabRefPreferences; -public class NetworkTab extends JPanel implements PrefsTab { +public class NetworkTab extends Pane implements PrefsTab { private final CheckBox useProxyCheckBox; private final TextField hostnameTextField; @@ -33,21 +28,24 @@ public class NetworkTab extends JPanel implements PrefsTab { private final JabRefPreferences preferences; private ProxyPreferences oldProxyPreferences; private final DialogService dialogService; + private final GridPane builder = new GridPane(); public NetworkTab(DialogService dialogService, JabRefPreferences preferences) { this.dialogService = dialogService; this.preferences = preferences; - setLayout(new BorderLayout()); + Font font = new Font(10); + Font font1 = new Font(14); useProxyCheckBox = new CheckBox(Localization.lang("Use custom proxy configuration")); - + useProxyCheckBox.setFont(font); hostnameTextField = new TextField(); hostnameTextField.setDisable(true); portTextField = new TextField(); portTextField.setDisable(true); useAuthenticationCheckBox = new CheckBox(Localization.lang("Proxy requires authentication")); + useAuthenticationCheckBox.setFont(font); useAuthenticationCheckBox.setDisable(true); usernameTextField = new TextField(); @@ -55,6 +53,7 @@ public NetworkTab(DialogService dialogService, JabRefPreferences preferences) { passwordTextField = new PasswordField(); passwordTextField.setDisable(true); Label passwordWarningLabel = new Label(Localization.lang("Attention: Password is stored in plain text!")); + passwordWarningLabel.setFont(font); passwordWarningLabel.setDisable(true); passwordWarningLabel.setTextFill(Paint.valueOf("Red")); @@ -72,25 +71,34 @@ public NetworkTab(DialogService dialogService, JabRefPreferences preferences) { passwordWarningLabel.setDisable(!useProxyCheckBox.isSelected() || !useAuthenticationCheckBox.isSelected()); }); - GridPane builder = new GridPane(); - - builder.add(new Label(Localization.lang("Network")),1,1); + Label label = new Label(Localization.lang("Network") + " ---------------------------------"); + label.setFont(font1); + builder.add(label,1,1); builder.add(new Separator(),2,1); builder.add(useProxyCheckBox,2,2); - builder.add(new Label(Localization.lang("Hostname") + ':'),1,3); + Label label1 = new Label(Localization.lang("Hostname") + ':'); + label1.setFont(font); + builder.add(label1,1,3); builder.add(hostnameTextField,2,3); - builder.add(new Label(Localization.lang("Port") + ':'),1,4); + Label label2 = new Label(Localization.lang("Port") + ':'); + label2.setFont(font); + builder.add(label2,1,4); builder.add(portTextField,2,4); builder.add(useAuthenticationCheckBox,2,5); - builder.add(new Label(Localization.lang("Username") + ':'),2,6); + Label label3 = new Label(Localization.lang("Username") + ':'); + label3.setFont(font); + builder.add(label3,2,6); builder.add(usernameTextField,3,6); - builder.add(new Label(Localization.lang("Password") + ':'),2,7); + Label label4 = new Label(Localization.lang("Password") + ':'); + label4.setFont(font); + builder.add(label4,2,7); builder.add(passwordTextField,3,7); builder.add(passwordWarningLabel,3,8); - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + } + + public GridPane getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java index 61b497f8c8d..0d5ace22bb2 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java +++ b/src/main/java/org/jabref/gui/preftabs/PreferencesDialog.java @@ -1,29 +1,23 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; -import java.awt.CardLayout; -import java.awt.Component; -import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.nio.file.Path; import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.prefs.BackingStoreException; import javax.swing.AbstractAction; -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.ListSelectionModel; +import javafx.geometry.Pos; +import javafx.scene.control.Button; import javafx.scene.control.ButtonBar.ButtonData; import javafx.scene.control.ButtonType; +import javafx.scene.control.Label; +import javafx.scene.layout.BorderPane; import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; +import javafx.scene.text.Font; import org.jabref.Globals; import org.jabref.JabRefException; @@ -61,23 +55,38 @@ public class PreferencesDialog extends BaseDialog { private static final Logger LOGGER = LoggerFactory.getLogger(PreferencesDialog.class); - private final JPanel main; + private final BorderPane main; private final DialogService dialogService; private final JabRefFrame frame; private final JabRefPreferences prefs; + private final AdvancedTab advancedTab; + private final AppearancePrefsTab appearancePrefsTab; + private final BibtexKeyPatternPrefTab bibtexKeyPatternPrefTab; + private final EntryEditorPrefsTab entryEditorPrefsTab; + private final ExportSortingPrefsTab exportSortingPrefsTab; + private final ExternalTab externalTab; + private final FileTab fileTab; + private final GeneralTab generalTab; + private final GroupsPrefsTab groupsPrefsTab; + private final ImportSettingsTab importSettingsTab; + private final NameFormatterTab nameFormatterTab; + private final NetworkTab networkTab; + private final PreviewPrefsTab previewPrefsTab; + private final TableColumnsTab tableColumnsTab; + private final TablePrefsTab tablePrefsTab; + private final XmpPrefsTab xmpPrefsTab; + private ArrayList arrayList = new ArrayList<>(); public PreferencesDialog(JabRefFrame parent) { setTitle(Localization.lang("JabRef preferences")); - getDialogPane().setPrefSize(1000, 800); + getDialogPane().setPrefSize(1200, 800); getDialogPane().setMinHeight(Region.USE_PREF_SIZE); setResizable(true); - ButtonType save = new ButtonType(Localization.lang("Save"), ButtonData.OK_DONE); - getDialogPane().getButtonTypes().addAll(save, ButtonType.CANCEL); ControlHelper.setAction(save, getDialogPane(), event -> { - storeAllSettings(); + storeAllSettings(); close(); }); @@ -85,85 +94,186 @@ public PreferencesDialog(JabRefFrame parent) { frame = parent; dialogService = frame.getDialogService(); - main = new JPanel(); + advancedTab = new AdvancedTab(dialogService,prefs); + appearancePrefsTab = new AppearancePrefsTab(dialogService,prefs); + bibtexKeyPatternPrefTab = new BibtexKeyPatternPrefTab(prefs,frame.getCurrentBasePanel()); + entryEditorPrefsTab = new EntryEditorPrefsTab(prefs); + exportSortingPrefsTab = new ExportSortingPrefsTab(prefs); + externalTab = new ExternalTab(frame,this,prefs); + fileTab = new FileTab(dialogService,prefs); + generalTab = new GeneralTab(dialogService,prefs); + groupsPrefsTab = new GroupsPrefsTab(prefs); + importSettingsTab = new ImportSettingsTab(prefs); + nameFormatterTab = new NameFormatterTab(prefs); + networkTab = new NetworkTab(dialogService,prefs); + previewPrefsTab = new PreviewPrefsTab(dialogService); + tableColumnsTab = new TableColumnsTab(prefs,frame); + tablePrefsTab = new TablePrefsTab(prefs); + xmpPrefsTab = new XmpPrefsTab(prefs); + + if (arrayList.isEmpty()) { + arrayList.add(advancedTab); + arrayList.add(appearancePrefsTab); + arrayList.add(bibtexKeyPatternPrefTab); + arrayList.add(entryEditorPrefsTab); + arrayList.add(exportSortingPrefsTab); + arrayList.add(externalTab); + arrayList.add(fileTab); + arrayList.add(generalTab); + arrayList.add(groupsPrefsTab); + arrayList.add(importSettingsTab); + arrayList.add(nameFormatterTab); + arrayList.add(networkTab); + arrayList.add(previewPrefsTab); + arrayList.add(tableColumnsTab); + arrayList.add(tablePrefsTab); + arrayList.add(xmpPrefsTab); + } - ControlHelper.setSwingContent(getDialogPane(), constructSwingContent()); - } - private JComponent constructSwingContent() { - JPanel mainPanel = new JPanel(); - final CardLayout cardLayout = new CardLayout(); - main.setLayout(cardLayout); - - List tabs = new ArrayList<>(); - tabs.add(new GeneralTab(dialogService, prefs)); - tabs.add(new FileTab(dialogService, prefs)); - tabs.add(new TablePrefsTab(prefs)); - tabs.add(new TableColumnsTab(prefs, frame)); - tabs.add(new PreviewPrefsTab(dialogService)); - tabs.add(new ExternalTab(frame, this, prefs)); - tabs.add(new GroupsPrefsTab(prefs)); - tabs.add(new EntryEditorPrefsTab(prefs)); - tabs.add(new BibtexKeyPatternPrefTab(prefs, frame.getCurrentBasePanel())); - tabs.add(new ImportSettingsTab(prefs)); - tabs.add(new ExportSortingPrefsTab(prefs)); - tabs.add(new NameFormatterTab(prefs)); - tabs.add(new XmpPrefsTab(prefs)); - tabs.add(new NetworkTab(dialogService, prefs)); - tabs.add(new AdvancedTab(dialogService, prefs)); - tabs.add(new AppearancePrefsTab(dialogService, prefs)); - - // add all tabs - tabs.forEach(tab -> main.add((Component) tab, tab.getTabName())); - - mainPanel.setBorder(BorderFactory.createEtchedBorder()); - - String[] tabNames = tabs.stream().map(PrefsTab::getTabName).toArray(String[]::new); - JList chooser = new JList<>(tabNames); - chooser.setBorder(BorderFactory.createEtchedBorder()); - // Set a prototype value to control the width of the list: - chooser.setPrototypeCellValue("This should be wide enough"); - chooser.setSelectedIndex(0); - chooser.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - // Add the selection listener that will show the correct panel when - // selection changes: - chooser.addListSelectionListener(e -> { - if (e.getValueIsAdjusting()) { - return; - } - String o = chooser.getSelectedValue(); - cardLayout.show(main, o); - }); + main = new BorderPane(); + main.setCenter(generalTab.getBuilder()); + getDialogPane().setContent(main); + constructSwingContent(); + } - JPanel buttons = new JPanel(); - buttons.setLayout(new GridLayout(4, 1)); - JButton importPreferences = new JButton(Localization.lang("Import preferences")); - buttons.add(importPreferences, 0); - JButton exportPreferences = new JButton(Localization.lang("Export preferences")); - buttons.add(exportPreferences, 1); - JButton showPreferences = new JButton(Localization.lang("Show preferences")); - buttons.add(showPreferences, 2); - JButton resetPreferences = new JButton(Localization.lang("Reset preferences")); - buttons.add(resetPreferences, 3); - - JPanel westPanel = new JPanel(); - westPanel.setLayout(new BorderLayout()); - westPanel.add(chooser, BorderLayout.CENTER); - westPanel.add(buttons, BorderLayout.SOUTH); - mainPanel.setLayout(new BorderLayout()); - mainPanel.add(putPanelInScrollPane(main), BorderLayout.CENTER); - mainPanel.add(putPanelInScrollPane(westPanel), BorderLayout.WEST); + private void constructSwingContent() { + BorderPane mainPanel = new BorderPane(); + + VBox vBox = new VBox(); + Font font = new Font(10); + + Button general = new Button(Localization.lang("General")); + general.setFont(font); + general.setAlignment(Pos.BASELINE_LEFT); + general.setOnAction( e -> main.setCenter(generalTab.getBuilder())); + general.setPrefSize(120,20); + + Button file = new Button(Localization.lang("File")); + file.setFont(font); + file.setAlignment(Pos.BASELINE_LEFT); + file.setPrefSize(120,20); + file.setOnAction( e-> main.setCenter(fileTab.getBuilder())); + + Button entryTable = new Button(Localization.lang("Entry table")); + entryTable.setFont(font); + entryTable.setAlignment(Pos.BASELINE_LEFT); + entryTable.setPrefSize(120,20); + entryTable.setOnAction(e -> main.setCenter(tablePrefsTab.getBuilder())); + + Button tableColumn = new Button(Localization.lang("Entry table columns")); + tableColumn.setFont(font); + tableColumn.setAlignment(Pos.BASELINE_LEFT); + tableColumn.setPrefSize(120,20); + tableColumn.setOnAction( e -> main.setCenter(tableColumnsTab.getBuilder())); + + Button entryPreview = new Button(Localization.lang("Entry preview")); + entryPreview.setFont(font); + entryPreview.setAlignment(Pos.BASELINE_LEFT); + entryPreview.setPrefSize(120,20); + entryPreview.setOnAction( e -> main.setCenter(previewPrefsTab.getGridPane())); + + Button externalPrograms = new Button(Localization.lang("External programs")); + externalPrograms.setFont(font); + externalPrograms.setAlignment(Pos.BASELINE_LEFT); + externalPrograms.setPrefSize(120,20); + externalPrograms.setOnAction(e -> main.setCenter(externalTab.getBuilder())); + + Button groups = new Button(Localization.lang("Groups")); + groups.setFont(font); + groups.setAlignment(Pos.BASELINE_LEFT); + groups.setPrefSize(120,20); + groups.setOnAction( e -> main.setCenter(groupsPrefsTab.getBuilder())); + + Button entryEditor = new Button(Localization.lang("Entry editor")); + entryEditor.setFont(font); + entryEditor.setAlignment(Pos.BASELINE_LEFT); + entryEditor.setPrefSize(120,20); + entryEditor.setOnAction( e -> main.setCenter(entryEditorPrefsTab.getBuilder())); + + Button bibkeyGenerator = new Button(Localization.lang("BibTeX key generator")); + bibkeyGenerator.setPrefSize(120,20); + bibkeyGenerator.setFont(font); + bibkeyGenerator.setAlignment(Pos.BASELINE_LEFT); + bibkeyGenerator.setOnAction( e -> main.setCenter(bibtexKeyPatternPrefTab.getBuilder())); + + Button imports = new Button(Localization.lang("Import")); + imports.setFont(font); + imports.setAlignment(Pos.BASELINE_LEFT); + imports.setPrefSize(120,20); + imports.setOnAction( e -> main.setCenter(importSettingsTab.getBuilder())); + + Button export = new Button(Localization.lang("Export sorting")); + export.setFont(font); + export.setAlignment(Pos.BASELINE_LEFT); + export.setPrefSize(120,20); + export.setOnAction( e -> main.setCenter(exportSortingPrefsTab.getBuilder())); + + Button nameFormatter = new Button(Localization.lang("Name formatter")); + nameFormatter.setFont(font); + nameFormatter.setAlignment(Pos.BASELINE_LEFT); + nameFormatter.setPrefSize(120,20); + nameFormatter.setOnAction( e -> main.setCenter(nameFormatterTab.getBuilder())); + + Button xmp = new Button(Localization.lang("XMP-metadata")); + xmp.setFont(font); + xmp.setAlignment(Pos.BASELINE_LEFT); + xmp.setPrefSize(120,20); + xmp.setOnAction( e -> main.setCenter(xmpPrefsTab.getBuilder())); + + Button network = new Button(Localization.lang("Network")); + network.setFont(font); + network.setAlignment(Pos.BASELINE_LEFT); + network.setPrefSize(120,20); + network.setOnAction(e -> main.setCenter(networkTab.getBuilder())); + + Button advanced = new Button(Localization.lang("Advanced")); + advanced.setFont(font); + advanced.setAlignment(Pos.BASELINE_LEFT); + advanced.setPrefSize(120,20); + advanced.setOnAction( e -> main.setCenter(advancedTab.getBuilder())); + + Button appearance = new Button(Localization.lang("Appearance")); + appearance.setFont(font); + appearance.setAlignment(Pos.BASELINE_LEFT); + appearance.setPrefSize(120,20); + appearance.setOnAction( e -> main.setCenter(appearancePrefsTab.getContainer())); + + vBox.getChildren().addAll(general, file, entryTable, tableColumn, entryPreview, externalPrograms, groups, + entryEditor, bibkeyGenerator, imports, export, nameFormatter, xmp, network, advanced, appearance); + + for (int i = 0; i < 18; i++) { + vBox.getChildren().add(new Label("")); + } + Button importPreferences = new Button(Localization.lang("Import preferences")); + importPreferences.setAlignment(Pos.BASELINE_LEFT); + importPreferences.setFont(font); + importPreferences.setPrefSize(120,20); + Button exportPreferences = new Button(Localization.lang("Export preferences")); + exportPreferences.setFont(font); + exportPreferences.setPrefSize(120,20); + exportPreferences.setAlignment(Pos.BASELINE_LEFT); + Button showPreferences = new Button(Localization.lang("Show preferences")); + showPreferences.setFont(font); + showPreferences.setAlignment(Pos.BASELINE_LEFT); + showPreferences.setPrefSize(120,20); + Button resetPreferences = new Button(Localization.lang("Reset preferences")); + resetPreferences.setFont(font); + resetPreferences.setPrefSize(120,20); + resetPreferences.setAlignment(Pos.BASELINE_LEFT); + + vBox.getChildren().addAll(importPreferences, exportPreferences, showPreferences, resetPreferences); + main.setLeft(vBox); // TODO: Key bindings: // KeyBinder.bindCloseDialogKeyToCancelAction(this.getRootPane(), cancelAction); // Import and export actions: - exportPreferences.setToolTipText(Localization.lang("Export preferences to file")); - exportPreferences.addActionListener(new ExportAction()); + exportPreferences.setAccessibleText(Localization.lang("Export preferences to file")); + exportPreferences.setOnAction( e -> new ExportAction()); - importPreferences.setToolTipText(Localization.lang("Import preferences from file")); - importPreferences.addActionListener(e -> { + importPreferences.setAccessibleText(Localization.lang("Import preferences from file")); + importPreferences.setOnAction(e -> { FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .addExtensionFilter(StandardFileType.XML) @@ -187,9 +297,9 @@ private JComponent constructSwingContent() { } }); - showPreferences.addActionListener( + showPreferences.setOnAction( e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(prefs)).setVisible(true)); - resetPreferences.addActionListener(e -> { + resetPreferences.setOnAction(e -> { boolean resetPreferencesClicked = DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showConfirmationDialogAndWait(Localization.lang("Reset preferences"), Localization.lang("Are you sure you want to reset all settings to default values?"), @@ -212,15 +322,6 @@ private JComponent constructSwingContent() { setValues(); - return mainPanel; - } - - private JScrollPane putPanelInScrollPane(JPanel panel) { - JScrollPane scrollPane = new JScrollPane(panel); - scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); - scrollPane.setBorder(null); - return scrollPane; } private String getPrefsExportPath() { @@ -229,7 +330,6 @@ private String getPrefsExportPath() { private void updateAfterPreferenceChanges() { setValues(); - Map customExporters = prefs.customExports.getCustomExportFormats(prefs, Globals.journalAbbreviationLoader); LayoutFormatterPreferences layoutPreferences = prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader); SavePreferences savePreferences = prefs.loadForExportFromPreferences(); @@ -240,15 +340,14 @@ private void updateAfterPreferenceChanges() { private void storeAllSettings() { // First check that all tabs are ready to close: - Component[] preferenceTabs = main.getComponents(); - for (Component tab : preferenceTabs) { - if (!((PrefsTab) tab).validateSettings()) { + for (PrefsTab tab : arrayList) { + if (!tab.validateSettings()) { return; // If not, break off. } } // Then store settings and close: - for (Component tab : preferenceTabs) { - ((PrefsTab) tab).storeSettings(); + for (PrefsTab tab : arrayList) { + tab.storeSettings(); } prefs.flush(); @@ -259,10 +358,8 @@ private void storeAllSettings() { public void setValues() { // Update all field values in the tabs: - int count = main.getComponentCount(); - Component[] comps = main.getComponents(); - for (int i = 0; i < count; i++) { - ((PrefsTab) comps[i]).setValues(); + for (PrefsTab prefsTab : arrayList) { + prefsTab.setValues(); } } diff --git a/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java index 1b1c1bbcf68..bdc03002eef 100644 --- a/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/PreviewPrefsTab.java @@ -1,25 +1,26 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.ArrayList; import java.util.Comparator; -import java.util.Enumeration; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutionException; -import javax.swing.BoxLayout; -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JList; import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.ListSelectionModel; import javax.swing.SwingWorker; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.control.Button; import javafx.scene.control.ButtonType; import javafx.scene.control.DialogPane; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextArea; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; +import javafx.scene.text.Font; import org.jabref.Globals; import org.jabref.JabRefGUI; @@ -33,9 +34,6 @@ import org.jabref.model.database.BibDatabaseContext; import org.jabref.preferences.PreviewPreferences; -import com.google.common.primitives.Ints; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.factories.Paddings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,24 +43,26 @@ public class PreviewPrefsTab extends JPanel implements PrefsTab { private SwingWorker, Void> discoverCitationStyleWorker; - private final DefaultListModel availableModel = new DefaultListModel<>(); - private final DefaultListModel chosenModel = new DefaultListModel<>(); + private final ObservableList availableModel = FXCollections.observableArrayList(); + private final ObservableList chosenModel = FXCollections.observableArrayList(); - private final JList available = new JList<>(availableModel); - private final JList chosen = new JList<>(chosenModel); + private List list = new ArrayList<>(); - private final JButton btnRight = new JButton("»"); - private final JButton btnLeft = new JButton("«"); - private final JButton btnUp = new JButton(Localization.lang("Up")); - private final JButton btnDown = new JButton(Localization.lang("Down")); - - private final JTextArea layout = new JTextArea("", 1, 1); - private final JButton btnTest = new JButton(Localization.lang("Test")); - private final JButton btnDefault = new JButton(Localization.lang("Default")); - private final JScrollPane scrollPane = new JScrollPane(layout); + private final ListView available = new ListView<>(availableModel); + private final ListView chosen = new ListView<>(chosenModel); + private final Button btnRight = new Button("»"); + private final Button btnLeft = new Button("«"); + private final Button btnUp = new Button(Localization.lang("Up")); + private final Button btnDown = new Button(Localization.lang("Down")); + private final GridPane gridPane = new GridPane(); + private final TextArea layout = new TextArea(); + private final Button btnTest = new Button(Localization.lang("Test")); + private final Button btnDefault = new Button(Localization.lang("Default")); + private final ScrollPane scrollPane = new ScrollPane(layout); private final DialogService dialogService; + public PreviewPrefsTab(DialogService dialogService) { this.dialogService = dialogService; setupLogic(); @@ -70,73 +70,71 @@ public PreviewPrefsTab(DialogService dialogService) { } private void setupLogic() { - chosen.getSelectionModel().addListSelectionListener(event -> { - boolean selectionEmpty = ((ListSelectionModel) event.getSource()).isSelectionEmpty(); - btnLeft.setEnabled(!selectionEmpty); - btnDown.setEnabled(!selectionEmpty); - btnUp.setEnabled(!selectionEmpty); + chosen.getSelectionModel().selectedItemProperty().addListener(event -> { + if (chosen.getSelectionModel().getSelectedIndices().isEmpty()) { + btnLeft.setDisable(true); + btnDown.setDisable(true); + btnUp.setDisable(true); + } }); - available.getSelectionModel() - .addListSelectionListener(e -> btnRight.setEnabled(!((ListSelectionModel) e.getSource()).isSelectionEmpty())); + available.getSelectionModel().selectedItemProperty().addListener( + e -> btnRight.setDisable(available.getSelectionModel().getSelectedIndices().isEmpty())); - btnRight.addActionListener(event -> { - for (Object object : available.getSelectedValuesList()) { - availableModel.removeElement(object); - chosenModel.addElement(object); + btnRight.setOnAction(event -> { + for (Object object : available.getSelectionModel().getSelectedItems()) { + availableModel.remove(object); + chosenModel.add(object); } storeSettings(); }); - btnLeft.addActionListener(event -> { - for (Object object : chosen.getSelectedValuesList()) { - availableModel.addElement(object); - chosenModel.removeElement(object); + btnLeft.setOnAction(event -> { + for (Object object : chosen.getSelectionModel().getSelectedItems()) { + availableModel.add(object); + chosenModel.remove(object); } storeSettings(); }); - btnUp.addActionListener(event -> { + btnUp.setOnAction(event -> { List newSelectedIndices = new ArrayList<>(); - for (int oldIndex : chosen.getSelectedIndices()) { + for (int oldIndex : chosen.getSelectionModel().getSelectedIndices()) { boolean alreadyTaken = newSelectedIndices.contains(oldIndex - 1); int newIndex = ((oldIndex > 0) && !alreadyTaken) ? oldIndex - 1 : oldIndex; chosenModel.add(newIndex, chosenModel.remove(oldIndex)); - newSelectedIndices.add(newIndex); + chosen.getSelectionModel().select(newIndex); } - chosen.setSelectedIndices(Ints.toArray(newSelectedIndices)); storeSettings(); }); - btnDown.addActionListener(event -> { + btnDown.setOnAction(event -> { List newSelectedIndices = new ArrayList<>(); - int[] selectedIndices = chosen.getSelectedIndices(); - for (int i = selectedIndices.length - 1; i >= 0; i--) { - int oldIndex = selectedIndices[i]; + ObservableList selectedIndices = chosen.getSelectionModel().getSelectedIndices(); + for (int i = selectedIndices.size() - 1; i >= 0; i--) { + int oldIndex = (int)selectedIndices.get(i); boolean alreadyTaken = newSelectedIndices.contains(oldIndex + 1); - int newIndex = ((oldIndex < (chosenModel.getSize() - 1)) && !alreadyTaken) ? oldIndex + 1 : oldIndex; + int newIndex = ((oldIndex < (chosenModel.size() - 1)) && !alreadyTaken) ? oldIndex + 1 : oldIndex; chosenModel.add(newIndex, chosenModel.remove(oldIndex)); - newSelectedIndices.add(newIndex); + chosen.getSelectionModel().select(newIndex); } - chosen.setSelectedIndices(Ints.toArray(newSelectedIndices)); storeSettings(); }); - btnDefault.addActionListener(event -> layout.setText(Globals.prefs.getPreviewPreferences() + btnDefault.setOnAction(event -> layout.setText(Globals.prefs.getPreviewPreferences() .getPreviewStyleDefault() .replace("__NEWLINE__", "\n"))); - btnTest.addActionListener(event -> { + btnTest.setOnAction(event -> { try { DefaultTaskExecutor.runInJavaFXThread(() -> { - PreviewPanel testPane = new PreviewPanel(null, null, Globals.getKeyPrefs(), Globals.prefs.getPreviewPreferences(), dialogService); - if (chosen.isSelectionEmpty()) { + if (chosen.getSelectionModel().getSelectedItems().isEmpty()) { testPane.setFixedLayout(layout.getText()); testPane.setEntry(TestEntry.getTestEntry()); } else { - int indexStyle = chosen.getSelectedIndex(); + int indexStyle = chosen.getSelectionModel().getSelectedIndex(); PreviewPreferences preferences = Globals.prefs.getPreviewPreferences(); preferences = new PreviewPreferences(preferences.getPreviewCycle(),indexStyle,preferences.getPreviewPanelDividerPosition(),preferences.isPreviewPanelEnabled(), preferences.getPreviewStyle(),preferences.getPreviewStyleDefault()); @@ -164,46 +162,22 @@ private void setupLogic() { } private void setupGui() { - JPanel chooseStyle = FormBuilder.create() - .columns("0:grow, $lcgap, pref, $lcgap, 0:grow") - .rows("pref, $lg, fill:pref:grow, $lg, pref:grow, $lg, pref:grow, $lg, pref:grow") - .padding(Paddings.DIALOG) - - .addSeparator(Localization.lang("Current Preview")) - .xyw(1, 1, 5) - .add(available) - .xywh(1, 3, 1, 7) - .add(chosen) - .xywh(5, 3, 1, 7) - - .add(btnRight) - .xy(3, 3, "fill, bottom") - .add(btnLeft) - .xy(3, 5, "fill, top") - .add(btnUp) - .xy(3, 7, "fill, bottom") - .add(btnDown) - .xy(3, 9, "fill, top") - .build(); - - JPanel preview = FormBuilder.create() - .columns("pref:grow, $lcgap, pref, $lcgap, pref") - .rows("pref, $lg, fill:pref:grow") - .padding(Paddings.DIALOG) - - .addSeparator(Localization.lang("Preview")) - .xy(1, 1) - .add(btnTest) - .xy(3, 1) - .add(btnDefault) - .xy(5, 1) - .add(scrollPane) - .xyw(1, 3, 5) - .build(); + VBox vBox = new VBox(); + vBox.getChildren().addAll(new Label(""), new Label(""),new Label(""),new Label(""), new Label(""),new Label(""),new Label(""), btnRight,btnLeft, new Label(""), new Label(""),new Label(""),btnUp,btnDown); + Label label = new Label(Localization.lang("Current Preview") + " ------------------------------------------"); + label.setFont(new Font(14)); + gridPane.add(label,1,1); + gridPane.add(available,1,2); + gridPane.add(vBox,2,2); + gridPane.add(chosen,3,2); + gridPane.add(btnTest,2,6); + gridPane.add(btnDefault,3,6); + layout.setPrefSize(600,300); + gridPane.add(scrollPane,1,9); + } - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - add(chooseStyle, BorderLayout.CENTER); - add(preview, BorderLayout.PAGE_END); + public GridPane getGridPane() { + return gridPane; } @Override @@ -216,26 +190,26 @@ public void setValues() { // in case the style is not a valid citation style file, an empty Optional is returned Optional citationStyle = CitationStyle.createCitationStyleFromFile(style); if (citationStyle.isPresent()) { - chosenModel.addElement(citationStyle.get()); + chosenModel.add(citationStyle.get()); } else { if (isPreviewChosen) { LOGGER.error("Preview is already in the list, something went wrong"); continue; } isPreviewChosen = true; - chosenModel.addElement(Localization.lang("Preview")); + chosenModel.add(Localization.lang("Preview")); } } availableModel.clear(); if (!isPreviewChosen) { - availableModel.addElement(Localization.lang("Preview")); + availableModel.add(Localization.lang("Preview")); } - btnLeft.setEnabled(!chosen.isSelectionEmpty()); - btnRight.setEnabled(!available.isSelectionEmpty()); - btnUp.setEnabled(!chosen.isSelectionEmpty()); - btnDown.setEnabled(!chosen.isSelectionEmpty()); + btnLeft.setDisable(!chosen.getSelectionModel().getSelectedItems().isEmpty()); + btnRight.setDisable(available.getSelectionModel().getSelectedIndices().isEmpty()); + btnUp.setDisable(!chosen.getSelectionModel().getSelectedIndices().isEmpty()); + btnDown.setDisable(!chosen.getSelectionModel().getSelectedIndices().isEmpty()); if (discoverCitationStyleWorker != null) { discoverCitationStyleWorker.cancel(true); @@ -257,9 +231,9 @@ public void done() { get().stream() .filter(style -> !previewPreferences.getPreviewCycle().contains(style.getFilePath())) .sorted(Comparator.comparing(CitationStyle::getTitle)) - .forEach(availableModel::addElement); + .forEach(availableModel::add); - btnRight.setEnabled(!availableModel.isEmpty()); + btnRight.setDisable(availableModel.isEmpty()); } catch (InterruptedException | ExecutionException e) { LOGGER.error("something went wrong while adding the discovered CitationStyles to the list "); } @@ -273,9 +247,7 @@ public void done() { @Override public void storeSettings() { List styles = new ArrayList<>(); - Enumeration elements = chosenModel.elements(); - while (elements.hasMoreElements()) { - Object obj = elements.nextElement(); + for (Object obj : chosenModel) { if (obj instanceof CitationStyle) { styles.add(((CitationStyle) obj).getFilePath()); } else if (obj instanceof String) { diff --git a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java index e3991783850..da11f374b54 100644 --- a/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TableColumnsTab.java @@ -1,6 +1,5 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.Collection; @@ -10,14 +9,11 @@ import java.util.Locale; import javax.swing.AbstractAction; -import javax.swing.JPanel; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; @@ -32,11 +28,12 @@ import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; +import javafx.scene.text.Font; import org.jabref.gui.BasePanel; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.help.HelpAction; @@ -49,7 +46,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class TableColumnsTab extends JPanel implements PrefsTab { +class TableColumnsTab extends Pane implements PrefsTab { private static final Logger LOGGER = LoggerFactory.getLogger(TableColumnsTab.class); @@ -90,6 +87,7 @@ class TableColumnsTab extends JPanel implements PrefsTab { private boolean oldWriteSpecialFields; private final VBox listOfFileColumnsVBox; private final ObservableList data; + private final GridPane builder = new GridPane(); /** * Customization of external program paths. * @@ -106,6 +104,9 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { new TableRow("journal",130), new TableRow("bibtexkey",100)); + Font font = new Font(10); + Font font1 = new Font(14); + colSetup = new TableView<>(); TableColumn field = new TableColumn<>(Localization.lang("Field name")); TableColumn column = new TableColumn<>(Localization.lang("Column width")); @@ -135,7 +136,6 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { final TextField addLast = new TextField(); addLast.setMaxWidth(column.getPrefWidth()); addLast.setPromptText("width"); - GridPane builder = new GridPane(); BorderPane tabPanel = new BorderPane(); ScrollPane sp = new ScrollPane(); sp.setContent(colSetup); @@ -213,15 +213,20 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { tabPanel.setBottom(toolBar); fileColumn = new CheckBox(Localization.lang("Show file column")); + fileColumn.setFont(font); urlColumn = new CheckBox(Localization.lang("Show URL/DOI column")); + urlColumn.setFont(font); preferUrl = new RadioButton(Localization.lang("Show URL first")); + preferUrl.setFont(font); preferDoi = new RadioButton(Localization.lang("Show DOI first")); + preferDoi.setFont(font); urlColumn.setOnAction(arg0 -> { preferUrl.setDisable(!urlColumn.isSelected()); preferDoi.setDisable(!urlColumn.isSelected()); }); arxivColumn = new CheckBox(Localization.lang("Show ArXiv column")); + arxivColumn.setFont(font); Collection fileTypes = ExternalFileTypes.getInstance().getExternalFileTypeSelection(); String[] fileTypeNames = new String[fileTypes.size()]; @@ -236,6 +241,7 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { listOfFileColumnsScrollPane.setMaxHeight(80); listOfFileColumnsScrollPane.setContent(listOfFileColumnsVBox); extraFileColumns = new CheckBox(Localization.lang("Show extra columns")); + extraFileColumns.setFont(font); if (!extraFileColumns.isSelected()) { listOfFileColumnsVBox.setDisable(true); } @@ -243,24 +249,33 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { /*** begin: special table columns and special fields ***/ - Button helpButton = new Button("Help"); + Button helpButton = new Button("?"); helpButton.setOnAction(e->new HelpAction(Localization.lang("Help on special fields"), HelpFile.SPECIAL_FIELDS).getHelpButton().doClick()); rankingColumn = new CheckBox(Localization.lang("Show rank")); + rankingColumn.setFont(font); qualityColumn = new CheckBox(Localization.lang("Show quality")); + qualityColumn.setFont(font); priorityColumn = new CheckBox(Localization.lang("Show priority")); + priorityColumn.setFont(font); relevanceColumn = new CheckBox(Localization.lang("Show relevance")); + relevanceColumn.setFont(font); printedColumn = new CheckBox(Localization.lang("Show printed status")); + priorityColumn.setFont(font); readStatusColumn = new CheckBox(Localization.lang("Show read status")); + readStatusColumn.setFont(font); // "sync keywords" and "write special" fields may be configured mutually exclusive only // The implementation supports all combinations (TRUE+TRUE and FALSE+FALSE, even if the latter does not make sense) // To avoid confusion, we opted to make the setting mutually exclusive syncKeywords = new RadioButton(Localization.lang("Synchronize with keywords")); + syncKeywords.setFont(font); writeSpecialFields = new RadioButton(Localization.lang("Write values of special fields as separate fields to BibTeX")); + writeSpecialFields.setFont(font); specialFieldsEnabled = new CheckBox(Localization.lang("Enable special fields")); + specialFieldsEnabled.setFont(font); specialFieldsEnabled.setOnAction(event -> { boolean isEnabled = specialFieldsEnabled.isSelected(); rankingColumn.setDisable(!isEnabled); @@ -273,7 +288,9 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { writeSpecialFields.setDisable(!isEnabled); }); - builder.add(new Label(Localization.lang("Special table columns")),1,1); + Label label = new Label(Localization.lang("Special table columns") + " ------------------------------------"); + label.setFont(font1); + builder.add(label,1,1); GridPane specialTableColumnsBuilder = new GridPane(); specialTableColumnsBuilder.add(specialFieldsEnabled,1,1); @@ -301,19 +318,25 @@ public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) { /*** end: special table columns and special fields ***/ - builder.add(new Label(Localization.lang("Entry table columns")),1,3); - builder.add(tabPanel,1,4); + builder.add(new Label(""),1,3); + + Label label1 = new Label(Localization.lang("Entry table columns") + " --------------------------------------"); + label1.setFont(font1); + builder.add(label1,1,4); + builder.add(tabPanel,1,5); Button buttonWidth = new Button("Update to current column widths"); + buttonWidth.setFont(font); buttonWidth.setOnAction(e->new UpdateWidthsAction()); Button buttonOrder = new Button("Update to current column order"); + buttonOrder.setFont(font); buttonOrder.setOnAction(e->new UpdateOrderAction()); - builder.add(buttonWidth,1,5); - builder.add(buttonOrder,1,6); + builder.add(buttonWidth,1,6); + builder.add(buttonOrder,1,7); + } - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + public GridPane getBuilder() { + return builder; } @Override diff --git a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java index 53030172f13..b17573f7e61 100644 --- a/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/TablePrefsTab.java @@ -1,31 +1,27 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; -import javax.swing.JPanel; - import javafx.collections.FXCollections; -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import javafx.scene.text.Font; import org.jabref.Globals; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; import org.jabref.preferences.JabRefPreferences; -class TablePrefsTab extends JPanel implements PrefsTab { +class TablePrefsTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; @@ -49,7 +45,7 @@ class TablePrefsTab extends JPanel implements PrefsTab { private final ComboBox priSort; private final ComboBox secSort; private final ComboBox terSort; - + private final GridPane builder = new GridPane(); /** * Customization of external program paths. @@ -59,7 +55,8 @@ class TablePrefsTab extends JPanel implements PrefsTab { */ public TablePrefsTab(JabRefPreferences prefs) { this.prefs = prefs; - setLayout(new BorderLayout()); + Font font = new Font(10); + Font font1 = new Font(14); /** * Added Bibtexkey to combobox. @@ -77,14 +74,21 @@ public TablePrefsTab(JabRefPreferences prefs) { terSort = new ComboBox<>(FXCollections.observableArrayList(allPlusKey)); autoResizeMode = new CheckBox(Localization.lang("Fit table horizontally on screen")); - + autoResizeMode.setFont(font); namesAsIs = new RadioButton(Localization.lang("Show names unchanged")); + namesAsIs.setFont(font); namesFf = new RadioButton(Localization.lang("Show 'Firstname Lastname'")); + namesFf.setFont(font); namesFl = new RadioButton(Localization.lang("Show 'Lastname, Firstname'")); + namesFl.setFont(font); namesNatbib = new RadioButton(Localization.lang("Natbib style")); + namesNatbib.setFont(font); noAbbrNames = new RadioButton(Localization.lang("Do not abbreviate names")); + noAbbrNames.setFont(font); abbrNames = new RadioButton(Localization.lang("Abbreviate names")); + abbrNames.setFont(font); lastNamesOnly = new RadioButton(Localization.lang("Show last names only")); + lastNamesOnly.setFont(font); priField = new TextField(); secField = new TextField(); @@ -113,52 +117,61 @@ public TablePrefsTab(JabRefPreferences prefs) { }); priDesc = new CheckBox(Localization.lang("Descending")); + priDesc.setFont(font); secDesc = new CheckBox(Localization.lang("Descending")); + secDesc.setFont(font); terDesc = new CheckBox(Localization.lang("Descending")); + terDesc.setFont(font); - GridPane builder = new GridPane(); - builder.add(new Label(Localization.lang("Format of author and editor names")),1,1); + Label label = new Label(Localization.lang("Format of author and editor names") + " ----------------------"); + label.setFont(font1); + builder.add(label,1,1); builder.add(namesAsIs,1,2); builder.add(noAbbrNames,2,2); builder.add(namesFf,1,3); builder.add(abbrNames,2,3); builder.add(namesFl,1,4); builder.add(lastNamesOnly,2,4); - builder.add(namesNatbib,1,5); + Label label1 = new Label(""); + builder.add(label1,1,6); - builder.add(new Label(Localization.lang("Default sort criteria")),1,6); + Label label2 = new Label(Localization.lang("Default sort criteria") + " ----------------------------------------"); + label2.setFont(font1); + builder.add(label2,1,7); // Create a new panel with its own FormLayout for these items: - Label lab = new Label(); - lab = new Label(Localization.lang("Primary sort criterion")); - builder.add(lab,1,7); - builder.add(priSort,2,7); - builder.add(priField,3,7); - builder.add(priDesc,4,7); + Label lab = new Label(Localization.lang("Primary sort criterion")); + lab.setFont(font); + builder.add(lab,1,8); + builder.add(priSort,2,8); + builder.add(priField,3,8); + builder.add(priDesc,4,8); lab = new Label(Localization.lang("Secondary sort criterion")); - builder.add(lab,1,8); - builder.add(secSort,2,8); - builder.add(secField,3,8); - builder.add(secDesc,4,8); + lab.setFont(font); + builder.add(lab,1,9); + builder.add(secSort,2,9); + builder.add(secField,3,9); + builder.add(secDesc,4,9); lab = new Label(Localization.lang("Tertiary sort criterion")); - builder.add(lab,1,9); - builder.add(terSort,2,9); - builder.add(terField,3,9); - builder.add(terDesc,4,9); + builder.add(lab,1,10); + builder.add(terSort,2,10); + builder.add(terField,3,10); + builder.add(terDesc,4,10); - builder.add(new Label(Localization.lang("Sort the following fields as numeric fields") + ':'),1,10); - builder.add(numericFields,2,10); + builder.add(new Label(Localization.lang("Sort the following fields as numeric fields") + ':'),1,11); + builder.add(numericFields,2,11); - builder.add(new Label(Localization.lang("General")),1,11); - builder.add(autoResizeMode,1,12); - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); + Label label3 = new Label(""); + builder.add(label3,1,12); + Label label4 = new Label(Localization.lang("General") + " ------------------------------------------------------"); + label4.setFont(font1); + builder.add(label4,1,13); + builder.add(autoResizeMode,1,14); namesNatbib.setOnAction(e -> { abbrNames.setDisable(namesNatbib.isSelected()); lastNamesOnly.setDisable(namesNatbib.isSelected()); @@ -166,6 +179,10 @@ public TablePrefsTab(JabRefPreferences prefs) { }); } + public GridPane getBuilder() { + return builder; + } + @Override public void setValues() { autoResizeMode.setSelected(prefs.getBoolean(JabRefPreferences.AUTO_RESIZE_MODE)); diff --git a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java index c2bdbd37970..cda5f44dfde 100644 --- a/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java +++ b/src/main/java/org/jabref/gui/preftabs/XmpPrefsTab.java @@ -1,25 +1,28 @@ package org.jabref.gui.preftabs; -import java.awt.BorderLayout; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import javax.swing.JPanel; - -import javafx.embed.swing.JFXPanel; -import javafx.scene.Scene; +import javafx.beans.property.SimpleStringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; -import javafx.scene.layout.VBox; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.text.Font; -import org.jabref.gui.customjfx.CustomJFXPanel; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -28,17 +31,16 @@ * * Allows the user to enable and configure the XMP privacy filter. */ -class XmpPrefsTab extends JPanel implements PrefsTab { +class XmpPrefsTab extends Pane implements PrefsTab { private final JabRefPreferences prefs; private boolean tableChanged; private int rowCount; - private final ArrayList textFields = new ArrayList<>(10); - private final VBox vBox = new VBox(); + private final GridPane builder = new GridPane(); + private final ObservableList data = FXCollections.observableArrayList(); private final CheckBox privacyFilterCheckBox = new CheckBox( Localization.lang("Do not write the following fields to XMP Metadata:")); - - private final List tableRows = new ArrayList<>(10); + private final List tableRows = new ArrayList<>(10); /** @@ -46,60 +48,89 @@ class XmpPrefsTab extends JPanel implements PrefsTab { */ public XmpPrefsTab(JabRefPreferences prefs) { this.prefs = Objects.requireNonNull(prefs); - setLayout(new BorderLayout()); - - GridPane builder = new GridPane(); - + TableView tableView = new TableView(); + TableColumn column = new TableColumn<>(Localization.lang("Field to filter")); + column.setCellValueFactory(new PropertyValueFactory<>("name")); + column.setCellFactory(TextFieldTableCell.forTableColumn()); + column.setOnEditCommit( + (TableColumn.CellEditEvent t) -> { + ((TableRow) t.getTableView().getItems().get( + t.getTablePosition().getRow()) + ).setName(t.getNewValue()); + }); + column.setPrefWidth(350); + tableView.setItems(data); + tableView.getColumns().add(column); + final TextField addName = new TextField(); + addName.setPromptText("name"); + addName.setMaxWidth(column.getPrefWidth()); BorderPane tablePanel = new BorderPane(); ScrollPane scrollPane = new ScrollPane(); scrollPane.setMaxHeight(400); - scrollPane.setMaxWidth(170); - textFields.add(new TextField("pdf")); - vBox.getChildren().add(new Label("Field to filter")); - vBox.getChildren().addAll(textFields); - scrollPane.setContent(vBox); + scrollPane.setMaxWidth(400); + scrollPane.setContent(tableView); tablePanel.setCenter(scrollPane); - Button add = new Button("+"); - add.setOnAction(e->new AddRowAction()); - Button delete = new Button("-"); - delete.setOnAction(e->new DeleteRowAction()); - VBox toolbar = new VBox(add,delete); - tablePanel.setRight(toolbar); + Button add = new Button("Add"); + add.setOnAction(e-> { + if (!addName.getText().isEmpty()) { + TableRow tableRow = new TableRow(addName.getText()); + addName.clear(); + data.add(tableRow); + tableRows.clear(); + tableRows.addAll(data); + rowCount++; + tableView.setItems(data); + tableChanged = true; + tableView.refresh(); + } + }); + Button delete = new Button("Delete"); + delete.setOnAction(e-> { + if (tableView.getFocusModel() != null && tableView.getFocusModel().getFocusedIndex() != -1) { + tableChanged = true; + int row = tableView.getFocusModel().getFocusedIndex(); + TableRow tableRow = data.get(row); + data.remove(tableRow); + tableRows.clear(); + tableRows.addAll(data); + tableView.setItems(data); + rowCount--; + tableView.refresh(); + } + }); + HBox toolbar = new HBox(addName,add,delete); + tablePanel.setBottom(toolbar); // Build Prefs Tabs - builder.add(new Label(Localization.lang("XMP export privacy settings")),1,1); - + Label label = new Label(Localization.lang("XMP export privacy settings") + " -------------------------"); + label.setFont(new Font(14)); + builder.add(label,1,1); + privacyFilterCheckBox.setFont(new Font(10)); builder.add(privacyFilterCheckBox,1,2); builder.add(tablePanel,1,3); - JFXPanel panel = CustomJFXPanel.wrap(new Scene(builder)); - setLayout(new BorderLayout()); - add(panel, BorderLayout.CENTER); } - class DeleteRowAction { - public DeleteRowAction() { - textFields.remove(textFields.get(textFields.size() - 1)); - rowCount--; - vBox.getChildren().clear(); - vBox.getChildren().add(new Label(Localization.lang("Field to filter"))); - vBox.getChildren().addAll(textFields); - tableChanged = true; - } + public GridPane getBuilder() { + return builder; } - class AddRowAction { + public static class TableRow { + private SimpleStringProperty name; + + TableRow(String name) { + this.name = new SimpleStringProperty(name); + } + + public void setName(String name) { + this.name.set(name); + } - public AddRowAction() { - rowCount++; - textFields.add(new TextField("")); - vBox.getChildren().clear(); - vBox.getChildren().add(new Label("field to filter")); - vBox.getChildren().addAll(textFields); - tableChanged = true; + public String getName() { + return name.get(); } } @@ -110,11 +141,7 @@ public AddRowAction() { public void setValues() { tableRows.clear(); //List names = JabRefPreferences.getInstance().getStringList(JabRefPreferences.XMP_PRIVACY_FILTERS); - Listnames = new ArrayList<>(); - for (TextField textField : textFields) { - names.add(textField.getText()); - } - tableRows.addAll(names); + tableRows.addAll(data); rowCount = tableRows.size() + 5; privacyFilterCheckBox.setSelected(JabRefPreferences.getInstance().getBoolean( From 0fb9d89ead8dbe168229027b0315ceb06aacf471 Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Fri, 10 Aug 2018 18:14:44 +0800 Subject: [PATCH 20/58] Polish the code style --- src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java index 8727d6ce17d..465ba42db71 100644 --- a/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java +++ b/src/main/java/org/jabref/gui/SaveOrderConfigDisplay.java @@ -15,8 +15,8 @@ import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.layout.GridPane; - import javafx.scene.text.Font; + import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.InternalBibtexFields; From 9a3a89d12f089fc8e684bc1893c10b8ba7a2ce7e Mon Sep 17 00:00:00 2001 From: 1160300311 <1399774753@qq.com> Date: Fri, 10 Aug 2018 19:07:57 +0800 Subject: [PATCH 21/58] Merge the latest commits --- src/main/java/org/jabref/JabRefGUI.java | 22 +- src/main/java/org/jabref/gui/GUIGlobals.java | 2 + .../jabref/gui/customjfx/CustomJFXPanel.java | 2 +- .../gui/fieldeditors/EditorTextArea.java | 35 ++ .../jabref/gui/fieldeditors/UrlEditor.java | 18 +- .../fieldeditors/contextmenu/EditorMenus.java | 19 + .../LinkedFilesEditDialogViewModel.java | 21 +- .../org/jabref/gui/help/AboutDialogView.java | 9 +- .../java/org/jabref/gui/icon/IconTheme.java | 6 +- .../java/org/jabref/gui/util/BaseDialog.java | 2 +- .../gui/util/DefaultFileUpdateMonitor.java | 4 + .../java/org/jabref/gui/util/ThemeLoader.java | 8 +- .../jabref/logic/formatter/Formatters.java | 2 + .../bibtexfields/CleanupURLFormatter.java | 65 +++ .../org/jabref/styletester/StyleTester.fxml | 481 ++++++++++++++++++ .../jabref/styletester/StyleTesterMain.java | 36 ++ .../jabref/styletester/StyleTesterView.java | 50 ++ 17 files changed, 748 insertions(+), 34 deletions(-) create mode 100644 src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupURLFormatter.java create mode 100644 src/main/java/org/jabref/styletester/StyleTester.fxml create mode 100644 src/main/java/org/jabref/styletester/StyleTesterMain.java create mode 100644 src/main/java/org/jabref/styletester/StyleTesterView.java diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/JabRefGUI.java index f6074c34725..507a5563d53 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/JabRefGUI.java @@ -54,10 +54,10 @@ public JabRefGUI(Stage mainStage, List argsDatabases, boolean isBl // passed file (we take the first one) should be focused focusedFile = argsDatabases.stream() - .findFirst() - .flatMap(ParserResult::getFile) - .map(File::getAbsolutePath) - .orElse(Globals.prefs.get(JabRefPreferences.LAST_FOCUSED)); + .findFirst() + .flatMap(ParserResult::getFile) + .map(File::getAbsolutePath) + .orElse(Globals.prefs.get(JabRefPreferences.LAST_FOCUSED)); openWindow(mainStage); JabRefGUI.checkForNewVersion(false); @@ -109,15 +109,15 @@ private void openWindow(Stage mainStage) { try { new SharedDatabaseUIManager(mainFrame).openSharedDatabaseFromParserResult(pr); } catch (SQLException | DatabaseNotSupportedException | InvalidDBMSConnectionPropertiesException | - NotASharedDatabaseException e) { + NotASharedDatabaseException e) { pr.getDatabaseContext().clearDatabaseFile(); // do not open the original file pr.getDatabase().clearSharedDatabaseID(); LOGGER.error("Connection error", e); dialogService.showErrorDialogAndWait( - Localization.lang("Connection error"), - Localization.lang("A local copy will be opened."), - e); + Localization.lang("Connection error"), + Localization.lang("A local copy will be opened."), + e); } toOpenTab.add(pr); } else if (pr.toOpenTab()) { @@ -150,7 +150,7 @@ private void openWindow(Stage mainStage) { } Scene scene = new Scene(JabRefGUI.mainFrame, 800, 800); - Globals.getThemeLoader().installBaseCss(scene); + Globals.getThemeLoader().installBaseCss(scene, Globals.prefs); mainStage.setTitle(JabRefFrame.FRAME_TITLE); mainStage.getIcons().addAll(IconTheme.getLogoSetFX()); mainStage.setScene(scene); @@ -166,7 +166,7 @@ private void openWindow(Stage mainStage) { for (ParserResult pr : failed) { String message = Localization.lang("Error opening file '%0'.", pr.getFile().get().getName()) + "\n" - + pr.getErrorMessage(); + + pr.getErrorMessage(); dialogService.showErrorDialogAndWait(Localization.lang("Error opening file"), message); @@ -223,7 +223,7 @@ private void openLastEditedDatabases() { } ParserResult parsedDatabase = OpenDatabase.loadDatabase(fileName, - Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); + Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); if (parsedDatabase.isEmpty()) { LOGGER.error(Localization.lang("Error opening file") + " '" + dbFile.getPath() + "'"); diff --git a/src/main/java/org/jabref/gui/GUIGlobals.java b/src/main/java/org/jabref/gui/GUIGlobals.java index 153018119e8..a8c25e50d94 100644 --- a/src/main/java/org/jabref/gui/GUIGlobals.java +++ b/src/main/java/org/jabref/gui/GUIGlobals.java @@ -4,6 +4,7 @@ import java.awt.Font; import org.jabref.Globals; +import org.jabref.gui.icon.IconTheme; import org.jabref.gui.keyboard.EmacsKeyBindings; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; @@ -55,6 +56,7 @@ public static void init() { // Set up entry editor colors, first time: GUIGlobals.updateEntryEditorColors(); + IconTheme.loadFonts(); GUIGlobals.currentFont = new Font(Globals.prefs.get(JabRefPreferences.FONT_FAMILY), Globals.prefs.getInt(JabRefPreferences.FONT_STYLE), Globals.prefs.getInt(JabRefPreferences.FONT_SIZE)); } diff --git a/src/main/java/org/jabref/gui/customjfx/CustomJFXPanel.java b/src/main/java/org/jabref/gui/customjfx/CustomJFXPanel.java index 1cb3e07b106..5cdafa593ce 100644 --- a/src/main/java/org/jabref/gui/customjfx/CustomJFXPanel.java +++ b/src/main/java/org/jabref/gui/customjfx/CustomJFXPanel.java @@ -13,7 +13,7 @@ public class CustomJFXPanel { public static JFXPanel wrap(Scene scene) { JFXPanel container = new JFXPanel(); - Globals.getThemeLoader().installBaseCss(scene); + Globals.getThemeLoader().installBaseCss(scene, Globals.prefs); DefaultTaskExecutor.runInJavaFXThread(() -> container.setScene(scene)); return container; } diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java b/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java index 1783e9f1396..a718e408252 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java +++ b/src/main/java/org/jabref/gui/fieldeditors/EditorTextArea.java @@ -2,6 +2,7 @@ import java.net.URL; import java.util.List; +import java.util.Objects; import java.util.ResourceBundle; import java.util.function.Supplier; @@ -15,6 +16,13 @@ public class EditorTextArea extends javafx.scene.control.TextArea implements Initializable, ContextMenuAddable { + /** + * Variable that contains user-defined behavior for paste action. + */ + private PasteActionHandler pasteActionHandler = () -> { + // Set empty paste behavior by default + }; + public EditorTextArea() { this(""); } @@ -65,4 +73,31 @@ public void populateContextMenu(ContextMenu contextMenu) { public void initialize(URL location, ResourceBundle resources) { // not needed } + + /** + * Set pasteActionHandler variable to passed handler + * @param handler an instance of PasteActionHandler that describes paste behavior + */ + public void setPasteActionHandler(PasteActionHandler handler) { + Objects.requireNonNull(handler); + this.pasteActionHandler = handler; + } + + /** + * Override javafx TextArea method applying TextArea.paste() and pasteActionHandler after + */ + @Override + public void paste() { + super.paste(); + pasteActionHandler.handle(); + } + + /** + * Interface presents user-described paste behaviour applying to paste method + */ + @FunctionalInterface + public interface PasteActionHandler { + + void handle(); + } } diff --git a/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java b/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java index b074522f30d..90d14071feb 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/UrlEditor.java @@ -1,12 +1,18 @@ package org.jabref.gui.fieldeditors; +import java.util.List; +import java.util.function.Supplier; + import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Parent; +import javafx.scene.control.MenuItem; import javafx.scene.layout.HBox; import org.jabref.gui.DialogService; import org.jabref.gui.autocompleter.AutoCompleteSuggestionProvider; +import org.jabref.gui.fieldeditors.contextmenu.EditorMenus; +import org.jabref.logic.formatter.bibtexfields.CleanupURLFormatter; import org.jabref.logic.integrity.FieldCheckers; import org.jabref.model.entry.BibEntry; import org.jabref.preferences.JabRefPreferences; @@ -15,17 +21,23 @@ public class UrlEditor extends HBox implements FieldEditorFX { - @FXML private UrlEditorViewModel viewModel; + @FXML private final UrlEditorViewModel viewModel; @FXML private EditorTextArea textArea; public UrlEditor(String fieldName, DialogService dialogService, AutoCompleteSuggestionProvider suggestionProvider, FieldCheckers fieldCheckers, JabRefPreferences preferences) { this.viewModel = new UrlEditorViewModel(fieldName, suggestionProvider, dialogService, fieldCheckers); ViewLoader.view(this) - .root(this) - .load(); + .root(this) + .load(); textArea.textProperty().bindBidirectional(viewModel.textProperty()); + Supplier> contextMenuSupplier = EditorMenus.getCleanupURLMenu(textArea); + textArea.addToContextMenu(contextMenuSupplier); + + // init paste handler for URLEditor to format pasted url link in textArea + textArea.setPasteActionHandler(()-> + textArea.setText(new CleanupURLFormatter().format(textArea.getText()))); new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), textArea); } diff --git a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java index 179a1cfb9b7..8068b8a3f4a 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java +++ b/src/main/java/org/jabref/gui/fieldeditors/contextmenu/EditorMenus.java @@ -16,6 +16,7 @@ import javafx.scene.control.Tooltip; import org.jabref.gui.actions.CopyDoiUrlAction; +import org.jabref.logic.formatter.bibtexfields.CleanupURLFormatter; import org.jabref.logic.formatter.bibtexfields.NormalizeNamesFormatter; import org.jabref.logic.l10n.Localization; @@ -84,4 +85,22 @@ public static Supplier> getDOIMenu(TextArea textArea) { return menuItems; }; } + + /** + * The default context menu with a specific menu item to cleanup URL. + * + * @param textArea text-area that this menu will be connected to + * @return menu containing items of the default menu and an item to cleanup a URL + */ + public static Supplier> getCleanupURLMenu(TextArea textArea) { + return () -> { + CustomMenuItem cleanupURL = new CustomMenuItem(new Label(Localization.lang("Cleanup URL link"))); + cleanupURL.setDisable(textArea.textProperty().isEmpty().get()); + cleanupURL.setOnAction(event -> textArea.setText(new CleanupURLFormatter().format(textArea.getText()))); + + List menuItems = new ArrayList<>(); + menuItems.add(cleanupURL); + return menuItems; + }; + } } diff --git a/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java b/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java index 492cda62592..94c534381c1 100644 --- a/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java +++ b/src/main/java/org/jabref/gui/filelist/LinkedFilesEditDialogViewModel.java @@ -76,26 +76,24 @@ public void openBrowseDialog() { String fileName = Paths.get(fileText).getFileName().toString(); FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() - .withInitialDirectory(workingDir) - .withInitialFileName(fileName) - .build(); + .withInitialDirectory(workingDir) + .withInitialFileName(fileName) + .build(); dialogService.showFileOpenDialog(fileDialogConfiguration).ifPresent(path -> { // Store the directory for next time: preferences.setWorkingDir(path); + link.set(relativize(path)); - // If the file is below the file directory, make the path relative: - List fileDirectories = database.getFileDirectoriesAsPaths(preferences.getFileDirectoryPreferences()); - path = FileUtil.shortenFileName(path, fileDirectories); - - link.set(path.toString()); setExternalFileTypeByExtension(link.getValueSafe()); }); } public void setValues(LinkedFile linkedFile) { description.set(linkedFile.getDescription()); - link.set(linkedFile.getLink()); + + Path linkPath = Paths.get(linkedFile.getLink()); + link.set(relativize(linkPath)); selectedExternalFileType.setValue(null); @@ -128,4 +126,9 @@ public LinkedFile getNewLinkedFile() { return new LinkedFile(description.getValue(), link.getValue(), monadicSelectedExternalFileType.map(ExternalFileType::toString).getOrElse("")); } + private String relativize(Path filePath) { + List fileDirectories = database.getFileDirectoriesAsPaths(preferences.getFileDirectoryPreferences()); + return FileUtil.shortenFileName(filePath, fileDirectories).toString(); + } + } diff --git a/src/main/java/org/jabref/gui/help/AboutDialogView.java b/src/main/java/org/jabref/gui/help/AboutDialogView.java index a977446f7b7..6bad3849de3 100644 --- a/src/main/java/org/jabref/gui/help/AboutDialogView.java +++ b/src/main/java/org/jabref/gui/help/AboutDialogView.java @@ -28,14 +28,19 @@ public class AboutDialogView extends BaseDialog { public AboutDialogView() { this.setTitle(Localization.lang("About JabRef")); + this.setResizable(true); ViewLoader.view(this) - .load() - .setAsDialogPane(this); + .load() + .setAsDialogPane(this); ControlHelper.setAction(copyVersionButton, getDialogPane(), event -> copyVersionToClipboard()); } + public AboutDialogViewModel getViewModel() { + return viewModel; + } + @FXML private void initialize() { viewModel = new AboutDialogViewModel(dialogService, clipBoardManager, buildInfo); diff --git a/src/main/java/org/jabref/gui/icon/IconTheme.java b/src/main/java/org/jabref/gui/icon/IconTheme.java index 73dcd876c75..1191180aae7 100644 --- a/src/main/java/org/jabref/gui/icon/IconTheme.java +++ b/src/main/java/org/jabref/gui/icon/IconTheme.java @@ -50,7 +50,7 @@ public class IconTheme { private static final Map KEY_TO_ICON = readIconThemeFile( IconTheme.class.getResource("/images/Icons.properties"), "/images/external/"); - static { + public static void loadFonts() { try (InputStream stream = getMaterialDesignIconsStream()) { FONT = Font.createFont(Font.TRUETYPE_FONT, stream); } catch (FontFormatException | IOException e) { @@ -362,14 +362,14 @@ public String fontFamily() { public Button asButton() { Button button = new Button(); button.setGraphic(getGraphicNode()); - button.getStyleClass().add("flatButton"); + button.getStyleClass().add("icon-button"); return button; } public ToggleButton asToggleButton() { ToggleButton button = new ToggleButton(); button.setGraphic(getGraphicNode()); - button.getStyleClass().add("flatButton"); + button.getStyleClass().add("icon-button"); return button; } } diff --git a/src/main/java/org/jabref/gui/util/BaseDialog.java b/src/main/java/org/jabref/gui/util/BaseDialog.java index 98bb1f7ae15..73c157838df 100644 --- a/src/main/java/org/jabref/gui/util/BaseDialog.java +++ b/src/main/java/org/jabref/gui/util/BaseDialog.java @@ -21,7 +21,7 @@ protected BaseDialog() { setDialogIcon(IconTheme.getJabRefImageFX()); - Globals.getThemeLoader().installBaseCss(getDialogPane().getScene()); + Globals.getThemeLoader().installBaseCss(getDialogPane().getScene(), Globals.prefs); } private void setDialogIcon(Image image) { diff --git a/src/main/java/org/jabref/gui/util/DefaultFileUpdateMonitor.java b/src/main/java/org/jabref/gui/util/DefaultFileUpdateMonitor.java index a9ef705e068..28de7285f3f 100644 --- a/src/main/java/org/jabref/gui/util/DefaultFileUpdateMonitor.java +++ b/src/main/java/org/jabref/gui/util/DefaultFileUpdateMonitor.java @@ -69,6 +69,10 @@ private void notifyAboutChange(Path path) { @Override public void addListenerForFile(Path file, FileUpdateListener listener) throws IOException { + if (watcher == null) { + throw new IllegalStateException("You need to start the file monitor before watching files"); + } + // We can't watch files directly, so monitor their parent directory for updates Path directory = file.toAbsolutePath().getParent(); directory.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY); diff --git a/src/main/java/org/jabref/gui/util/ThemeLoader.java b/src/main/java/org/jabref/gui/util/ThemeLoader.java index 208b808ec31..87eeb0a83e9 100644 --- a/src/main/java/org/jabref/gui/util/ThemeLoader.java +++ b/src/main/java/org/jabref/gui/util/ThemeLoader.java @@ -11,10 +11,10 @@ import javafx.scene.Parent; import javafx.scene.Scene; -import org.jabref.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.model.strings.StringUtil; import org.jabref.model.util.FileUpdateMonitor; +import org.jabref.preferences.JabRefPreferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,7 +49,7 @@ public ThemeLoader(FileUpdateMonitor fileUpdateMonitor) { * Installs the base css file as a stylesheet in the given scene. * Changes in the css file lead to a redraw of the scene using the new css file. */ - public void installBaseCss(Scene scene) { + public void installBaseCss(Scene scene, JabRefPreferences preferences) { addAndWatchForChanges(scene, DEFAULT_PATH_MAIN_CSS, 0); if (StringUtil.isNotBlank(CSS_SYSTEM_PROPERTY)) { @@ -60,7 +60,7 @@ public void installBaseCss(Scene scene) { } } - Globals.prefs.getFontSize().ifPresent(size -> scene.getRoot().setStyle("-fx-font-size: " + size + "pt;")); + preferences.getFontSize().ifPresent(size -> scene.getRoot().setStyle("-fx-font-size: " + size + "pt;")); } private void addAndWatchForChanges(Scene scene, String cssUrl, int index) { @@ -77,7 +77,7 @@ private void addAndWatchForChanges(Scene scene, String cssUrl, int index) { DefaultTaskExecutor.runInJavaFXThread(() -> { scene.getStylesheets().remove(cssUrl); - scene.getStylesheets().add(index, cssUrl); + scene.getStylesheets().add(index, cssUrl); } ); }); diff --git a/src/main/java/org/jabref/logic/formatter/Formatters.java b/src/main/java/org/jabref/logic/formatter/Formatters.java index d1cd14925bb..4e1d25f968f 100644 --- a/src/main/java/org/jabref/logic/formatter/Formatters.java +++ b/src/main/java/org/jabref/logic/formatter/Formatters.java @@ -6,6 +6,7 @@ import java.util.Objects; import java.util.Optional; +import org.jabref.logic.formatter.bibtexfields.CleanupURLFormatter; import org.jabref.logic.formatter.bibtexfields.ClearFormatter; import org.jabref.logic.formatter.bibtexfields.EscapeUnderscoresFormatter; import org.jabref.logic.formatter.bibtexfields.HtmlToLatexFormatter; @@ -56,6 +57,7 @@ public static List getCaseChangers() { public static List getOthers() { return Arrays.asList( new ClearFormatter(), + new CleanupURLFormatter(), new LatexCleanupFormatter(), new MinifyNameListFormatter(), new NormalizeDateFormatter(), diff --git a/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupURLFormatter.java b/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupURLFormatter.java new file mode 100644 index 00000000000..2051b76c16f --- /dev/null +++ b/src/main/java/org/jabref/logic/formatter/bibtexfields/CleanupURLFormatter.java @@ -0,0 +1,65 @@ +package org.jabref.logic.formatter.bibtexfields; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.jabref.logic.l10n.Localization; +import org.jabref.model.cleanup.Formatter; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Cleanup URL link + */ +public class CleanupURLFormatter extends Formatter { + + private static final Log LOGGER = LogFactory.getLog(CleanupURLFormatter.class); + // This regexp find "url=" or "to=" parameter in full link and get text after them + private static final Pattern PATTERN_URL = Pattern.compile("(?:url|to)=([^&]*)"); + + @Override + public String getName() { + return Localization.lang("Cleanup URL link"); + } + + @Override + public String getKey() { + return "cleanup_url"; + } + + @Override + public String format(String value) { + String decodedLink = value; + String toDecode = value; + + Matcher matcher = PATTERN_URL.matcher(value); + if (matcher.find()) { + toDecode = matcher.group(1); + } + try { + decodedLink = URLDecoder.decode(toDecode, StandardCharsets.UTF_8.name()); + } + catch (UnsupportedEncodingException e) { + LOGGER.warn("Used unsupported character encoding", e); + } + return decodedLink; + } + + @Override + public String getDescription() { + return Localization.lang("Cleanup URL link by removing special symbols and extracting simple link"); + } + + @Override + public String getExampleInput() { + return "https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=11&cad=" + + "rja&uact=8&ved=0ahUKEwjg3ZrB_ZPXAhVGuhoKHYdOBOg4ChAWCCYwAA&url=" + + "http%3A%2F%2Fwww.focus.de%2Fgesundheit%2Fratgeber%2Fherz%2Ftest%2" + + "Flebenserwartung-werden-sie-100-jahre-alt_aid_363828.html" + "&usg=AOvVaw1G6m2jf-pTHYkXceii4hXU"; + } + +} diff --git a/src/main/java/org/jabref/styletester/StyleTester.fxml b/src/main/java/org/jabref/styletester/StyleTester.fxml new file mode 100644 index 00000000000..31f5abc03d3 --- /dev/null +++ b/src/main/java/org/jabref/styletester/StyleTester.fxml @@ -0,0 +1,481 @@ +package org.jabref.styletester; + +import javafx.application.Application; +import javafx.scene.Scene; +import javafx.stage.Stage; + +import org.jabref.JabRefExecutorService; +import org.jabref.gui.icon.IconTheme; +import org.jabref.gui.util.DefaultFileUpdateMonitor; +import org.jabref.gui.util.ThemeLoader; +import org.jabref.preferences.JabRefPreferences; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +