diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 05c03a4594f..eee63f64018 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -257,7 +257,7 @@ jobs: uses: unsplash/comment-on-pr@master if: steps.authors_check.outputs.newauthor == 'true' env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GH_TOKEN_COMMENT_ON_PR }} with: msg: "${{ steps.authors_check.outputs.message }}" check_for_duplicate_msg: true diff --git a/.idea/runConfigurations/JabRef_Main.xml b/.idea/runConfigurations/JabRef_Main.xml index d57c0fd5ac5..f6e0ca898ae 100644 --- a/.idea/runConfigurations/JabRef_Main.xml +++ b/.idea/runConfigurations/JabRef_Main.xml @@ -1,9 +1,9 @@ - - \ No newline at end of file + diff --git a/.mailmap b/.mailmap index a755a5d1806..b03046749ac 100644 --- a/.mailmap +++ b/.mailmap @@ -47,6 +47,7 @@ Frédéric Darboux Frédéric Darboux Frédéric Darboux Frédéric Darboux +Frédéric Darboux Florian Straßer Gregor Herrmann Hakan Duran hakova diff --git a/.markdownlint.yml b/.markdownlint.yml index 3ed5b253fa6..0ada157fae9 100644 --- a/.markdownlint.yml +++ b/.markdownlint.yml @@ -13,6 +13,9 @@ MD013: false MD026: punctuation: ".,;:!" +# not supported by gitbook +MD031: false + MD033: # we have tags with ids and superscript allowed_elements: ['a', 'sup'] diff --git a/AUTHORS b/AUTHORS index 3a8b70a713e..c57cec7736e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -119,6 +119,7 @@ Ethan Harris Fabian Bauer Fabian Bieker Fabiani Giovanni +Fabio Marcos Fabrice Dessaint Fancy Zhang Fedor Bezrukov @@ -223,6 +224,7 @@ Lucas Beretti Luciana de Melo e Abud Lugduni Desrosiers Luis Romero +m-mauersberger Mairieli Wessel Malik Atalla Malte Deiseroth diff --git a/CHANGELOG.md b/CHANGELOG.md index d12ff9edf47..ac4b929ca22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ + # Changelog All notable changes to this project will be documented in this file. @@ -13,15 +14,29 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We added a query parser and mapping layer to enable conversion of queries formulated in simplified lucene syntax by the user into api queries. [#6799](https://github.com/JabRef/jabref/pull/6799) - We added some basic functionality to customise the look of JabRef by importing a css theme file. [#5790](https://github.com/JabRef/jabref/issues/5790) +- We added connection check function in network preference setting [#6560](https://github.com/JabRef/jabref/issues/6560) ### Changed +- We restructured the 'File' tab and extracted some parts into the 'Linked files' tab [#6779](https://github.com/JabRef/jabref/pull/6779) - JabRef now offers journal lists from . JabRef the lists which use a dot inside the abbreviations. [#5749](https://github.com/JabRef/jabref/pull/5749) +- We removed two useless preferences in the groups preferences dialog. [#6836](https://github.com/JabRef/jabref/pull/6836) +- Synchronization of SpecialFields to keywords is now disabled by default. [#6621](https://github.com/JabRef/jabref/issues/6621) +- JabRef no longer opens the entry editor with the first entry on startup [#6855](https://github.com/JabRef/jabref/issues/6855) +- We completed the rebranding of `bibtexkey` as `citationkey` which was started in JabRef 5.1. +- JabRef no longer opens the entry editor with the first entry on startup [#6855](https://github.com/JabRef/jabref/issues/6855) +- Fetch by ID: (long) "SAO/NASA Astrophysics Data System" replaced by (short) "SAO/NASA ADS" [#6876](https://github.com/JabRef/jabref/pull/6876) +- We changed the title of the window "Manage field names and content": to have the same title as the corresponding menu item [#6895](https://github.com/JabRef/jabref/pull/6895) ### Fixed -### Removed +- We fixed an issue changing the icon link_variation_off that is not meaningful. [#6834][https://github.com/JabRef/jabref/issues/6834] +- We fixed an issue where the `.sav` file was not deleted upon exiting JabRef. [#6109](https://github.com/JabRef/jabref/issues/6109) +- We fixed a linked identifier icon inconsistency. [#6705](https://github.com/JabRef/jabref/issues/6705) +- We fixed the wrong behavior that font size changes are not reflected in dialogs. [#6039](https://github.com/JabRef/jabref/issues/6039) +- We fixed an issue where the sort order of the entry table was reset after a restart of JabRef [#6898](https://github.com/JabRef/jabref/pull/6898) +### Removed ## [5.1] – 2020-08-30 diff --git a/build.gradle b/build.gradle index fb234d6534e..eeb02422810 100644 --- a/build.gradle +++ b/build.gradle @@ -13,10 +13,10 @@ plugins { id 'application' id "com.simonharrer.modernizer" version '2.1.0-1' id 'me.champeau.gradle.jmh' version '0.5.1' - id 'com.github.ben-manes.versions' version '0.29.0' + id 'com.github.ben-manes.versions' version '0.30.0' id 'org.javamodularity.moduleplugin' version '1.7.0' id 'org.openjfx.javafxplugin' version '0.0.9' - id 'org.beryx.jlink' version '2.21.3' + id 'org.beryx.jlink' version '2.21.4' // nicer test outputs during running and completion // Homepage: https://github.com/radarsh/gradle-test-logger-plugin @@ -46,7 +46,7 @@ java { } application { - mainClassName = "$moduleName/org.jabref.JabRefLauncher" + mainClassName = "$moduleName/org.jabref.gui.JabRefLauncher" } // TODO: Ugly workaround to temporarily ignore build errors to dependencies of latex2unicode @@ -105,8 +105,8 @@ dependencies { // Include all jar-files in the 'lib' folder as dependencies implementation fileTree(dir: 'lib', includes: ['*.jar']) - implementation 'org.apache.pdfbox:pdfbox:2.0.20' - implementation 'org.apache.pdfbox:fontbox:2.0.20' + implementation 'org.apache.pdfbox:pdfbox:2.0.21' + implementation 'org.apache.pdfbox:fontbox:2.0.21' implementation 'org.apache.pdfbox:xmpbox:2.0.20' implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.8' @@ -137,7 +137,7 @@ dependencies { antlr4 'org.antlr:antlr4:4.8-1' implementation 'org.antlr:antlr4-runtime:4.8-1' - implementation (group: 'org.apache.lucene', name: 'lucene-queryparser', version: '8.6.1') { + implementation (group: 'org.apache.lucene', name: 'lucene-queryparser', version: '8.6.2') { exclude group: 'org.apache.lucene', module: 'lucene-sandbox' } @@ -207,9 +207,10 @@ dependencies { testImplementation 'net.bytebuddy:byte-buddy-parent:1.10.14' testRuntime group: 'org.apache.logging.log4j', name: 'log4j-core', version: '3.0.0-SNAPSHOT' testRuntime group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '3.0.0-SNAPSHOT' - testImplementation 'org.mockito:mockito-core:3.5.7' + testImplementation 'org.mockito:mockito-core:3.5.10' testImplementation 'org.xmlunit:xmlunit-core:2.7.0' testImplementation 'org.xmlunit:xmlunit-matchers:2.7.0' + testRuntime 'com.tngtech.archunit:archunit-junit5-engine:0.14.1' testImplementation 'com.tngtech.archunit:archunit-junit5-api:0.14.1' testImplementation "org.testfx:testfx-core:4.0.17-alpha-SNAPSHOT" testImplementation "org.testfx:testfx-junit5:4.0.17-alpha-SNAPSHOT" @@ -442,6 +443,11 @@ test { excludeTags 'DatabaseTest', 'FetcherTest', 'GUITest' } + moduleOptions { + // TODO: Remove this as soon as archunit is modularized + runOnClasspath = true + } + testLogging { // set options for log level LIFECYCLE // for debugging tests: add "STANDARD_OUT", "STANDARD_ERROR" diff --git a/buildres/linux/JabRef.desktop b/buildres/linux/JabRef.desktop index c2aae778161..8bbaff35f2f 100644 --- a/buildres/linux/JabRef.desktop +++ b/buildres/linux/JabRef.desktop @@ -9,4 +9,4 @@ Type=Application DESKTOP_MIMES Categories=DEPLOY_BUNDLE_CATEGORY Keywords=bibtex;biblatex;latex;bibliography -StartupWMClass=org.jabref.JabRefMain +StartupWMClass=org.jabref.gui.JabRefMain diff --git a/docs/.gitbook/assets/eclipse-create-run-config (1) (1).png b/docs/.gitbook/assets/eclipse-create-run-config (1) (1).png new file mode 100644 index 00000000000..1412291a55a Binary files /dev/null and b/docs/.gitbook/assets/eclipse-create-run-config (1) (1).png differ diff --git a/docs/.gitbook/assets/eclipse-create-run-config (1).png b/docs/.gitbook/assets/eclipse-create-run-config (1).png new file mode 100644 index 00000000000..1412291a55a Binary files /dev/null and b/docs/.gitbook/assets/eclipse-create-run-config (1).png differ diff --git a/docs/.gitbook/assets/grafik (1) (1).png b/docs/.gitbook/assets/grafik (1) (1).png new file mode 100644 index 00000000000..c3b7615fdda Binary files /dev/null and b/docs/.gitbook/assets/grafik (1) (1).png differ diff --git a/docs/.gitbook/assets/intellij-enable-annotation-processing.png b/docs/.gitbook/assets/intellij-enable-annotation-processing.png new file mode 100644 index 00000000000..784ce6cd19e Binary files /dev/null and b/docs/.gitbook/assets/intellij-enable-annotation-processing.png differ diff --git a/docs/.gitbook/assets/intellij-gradle-config-ignore-buildSrc (1) (1).png b/docs/.gitbook/assets/intellij-gradle-config-ignore-buildSrc (1) (1).png new file mode 100644 index 00000000000..30fd74bba1c Binary files /dev/null and b/docs/.gitbook/assets/intellij-gradle-config-ignore-buildSrc (1) (1).png differ diff --git a/docs/.gitbook/assets/intellij-gradle-config-ignore-buildSrc (2).png b/docs/.gitbook/assets/intellij-gradle-config-ignore-buildSrc (2).png new file mode 100644 index 00000000000..203ad5ad207 Binary files /dev/null and b/docs/.gitbook/assets/intellij-gradle-config-ignore-buildSrc (2).png differ diff --git a/docs/.gitbook/assets/intellij-wrap-at-right-margin.png b/docs/.gitbook/assets/intellij-wrap-at-right-margin.png new file mode 100644 index 00000000000..c3b7615fdda Binary files /dev/null and b/docs/.gitbook/assets/intellij-wrap-at-right-margin.png differ diff --git a/docs/README.md b/docs/README.md index 6fdbda908c2..096a6147596 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # Overview on Developing -This page presents all development informatation around JabRef. +This page presents all development information around JabRef. ## Starting point for newcomers @@ -37,23 +37,11 @@ Without jlink, it is not possible to generate a fat jar any more. During develop Diagram showing aspects of groups: [Groups.uml](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/Groups.uml). -## Decision Records +## Architectural Decision Records -This log lists the decisions for JabRef. +[Architectural decisions for JabRef](adr.md) are recorded. -* [ADR-0000](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0000-use-markdown-architectural-decision-records.md) - Use Markdown Architectural Decision Records -* [ADR-0001](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0001-use-crowdin-for-translations.md) - Use Crowdin for translations -* [ADR-0002](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0002-use-slf4j-for-logging.md) - Use slf4j together with log4j2 for logging -* [ADR-0003](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0003-use-gradle-as-build-tool.md) - Use Gradle as build tool -* [ADR-0004](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0004-use-mariadb-connector.md) - Use MariaDB Connector -* [ADR-0005](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0005-fully-support-utf8-only-for-latex-files.md) - Fully Support UTF-8 Only For LaTeX Files -* [ADR-0006](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0006-only-translated-strings-in-language-file.md) - Only translated strings in language file -* [ADR-0007](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0007-human-readable-changelog.md) - Provide a human-readable changelog -* [ADR-0008](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0008-use-public-final-instead-of-getters.md) - Use public final instead of getters to offer access to immutable variables -* [ADR-0009](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0009-use-plain-junit5-for-testing.md) - Use Plain JUnit5 for advanced test assertions -* [ADR-0010](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/0010-use-h2-as-internal-database.md) - Use H2 as Internal SQL Database - -For new ADRs, please use [template.md](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/template.md) as basis. More information on MADR is available at [https://adr.github.io/madr/](https://adr.github.io/madr/). General information about architectural decision records is available at [https://adr.github.io/](https://adr.github.io/). +For new ADRs, please use [template.md](https://github.com/JabRef/jabref/tree/3b3716b1e05a0d3273c886e102a8efe5e96472e0/docs/adr/template.md) as basis. More information on MADR is available at [https://adr.github.io/madr/](https://adr.github.io/madr/). General information about architectural decision records is available at [https://adr.github.io/](https://adr.github.io/). Add them to the [list of architectural decision records](adr.md). ## FAQ diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index a3836d7d6ba..a9d5917e5e9 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -13,6 +13,7 @@ * [Code Quality](advanced-reading/code-quality.md) * [Recommendations for UI design](advanced-reading/ui-recommendations.md) * [Custom SVG icons](advanced-reading/custom-svg-icons.md) + * [Working on fetchers](advanced-reading/fetchers.md) * [Creating a binary and debug it](advanced-reading/jpackage.md) * [JabRef and Software Engineering](teaching.md) * [Readings on Coding](readings-on-coding/README.md) diff --git a/docs/adr.md b/docs/adr.md index 8c8e4783f47..3907e985781 100644 --- a/docs/adr.md +++ b/docs/adr.md @@ -1,6 +1,27 @@ # Architectural Decisions -This directory contains the architectural decisions for JabRef. +Architectural decisions for JabRef: -For new ADRs, please use [template.md](https://github.com/JabRef/jabref/tree/98e9fc3ddc7b59ca35101c7f37b183ca2e69d8a0/docs/adr/template.md) as basis. More information on the used format is available at [https://adr.github.io/madr/](https://adr.github.io/madr/). General information about architectural decision records is available at [https://adr.github.io/](https://adr.github.io/). +* [ADR-0000](https://github.com/JabRef/jabref/tree/docs/adr/0000-use-markdown-architectural-decision-records.md) - Use Markdown Architectural Decision Records +* [ADR-0001](https://github.com/JabRef/jabref/tree/docs/adr/0001-use-crowdin-for-translations.md) - Use Crowdin for translations +* [ADR-0002](https://github.com/JabRef/jabref/tree/docs/adr/0002-use-slf4j-for-logging.md) - Use slf4j together with log4j2 for logging +* [ADR-0003](https://github.com/JabRef/jabref/tree/docs/adr/0003-use-gradle-as-build-tool.md) - Use Gradle as build tool +* [ADR-0004](https://github.com/JabRef/jabref/tree/docs/adr/0004-use-mariadb-connector.md) - Use MariaDB Connector +* [ADR-0005](https://github.com/JabRef/jabref/tree/docs/adr/0005-fully-support-utf8-only-for-latex-files.md) - Fully Support UTF-8 Only For LaTeX Files +* [ADR-0006](https://github.com/JabRef/jabref/tree/docs/adr/0006-only-translated-strings-in-language-file.md) - Only translated strings in language file +* [ADR-0007](https://github.com/JabRef/jabref/tree/docs/adr/0007-human-readable-changelog.md) - Provide a human-readable changelog +* [ADR-0008](https://github.com/JabRef/jabref/tree/docs/adr/0008-use-public-final-instead-of-getters.md) - Use public final instead of getters to offer access to immutable variables +* [ADR-0009](https://github.com/JabRef/jabref/tree/docs/adr/0009-use-plain-junit5-for-testing.md) - Use Plain JUnit5 for advanced test assertions +* [ADR-0010](https://github.com/JabRef/jabref/tree/docs/adr/0010-use-h2-as-internal-database.md) - Use H2 as Internal SQL Database +* [ADR-0011](https://github.com/JabRef/jabref/tree/docs/adr/0011-test-external-links-in-documentation.md) - Test external links in documentation +* [ADR-0012](https://github.com/JabRef/jabref/tree/docs/adr/0012-handle-different-bibEntry-formats-of-fetchers.md) - Handle different bibentry formats of fetchers by adding a layer +* [ADR-0013](https://github.com/JabRef/jabref/tree/docs/adr/0013-add-native-support-biblatex-software.md) - Add Native Support for BibLatex-Sotware +fix checkstyle in adr +* [ADR-0014](https://github.com/JabRef/jabref/tree/docs/adr/0014-separate-URL-creation-to-enable-proper-logging.md) - Separate URL creation to enable proper logging +* [ADR-0015](https://github.com/JabRef/jabref/tree/docs/adr/0015-support-an-abstract-query-syntax-for-query-conversion.md) - Query syntax design +* [ADR-0016](https://github.com/JabRef/jabref/tree/docs/adr/0016-mutable-preferences-objects.md) - Mutable preferences objects +* [ADR-0017](https://github.com/JabRef/jabref/tree/docs/adr/0017-allow-model-access-logic.md) - Allow org.jabref.model to access org.jabref.logic + + +For new ADRs, please use [template.md](https://github.com/JabRef/jabref/tree/98e9fc3ddc7b59ca35101c7f37b183ca2e69d8a0/docs/adr/template.md) as basis. More information on the used format is available at [https://adr.github.io/madr/](https://adr.github.io/madr/). General information about architectural decision records is available at [https://adr.github.io/](https://adr.github.io/). Then add them to the above list. diff --git a/docs/adr/0003-use-gradle-as-build-tool.md b/docs/adr/0003-use-gradle-as-build-tool.md index 81000f31444..5dac1018032 100644 --- a/docs/adr/0003-use-gradle-as-build-tool.md +++ b/docs/adr/0003-use-gradle-as-build-tool.md @@ -38,7 +38,7 @@ Chosen option: "Gradle", because it is lean and fits our development style. * Good, because [it offers custom dependency scopes](https://gradle.org/maven-vs-gradle/) * Good, because [it has good community support](https://linuxhint.com/ant-vs-maven-vs-gradle/) * Good, because [its performance can be 100 times more than maven's performance](https://gradle.org/gradle-vs-maven-performance/). -* Bad, because [not that many plugins are available/maintained yet](https://blog.philipphauer.de/moving-back-from-gradle-to-maven/) +* Bad, because [not that many plugins are available/maintained yet](https://phauer.com/2018/moving-back-from-gradle-to-maven/) * Bad, because [it lacks a wide variety of application server integrations](http://pages.zeroturnaround.com/rs/zeroturnaround/images/java-build-tools-part-2.pdf) * Bad, because [it has a medium popularity](http://pages.zeroturnaround.com/rs/zeroturnaround/images/java-build-tools-part-2.pdf) * Bad, because [it allows custom build scripts which need to be debugged](https://www.softwareyoga.com/10-reasons-why-we-chose-maven-over-gradle/) diff --git a/docs/adr/0015-support-an-abstract-query-syntax-for-query-conversion.md b/docs/adr/0015-support-an-abstract-query-syntax-for-query-conversion.md index cb6a8f214fa..f25f161c2ff 100644 --- a/docs/adr/0015-support-an-abstract-query-syntax-for-query-conversion.md +++ b/docs/adr/0015-support-an-abstract-query-syntax-for-query-conversion.md @@ -27,10 +27,23 @@ For simplicitly, and lack of universal capabilities across fetchers, only basic * `year` (for single year) * `year-range` (for range e.g. `year-range:2012-2015`) * The `journal`, `year`, and `year-range` fields should only be populated once in each query +* The `year` and `year-range` fields are mutually exclusive * Example: * `author:"Igor Steinmacher" author:"Christoph Treude" year:2017` will be converted to * `author:"Igor Steinmacher" AND author:"Christoph Treude" AND year:2017` +The supported syntax can be expressed in EBNF as follows: + +Query := {Clause} \ +Clause:= \[Field\] Term \ +Field := author: | title: | journal: | year: | year-range: | default:\ +Term := Word | Phrase \ + +Word can be derived to any series of non-whitespace characters. +Phrases are multiple words wrapped in quotes and may contain white-space characters within the quotes.\ +Note: Even though this EBNF syntactically allows the creation of queries with year and year-range fields, +such a query does not make sense semantically and therefore will not be executed. + ### Positive Consequences * Already tested diff --git a/docs/adr/0016-mutable-preferences-objects.md b/docs/adr/0016-mutable-preferences-objects.md new file mode 100644 index 00000000000..6abb70af9c1 --- /dev/null +++ b/docs/adr/0016-mutable-preferences-objects.md @@ -0,0 +1,16 @@ +# Mutable preferences objects + +## Context and Problem Statement + +To create an immutable preferences object every time seems to be a waste of time and computer memory. + +## Considered Options + +* Create a new object every time a preferences object should be altered by a with*-method, similar to a builder. +* Alter the existing object and return it. + +## Decision Outcome + +Chosen option: "Alter the exiting object", because the preferences objects are just wrappers around the basic preferences framework of JDK. They +should be mutable on-the-fly similar to objects with a Builder inside and to be stored immediatly again in the +preferences. diff --git a/docs/adr/0017-allow-model-access-logic.md b/docs/adr/0017-allow-model-access-logic.md new file mode 100644 index 00000000000..5567fe198d4 --- /dev/null +++ b/docs/adr/0017-allow-model-access-logic.md @@ -0,0 +1,40 @@ +# Allow org.jabref.model to access org.jabref.logic + +## Context and Problem Statement + +- How to create a maintainable architecture? +- How to split model, logic, and UI + +## Decision Drivers + +- New comers should find the architecture "split" natural +- The architecture should be a help (and not a burden) + +## Considered Options + +- `org.jabref.model` uses `org.jabref.model` (and external libraries) only +- `org.jabref.model` may use `org.jabref.logic` in defined cases +- `org.jabref.model` and `org.jabref.logic` may access each other freely + +## Decision Outcome + +Chosen option: "`org.jabref.model` may use `org.jabref.logic` in defined cases", because comes out best \(see below\). + +## Pros and Cons of the Options + +### `org.jabref.model` uses `org.jabref.model` (and external libraries) only + +- Good, because clear separation of model and logic +- Bad, because this leads to an [Anemic Domain Model](https://martinfowler.com/bliki/AnemicDomainModel.html) + +### `org.jabref.model` may use `org.jabref.logic` in defined cases + +- Good, because model and logic are still separated +- Neutral, because each exception has to be discussed and agreed +- Bad, because new comers have to be informed that there are certain (agreed) exceptions for model to access logic + +### `org.jabref.model` and `org.jabref.logic` may access each other freely + +- Bad, because may lead to spaghetti code +- Bad, because coupling between model and logic is increased +- Bad, because cohesion inside model is decreased diff --git a/docs/adr/template.md b/docs/adr/template.md index b07f46e2eb0..b4974469854 100644 --- a/docs/adr/template.md +++ b/docs/adr/template.md @@ -1,73 +1,67 @@ -# \[short title of solved problem and solution\] +# MADR Templae -* Status: \[proposed \| rejected \| accepted \| deprecated \| … \| superseded by [ADR-0005](0005-fully-support-utf8-only-for-latex-files.md)\] -* Deciders: \[list everyone involved in the decision\] -* Date: \[YYYY-MM-DD when the decision was last updated\] +The template of [MADR](https://adr.github.io/madr/) is available at . +You can omit the `<-- optional -->` parts, which lead to a very minimal ADR: -Technical Story: \[description \| ticket/issue URL\] +```markdown +# [short title of solved problem and solution] ## Context and Problem Statement -\[Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.\] - -## Decision Drivers - -* \[driver 1, e.g., a force, facing concern, …\] -* \[driver 2, e.g., a force, facing concern, …\] -* … +[Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.] ## Considered Options -* \[option 1\] -* \[option 2\] -* \[option 3\] -* … +* [option 1] +* [option 2] +* [option 3] +* … ## Decision Outcome -Chosen option: "\[option 1\]", because \[justification. e.g., only option, which meets k.o. criterion decision driver \| which resolves force force \| … \| comes out best \(see below\)\]. - -### Positive Consequences +Chosen option: "[option 1]", because [justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force force | … ]. +``` -* \[e.g., improvement of quality attribute satisfaction, follow-up decisions required, …\] -* … +In case you want to include the pros and cons of the options, the template is as follows: -### Negative Consequences +```markdown +# [short title of solved problem and solution] -* \[e.g., compromising quality attribute, follow-up decisions required, …\] -* … - -## Pros and Cons of the Options +## Context and Problem Statement -### \[option 1\] +[Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.] -\[example \| description \| pointer to more information \| …\] +## Considered Options -* Good, because \[argument a\] -* Good, because \[argument b\] -* Bad, because \[argument c\] -* … +* [option 1] +* [option 2] +* [option 3] +* … -### \[option 2\] +## Decision Outcome -\[example \| description \| pointer to more information \| …\] +Chosen option: "[option 1]", because comes out best (see below). -* Good, because \[argument a\] -* Good, because \[argument b\] -* Bad, because \[argument c\] -* … +## Pros and Cons of the Options -### \[option 3\] +### [option 1] -\[example \| description \| pointer to more information \| …\] +* Good, because [argument a] +* Good, because [argument b] +* Bad, because [argument c] +* … -* Good, because \[argument a\] -* Good, because \[argument b\] -* Bad, because \[argument c\] -* … +### [option 2] -## Links +* Good, because [argument a] +* Good, because [argument b] +* Bad, because [argument c] +* … -* \[Link type\] \[Link to ADR\] -* … +### [option 3] +* Good, because [argument a] +* Good, because [argument b] +* Bad, because [argument c] +* … +``` diff --git a/docs/advanced-reading/fetchers.md b/docs/advanced-reading/fetchers.md index 47448f8daec..b9310a4f0d5 100644 --- a/docs/advanced-reading/fetchers.md +++ b/docs/advanced-reading/fetchers.md @@ -1,30 +1,24 @@ # Working on fetchers -Fetchers are the implementation of the [search using online services](https://docs.jabref.org/collect/import-using-online-bibliographic-database). -Some fetchers require API keys to get them working. -To get the fetchers running in a JabRef development setup, the keys need to be placed in the respective enviornment variable. -The following table lists the respective fetchers, where to get the key from and the environment variable where the key has to be placed. +Fetchers are the implementation of the [search using online services](https://docs.jabref.org/collect/import-using-online-bibliographic-database). Some fetchers require API keys to get them working. To get the fetchers running in a JabRef development setup, the keys need to be placed in the respective enviornment variable. The following table lists the respective fetchers, where to get the key from and the environment variable where the key has to be placed. | Service | Key Source | Environment Variable | Rate Limit | -| -- | -- | -- | -- | +| :--- | :--- | :--- | :--- | | [IEEEXplore](https://docs.jabref.org/collect/import-using-online-bibliographic-database/ieeexplore) | [IEEE Xplore API portal](https://developer.ieee.org/) | `IEEEAPIKey` | 200 calls/day | -| [MathSciNet](http://www.ams.org/mathscinet) | (none) | (none) | Depending on the current network | +| [MathSciNet](http://www.ams.org/mathscinet) | \(none\) | \(none\) | Depending on the current network | | [SAO/NASA Astrophysics Data System](https://docs.jabref.org/collect/import-using-online-bibliographic-database/ads) | [ADS UI](https://ui.adsabs.harvard.edu/user/settings/token) | `AstrophysicsDataSystemAPIKey` | 5000 calls/day | -| [Springer Nature](https://docs.jabref.org/collect/import-using-online-bibliographic-database/springer) | [Springer Nature API Portal](https://dev.springernature.com/) | `SpringerNatureAPIKey`| 5000 calls/day | -| [Zentralblatt Math](https://www.zbmath.org/) | (none) | (none) | Depending on the current network | +| [Springer Nature](https://docs.jabref.org/collect/import-using-online-bibliographic-database/springer) | [Springer Nature API Portal](https://dev.springernature.com/) | `SpringerNatureAPIKey` | 5000 calls/day | +| [Zentralblatt Math](https://www.zbmath.org/) | \(none\) | \(none\) | Depending on the current network | -"Depending on the current network" means that it depends whether your request is routed through a network having paid access. -For instance, some universities have subscriptions to MathSciNet. +"Depending on the current network" means that it depends whether your request is routed through a network having paid access. For instance, some universities have subscriptions to MathSciNet. -On Windows, you have to log-off and log-on to let IntelliJ know about the environment variable change. -Execute the gradle task "processResources" in the group "others" within IntelliJ to ensure the values have been correctly written. -Now, the fetcher tests should run without issues. +On Windows, you have to log-off and log-on to let IntelliJ know about the environment variable change. Execute the gradle task "processResources" in the group "others" within IntelliJ to ensure the values have been correctly written. Now, the fetcher tests should run without issues. ## Background on embedding the keys in JabRef The keys are placed into the `build.properties` file. -```properties +```text springerNatureAPIKey=${springerNatureAPIKey} ``` @@ -40,6 +34,5 @@ The `BuildInfo` class reads from that file. new BuildInfo().springerNatureAPIKey ``` -When executing `./gradlew run`, gradle executes `processResources` and populates `build/build.properties` accordingly. -However, when working directly in the IDE, Eclipse keeps reading `build.properties` from `src/main/resources`. -In IntelliJ, the task `JabRef Main` is executing `./gradlew processResources` before running JabRef from the IDE to ensure the `build.properties` is properly populated. +When executing `./gradlew run`, gradle executes `processResources` and populates `build/build.properties` accordingly. However, when working directly in the IDE, Eclipse keeps reading `build.properties` from `src/main/resources`. In IntelliJ, the task `JabRef Main` is executing `./gradlew processResources` before running JabRef from the IDE to ensure the `build.properties` is properly populated. + diff --git a/docs/advanced-reading/jpackage.md b/docs/advanced-reading/jpackage.md index 48f9aa88e45..709c97b0447 100644 --- a/docs/advanced-reading/jpackage.md +++ b/docs/advanced-reading/jpackage.md @@ -28,7 +28,7 @@ Sometimes issues with modularity only arise in the installed version and do not 3. Modify the `build\image\JabRef\runtime\bin\Jabref.bat` file, replace the last line with ```text - pushd %DIR% & %JAVA_EXEC% -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n -p "%~dp0/../app" -m org.jabref/org.jabref.JabRefLauncher %* & popd + pushd %DIR% & %JAVA_EXEC% -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n -p "%~dp0/../app" -m org.jabref/org.jabref.gui.JabRefLauncher %* & popd ``` 4. Open your IDE and add a "Remote Debugging Configuration" for `localhost:8000` diff --git a/docs/getting-into-the-code/code-howtos.md b/docs/getting-into-the-code/code-howtos.md index 512d78ad64d..b1e0ca97980 100644 --- a/docs/getting-into-the-code/code-howtos.md +++ b/docs/getting-into-the-code/code-howtos.md @@ -22,15 +22,14 @@ Principles: * Catch and wrap all API exceptions \(such as `IOExceptions`\) and rethrow them * Example: - ```java + ```java try { // ... } catch (IOException ioe) { throw new JabRefException("Something went wrong...", Localization.lang("Something went wrong...", ioe); } - ``` - + ``` * Never, ever throw and catch `Exception` or `Throwable` * Errors should only be logged when they are finally caught \(i.e., logged only once\). See **Logging** for details. * If the Exception message is intended to be shown to the User in the UI \(see below\) provide also a localizedMessage \(see `JabRefException`\). @@ -52,7 +51,7 @@ TODO: Usage of status bar and Swing Dialogs ## Using the EventSystem -### What the EventSystem is used for? +### What the EventSystem is used for Many times there is a need to provide an object on many locations simultaneously. This design pattern is quite similar to Java's Observer, but it is much simplier and readable while having the same functional sense. diff --git a/docs/getting-into-the-code/guidelines-for-setting-up-a-local-workspace.md b/docs/getting-into-the-code/guidelines-for-setting-up-a-local-workspace.md index 429742ea298..9bac648c0e7 100644 --- a/docs/getting-into-the-code/guidelines-for-setting-up-a-local-workspace.md +++ b/docs/getting-into-the-code/guidelines-for-setting-up-a-local-workspace.md @@ -56,7 +56,7 @@ It is strongly recommend that you have git installed. We suggest [IntelliJ IDEA](https://www.jetbrains.com/idea/) or [Eclipse \(for advanced users\)](https://eclipse.org/) \(`2020-03` or newer\). -Under Ubuntu Linux, you can follow the [documentation from the Ubuntu Community](https://help.ubuntu.com/community/EclipseIDE#Download_Eclipse) or the [step-by-step guideline from Krizna](https://www.krizna.com/ubuntu/install-eclipse-in-ubuntu-12-04/) to install Eclipse. Under Windows, download it from [www.eclipse.org](http://www.eclipse.org/downloads/) and run the installer. +On Ubuntu Linux, you can follow the [documentation from the Ubuntu Community](https://help.ubuntu.com/community/EclipseIDE#Download_Eclipse) or the [step-by-step guideline from Krizna](https://www.krizna.com/ubuntu/install-eclipse-in-ubuntu-12-04/) to install Eclipse. Under Windows, download it from [www.eclipse.org](http://www.eclipse.org/downloads/) and run the installer. ### Other Tooling @@ -88,26 +88,22 @@ These steps are very important. They allow you to focus on the content and ensur ### Setup for IntelliJ IDEA -IntelliJ IDEA fully supports Gradle as a build tool, but also has an internal build system which is usually faster. For JabRef, Gradle is required to make a full build but once set up, IntelliJ IDEA's internal system can be used for sub-sequent builds. +We recommend to install IntelliJ IDEA using [JetBrains Toolbox App](https://www.jetbrains.com/toolbox-app/), because IDE updates are automatically installed. -To configure IntelliJ IDEA for developing JabRef, you should first ensure that you have enabled both bundled plugins _Gradle_ and _Gradle Extension_ +IntelliJ IDEA fully supports Gradle as a build tool, but also has an internal build system which is usually faster. For JabRef, Gradle is required to make a full build but once set up, IntelliJ IDEA's internal system can be used for sub-sequent builds. -* Navigate to **File \| Settings \| Plugins \| Installed** and check that you have +To configure IntelliJ IDEA for developing JabRef, you should first ensure that you have enabled both bundled plugins _Gradle_ and _Gradle Extension_: - the _Gradle_ and _Gradle Extension_ enabled. +* Navigate to **File \| Settings \| Plugins \| Installed** and check that you have the _Gradle_ and _Gradle Extension_ enabled. After that, you can open `jabref/build.gradle` as a project. It is crucial that Java 14 is used consistently for the JabRef project which includes ensuring the right settings for your project structure, Gradle build, and run configurations. -* Ensure you have a Java 14 SDK configured by navigating to - - **File \| Project Structure \| Platform Settings \| SDKs**. If you don't have one, add a new Java JDK and point it to the - - location of a JDK 14. +Ensure you have a Java 14 SDK configured by navigating to **File \| Project Structure \| Platform Settings \| SDKs**. If you don't have one, add a new Java JDK and point it to the location of a JDK 14: * Navigate to **File \| Project Structure \| Project** and ensure that the projects' SDK is Java 14 * Navigate to **File \| Settings \| Build, Execution, Deployment \| Build Tools \| Gradle** and select the Java 14 SDK as the Gradle JVM at the bottom. -To prepare IntelliJ's build system two additional steps are required +To prepare IntelliJ's build system two additional steps are required: * Navigate to **File \| Settings \| Build, Execution, Deployment \| Compiler \| Java Compiler**, and under "Override compiler parameters per-module" add \(\[+\]\) the following compiler arguments for the `JabRef.main` module: @@ -118,16 +114,20 @@ To prepare IntelliJ's build system two additional steps are required * Enable annotation processors by navigating to **File \| Settings \| Build, Execution, Deployment \| Compiler \| Annotation processors** and check "Enable annotation processing" + ![Enable annotation processing](../.gitbook/assets/intellij-enable-annotation-processing.png) + To have autoformat working properly in the context of line wrapping, "Wrap at right margin" has to be disabled as shown below. Details are found in [IntelliJ issue 240517](https://youtrack.jetbrains.com/issue/IDEA-240517). -![Disable wrapping at right margin to prevent JavaDoc to be wrapped](../.gitbook/assets/grafik%20%281%29.png) +![Disable wrapping at right margin to prevent JavaDoc to be wrapped](../.gitbook/assets/intellij-wrap-at-right-margin.png) #### Using Gradle from within IntelliJ IDEA Ensuring JabRef builds with Gradle should always the first step because, e.g. it generates additional sources that are required for compiling the code. After adjusting all settings mentioned earlier, your first step should be to * Open the Gradle Tool Window with the small button that can usually be found on the right side of IDEA or navigate to **View \| Tool Windows \| Gradle**. -* In the Gradle Tool Window, press the "Reimport All Gradle Projects" button to ensure that all settings are up-to-date with the setting changes. +* In the Gradle Tool Window, press the "Reload All Gradle Projects" button to ensure that all settings are up-to-date + + with the setting changes. After that, you can use the Gradle Tool Window to build all parts JabRef and run it. To do so, expand the JabRef project in the Gradle Tool Window and navigate to Tasks. From there, you can @@ -137,6 +137,8 @@ After that a new entry called "jabref \[run\]" will appear in the run configurat #### Using IntelliJ's internal build system +**Note that these steps do not work on IntelliJ 2020.x.**. You have to keep using gradle for executing tasks. See [IDEA-249391](https://youtrack.jetbrains.com/issue/IDEA-249391) for details. + You should use IntelliJ IDEA's internal build system for compiling and running JabRef during development, because it is usually more responsive. Thereby, **it's important** that you understand that JabRef relies on generated sources which are only build through Gradle. Therefore, to build or update these dependencies you need to run the `assemble` Gradle task at least once. To use IntelliJ IDEA's internal build system when you build JabRef through **Build \| Build Project** or use the provided "JabRef Main" run configuration, ensure that @@ -144,37 +146,39 @@ To use IntelliJ IDEA's internal build system when you build JabRef through **Bui * In **File \| Settings \| Build, Execution, Deployment \| Build Tools \| Gradle** the setting "Build and run using" and "Test using" is set to "IntelliJ IDEA". * Ignore the Gradle project "buildSrc" by clicking the button **Select Project Data To Import** in the Gradle Tool Window and unchecking the folder "buildSrc". - ![Ignore the Gradle project "buildSrc"](../.gitbook/assets/intellij-gradle-config-ignore-buildSrc%20%281%29.png) + ![Ignore the Gradle project "buildSrc"](../.gitbook/assets/intellij-gradle-config-ignore-buildSrc%20%282%29.png) + +* Delete `org.jabref.gui.logging.plugins.Log4jPlugins` \(location: `generated\org\jabref\gui\logging\plugins\Log4jPlugins.java`\). Otherwise, you will see folowing error: + + ```text + Error:java: Unable to create Plugin Service Class org.jabref.gui.logging.plugins.Log4jPlugins + ``` + + or following error: + + ```text + Error:(16, 25) java: package org.jabref.search does not exist + ``` Essentially, you now have the best of both worlds: You can run Gradle tasks using the Gradle Tool Window and unless you haven't made changes to input files that generate sources, you can compile and run with IntelliJ's faster internal build system. +In case all steps are followed, and there are still issues with `SearchBaseVisitor` \(e.g., `Error:(16, 25) java: package org.jabref.search does not exist`\), you have to delete `generated\org\jabref\gui\logging\plugins\Log4jPlugins.java`. This is independet of having enabled or disabled Annotation Processing \(see above at "Enable Annotation Processing"\). + #### Using JabRef's code style Contributions to JabRef's source code need to have a code formatting that is consistent with existing source code. For that purpose, JabRef provides code-style and check-style definitions. * Install the [CheckStyle-IDEA plugin](http://plugins.jetbrains.com/plugin/1065?pr=idea), it can be found via the plug-in repository: - - 1. Navigate to **File \| Settings \| Plugins \| Marketplace** and search for "Checkstyle" and choose "CheckStyle-IDEA" - 2. Close the settings afterwards and restart IntelliJ - + 1. Navigate to **File \| Settings \| Plugins \| Marketplace** and search for "Checkstyle" and choose "CheckStyle-IDEA" + 2. Close the settings afterwards and restart IntelliJ * Go to **File \| Settings \| Editor \| Code Style** * Click on the settings wheel \(next to the scheme chooser\), then click "Import Scheme" * Select the IntelliJ configuration file `config/IntelliJ Code Style.xml` -* Go to **File \| Settings \| Tools \| Checkstyle \| Configuration File** - - 1. Import the CheckStyle configuration file by clicking the \[+\] button - 2. For the description provide "JabRef" - 3. Click "Browse" and choose `config/checkstyle/checkstyle.xml` - 4. Click "Next" and "Finish" - 5. Activate the CheckStyle configuration file by ticking it in the list - 6. Ensure that the [latest CheckStyle version](https://checkstyle.org/releasenotes.html) is selected \(8.36 or higher\). 8.36 is required for Java 14. - 7. Set the "Scan Scope" to "Only Java sources \(including tests\) - 8. Save settings by clicking "OK" - 9. Your configuration should now look like this: - - ```text - ![checkstyle settings](../.gitbook/assets/intellij-checkstyle-settings.png) - ``` +* Go to **File \| Settings \| Tools \| Checkstyle \| Configuration File** 1. Import the CheckStyle configuration file by clicking the \[+\] button 2. For the description provide "JabRef" 3. Click "Browse" and choose `config/checkstyle/checkstyle.xml` 4. Click "Next" and "Finish" 5. Activate the CheckStyle configuration file by ticking it in the list 6. Ensure that the [latest CheckStyle version](https://checkstyle.org/releasenotes.html) is selected \(8.36 or higher\). 8.36 is required for Java 14. 7. Set the "Scan Scope" to "Only Java sources \(including tests\) 8. Save settings by clicking "OK" 9. Your configuration should now look like this: + + ```text + ![checkstyle settings](../.gitbook/assets/intellij-checkstyle-settings.png) + ``` ### Setup for Eclipse @@ -188,10 +192,10 @@ Make sure your Eclipse installation us up to date, Eclipse JEE 2020-03 or newer 3. Open or import the existing project in Eclipse as Java project. * Remark: Importing it as gradle project will not work correctly. * Refresh the project in Eclipse -4. Create a run/debug configuration for the main class `org.jabref.JabRefLauncher` and/or for `org.jabref.JabRefMain` \(both can be used equivalently\) +4. Create a run/debug configuration for the main class `org.jabref.gui.JabRefLauncher` and/or for `org.jabref.gui.JabRefMain` \(both can be used equivalently\) * Remark: The run/debug configuration needs to be added by right clicking the class \(e.g. JabRefLauncher or JabRefMain\) otherwise it will not work. - ![Creating the run/debug configuration by right clicking on the class](../.gitbook/assets/eclipse-create-run-config.png) + ![Creating the run/debug configuration by right clicking on the class](../.gitbook/assets/eclipse-create-run-config%20%281%29%20%281%29.png) * In the tab "Arguments" of the run/debug configuration, enter the following runtime VM arguments: @@ -213,6 +217,7 @@ Make sure your Eclipse installation us up to date, Eclipse JEE 2020-03 or newer --add-exports javafx.web/com.sun.webkit=org.controlsfx.controls --add-exports javafx.graphics/com.sun.javafx.css=org.controlsfx.controls --add-exports javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix + --add-exports javafx.graphics/com.sun.javafx.stage=com.jfoenix --add-exports com.oracle.truffle.regex/com.oracle.truffle.regex=org.graalvm.truffle --patch-module org.jabref=build/resources/main ``` diff --git a/docs/getting-into-the-code/high-level-documentation.md b/docs/getting-into-the-code/high-level-documentation.md index eb4d80521db..84e5295ae70 100644 --- a/docs/getting-into-the-code/high-level-documentation.md +++ b/docs/getting-into-the-code/high-level-documentation.md @@ -35,5 +35,5 @@ All packages and classes which are currently not part of these packages \(we are ## Most Important Classes and their Relation -Both GUI and CLI are started via the `JabRefMain` which will in turn call `JabRef` which then decides whether the GUI \(`JabRefFrame`\) or the CLI \(`JabRefCLI` and a lot of code in `JabRef`\) will be started. The `JabRefFrame` represents the Window which contains a `SidePane` on the left used for the fetchers/groups Each tab is a `BasePanel` which has a `SearchBar` at the top, a `MainTable` at the center and a `PreviewPanel` or an `EntryEditor` at the bottom. Any right click on the `MainTable` is handled by the `RightClickMenu`. Each `BasePanel` holds a `BibDatabaseContext` consisting of a `BibDatabase` and the `MetaData`, which are the only relevant data of the currently shown database. A `BibDatabase` has a list of `BibEntries`. Each `BibEntry` has a key, a bibtex key and a key/value store for the fields with their values. Interpreted data \(such as the type or the file field\) is stored in the `TypedBibentry` type. The user can change the `JabRefPreferences` through the `PreferencesDialog`. +Both GUI and CLI are started via the `JabRefMain` which will in turn call `JabRef` which then decides whether the GUI \(`JabRefFrame`\) or the CLI \(`JabRefCLI` and a lot of code in `JabRef`\) will be started. The `JabRefFrame` represents the Window which contains a `SidePane` on the left used for the fetchers/groups Each tab is a `BasePanel` which has a `SearchBar` at the top, a `MainTable` at the center and a `PreviewPanel` or an `EntryEditor` at the bottom. Any right click on the `MainTable` is handled by the `RightClickMenu`. Each `BasePanel` holds a `BibDatabaseContext` consisting of a `BibDatabase` and the `MetaData`, which are the only relevant data of the currently shown database. A `BibDatabase` has a list of `BibEntries`. Each `BibEntry` has an ID, a citation key and a key/value store for the fields with their values. Interpreted data \(such as the type or the file field\) is stored in the `TypedBibentry` type. The user can change the `JabRefPreferences` through the `PreferencesDialog`. diff --git a/docs/teaching.md b/docs/teaching.md index 5c6d408cc84..41017b7a257 100644 --- a/docs/teaching.md +++ b/docs/teaching.md @@ -12,8 +12,13 @@ We recommend to start early and constantly, since students working earlier and m 2. Be aware that from the first pull request to the final acceptance the typical time needed is two weeks. 3. Be aware that JabRef tries to achieve high code quality. This leads to code reviews requiring actions from the contributors. This also applies for code of students. Read on at our [Development Strategy](getting-into-the-code/development-strategy.md) for more details. 4. Choose tasks from one of the following boards. Write a comment on each issue so that it can be reserved for your course. + * Candidates for university projects: [https://github.com/JabRef/jabref/projects/9](https://github.com/JabRef/jabref/projects/9) + * This board categorizes in small, medium, and large features * Feature Board: [https://github.com/JabRef/jabref/projects/7](https://github.com/JabRef/jabref/projects/7) + * This is a general feature board. Recommended, if the board above is empty or you did not find something suitable * Bug Board: [https://github.com/JabRef/jabref/projects/5](https://github.com/JabRef/jabref/projects/5) + * This is an excellent board to find issues training the maintainance knowledge which is essential for industry work + * General "good first issues". The JabRef team tags issues as [good first issues](https://github.com/jabref/jabref/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) to indicate open tasks offering a good start into the JabRef code. These issues are more a list of random bugs and features. For a more structured comparison of the opened tasks, we recommend the projectd boards listed above. 5. Be aware that the difficulty of bugs and feature vary. A task should be chosen with care. The JabRef team can help here: The majority of the team has experiences in teaching 6. Get in touch with the JabRef team to discuss details. We offer email, skype, [gitter.im](https://gitter.im/JabRef/jabref), discord. Get in touch with [@koppor](https://github.com/koppor/) to find the right channel and to start forming the success of your course. diff --git a/mlc_config.json b/mlc_config.json index 91ac75cfd09..4ad20beb329 100644 --- a/mlc_config.json +++ b/mlc_config.json @@ -3,6 +3,9 @@ { "pattern": "^CONTRIBUTING\\.md" }, + { + "pattern": "^https://codecov\\.io/" + }, { "pattern": "^https://dl\\.acm\\.org" }, diff --git a/scripts/generate-authors.sh b/scripts/generate-authors.sh index c2e1108e47e..6f00f12bb62 100755 --- a/scripts/generate-authors.sh +++ b/scripts/generate-authors.sh @@ -58,5 +58,5 @@ cd "$(dirname "$(readlink -f "$BASH_SOURCE")")/.." # co-authors coauthors=$(git log -i --grep=co-authored-by | grep -i "co-authored-by" | sed "s/.*co-authored-by: \(.*\)/\1/I" | sed "s/ <.*//") - echo -e "$authors\n$(git log --format='%aN')\n$coauthors" | grep -v "\[bot\]" | grep -v "JabRef" | grep -v "Siedlerchr" | grep -v "^Christoph$" | grep -v "^Mootez$" | grep -v "oscargus" | grep -v "dependabot" | grep -v "github actions" | grep -v "igorsteinmacher" | grep -v "halirutan" | grep -v "matthiasgeiger" | grep -v "Gitter Badger" | grep -v "gdstewart" | LC_ALL=C.UTF-8 sort --unique --ignore-case + echo -e "$authors\n$(git log --format='%aN')\n$coauthors" | grep -v "\[bot\]" | grep -v "JabRef" | grep -v "Siedlerchr" | grep -v "^Christoph$" | grep -v "^Mootez$" | grep -v "oscargus" | grep -v "dependabot" | grep -v "github actions" | grep -v "igorsteinmacher" | grep -v "halirutan" | grep -v "matthiasgeiger" | grep -v "Gitter Badger" | grep -v "gdstewart" | grep -v "chenyuheng" | LC_ALL=C.UTF-8 sort --unique --ignore-case } > AUTHORS diff --git a/snap/local/JabRef-launcher b/snap/local/JabRef-launcher index c65a6120820..469bca8698b 100755 --- a/snap/local/JabRef-launcher +++ b/snap/local/JabRef-launcher @@ -1,3 +1,3 @@ #! /bin/sh DIR="$SNAP/lib/runtime/bin" -"$DIR/java" -p "$DIR/../app" -m org.jabref/org.jabref.JabRefLauncher "$@" \ No newline at end of file +"$DIR/java" -p "$DIR/../app" -m org.jabref/org.jabref.gui.JabRefLauncher "$@" diff --git a/src/jmh/java/org/jabref/benchmarks/Benchmarks.java b/src/jmh/java/org/jabref/benchmarks/Benchmarks.java index a4d12e698ce..31935438c71 100644 --- a/src/jmh/java/org/jabref/benchmarks/Benchmarks.java +++ b/src/jmh/java/org/jabref/benchmarks/Benchmarks.java @@ -7,7 +7,7 @@ import java.util.Random; import java.util.stream.Collectors; -import org.jabref.Globals; +import org.jabref.gui.Globals; import org.jabref.logic.exporter.BibtexDatabaseWriter; import org.jabref.logic.exporter.SavePreferences; import org.jabref.logic.formatter.bibtexfields.HtmlToLatexFormatter; @@ -55,7 +55,7 @@ public void init() throws Exception { Random randomizer = new Random(); for (int i = 0; i < 1000; i++) { BibEntry entry = new BibEntry(); - entry.setCiteKey("id" + i); + entry.setCitationKey("id" + i); entry.setField(StandardField.TITLE, "This is my title " + i); entry.setField(StandardField.AUTHOR, "Firstname Lastname and FirstnameA LastnameA and FirstnameB LastnameB" + i); entry.setField(StandardField.JOURNAL, "Journal Title " + i); diff --git a/src/main/java/org/jabref/architecture/AllowedToUseAwt.java b/src/main/java/org/jabref/architecture/AllowedToUseAwt.java new file mode 100644 index 00000000000..d4cdb549485 --- /dev/null +++ b/src/main/java/org/jabref/architecture/AllowedToUseAwt.java @@ -0,0 +1,10 @@ +package org.jabref.architecture; + +/** + * Annotation to indicate that this logic class can access AWT + */ +public @interface AllowedToUseAwt { + + // The rationale + String value(); +} diff --git a/src/main/java/org/jabref/architecture/AllowedToUseLogic.java b/src/main/java/org/jabref/architecture/AllowedToUseLogic.java new file mode 100644 index 00000000000..ed6be5be7c4 --- /dev/null +++ b/src/main/java/org/jabref/architecture/AllowedToUseLogic.java @@ -0,0 +1,10 @@ +package org.jabref.architecture; + +/** + * Annotation to indicate that this logic class can be used in the model package. + */ +public @interface AllowedToUseLogic { + + // The rationale + String value(); +} diff --git a/src/main/java/org/jabref/cli/ArgumentProcessor.java b/src/main/java/org/jabref/cli/ArgumentProcessor.java index a5d723cfcdb..eeee79c1366 100644 --- a/src/main/java/org/jabref/cli/ArgumentProcessor.java +++ b/src/main/java/org/jabref/cli/ArgumentProcessor.java @@ -11,11 +11,11 @@ import java.util.Set; import java.util.prefs.BackingStoreException; -import org.jabref.Globals; -import org.jabref.JabRefException; +import org.jabref.gui.Globals; import org.jabref.gui.externalfiles.AutoSetFileLinksUtil; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.undo.NamedCompound; +import org.jabref.logic.JabRefException; import org.jabref.logic.citationkeypattern.CitationKeyGenerator; import org.jabref.logic.exporter.AtomicFileWriter; import org.jabref.logic.exporter.BibDatabaseWriter; @@ -48,6 +48,7 @@ import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.BibEntry; import org.jabref.model.strings.StringUtil; +import org.jabref.model.util.DummyFileUpdateMonitor; import org.jabref.preferences.SearchPreferences; import com.google.common.base.Throwables; @@ -83,7 +84,7 @@ private static Optional importToOpenBase(String argument) { } private static Optional importBibtexToOpenBase(String argument) { - BibtexParser parser = new BibtexParser(Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()); + BibtexParser parser = new BibtexParser(Globals.prefs.getImportFormatPreferences(), new DummyFileUpdateMonitor()); try { List entries = parser.parseEntries(argument); ParserResult result = new ParserResult(entries); @@ -143,7 +144,7 @@ private static Optional importFile(Path file, String importFormat) // * means "guess the format": System.out.println(Localization.lang("Importing in unknown format") + ": " + file); - ImportFormatReader.UnknownFormatImport importResult = Globals.IMPORT_FORMAT_READER.importUnknownFormat(file, Globals.getFileUpdateMonitor()); + ImportFormatReader.UnknownFormatImport importResult = Globals.IMPORT_FORMAT_READER.importUnknownFormat(file, new DummyFileUpdateMonitor()); System.out.println(Localization.lang("Format used") + ": " + importResult.format); return Optional.of(importResult.parserResult); @@ -273,7 +274,7 @@ private boolean exportMatches(List loaded) { // export new database Optional exporter = Globals.exportFactory.getExporterByName(formatName); - if (!exporter.isPresent()) { + if (exporter.isEmpty()) { System.err.println(Localization.lang("Unknown export format") + ": " + formatName); } else { // We have an TemplateExporter instance: @@ -387,7 +388,7 @@ private boolean generateAux(List loaded, String[] data) { private void saveDatabase(BibDatabase newBase, String subName) { try { System.out.println(Localization.lang("Saving") + ": " + subName); - SavePreferences prefs = Globals.prefs.loadForSaveFromPreferences(); + SavePreferences prefs = Globals.prefs.getSavePreferences(); AtomicFileWriter fileWriter = new AtomicFileWriter(Path.of(subName), prefs.getEncoding()); BibDatabaseWriter databaseWriter = new BibtexDatabaseWriter(fileWriter, prefs, Globals.entryTypesManager); databaseWriter.saveDatabase(new BibDatabaseContext(newBase)); @@ -435,7 +436,7 @@ private void exportFile(List loaded, String[] data) { .getFileDirectories(Globals.prefs.getFilePreferences()); System.out.println(Localization.lang("Exporting") + ": " + data[0]); Optional exporter = Globals.exportFactory.getExporterByName(data[1]); - if (!exporter.isPresent()) { + if (exporter.isEmpty()) { System.err.println(Localization.lang("Unknown export format") + ": " + data[1]); } else { // We have an exporter: @@ -458,10 +459,10 @@ private void importPreferences() { Globals.entryTypesManager.addCustomOrModifiedTypes(Globals.prefs.loadBibEntryTypes(BibDatabaseMode.BIBTEX), Globals.prefs.loadBibEntryTypes(BibDatabaseMode.BIBLATEX)); List customExporters = Globals.prefs.getCustomExportFormats(Globals.journalAbbreviationRepository); - LayoutFormatterPreferences layoutPreferences = Globals.prefs - .getLayoutFormatterPreferences(Globals.journalAbbreviationRepository); - SavePreferences savePreferences = Globals.prefs.loadForExportFromPreferences(); - XmpPreferences xmpPreferences = Globals.prefs.getXMPPreferences(); + LayoutFormatterPreferences layoutPreferences = + Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository); + SavePreferences savePreferences = Globals.prefs.getSavePreferencesForExport(); + XmpPreferences xmpPreferences = Globals.prefs.getXmpPreferences(); Globals.exportFactory = ExporterFactory.create(customExporters, layoutPreferences, savePreferences, xmpPreferences); } catch (JabRefException ex) { LOGGER.error("Cannot import preferences", ex); @@ -495,7 +496,11 @@ private void automaticallySetFileLinks(List loaded) { for (ParserResult parserResult : loaded) { BibDatabase database = parserResult.getDatabase(); LOGGER.info(Localization.lang("Automatically setting file links")); - AutoSetFileLinksUtil util = new AutoSetFileLinksUtil(parserResult.getDatabaseContext(), Globals.prefs.getFilePreferences(), Globals.prefs.getAutoLinkPreferences(), ExternalFileTypes.getInstance()); + AutoSetFileLinksUtil util = new AutoSetFileLinksUtil( + parserResult.getDatabaseContext(), + Globals.prefs.getFilePreferences(), + Globals.prefs.getAutoLinkPreferences(), + ExternalFileTypes.getInstance()); util.linkAssociatedFiles(database.getEntries(), new NamedCompound("")); } } @@ -534,7 +539,7 @@ private Optional fetch(String fetchCommand) { Optional selectedFetcher = fetchers.stream() .filter(fetcher -> fetcher.getName().equalsIgnoreCase(engine)) .findFirst(); - if (!selectedFetcher.isPresent()) { + if (selectedFetcher.isEmpty()) { System.out.println(Localization.lang("Could not find fetcher '%0'", engine)); System.out.println(Localization.lang("The following fetchers are available:")); diff --git a/src/main/java/org/jabref/cli/AuxCommandLine.java b/src/main/java/org/jabref/cli/AuxCommandLine.java index 00cb424fb54..61f4c133008 100644 --- a/src/main/java/org/jabref/cli/AuxCommandLine.java +++ b/src/main/java/org/jabref/cli/AuxCommandLine.java @@ -3,9 +3,9 @@ import java.nio.file.Path; import org.jabref.gui.auximport.AuxParserResultViewModel; +import org.jabref.logic.auxparser.AuxParser; +import org.jabref.logic.auxparser.AuxParserResult; import org.jabref.logic.auxparser.DefaultAuxParser; -import org.jabref.model.auxparser.AuxParser; -import org.jabref.model.auxparser.AuxParserResult; import org.jabref.model.database.BibDatabase; import org.jabref.model.strings.StringUtil; diff --git a/src/main/java/org/jabref/cli/CrossrefFetcherEvaluator.java b/src/main/java/org/jabref/cli/CrossrefFetcherEvaluator.java index 6db58af18c0..207f523753c 100644 --- a/src/main/java/org/jabref/cli/CrossrefFetcherEvaluator.java +++ b/src/main/java/org/jabref/cli/CrossrefFetcherEvaluator.java @@ -9,7 +9,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; -import org.jabref.Globals; +import org.jabref.gui.Globals; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.fetcher.CrossRef; diff --git a/src/main/java/org/jabref/cli/JabRefCLI.java b/src/main/java/org/jabref/cli/JabRefCLI.java index f9b0b4d4cbf..e9d26874b00 100644 --- a/src/main/java/org/jabref/cli/JabRefCLI.java +++ b/src/main/java/org/jabref/cli/JabRefCLI.java @@ -2,7 +2,7 @@ import java.util.List; -import org.jabref.Globals; +import org.jabref.gui.Globals; import org.jabref.logic.l10n.Localization; import org.apache.commons.cli.CommandLine; diff --git a/src/main/java/org/jabref/gui/Base.css b/src/main/java/org/jabref/gui/Base.css index 1b9dee1176b..2ad2009d218 100644 --- a/src/main/java/org/jabref/gui/Base.css +++ b/src/main/java/org/jabref/gui/Base.css @@ -1173,3 +1173,18 @@ We want to have a look that matches our icons in the tool-bar */ TextFlow * { -fx-fill: -fx-text-background-color; } + +.chips-pane > .editor { + -fx-pref-height: 30px; + -fx-padding: 0px 0px 0px -8px; + -fx-margin: 0em; +} + +.searchBar:invalid { + -fx-background-color: rgba(240, 128, 128, 0.5); +} + +.searchBar:unsupported { + -fx-background-color: rgba(255, 159, 67, 0.5); + +} diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index eacb550283a..e98e641a73b 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -12,7 +12,6 @@ import javafx.scene.control.SplitPane; import javafx.scene.layout.StackPane; -import org.jabref.Globals; import org.jabref.gui.autocompleter.AutoCompletePreferences; import org.jabref.gui.autocompleter.PersonNameSuggestionProvider; import org.jabref.gui.autocompleter.SuggestionProviders; @@ -33,6 +32,7 @@ import org.jabref.logic.l10n.Localization; import org.jabref.logic.pdf.FileAnnotationCache; import org.jabref.logic.search.SearchQuery; +import org.jabref.logic.shared.DatabaseLocation; import org.jabref.logic.util.UpdateField; import org.jabref.model.FieldChange; import org.jabref.model.database.BibDatabase; @@ -40,7 +40,6 @@ import org.jabref.model.database.event.BibDatabaseContextChangedEvent; import org.jabref.model.database.event.EntriesAddedEvent; import org.jabref.model.database.event.EntriesRemovedEvent; -import org.jabref.model.database.shared.DatabaseLocation; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.event.EntriesEventSource; import org.jabref.model.entry.event.EntryChangedEvent; @@ -120,8 +119,6 @@ public BasePanel(JabRefFrame frame, BasePanelPreferences preferences, BibDatabas this.getDatabase().registerListener(new UpdateTimestampListener(Globals.prefs)); this.entryEditor = new EntryEditor(this, externalFileTypes); - // Open entry editor for first entry on start up. - Platform.runLater(this::clearAndSelectFirst); } @Subscribe @@ -614,7 +611,7 @@ public void copy() { } public void paste() { - mainTable.paste(); + mainTable.paste(this.bibDatabaseContext.getMode()); } public void cut() { diff --git a/src/main/java/org/jabref/gui/BasePanelPreferences.java b/src/main/java/org/jabref/gui/BasePanelPreferences.java index 595bfc81740..bc95224afa6 100644 --- a/src/main/java/org/jabref/gui/BasePanelPreferences.java +++ b/src/main/java/org/jabref/gui/BasePanelPreferences.java @@ -3,7 +3,6 @@ import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; -import org.jabref.Globals; import org.jabref.gui.autocompleter.AutoCompletePreferences; import org.jabref.gui.entryeditor.EntryEditorPreferences; import org.jabref.gui.keyboard.KeyBindingRepository; diff --git a/src/main/java/org/jabref/gui/ClipBoardManager.java b/src/main/java/org/jabref/gui/ClipBoardManager.java index ba680353434..78f9e7aa39a 100644 --- a/src/main/java/org/jabref/gui/ClipBoardManager.java +++ b/src/main/java/org/jabref/gui/ClipBoardManager.java @@ -19,7 +19,7 @@ import javafx.scene.input.DataFormat; import javafx.scene.input.MouseButton; -import org.jabref.Globals; +import org.jabref.architecture.AllowedToUseAwt; import org.jabref.logic.bibtex.BibEntryWriter; import org.jabref.logic.bibtex.FieldWriter; import org.jabref.logic.importer.FetcherException; @@ -37,6 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@AllowedToUseAwt("Requires ava.awt.datatransfer.Clipboard") public class ClipBoardManager { public static final DataFormat XML = new DataFormat("application/xml"); diff --git a/src/main/java/org/jabref/gui/DefaultInjector.java b/src/main/java/org/jabref/gui/DefaultInjector.java index b485c9db34b..aefc1b4f232 100644 --- a/src/main/java/org/jabref/gui/DefaultInjector.java +++ b/src/main/java/org/jabref/gui/DefaultInjector.java @@ -4,8 +4,6 @@ import javax.swing.undo.UndoManager; -import org.jabref.Globals; -import org.jabref.JabRefGUI; import org.jabref.gui.keyboard.KeyBindingRepository; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.journals.JournalAbbreviationRepository; diff --git a/src/main/java/org/jabref/gui/EntryTypeView.java b/src/main/java/org/jabref/gui/EntryTypeView.java index 2de294e1ce1..f304238b688 100644 --- a/src/main/java/org/jabref/gui/EntryTypeView.java +++ b/src/main/java/org/jabref/gui/EntryTypeView.java @@ -18,7 +18,6 @@ import javafx.scene.layout.FlowPane; import javafx.stage.Screen; -import org.jabref.Globals; import org.jabref.gui.util.BaseDialog; import org.jabref.gui.util.ControlHelper; import org.jabref.gui.util.IconValidationDecorator; diff --git a/src/main/java/org/jabref/gui/EntryTypeViewModel.java b/src/main/java/org/jabref/gui/EntryTypeViewModel.java index 2326c66cf7e..926ad996e08 100644 --- a/src/main/java/org/jabref/gui/EntryTypeViewModel.java +++ b/src/main/java/org/jabref/gui/EntryTypeViewModel.java @@ -14,12 +14,12 @@ import javafx.concurrent.Task; import javafx.concurrent.Worker; -import org.jabref.Globals; import org.jabref.gui.duplicationFinder.DuplicateResolverDialog; -import org.jabref.logic.bibtex.DuplicateCheck; import org.jabref.logic.citationkeypattern.CitationKeyGenerator; +import org.jabref.logic.database.DuplicateCheck; import org.jabref.logic.importer.FetcherException; import org.jabref.logic.importer.IdBasedFetcher; +import org.jabref.logic.importer.ImportCleanup; import org.jabref.logic.importer.WebFetchers; import org.jabref.logic.importer.fetcher.DoiFetcher; import org.jabref.logic.l10n.Localization; @@ -147,6 +147,8 @@ public void runFetcherWorker() { Optional result = fetcherWorker.getValue(); if (result.isPresent()) { final BibEntry entry = result.get(); + ImportCleanup cleanup = new ImportCleanup(basePanel.getBibDatabaseContext().getMode()); + cleanup.doPostCleanup(entry); Optional duplicate = new DuplicateCheck(Globals.entryTypesManager).containsDuplicate(basePanel.getDatabase(), entry, basePanel.getBibDatabaseContext().getMode()); if ((duplicate.isPresent())) { DuplicateResolverDialog dialog = new DuplicateResolverDialog(entry, duplicate.get(), DuplicateResolverDialog.DuplicateResolverType.IMPORT_CHECK, basePanel.getBibDatabaseContext(), stateManager); diff --git a/src/main/java/org/jabref/gui/FXDialog.java b/src/main/java/org/jabref/gui/FXDialog.java index f0d071ae74f..f1c93adbdee 100644 --- a/src/main/java/org/jabref/gui/FXDialog.java +++ b/src/main/java/org/jabref/gui/FXDialog.java @@ -8,7 +8,6 @@ import javafx.stage.Modality; import javafx.stage.Stage; -import org.jabref.Globals; import org.jabref.gui.icon.IconTheme; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.keyboard.KeyBindingRepository; diff --git a/src/main/java/org/jabref/FallbackExceptionHandler.java b/src/main/java/org/jabref/gui/FallbackExceptionHandler.java similarity index 97% rename from src/main/java/org/jabref/FallbackExceptionHandler.java rename to src/main/java/org/jabref/gui/FallbackExceptionHandler.java index 0c0a4cb4391..b053a5f9be2 100644 --- a/src/main/java/org/jabref/FallbackExceptionHandler.java +++ b/src/main/java/org/jabref/gui/FallbackExceptionHandler.java @@ -1,4 +1,4 @@ -package org.jabref; +package org.jabref.gui; import org.jabref.gui.util.DefaultTaskExecutor; diff --git a/src/main/java/org/jabref/Globals.java b/src/main/java/org/jabref/gui/Globals.java similarity index 97% rename from src/main/java/org/jabref/Globals.java rename to src/main/java/org/jabref/gui/Globals.java index 8663a282b13..db851799580 100644 --- a/src/main/java/org/jabref/Globals.java +++ b/src/main/java/org/jabref/gui/Globals.java @@ -1,4 +1,4 @@ -package org.jabref; +package org.jabref.gui; import java.awt.GraphicsEnvironment; import java.util.Optional; @@ -6,8 +6,7 @@ import javafx.stage.Screen; -import org.jabref.gui.ClipBoardManager; -import org.jabref.gui.StateManager; +import org.jabref.architecture.AllowedToUseAwt; import org.jabref.gui.keyboard.KeyBindingRepository; import org.jabref.gui.undo.CountingUndoManager; import org.jabref.gui.util.DefaultFileUpdateMonitor; @@ -33,6 +32,7 @@ * @deprecated try to use {@link StateManager} and {@link org.jabref.preferences.PreferencesService} */ @Deprecated +@AllowedToUseAwt("Requires AWT for headless check") public class Globals { /** @@ -131,6 +131,7 @@ public static FileUpdateMonitor getFileUpdateMonitor() { public static void shutdownThreadPools() { TASK_EXECUTOR.shutdown(); + fileUpdateMonitor.shutdown(); JabRefExecutorService.INSTANCE.shutdownEverything(); } diff --git a/src/main/java/org/jabref/JabRefExecutorService.java b/src/main/java/org/jabref/gui/JabRefExecutorService.java similarity index 77% rename from src/main/java/org/jabref/JabRefExecutorService.java rename to src/main/java/org/jabref/gui/JabRefExecutorService.java index a90668d9bd2..f60285e46ff 100644 --- a/src/main/java/org/jabref/JabRefExecutorService.java +++ b/src/main/java/org/jabref/gui/JabRefExecutorService.java @@ -1,4 +1,4 @@ -package org.jabref; +package org.jabref.gui; import java.util.Collection; import java.util.Collections; @@ -22,24 +22,29 @@ public class JabRefExecutorService { public static final JabRefExecutorService INSTANCE = new JabRefExecutorService(); + private static final Logger LOGGER = LoggerFactory.getLogger(JabRefExecutorService.class); + private final ExecutorService executorService = Executors.newCachedThreadPool(r -> { Thread thread = new Thread(r); thread.setName("JabRef CachedThreadPool"); thread.setUncaughtExceptionHandler(new FallbackExceptionHandler()); return thread; }); + private final ExecutorService lowPriorityExecutorService = Executors.newCachedThreadPool(r -> { Thread thread = new Thread(r); thread.setName("JabRef LowPriorityCachedThreadPool"); thread.setUncaughtExceptionHandler(new FallbackExceptionHandler()); return thread; }); + private final Timer timer = new Timer("timer", true); + private Thread remoteThread; private JabRefExecutorService() { - } + } public void execute(Runnable command) { Objects.requireNonNull(command); @@ -132,13 +137,16 @@ public void submit(TimerTask timerTask, long millisecondsDelay) { timer.schedule(timerTask, millisecondsDelay); } + /** + * Shuts everything down. After termination, this method returns. + */ public void shutdownEverything() { - // those threads will be allowed to finish - this.executorService.shutdown(); - // those threads will be interrupted in their current task - this.lowPriorityExecutorService.shutdownNow(); // kill the remote thread stopRemoteThread(); + + gracefullyShutdown(this.executorService); + gracefullyShutdown(this.lowPriorityExecutorService); + timer.cancel(); } @@ -164,4 +172,28 @@ public void run() { } } } + + /** + * Shuts down the provided executor service by first trying a normal shutdown, then waiting for the shutdown and then forcibly shutting it down. + * Returns if the status of the shut down is known. + */ + public static void gracefullyShutdown(ExecutorService executorService) { + try { + // This is non-blocking. See https://stackoverflow.com/a/57383461/873282. + executorService.shutdown(); + if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) { + LOGGER.debug("One minute passed, {} still not completed. Trying forced shutdown.", executorService.toString()); + // those threads will be interrupted in their current task + executorService.shutdownNow(); + if (executorService.awaitTermination(60, TimeUnit.SECONDS)) { + LOGGER.debug("One minute passed again - forced shutdown of {} worked.", executorService.toString()); + } else { + LOGGER.error("{} did not terminate", executorService.toString()); + } + } + } catch (InterruptedException ie) { + executorService.shutdownNow(); + Thread.currentThread().interrupt(); + } + } } diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index a7590558a1c..3fcbca23310 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -46,8 +46,6 @@ import javafx.scene.shape.Rectangle; import javafx.stage.Stage; -import org.jabref.Globals; -import org.jabref.JabRefExecutorService; import org.jabref.gui.actions.ActionFactory; import org.jabref.gui.actions.ActionHelper; import org.jabref.gui.actions.SimpleCommand; @@ -125,16 +123,17 @@ import org.jabref.logic.autosaveandbackup.BackupManager; import org.jabref.logic.citationstyle.CitationStyleOutputFormat; import org.jabref.logic.importer.IdFetcher; +import org.jabref.logic.importer.ImportCleanup; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.WebFetchers; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.shared.DatabaseLocation; import org.jabref.logic.undo.AddUndoableActionEvent; import org.jabref.logic.undo.UndoChangeEvent; import org.jabref.logic.undo.UndoRedoEvent; import org.jabref.logic.util.OS; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.database.BibDatabaseContext; -import org.jabref.model.database.shared.DatabaseLocation; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.SpecialField; import org.jabref.model.entry.field.StandardField; @@ -218,9 +217,7 @@ private void initDragAndDrop() { } }); - this.getScene().setOnDragExited(event -> { - tabbedPane.getTabs().remove(dndIndicator); - }); + this.getScene().setOnDragExited(event -> tabbedPane.getTabs().remove(dndIndicator)); this.getScene().setOnDragDropped(event -> { tabbedPane.getTabs().remove(dndIndicator); @@ -792,7 +789,7 @@ private MenuBar createMenu() { factory.createMenuItem(StandardActions.MASS_SET_FIELDS, new MassSetFieldsAction(stateManager, dialogService, undoManager)) ); - if (Globals.prefs.getBoolean(JabRefPreferences.SPECIALFIELDSENABLED)) { + if (Globals.prefs.getSpecialFieldsPreferences().isSpecialFieldsEnabled()) { edit.getItems().addAll( new SeparatorMenuItem(), // ToDo: SpecialField needs the active BasePanel to mark it as changed. @@ -1033,7 +1030,7 @@ public void addParserResult(ParserResult parserResult, boolean focusPanel) { } else { // only add tab if DB is not already open Optional panel = getBasePanelList().stream() - .filter(p -> p.getBibDatabaseContext().getDatabasePath().equals(parserResult.getFile())) + .filter(p -> p.getBibDatabaseContext().getDatabasePath().equals(parserResult.getPath())) .findFirst(); if (panel.isPresent()) { @@ -1092,7 +1089,7 @@ public void updateAllTabTitles() { Optional file = getBasePanelAt(i).getBibDatabaseContext().getDatabasePath(); if (file.isPresent()) { - if (!uniqPath.equals(file.get().getFileName()) && uniqPath.contains(File.separator)) { + if (!uniqPath.equals(file.get().getFileName().toString()) && uniqPath.contains(File.separator)) { // remove filename uniqPath = uniqPath.substring(0, uniqPath.lastIndexOf(File.separator)); tabbedPane.getTabs().get(i).setText(getBasePanelAt(i).getTabTitle() + " \u2014 " + uniqPath); @@ -1189,6 +1186,8 @@ private boolean readyForAutosave(BibDatabaseContext context) { */ private void addImportedEntries(final BasePanel panel, final ParserResult parserResult) { BackgroundTask task = BackgroundTask.wrap(() -> parserResult); + ImportCleanup cleanup = new ImportCleanup(panel.getBibDatabaseContext().getMode()); + cleanup.doPostCleanup(parserResult.getDatabase().getEntries()); ImportEntriesDialog dialog = new ImportEntriesDialog(panel.getBibDatabaseContext(), task); dialog.setTitle(Localization.lang("Import")); dialog.showAndWait(); diff --git a/src/main/java/org/jabref/JabRefGUI.java b/src/main/java/org/jabref/gui/JabRefGUI.java similarity index 98% rename from src/main/java/org/jabref/JabRefGUI.java rename to src/main/java/org/jabref/gui/JabRefGUI.java index fd228609a3d..4cdbb7850fa 100644 --- a/src/main/java/org/jabref/JabRefGUI.java +++ b/src/main/java/org/jabref/gui/JabRefGUI.java @@ -1,4 +1,4 @@ -package org.jabref; +package org.jabref.gui; import java.io.File; import java.sql.SQLException; @@ -11,8 +11,6 @@ import javafx.stage.Screen; import javafx.stage.Stage; -import org.jabref.gui.BasePanel; -import org.jabref.gui.JabRefFrame; import org.jabref.gui.dialogs.BackupUIManager; import org.jabref.gui.help.VersionWorker; import org.jabref.gui.icon.IconTheme; @@ -23,9 +21,9 @@ import org.jabref.logic.importer.OpenDatabase; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.shared.DatabaseNotSupportedException; import org.jabref.logic.shared.exception.InvalidDBMSConnectionPropertiesException; import org.jabref.logic.shared.exception.NotASharedDatabaseException; -import org.jabref.model.database.shared.DatabaseNotSupportedException; import org.jabref.preferences.JabRefPreferences; import impl.org.controlsfx.skin.DecorationPane; diff --git a/src/main/java/org/jabref/JabRefLauncher.java b/src/main/java/org/jabref/gui/JabRefLauncher.java similarity index 91% rename from src/main/java/org/jabref/JabRefLauncher.java rename to src/main/java/org/jabref/gui/JabRefLauncher.java index f5e5ba0e3c0..67a1a1803b5 100644 --- a/src/main/java/org/jabref/JabRefLauncher.java +++ b/src/main/java/org/jabref/gui/JabRefLauncher.java @@ -1,4 +1,4 @@ -package org.jabref; +package org.jabref.gui; /** * JabRef launcher: This just starts JabRefMain. It is there because to have the name consistent to other Java applications. diff --git a/src/main/java/org/jabref/JabRefMain.java b/src/main/java/org/jabref/gui/JabRefMain.java similarity index 94% rename from src/main/java/org/jabref/JabRefMain.java rename to src/main/java/org/jabref/gui/JabRefMain.java index e004d0e1627..826c561587f 100644 --- a/src/main/java/org/jabref/JabRefMain.java +++ b/src/main/java/org/jabref/gui/JabRefMain.java @@ -1,4 +1,4 @@ -package org.jabref; +package org.jabref.gui; import java.net.Authenticator; @@ -9,8 +9,8 @@ import org.jabref.cli.ArgumentProcessor; import org.jabref.cli.JabRefCLI; -import org.jabref.gui.FXDialog; import org.jabref.gui.remote.JabRefMessageHandler; +import org.jabref.logic.exporter.ExporterFactory; import org.jabref.logic.journals.JournalAbbreviationLoader; import org.jabref.logic.l10n.Localization; import org.jabref.logic.net.ProxyAuthenticator; @@ -165,10 +165,14 @@ private static void applyPreferences(JabRefPreferences preferences) { // Build list of Import and Export formats Globals.IMPORT_FORMAT_READER.resetImportFormats(Globals.prefs.getImportFormatPreferences(), - Globals.prefs.getXMPPreferences(), Globals.getFileUpdateMonitor()); + Globals.prefs.getXmpPreferences(), Globals.getFileUpdateMonitor()); Globals.entryTypesManager.addCustomOrModifiedTypes(preferences.loadBibEntryTypes(BibDatabaseMode.BIBTEX), preferences.loadBibEntryTypes(BibDatabaseMode.BIBLATEX)); - Globals.exportFactory = Globals.prefs.getExporterFactory(Globals.journalAbbreviationRepository); + Globals.exportFactory = ExporterFactory.create( + Globals.prefs.getCustomExportFormats(Globals.journalAbbreviationRepository), + Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository), + Globals.prefs.getSavePreferencesForExport(), + Globals.prefs.getXmpPreferences()); // Initialize protected terms loader Globals.protectedTermsLoader = new ProtectedTermsLoader(Globals.prefs.getProtectedTermsPreferences()); diff --git a/src/main/java/org/jabref/gui/SendAsEMailAction.java b/src/main/java/org/jabref/gui/SendAsEMailAction.java index 15118bea93d..2ba19e6798f 100644 --- a/src/main/java/org/jabref/gui/SendAsEMailAction.java +++ b/src/main/java/org/jabref/gui/SendAsEMailAction.java @@ -8,7 +8,7 @@ import java.util.ArrayList; import java.util.List; -import org.jabref.Globals; +import org.jabref.architecture.AllowedToUseAwt; import org.jabref.gui.actions.ActionHelper; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.desktop.JabRefDesktop; @@ -34,6 +34,7 @@ * are opened. This feature is disabled by default and can be switched on at * preferences/external programs */ +@AllowedToUseAwt("Requires AWT to send an email") public class SendAsEMailAction extends SimpleCommand { private static final Logger LOGGER = LoggerFactory.getLogger(SendAsEMailAction.class); diff --git a/src/main/java/org/jabref/gui/SidePaneManager.java b/src/main/java/org/jabref/gui/SidePaneManager.java index 55b55d4f795..472589044e3 100644 --- a/src/main/java/org/jabref/gui/SidePaneManager.java +++ b/src/main/java/org/jabref/gui/SidePaneManager.java @@ -7,7 +7,6 @@ import java.util.Map; import java.util.stream.Stream; -import org.jabref.Globals; import org.jabref.gui.groups.GroupSidePane; import org.jabref.gui.importer.fetcher.WebSearchPane; import org.jabref.gui.openoffice.OpenOfficeSidePanel; diff --git a/src/main/java/org/jabref/gui/actions/JabRefAction.java b/src/main/java/org/jabref/gui/actions/JabRefAction.java index c017c979e06..5d1fbd10e28 100644 --- a/src/main/java/org/jabref/gui/actions/JabRefAction.java +++ b/src/main/java/org/jabref/gui/actions/JabRefAction.java @@ -5,7 +5,7 @@ import javafx.beans.binding.Bindings; -import org.jabref.Globals; +import org.jabref.gui.Globals; import org.jabref.gui.keyboard.KeyBindingRepository; import de.saxsys.mvvmfx.utils.commands.Command; diff --git a/src/main/java/org/jabref/gui/autocompleter/BibEntrySuggestionProvider.java b/src/main/java/org/jabref/gui/autocompleter/BibEntrySuggestionProvider.java index 3cf297c71c1..a69b8a3b1c1 100644 --- a/src/main/java/org/jabref/gui/autocompleter/BibEntrySuggestionProvider.java +++ b/src/main/java/org/jabref/gui/autocompleter/BibEntrySuggestionProvider.java @@ -13,7 +13,7 @@ import org.controlsfx.control.textfield.AutoCompletionBinding; /** - * Delivers possible completions as a list of {@link BibEntry} based on their cite key. + * Delivers possible completions as a list of {@link BibEntry} based on their citation key. */ public class BibEntrySuggestionProvider extends SuggestionProvider { @@ -25,7 +25,7 @@ public BibEntrySuggestionProvider(BibDatabase database) { @Override protected Equivalence getEquivalence() { - return Equivalence.equals().onResultOf(BibEntry::getCiteKeyOptional); + return Equivalence.equals().onResultOf(BibEntry::getCitationKey); } @Override @@ -36,7 +36,7 @@ protected Comparator getComparator() { @Override protected boolean isMatch(BibEntry entry, AutoCompletionBinding.ISuggestionRequest request) { String userText = request.getUserText(); - return entry.getCiteKeyOptional() + return entry.getCitationKey() .map(key -> StringUtil.containsIgnoreCase(key, userText)) .orElse(false); } diff --git a/src/main/java/org/jabref/gui/autocompleter/ContentSelectorSuggestionProvider.java b/src/main/java/org/jabref/gui/autocompleter/ContentSelectorSuggestionProvider.java index dc2299fa685..01e56ff5350 100644 --- a/src/main/java/org/jabref/gui/autocompleter/ContentSelectorSuggestionProvider.java +++ b/src/main/java/org/jabref/gui/autocompleter/ContentSelectorSuggestionProvider.java @@ -1,5 +1,7 @@ package org.jabref.gui.autocompleter; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.stream.Stream; @@ -22,4 +24,14 @@ public ContentSelectorSuggestionProvider(SuggestionProvider suggestionPr public Stream getSource() { return Stream.concat(contentSelectorValues.stream(), suggestionProvider.getSource()); } + + @Override + public Collection getPossibleSuggestions() { + List suggestions = new ArrayList<>(); + if (suggestionProvider != null) { + suggestions.addAll(suggestionProvider.getPossibleSuggestions()); + } + suggestions.addAll(contentSelectorValues); + return suggestions; + } } diff --git a/src/main/java/org/jabref/gui/autocompleter/SuggestionProvider.java b/src/main/java/org/jabref/gui/autocompleter/SuggestionProvider.java index 8d6bba4633a..341c9ef8f5e 100644 --- a/src/main/java/org/jabref/gui/autocompleter/SuggestionProvider.java +++ b/src/main/java/org/jabref/gui/autocompleter/SuggestionProvider.java @@ -60,6 +60,16 @@ public final Collection provideSuggestions(ISuggestionRequest request) { protected abstract Equivalence getEquivalence(); + public Collection getPossibleSuggestions() { + Comparator comparator = getComparator().reversed(); + Equivalence equivalence = getEquivalence(); + return getSource().map(equivalence::wrap) // Need to do a bit of acrobatic as there is no distinctBy method + .distinct() + .map(Equivalence.Wrapper::get) + .sorted(comparator) + .collect(Collectors.toList()); + } + /** * Get the comparator to order the suggestions */ diff --git a/src/main/java/org/jabref/gui/autocompleter/SuggestionProviders.java b/src/main/java/org/jabref/gui/autocompleter/SuggestionProviders.java index 1d4a039735f..47e1309fc1c 100644 --- a/src/main/java/org/jabref/gui/autocompleter/SuggestionProviders.java +++ b/src/main/java/org/jabref/gui/autocompleter/SuggestionProviders.java @@ -32,10 +32,9 @@ public SuggestionProvider getForField(Field field) { Set fieldProperties = field.getProperties(); if (fieldProperties.contains(FieldProperty.PERSON_NAMES)) { return new PersonNameSuggestionProvider(field, database); - } else if (fieldProperties.contains(FieldProperty.SINGLE_ENTRY_LINK)) { + } else if (fieldProperties.contains(FieldProperty.SINGLE_ENTRY_LINK) || fieldProperties.contains(FieldProperty.MULTIPLE_ENTRY_LINK)) { return new BibEntrySuggestionProvider(database); - } else if (fieldProperties.contains(FieldProperty.JOURNAL_NAME) - || StandardField.PUBLISHER.equals(field)) { + } else if (fieldProperties.contains(FieldProperty.JOURNAL_NAME) || StandardField.PUBLISHER.equals(field)) { return new JournalsSuggestionProvider(field, database, abbreviationRepository); } else { return new WordSuggestionProvider(field, database); diff --git a/src/main/java/org/jabref/gui/auximport/AuxParserResultViewModel.java b/src/main/java/org/jabref/gui/auximport/AuxParserResultViewModel.java index e30753c8542..d565151eb71 100644 --- a/src/main/java/org/jabref/gui/auximport/AuxParserResultViewModel.java +++ b/src/main/java/org/jabref/gui/auximport/AuxParserResultViewModel.java @@ -1,7 +1,7 @@ package org.jabref.gui.auximport; +import org.jabref.logic.auxparser.AuxParserResult; import org.jabref.logic.l10n.Localization; -import org.jabref.model.auxparser.AuxParserResult; public class AuxParserResultViewModel { diff --git a/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java b/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java index ccbf6c53c29..518b09efc2b 100644 --- a/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java +++ b/src/main/java/org/jabref/gui/auximport/FromAuxDialog.java @@ -16,11 +16,11 @@ import org.jabref.gui.JabRefFrame; import org.jabref.gui.util.BaseDialog; import org.jabref.gui.util.FileDialogConfiguration; +import org.jabref.logic.auxparser.AuxParser; +import org.jabref.logic.auxparser.AuxParserResult; import org.jabref.logic.auxparser.DefaultAuxParser; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.StandardFileType; -import org.jabref.model.auxparser.AuxParser; -import org.jabref.model.auxparser.AuxParserResult; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; import org.jabref.preferences.PreferencesService; diff --git a/src/main/java/org/jabref/gui/bibtexextractor/BibtexExtractorViewModel.java b/src/main/java/org/jabref/gui/bibtexextractor/BibtexExtractorViewModel.java index 1bf6ea2cd46..a7181ba3ae1 100644 --- a/src/main/java/org/jabref/gui/bibtexextractor/BibtexExtractorViewModel.java +++ b/src/main/java/org/jabref/gui/bibtexextractor/BibtexExtractorViewModel.java @@ -8,8 +8,8 @@ import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.StateManager; import org.jabref.gui.externalfiles.ImportHandler; import org.jabref.gui.externalfiletype.ExternalFileTypes; diff --git a/src/main/java/org/jabref/gui/citationkeypattern/CitationKeyPatternDialog.java b/src/main/java/org/jabref/gui/citationkeypattern/CitationKeyPatternDialog.java index e051ff2dcbb..4b33b9de97b 100644 --- a/src/main/java/org/jabref/gui/citationkeypattern/CitationKeyPatternDialog.java +++ b/src/main/java/org/jabref/gui/citationkeypattern/CitationKeyPatternDialog.java @@ -2,11 +2,11 @@ import javafx.scene.control.ButtonType; -import org.jabref.Globals; import org.jabref.gui.BasePanel; +import org.jabref.gui.Globals; import org.jabref.gui.util.BaseDialog; +import org.jabref.logic.citationkeypattern.AbstractCitationKeyPattern; import org.jabref.logic.l10n.Localization; -import org.jabref.model.bibtexkeypattern.AbstractCitationKeyPattern; import org.jabref.model.metadata.MetaData; public class CitationKeyPatternDialog extends BaseDialog { diff --git a/src/main/java/org/jabref/gui/citationkeypattern/CitationKeyPatternPanel.java b/src/main/java/org/jabref/gui/citationkeypattern/CitationKeyPatternPanel.java index c9114dc89dd..56f98b88e26 100644 --- a/src/main/java/org/jabref/gui/citationkeypattern/CitationKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/citationkeypattern/CitationKeyPatternPanel.java @@ -10,15 +10,15 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; -import org.jabref.Globals; import org.jabref.gui.BasePanel; +import org.jabref.gui.Globals; import org.jabref.gui.actions.ActionFactory; import org.jabref.gui.actions.StandardActions; import org.jabref.gui.help.HelpAction; +import org.jabref.logic.citationkeypattern.AbstractCitationKeyPattern; +import org.jabref.logic.citationkeypattern.DatabaseCitationKeyPattern; import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; -import org.jabref.model.bibtexkeypattern.AbstractCitationKeyPattern; -import org.jabref.model.bibtexkeypattern.DatabaseCitationKeyPattern; import org.jabref.model.database.BibDatabaseMode; import org.jabref.model.entry.BibEntryType; import org.jabref.model.entry.types.EntryType; diff --git a/src/main/java/org/jabref/gui/citationkeypattern/GenerateCitationKeyAction.java b/src/main/java/org/jabref/gui/citationkeypattern/GenerateCitationKeyAction.java index 208d8216a15..4173db5cc65 100644 --- a/src/main/java/org/jabref/gui/citationkeypattern/GenerateCitationKeyAction.java +++ b/src/main/java/org/jabref/gui/citationkeypattern/GenerateCitationKeyAction.java @@ -2,8 +2,8 @@ import java.util.List; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.StateManager; import org.jabref.gui.actions.ActionHelper; @@ -68,15 +68,14 @@ public static boolean confirmOverwriteKeys(DialogService dialogService) { private void checkOverwriteKeysChosen() { // We don't want to generate keys for entries which already have one thus remove the entries if (Globals.prefs.getBoolean(JabRefPreferences.AVOID_OVERWRITING_KEY)) { - entries.removeIf(BibEntry::hasCiteKey); - // if we're going to override some cite keys warn the user about it - } else if (entries.parallelStream().anyMatch(BibEntry::hasCiteKey)) { + entries.removeIf(BibEntry::hasCitationKey); + // if we're going to override some citation keys warn the user about it + } else if (entries.parallelStream().anyMatch(BibEntry::hasCitationKey)) { boolean overwriteKeys = confirmOverwriteKeys(dialogService); - // The user doesn't want to override cite keys + // The user doesn't want to override citation keys if (!overwriteKeys) { isCanceled = true; - return; } } } @@ -87,7 +86,7 @@ private void generateKeys() { } stateManager.getActiveDatabase().ifPresent(databaseContext -> { - // generate the new cite keys for each entry + // generate the new citation keys for each entry final NamedCompound compound = new NamedCompound(Localization.lang("Autogenerate citation keys")); CitationKeyGenerator keyGenerator = new CitationKeyGenerator(databaseContext, Globals.prefs.getCitationKeyPatternPreferences()); @@ -97,7 +96,7 @@ private void generateKeys() { } compound.end(); - // register the undo event only if new cite keys were generated + // register the undo event only if new citation keys were generated if (compound.hasEdits()) { frame.getUndoManager().addEdit(compound); } diff --git a/src/main/java/org/jabref/gui/citationkeypattern/GenerateCitationKeySingleAction.java b/src/main/java/org/jabref/gui/citationkeypattern/GenerateCitationKeySingleAction.java index 43e2acbe1ef..b66beef36be 100644 --- a/src/main/java/org/jabref/gui/citationkeypattern/GenerateCitationKeySingleAction.java +++ b/src/main/java/org/jabref/gui/citationkeypattern/GenerateCitationKeySingleAction.java @@ -32,7 +32,7 @@ public GenerateCitationKeySingleAction(BibEntry entry, BibDatabaseContext databa @Override public void execute() { - if (!entry.hasCiteKey() || GenerateCitationKeyAction.confirmOverwriteKeys(dialogService)) { + if (!entry.hasCitationKey() || GenerateCitationKeyAction.confirmOverwriteKeys(dialogService)) { new CitationKeyGenerator(databaseContext, preferencesService.getCitationKeyPatternPreferences()) .generateAndSetKey(entry) .ifPresent(change -> undoManager.addEdit(new UndoableKeyChange(change))); diff --git a/src/main/java/org/jabref/gui/cleanup/CleanupAction.java b/src/main/java/org/jabref/gui/cleanup/CleanupAction.java index fe59b6e3294..1fa40af1f84 100644 --- a/src/main/java/org/jabref/gui/cleanup/CleanupAction.java +++ b/src/main/java/org/jabref/gui/cleanup/CleanupAction.java @@ -3,8 +3,8 @@ import java.util.List; import java.util.Optional; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.StateManager; import org.jabref.gui.actions.ActionHelper; diff --git a/src/main/java/org/jabref/gui/cleanup/CleanupDialog.java b/src/main/java/org/jabref/gui/cleanup/CleanupDialog.java index 83d9e810b05..20d3648e940 100644 --- a/src/main/java/org/jabref/gui/cleanup/CleanupDialog.java +++ b/src/main/java/org/jabref/gui/cleanup/CleanupDialog.java @@ -6,7 +6,7 @@ import org.jabref.logic.cleanup.CleanupPreset; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; -import org.jabref.model.metadata.FilePreferences; +import org.jabref.preferences.FilePreferences; public class CleanupDialog extends BaseDialog { diff --git a/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java b/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java index 3ea9fa7c8c7..3d94fee18bc 100644 --- a/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java +++ b/src/main/java/org/jabref/gui/cleanup/CleanupPresetPanel.java @@ -14,11 +14,11 @@ import org.jabref.gui.commonfxcontrols.FieldFormatterCleanupsPanel; import org.jabref.logic.cleanup.CleanupPreset; +import org.jabref.logic.cleanup.FieldFormatterCleanups; import org.jabref.logic.l10n.Localization; -import org.jabref.model.cleanup.FieldFormatterCleanups; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.field.StandardField; -import org.jabref.model.metadata.FilePreferences; +import org.jabref.preferences.FilePreferences; import com.airhacks.afterburner.views.ViewLoader; diff --git a/src/main/java/org/jabref/gui/collab/ChangeScanner.java b/src/main/java/org/jabref/gui/collab/ChangeScanner.java index 469d5e3fd2c..f09de7c2bdd 100644 --- a/src/main/java/org/jabref/gui/collab/ChangeScanner.java +++ b/src/main/java/org/jabref/gui/collab/ChangeScanner.java @@ -5,7 +5,7 @@ import java.util.Collections; import java.util.List; -import org.jabref.Globals; +import org.jabref.gui.Globals; import org.jabref.logic.bibtex.comparator.BibDatabaseDiff; import org.jabref.logic.bibtex.comparator.BibEntryDiff; import org.jabref.logic.bibtex.comparator.BibStringDiff; diff --git a/src/main/java/org/jabref/gui/collab/DatabaseChangeMonitor.java b/src/main/java/org/jabref/gui/collab/DatabaseChangeMonitor.java index 6c1b8e2c55f..6181129601b 100644 --- a/src/main/java/org/jabref/gui/collab/DatabaseChangeMonitor.java +++ b/src/main/java/org/jabref/gui/collab/DatabaseChangeMonitor.java @@ -20,7 +20,7 @@ public class DatabaseChangeMonitor implements FileUpdateListener { private final BibDatabaseContext database; private final FileUpdateMonitor fileMonitor; private final List listeners; - private TaskExecutor taskExecutor; + private final TaskExecutor taskExecutor; public DatabaseChangeMonitor(BibDatabaseContext database, FileUpdateMonitor fileMonitor, TaskExecutor taskExecutor) { this.database = database; diff --git a/src/main/java/org/jabref/gui/collab/EntryAddChangeViewModel.java b/src/main/java/org/jabref/gui/collab/EntryAddChangeViewModel.java index ea28f4e9d1d..6e5e0d8b456 100644 --- a/src/main/java/org/jabref/gui/collab/EntryAddChangeViewModel.java +++ b/src/main/java/org/jabref/gui/collab/EntryAddChangeViewModel.java @@ -2,8 +2,8 @@ import javafx.scene.Node; -import org.jabref.Globals; -import org.jabref.JabRefGUI; +import org.jabref.gui.Globals; +import org.jabref.gui.JabRefGUI; import org.jabref.gui.preview.PreviewViewer; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableInsertEntries; @@ -17,7 +17,7 @@ class EntryAddChangeViewModel extends DatabaseChangeViewModel { public EntryAddChangeViewModel(BibEntry entry) { super(); - this.name = entry.getCiteKeyOptional() + this.name = entry.getCitationKey() .map(key -> Localization.lang("Added entry") + ": '" + key + '\'') .orElse(Localization.lang("Added entry")); this.entry = entry; diff --git a/src/main/java/org/jabref/gui/collab/EntryChangeViewModel.java b/src/main/java/org/jabref/gui/collab/EntryChangeViewModel.java index cc303b27178..bbb006da2cc 100644 --- a/src/main/java/org/jabref/gui/collab/EntryChangeViewModel.java +++ b/src/main/java/org/jabref/gui/collab/EntryChangeViewModel.java @@ -25,7 +25,7 @@ public EntryChangeViewModel(BibEntry entry, BibEntry newEntry) { this.oldEntry = entry; this.newEntry = newEntry; - name = entry.getCiteKeyOptional() + name = entry.getCitationKey() .map(key -> Localization.lang("Modified entry") + ": '" + key + '\'') .orElse(Localization.lang("Modified entry")); } diff --git a/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java b/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java index 4ffdedf3575..ff6adfd3fce 100644 --- a/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java +++ b/src/main/java/org/jabref/gui/collab/EntryDeleteChangeViewModel.java @@ -2,8 +2,8 @@ import javafx.scene.Node; -import org.jabref.Globals; -import org.jabref.JabRefGUI; +import org.jabref.gui.Globals; +import org.jabref.gui.JabRefGUI; import org.jabref.gui.preview.PreviewViewer; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableRemoveEntries; @@ -22,7 +22,7 @@ class EntryDeleteChangeViewModel extends DatabaseChangeViewModel { public EntryDeleteChangeViewModel(BibEntry entry) { super(Localization.lang("Deleted entry")); - this.name = entry.getCiteKeyOptional() + this.name = entry.getCitationKey() .map(key -> Localization.lang("Deleted entry") + ": '" + key + '\'') .orElse(Localization.lang("Deleted entry")); this.entry = entry; diff --git a/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternPanel.java b/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternPanel.java index 42b28084211..ac61606744c 100644 --- a/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternPanel.java +++ b/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternPanel.java @@ -13,11 +13,11 @@ import org.jabref.gui.icon.IconTheme; import org.jabref.gui.util.ValueTableCellFactory; +import org.jabref.logic.citationkeypattern.AbstractCitationKeyPattern; import org.jabref.logic.l10n.Localization; -import org.jabref.model.bibtexkeypattern.AbstractCitationKeyPattern; import org.jabref.model.entry.BibEntryType; import org.jabref.model.entry.types.EntryType; -import org.jabref.preferences.JabRefPreferences; +import org.jabref.preferences.PreferencesService; import com.airhacks.afterburner.views.ViewLoader; @@ -32,7 +32,7 @@ public class CitationKeyPatternPanel extends TableView entryTypeList, AbstractCitationKeyPattern keyPattern) { + public CitationKeyPatternPanel(PreferencesService preferences, Collection entryTypeList, AbstractCitationKeyPattern keyPattern) { super(); viewModel = new CitationKeyPatternPanelViewModel(preferences, entryTypeList, keyPattern); diff --git a/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternPanelViewModel.java b/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternPanelViewModel.java index 6f906b98c38..fa3a1978b29 100644 --- a/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternPanelViewModel.java +++ b/src/main/java/org/jabref/gui/commonfxcontrols/CitationKeyPatternPanelViewModel.java @@ -9,11 +9,11 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; +import org.jabref.logic.citationkeypattern.AbstractCitationKeyPattern; import org.jabref.logic.l10n.Localization; -import org.jabref.model.bibtexkeypattern.AbstractCitationKeyPattern; import org.jabref.model.entry.BibEntryType; import org.jabref.model.entry.types.EntryType; -import org.jabref.preferences.JabRefPreferences; +import org.jabref.preferences.PreferencesService; public class CitationKeyPatternPanelViewModel { @@ -38,9 +38,9 @@ public class CitationKeyPatternPanelViewModel { private final ObjectProperty defaultItemProperty = new SimpleObjectProperty<>(); private final AbstractCitationKeyPattern initialKeyPattern; private final Collection bibEntryTypeList; - private final JabRefPreferences preferences; + private final PreferencesService preferences; - public CitationKeyPatternPanelViewModel(JabRefPreferences preferences, Collection entryTypeList, AbstractCitationKeyPattern initialKeyPattern) { + public CitationKeyPatternPanelViewModel(PreferencesService preferences, Collection entryTypeList, AbstractCitationKeyPattern initialKeyPattern) { this.preferences = preferences; this.bibEntryTypeList = entryTypeList; this.initialKeyPattern = initialKeyPattern; @@ -72,12 +72,12 @@ public void setValues() { } public void setItemToDefaultPattern(CitationKeyPatternPanelItemModel item) { - item.setPattern((String) preferences.defaults.get(JabRefPreferences.DEFAULT_CITATION_KEY_PATTERN)); + item.setPattern(preferences.getDefaultsDefaultCitationKeyPattern()); } public void resetAll() { patternListProperty.forEach(item -> item.setPattern("")); - defaultItemProperty.getValue().setPattern((String) preferences.defaults.get(JabRefPreferences.DEFAULT_CITATION_KEY_PATTERN)); + defaultItemProperty.getValue().setPattern(preferences.getDefaultsDefaultCitationKeyPattern()); } public ListProperty patternListProperty() { diff --git a/src/main/java/org/jabref/gui/commonfxcontrols/FieldFormatterCleanupsPanel.java b/src/main/java/org/jabref/gui/commonfxcontrols/FieldFormatterCleanupsPanel.java index d0ded8f1863..ed6df61fce5 100644 --- a/src/main/java/org/jabref/gui/commonfxcontrols/FieldFormatterCleanupsPanel.java +++ b/src/main/java/org/jabref/gui/commonfxcontrols/FieldFormatterCleanupsPanel.java @@ -18,9 +18,9 @@ import org.jabref.gui.util.FieldsUtil; import org.jabref.gui.util.ValueTableCellFactory; import org.jabref.gui.util.ViewModelListCellFactory; +import org.jabref.logic.cleanup.FieldFormatterCleanup; +import org.jabref.logic.cleanup.Formatter; import org.jabref.logic.l10n.Localization; -import org.jabref.model.cleanup.FieldFormatterCleanup; -import org.jabref.model.cleanup.Formatter; import org.jabref.model.entry.field.Field; import com.airhacks.afterburner.views.ViewLoader; diff --git a/src/main/java/org/jabref/gui/commonfxcontrols/FieldFormatterCleanupsPanelViewModel.java b/src/main/java/org/jabref/gui/commonfxcontrols/FieldFormatterCleanupsPanelViewModel.java index 24258baa7ac..b5169b5b69d 100644 --- a/src/main/java/org/jabref/gui/commonfxcontrols/FieldFormatterCleanupsPanelViewModel.java +++ b/src/main/java/org/jabref/gui/commonfxcontrols/FieldFormatterCleanupsPanelViewModel.java @@ -9,11 +9,11 @@ import javafx.collections.FXCollections; import javafx.scene.control.SelectionModel; -import org.jabref.Globals; +import org.jabref.gui.Globals; import org.jabref.gui.util.NoSelectionModel; import org.jabref.logic.cleanup.Cleanups; -import org.jabref.model.cleanup.FieldFormatterCleanup; -import org.jabref.model.cleanup.Formatter; +import org.jabref.logic.cleanup.FieldFormatterCleanup; +import org.jabref.logic.cleanup.Formatter; import org.jabref.model.entry.field.Field; import org.jabref.model.entry.field.FieldFactory; diff --git a/src/main/java/org/jabref/gui/copyfiles/CopyFilesAction.java b/src/main/java/org/jabref/gui/copyfiles/CopyFilesAction.java index 943411735d4..24c28e38097 100644 --- a/src/main/java/org/jabref/gui/copyfiles/CopyFilesAction.java +++ b/src/main/java/org/jabref/gui/copyfiles/CopyFilesAction.java @@ -6,8 +6,8 @@ import javafx.concurrent.Task; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.DirectoryDialogConfiguration; diff --git a/src/main/java/org/jabref/gui/copyfiles/CopyFilesTask.java b/src/main/java/org/jabref/gui/copyfiles/CopyFilesTask.java index a9cf049c565..1e12a4efa53 100644 --- a/src/main/java/org/jabref/gui/copyfiles/CopyFilesTask.java +++ b/src/main/java/org/jabref/gui/copyfiles/CopyFilesTask.java @@ -14,7 +14,7 @@ import javafx.concurrent.Task; -import org.jabref.Globals; +import org.jabref.gui.Globals; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; import org.jabref.logic.util.io.FileUtil; diff --git a/src/main/java/org/jabref/gui/copyfiles/CopySingleFileAction.java b/src/main/java/org/jabref/gui/copyfiles/CopySingleFileAction.java index 98d330d1482..0981032c29a 100644 --- a/src/main/java/org/jabref/gui/copyfiles/CopySingleFileAction.java +++ b/src/main/java/org/jabref/gui/copyfiles/CopySingleFileAction.java @@ -4,8 +4,8 @@ import java.util.Optional; import java.util.function.BiFunction; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.io.FileUtil; diff --git a/src/main/java/org/jabref/gui/customentrytypes/CustomEntryTypeDialogViewModel.java b/src/main/java/org/jabref/gui/customentrytypes/CustomEntryTypeDialogViewModel.java index 2e91b67a4b7..14addc7ea20 100644 --- a/src/main/java/org/jabref/gui/customentrytypes/CustomEntryTypeDialogViewModel.java +++ b/src/main/java/org/jabref/gui/customentrytypes/CustomEntryTypeDialogViewModel.java @@ -50,7 +50,7 @@ public Field fromString(String string) { } }; - private final ObservableList fieldsForAdding = FXCollections.observableArrayList(FieldFactory.getStandardFielsdsWithBibTexKey()); + private final ObservableList fieldsForAdding = FXCollections.observableArrayList(FieldFactory.getStandardFieldsWithCitationKey()); private final ObjectProperty selectedEntryType = new SimpleObjectProperty<>(); private final ObjectProperty selectedFieldToAdd = new SimpleObjectProperty<>(); private final StringProperty entryTypeToAdd = new SimpleStringProperty(""); diff --git a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java index fee12ffa38e..3ae0a346f02 100644 --- a/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java +++ b/src/main/java/org/jabref/gui/desktop/JabRefDesktop.java @@ -10,8 +10,8 @@ import java.util.Optional; import java.util.regex.Pattern; -import org.jabref.Globals; -import org.jabref.JabRefGUI; +import org.jabref.gui.Globals; +import org.jabref.gui.JabRefGUI; import org.jabref.gui.desktop.os.DefaultDesktop; import org.jabref.gui.desktop.os.Linux; import org.jabref.gui.desktop.os.NativeDesktop; diff --git a/src/main/java/org/jabref/gui/desktop/os/DefaultDesktop.java b/src/main/java/org/jabref/gui/desktop/os/DefaultDesktop.java index 457503ae272..5cb41e0d0f2 100644 --- a/src/main/java/org/jabref/gui/desktop/os/DefaultDesktop.java +++ b/src/main/java/org/jabref/gui/desktop/os/DefaultDesktop.java @@ -5,9 +5,12 @@ import java.io.IOException; import java.nio.file.Path; +import org.jabref.architecture.AllowedToUseAwt; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@AllowedToUseAwt("Requires AWT to open a file") public class DefaultDesktop implements NativeDesktop { private static final Logger LOGGER = LoggerFactory.getLogger(NativeDesktop.class); diff --git a/src/main/java/org/jabref/gui/desktop/os/Linux.java b/src/main/java/org/jabref/gui/desktop/os/Linux.java index ee1881af803..e501d3ba620 100644 --- a/src/main/java/org/jabref/gui/desktop/os/Linux.java +++ b/src/main/java/org/jabref/gui/desktop/os/Linux.java @@ -8,7 +8,7 @@ import java.util.Locale; import java.util.Optional; -import org.jabref.JabRefExecutorService; +import org.jabref.gui.JabRefExecutorService; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.util.StreamGobbler; diff --git a/src/main/java/org/jabref/gui/desktop/os/OSX.java b/src/main/java/org/jabref/gui/desktop/os/OSX.java index 57f145f7460..b48c8bef411 100644 --- a/src/main/java/org/jabref/gui/desktop/os/OSX.java +++ b/src/main/java/org/jabref/gui/desktop/os/OSX.java @@ -6,9 +6,11 @@ import java.nio.file.Path; import java.util.Optional; +import org.jabref.architecture.AllowedToUseAwt; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; +@AllowedToUseAwt("Requires AWT to open a file") public class OSX implements NativeDesktop { @Override diff --git a/src/main/java/org/jabref/gui/dialogs/AutosaveUiManager.java b/src/main/java/org/jabref/gui/dialogs/AutosaveUiManager.java index a1d6da59753..660995a0795 100644 --- a/src/main/java/org/jabref/gui/dialogs/AutosaveUiManager.java +++ b/src/main/java/org/jabref/gui/dialogs/AutosaveUiManager.java @@ -1,7 +1,7 @@ package org.jabref.gui.dialogs; -import org.jabref.Globals; import org.jabref.gui.BasePanel; +import org.jabref.gui.Globals; import org.jabref.gui.exporter.SaveDatabaseAction; import org.jabref.model.database.event.AutosaveEvent; diff --git a/src/main/java/org/jabref/gui/documentviewer/DocumentViewerViewModel.java b/src/main/java/org/jabref/gui/documentviewer/DocumentViewerViewModel.java index 48097879406..dc32be00a35 100644 --- a/src/main/java/org/jabref/gui/documentviewer/DocumentViewerViewModel.java +++ b/src/main/java/org/jabref/gui/documentviewer/DocumentViewerViewModel.java @@ -16,8 +16,8 @@ import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; -import org.jabref.Globals; import org.jabref.gui.AbstractViewModel; +import org.jabref.gui.Globals; import org.jabref.gui.StateManager; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.LinkedFile; diff --git a/src/main/java/org/jabref/gui/documentviewer/PdfDocumentPageViewModel.java b/src/main/java/org/jabref/gui/documentviewer/PdfDocumentPageViewModel.java index 0bfb3f7775a..5ad9a3b528c 100644 --- a/src/main/java/org/jabref/gui/documentviewer/PdfDocumentPageViewModel.java +++ b/src/main/java/org/jabref/gui/documentviewer/PdfDocumentPageViewModel.java @@ -8,6 +8,8 @@ import javafx.embed.swing.SwingFXUtils; import javafx.scene.image.Image; +import org.jabref.architecture.AllowedToUseAwt; + import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.common.PDRectangle; @@ -17,6 +19,7 @@ /** * Represents the view model of a pdf page backed by a {@link PDPage}. */ +@AllowedToUseAwt("Requires AWT due to PDFBox") public class PdfDocumentPageViewModel extends DocumentPageViewModel { private final PDPage page; diff --git a/src/main/java/org/jabref/gui/duplicationFinder/DuplicateSearch.java b/src/main/java/org/jabref/gui/duplicationFinder/DuplicateSearch.java index eeb4528de9f..b0bdb122ea1 100644 --- a/src/main/java/org/jabref/gui/duplicationFinder/DuplicateSearch.java +++ b/src/main/java/org/jabref/gui/duplicationFinder/DuplicateSearch.java @@ -11,10 +11,10 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import org.jabref.Globals; -import org.jabref.JabRefExecutorService; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; +import org.jabref.gui.JabRefExecutorService; import org.jabref.gui.JabRefFrame; import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; @@ -25,7 +25,7 @@ import org.jabref.gui.undo.UndoableRemoveEntries; import org.jabref.gui.util.BackgroundTask; import org.jabref.gui.util.DefaultTaskExecutor; -import org.jabref.logic.bibtex.DuplicateCheck; +import org.jabref.logic.database.DuplicateCheck; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.database.BibDatabaseMode; diff --git a/src/main/java/org/jabref/gui/edit/CopyDoiUrlAction.java b/src/main/java/org/jabref/gui/edit/CopyDoiUrlAction.java index bbc936366ed..459df55a595 100644 --- a/src/main/java/org/jabref/gui/edit/CopyDoiUrlAction.java +++ b/src/main/java/org/jabref/gui/edit/CopyDoiUrlAction.java @@ -4,8 +4,8 @@ import javafx.scene.control.TextArea; -import org.jabref.Globals; -import org.jabref.JabRefGUI; +import org.jabref.gui.Globals; +import org.jabref.gui.JabRefGUI; import org.jabref.gui.actions.SimpleCommand; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.identifier.DOI; diff --git a/src/main/java/org/jabref/gui/edit/CopyMoreAction.java b/src/main/java/org/jabref/gui/edit/CopyMoreAction.java index 5f982b01da3..ac138cf5a85 100644 --- a/src/main/java/org/jabref/gui/edit/CopyMoreAction.java +++ b/src/main/java/org/jabref/gui/edit/CopyMoreAction.java @@ -6,9 +6,9 @@ import java.util.Optional; import java.util.stream.Collectors; -import org.jabref.Globals; import org.jabref.gui.ClipBoardManager; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.JabRefDialogService; import org.jabref.gui.StateManager; import org.jabref.gui.actions.ActionHelper; @@ -104,8 +104,8 @@ private void copyKey() { // Collect all non-null keys. List keys = entries.stream() - .filter(entry -> entry.getCiteKeyOptional().isPresent()) - .map(entry -> entry.getCiteKeyOptional().get()) + .filter(entry -> entry.getCitationKey().isPresent()) + .map(entry -> entry.getCitationKey().get()) .collect(Collectors.toList()); if (keys.isEmpty()) { @@ -131,8 +131,8 @@ private void copyCiteKey() { // Collect all non-null keys. List keys = entries.stream() - .filter(entry -> entry.getCiteKeyOptional().isPresent()) - .map(entry -> entry.getCiteKeyOptional().get()) + .filter(entry -> entry.getCitationKey().isPresent()) + .map(entry -> entry.getCitationKey().get()) .collect(Collectors.toList()); if (keys.isEmpty()) { @@ -161,7 +161,7 @@ private void copyKeyAndTitle() { List entries = stateManager.getSelectedEntries(); // ToDo: this string should be configurable to allow arbitrary exports - StringReader layoutString = new StringReader("\\bibtexkey - \\begin{title}\\format[RemoveBrackets]{\\title}\\end{title}\n"); + StringReader layoutString = new StringReader("\\citationkey - \\begin{title}\\format[RemoveBrackets]{\\title}\\end{title}\n"); Layout layout; try { layout = new LayoutHelper(layoutString, preferencesService.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository)).getLayoutFromText(); @@ -175,7 +175,7 @@ private void copyKeyAndTitle() { int entriesWithKeys = 0; // Collect all non-null keys. for (BibEntry entry : entries) { - if (entry.hasCiteKey()) { + if (entry.hasCitationKey()) { entriesWithKeys++; keyAndTitle.append(layout.doLayout(entry, stateManager.getActiveDatabase().get().getDatabase())); } @@ -209,7 +209,7 @@ private void copyKeyAndLink() { StringBuilder keyAndLink = new StringBuilder(); List entriesWithKey = entries.stream() - .filter(BibEntry::hasCiteKey) + .filter(BibEntry::hasCitationKey) .collect(Collectors.toList()); if (entriesWithKey.isEmpty()) { @@ -218,7 +218,7 @@ private void copyKeyAndLink() { } for (BibEntry entry : entriesWithKey) { - String key = entry.getCiteKeyOptional().get(); + String key = entry.getCitationKey().get(); String url = entry.getField(StandardField.URL).orElse(""); keyAndLink.append(url.isEmpty() ? key : String.format("%s", url, key)); keyAndLink.append(OS.NEWLINE); diff --git a/src/main/java/org/jabref/gui/edit/ManageKeywordsViewModel.java b/src/main/java/org/jabref/gui/edit/ManageKeywordsViewModel.java index 3cf44e966fb..7c2809813d7 100644 --- a/src/main/java/org/jabref/gui/edit/ManageKeywordsViewModel.java +++ b/src/main/java/org/jabref/gui/edit/ManageKeywordsViewModel.java @@ -105,7 +105,7 @@ public void saveChanges() { return; } - if (preferences.isKeywordSyncEnabled() && !keywordsToAdd.isEmpty()) { + if (preferences.getSpecialFieldsPreferences().isKeywordSyncEnabled() && !keywordsToAdd.isEmpty()) { SpecialFieldsUtils.synchronizeSpecialFields(keywordsToAdd, keywordsToRemove); } @@ -125,11 +125,9 @@ private NamedCompound updateKeywords(List entries, KeywordList keyword // put keywords back Optional change = entry.putKeywords(keywords, preferences.getKeywordDelimiter()); - if (change.isPresent()) { - ce.addEdit(new UndoableFieldChange(change.get())); - } + change.ifPresent(fieldChange -> ce.addEdit(new UndoableFieldChange(fieldChange))); - if (preferences.isKeywordSyncEnabled()) { + if (preferences.getSpecialFieldsPreferences().isKeywordSyncEnabled()) { SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, preferences.getKeywordDelimiter()); } } diff --git a/src/main/java/org/jabref/gui/edit/MassSetFieldsDialog.java b/src/main/java/org/jabref/gui/edit/MassSetFieldsDialog.java index 496c9f648c6..785b571ceb3 100644 --- a/src/main/java/org/jabref/gui/edit/MassSetFieldsDialog.java +++ b/src/main/java/org/jabref/gui/edit/MassSetFieldsDialog.java @@ -62,7 +62,7 @@ public class MassSetFieldsDialog extends BaseDialog { this.undoManager = undoManager; init(); - this.setTitle("Set/clear/append/rename fields"); + this.setTitle(Localization.lang("Manage field names & content")); this.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL); this.setResultConverter(button -> { if (button == ButtonType.OK) { diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index 780a953f988..068e9ecd41d 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -25,9 +25,9 @@ import javafx.scene.input.TransferMode; import javafx.scene.layout.BorderPane; -import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.StateManager; import org.jabref.gui.citationkeypattern.GenerateCitationKeySingleAction; import org.jabref.gui.entryeditor.fileannotationtab.FileAnnotationTab; diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java index 760ad6edf80..03dc9fa06ab 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java @@ -76,7 +76,7 @@ public void init(BibEntry entry) { cancelSearch(); currentEntry = entry; - Optional citeKey = entry.getCiteKeyOptional(); + Optional citeKey = entry.getCitationKey(); if (citeKey.isPresent()) { startSearch(citeKey.get()); diff --git a/src/main/java/org/jabref/gui/entryeditor/RelatedArticlesTab.java b/src/main/java/org/jabref/gui/entryeditor/RelatedArticlesTab.java index 039e229d508..d381159649b 100644 --- a/src/main/java/org/jabref/gui/entryeditor/RelatedArticlesTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/RelatedArticlesTab.java @@ -18,12 +18,15 @@ import javafx.scene.text.FontPosture; import javafx.scene.text.Text; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.desktop.JabRefDesktop; import org.jabref.gui.util.BackgroundTask; +import org.jabref.logic.importer.ImportCleanup; import org.jabref.logic.importer.fetcher.MrDLibFetcher; import org.jabref.logic.l10n.Localization; +import org.jabref.model.database.BibDatabase; +import org.jabref.model.database.BibDatabaseModeDetection; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.StandardField; import org.jabref.preferences.JabRefPreferences; @@ -67,6 +70,8 @@ private StackPane getRelatedArticlesPane(BibEntry entry) { .wrap(() -> fetcher.performSearch(entry)) .onRunning(() -> progress.setVisible(true)) .onSuccess(relatedArticles -> { + ImportCleanup cleanup = new ImportCleanup(BibDatabaseModeDetection.inferMode(new BibDatabase(List.of(entry)))); + cleanup.doPostCleanup(relatedArticles); progress.setVisible(false); root.getChildren().add(getRelatedArticleInfo(relatedArticles, fetcher)); }) diff --git a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java index 749a21ba131..aba1aca5363 100644 --- a/src/main/java/org/jabref/gui/entryeditor/SourceTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/SourceTab.java @@ -19,8 +19,8 @@ import javafx.scene.control.Tooltip; import javafx.scene.input.InputMethodRequests; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.StateManager; import org.jabref.gui.actions.ActionFactory; import org.jabref.gui.actions.SimpleCommand; @@ -278,10 +278,10 @@ private void storeSource(BibEntry outOfFocusEntry, String text) { NamedCompound compound = new NamedCompound(Localization.lang("source edit")); BibEntry newEntry = database.getEntries().get(0); - String newKey = newEntry.getCiteKeyOptional().orElse(null); + String newKey = newEntry.getCitationKey().orElse(null); if (newKey != null) { - outOfFocusEntry.setCiteKey(newKey); + outOfFocusEntry.setCitationKey(newKey); } else { outOfFocusEntry.clearCiteKey(); } diff --git a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabViewModel.java b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabViewModel.java index 5ae41bd4c24..d98e5e59d91 100644 --- a/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FileAnnotationTabViewModel.java @@ -16,8 +16,8 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; -import org.jabref.Globals; import org.jabref.gui.AbstractViewModel; +import org.jabref.gui.Globals; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.logic.l10n.Localization; import org.jabref.logic.pdf.FileAnnotationCache; diff --git a/src/main/java/org/jabref/gui/exporter/CreateModifyExporterDialogViewModel.java b/src/main/java/org/jabref/gui/exporter/CreateModifyExporterDialogViewModel.java index 924adeacbc3..116c84e14c7 100644 --- a/src/main/java/org/jabref/gui/exporter/CreateModifyExporterDialogViewModel.java +++ b/src/main/java/org/jabref/gui/exporter/CreateModifyExporterDialogViewModel.java @@ -70,7 +70,7 @@ public ExporterViewModel saveExporter() { // Create a new exporter to be returned to ExportCustomizationDialogViewModel, which requested it LayoutFormatterPreferences layoutPreferences = preferences.getLayoutFormatterPreferences(repository); - SavePreferences savePreferences = preferences.loadForExportFromPreferences(); + SavePreferences savePreferences = preferences.getSavePreferencesForExport(); TemplateExporter format = new TemplateExporter(name.get(), layoutFile.get(), extension.get(), layoutPreferences, savePreferences); format.setCustomExport(true); diff --git a/src/main/java/org/jabref/gui/exporter/ExportCommand.java b/src/main/java/org/jabref/gui/exporter/ExportCommand.java index 3a9534fcf65..70f4e5adca0 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportCommand.java +++ b/src/main/java/org/jabref/gui/exporter/ExportCommand.java @@ -7,8 +7,8 @@ import javafx.stage.FileChooser; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.BackgroundTask; @@ -53,8 +53,8 @@ public ExportCommand(JabRefFrame frame, boolean selectedOnly, JabRefPreferences public void execute() { List customExporters = preferences.getCustomExportFormats(Globals.journalAbbreviationRepository); LayoutFormatterPreferences layoutPreferences = preferences.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository); - SavePreferences savePreferences = preferences.loadForExportFromPreferences(); - XmpPreferences xmpPreferences = preferences.getXMPPreferences(); + SavePreferences savePreferences = preferences.getSavePreferencesForExport(); + XmpPreferences xmpPreferences = preferences.getXmpPreferences(); // Get list of exporters and sort before adding to file dialog List exporters = Globals.exportFactory.getExporters().stream() diff --git a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java index 02ade4ac4bc..b40ff5cb952 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java +++ b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java @@ -13,10 +13,10 @@ import javafx.scene.input.ClipboardContent; -import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.ClipBoardManager; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.BackgroundTask; diff --git a/src/main/java/org/jabref/gui/exporter/SaveAction.java b/src/main/java/org/jabref/gui/exporter/SaveAction.java index eadd350770a..2a80a25148d 100644 --- a/src/main/java/org/jabref/gui/exporter/SaveAction.java +++ b/src/main/java/org/jabref/gui/exporter/SaveAction.java @@ -1,6 +1,6 @@ package org.jabref.gui.exporter; -import org.jabref.Globals; +import org.jabref.gui.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.StateManager; import org.jabref.gui.actions.ActionHelper; diff --git a/src/main/java/org/jabref/gui/exporter/SaveAllAction.java b/src/main/java/org/jabref/gui/exporter/SaveAllAction.java index 0e9770c034f..4c2c1dd69a3 100644 --- a/src/main/java/org/jabref/gui/exporter/SaveAllAction.java +++ b/src/main/java/org/jabref/gui/exporter/SaveAllAction.java @@ -1,8 +1,8 @@ package org.jabref.gui.exporter; -import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.actions.SimpleCommand; import org.jabref.logic.l10n.Localization; diff --git a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java index 8abfc0dfc18..42c5a572c48 100644 --- a/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java +++ b/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java @@ -28,11 +28,11 @@ import org.jabref.logic.exporter.SavePreferences; import org.jabref.logic.l10n.Encodings; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.shared.DatabaseLocation; import org.jabref.logic.shared.prefs.SharedDatabasePreferences; import org.jabref.logic.util.StandardFileType; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.database.event.ChangePropagation; -import org.jabref.model.database.shared.DatabaseLocation; import org.jabref.model.entry.BibEntryTypesManager; import org.jabref.preferences.JabRefPreferences; @@ -166,7 +166,7 @@ private Optional askForSavePath() { private boolean save(BibDatabaseContext bibDatabaseContext, SaveDatabaseMode mode) { Optional databasePath = bibDatabaseContext.getDatabasePath(); - if (!databasePath.isPresent()) { + if (databasePath.isEmpty()) { Optional savePath = askForSavePath(); if (!savePath.isPresent()) { return false; @@ -216,10 +216,10 @@ private boolean save(Path targetPath, SaveDatabaseMode mode) { } private boolean saveDatabase(Path file, boolean selectedOnly, Charset encoding, SavePreferences.DatabaseSaveType saveType) throws SaveException { - SavePreferences preferences = this.preferences.loadForSaveFromPreferences() + SavePreferences preferences = this.preferences.getSavePreferences() .withEncoding(encoding) .withSaveType(saveType); - try (AtomicFileWriter fileWriter = new AtomicFileWriter(file, preferences.getEncoding(), preferences.makeBackup())) { + try (AtomicFileWriter fileWriter = new AtomicFileWriter(file, preferences.getEncoding(), preferences.shouldMakeBackup())) { BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(fileWriter, preferences, entryTypesManager); if (selectedOnly) { diff --git a/src/main/java/org/jabref/gui/exporter/WriteXMPAction.java b/src/main/java/org/jabref/gui/exporter/WriteXMPAction.java index 90ed161d558..51570c8fdfa 100644 --- a/src/main/java/org/jabref/gui/exporter/WriteXMPAction.java +++ b/src/main/java/org/jabref/gui/exporter/WriteXMPAction.java @@ -20,9 +20,9 @@ import javafx.scene.paint.Color; import javafx.stage.Stage; -import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.FXDialog; +import org.jabref.gui.Globals; import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.BackgroundTask; @@ -117,7 +117,7 @@ private void writeXMP() { .collect(Collectors.toList()); Platform.runLater(() -> optionsDialog.getProgressArea() - .appendText(entry.getCiteKeyOptional().orElse(Localization.lang("undefined")) + "\n")); + .appendText(entry.getCitationKey().orElse(Localization.lang("undefined")) + "\n")); if (files.isEmpty()) { skipped++; @@ -127,7 +127,7 @@ private void writeXMP() { for (Path file : files) { if (Files.exists(file)) { try { - XmpUtilWriter.writeXmp(file, entry, database, Globals.prefs.getXMPPreferences()); + XmpUtilWriter.writeXmp(file, entry, database, Globals.prefs.getXmpPreferences()); Platform.runLater( () -> optionsDialog.getProgressArea().appendText(" " + Localization.lang("OK") + ".\n")); entriesChanged++; diff --git a/src/main/java/org/jabref/gui/externalfiles/AutoLinkFilesAction.java b/src/main/java/org/jabref/gui/externalfiles/AutoLinkFilesAction.java index 505137edc35..487e9250a33 100644 --- a/src/main/java/org/jabref/gui/externalfiles/AutoLinkFilesAction.java +++ b/src/main/java/org/jabref/gui/externalfiles/AutoLinkFilesAction.java @@ -52,8 +52,12 @@ public void execute() { List entries = stateManager.getSelectedEntries(); final NamedCompound nc = new NamedCompound(Localization.lang("Automatically set file links")); - AutoSetFileLinksUtil util = new AutoSetFileLinksUtil(database, preferences.getFilePreferences(), preferences.getAutoLinkPreferences(), ExternalFileTypes.getInstance()); - Task> linkFilesTask = new Task>() { + AutoSetFileLinksUtil util = new AutoSetFileLinksUtil( + database, + preferences.getFilePreferences(), + preferences.getAutoLinkPreferences(), + ExternalFileTypes.getInstance()); + Task> linkFilesTask = new Task<>() { @Override protected List call() { diff --git a/src/main/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtil.java b/src/main/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtil.java index f771d0bed44..70927daa0a6 100644 --- a/src/main/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtil.java +++ b/src/main/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtil.java @@ -14,17 +14,17 @@ import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.gui.util.DefaultTaskExecutor; +import org.jabref.logic.bibtex.FileFieldWriter; import org.jabref.logic.util.io.AutoLinkPreferences; import org.jabref.logic.util.io.FileFinder; import org.jabref.logic.util.io.FileFinders; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.FileFieldWriter; import org.jabref.model.entry.LinkedFile; import org.jabref.model.entry.field.StandardField; -import org.jabref.model.metadata.FilePreferences; import org.jabref.model.util.FileHelper; +import org.jabref.preferences.FilePreferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/jabref/gui/externalfiles/DownloadFullTextAction.java b/src/main/java/org/jabref/gui/externalfiles/DownloadFullTextAction.java index 73bf06cce21..019678e7d84 100644 --- a/src/main/java/org/jabref/gui/externalfiles/DownloadFullTextAction.java +++ b/src/main/java/org/jabref/gui/externalfiles/DownloadFullTextAction.java @@ -10,8 +10,8 @@ import javafx.concurrent.Task; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.StateManager; import org.jabref.gui.actions.ActionHelper; import org.jabref.gui.actions.SimpleCommand; @@ -126,7 +126,7 @@ private void downloadFullTexts(Map> downloads, BibDataba addLinkedFileFromURL(databaseContext, result.get(), entry, dir.get()); } else { dialogService.notify(Localization.lang("No full text document found for entry %0.", - entry.getCiteKeyOptional().orElse(Localization.lang("undefined")))); + entry.getCitationKey().orElse(Localization.lang("undefined")))); } } } @@ -150,7 +150,7 @@ private void addLinkedFileFromURL(BibDatabaseContext databaseContext, URL url, B databaseContext, Globals.TASK_EXECUTOR, dialogService, - preferences.getXMPPreferences(), + preferences.getXmpPreferences(), preferences.getFilePreferences(), ExternalFileTypes.getInstance()); @@ -164,11 +164,11 @@ private void addLinkedFileFromURL(BibDatabaseContext databaseContext, URL url, B ExternalFileTypes.getInstance()); entry.addFile(downloadedFile); dialogService.notify(Localization.lang("Finished downloading full text document for entry %0.", - entry.getCiteKeyOptional().orElse(Localization.lang("undefined")))); + entry.getCitationKey().orElse(Localization.lang("undefined")))); }); downloadTask.titleProperty().set(Localization.lang("Downloading")); downloadTask.messageProperty().set( - Localization.lang("Fulltext for") + ": " + entry.getCiteKeyOptional().orElse(Localization.lang("New entry"))); + Localization.lang("Fulltext for") + ": " + entry.getCitationKey().orElse(Localization.lang("New entry"))); downloadTask.showToUser(true); Globals.TASK_EXECUTOR.execute(downloadTask); } catch (MalformedURLException exception) { @@ -176,7 +176,7 @@ private void addLinkedFileFromURL(BibDatabaseContext databaseContext, URL url, B } } else { dialogService.notify(Localization.lang("Full text document for entry %0 already linked.", - entry.getCiteKeyOptional().orElse(Localization.lang("undefined")))); + entry.getCitationKey().orElse(Localization.lang("undefined")))); } } } diff --git a/src/main/java/org/jabref/gui/externalfiles/ExternalFilesEntryLinker.java b/src/main/java/org/jabref/gui/externalfiles/ExternalFilesEntryLinker.java index 657ece362e5..2c5dfa66571 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ExternalFilesEntryLinker.java +++ b/src/main/java/org/jabref/gui/externalfiles/ExternalFilesEntryLinker.java @@ -14,7 +14,7 @@ import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.LinkedFile; -import org.jabref.model.metadata.FilePreferences; +import org.jabref.preferences.FilePreferences; public class ExternalFilesEntryLinker { diff --git a/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesDialog.java b/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesDialog.java index ceaea36f3d2..cbef3f235f6 100644 --- a/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesDialog.java +++ b/src/main/java/org/jabref/gui/externalfiles/FindUnlinkedFilesDialog.java @@ -35,8 +35,8 @@ import javafx.scene.layout.VBox; import javafx.stage.FileChooser; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.externalfiletype.ExternalFileType; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.importer.UnlinkedFilesCrawler; @@ -57,7 +57,7 @@ import org.slf4j.LoggerFactory; /** - * GUI Dialog for the feature "Find unlinked files". + * GUI Dialog for the feature "Search for unlinked local files". */ public class FindUnlinkedFilesDialog extends BaseDialog { @@ -77,7 +77,7 @@ public class FindUnlinkedFilesDialog extends BaseDialog { public FindUnlinkedFilesDialog(BibDatabaseContext database, DialogService dialogService, CountingUndoManager undoManager) { super(); - this.setTitle(Localization.lang("Find unlinked files")); + this.setTitle(Localization.lang("Search for unlinked local files")); this.dialogService = dialogService; databaseContext = database; diff --git a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java index 9ffed42bc07..dcb570a82cd 100644 --- a/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java +++ b/src/main/java/org/jabref/gui/externalfiles/ImportHandler.java @@ -8,13 +8,14 @@ import javax.swing.undo.CompoundEdit; import javax.swing.undo.UndoManager; -import org.jabref.Globals; import org.jabref.gui.DialogService; +import org.jabref.gui.Globals; import org.jabref.gui.StateManager; import org.jabref.gui.externalfiletype.ExternalFileTypes; import org.jabref.gui.undo.UndoableInsertEntries; import org.jabref.logic.citationkeypattern.CitationKeyGenerator; import org.jabref.logic.externalfiles.ExternalFilesContentImporter; +import org.jabref.logic.importer.ImportCleanup; import org.jabref.logic.util.UpdateField; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.FieldChange; @@ -107,7 +108,8 @@ private BibEntry createEmptyEntryWithLink(Path file) { public void importEntries(List entries) { // TODO: Add undo/redo // undoManager.addEdit(new UndoableInsertEntries(panel.getDatabase(), entries)); - + ImportCleanup cleanup = new ImportCleanup(database.getMode()); + cleanup.doPostCleanup(entries); database.getDatabase().insertEntries(entries); // Set owner/timestamp @@ -115,7 +117,7 @@ public void importEntries(List entries) { preferencesService.getOwnerPreferences(), preferencesService.getTimestampPreferences()); - // Generate bibtex keys + // Generate citation keys generateKeys(entries); // Add to group diff --git a/src/main/java/org/jabref/gui/externalfiletype/ExternalFileTypes.java b/src/main/java/org/jabref/gui/externalfiletype/ExternalFileTypes.java index 485a050523c..1fca8528a39 100644 --- a/src/main/java/org/jabref/gui/externalfiletype/ExternalFileTypes.java +++ b/src/main/java/org/jabref/gui/externalfiletype/ExternalFileTypes.java @@ -10,8 +10,8 @@ import java.util.Set; import java.util.TreeSet; -import org.jabref.Globals; -import org.jabref.model.entry.FileFieldWriter; +import org.jabref.gui.Globals; +import org.jabref.logic.bibtex.FileFieldWriter; import org.jabref.model.entry.LinkedFile; import org.jabref.model.strings.StringUtil; import org.jabref.model.util.FileHelper; diff --git a/src/main/java/org/jabref/gui/fieldeditors/AbstractEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/AbstractEditorViewModel.java index 064b8808bdf..a2d47b08a68 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/AbstractEditorViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/AbstractEditorViewModel.java @@ -7,8 +7,8 @@ import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; -import org.jabref.JabRefGUI; import org.jabref.gui.AbstractViewModel; +import org.jabref.gui.JabRefGUI; import org.jabref.gui.autocompleter.SuggestionProvider; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.gui.util.BindingsHelper; @@ -23,7 +23,6 @@ import de.saxsys.mvvmfx.utils.validation.FunctionBasedValidator; import de.saxsys.mvvmfx.utils.validation.ValidationMessage; import de.saxsys.mvvmfx.utils.validation.Validator; -import org.apache.commons.lang3.StringUtils; import org.controlsfx.control.textfield.AutoCompletionBinding; public class AbstractEditorViewModel extends AbstractViewModel { @@ -66,10 +65,10 @@ public void bindToEntry(BibEntry entry) { newValue -> { if (newValue != null) { // Controlsfx uses hardcoded \n for multiline fields, but JabRef stores them in OS Newlines format - String oldValue = entry.getField(field).map(value -> value.replace(OS.NEWLINE, "\n")).orElse(null); + String oldValue = entry.getField(field).map(value -> value.replace(OS.NEWLINE, "\n").trim()).orElse(null); // Autosave and save action trigger the entry editor to reload the fields, so we have to // check for changes here, otherwise the cursor position is annoyingly reset every few seconds - if (!(newValue.trim()).equals(StringUtils.trim(oldValue))) { + if (!(newValue.trim()).equals(oldValue)) { entry.setField(field, newValue); UndoManager undoManager = JabRefGUI.getMainFrame().getUndoManager(); undoManager.addEdit(new UndoableFieldChange(entry, field, oldValue, newValue)); diff --git a/src/main/java/org/jabref/gui/fieldeditors/CitationKeyEditor.fxml b/src/main/java/org/jabref/gui/fieldeditors/CitationKeyEditor.fxml index 5e38d8c98ab..fcb4b34414c 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/CitationKeyEditor.fxml +++ b/src/main/java/org/jabref/gui/fieldeditors/CitationKeyEditor.fxml @@ -6,5 +6,5 @@ -