diff --git a/.gitignore b/.gitignore index fd187d3f735..f2a7cad5e5e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ src-gen/ docs/book.pdf docs/_book/ +# Jekyll for docs/ +docs/Gemfile.lock + # ignore the generated markdown file if the user forgets to delete it status.md diff --git a/CHANGELOG.md b/CHANGELOG.md index ff69d86f76d..edd8aae36d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve ### Added - We added a field showing the BibTeX/biblatex source for added and deleted entries in the "External Changes Resolver" dialog. [#9509](https://github.com/JabRef/jabref/issues/9509) -- We added a search history list in the search field's right click menu [#7906](https://github.com/JabRef/jabref/issues/7906) +- We added a search history list in the search field's right click menu. [#7906](https://github.com/JabRef/jabref/issues/7906) - We added a full text fetcher for IACR eprints. [#9651](https://github.com/JabRef/jabref/pull/9651) - We added "Attach file from URL" to right-click context menu to download and store a file with the reference library. [#9646](https://github.com/JabRef/jabref/issues/9646) - We enabled updating an existing entry with data from InspireHEP. [#9351](https://github.com/JabRef/jabref/issues/9351) @@ -24,34 +24,41 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve ### Changed - 'Get full text' now also checks the file url. [#568](https://github.com/koppor/jabref/issues/568) -- `log.txt` now contains an entry if a BibTeX entry could not be parsed. - JabRef writes a new backup file only if there is a change. Before, JabRef created a backup upon start. [#9679](https://github.com/JabRef/jabref/pull/9679) - We modified the `Add Group` dialog to use the most recently selected group hierarchical context. [#9141](https://github.com/JabRef/jabref/issues/9141) - We refined the 'main directory not found' error message. [#9625](https://github.com/JabRef/jabref/pull/9625) - JabRef writes a new backup file only if there is a change. Before, JabRef created a backup upon start. [#9679](https://github.com/JabRef/jabref/pull/9679) - Backups of libraries are not stored per JabRef version, but collected together. - We streamlined the paths for logs and backups: The parent path fragement is always `logs` or `backups`. +- `log.txt` now contains an entry if a BibTeX entry could not be parsed. - `log.txt` now contains debug messages. Debugging needs to be enabled explicitly. [#9678](https://github.com/JabRef/jabref/pull/9678) - `log.txt` does not contain entries for non-found files during PDF indexing. [#9678](https://github.com/JabRef/jabref/pull/9678) - We improved the Medline importer to correctly import ISO dates for `revised`. [#9536](https://github.com/JabRef/jabref/issues/9536) - +- To avoid cluttering of the directory, We always delete the `.sav` file upon successful write. [#9675](https://github.com/JabRef/jabref/pull/9675) +- We improved the unlinking/deletion of multiple linked files of an entry using the Delete key. [#9473](https://github.com/JabRef/jabref/issues/9473) ### Fixed -- We fixed an issue where the browser import would add ' characters before the BibTeX entry on Linux [#9588](https://github.com/JabRef/jabref/issues/9588) -- We fixed an issue where searching for a specific term with the DOAB fetcher lead to an exception [#9571](https://github.com/JabRef/jabref/issues/9571) -- We fixed an issue where the "Import" -> "Library to import to" did not show the correct library name if two opened libraries had the same suffix [#9567](https://github.com/JabRef/jabref/issues/9567) -- We fixed an issue where the rpm-Version of JabRef could not be properly uninstalled and reinstalled [#9558](https://github.com/JabRef/jabref/issues/9558), [#9603](https://github.com/JabRef/jabref/issues/9603) -- We fixed an issue where the command line export using `--exportMatches` flag does not create an output bib file [#9581](https://github.com/JabRef/jabref/issues/9581) -- We fixed an issue where custom field in the custom entry types could not be set to mulitline [#9609](https://github.com/JabRef/jabref/issues/9609) -- We fixed an issue where the Office XML exporter did not resolve BibTeX-Strings when exporting entries [forum#3741](https://discourse.jabref.org/t/exporting-bibtex-constant-strings-to-ms-office-2007-xml/3741) +- We fixed an issue where the browser import would add ' characters before the BibTeX entry on Linux. [#9588](https://github.com/JabRef/jabref/issues/9588) +- We fixed an issue where searching for a specific term with the DOAB fetcher lead to an exception. [#9571](https://github.com/JabRef/jabref/issues/9571) +- We fixed an issue where the "Import" -> "Library to import to" did not show the correct library name if two opened libraries had the same suffix. [#9567](https://github.com/JabRef/jabref/issues/9567) +- We fixed an issue where the rpm-Version of JabRef could not be properly uninstalled and reinstalled. [#9558](https://github.com/JabRef/jabref/issues/9558), [#9603](https://github.com/JabRef/jabref/issues/9603) +- We fixed an issue where the command line export using `--exportMatches` flag does not create an output bib file. [#9581](https://github.com/JabRef/jabref/issues/9581) +- We fixed an issue where custom field in the custom entry types could not be set to mulitline. [#9609](https://github.com/JabRef/jabref/issues/9609) +- We fixed an issue where the Office XML exporter did not resolve BibTeX-Strings when exporting entries. [forum#3741](https://discourse.jabref.org/t/exporting-bibtex-constant-strings-to-ms-office-2007-xml/3741) +- We fixed an issue where the Merge Entries Toolbar configuration was not saved after hitting 'Merge Entries' button. [#9091](https://github.com/JabRef/jabref/issues/9091) +- We fixed an issue where the password is saved locally if user wants to use proxy with authentication. [#8055](https://github.com/JabRef/jabref/issues/8055) - JabRef is now more relaxed when parsing field content: In case a field content ended with `\`, the combination `\}` was treated as plain `}`. [#9668](https://github.com/JabRef/jabref/issues/9668) +- We resolved an issue that cut off the number of group entries when it exceedet four digits. [#8797](https://github.com/JabRef/jabref/issues/8797) +- We fixed an issue where the Global Search UI preview is still white in dark theme. [#9362](https://github.com/JabRef/jabref/issues/9362) +- We fixed the double paste issue when Cmd + v is pressed on 'New entry from plaintext' dialog. [#9367](https://github.com/JabRef/jabref/issues/9367) ### Removed -- We removed the support of BibTeXML.[#9540](https://github.com/JabRef/jabref/issues/9540) +- We removed the support of BibTeXML. [#9540](https://github.com/JabRef/jabref/issues/9540) +- We removed support for Markdown syntax for strikethrough and task lists in comment fields. [#9726](https://github.com/JabRef/jabref/pull/9726) diff --git a/README.md b/README.md index 1134969f30f..6fcb79d3783 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ It supports you in every step of your research work. - Native BibTeX and Biblatex support - Cite-as-you-write functionality for external applications such as Emacs, Kile, LyX, Texmaker, TeXstudio, Vim and WinEdt. -- Format references in one of the many thousand built-in citation styles or create your style +- Format references using one of thousands of built-in citation styles or create your own style - Support for Word and LibreOffice/OpenOffice for inserting and formatting citations ### Share diff --git a/build.gradle b/build.gradle index 795c361c5ec..919118e8850 100644 --- a/build.gradle +++ b/build.gradle @@ -99,7 +99,7 @@ dependencyLocking { } javafx { - version = "19" + version = "20" modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.web', 'javafx.swing' ] } @@ -130,14 +130,14 @@ dependencies { implementation 'commons-cli:commons-cli:1.5.0' - implementation 'org.libreoffice:unoloader:7.5.0' - implementation 'org.libreoffice:libreoffice:7.5.0' + implementation 'org.libreoffice:unoloader:7.5.1' + implementation 'org.libreoffice:libreoffice:7.5.1' implementation 'io.github.java-diff-utils:java-diff-utils:4.12' implementation 'info.debatty:java-string-similarity:2.0.0' - antlr4 'org.antlr:antlr4:4.9.3' - implementation 'org.antlr:antlr4-runtime:4.9.3' + antlr4 'org.antlr:antlr4:4.12.0' + implementation 'org.antlr:antlr4-runtime:4.12.0' implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '6.5.0.202303070854-r' @@ -170,15 +170,15 @@ dependencies { implementation 'com.jfoenix:jfoenix:9.0.10' implementation 'org.controlsfx:controlsfx:11.1.2' - implementation 'org.jsoup:jsoup:1.15.3' + implementation 'org.jsoup:jsoup:1.15.4' implementation 'com.konghq:unirest-java:3.14.2' implementation 'org.slf4j:slf4j-api:2.0.7' implementation "org.tinylog:tinylog-api:2.6.1" implementation "org.tinylog:slf4j-tinylog:2.6.1" - implementation "org.tinylog:tinylog-impl:2.6.0" + implementation "org.tinylog:tinylog-impl:2.6.1" - implementation 'de.undercouch:citeproc-java:3.0.0-alpha.6' + implementation 'de.undercouch:citeproc-java:3.0.0-beta.2' // Data mapping implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0' @@ -228,7 +228,7 @@ dependencies { testImplementation "org.testfx:testfx-junit5:4.0.16-alpha" testImplementation "org.hamcrest:hamcrest-library:2.2" - checkstyle 'com.puppycrawl.tools:checkstyle:10.8.1' + checkstyle 'com.puppycrawl.tools:checkstyle:10.9.3' // xjc needs the runtime as well for the ant task, otherwise it fails xjc group: 'org.glassfish.jaxb', name: 'jaxb-xjc', version: '3.0.2' xjc group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2' diff --git a/buildres/csl/csl-locales/Gemfile.lock b/buildres/csl/csl-locales/Gemfile.lock index a15585eddab..56198040bff 100644 --- a/buildres/csl/csl-locales/Gemfile.lock +++ b/buildres/csl/csl-locales/Gemfile.lock @@ -62,20 +62,20 @@ GEM ruby-progressbar (~> 1.4) git_diff (0.4.3) hashdiff (0.3.7) - mini_portile2 (2.8.0) + mini_portile2 (2.8.1) multipart-post (2.1.1) namae (1.1.1) - nokogiri (1.13.4) + nokogiri (1.13.10) mini_portile2 (~> 2.8.0) racc (~> 1.4) - nokogiri (1.13.4-x64-mingw32) + nokogiri (1.13.10-x64-mingw32) racc (~> 1.4) octokit (4.21.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) ostruct (0.5.2) public_suffix (4.0.6) - racc (1.6.0) + racc (1.6.2) rake (13.0.6) reverse_markdown (2.1.1) nokogiri diff --git a/buildres/csl/csl-locales/composer.json b/buildres/csl/csl-locales/composer.json new file mode 100644 index 00000000000..d458ecc68b5 --- /dev/null +++ b/buildres/csl/csl-locales/composer.json @@ -0,0 +1,19 @@ +{ + "name": "citation-style-language/locales", + "description": "Citation Style Language (CSL) Locales", + "type": "library", + "license": "CC-BY-SA-3.0", + "homepage": "http://citationstyles.org/", + "authors": [ + { + "name": "Citation Style Language (CSL) Team", + "homepage": "http://citationstyles.org/about/#Credits" + } + ], + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "require": {} +} diff --git a/buildres/csl/csl-locales/locales-eu.xml b/buildres/csl/csl-locales/locales-eu.xml index 2579e55227c..20bf2efbb0a 100644 --- a/buildres/csl/csl-locales/locales-eu.xml +++ b/buildres/csl/csl-locales/locales-eu.xml @@ -4,6 +4,9 @@ Amaraun + + Miren BZ + This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License 2012-07-04T23:31:02+00:00 @@ -11,7 +14,7 @@ - + @@ -64,7 +67,7 @@ arg. et al. bidean - -(e)tik + hemendik: ibíd. in moldiztegian @@ -84,7 +87,7 @@ berreskuratua scale - version + bertsioa preprint @@ -170,7 +173,7 @@ . - lehengo + lehenengo bigarren hirugarren laugarren @@ -291,8 +294,8 @@ bertsoak - luburikia - luburukiak + liburukia + liburukiak @@ -565,23 +568,23 @@ -(e)k arg. eta itzul. - urtarrilak - otsailak - martxoak - apirilak - maiatzak - ekainak - uztailak - abuztuak - irailak - urriak - azaroak - abenduak + urtarrila + otsaila + martxoa + apirila + maiatza + ekaina + uztaila + abuztua + iraila + urria + azaroa + abendua urt. ots. - martx. + mar. apr. mai. eka. diff --git a/buildres/csl/csl-locales/locales-nb-NO.xml b/buildres/csl/csl-locales/locales-nb-NO.xml index d1b4499d0eb..2731a9ca648 100644 --- a/buildres/csl/csl-locales/locales-nb-NO.xml +++ b/buildres/csl/csl-locales/locales-nb-NO.xml @@ -307,7 +307,7 @@ op. s. - ss. + s. s. diff --git a/buildres/csl/csl-locales/locales-nl-NL.xml b/buildres/csl/csl-locales/locales-nl-NL.xml index 8852c3c340c..c03460db270 100644 --- a/buildres/csl/csl-locales/locales-nl-NL.xml +++ b/buildres/csl/csl-locales/locales-nl-NL.xml @@ -162,7 +162,7 @@ - + - : , ; @@ -614,7 +614,7 @@ lente zomer - herst + herfst winter diff --git a/buildres/csl/csl-locales/locales-nn-NO.xml b/buildres/csl/csl-locales/locales-nn-NO.xml index 8a5be2999b2..99f55cb4b33 100644 --- a/buildres/csl/csl-locales/locales-nn-NO.xml +++ b/buildres/csl/csl-locales/locales-nn-NO.xml @@ -307,7 +307,7 @@ op. s. - ss. + s. s. diff --git a/buildres/csl/csl-locales/locales-pt-BR.xml b/buildres/csl/csl-locales/locales-pt-BR.xml index 2b45696c987..d187312e3f1 100644 --- a/buildres/csl/csl-locales/locales-pt-BR.xml +++ b/buildres/csl/csl-locales/locales-pt-BR.xml @@ -6,6 +6,9 @@ Meira da Rocha + + + Renato Cirino This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License 2016-05-16T00:00:00+03:00 @@ -23,9 +26,9 @@ advance online publication - album - audio recording - film + álbum + gravação de áudio + filme henceforth loc. cit. no place @@ -34,22 +37,22 @@ n.p. on op. cit. - original work published + trabalho original publicado comunicação pessoal podcast - podcast episode + episódio de podcast preprint - radio broadcast - radio series - radio series episode - special issue - special section - television broadcast - television series - television series episode - video + transmissão de rádio + série radiofônica + episódio de série radiofônica + edição especial + sessão especial + transmissão de tv + série de tv + episódio de série de tv + vídeo working paper - acessado + acesso em e e outros anônimo @@ -91,48 +94,48 @@ preprint - journal article - magazine article - newspaper article - bill - - broadcast - - classic - collection + artigo de periódico + artigo de revista + artigo de jornal + lei + livro + transmissão + capítulo de livro + clássico + coleção dataset - document + documento entry - dictionary entry - encyclopedia entry - event + verbete de dicionário + verbete de enciclopédia + evento - graphic - hearing + gráfico + audiência entrevista legal case - legislation - manuscript - map - video recording + legislação + manuscrito + mapa + gravação de vídeo musical score - pamphlet - conference paper - patent + panleto + artigo de conferência + patente performance periodical comunicação pessoal - post - blog post + postagem + postagem de blog regulation report - review - book review + revisão + revisão de livro software - audio recording - presentation - standard - thesis + gravação de áudio + apresentação + padrão + tese treaty webpage @@ -150,7 +153,7 @@ video rec. rep. rev. - bk. rev. + rev. liv. audio rec. @@ -198,16 +201,16 @@ - act - acts + ato + atos - appendix - appendices + apêndice + apêndices - article - articles + artigo + artigos canon @@ -218,28 +221,28 @@ locations - equation - equations + equação + equações - rule - rules + regra + regras - scene - scenes + cena + cenas - table - tables + tabela + tabelas - title - titles + título + títulos livro @@ -396,52 +399,52 @@ chairs - compiler - compilers + compilador + compiladores - contributor - contributors + contribuidor + contribuidores - curator - curators + curador + curadores - executive producer - executive producers + produtor executivo + produtores executivos - guest - guests + convidado + convidados - host - hosts + anfitrião + anfitriões - narrator - narrators + narrador + narradores - organizer - organizers + organizador + organizadores performer performers - producer - producers + produtor + produtores - writer - writers + escritor + escritores - series creator - series creators + criador da série + criadores da série diretor @@ -543,11 +546,11 @@ with guest hosted by narrated by - organized by - performed by - produced by - written by - created by + organizado por + performado por + produzido por + escrito por + criado por por dirigido por organizado por diff --git a/buildres/csl/csl-styles/american-institute-of-physics.csl b/buildres/csl/csl-styles/american-institute-of-physics.csl index 5480ac8e545..b6ae0dc82e8 100644 --- a/buildres/csl/csl-styles/american-institute-of-physics.csl +++ b/buildres/csl/csl-styles/american-institute-of-physics.csl @@ -1,27 +1,30 @@ diff --git a/buildres/csl/csl-styles/chicago-annotated-bibliography.csl b/buildres/csl/csl-styles/chicago-annotated-bibliography.csl index 06b2bf8c859..82534d49163 100644 --- a/buildres/csl/csl-styles/chicago-annotated-bibliography.csl +++ b/buildres/csl/csl-styles/chicago-annotated-bibliography.csl @@ -185,9 +185,12 @@ - - + + + + + @@ -218,6 +221,11 @@ + + + + + @@ -561,7 +569,20 @@ - + + + + + + + + + + + + @@ -1145,9 +1166,17 @@ - - + + + + + + + + + + @@ -1158,9 +1187,16 @@ - - + + + + + + + + + diff --git a/buildres/csl/csl-styles/chicago-fullnote-bibliography-short-title-subsequent.csl b/buildres/csl/csl-styles/chicago-fullnote-bibliography-short-title-subsequent.csl index 16d2dca4044..3b987c9acb3 100644 --- a/buildres/csl/csl-styles/chicago-fullnote-bibliography-short-title-subsequent.csl +++ b/buildres/csl/csl-styles/chicago-fullnote-bibliography-short-title-subsequent.csl @@ -186,9 +186,12 @@ - - + + + + + @@ -219,6 +222,11 @@ + + + + + @@ -562,7 +570,20 @@ - + + + + + + + + + + + + @@ -1146,9 +1167,17 @@ - - + + + + + + + + + + @@ -1159,9 +1188,16 @@ - - + + + + + + + + + diff --git a/buildres/csl/csl-styles/chicago-fullnote-bibliography-with-ibid.csl b/buildres/csl/csl-styles/chicago-fullnote-bibliography-with-ibid.csl index a37796ea16c..bc0eedcac9f 100644 --- a/buildres/csl/csl-styles/chicago-fullnote-bibliography-with-ibid.csl +++ b/buildres/csl/csl-styles/chicago-fullnote-bibliography-with-ibid.csl @@ -185,9 +185,12 @@ - - + + + + + @@ -218,6 +221,11 @@ + + + + + @@ -561,7 +569,20 @@ - + + + + + + + + + + + + @@ -1145,9 +1166,17 @@ - - + + + + + + + + + + @@ -1158,9 +1187,16 @@ - - + + + + + + + + + diff --git a/buildres/csl/csl-styles/chicago-fullnote-bibliography.csl b/buildres/csl/csl-styles/chicago-fullnote-bibliography.csl index da4969f115d..23e94cda08e 100644 --- a/buildres/csl/csl-styles/chicago-fullnote-bibliography.csl +++ b/buildres/csl/csl-styles/chicago-fullnote-bibliography.csl @@ -34,7 +34,7 @@ Chicago format with full notes and bibliography - 2017-10-12T12:00:00+00:00 + 2022-01-16T19:46:01+00:00 This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License @@ -185,9 +185,12 @@ - - + + + + + @@ -218,6 +221,11 @@ + + + + + @@ -561,7 +569,20 @@ - + + + + + + + + + + + + @@ -1145,9 +1166,17 @@ - - + + + + + + + + + + @@ -1158,9 +1187,16 @@ - - + + + + + + + + + diff --git a/buildres/csl/csl-styles/chicago-library-list.csl b/buildres/csl/csl-styles/chicago-library-list.csl index 0f268c412ca..50adb02a727 100644 --- a/buildres/csl/csl-styles/chicago-library-list.csl +++ b/buildres/csl/csl-styles/chicago-library-list.csl @@ -185,9 +185,12 @@ - - + + + + + @@ -218,6 +221,11 @@ + + + + + @@ -561,7 +569,20 @@ - + + + + + + + + + + + + @@ -1145,9 +1166,17 @@ - - + + + + + + + + + + @@ -1158,9 +1187,16 @@ - - + + + + + + + + + diff --git a/buildres/csl/csl-styles/chicago-note-bibliography-with-ibid.csl b/buildres/csl/csl-styles/chicago-note-bibliography-with-ibid.csl index 66406945d34..93c2cb214af 100644 --- a/buildres/csl/csl-styles/chicago-note-bibliography-with-ibid.csl +++ b/buildres/csl/csl-styles/chicago-note-bibliography-with-ibid.csl @@ -185,9 +185,12 @@ - - + + + + + @@ -218,6 +221,11 @@ + + + + + @@ -561,7 +569,20 @@ - + + + + + + + + + + + + @@ -1145,9 +1166,17 @@ - - + + + + + + + + + + @@ -1158,9 +1187,16 @@ - - + + + + + + + + + diff --git a/buildres/csl/csl-styles/chicago-note-bibliography.csl b/buildres/csl/csl-styles/chicago-note-bibliography.csl index 83da96cb4de..217c873b527 100644 --- a/buildres/csl/csl-styles/chicago-note-bibliography.csl +++ b/buildres/csl/csl-styles/chicago-note-bibliography.csl @@ -185,9 +185,12 @@ - - + + + + + @@ -218,6 +221,11 @@ + + + + + @@ -561,7 +569,20 @@ - + + + + + + + + + + + + @@ -1145,9 +1166,17 @@ - - + + + + + + + + + + @@ -1158,9 +1187,16 @@ - - + + + + + + + + + diff --git a/buildres/csl/csl-styles/czech-journal-of-international-relations.csl b/buildres/csl/csl-styles/czech-journal-of-international-relations.csl new file mode 100644 index 00000000000..b979582f4a0 --- /dev/null +++ b/buildres/csl/csl-styles/czech-journal-of-international-relations.csl @@ -0,0 +1,268 @@ + + diff --git a/buildres/csl/csl-styles/dependent/monash-university-harvard.csl b/buildres/csl/csl-styles/dependent/monash-university-harvard.csl new file mode 100644 index 00000000000..3280a0c88fc --- /dev/null +++ b/buildres/csl/csl-styles/dependent/monash-university-harvard.csl @@ -0,0 +1,14 @@ + + diff --git a/buildres/csl/csl-styles/dependent/survey-of-ophthalmology.csl b/buildres/csl/csl-styles/dependent/survey-of-ophthalmology.csl deleted file mode 100644 index 654b1e0da0c..00000000000 --- a/buildres/csl/csl-styles/dependent/survey-of-ophthalmology.csl +++ /dev/null @@ -1,16 +0,0 @@ - - diff --git a/buildres/csl/csl-styles/elsevier-american-chemical-society.csl b/buildres/csl/csl-styles/elsevier-american-chemical-society.csl new file mode 100644 index 00000000000..e1f9d46fabd --- /dev/null +++ b/buildres/csl/csl-styles/elsevier-american-chemical-society.csl @@ -0,0 +1,292 @@ + + diff --git a/buildres/csl/csl-styles/harvard-stellenbosch-university.csl b/buildres/csl/csl-styles/harvard-stellenbosch-university.csl index 67e4d4d85ca..af978c13db6 100644 --- a/buildres/csl/csl-styles/harvard-stellenbosch-university.csl +++ b/buildres/csl/csl-styles/harvard-stellenbosch-university.csl @@ -18,7 +18,7 @@ - v. + vol. available @@ -31,7 +31,7 @@ - @@ -39,15 +39,16 @@ - - - + + + @@ -175,26 +178,25 @@ - - - - - + + + + + + + + + + - - - - - - + - + @@ -225,7 +227,7 @@ - + @@ -239,7 +241,12 @@ - + + + + + + @@ -282,12 +289,20 @@ - - - - + + + + + + + + + + + + + - diff --git a/buildres/csl/csl-styles/hochschule-fur-soziale-arbeit-fhnw.csl b/buildres/csl/csl-styles/hochschule-fur-soziale-arbeit-fhnw.csl index d579949b5a9..915a1821eb3 100644 --- a/buildres/csl/csl-styles/hochschule-fur-soziale-arbeit-fhnw.csl +++ b/buildres/csl/csl-styles/hochschule-fur-soziale-arbeit-fhnw.csl @@ -177,7 +177,7 @@ - + diff --git a/buildres/csl/csl-styles/monash-university-harvard.csl b/buildres/csl/csl-styles/iainutuban-tarbiyah.csl similarity index 81% rename from buildres/csl/csl-styles/monash-university-harvard.csl rename to buildres/csl/csl-styles/iainutuban-tarbiyah.csl index 6021110b2d1..500c582cd59 100644 --- a/buildres/csl/csl-styles/monash-university-harvard.csl +++ b/buildres/csl/csl-styles/iainutuban-tarbiyah.csl @@ -1,28 +1,29 @@ - diff --git a/buildres/csl/csl-styles/the-accounting-review.csl b/buildres/csl/csl-styles/the-accounting-review.csl index a0931ad6bbf..64133cc8699 100644 --- a/buildres/csl/csl-styles/the-accounting-review.csl +++ b/buildres/csl/csl-styles/the-accounting-review.csl @@ -4,7 +4,7 @@ The Accounting Review http://www.zotero.org/styles/the-accounting-review - + Sebastian Karcher @@ -12,11 +12,14 @@ Julian Onions julian.onions@gmail.com + + Patrick O'Brien + 0001-4826 1558-7967 - 2012-10-25T21:15:26+00:00 + 2023-03-16T09:10:03+00:00 This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License @@ -392,7 +395,7 @@ - + @@ -403,7 +406,7 @@ - + diff --git a/buildres/csl/csl-styles/trames.csl b/buildres/csl/csl-styles/trames.csl new file mode 100644 index 00000000000..ba1a59d3a7b --- /dev/null +++ b/buildres/csl/csl-styles/trames.csl @@ -0,0 +1,243 @@ + + diff --git a/buildres/csl/csl-styles/travail-et-emploi.csl b/buildres/csl/csl-styles/travail-et-emploi.csl new file mode 100644 index 00000000000..8da76eb6d48 --- /dev/null +++ b/buildres/csl/csl-styles/travail-et-emploi.csl @@ -0,0 +1,394 @@ + + diff --git a/buildres/csl/csl-styles/ucl-university-college-apa.csl b/buildres/csl/csl-styles/ucl-university-college-apa.csl index 283f14aef7b..7f514e6fbfb 100644 --- a/buildres/csl/csl-styles/ucl-university-college-apa.csl +++ b/buildres/csl/csl-styles/ucl-university-college-apa.csl @@ -1580,7 +1580,6 @@ - diff --git a/buildres/csl/csl-styles/uni-fribourg-theologie.csl b/buildres/csl/csl-styles/uni-fribourg-theologie.csl new file mode 100644 index 00000000000..508154f893e --- /dev/null +++ b/buildres/csl/csl-styles/uni-fribourg-theologie.csl @@ -0,0 +1,266 @@ + + diff --git a/buildres/csl/csl-styles/universite-du-quebec-a-montreal.csl b/buildres/csl/csl-styles/universite-du-quebec-a-montreal.csl index fbb02bda7e4..11211efce41 100644 --- a/buildres/csl/csl-styles/universite-du-quebec-a-montreal.csl +++ b/buildres/csl/csl-styles/universite-du-quebec-a-montreal.csl @@ -408,6 +408,12 @@ + + + + + + @@ -511,10 +517,20 @@ - - - - + + + + + + + + + + + + + + diff --git a/buildres/csl/csl-styles/university-of-pretoria-harvard-theology-religion.csl b/buildres/csl/csl-styles/university-of-pretoria-harvard-theology-religion.csl index f59a9edfa0a..4bb738acb44 100644 --- a/buildres/csl/csl-styles/university-of-pretoria-harvard-theology-religion.csl +++ b/buildres/csl/csl-styles/university-of-pretoria-harvard-theology-religion.csl @@ -13,7 +13,7 @@ - 2022-06-22T00:06:00+00:00 + 2023-03-30T00:13:00+00:00 This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License @@ -249,23 +249,25 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + @@ -313,6 +315,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/buildres/csl/csl-styles/vancouver-alphabetical.csl b/buildres/csl/csl-styles/vancouver-alphabetical.csl new file mode 100644 index 00000000000..4731ecd88ac --- /dev/null +++ b/buildres/csl/csl-styles/vancouver-alphabetical.csl @@ -0,0 +1,346 @@ + + diff --git a/buildres/csl/csl-styles/zeitschrift-fur-geschichtsdidaktik.csl b/buildres/csl/csl-styles/zeitschrift-fur-geschichtsdidaktik.csl index 47f088f4bd6..35b692db828 100644 --- a/buildres/csl/csl-styles/zeitschrift-fur-geschichtsdidaktik.csl +++ b/buildres/csl/csl-styles/zeitschrift-fur-geschichtsdidaktik.csl @@ -8,6 +8,7 @@ + Patrick O'Brien @@ -16,12 +17,12 @@ 1610-5982 2196-8292 - 2021-07-26T10:07:30+00:00 + 2023-03-13T09:23:25+00:00 This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License - u. a. + u.a. gesehen am H. @@ -29,15 +30,15 @@ - - + + - - + + @@ -85,7 +86,7 @@ - + @@ -117,7 +118,7 @@ @@ -297,7 +298,7 @@ - + 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 9cbc6e46dad..8a6182e9f1b 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 @@ -85,7 +85,7 @@ In the following, we will use `c:\git-repositories` as base folder: ```cmd cd \ mkdir git-repositories -cd git-reposiroties +cd git-repositories ``` **Note that putting the repo jabref directly under `C:\` or any other drive letter under windows causes compile errors** diff --git a/src/main/java/org/jabref/gui/DialogService.java b/src/main/java/org/jabref/gui/DialogService.java index 26cf46c00a1..c152bdcb343 100644 --- a/src/main/java/org/jabref/gui/DialogService.java +++ b/src/main/java/org/jabref/gui/DialogService.java @@ -20,6 +20,7 @@ import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.logic.l10n.Localization; +import org.controlsfx.control.textfield.CustomPasswordField; import org.controlsfx.dialog.ProgressDialog; /** @@ -161,6 +162,14 @@ boolean showConfirmationDialogWithOptOutAndWait(String title, String content, String okButtonLabel, String cancelButtonLabel, String optOutMessage, Consumer optOutAction); + /** + * This will create and display new {@link CustomPasswordField} that doesn't show the text, and two buttons + * one cancel and one ok. + * + * @return the entered password if pressed "OK", null otherwise + */ + Optional showPasswordDialogAndWait(String title, String header, String content); + /** * Shows a custom dialog without returning any results. * diff --git a/src/main/java/org/jabref/gui/JabRefDialogService.java b/src/main/java/org/jabref/gui/JabRefDialogService.java index d21e0b3b9d9..9709223cc2b 100644 --- a/src/main/java/org/jabref/gui/JabRefDialogService.java +++ b/src/main/java/org/jabref/gui/JabRefDialogService.java @@ -26,6 +26,7 @@ import javafx.scene.control.DialogPane; import javafx.scene.control.Label; import javafx.scene.control.TextInputDialog; +import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; @@ -49,6 +50,7 @@ import com.tobiasdiez.easybind.EasyBind; import org.controlsfx.control.Notifications; import org.controlsfx.control.TaskProgressView; +import org.controlsfx.control.textfield.CustomPasswordField; import org.controlsfx.dialog.ExceptionDialog; import org.controlsfx.dialog.ProgressDialog; import org.slf4j.Logger; @@ -270,6 +272,30 @@ public Optional showCustomDialogAndWait(javafx.scene.control.Dialog di return dialog.showAndWait(); } + @Override + public Optional showPasswordDialogAndWait(String title, String header, String content) { + javafx.scene.control.Dialog dialog = new javafx.scene.control.Dialog<>(); + dialog.setTitle(title); + dialog.setHeaderText(header); + + CustomPasswordField passwordField = new CustomPasswordField(); + + HBox box = new HBox(); + box.setSpacing(10); + box.getChildren().addAll(new Label(content), passwordField); + dialog.setTitle(title); + dialog.getDialogPane().setContent(box); + + dialog.getDialogPane().getButtonTypes().addAll(ButtonType.CANCEL, ButtonType.OK); + dialog.setResultConverter(dialogButton -> { + if (dialogButton == ButtonType.OK) { + return passwordField.getText(); + } + return null; + }); + return dialog.showAndWait(); + } + @Override public void showProgressDialog(String title, String content, Task task) { ProgressDialog progressDialog = new ProgressDialog(task); diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 4769fd425e7..aef94bdf1dd 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -18,6 +18,7 @@ import javafx.beans.binding.StringBinding; import javafx.collections.transformation.FilteredList; import javafx.concurrent.Task; +import javafx.event.ActionEvent; import javafx.geometry.Orientation; import javafx.scene.Group; import javafx.scene.Node; @@ -842,6 +843,13 @@ private MenuBar createMenu() { SpecialFieldMenuItemFactory.getSpecialFieldSingleItem(SpecialField.PRINTED, factory, this, dialogService, prefs, undoManager, stateManager), SpecialFieldMenuItemFactory.createSpecialFieldMenu(SpecialField.PRIORITY, factory, this, dialogService, prefs, undoManager, stateManager), SpecialFieldMenuItemFactory.createSpecialFieldMenu(SpecialField.READ_STATUS, factory, this, dialogService, prefs, undoManager, stateManager)); + edit.addEventHandler(ActionEvent.ACTION, event -> { + // Work around for mac only issue, where cmd+v on a dialogue triggers the paste action of menu item, resulting in addition of the pasted content in the MainTable. + // If the mainscreen is not focused, the actions captured by menu are consumed. + if (OS.OS_X && !mainStage.focusedProperty().get()) { + event.consume(); + } + }); // @formatter:off library.getItems().addAll( diff --git a/src/main/java/org/jabref/gui/JabRefGUI.java b/src/main/java/org/jabref/gui/JabRefGUI.java index 4f5963945ea..95bea74d9af 100644 --- a/src/main/java/org/jabref/gui/JabRefGUI.java +++ b/src/main/java/org/jabref/gui/JabRefGUI.java @@ -20,6 +20,7 @@ import org.jabref.gui.shared.SharedDatabaseUIManager; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.net.ProxyRegisterer; import org.jabref.logic.shared.DatabaseNotSupportedException; import org.jabref.logic.shared.exception.InvalidDBMSConnectionPropertiesException; import org.jabref.logic.shared.exception.NotASharedDatabaseException; @@ -27,6 +28,7 @@ import org.jabref.preferences.GuiPreferences; import org.jabref.preferences.PreferencesService; +import com.airhacks.afterburner.injection.Injector; import impl.org.controlsfx.skin.DecorationPane; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,6 +63,15 @@ public JabRefGUI(Stage mainStage, List databases, boolean isBlank, Globals.TASK_EXECUTOR, preferencesService.getInternalPreferences()) .checkForNewVersionDelayed(); + + if (preferencesService.getProxyPreferences().shouldUseProxy() && preferencesService.getProxyPreferences().shouldUseAuthentication()) { + DialogService dialogService = Injector.instantiateModelOrService(DialogService.class); + dialogService.showPasswordDialogAndWait(Localization.lang("Proxy configuration"), Localization.lang("Proxy requires password"), Localization.lang("Password")) + .ifPresent(newPassword -> { + preferencesService.getProxyPreferences().setPassword(newPassword); + ProxyRegisterer.register(preferencesService.getProxyPreferences()); + }); + } } private void openWindow(Stage mainStage) { diff --git a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeViewModel.java b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeViewModel.java index 1faca05630a..0e176c0bb2e 100644 --- a/src/main/java/org/jabref/gui/customentrytypes/EntryTypeViewModel.java +++ b/src/main/java/org/jabref/gui/customentrytypes/EntryTypeViewModel.java @@ -22,10 +22,10 @@ public EntryTypeViewModel(BibEntryType entryType, Predicate isMultiline) this.entryType.set(entryType); List allFieldsForType = entryType.getAllBibFields() - .stream().map(bibField -> new FieldViewModel(bibField.getField(), - entryType.isRequired(bibField.getField()), - bibField.getPriority(), - isMultiline.test(bibField.getField()))) + .stream().map(bibField -> new FieldViewModel(bibField.field(), + entryType.isRequired(bibField.field()), + bibField.priority(), + isMultiline.test(bibField.field()))) .collect(Collectors.toList()); fields = FXCollections.observableArrayList((allFieldsForType)); } diff --git a/src/main/java/org/jabref/gui/duplicationFinder/DuplicateResolverDialog.java b/src/main/java/org/jabref/gui/duplicationFinder/DuplicateResolverDialog.java index 205e4df75de..15a27d4f810 100644 --- a/src/main/java/org/jabref/gui/duplicationFinder/DuplicateResolverDialog.java +++ b/src/main/java/org/jabref/gui/duplicationFinder/DuplicateResolverDialog.java @@ -122,6 +122,7 @@ private void init(BibEntry one, BibEntry two, DuplicateResolverType type) { this.setResultConverter(button -> { // Updates the window state on button press stateManager.setDialogWindowState(getClass().getSimpleName(), new DialogWindowState(this.getX(), this.getY(), this.getDialogPane().getHeight(), this.getDialogPane().getWidth())); + threeWayMerge.saveConfiguration(); if (button.equals(first)) { return DuplicateResolverResult.KEEP_LEFT; diff --git a/src/main/java/org/jabref/gui/entryeditor/OtherFieldsTab.java b/src/main/java/org/jabref/gui/entryeditor/OtherFieldsTab.java index 50a8066d2cd..180ea465c53 100644 --- a/src/main/java/org/jabref/gui/entryeditor/OtherFieldsTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/OtherFieldsTab.java @@ -75,7 +75,7 @@ protected Set determineFieldsToShow(BibEntry entry) { Set otherFields = entry.getFields().stream().filter(field -> !allKnownFields.contains(field)).collect(Collectors.toCollection(LinkedHashSet::new)); otherFields.removeAll(entryType.get().getDeprecatedFields(mode)); - otherFields.removeAll(entryType.get().getOptionalFields().stream().map(BibField::getField).collect(Collectors.toSet())); + otherFields.removeAll(entryType.get().getOptionalFields().stream().map(BibField::field).collect(Collectors.toSet())); otherFields.remove(InternalField.KEY_FIELD); otherFields.removeAll(customTabFieldNames); return otherFields; diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java index f18975dad88..1e3daafffe7 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java @@ -385,7 +385,7 @@ public boolean delete() { Optional file = linkedFile.findIn(databaseContext, preferences.getFilePreferences()); if (file.isEmpty()) { - LOGGER.warn("Could not find file " + linkedFile.getLink()); + LOGGER.warn("Could not find file {}", linkedFile.getLink()); return true; } @@ -407,7 +407,7 @@ public boolean delete() { return true; } catch (IOException ex) { dialogService.showErrorDialogAndWait(Localization.lang("Cannot delete file"), Localization.lang("File permission error")); - LOGGER.warn("File permission error while deleting: " + linkedFile, ex); + LOGGER.warn("File permission error while deleting: {}", linkedFile, ex); } } } diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java index e93c3952858..b59d1a3164d 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java @@ -1,6 +1,5 @@ package org.jabref.gui.fieldeditors; -import java.util.List; import java.util.Optional; import javafx.beans.binding.Bindings; @@ -41,6 +40,7 @@ import org.jabref.gui.icon.IconTheme; import org.jabref.gui.importer.GrobidOptInDialogHelper; import org.jabref.gui.keyboard.KeyBinding; +import org.jabref.gui.linkedfile.DeleteFileAction; import org.jabref.gui.util.BindingsHelper; import org.jabref.gui.util.TaskExecutor; import org.jabref.gui.util.ViewModelListCellFactory; @@ -218,10 +218,8 @@ private void setUpKeyBindings() { if (keyBinding.isPresent()) { switch (keyBinding.get()) { case DELETE_ENTRY: - List toBeDeleted = List.copyOf(listView.getSelectionModel().getSelectedItems()); - for (LinkedFileViewModel selectedItem : toBeDeleted) { - viewModel.deleteFile(selectedItem); - } + new DeleteFileAction(dialogService, preferencesService, databaseContext, + viewModel, listView).execute(); event.consume(); break; default: diff --git a/src/main/java/org/jabref/gui/groups/GroupTree.css b/src/main/java/org/jabref/gui/groups/GroupTree.css index 272e9a8cb83..29a4b5a204e 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTree.css +++ b/src/main/java/org/jabref/gui/groups/GroupTree.css @@ -18,11 +18,11 @@ } .numberColumn > .hits { - -fx-font-size: 85%; + -fx-font-size: 0.75em; -fx-background-color: -jr-group-hits-bg; -fx-padding: 0.4em 0.4em 0.4em 0.4em; -fx-background-insets: 0; - -fx-background-radius: 0.8em; + -fx-background-radius: 0.7em; } .numberColumn > .hits .text { diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeView.java b/src/main/java/org/jabref/gui/groups/GroupTreeView.java index eac9957ff29..9cc3ce11d27 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeView.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeView.java @@ -2,6 +2,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.text.DecimalFormat; import java.time.Duration; import java.util.ArrayList; import java.util.LinkedList; @@ -11,6 +12,7 @@ import java.util.stream.Collectors; import javafx.application.Platform; +import javafx.beans.binding.Bindings; import javafx.beans.property.ObjectProperty; import javafx.css.PseudoClass; import javafx.scene.control.Button; @@ -114,9 +116,9 @@ private void createNodes() { mainColumn.setResizable(true); numberColumn = new TreeTableColumn<>(); numberColumn.getStyleClass().add("numberColumn"); - numberColumn.setMinWidth(40d); - numberColumn.setMaxWidth(40d); - numberColumn.setPrefWidth(40d); + numberColumn.setMinWidth(60d); + numberColumn.setMaxWidth(60d); + numberColumn.setPrefWidth(60d); numberColumn.setResizable(false); expansionNodeColumn = new TreeTableColumn<>(); expansionNodeColumn.getStyleClass().add("expansionNodeColumn"); @@ -131,7 +133,7 @@ private void createNodes() { groupTree.getColumns().addAll(List.of(mainColumn, numberColumn, expansionNodeColumn)); this.setCenter(groupTree); - mainColumn.prefWidthProperty().bind(groupTree.widthProperty().subtract(60d).subtract(15)); + mainColumn.prefWidthProperty().bind(groupTree.widthProperty().subtract(80d).subtract(15d)); addNewGroup = new Button(Localization.lang("Add group")); addNewGroup.setId("addNewGroup"); @@ -213,10 +215,27 @@ private void initialize() { } if (newValue) { - text.textProperty().bind(group.getHits().asString()); + text.textProperty().bind(group.getHits().map(Number::intValue).map(this::getFormattedNumber)); } }); text.getStyleClass().setAll("text"); + + text.styleProperty().bind(Bindings.createStringBinding(() -> { + double reducedFontSize; + double font_size = preferencesService.getAppearancePreferences().getMainFontSize(); + // For each breaking point, the font size is reduced 0.20 em to fix issue 8797 + if (font_size > 26.0) { + reducedFontSize = 0.25; + } else if (font_size > 22.0) { + reducedFontSize = 0.35; + } else if (font_size > 18.0) { + reducedFontSize = 0.55; + } else { + reducedFontSize = 0.75; + } + return String.format("-fx-font-size: %fem;", reducedFontSize); + }, preferencesService.getAppearancePreferences().mainFontSizeProperty())); + node.getChildren().add(text); node.setMaxWidth(Control.USE_PREF_SIZE); return node; @@ -497,6 +516,17 @@ private void addNewGroup() { viewModel.addNewGroupToRoot(); } + private String getFormattedNumber(int hits) { + if (hits >= 1000000) { + double millions = hits / 1000000.0; + return new DecimalFormat("#,##0.#").format(millions) + "m"; + } else if (hits >= 1000) { + double thousands = hits / 1000.0; + return new DecimalFormat("#,##0.#").format(thousands) + "k"; + } + return Integer.toString(hits); + } + /** * Workaround taken from https://github.com/controlsfx/controlsfx/issues/330 */ diff --git a/src/main/java/org/jabref/gui/linkedfile/DeleteFileAction.java b/src/main/java/org/jabref/gui/linkedfile/DeleteFileAction.java new file mode 100644 index 00000000000..a1f9ef3bb15 --- /dev/null +++ b/src/main/java/org/jabref/gui/linkedfile/DeleteFileAction.java @@ -0,0 +1,138 @@ +package org.jabref.gui.linkedfile; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; + +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonBar; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ListView; + +import org.jabref.gui.DialogService; +import org.jabref.gui.actions.SimpleCommand; +import org.jabref.gui.fieldeditors.LinkedFileViewModel; +import org.jabref.gui.fieldeditors.LinkedFilesEditorViewModel; +import org.jabref.logic.l10n.Localization; +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.LinkedFile; +import org.jabref.preferences.PreferencesService; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DeleteFileAction extends SimpleCommand { + + private static final Logger LOGGER = LoggerFactory.getLogger(DeleteFileAction.class); + + private final DialogService dialogService; + private final PreferencesService preferences; + private final BibDatabaseContext databaseContext; + private final LinkedFilesEditorViewModel viewModel; + private final ListView listView; + + public DeleteFileAction(DialogService dialogService, + PreferencesService preferences, + BibDatabaseContext databaseContext, + LinkedFilesEditorViewModel viewModel, + ListView listView) { + this.dialogService = dialogService; + this.preferences = preferences; + this.databaseContext = databaseContext; + this.viewModel = viewModel; + this.listView = listView; + } + + @Override + public void execute() { + List toBeDeleted = List.copyOf(listView.getSelectionModel().getSelectedItems()); + + if (toBeDeleted.isEmpty()) { + dialogService.notify(Localization.lang("This operation requires selected linked files.")); + return; + } + + String dialogTitle; + String dialogContent; + + if (toBeDeleted.size() != 1) { + dialogTitle = Localization.lang("Delete %0 files", toBeDeleted.size()); + dialogContent = Localization.lang("Delete %0 files permanently from disk, or just remove the files from the entry? " + + "Pressing Delete will delete the files permanently from disk.", toBeDeleted.size()); + } else { + Optional file = toBeDeleted.get(0).getFile().findIn(databaseContext, preferences.getFilePreferences()); + + if (file.isPresent()) { + dialogTitle = Localization.lang("Delete '%0'", file.get().getFileName().toString()); + dialogContent = Localization.lang("Delete '%0' permanently from disk, or just remove the file from the entry? " + + "Pressing Delete will delete the file permanently from disk.", file.get().toString()); + } else { + dialogService.notify(Localization.lang("Error accessing file '%0'.", toBeDeleted.get(0).getFile().getLink())); + return; + } + } + + ButtonType removeFromEntry = new ButtonType(Localization.lang("Remove from entry"), ButtonBar.ButtonData.YES); + ButtonType deleteFromEntry = new ButtonType(Localization.lang("Delete from disk")); + Optional buttonType = dialogService.showCustomButtonDialogAndWait(Alert.AlertType.INFORMATION, + dialogTitle, dialogContent, removeFromEntry, deleteFromEntry, ButtonType.CANCEL); + + if (buttonType.isPresent()) { + if (buttonType.get().equals(removeFromEntry)) { + deleteFiles(toBeDeleted, false); + } + + if (buttonType.get().equals(deleteFromEntry)) { + deleteFiles(toBeDeleted, true); + } + } + } + + /** + * Deletes the files from the entry and optionally from disk. + * + * @param toBeDeleted the files to be deleted + * @param deleteFromDisk if true, the files are deleted from disk, otherwise they are only removed from the entry + */ + private void deleteFiles(List toBeDeleted, boolean deleteFromDisk) { + for (LinkedFileViewModel fileViewModel : toBeDeleted) { + if (fileViewModel.getFile().isOnlineLink()) { + viewModel.removeFileLink(fileViewModel); + } else { + if (deleteFromDisk) { + deleteFileFromDisk(fileViewModel); + } + viewModel.getFiles().remove(fileViewModel); + } + } + } + + /** + * Deletes the file from disk without asking the user for confirmation. + * + * @param fileViewModel the file to be deleted + */ + public void deleteFileFromDisk(LinkedFileViewModel fileViewModel) { + LinkedFile linkedFile = fileViewModel.getFile(); + + Optional file = linkedFile.findIn(databaseContext, preferences.getFilePreferences()); + + if (file.isEmpty()) { + LOGGER.warn("Could not find file {}", linkedFile.getLink()); + } + + if (file.isPresent()) { + try { + Files.delete(file.get()); + } catch ( + IOException ex) { + dialogService.showErrorDialogAndWait(Localization.lang("Cannot delete file"), Localization.lang("File permission error")); + LOGGER.warn("File permission error while deleting: {}", linkedFile, ex); + } + } else { + dialogService.notify(Localization.lang("Error accessing file '%0'.", linkedFile.getLink())); + } + } +} diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java index 23a82a1ddde..8be99e1bfee 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeEntriesDialog.java @@ -36,6 +36,7 @@ private void init() { ButtonType replaceEntries = new ButtonType(Localization.lang("Merge entries"), ButtonBar.ButtonData.OK_DONE); this.getDialogPane().getButtonTypes().setAll(ButtonType.CANCEL, replaceEntries); this.setResultConverter(buttonType -> { + threeWayMergeView.saveConfiguration(); if (buttonType.equals(replaceEntries)) { return new EntriesMergeResult(one, two, threeWayMergeView.getLeftEntry(), threeWayMergeView.getRightEntry(), threeWayMergeView.getMergedEntry()); } else { diff --git a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java index 5767d747a4c..fd2b1b3105f 100644 --- a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java +++ b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java @@ -191,4 +191,8 @@ public BibEntry getLeftEntry() { public BibEntry getRightEntry() { return viewModel.getRightEntry(); } + + public void saveConfiguration() { + toolbar.saveToolbarConfiguration(); + } } diff --git a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/cell/ThreeWayMergeCell.java b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/cell/ThreeWayMergeCell.java index 2a4b020aaef..1c9df85a6bd 100644 --- a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/cell/ThreeWayMergeCell.java +++ b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/cell/ThreeWayMergeCell.java @@ -6,9 +6,6 @@ import com.tobiasdiez.easybind.EasyBind; -/** - * - */ public abstract class ThreeWayMergeCell extends HBox { public static final String ODD_PSEUDO_CLASS = "odd"; public static final String EVEN_PSEUDO_CLASS = "even"; diff --git a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/toolbar/ThreeWayMergeToolbar.java b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/toolbar/ThreeWayMergeToolbar.java index 8a656830e4d..03a595741e5 100644 --- a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/toolbar/ThreeWayMergeToolbar.java +++ b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/toolbar/ThreeWayMergeToolbar.java @@ -17,9 +17,11 @@ import org.jabref.gui.mergeentries.newmergedialog.DiffMethod; import org.jabref.gui.mergeentries.newmergedialog.diffhighlighter.DiffHighlighter.BasicDiffMethod; import org.jabref.logic.l10n.Localization; +import org.jabref.preferences.GuiPreferences; import org.jabref.preferences.PreferencesService; import com.airhacks.afterburner.views.ViewLoader; +import com.google.common.base.Enums; import com.tobiasdiez.easybind.EasyBind; import com.tobiasdiez.easybind.EasyBinding; import jakarta.inject.Inject; @@ -66,7 +68,7 @@ public ThreeWayMergeToolbar() { public void initialize() { showDiff = EasyBind.map(plainTextOrDiffComboBox.valueProperty(), plainTextOrDiff -> plainTextOrDiff == PlainTextOrDiff.Diff); plainTextOrDiffComboBox.getItems().addAll(PlainTextOrDiff.values()); - plainTextOrDiffComboBox.getSelectionModel().select(PlainTextOrDiff.Diff); + plainTextOrDiffComboBox.setConverter(new StringConverter<>() { @Override public String toString(PlainTextOrDiff plainTextOrDiff) { @@ -81,7 +83,7 @@ public PlainTextOrDiff fromString(String string) { diffViewComboBox.disableProperty().bind(notShowDiffProperty()); diffViewComboBox.getItems().addAll(DiffView.values()); - diffViewComboBox.getSelectionModel().select(DiffView.UNIFIED); + diffViewComboBox.setConverter(new StringConverter<>() { @Override public String toString(DiffView diffView) { @@ -105,11 +107,30 @@ public DiffView fromString(String string) { } })); - diffHighlightingMethodToggleGroup.selectToggle(highlightWordsRadioButton); - plainTextOrDiffComboBox.valueProperty().set(PlainTextOrDiff.Diff); - onlyShowChangedFieldsCheck.selectedProperty().bindBidirectional(preferencesService.getGuiPreferences().mergeShowChangedFieldOnlyProperty()); onlyShowChangedFields.bind(onlyShowChangedFieldsCheck.selectedProperty()); + + loadSavedConfiguration(); + } + + private void loadSavedConfiguration() { + GuiPreferences guiPreferences = preferencesService.getGuiPreferences(); + + PlainTextOrDiff plainTextOrDiffPreference = guiPreferences.getMergeShouldShowDiff() ? PlainTextOrDiff.Diff : PlainTextOrDiff.PLAIN_TEXT; + plainTextOrDiffComboBox.getSelectionModel().select(plainTextOrDiffPreference); + + DiffView diffViewPreference = guiPreferences.getMergeShouldShowUnifiedDiff() ? DiffView.UNIFIED : DiffView.SPLIT; + diffViewComboBox.getSelectionModel().select(diffViewPreference); + + diffHighlightingMethodToggleGroup.selectToggle(guiPreferences.getMergeHighlightWords() ? highlightWordsRadioButton : highlightCharactersRadioButtons); + } + + public void saveToolbarConfiguration() { + preferencesService.getGuiPreferences().setMergeShouldShowDiff(plainTextOrDiffComboBox.getValue() == PlainTextOrDiff.Diff); + preferencesService.getGuiPreferences().setMergeShouldShowUnifiedDiff(diffViewComboBox.getValue() == DiffView.UNIFIED); + + boolean highlightWordsRadioButtonValue = diffHighlightingMethodToggleGroup.getSelectedToggle().equals(highlightWordsRadioButton); + preferencesService.getGuiPreferences().setMergeHighlightWords(highlightWordsRadioButtonValue); } public ObjectProperty diffViewProperty() { @@ -185,6 +206,10 @@ public enum PlainTextOrDiff { this.value = value; } + public static PlainTextOrDiff parse(String name) { + return Enums.getIfPresent(PlainTextOrDiff.class, name).or(Diff); + } + public String getValue() { return value; } @@ -203,6 +228,10 @@ public enum DiffView { this.value = value; } + public static DiffView parse(String name) { + return Enums.getIfPresent(DiffView.class, name).or(UNIFIED); + } + public String getValue() { return value; } diff --git a/src/main/java/org/jabref/gui/preview/PreviewViewer.java b/src/main/java/org/jabref/gui/preview/PreviewViewer.java index 78a7d47d2ee..222478609e0 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewViewer.java +++ b/src/main/java/org/jabref/gui/preview/PreviewViewer.java @@ -244,7 +244,8 @@ public void setEntry(BibEntry newEntry) { private void update() { if (entry.isEmpty() || (layout == null)) { - // Nothing to do + // Make sure that the preview panel is not completely white, especially with dark theme on + setPreviewText(""); return; } diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchResultDialog.java b/src/main/java/org/jabref/gui/search/GlobalSearchResultDialog.java index 1b330015949..3109bb7d6a4 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchResultDialog.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchResultDialog.java @@ -58,6 +58,11 @@ private void initialize() { resultsTable.getColumns().removeIf(col -> col instanceof SpecialFieldColumn); resultsTable.getSelectionModel().selectFirst(); + + if (resultsTable.getSelectionModel().getSelectedItem() != null) { + previewViewer.setEntry(resultsTable.getSelectionModel().getSelectedItem().getEntry()); + } + resultsTable.getSelectionModel().selectedItemProperty().addListener((obs, old, newValue) -> { if (newValue != null) { previewViewer.setEntry(newValue.getEntry()); diff --git a/src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java b/src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java index 4632d13cc3d..11ebd5ffebe 100644 --- a/src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java +++ b/src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java @@ -117,7 +117,7 @@ private void writeRequiredFieldsFirstRemainingFieldsSecond(BibEntry entry, BibWr List optionalFields = type.get() .getOptionalFields() .stream() - .map(BibField::getField) + .map(BibField::field) .sorted(Comparator.comparing(Field::getName)) .collect(Collectors.toList()); diff --git a/src/main/java/org/jabref/logic/bibtex/comparator/BibStringDiff.java b/src/main/java/org/jabref/logic/bibtex/comparator/BibStringDiff.java index 8050af537fa..65fe125a765 100644 --- a/src/main/java/org/jabref/logic/bibtex/comparator/BibStringDiff.java +++ b/src/main/java/org/jabref/logic/bibtex/comparator/BibStringDiff.java @@ -57,7 +57,7 @@ public static List compare(BibDatabase originalDatabase, BibDatab Optional match = newDatabase .getStringValues().stream() - .filter(test -> test.getName().equals(original.getName())) + .filter(test -> test.getContent().equals(original.getContent())) .findAny(); if (match.isPresent()) { // We have found a string with the same content. It cannot have the same diff --git a/src/main/java/org/jabref/logic/database/DuplicateCheck.java b/src/main/java/org/jabref/logic/database/DuplicateCheck.java index b2053c21120..c665fe5aec9 100644 --- a/src/main/java/org/jabref/logic/database/DuplicateCheck.java +++ b/src/main/java/org/jabref/logic/database/DuplicateCheck.java @@ -123,7 +123,7 @@ private static boolean compareOptionalFields(final BibEntryType type, if (optionalFields.isEmpty()) { return req[0] >= DuplicateCheck.DUPLICATE_THRESHOLD; } - final double[] opt = DuplicateCheck.compareFieldSet(optionalFields.stream().map(BibField::getField).collect(Collectors.toSet()), one, two); + final double[] opt = DuplicateCheck.compareFieldSet(optionalFields.stream().map(BibField::field).collect(Collectors.toSet()), one, two); final double numerator = (DuplicateCheck.REQUIRED_WEIGHT * req[0] * req[1]) + (opt[0] * opt[1]); final double denominator = (req[1] * DuplicateCheck.REQUIRED_WEIGHT) + opt[1]; final double totValue = numerator / denominator; diff --git a/src/main/java/org/jabref/logic/exporter/AtomicFileOutputStream.java b/src/main/java/org/jabref/logic/exporter/AtomicFileOutputStream.java index 5694d79b803..58f98365592 100644 --- a/src/main/java/org/jabref/logic/exporter/AtomicFileOutputStream.java +++ b/src/main/java/org/jabref/logic/exporter/AtomicFileOutputStream.java @@ -62,6 +62,7 @@ public class AtomicFileOutputStream extends FilterOutputStream { private final Path temporaryFile; private final FileLock temporaryFileLock; + /** * A backup of the target file (if it exists), created when the stream is closed */ @@ -75,7 +76,7 @@ public class AtomicFileOutputStream extends FilterOutputStream { * Creates a new output stream to write to or replace the file at the specified path. * * @param path the path of the file to write to or replace - * @param keepBackup whether to keep the backup file after a successful write process + * @param keepBackup whether to keep the backup file (.sav) after a successful write process */ public AtomicFileOutputStream(Path path, boolean keepBackup) throws IOException { // Files.newOutputStream(getPathOfTemporaryFile(path)) leads to a "sun.nio.ch.ChannelOutputStream", which does not offer "lock" @@ -84,7 +85,7 @@ public AtomicFileOutputStream(Path path, boolean keepBackup) throws IOException /** * Creates a new output stream to write to or replace the file at the specified path. - * The backup file is deleted when write was successful. + * The backup file (.sav) is deleted when write was successful. * * @param path the path of the file to write to or replace */ @@ -238,7 +239,7 @@ public void close() throws IOException { } if (!keepBackup) { - // Remove backup file + // Remove backup file for saving Files.deleteIfExists(backupFile); } } finally { diff --git a/src/main/java/org/jabref/logic/exporter/ModsExporter.java b/src/main/java/org/jabref/logic/exporter/ModsExporter.java index da8afbcbcb8..ba07204ed92 100644 --- a/src/main/java/org/jabref/logic/exporter/ModsExporter.java +++ b/src/main/java/org/jabref/logic/exporter/ModsExporter.java @@ -373,9 +373,9 @@ private void addOriginInformation(Field field, String value, OriginInfoDefinitio addDate("dateIssued", value, originInfo); } else if (field.equals(new UnknownField("created"))) { addDate("dateCreated", value, originInfo); - } else if (field.equals(new UnknownField("modified"))) { + } else if (field.equals(StandardField.MODIFICATIONDATE)) { addDate("dateModified", value, originInfo); - } else if (field.equals(new UnknownField("captured"))) { + } else if (field.equals(StandardField.CREATIONDATE)) { addDate("dateCaptured", value, originInfo); } else if (StandardField.PUBLISHER.equals(field)) { StringPlusLanguagePlusSupplied publisher = new StringPlusLanguagePlusSupplied(); diff --git a/src/main/java/org/jabref/logic/exporter/SavePreferences.java b/src/main/java/org/jabref/logic/exporter/SavePreferences.java index 1165d3338c9..a566c0c3449 100644 --- a/src/main/java/org/jabref/logic/exporter/SavePreferences.java +++ b/src/main/java/org/jabref/logic/exporter/SavePreferences.java @@ -49,7 +49,7 @@ public SavePreferences(Boolean saveInOriginalOrder, this(saveInOriginalOrder, saveOrder, - true, + false, saveType, takeMetadataSaveOrderInAccount, reformatFile, diff --git a/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java index 1684be0e9ed..e6f9b92019a 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/ModsImporter.java @@ -516,9 +516,9 @@ private void parseIdentifier(Map fields, Identifier identifier, B private void putDate(Map fields, String elementName, String date) { if (date != null) { + Optional optionalParsedDate = Date.parse(date); switch (elementName) { case "dateIssued" -> { - Optional optionalParsedDate = Date.parse(date); optionalParsedDate .ifPresent(parsedDate -> fields.put(StandardField.DATE, parsedDate.getNormalized())); @@ -534,10 +534,12 @@ private void putDate(Map fields, String elementName, String date) fields.put(new UnknownField("created"), date); } case "dateCaptured" -> { - fields.put(new UnknownField("captured"), date); + optionalParsedDate + .ifPresent(parsedDate -> fields.put(StandardField.CREATIONDATE, parsedDate.getNormalized())); } case "dateModified" -> { - fields.put(new UnknownField("modified"), date); + optionalParsedDate + .ifPresent(parsedDate -> fields.put(StandardField.MODIFICATIONDATE, parsedDate.getNormalized())); } } } diff --git a/src/main/java/org/jabref/logic/integrity/NoBibtexFieldChecker.java b/src/main/java/org/jabref/logic/integrity/NoBibtexFieldChecker.java index 7d46cb42052..feb29ad750d 100644 --- a/src/main/java/org/jabref/logic/integrity/NoBibtexFieldChecker.java +++ b/src/main/java/org/jabref/logic/integrity/NoBibtexFieldChecker.java @@ -22,7 +22,7 @@ private Set getAllBiblatexOnlyFields() { return BiblatexEntryTypeDefinitions.ALL.stream() .flatMap(type -> type.getAllBibFields().stream()) .filter(field -> !allBibtexFields.contains(field)) - .map(BibField::getField) + .map(BibField::field) // these fields are displayed by JabRef as default .filter(field -> !field.equals(StandardField.ABSTRACT)) .filter(field -> !field.equals(StandardField.COMMENT)) diff --git a/src/main/java/org/jabref/logic/layout/format/AuthorLF_FF.java b/src/main/java/org/jabref/logic/layout/format/AuthorLF_FF.java index ef394e091a3..3e027862412 100644 --- a/src/main/java/org/jabref/logic/layout/format/AuthorLF_FF.java +++ b/src/main/java/org/jabref/logic/layout/format/AuthorLF_FF.java @@ -3,9 +3,6 @@ import org.jabref.logic.layout.LayoutFormatter; import org.jabref.model.entry.AuthorList; -/** - * - */ public class AuthorLF_FF implements LayoutFormatter { @Override diff --git a/src/main/java/org/jabref/logic/layout/format/AuthorLF_FFAbbr.java b/src/main/java/org/jabref/logic/layout/format/AuthorLF_FFAbbr.java index 4fda2fd8386..01866e0ea83 100644 --- a/src/main/java/org/jabref/logic/layout/format/AuthorLF_FFAbbr.java +++ b/src/main/java/org/jabref/logic/layout/format/AuthorLF_FFAbbr.java @@ -3,9 +3,6 @@ import org.jabref.logic.layout.LayoutFormatter; import org.jabref.model.entry.AuthorList; -/** - * - */ public class AuthorLF_FFAbbr implements LayoutFormatter { @Override diff --git a/src/main/java/org/jabref/model/entry/BibEntryType.java b/src/main/java/org/jabref/model/entry/BibEntryType.java index c8eb7b92b6e..d08221e0e61 100644 --- a/src/main/java/org/jabref/model/entry/BibEntryType.java +++ b/src/main/java/org/jabref/model/entry/BibEntryType.java @@ -38,7 +38,7 @@ public EntryType getType() { */ public Set getOptionalFields() { return getAllBibFields().stream() - .filter(field -> !isRequired(field.getField())) + .filter(field -> !isRequired(field.field())) .collect(Collectors.toCollection(LinkedHashSet::new)); } @@ -66,20 +66,20 @@ public Set getAllBibFields() { } public Set getAllFields() { - return fields.stream().map(BibField::getField).collect(Collectors.toCollection(LinkedHashSet::new)); + return fields.stream().map(BibField::field).collect(Collectors.toCollection(LinkedHashSet::new)); } public Set getPrimaryOptionalFields() { return getOptionalFields().stream() - .filter(field -> field.getPriority() == FieldPriority.IMPORTANT) - .map(BibField::getField) + .filter(field -> field.priority() == FieldPriority.IMPORTANT) + .map(BibField::field) .collect(Collectors.toCollection(LinkedHashSet::new)); } public Set getSecondaryOptionalFields() { return getOptionalFields().stream() - .filter(field -> field.getPriority() == FieldPriority.DETAIL) - .map(BibField::getField) + .filter(field -> field.priority() == FieldPriority.DETAIL) + .map(BibField::field) .collect(Collectors.toCollection(LinkedHashSet::new)); } @@ -112,9 +112,9 @@ public Set getSecondaryOptionalNotDeprecatedFields(BibDatabaseMode mode) private Set getOptionalFieldsAndAliases() { Set optionalFieldsAndAliases = new LinkedHashSet<>(getOptionalFields().size()); for (BibField field : getOptionalFields()) { - optionalFieldsAndAliases.add(field.getField()); - if (EntryConverter.FIELD_ALIASES_BIBTEX_TO_BIBLATEX.containsKey(field.getField())) { - optionalFieldsAndAliases.add(field.getField()); + optionalFieldsAndAliases.add(field.field()); + if (EntryConverter.FIELD_ALIASES_BIBTEX_TO_BIBLATEX.containsKey(field.field())) { + optionalFieldsAndAliases.add(field.field()); } } return optionalFieldsAndAliases; diff --git a/src/main/java/org/jabref/model/entry/BibEntryTypeBuilder.java b/src/main/java/org/jabref/model/entry/BibEntryTypeBuilder.java index 08f294bc3e1..ddc510d7d4b 100644 --- a/src/main/java/org/jabref/model/entry/BibEntryTypeBuilder.java +++ b/src/main/java/org/jabref/model/entry/BibEntryTypeBuilder.java @@ -29,7 +29,7 @@ public BibEntryTypeBuilder withType(EntryType type) { } public BibEntryTypeBuilder withImportantFields(Set newFields) { - return withImportantFields(newFields.stream().map(BibField::getField).collect(Collectors.toCollection(LinkedHashSet::new))); + return withImportantFields(newFields.stream().map(BibField::field).collect(Collectors.toCollection(LinkedHashSet::new))); } public BibEntryTypeBuilder withImportantFields(Collection newFields) { diff --git a/src/main/java/org/jabref/model/entry/BibEntryTypesManager.java b/src/main/java/org/jabref/model/entry/BibEntryTypesManager.java index 39e9f7ecdb3..81183b2bd5e 100644 --- a/src/main/java/org/jabref/model/entry/BibEntryTypesManager.java +++ b/src/main/java/org/jabref/model/entry/BibEntryTypesManager.java @@ -61,7 +61,7 @@ public static String serialize(BibEntryType entryType) { builder.append(FieldFactory.serializeFieldsList( entryType.getOptionalFields() .stream() - .map(BibField::getField) + .map(BibField::field) .collect(Collectors.toList()))); builder.append("]"); return builder.toString(); diff --git a/src/main/java/org/jabref/model/entry/field/BibField.java b/src/main/java/org/jabref/model/entry/field/BibField.java index 3aefdd9ec29..4d0729e4f4a 100644 --- a/src/main/java/org/jabref/model/entry/field/BibField.java +++ b/src/main/java/org/jabref/model/entry/field/BibField.java @@ -2,23 +2,7 @@ import java.util.Objects; -public class BibField implements Comparable { - - private final FieldPriority priority; - private final Field field; - - public BibField(Field field, FieldPriority priority) { - this.priority = priority; - this.field = field; - } - - public Field getField() { - return field; - } - - public FieldPriority getPriority() { - return priority; - } +public record BibField(Field field, FieldPriority priority) implements Comparable { @Override public boolean equals(Object o) { diff --git a/src/main/java/org/jabref/model/entry/types/BibtexEntryTypeDefinitions.java b/src/main/java/org/jabref/model/entry/types/BibtexEntryTypeDefinitions.java index 8ee79a27c30..594301642b7 100644 --- a/src/main/java/org/jabref/model/entry/types/BibtexEntryTypeDefinitions.java +++ b/src/main/java/org/jabref/model/entry/types/BibtexEntryTypeDefinitions.java @@ -9,10 +9,8 @@ import org.jabref.model.entry.field.StandardField; /** - * This class represents all supported BibTex entry types. - *

- * Article, Book, Booklet, Conference, Inbook, Incollection, Inproceedings, - * Manual, Mastersthesis, Misc, Phdthesis, Proceedings, Techreport, Unpublished + * This class represents all supported BibTeX entry types. + * The BibLaTeX entry types are defined at {@link BiblatexEntryTypeDefinitions}. */ public class BibtexEntryTypeDefinitions { /** diff --git a/src/main/java/org/jabref/model/entry/types/StandardEntryType.java b/src/main/java/org/jabref/model/entry/types/StandardEntryType.java index 6f6f91ac6a5..6f5d11b1160 100644 --- a/src/main/java/org/jabref/model/entry/types/StandardEntryType.java +++ b/src/main/java/org/jabref/model/entry/types/StandardEntryType.java @@ -2,6 +2,12 @@ import java.util.Locale; +/** + * Defines standard entry types as defined by BibTeX and BibLaTeX. + * At {@link BibtexEntryTypeDefinitions}, the required and optional fields for each type (for BibTeX) is defined. + * The BibLaTeX entry types are defined at {@link BiblatexEntryTypeDefinitions}. + * More reading on BibTeX and its fields is collected at JabRef's documentation. + */ public enum StandardEntryType implements EntryType { // BibTeX Article("Article"), @@ -19,7 +25,7 @@ public enum StandardEntryType implements EntryType { Proceedings("Proceedings"), TechReport("TechReport"), Unpublished("Unpublished"), - // Biblatex + // BibLaTeX BookInBook("BookInBook"), InReference("InReference"), MvBook("MvBook"), diff --git a/src/main/java/org/jabref/preferences/GuiPreferences.java b/src/main/java/org/jabref/preferences/GuiPreferences.java index fc0bd899286..c868ba3d751 100644 --- a/src/main/java/org/jabref/preferences/GuiPreferences.java +++ b/src/main/java/org/jabref/preferences/GuiPreferences.java @@ -33,6 +33,9 @@ public class GuiPreferences { private final StringProperty lastSelectedIdBasedFetcher; private final ObjectProperty mergeDiffMode; + private final BooleanProperty mergeShouldShowDiff; + private final BooleanProperty mergeShouldShowUnifiedDiff; + private final BooleanProperty mergeHighlightWords; private final BooleanProperty mergeShowChangedFieldsOnly; private final DoubleProperty sidePaneWidth; @@ -46,6 +49,9 @@ public GuiPreferences(double positionX, FileHistory fileHistory, String lastSelectedIdBasedFetcher, DiffMode mergeDiffMode, + boolean mergeShouldShowDiff, + boolean mergeShouldShowUnifiedDiff, + boolean mergeHighlightWords, double sidePaneWidth, boolean mergeShowChangedFieldsOnly) { this.positionX = new SimpleDoubleProperty(positionX); @@ -57,6 +63,10 @@ public GuiPreferences(double positionX, this.lastFocusedFile = new SimpleObjectProperty<>(lastFocusedFile); this.lastSelectedIdBasedFetcher = new SimpleStringProperty(lastSelectedIdBasedFetcher); this.mergeDiffMode = new SimpleObjectProperty<>(mergeDiffMode); + this.mergeShouldShowDiff = new SimpleBooleanProperty(mergeShouldShowDiff); + this.mergeShouldShowUnifiedDiff = new SimpleBooleanProperty(mergeShouldShowUnifiedDiff); + this.mergeHighlightWords = new SimpleBooleanProperty(mergeHighlightWords); + this.sidePaneWidth = new SimpleDoubleProperty(sidePaneWidth); this.fileHistory = fileHistory; this.mergeShowChangedFieldsOnly = new SimpleBooleanProperty(mergeShowChangedFieldsOnly); @@ -170,6 +180,42 @@ public void setMergeDiffMode(DiffMode mergeDiffMode) { this.mergeDiffMode.set(mergeDiffMode); } + public boolean getMergeShouldShowDiff() { + return mergeShouldShowDiff.get(); + } + + public BooleanProperty mergeShouldShowDiffProperty() { + return mergeShouldShowDiff; + } + + public void setMergeShouldShowDiff(boolean mergeShouldShowDiff) { + this.mergeShouldShowDiff.set(mergeShouldShowDiff); + } + + public boolean getMergeShouldShowUnifiedDiff() { + return mergeShouldShowUnifiedDiff.get(); + } + + public BooleanProperty mergeShouldShowUnifiedDiffProperty() { + return mergeShouldShowUnifiedDiff; + } + + public void setMergeShouldShowUnifiedDiff(boolean mergeShouldShowUnifiedDiff) { + this.mergeShouldShowUnifiedDiff.set(mergeShouldShowUnifiedDiff); + } + + public boolean getMergeHighlightWords() { + return mergeHighlightWords.get(); + } + + public BooleanProperty mergeHighlightWordsProperty() { + return mergeHighlightWords; + } + + public void setMergeHighlightWords(boolean mergeHighlightsWords) { + this.mergeHighlightWords.set(mergeHighlightsWords); + } + public double getSidePaneWidth() { return sidePaneWidth.get(); } diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 4781e359d7d..8db213d76c4 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -238,6 +238,11 @@ public class JabRefPreferences implements PreferencesService { // merge related public static final String MERGE_ENTRIES_DIFF_MODE = "mergeEntriesDiffMode"; + public static final String MERGE_ENTRIES_SHOULD_SHOW_DIFF = "mergeEntriesShouldShowDiff"; + public static final String MERGE_ENTRIES_SHOULD_SHOW_UNIFIED_DIFF = "mergeEntriesShouldShowUnifiedDiff"; + public static final String MERGE_ENTRIES_HIGHLIGHT_WORDS = "mergeEntriesHighlightWords"; + + public static final String MERGE_SHOW_ONLY_CHANGED_FIELDS = "mergeShowOnlyChangedFields"; public static final String CUSTOM_EXPORT_FORMAT = "customExportFormat"; @@ -587,6 +592,9 @@ private JabRefPreferences() { defaults.put(DEFAULT_SHOW_SOURCE, Boolean.FALSE); defaults.put(MERGE_ENTRIES_DIFF_MODE, DiffMode.WORD.name()); + defaults.put(MERGE_ENTRIES_SHOULD_SHOW_DIFF, Boolean.TRUE); + defaults.put(MERGE_ENTRIES_SHOULD_SHOW_UNIFIED_DIFF, Boolean.TRUE); + defaults.put(MERGE_ENTRIES_HIGHLIGHT_WORDS, Boolean.TRUE); defaults.put(MERGE_SHOW_ONLY_CHANGED_FIELDS, Boolean.FALSE); defaults.put(SHOW_RECOMMENDATIONS, Boolean.TRUE); @@ -1564,14 +1572,13 @@ public ProxyPreferences getProxyPreferences() { get(PROXY_PORT), getBoolean(PROXY_USE_AUTHENTICATION), get(PROXY_USERNAME), - get(PROXY_PASSWORD)); + (String) defaults.get(PROXY_PASSWORD)); EasyBind.listen(proxyPreferences.useProxyProperty(), (obs, oldValue, newValue) -> putBoolean(PROXY_USE, newValue)); EasyBind.listen(proxyPreferences.hostnameProperty(), (obs, oldValue, newValue) -> put(PROXY_HOSTNAME, newValue)); EasyBind.listen(proxyPreferences.portProperty(), (obs, oldValue, newValue) -> put(PROXY_PORT, newValue)); EasyBind.listen(proxyPreferences.useAuthenticationProperty(), (obs, oldValue, newValue) -> putBoolean(PROXY_USE_AUTHENTICATION, newValue)); EasyBind.listen(proxyPreferences.usernameProperty(), (obs, oldValue, newValue) -> put(PROXY_USERNAME, newValue)); - EasyBind.listen(proxyPreferences.passwordProperty(), (obs, oldValue, newValue) -> put(PROXY_PASSWORD, newValue)); return proxyPreferences; } @@ -2511,6 +2518,9 @@ public GuiPreferences getGuiPreferences() { getFileHistory(), get(ID_ENTRY_GENERATOR), DiffMode.parse(get(MERGE_ENTRIES_DIFF_MODE)), + getBoolean(MERGE_ENTRIES_SHOULD_SHOW_DIFF), + getBoolean(MERGE_ENTRIES_SHOULD_SHOW_UNIFIED_DIFF), + getBoolean(MERGE_ENTRIES_HIGHLIGHT_WORDS), getDouble(SIDE_PANE_WIDTH), getBoolean(MERGE_SHOW_ONLY_CHANGED_FIELDS)); @@ -2536,6 +2546,9 @@ public GuiPreferences getGuiPreferences() { guiPreferences.getFileHistory().addListener((InvalidationListener) change -> storeFileHistory(guiPreferences.getFileHistory())); EasyBind.listen(guiPreferences.lastSelectedIdBasedFetcherProperty(), (obs, oldValue, newValue) -> put(ID_ENTRY_GENERATOR, newValue)); EasyBind.listen(guiPreferences.mergeDiffModeProperty(), (obs, oldValue, newValue) -> put(MERGE_ENTRIES_DIFF_MODE, newValue.name())); + EasyBind.listen(guiPreferences.mergeShouldShowDiffProperty(), (obs, oldValue, newValue) -> putBoolean(MERGE_ENTRIES_SHOULD_SHOW_DIFF, newValue)); + EasyBind.listen(guiPreferences.mergeShouldShowUnifiedDiffProperty(), (obs, oldValue, newValue) -> putBoolean(MERGE_ENTRIES_SHOULD_SHOW_UNIFIED_DIFF, newValue)); + EasyBind.listen(guiPreferences.mergeHighlightWordsProperty(), (obs, oldValue, newValue) -> putBoolean(MERGE_ENTRIES_HIGHLIGHT_WORDS, newValue)); EasyBind.listen(guiPreferences.sidePaneWidthProperty(), (obs, oldValue, newValue) -> putDouble(SIDE_PANE_WIDTH, newValue.doubleValue())); EasyBind.listen(guiPreferences.mergeShowChangedFieldOnlyProperty(), (obs, oldValue, newValue) -> putBoolean(MERGE_SHOW_ONLY_CHANGED_FIELDS, newValue)); diff --git a/src/main/resources/csl-styles/ieee.csl b/src/main/resources/csl-styles/ieee.csl index 8238e0aac1d..19081952c37 100644 --- a/src/main/resources/csl-styles/ieee.csl +++ b/src/main/resources/csl-styles/ieee.csl @@ -183,7 +183,6 @@ - @@ -295,6 +294,19 @@ + + + + + + + + + + + + + @@ -337,16 +349,38 @@ - + + + + + + - + + + + + + + + + + + + + + + + + + @@ -399,6 +433,7 @@ + @@ -417,29 +452,13 @@ - - - - - - - - - - - - - - - - - + diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 48fa49e57ad..c772cf06f87 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -1,3 +1,5 @@ +Proxy\ requires\ password=Proxy requires password + Could\ not\ delete\ empty\ entries.=Could not delete empty entries. Delete\ empty\ entries=Delete empty entries @@ -2537,3 +2539,8 @@ Please\ select\ a\ valid\ main\ directory\ under=Please select a valid main dire Search\ from\ history...=Search from history... your\ search\ history\ is\ empty=your search history is empty Clear\ history =Clear history + +Delete\ %0\ files=Delete %0 files +Delete\ %0\ files\ permanently\ from\ disk,\ or\ just\ remove\ the\ files\ from\ the\ entry?\ Pressing\ Delete\ will\ delete\ the\ files\ permanently\ from\ disk.=Delete %0 files permanently from disk, or just remove the files from the entry? Pressing Delete will delete the files permanently from disk. +Error\ accessing\ file\ '%0'.=Error accessing file '%0'. +This\ operation\ requires\ selected\ linked\ files.=This operation requires selected linked files. diff --git a/src/test/java/org/jabref/logic/bibtex/comparator/BibStringDiffTest.java b/src/test/java/org/jabref/logic/bibtex/comparator/BibStringDiffTest.java index 1db4078fdfa..28f8ed4d801 100644 --- a/src/test/java/org/jabref/logic/bibtex/comparator/BibStringDiffTest.java +++ b/src/test/java/org/jabref/logic/bibtex/comparator/BibStringDiffTest.java @@ -1,5 +1,6 @@ package org.jabref.logic.bibtex.comparator; +import java.util.Collections; import java.util.List; import org.jabref.model.database.BibDatabase; @@ -9,6 +10,9 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -22,13 +26,100 @@ public class BibStringDiffTest { void setUp() { when(originalDataBase.hasNoStrings()).thenReturn(false); when(newDataBase.hasNoStrings()).thenReturn(false); - when(originalDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name", "content"), new BibtexString("name2", "content2"))); - when(newDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name", "content"), new BibtexString("name2", "content3"))); } @Test void compareTest() { + when(originalDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name", "content"), new BibtexString("name2", "content2"))); + when(newDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name", "content"), new BibtexString("name2", "content3"))); + List result = BibStringDiff.compare(originalDataBase, newDataBase); assertEquals(List.of(diff), result); } + + @Test + void equalTest() { + BibStringDiff other = new BibStringDiff(diff.getOriginalString(), diff.getNewString()); + assertEquals(diff, other); + assertEquals(diff.hashCode(), other.hashCode()); + } + + @Test + void notEqualTest() { + BibStringDiff other = new BibStringDiff(diff.getNewString(), diff.getOriginalString()); + assertNotEquals(diff, other); + assertNotEquals(diff.hashCode(), other.hashCode()); + } + + @Test + void identicalObjectsAreEqual() { + BibStringDiff other = diff; + assertTrue(other.equals(diff)); + } + + @Test + void compareToNullObjectIsFalse() { + assertFalse(diff.equals(null)); + } + + @Test + void compareToDifferentClassIsFalse() { + assertFalse(diff.equals(new Object())); + } + + @Test + void testGetters() { + BibtexString bsOne = new BibtexString("aKahle", "Kahle, Brewster"); + BibtexString bsTwo = new BibtexString("iMIT", "Institute of Technology"); + BibStringDiff diff = new BibStringDiff(bsOne, bsTwo); + assertEquals(diff.getOriginalString(), bsOne); + assertEquals(diff.getNewString(), bsTwo); + } + + @Test + void testCompareEmptyDatabases() { + when(originalDataBase.hasNoStrings()).thenReturn(true); + when(newDataBase.hasNoStrings()).thenReturn(true); + + assertEquals(Collections.emptyList(), BibStringDiff.compare(originalDataBase, newDataBase)); + } + + @Test + void testCompareNameChange() { + when(originalDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name", "content"))); + when(newDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name2", "content"))); + + List result = BibStringDiff.compare(originalDataBase, newDataBase); + BibStringDiff expectedDiff = new BibStringDiff(new BibtexString("name", "content"), new BibtexString("name2", "content")); + assertEquals(List.of(expectedDiff), result); + } + + @Test + void testCompareNoDiff() { + when(originalDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name", "content"))); + when(newDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name", "content"))); + + List result = BibStringDiff.compare(originalDataBase, newDataBase); + assertEquals(Collections.emptyList(), result); + } + + @Test + void testCompareRemovedString() { + when(originalDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name", "content"))); + when(newDataBase.getStringValues()).thenReturn(Collections.emptyList()); + + List result = BibStringDiff.compare(originalDataBase, newDataBase); + BibStringDiff expectedDiff = new BibStringDiff(new BibtexString("name", "content"), null); + assertEquals(List.of(expectedDiff), result); + } + + @Test + void testCompareAddString() { + when(originalDataBase.getStringValues()).thenReturn(Collections.emptyList()); + when(newDataBase.getStringValues()).thenReturn(List.of(new BibtexString("name", "content"))); + + List result = BibStringDiff.compare(originalDataBase, newDataBase); + BibStringDiff expectedDiff = new BibStringDiff(null, new BibtexString("name", "content")); + assertEquals(List.of(expectedDiff), result); + } } diff --git a/src/test/java/org/jabref/logic/citationstyle/CitationStyleGeneratorTest.java b/src/test/java/org/jabref/logic/citationstyle/CitationStyleGeneratorTest.java index cf01446944a..a6694088d99 100644 --- a/src/test/java/org/jabref/logic/citationstyle/CitationStyleGeneratorTest.java +++ b/src/test/java/org/jabref/logic/citationstyle/CitationStyleGeneratorTest.java @@ -34,7 +34,7 @@ void testACMCitation() { // if the acm-siggraph.csl citation style changes this has to be modified String expected = "

" - + "Smith, B., Jones, B., and Williams, J. 2016-07. Title of the test entry. BibTeX Journal 34, 3, 45–67." + + "Smith, B., Jones, B., and Williams, J. 2016. Title of the test entry. BibTeX Journal 34, 3, 45–67." + "
\n" + ""; @@ -51,7 +51,7 @@ void testAPACitation() { // if the apa-7th-citation.csl citation style changes this has to be modified String expected = "
" - + "Smith, B., Jones, B., & Williams, J. (2016-07). Title of the test entry. BibTeX Journal, 34(3), 45–67. https://doi.org/10.1001/bla.blubb" + + "Smith, B., Jones, B., & Williams, J. (2016). Title of the test entry. BibTeX Journal, 34(3), 45–67. https://doi.org/10.1001/bla.blubb" + "
\n" + ""; @@ -94,7 +94,7 @@ void testMissingCitationStyle() { @Test void testHtmlFormat() { String expectedCitation = "
\n" + - "
[1]
B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, 2016-07, doi: 10.1001/bla.blubb.
\n" + + "
[1]
B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, Jul. 2016, doi: 10.1001/bla.blubb.
\n" + "
\n"; BibEntry entry = TestEntry.getTestEntry(); @@ -107,7 +107,7 @@ void testHtmlFormat() { @Test void testTextFormat() { - String expectedCitation = "[1]B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, 2016-07, doi: 10.1001/bla.blubb.\n"; + String expectedCitation = "[1]B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, Jul. 2016, doi: 10.1001/bla.blubb.\n"; BibEntry entry = TestEntry.getTestEntry(); String style = CitationStyle.getDefault().getSource(); @@ -133,7 +133,7 @@ void testHandleDiacritics() { @Test void testHandleAmpersand() { - String expectedCitation = "[1]B. Smith, B. Jones, and J. Williams, “Famous quote: “&TitleTest&” - that is it,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, 2016-07, doi: 10.1001/bla.blubb.\n"; + String expectedCitation = "[1]B. Smith, B. Jones, and J. Williams, “Famous quote: “&TitleTest&” - that is it,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, Jul. 2016, doi: 10.1001/bla.blubb.\n"; BibEntry entry = TestEntry.getTestEntry(); entry.setField(StandardField.TITLE, "Famous quote: “&TitleTest&” - that is it"); String style = CitationStyle.getDefault().getSource(); @@ -160,7 +160,7 @@ void testHandleCrossRefFields() { .withField(StandardField.YEAR, "2021") .withField(StandardField.ADDRESS, "Somewhere"); - String expectedCitation = "[1]B. Smith, “An article,” J. Jones, Ed. Somewhere: Great Publisher, 2021, pp. 1–10.\n"; + String expectedCitation = "[1]B. Smith, “An article,” J. Jones, Ed., Somewhere: Great Publisher, 2021, pp. 1–10.\n"; BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(new BibDatabase(List.of(firstEntry, secondEntry))); String style = CitationStyle.getDefault().getSource(); diff --git a/src/test/java/org/jabref/logic/citationstyle/CitationStyleTest.java b/src/test/java/org/jabref/logic/citationstyle/CitationStyleTest.java index b05aed909a5..6bdbac10b98 100644 --- a/src/test/java/org/jabref/logic/citationstyle/CitationStyleTest.java +++ b/src/test/java/org/jabref/logic/citationstyle/CitationStyleTest.java @@ -27,10 +27,11 @@ void testDefaultCitation() { String citation = CitationStyleGenerator.generateCitation(TestEntry.getTestEntry(), CitationStyle.getDefault().getSource(), CitationStyleOutputFormat.HTML, context, new BibEntryTypesManager()); // if the default citation style changes this has to be modified - String expected = "
\n" - + "
[1]
B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, 2016-07, doi: 10.1001/bla.blubb.
\n" - + "
\n" - + ""; + String expected = """ +
+
[1]
B. Smith, B. Jones, and J. Williams, “Title of the test entry,” BibTeX Journal, vol. 34, no. 3, pp. 45–67, Jul. 2016, doi: 10.1001/bla.blubb.
+
+ """; assertEquals(expected, citation); } diff --git a/src/test/java/org/jabref/logic/layout/format/MarkdownFormatterTest.java b/src/test/java/org/jabref/logic/layout/format/MarkdownFormatterTest.java index 595bc6fcc1d..e5e1f9281e6 100644 --- a/src/test/java/org/jabref/logic/layout/format/MarkdownFormatterTest.java +++ b/src/test/java/org/jabref/logic/layout/format/MarkdownFormatterTest.java @@ -6,7 +6,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; class MarkdownFormatterTest { @@ -37,21 +36,4 @@ void formatWhenFormattingNullThenThrowsException() { Exception exception = assertThrows(NullPointerException.class, () -> markdownFormatter.format(null)); assertEquals("Field Text should not be null, when handed to formatter", exception.getMessage()); } - - @Test - void formatWhenMarkupContainingStrikethroughThenContainsMatchingDel() { - // Only test strikethrough extension - assertTrue(markdownFormatter.format("a ~~b~~ b").contains("b")); - } - - @Test - void formatWhenMarkupContainingTaskListThenContainsFormattedTaskList() { - String actual = markdownFormatter.format("Some text\n" + - "* [ ] open task\n" + - "* [x] closed task\n\n" + - "some other text"); - // Only test list items - assertTrue(actual.contains("
  •  open task
  • ")); - assertTrue(actual.contains("
  •  closed task
  • ")); - } } diff --git a/src/test/java/org/jabref/logic/net/ProxyTest.java b/src/test/java/org/jabref/logic/net/ProxyTest.java new file mode 100644 index 00000000000..510f9ce1a50 --- /dev/null +++ b/src/test/java/org/jabref/logic/net/ProxyTest.java @@ -0,0 +1,37 @@ +package org.jabref.logic.net; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ProxyTest { + /** + * The test checks if ProxyPreference class is still able to store password and use it from memory, + * even though it's no longer stored in register. + */ + @Test + public void testProxyPreferencesStorePassword() { + // mock data + Boolean useProxy = true; + String hostname = "testName"; + String port = "8080"; + Boolean useAuthentication = true; + String username = "testUserName"; + String password = "testPassword"; + // Creates proxy preference + ProxyPreferences proxyPref = new ProxyPreferences( + useProxy, + hostname, + port, + useAuthentication, + username, + password); + // Check if mock data is stored in object memory and can be extracted + assertEquals(proxyPref.shouldUseProxy(), true); + assertEquals(proxyPref.getHostname(), hostname); + assertEquals(proxyPref.getPort(), port); + assertEquals(proxyPref.shouldUseAuthentication(), true); + assertEquals(proxyPref.getUsername(), username); + assertEquals(proxyPref.getPassword(), password); + } +} diff --git a/src/test/java/org/jabref/model/entry/BibEntryTest.java b/src/test/java/org/jabref/model/entry/BibEntryTest.java index a27c2ccdc61..784f5f03431 100644 --- a/src/test/java/org/jabref/model/entry/BibEntryTest.java +++ b/src/test/java/org/jabref/model/entry/BibEntryTest.java @@ -64,7 +64,7 @@ void getFieldIsCaseInsensitive() throws Exception { @Test void getFieldWorksWithBibFieldAsWell() throws Exception { entry.setField(StandardField.AUTHOR, "value"); - assertEquals(Optional.of("value"), entry.getField(new BibField(StandardField.AUTHOR, FieldPriority.IMPORTANT).getField())); + assertEquals(Optional.of("value"), entry.getField(new BibField(StandardField.AUTHOR, FieldPriority.IMPORTANT).field())); } @Test @@ -80,7 +80,7 @@ void setFieldLeadsToAChangedEntry() throws Exception { @Test void setFieldWorksWithBibFieldAsWell() throws Exception { - entry.setField(new BibField(StandardField.AUTHOR, FieldPriority.IMPORTANT).getField(), "value"); + entry.setField(new BibField(StandardField.AUTHOR, FieldPriority.IMPORTANT).field(), "value"); assertEquals(Optional.of("value"), entry.getField(StandardField.AUTHOR)); } diff --git a/src/test/resources/org/jabref/logic/exporter/ModsExportFormatTestAllFields.bib b/src/test/resources/org/jabref/logic/exporter/ModsExportFormatTestAllFields.bib index 911c90bd44d..9ef7a8ccdaf 100644 --- a/src/test/resources/org/jabref/logic/exporter/ModsExportFormatTestAllFields.bib +++ b/src/test/resources/org/jabref/logic/exporter/ModsExportFormatTestAllFields.bib @@ -1,31 +1,31 @@ % Encoding: UTF-8 @Article{, - author = {Don't, know and Realy, don't know}, - title = {title}, - journal = {Some journal}, - year = {2000}, - volume = {5}, - pages = {67-68}, - note = {a note, and another note}, - abstract = {abstract}, - address = {India}, - affiliation = {an affiliation}, - captured = {2000-11-11}, - created = {2000-11-10}, - date = {2000}, - doi = {someDoi}, - edition = {2}, - issuance = {monographic}, - issue = {10}, - keywords = {keyword, electrophoresis, neoplasia, spectrometry, translation}, - language = {en}, - location = {somewhere}, - modified = {2000-12-10}, - pmid = {123456789}, - publisher = {Verlag verlag}, - uri = {an uri}, - url = {someWebSite}, + author = {Don't, know and Realy, don't know}, + title = {title}, + journal = {Some journal}, + year = {2000}, + volume = {5}, + pages = {67-68}, + note = {a note, and another note}, + abstract = {abstract}, + address = {India}, + affiliation = {an affiliation}, + creationdate = {2000-11-11}, + created = {2000-11-10}, + date = {2000}, + doi = {someDoi}, + edition = {2}, + issuance = {monographic}, + issue = {10}, + keywords = {keyword, electrophoresis, neoplasia, spectrometry, translation}, + language = {en}, + location = {somewhere}, + modificationdate = {2000-12-10}, + pmid = {123456789}, + publisher = {Verlag verlag}, + uri = {an uri}, + url = {someWebSite}, } @Comment{jabref-meta: databaseType:bibtex;} diff --git a/src/test/resources/org/jabref/logic/exporter/ModsExportFormatTestAllFields.xml b/src/test/resources/org/jabref/logic/exporter/ModsExportFormatTestAllFields.xml index 9ffb277f992..a307e50d99e 100644 --- a/src/test/resources/org/jabref/logic/exporter/ModsExportFormatTestAllFields.xml +++ b/src/test/resources/org/jabref/logic/exporter/ModsExportFormatTestAllFields.xml @@ -51,8 +51,8 @@ India - 2000-11-11 2000-11-10 + 2000-11-11 2 monographic 2000-12-10 diff --git a/src/test/resources/org/jabref/logic/importer/fileformat/MODSImporterTestAllFields.bib b/src/test/resources/org/jabref/logic/importer/fileformat/MODSImporterTestAllFields.bib index 2e7c3edea99..ab9b490395f 100644 --- a/src/test/resources/org/jabref/logic/importer/fileformat/MODSImporterTestAllFields.bib +++ b/src/test/resources/org/jabref/logic/importer/fileformat/MODSImporterTestAllFields.bib @@ -1,17 +1,17 @@ @article{TelPeak, - abstract = {an abstract}, - affiliation = {an affiliation}, - author = {Telescope}, - captured = {1955-11-30}, - city = {New York}, - country = {United States}, - created = {1955-03-22}, - edition = {2}, - journal = {Cell}, - modified = {1970-12-01}, - pages = {50}, - source = {Indiana University Digital Library Program}, - title = {Telescope PK from Zabriskie Pt.}, - url = {http://purl.dlib.indiana.edu/iudl/archives/cushman/P07803, http://quod.lib.umich.edu/m/mods/thumbs/Indiana/oai.dlib.indiana.edu/ archives/cushman/oai_3Aoai.dlib.indiana.edu_3Aarchives_5Ccushman_5CP07803.png}, - year = {1955} + abstract = {an abstract}, + affiliation = {an affiliation}, + author = {Telescope}, + creationdate = {1955-11-30}, + city = {New York}, + country = {United States}, + created = {1955-03-22}, + edition = {2}, + journal = {Cell}, + modificationdate = {1970-12-01}, + pages = {50}, + source = {Indiana University Digital Library Program}, + title = {Telescope PK from Zabriskie Pt.}, + url = {http://purl.dlib.indiana.edu/iudl/archives/cushman/P07803, http://quod.lib.umich.edu/m/mods/thumbs/Indiana/oai.dlib.indiana.edu/ archives/cushman/oai_3Aoai.dlib.indiana.edu_3Aarchives_5Ccushman_5CP07803.png}, + year = {1955} }