diff --git a/.github/workflows/deployment-arm64.yml b/.github/workflows/deployment-arm64.yml index a7337738223..c0a6d1406b4 100644 --- a/.github/workflows/deployment-arm64.yml +++ b/.github/workflows/deployment-arm64.yml @@ -66,12 +66,12 @@ jobs: submodules: 'true' show-progress: 'false' - name: Install GitVersion - uses: gittools/actions/gitversion/setup@v1.1.1 + uses: gittools/actions/gitversion/setup@v1.2.0 with: versionSpec: "5.x" - name: Run GitVersion id: gitversion - uses: gittools/actions/gitversion/execute@v1.1.1 + uses: gittools/actions/gitversion/execute@v1.2.0 - name: Setup JDK uses: actions/setup-java@v4 with: diff --git a/.github/workflows/deployment-jdk-ea.yml b/.github/workflows/deployment-jdk-ea.yml index 63d8e2a1dd5..b60489da7c5 100644 --- a/.github/workflows/deployment-jdk-ea.yml +++ b/.github/workflows/deployment-jdk-ea.yml @@ -84,12 +84,12 @@ jobs: packages: pigz version: 1.0 - name: Install GitVersion - uses: gittools/actions/gitversion/setup@v1.1.1 + uses: gittools/actions/gitversion/setup@v1.2.0 with: versionSpec: "5.x" - name: Run GitVersion id: gitversion - uses: gittools/actions/gitversion/execute@v1.1.1 + uses: gittools/actions/gitversion/execute@v1.2.0 # JDK - name: 'Set up JDK ${{ matrix.jdk }}' diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 2b72f5dd63a..cdfa8d54960 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -79,12 +79,12 @@ jobs: packages: pigz version: 1.0 - name: Install GitVersion - uses: gittools/actions/gitversion/setup@v1.1.1 + uses: gittools/actions/gitversion/setup@v1.2.0 with: versionSpec: "5.x" - name: Run GitVersion id: gitversion - uses: gittools/actions/gitversion/execute@v1.1.1 + uses: gittools/actions/gitversion/execute@v1.2.0 - name: Setup JDK uses: actions/setup-java@v4 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 2eeb36c1e68..f85d4bf162d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,11 +12,22 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv ### Added - We added support for selecting and using CSL Styles in JabRef's OpenOffice/LibreOffice integration for inserting bibliographic and in-text citations into a document. +- We added support for selecting and using CSL Styles in JabRef's OpenOffice/LibreOffice integration for inserting bibliographic and in-text citations into a document. [#2146](https://github.com/JabRef/jabref/issues/2146), [#8893](https://github.com/JabRef/jabref/issues/8893) +- Added minimal support for [biblatex data annotation](https://mirrors.ctan.org/macros/latex/contrib/biblatex/doc/biblatex.pdf#subsection.3.7) fields in .layout files. [#11505](https://github.com/JabRef/jabref/issues/11505) +- Added saving of selected options in the [Lookup -> Search for unlinked local files dialog](https://docs.jabref.org/collect/findunlinkedfiles#link-the-pdfs-to-your-bib-library). [#11439](https://github.com/JabRef/jabref/issues/11439) ### Changed +- The Pubmed/Medline Plain importer now imports the PMID field as well [#11488](https://github.com/JabRef/jabref/issues/11488) +- The 'Check for updates' menu bar button is now always enabled. [#11485](https://github.com/JabRef/jabref/pull/11485) +- JabRef respects the [configuration for storing files relative to the .bib file](https://docs.jabref.org/finding-sorting-and-cleaning-entries/filelinks#directories-for-files) in more cases. [#11492](https://github.com/JabRef/jabref/pull/11492) + ### Fixed +- We fixed an issue where the 'Check for updates' preference was not saved. [#11485](https://github.com/JabRef/jabref/pull/11485) +- We fixed an issue where an exception was thrown after changing "show preview as a tab" in the preferences. [#11515](https://github.com/JabRef/jabref/pull/11515) +- We fixed an issue where a new unsaved library was not marked with an asterisk [#11519](https://github.com/JabRef/jabref/pull/11519) + ### Removed diff --git a/PRIVACY.md b/PRIVACY.md index 08b8c34b138..9a7e6b0390f 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -38,41 +38,42 @@ These third parties may log additional information besides your IP address and t These third-party services are the following: -| Service | Privacy Policy | -|-----------------------------------------------------------------------------------------------------------------|----------------| -| [ACM](https://www.acm.org/) | | -| [ACS Publications](https://pubs.acs.org/) | | -| [APS Advancing Physics](https://harvest.aps.org/) | | -| [arXiv.org](https://arxiv.org/) | | -| [Bibliotheksverbund Bayern](https://www.bib-bvb.de/) | | -| [Biodiversity Heritage Library](https://www.biodiversitylibrary.org/) | | -| [Collection of Computer Science Bibliographies](https://en.wikipedia.org/wiki/Collection_of_Computer_Science_Bibliographies) | **currently unavailable**, offline | -| [CrossRef](https://www.crossref.org/) | | -| [dblp](https://dblp.uni-trier.de/) | | -| [Directory of Open Access Books](https://www.doabooks.org/) | | -| [Digitala Vetenskapliga Arkivet](https://www.diva-portal.org/) | | -| [DOI Foundation](https://www.doi.org/) | | -| [Elsevier](https://www.elsevier.com/) | | -| [Google Scholar](https://scholar.google.com/) | | -| [Gemeinsamer Verbundkatalog](https://www.gbv.de/) | | -| [IACR](https://www.iacr.org/) | | -| [IEEEXplore](https://ieeexplore.ieee.org/Xplore/home.jsp) | | -| [INSPIRE](https://inspirehep.net/) | | -| [JSTOR](https://www.jstor.org/) | | -| [Library of Congress](https://lccn.loc.gov/) | | -| [National Library of Medicine](https://www.ncbi.nlm.nih.gov/) | | -| [MathSciNet](http://www.ams.org/mathscinet) | | -| [mEDRA](https://www.medra.org/) | | -| [Mr. DLib](https://mr-dlib.org/) [1] | | -| [Openlibrary](https://openlibrary.org) | | -| [ResearchGate](https://www.researchgate.net/) | | -| [IETF Datatracker](https://datatracker.ietf.org/) | | -| [Semantic Scholar](https://www.semanticscholar.org/), powered by [Allen Institute for AI](https://allenai.org/) | | -| [Springer Nature](https://dev.springernature.com/) | | -| [The SAO/NASA Astrophysics Data System](https://ui.adsabs.harvard.edu/) | | -| [Unpaywall](https://unpaywall.org/) | | -| [zbMATH Open](https://www.zbmath.org) | | -| [ISIDORE](https://isidore.science/) | | +| Service | Privacy Policy | +|------------------------------------------------------------------------------------------------------------------------------|----------------| +| [ACM](https://www.acm.org/) | | +| [ACS Publications](https://pubs.acs.org/) | | +| [APS Advancing Physics](https://harvest.aps.org/) | | +| [arXiv.org](https://arxiv.org/) | | +| [Bibliotheksverbund Bayern](https://www.bib-bvb.de/) | | +| [Biodiversity Heritage Library](https://www.biodiversitylibrary.org/) | | +| [Collection of Computer Science Bibliographies](https://en.wikipedia.org/wiki/Collection_of_Computer_Science_Bibliographies) | **currently unavailable**, offline | +| [CrossRef](https://www.crossref.org/) | | +| [dblp](https://dblp.uni-trier.de/) | | +| [Directory of Open Access Books](https://www.doabooks.org/) | | +| [Digitala Vetenskapliga Arkivet](https://www.diva-portal.org/) | | +| [DOI Foundation](https://www.doi.org/) | | +| [Elsevier](https://www.elsevier.com/) | | +| [Google Scholar](https://scholar.google.com/) | | +| [Gemeinsamer Verbundkatalog](https://www.gbv.de/) | | +| [IACR](https://www.iacr.org/) | | +| [IEEEXplore](https://ieeexplore.ieee.org/Xplore/home.jsp) | | +| [INSPIRE](https://inspirehep.net/) | | +| [JSTOR](https://www.jstor.org/) | | +| [Library of Congress](https://lccn.loc.gov/) | | +| [National Library of Medicine](https://www.ncbi.nlm.nih.gov/) | | +| [MathSciNet](http://www.ams.org/mathscinet) | | +| [mEDRA](https://www.medra.org/) | | +| [Mr. DLib](https://mr-dlib.org/) [1] | | +| [OpenAI](https://openai.com/) | | +| [Openlibrary](https://openlibrary.org) | | +| [ResearchGate](https://www.researchgate.net/) | | +| [IETF Datatracker](https://datatracker.ietf.org/) | | +| [Semantic Scholar](https://www.semanticscholar.org/), powered by [Allen Institute for AI](https://allenai.org/) | | +| [Springer Nature](https://dev.springernature.com/) | | +| [The SAO/NASA Astrophysics Data System](https://ui.adsabs.harvard.edu/) | | +| [Unpaywall](https://unpaywall.org/) | | +| [zbMATH Open](https://www.zbmath.org) | | +| [ISIDORE](https://isidore.science/) | | [1]: *Note: The Mr. DLib service is used for the related articles tab in the entry editor and collects also your language, your browser and operating system (by default*disabled*).* diff --git a/build.gradle b/build.gradle index 48d72650e11..9c1bd518766 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { id 'me.champeau.jmh' version '0.7.2' // This is https://github.com/java9-modularity/gradle-modules-plugin/pull/282 - id 'com.github.koppor.gradle-modules-plugin' version 'jitpack-SNAPSHOT' + id 'com.github.koppor.gradle-modules-plugin' version 'v1.8.15-cmd-1' id 'org.openjfx.javafxplugin' version '0.1.0' @@ -134,7 +134,7 @@ dependencyLocking { } javafx { - version = "22.0.1" + version = "22.0.2" modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.web', 'javafx.swing' ] } @@ -168,7 +168,7 @@ dependencies { implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.11.0' implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.14.0' implementation group: 'org.apache.commons', name: 'commons-text', version: '1.12.0' - implementation 'commons-logging:commons-logging:1.3.2' + implementation 'commons-logging:commons-logging:1.3.3' implementation 'com.h2database:h2-mvstore:2.2.224' // required for reading write-protected PDFs - see https://github.com/JabRef/jabref/pull/942#issuecomment-209252635 @@ -198,8 +198,8 @@ dependencies { implementation 'org.postgresql:postgresql:42.7.3' // Support unix socket connection types - implementation 'com.kohlschutter.junixsocket:junixsocket-core:2.9.1' - implementation 'com.kohlschutter.junixsocket:junixsocket-mysql:2.9.1' + implementation 'com.kohlschutter.junixsocket:junixsocket-core:2.10.0' + implementation 'com.kohlschutter.junixsocket:junixsocket-mysql:2.10.0' implementation ('com.oracle.ojdbc:ojdbc10:19.3.0.0') { // causing module issues @@ -240,7 +240,7 @@ dependencies { implementation 'org.controlsfx:controlsfx:11.2.1' - implementation 'org.jsoup:jsoup:1.17.2' + implementation 'org.jsoup:jsoup:1.18.1' implementation 'com.konghq:unirest-java-core:4.4.0' implementation 'com.konghq:unirest-modules-gson:4.4.0' implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1' @@ -328,7 +328,7 @@ dependencies { xjc group: 'org.glassfish.jaxb', name: 'jaxb-xjc', version: '3.0.2' xjc group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2' - rewrite(platform("org.openrewrite.recipe:rewrite-recipe-bom:2.14.0")) + rewrite(platform("org.openrewrite.recipe:rewrite-recipe-bom:2.15.0")) rewrite("org.openrewrite.recipe:rewrite-static-analysis") rewrite("org.openrewrite.recipe:rewrite-logging-frameworks") rewrite("org.openrewrite.recipe:rewrite-testing-frameworks") diff --git a/docs/code-howtos/faq.md b/docs/code-howtos/faq.md index da5b9343dcd..368ffc96103 100644 --- a/docs/code-howtos/faq.md +++ b/docs/code-howtos/faq.md @@ -7,14 +7,36 @@ parent: Code Howtos Following is a list of common errors encountered by developers which lead to failing tests, with their common solutions: -* `org.jabref.architecture.MainArchitectureTest` `restrictStandardStreams` FAILED - * Fix : Check if you've used ```System.out.println(...)``` (the standard output stream) to log anything into the console. This is an architectural violation, as you should use the Logger instead for logging. More details on how to log can be found [here](https://devdocs.jabref.org/code-howtos/logging.html). +* Failing Checkstyle tests: + * Fix: JabRef follows a pre-defined style of code for uniformity and maintainability that must be adhered to during development. To set up warnings and auto-fixes conforming to these style rules in your IDE, follow [Step 3](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html) of the process to set up a local workspace in the documentation. Ideally, follow all the [set up rules](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/) in the documentation end-to-end to avoid typical set-up errors.
Note: The steps provided in the documentation are for IntelliJ, which is the preferred IDE for Java development. The `checkstyle.xml` is also available for VSCode, in the same directory as mentioned in the steps. -* `org.jabref.architecture.MainArchitectureTest` `doNotUseLogicInModel` FAILED - * Fix : One common case when this test fails is when you put any class purely containing business logic at some level inside the ```model``` directory (```org/jabref/model/```). To fix this, shift the class to a subdirectory within the ```logic``` directory (```org/jabref/logic/```). +* Failing OpenRewrite tests: + * Fix: [OpenRewrite](https://docs.openrewrite.org/) is an automated refactoring ecosystem for source code. Execute the Gradle task `rewriteRun` from the `rewrite` group of the Gradle Tool window in IntelliJ to apply the automated refactoring and pass the test.
+ ![Executing Gradle task rewriteRun](../images/rewriteRun.png)
* `org.jabref.logic.l10n.LocalizationConsistencyTest` `findMissingLocalizationKeys` FAILED - * Fix : You have probably used Strings that are visible on the UI (to the user) but not wrapped them using ```Localization.lang(...)``` and added them to the [localization properties file](https://github.com/JabRef/jabref/blob/main/src/main/resources/l10n/JabRef_en.properties). + * Fix: You have probably used Strings that are visible on the UI (to the user) but not wrapped them using `Localization.lang(...)` and added them to the [localization properties file](https://github.com/JabRef/jabref/blob/main/src/main/resources/l10n/JabRef_en.properties). Read more about the background and format of localization in JabRef [here](https://devdocs.jabref.org/code-howtos/localization.html). +* `org.jabref.logic.l10n.LocalizationConsistencyTest` `findObsoleteLocalizationKeys` FAILED + * Fix: There are localization keys [localization properties file](https://github.com/JabRef/jabref/blob/main/src/main/resources/l10n/JabRef_en.properties) that are not used in the code, probably due to the removal of existing code. Navigate to the unused key-value pairs in the file and remove them. You can always click on the details of the failing test to pinpoint which keys are unused. + Read more about the background and format of localization in JabRef [here](https://devdocs.jabref.org/code-howtos/localization.html). + +* `org.jabref.logic.citationstyle.CitationStyle` `discoverCitationStyles` ERROR: Could not find any citation style. Tried with /ieee.csl. + * Fix: Check the directory `src/main/resources/csl-styles`. If it is missing or empty, run `git submodule update`. Now, check inside if `ieee.csl` exists. If it does not, run `git reset --hard` inside that directory. + +* `java.lang.IllegalArgumentException`: Unable to load locale en-US
ERROR: Could not generate BibEntry citation. The CSL engine could not create a preview for your item. + * Fix: Check the directory `src/main/resources/csl-locales`. If it is missing or empty, run `git submodule update`. If still not fixed, run `git reset --hard` inside that directory. + +* `org.jabref.architecture.MainArchitectureTest` `restrictStandardStreams` FAILED + * Fix: Check if you've used `System.out.println(...)` (the standard output stream) to log anything into the console. This is an architectural violation, as you should use the Logger instead for logging. More details on how to log can be found [here](https://devdocs.jabref.org/code-howtos/logging.html). + +* `org.jabref.architecture.MainArchitectureTest` `doNotUseLogicInModel` FAILED + * Fix: One common case when this test fails is when you put any class purely containing business logic inside the `model` package (i.e., inside the directory `org/jabref/model/`). To fix this, shift the class to a sub-package within the `logic` package (i.e., the directory`org/jabref/logic/`). An efficient way to do this is to use IntelliJ's built-in refactoring capabilities - right-click on the file, go to "Refactor" and use "Move Class". The import statement for all the classes using this class will be automatically adjusted according to the new location.
+ ![Moving a file using refactor](../images/refactor-moving.png)
+ +* `ANTLR Tool version 4.12.0 used for code generation does not match the current runtime version 4.13.1` + * Fix: Execute the Gradle task `clean` from the `build` group of the Gradle Tool Window in IntelliJ:
+ ![Executing Gradle task clean](../images/clean.png)
+ diff --git a/docs/images/clean.png b/docs/images/clean.png new file mode 100644 index 00000000000..c4c0df895aa Binary files /dev/null and b/docs/images/clean.png differ diff --git a/docs/images/refactor-moving.png b/docs/images/refactor-moving.png new file mode 100644 index 00000000000..fb7b5e7fe8f Binary files /dev/null and b/docs/images/refactor-moving.png differ diff --git a/docs/images/rewriteRun.png b/docs/images/rewriteRun.png new file mode 100644 index 00000000000..2bfde7b2755 Binary files /dev/null and b/docs/images/rewriteRun.png differ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d..2c3521197d7 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8a1f6b97f47..68e8816d71c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf13397..f5feea6d6b1 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30dbdee..9d21a21834d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/src/main/java/org/jabref/architecture/AllowedToUseClassGetResource.java b/src/main/java/org/jabref/architecture/AllowedToUseClassGetResource.java new file mode 100644 index 00000000000..a8f98bdc549 --- /dev/null +++ b/src/main/java/org/jabref/architecture/AllowedToUseClassGetResource.java @@ -0,0 +1,11 @@ +package org.jabref.architecture; + +/** + * Annotation to indicate that this logic class can use class.getResource(). + * Mostly, because {@link java.nio.file.Path} is not used. + * See https://github.com/oracle/graal/issues/7682 for a longer discussion. + */ +public @interface AllowedToUseClassGetResource { + // The rationale + String value(); +} diff --git a/src/main/java/org/jabref/architecture/AllowedToUseSwing.java b/src/main/java/org/jabref/architecture/AllowedToUseSwing.java index 99a40a4bade..6820421c880 100644 --- a/src/main/java/org/jabref/architecture/AllowedToUseSwing.java +++ b/src/main/java/org/jabref/architecture/AllowedToUseSwing.java @@ -4,7 +4,6 @@ * Annotation to indicate that this logic class can access swing */ public @interface AllowedToUseSwing { - // The rationale String value(); } diff --git a/src/main/java/org/jabref/gui/LibraryTab.java b/src/main/java/org/jabref/gui/LibraryTab.java index f3eb5d52d03..bd16389dd9c 100644 --- a/src/main/java/org/jabref/gui/LibraryTab.java +++ b/src/main/java/org/jabref/gui/LibraryTab.java @@ -415,13 +415,8 @@ public void updateTabTitle(boolean isChanged) { uniquePathPart.ifPresent(part -> tabTitle.append(" \u2013 ").append(part)); } else { if (databaseLocation == DatabaseLocation.LOCAL) { + tabTitle.append('*'); tabTitle.append(Localization.lang("untitled")); - if (bibDatabaseContext.getDatabase().hasEntries()) { - // if the database is not empty and no file is assigned, - // the database came from an import and has to be treated somehow - // -> mark as changed - tabTitle.append('*'); - } } else { addSharedDbInformation(tabTitle, bibDatabaseContext); addSharedDbInformation(toolTipText, bibDatabaseContext); diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index 246c89dee4d..5d758895069 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -148,7 +148,11 @@ public EntryEditor(LibraryTab libraryTab, UndoAction undoAction, RedoAction redo } }); EasyBind.listen(preferencesService.getPreviewPreferences().showPreviewAsExtraTabProperty(), - (obs, oldValue, newValue) -> adaptVisibleTabs()); + (obs, oldValue, newValue) -> { + if (currentlyEditedEntry != null) { + adaptVisibleTabs(); + } + }); } private void setupDragAndDrop(LibraryTab libraryTab) { diff --git a/src/main/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtil.java b/src/main/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtil.java index bd3f494e3c6..7733bedfb07 100644 --- a/src/main/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtil.java +++ b/src/main/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtil.java @@ -6,7 +6,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; @@ -52,6 +51,7 @@ public List getFileExceptions() { } private static final Logger LOGGER = LoggerFactory.getLogger(AutoSetFileLinksUtil.class); + private final List directories; private final AutoLinkPreferences autoLinkPreferences; private final FilePreferences filePreferences; @@ -106,7 +106,9 @@ public LinkFilesResult linkAssociatedFiles(List entries, NamedCompound public List findAssociatedNotLinkedFiles(BibEntry entry) throws IOException { List linkedFiles = new ArrayList<>(); - List extensions = filePreferences.getExternalFileTypes().stream().map(ExternalFileType::getExtension).collect(Collectors.toList()); + List extensions = filePreferences.getExternalFileTypes().stream().map(ExternalFileType::getExtension).toList(); + + LOGGER.debug("Searching for extensions {} in directories {}", extensions, directories); // Run the search operation FileFinder fileFinder = FileFinders.constructFromConfiguration(autoLinkPreferences); @@ -134,6 +136,7 @@ public List findAssociatedNotLinkedFiles(BibEntry entry) throws IOEx Path relativeFilePath = FileUtil.relativize(foundFile, directories); LinkedFile linkedFile = new LinkedFile("", relativeFilePath, strType); linkedFiles.add(linkedFile); + LOGGER.debug("Found file {} for entry {}", linkedFile, entry.getCitationKey()); } } diff --git a/src/main/java/org/jabref/gui/externalfiles/DateRange.java b/src/main/java/org/jabref/gui/externalfiles/DateRange.java index b73f700481c..b8a6e221ec8 100644 --- a/src/main/java/org/jabref/gui/externalfiles/DateRange.java +++ b/src/main/java/org/jabref/gui/externalfiles/DateRange.java @@ -11,11 +11,19 @@ public enum DateRange { private final String dateRange; - DateRange(String dateRange) { + DateRange(String dateRange) { this.dateRange = dateRange; } + public static DateRange parse(String name) { + try { + return DateRange.valueOf(name); + } catch (IllegalArgumentException e) { + return ALL_TIME; + } + } + public String getDateRange() { - return dateRange; - } + return dateRange; + } } diff --git a/src/main/java/org/jabref/gui/externalfiles/ExternalFileSorter.java b/src/main/java/org/jabref/gui/externalfiles/ExternalFileSorter.java index e425c642750..ddb23ac221e 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ExternalFileSorter.java +++ b/src/main/java/org/jabref/gui/externalfiles/ExternalFileSorter.java @@ -13,6 +13,14 @@ public enum ExternalFileSorter { this.sorter = sorter; } + public static ExternalFileSorter parse(String name) { + try { + return ExternalFileSorter.valueOf(name); + } catch (IllegalArgumentException e) { + return DEFAULT; + } + } + public String getSorter() { return sorter; } diff --git a/src/main/java/org/jabref/gui/externalfiles/FileExtensionViewModel.java b/src/main/java/org/jabref/gui/externalfiles/FileExtensionViewModel.java index 5cee5f7bc05..ece8217dfca 100644 --- a/src/main/java/org/jabref/gui/externalfiles/FileExtensionViewModel.java +++ b/src/main/java/org/jabref/gui/externalfiles/FileExtensionViewModel.java @@ -15,16 +15,22 @@ public class FileExtensionViewModel { + private final String name; private final String description; private final List extensions; private final FilePreferences filePreferences; FileExtensionViewModel(FileType fileType, FilePreferences filePreferences) { + this.name = fileType.getName(); this.description = Localization.lang("%0 file", fileType.getName()); this.extensions = fileType.getExtensionsWithAsteriskAndDot(); this.filePreferences = filePreferences; } + public String getName() { + return this.name; + } + public String getDescription() { return this.description + extensions.stream().collect(Collectors.joining(", ", " (", ")")); } diff --git a/src/main/java/org/jabref/gui/externalfiles/UnlinkedFilesDialogView.java b/src/main/java/org/jabref/gui/externalfiles/UnlinkedFilesDialogView.java index 3a7213feee6..1f15e3b78ac 100644 --- a/src/main/java/org/jabref/gui/externalfiles/UnlinkedFilesDialogView.java +++ b/src/main/java/org/jabref/gui/externalfiles/UnlinkedFilesDialogView.java @@ -1,6 +1,7 @@ package org.jabref.gui.externalfiles; import java.nio.file.Path; +import java.util.Objects; import javax.swing.undo.UndoManager; @@ -46,6 +47,7 @@ import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.util.FileUpdateMonitor; import org.jabref.preferences.PreferencesService; +import org.jabref.preferences.UnlinkedFilesDialogPreferences; import com.airhacks.afterburner.views.ViewLoader; import com.tobiasdiez.easybind.EasyBind; @@ -158,21 +160,21 @@ private void initDirectorySelection() { .install(fileTypeCombo); fileTypeCombo.setItems(viewModel.getFileFilters()); fileTypeCombo.valueProperty().bindBidirectional(viewModel.selectedExtensionProperty()); - fileTypeCombo.getSelectionModel().selectFirst(); + new ViewModelListCellFactory() .withText(DateRange::getDateRange) .install(fileDateCombo); fileDateCombo.setItems(viewModel.getDateFilters()); fileDateCombo.valueProperty().bindBidirectional(viewModel.selectedDateProperty()); - fileDateCombo.getSelectionModel().selectFirst(); + new ViewModelListCellFactory() .withText(ExternalFileSorter::getSorter) .install(fileSortCombo); fileSortCombo.setItems(viewModel.getSorters()); fileSortCombo.valueProperty().bindBidirectional(viewModel.selectedSortProperty()); - fileSortCombo.getSelectionModel().selectFirst(); directoryPathField.setText(bibDatabaseContext.getFirstExistingFileDir(preferencesService.getFilePreferences()).map(Path::toString).orElse("")); + loadSavedConfiguration(); } private void initUnlinkedFilesList() { @@ -227,6 +229,25 @@ private void initButtons() { scanButton.disableProperty().bind(viewModel.taskActiveProperty().or(viewModel.directoryPathValidationStatus().validProperty().not())); } + private void loadSavedConfiguration() { + UnlinkedFilesDialogPreferences unlinkedFilesDialogPreferences = preferencesService.getUnlinkedFilesDialogPreferences(); + + FileExtensionViewModel selectedExtension = fileTypeCombo.getItems() + .stream() + .filter(item -> Objects.equals(item.getName(), unlinkedFilesDialogPreferences.getUnlinkedFilesSelectedExtension())) + .findFirst() + .orElseThrow(); + fileTypeCombo.getSelectionModel().select(selectedExtension); + fileDateCombo.getSelectionModel().select(unlinkedFilesDialogPreferences.getUnlinkedFilesSelectedDateRange()); + fileSortCombo.getSelectionModel().select(unlinkedFilesDialogPreferences.getUnlinkedFilesSelectedSort()); + } + + public void saveConfiguration() { + preferencesService.getUnlinkedFilesDialogPreferences().setUnlinkedFilesSelectedExtension(fileTypeCombo.getValue().getName()); + preferencesService.getUnlinkedFilesDialogPreferences().setUnlinkedFilesSelectedDateRange(fileDateCombo.getValue()); + preferencesService.getUnlinkedFilesDialogPreferences().setUnlinkedFilesSelectedSort(fileSortCombo.getValue()); + } + @FXML void browseFileDirectory() { viewModel.browseFileDirectory(); @@ -235,6 +256,7 @@ void browseFileDirectory() { @FXML void scanFiles() { viewModel.startSearch(); + saveConfiguration(); } @FXML diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditorViewModel.java index 005ef6e75ff..f628f9514bf 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditorViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditorViewModel.java @@ -190,9 +190,15 @@ public void bindToEntry(BibEntry entry) { super.bindToEntry(entry); if ((entry != null) && preferences.getEntryEditorPreferences().autoLinkFilesEnabled()) { + LOGGER.debug("Auto-linking files for entry {}", entry); BackgroundTask> findAssociatedNotLinkedFiles = BackgroundTask .wrap(() -> findAssociatedNotLinkedFiles(entry)) - .onSuccess(files::addAll); + .onSuccess(list -> { + if (!list.isEmpty()) { + LOGGER.debug("Found non-associated files:", list); + files.addAll(list); + } + }); taskExecutor.execute(findAssociatedNotLinkedFiles); } } @@ -224,6 +230,7 @@ private List findAssociatedNotLinkedFiles(BibEntry entry) { dialogService.showErrorDialogAndWait("Error accessing the file system", e); } + LOGGER.trace("Found {} associated files for entry {}", result.size(), entry.getCitationKey()); return result; } diff --git a/src/main/java/org/jabref/gui/fieldeditors/journalinfo/JournalInfoView.java b/src/main/java/org/jabref/gui/fieldeditors/journalinfo/JournalInfoView.java index adffd08e287..24712ff4a3b 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/journalinfo/JournalInfoView.java +++ b/src/main/java/org/jabref/gui/fieldeditors/journalinfo/JournalInfoView.java @@ -8,10 +8,12 @@ import javafx.scene.control.Label; import javafx.scene.layout.VBox; +import org.jabref.architecture.AllowedToUseClassGetResource; import org.jabref.logic.importer.FetcherException; import com.airhacks.afterburner.views.ViewLoader; +@AllowedToUseClassGetResource("JavaFX internally handles the passed URLs properly.") public class JournalInfoView extends VBox { @FXML private Label title; @FXML private Label categories; diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeView.java b/src/main/java/org/jabref/gui/groups/GroupTreeView.java index 8bae9b4353c..ef837d2586e 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeView.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeView.java @@ -43,6 +43,7 @@ import javafx.scene.layout.StackPane; import javafx.scene.text.Text; +import org.jabref.architecture.AllowedToUseClassGetResource; import org.jabref.gui.DialogService; import org.jabref.gui.DragAndDropDataFormats; import org.jabref.gui.StateManager; @@ -70,6 +71,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@AllowedToUseClassGetResource("JavaFX internally handles the passed URLs properly.") public class GroupTreeView extends BorderPane { private static final Logger LOGGER = LoggerFactory.getLogger(GroupTreeView.class); diff --git a/src/main/java/org/jabref/gui/help/SearchForUpdateAction.java b/src/main/java/org/jabref/gui/help/SearchForUpdateAction.java index 94110fddf4f..d4b7d3aec25 100644 --- a/src/main/java/org/jabref/gui/help/SearchForUpdateAction.java +++ b/src/main/java/org/jabref/gui/help/SearchForUpdateAction.java @@ -20,8 +20,6 @@ public SearchForUpdateAction(PreferencesService preferencesService, this.preferencesService = preferencesService; this.dialogService = dialogService; this.taskExecutor = taskExecutor; - - this.executable.bind(preferencesService.getInternalPreferences().versionCheckEnabledProperty()); } @Override diff --git a/src/main/java/org/jabref/gui/help/VersionWorker.java b/src/main/java/org/jabref/gui/help/VersionWorker.java index 5a21e89cf78..c53f0eaeccd 100644 --- a/src/main/java/org/jabref/gui/help/VersionWorker.java +++ b/src/main/java/org/jabref/gui/help/VersionWorker.java @@ -61,10 +61,6 @@ private Optional getNewVersion() throws IOException { } public void checkForNewVersionAsync() { - if (!internalPreferences.isVersionCheckEnabled()) { - return; - } - BackgroundTask.wrap(this::getNewVersion) .onSuccess(version -> showUpdateInfo(version, true)) .onFailure(exception -> showConnectionError(exception, true)) @@ -72,10 +68,6 @@ public void checkForNewVersionAsync() { } public void checkForNewVersionDelayed() { - if (!internalPreferences.isVersionCheckEnabled()) { - return; - } - BackgroundTask.wrap(this::getNewVersion) .onSuccess(version -> showUpdateInfo(version, false)) .onFailure(exception -> showConnectionError(exception, false)) diff --git a/src/main/java/org/jabref/gui/icon/IconTheme.java b/src/main/java/org/jabref/gui/icon/IconTheme.java index cc9bad0528b..857aee790d5 100644 --- a/src/main/java/org/jabref/gui/icon/IconTheme.java +++ b/src/main/java/org/jabref/gui/icon/IconTheme.java @@ -22,6 +22,8 @@ import javafx.scene.image.Image; import javafx.scene.paint.Color; +import org.jabref.architecture.AllowedToUseClassGetResource; + import org.kordamp.ikonli.Ikon; import org.kordamp.ikonli.IkonProvider; import org.kordamp.ikonli.materialdesign2.MaterialDesignA; @@ -50,6 +52,7 @@ import static java.util.EnumSet.allOf; +@AllowedToUseClassGetResource("JavaFX internally handles the passed URLs properly.") public class IconTheme { public static final Color DEFAULT_DISABLED_COLOR = Color.web("#c8c8c8"); diff --git a/src/main/java/org/jabref/gui/icon/JabRefIkonHandler.java b/src/main/java/org/jabref/gui/icon/JabRefIkonHandler.java index 2f9bc45e0d1..b09703d9189 100644 --- a/src/main/java/org/jabref/gui/icon/JabRefIkonHandler.java +++ b/src/main/java/org/jabref/gui/icon/JabRefIkonHandler.java @@ -3,9 +3,12 @@ import java.io.InputStream; import java.net.URL; +import org.jabref.architecture.AllowedToUseClassGetResource; + import org.kordamp.ikonli.AbstractIkonHandler; import org.kordamp.ikonli.Ikon; +@AllowedToUseClassGetResource("JavaFX internally handles the passed URLs properly.") public class JabRefIkonHandler extends AbstractIkonHandler { private static String FONT_RESOURCE = "/fonts/JabRefMaterialDesign.ttf"; diff --git a/src/main/java/org/jabref/gui/maintable/MainTable.java b/src/main/java/org/jabref/gui/maintable/MainTable.java index 8ad0bd8fc43..16b51d631cc 100644 --- a/src/main/java/org/jabref/gui/maintable/MainTable.java +++ b/src/main/java/org/jabref/gui/maintable/MainTable.java @@ -24,6 +24,7 @@ import javafx.scene.input.MouseEvent; import javafx.scene.input.TransferMode; +import org.jabref.architecture.AllowedToUseClassGetResource; import org.jabref.gui.ClipBoardManager; import org.jabref.gui.DialogService; import org.jabref.gui.DragAndDropDataFormats; @@ -60,6 +61,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@AllowedToUseClassGetResource("JavaFX internally handles the passed URLs properly.") public class MainTable extends TableView { private static final Logger LOGGER = LoggerFactory.getLogger(MainTable.class); diff --git a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java index ac04d895b11..131b8477145 100644 --- a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java +++ b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java @@ -11,6 +11,7 @@ import javafx.scene.layout.VBox; import javafx.stage.Screen; +import org.jabref.architecture.AllowedToUseClassGetResource; import org.jabref.gui.mergeentries.newmergedialog.fieldsmerger.FieldMergerFactory; import org.jabref.gui.mergeentries.newmergedialog.toolbar.ThreeWayMergeToolbar; import org.jabref.logic.l10n.Localization; @@ -19,6 +20,7 @@ import org.jabref.model.entry.field.FieldProperty; import org.jabref.preferences.PreferencesService; +@AllowedToUseClassGetResource("JavaFX internally handles the passed URLs properly.") public class ThreeWayMergeView extends VBox { public static final int GRID_COLUMN_MIN_WIDTH = 250; diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 92724bf1bce..76ace5b162c 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -12,6 +12,7 @@ import org.jabref.gui.DialogService; import org.jabref.logic.JabRefException; +import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.l10n.Localization; import org.jabref.logic.openoffice.NoDocumentFoundException; import org.jabref.logic.openoffice.action.EditInsert; @@ -23,7 +24,8 @@ import org.jabref.logic.openoffice.frontend.OOFrontend; import org.jabref.logic.openoffice.frontend.RangeForOverlapCheck; import org.jabref.logic.openoffice.oocsltext.CSLCitationOOAdapter; -import org.jabref.logic.openoffice.style.OOBibStyle; +import org.jabref.logic.openoffice.style.JStyle; +import org.jabref.logic.openoffice.style.OOStyle; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; @@ -297,7 +299,7 @@ private static OOVoidResult checkIfOpenOfficeIsRecordingChanges(XTextDo return OOVoidResult.ok(); } - OOVoidResult styleIsRequired(OOBibStyle style) { + OOVoidResult styleIsRequired(OOStyle style) { if (style == null) { return OOVoidResult.error(OOError.noValidStyleSelected()); } else { @@ -393,24 +395,24 @@ private OOVoidResult checkStyleExistsInTheDocument(String familyName, return OOVoidResult.ok(); } - public OOVoidResult checkStylesExistInTheDocument(OOBibStyle style, XTextDocument doc) { - String pathToStyleFile = style.getPath(); + public OOVoidResult checkStylesExistInTheDocument(JStyle jStyle, XTextDocument doc) { + String pathToStyleFile = jStyle.getPath(); List> results = new ArrayList<>(); try { results.add(checkStyleExistsInTheDocument(UnoStyle.PARAGRAPH_STYLES, - style.getReferenceHeaderParagraphFormat(), + jStyle.getReferenceHeaderParagraphFormat(), doc, "ReferenceHeaderParagraphFormat", pathToStyleFile)); results.add(checkStyleExistsInTheDocument(UnoStyle.PARAGRAPH_STYLES, - style.getReferenceParagraphFormat(), + jStyle.getReferenceParagraphFormat(), doc, "ReferenceParagraphFormat", pathToStyleFile)); - if (style.isFormatCitations()) { + if (jStyle.isFormatCitations()) { results.add(checkStyleExistsInTheDocument(UnoStyle.CHARACTER_STYLES, - style.getCitationCharacterFormat(), + jStyle.getCitationCharacterFormat(), doc, "CitationCharacterFormat", pathToStyleFile)); @@ -522,10 +524,10 @@ public void guiActionApplyCitationEntries(List citationEntries) { */ public void guiActionInsertEntry(List entries, BibDatabaseContext bibDatabaseContext, - OOBibStyle style, + OOStyle style, CitationType citationType, String pageInfo, - Optional syncOptions, StyleSelectDialogViewModel.StyleType selectedStyleType) { + Optional syncOptions) { final String errorTitle = "Could not insert citation"; @@ -552,10 +554,12 @@ public void guiActionInsertEntry(List entries, return; } - if (testDialog(errorTitle, - checkStylesExistInTheDocument(style, doc), - checkIfOpenOfficeIsRecordingChanges(doc))) { - return; + if (style instanceof JStyle jStyle) { + if (testDialog(errorTitle, + checkStylesExistInTheDocument(jStyle, doc), + checkIfOpenOfficeIsRecordingChanges(doc))) { + return; + } } /* @@ -582,27 +586,27 @@ public void guiActionInsertEntry(List entries, try { UnoUndo.enterUndoContext(doc, "Insert citation"); - if (selectedStyleType == StyleSelectDialogViewModel.StyleType.CSL) { - // Handle CSL Styles + if (style instanceof CitationStyle citationStyle) { + // Handle insertion of CSL Style citations if (citationType == CitationType.AUTHORYEAR_INTEXT) { - CSLCitationOOAdapter.insertInText(doc, cursor.get(), entries, bibDatabaseContext); + CSLCitationOOAdapter.insertInText(doc, cursor.get(), citationStyle, entries, bibDatabaseContext); } else { - CSLCitationOOAdapter.insertBibliography(doc, cursor.get(), entries, bibDatabaseContext); + CSLCitationOOAdapter.insertBibliography(doc, cursor.get(), citationStyle, entries, bibDatabaseContext); } - } else { - // Handle JStyles + } else if (style instanceof JStyle jStyle) { + // Handle insertion of JStyle citations EditInsert.insertCitationGroup(doc, frontend.get(), cursor.get(), entries, bibDatabaseContext.getDatabase(), - style, + jStyle, citationType, pageInfo); - } - if (syncOptions.isPresent()) { - Update.resyncDocument(doc, style, fcursor.get(), syncOptions.get()); + if (syncOptions.isPresent()) { + Update.resyncDocument(doc, jStyle, fcursor.get(), syncOptions.get()); + } } } catch (NoDocumentException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); @@ -625,13 +629,13 @@ public void guiActionInsertEntry(List entries, /** * GUI action "Merge citations" */ - public void guiActionMergeCitationGroups(List databases, OOBibStyle style) { + public void guiActionMergeCitationGroups(List databases, JStyle jStyle) { final String errorTitle = Localization.lang("Problem combining cite markers"); OOResult odoc = getXTextDocument(); if (testDialog(errorTitle, odoc.asVoidResult(), - styleIsRequired(style), + styleIsRequired(jStyle), databaseIsRequired(databases, OOError::noDataBaseIsOpen))) { return; } @@ -641,7 +645,7 @@ public void guiActionMergeCitationGroups(List databases, OOBibStyle if (testDialog(errorTitle, fcursor.asVoidResult(), - checkStylesExistInTheDocument(style, doc), + checkStylesExistInTheDocument(jStyle, doc), checkIfOpenOfficeIsRecordingChanges(doc))) { return; } @@ -650,11 +654,11 @@ public void guiActionMergeCitationGroups(List databases, OOBibStyle UnoUndo.enterUndoContext(doc, "Merge citations"); OOFrontend frontend = new OOFrontend(doc); - boolean madeModifications = EditMerge.mergeCitationGroups(doc, frontend, style); + boolean madeModifications = EditMerge.mergeCitationGroups(doc, frontend, jStyle); if (madeModifications) { UnoCrossRef.refresh(doc); Update.SyncOptions syncOptions = new Update.SyncOptions(databases); - Update.resyncDocument(doc, style, fcursor.get(), syncOptions); + Update.resyncDocument(doc, jStyle, fcursor.get(), syncOptions); } } catch (NoDocumentException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); @@ -679,13 +683,13 @@ public void guiActionMergeCitationGroups(List databases, OOBibStyle *

* Do the opposite of MergeCitationGroups. Combined markers are split, with a space inserted between. */ - public void guiActionSeparateCitations(List databases, OOBibStyle style) { + public void guiActionSeparateCitations(List databases, JStyle jStyle) { final String errorTitle = Localization.lang("Problem during separating cite markers"); OOResult odoc = getXTextDocument(); if (testDialog(errorTitle, odoc.asVoidResult(), - styleIsRequired(style), + styleIsRequired(jStyle), databaseIsRequired(databases, OOError::noDataBaseIsOpen))) { return; } @@ -695,7 +699,7 @@ public void guiActionSeparateCitations(List databases, OOBibStyle s if (testDialog(errorTitle, fcursor.asVoidResult(), - checkStylesExistInTheDocument(style, doc), + checkStylesExistInTheDocument(jStyle, doc), checkIfOpenOfficeIsRecordingChanges(doc))) { return; } @@ -704,11 +708,11 @@ public void guiActionSeparateCitations(List databases, OOBibStyle s UnoUndo.enterUndoContext(doc, "Separate citations"); OOFrontend frontend = new OOFrontend(doc); - boolean madeModifications = EditSeparate.separateCitations(doc, frontend, databases, style); + boolean madeModifications = EditSeparate.separateCitations(doc, frontend, databases, jStyle); if (madeModifications) { UnoCrossRef.refresh(doc); Update.SyncOptions syncOptions = new Update.SyncOptions(databases); - Update.resyncDocument(doc, style, fcursor.get(), syncOptions); + Update.resyncDocument(doc, jStyle, fcursor.get(), syncOptions); } } catch (NoDocumentException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); @@ -801,9 +805,9 @@ public Optional exportCitedHelper(List databases, bool * GUI action, refreshes citation markers and bibliography. * * @param databases Must have at least one. - * @param style Style. + * @param jStyle Style. */ - public void guiActionUpdateDocument(List databases, OOBibStyle style) { + public void guiActionUpdateDocument(List databases, JStyle jStyle) { final String errorTitle = Localization.lang("Unable to synchronize bibliography"); try { @@ -811,7 +815,7 @@ public void guiActionUpdateDocument(List databases, OOBibStyle styl OOResult odoc = getXTextDocument(); if (testDialog(errorTitle, odoc.asVoidResult(), - styleIsRequired(style))) { + styleIsRequired(jStyle))) { return; } @@ -821,7 +825,7 @@ public void guiActionUpdateDocument(List databases, OOBibStyle styl if (testDialog(errorTitle, fcursor.asVoidResult(), - checkStylesExistInTheDocument(style, doc), + checkStylesExistInTheDocument(jStyle, doc), checkIfOpenOfficeIsRecordingChanges(doc))) { return; } @@ -840,7 +844,7 @@ public void guiActionUpdateDocument(List databases, OOBibStyle styl .setUpdateBibliography(true) .setAlwaysAddCitedOnPages(this.alwaysAddCitedOnPages); - unresolvedKeys = Update.synchronizeDocument(doc, frontend, style, fcursor.get(), syncOptions); + unresolvedKeys = Update.synchronizeDocument(doc, frontend, jStyle, fcursor.get(), syncOptions); } finally { UnoUndo.leaveUndoContext(doc); fcursor.get().restore(doc); diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index 1a14acfaceb..e5d6cd783f2 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -49,8 +49,8 @@ import org.jabref.logic.openoffice.OpenOfficeFileSearch; import org.jabref.logic.openoffice.OpenOfficePreferences; import org.jabref.logic.openoffice.action.Update; -import org.jabref.logic.openoffice.oocsltext.CSLCitationOOAdapter; -import org.jabref.logic.openoffice.style.OOBibStyle; +import org.jabref.logic.openoffice.style.JStyle; +import org.jabref.logic.openoffice.style.OOStyle; import org.jabref.logic.openoffice.style.StyleLoader; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; @@ -100,8 +100,7 @@ public class OpenOfficePanel { private final FileUpdateMonitor fileUpdateMonitor; private final BibEntryTypesManager entryTypesManager; private OOBibBase ooBase; - private OOBibStyle jStyle; - private StyleSelectDialogViewModel.StyleType currentStyleType; + private OOStyle currentStyle; public OpenOfficePanel(LibraryTabContainer tabContainer, PreferencesService preferencesService, @@ -165,21 +164,27 @@ public Node getContent() { * Return true if failed. In this case the dialog is already shown. */ private boolean getOrUpdateTheStyle(String title) { + currentStyle = loader.getUsedStyleUnified(); final boolean FAIL = true; final boolean PASS = false; - if (jStyle == null) { - jStyle = loader.getUsedStyle(); + if (currentStyle == null) { + currentStyle = loader.getUsedStyleUnified(); } else { - try { - jStyle.ensureUpToDate(); - } catch (IOException ex) { - LOGGER.warn("Unable to reload style file '{}'", jStyle.getPath(), ex); - String msg = Localization.lang("Unable to reload style file") - + "'" + jStyle.getPath() + "'" - + "\n" + ex.getMessage(); - new OOError(title, msg, ex).showErrorDialog(dialogService); - return FAIL; + if (currentStyle instanceof JStyle jStyle) { + try { + jStyle.ensureUpToDate(); + } catch (IOException ex) { + LOGGER.warn("Unable to reload style file '{}'", jStyle.getPath(), ex); + String msg = Localization.lang("Unable to reload style file") + + "'" + jStyle.getPath() + "'" + + "\n" + ex.getMessage(); + new OOError(title, msg, ex).showErrorDialog(dialogService); + return FAIL; + } + } else { + // CSL Styles don't need to be updated + return PASS; } } return PASS; @@ -197,18 +202,16 @@ private void initPanel() { StyleSelectDialogView styleDialog = new StyleSelectDialogView(loader); dialogService.showCustomDialogAndWait(styleDialog) .ifPresent(selectedStyle -> { - jStyle = selectedStyle; - currentStyleType = styleDialog.getSelectedStyleType(); - try { - jStyle.ensureUpToDate(); - } catch (IOException e) { - LOGGER.warn("Unable to reload style file '{}'", jStyle.getPath(), e); - } - if (currentStyleType == StyleSelectDialogViewModel.StyleType.JSTYLE) { + currentStyle = selectedStyle; + if (currentStyle instanceof JStyle jStyle) { + try { + jStyle.ensureUpToDate(); + } catch (IOException e) { + LOGGER.warn("Unable to reload style file '{}'", jStyle.getPath(), e); + } dialogService.notify(Localization.lang("Currently selected JStyle: '%0'", jStyle.getName())); - } else { - CitationStyle cslStyle = CSLCitationOOAdapter.getSelectedStyle(); - dialogService.notify(Localization.lang("Currently selected CSL Style: '%0'", cslStyle.getTitle())); + } else if (currentStyle instanceof CitationStyle cslStyle) { + dialogService.notify(Localization.lang("Currently selected CSL Style: '%0'", cslStyle.getName())); } }); }); @@ -228,22 +231,24 @@ private void initPanel() { update.setTooltip(new Tooltip(Localization.lang("Ensure that the bibliography is up-to-date"))); - update.setOnAction(event -> { - String title = Localization.lang("Could not update bibliography"); - if (getOrUpdateTheStyle(title)) { - return; - } - List databases = getBaseList(); - ooBase.guiActionUpdateDocument(databases, jStyle); - }); + if (currentStyle instanceof JStyle jStyle) { + update.setOnAction(event -> { + String title = Localization.lang("Could not update bibliography"); + if (getOrUpdateTheStyle(title)) { + return; + } + List databases = getBaseList(); + ooBase.guiActionUpdateDocument(databases, jStyle); + }); - merge.setMaxWidth(Double.MAX_VALUE); - merge.setTooltip(new Tooltip(Localization.lang("Combine pairs of citations that are separated by spaces only"))); - merge.setOnAction(e -> ooBase.guiActionMergeCitationGroups(getBaseList(), jStyle)); + merge.setMaxWidth(Double.MAX_VALUE); + merge.setTooltip(new Tooltip(Localization.lang("Combine pairs of citations that are separated by spaces only"))); + merge.setOnAction(e -> ooBase.guiActionMergeCitationGroups(getBaseList(), jStyle)); - unmerge.setMaxWidth(Double.MAX_VALUE); - unmerge.setTooltip(new Tooltip(Localization.lang("Separate merged citations"))); - unmerge.setOnAction(e -> ooBase.guiActionSeparateCitations(getBaseList(), jStyle)); + unmerge.setMaxWidth(Double.MAX_VALUE); + unmerge.setTooltip(new Tooltip(Localization.lang("Separate merged citations"))); + unmerge.setOnAction(e -> ooBase.guiActionSeparateCitations(getBaseList(), jStyle)); + } ContextMenu settingsMenu = createSettingsPopup(); settingsB.setMaxWidth(Double.MAX_VALUE); @@ -417,25 +422,30 @@ protected OOBibBase call() throws Exception { connectTask.setOnFailed(value -> { Throwable ex = connectTask.getException(); LOGGER.error("autodetect failed", ex); - if (ex instanceof UnsatisfiedLinkError) { - LOGGER.warn("Could not connect to running OpenOffice/LibreOffice", ex); - - dialogService.showErrorDialogAndWait(Localization.lang("Unable to connect. One possible reason is that JabRef " - + "and OpenOffice/LibreOffice are not both running in either 32 bit mode or 64 bit mode.")); - } else if (ex instanceof IOException) { - LOGGER.warn("Could not connect to running OpenOffice/LibreOffice", ex); - - dialogService.showErrorDialogAndWait(Localization.lang("Could not connect to running OpenOffice/LibreOffice."), - Localization.lang("Could not connect to running OpenOffice/LibreOffice.") - + "\n" - + Localization.lang("Make sure you have installed OpenOffice/LibreOffice with Java support.") + "\n" - + Localization.lang("If connecting manually, please verify program and library paths.") + "\n" + "\n" + Localization.lang("Error message:"), - ex); - } else if (ex instanceof BootstrapException bootstrapEx) { - LOGGER.error("Exception boostrap cause", bootstrapEx.getTargetException()); - dialogService.showErrorDialogAndWait("Bootstrap error", bootstrapEx.getTargetException()); - } else { - dialogService.showErrorDialogAndWait(Localization.lang("Autodetection failed"), Localization.lang("Autodetection failed"), ex); + switch (ex) { + case UnsatisfiedLinkError unsatisfiedLinkError -> { + LOGGER.warn("Could not connect to running OpenOffice/LibreOffice", ex); + + dialogService.showErrorDialogAndWait(Localization.lang("Unable to connect. One possible reason is that JabRef " + + "and OpenOffice/LibreOffice are not both running in either 32 bit mode or 64 bit mode.")); + } + case IOException ioException -> { + LOGGER.warn("Could not connect to running OpenOffice/LibreOffice", ex); + + dialogService.showErrorDialogAndWait(Localization.lang("Could not connect to running OpenOffice/LibreOffice."), + Localization.lang("Could not connect to running OpenOffice/LibreOffice.") + + "\n" + + Localization.lang("Make sure you have installed OpenOffice/LibreOffice with Java support.") + "\n" + + Localization.lang("If connecting manually, please verify program and library paths.") + "\n" + "\n" + Localization.lang("Error message:"), + ex); + } + case BootstrapException bootstrapEx -> { + LOGGER.error("Exception boostrap cause", bootstrapEx.getTargetException()); + dialogService.showErrorDialogAndWait("Bootstrap error", bootstrapEx.getTargetException()); + } + case null, + default -> + dialogService.showErrorDialogAndWait(Localization.lang("Autodetection failed"), Localization.lang("Autodetection failed"), ex); } }); @@ -522,11 +532,10 @@ private void pushEntries(CitationType citationType, boolean addPageInfo) { ooBase.guiActionInsertEntry(entries, bibDatabaseContext, - jStyle, + currentStyle, citationType, pageInfo, - syncOptions, - currentStyleType); + syncOptions); } /** diff --git a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.fxml b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.fxml index 152aae43ab9..f7020aa2d25 100644 --- a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.fxml +++ b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialog.fxml @@ -11,60 +11,73 @@ + - - - - - - - - - - - - -