diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 2e3f869b953..49eae5fb82f 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -32,7 +32,16 @@ jobs: - name: Checkout source uses: actions/checkout@v1 with: - fetch-depth: 1 + depth: 1 + submodules: true + - name: Extract branch name + shell: bash + run: | + ref=${GITHUB_REF#refs/heads/} + ref=${ref#refs/pull/} + ref=${ref%/merge} + echo "##[set-output name=branch;]${ref}" + id: extract_branch - name: Set up JDK uses: actions/setup-java@v1 with: @@ -74,10 +83,14 @@ jobs: - name: Package application image run: ${{ matrix.archivePortable }} shell: bash - - name: Extract branch name + - name: Build and publish snap + if: matrix.os == 'ubuntu-latest' && steps.extract_branch.outputs.branch == 'master' + env: + SNAPCRAFT_LOGIN_FILE: ${{ secrets.SNAPCRAFT_LOGIN_FILE }} + run: | + docker run -v $(pwd):$(pwd) -t lyzardking/snapcraft-bionic sh -c "apt update -qq && cd $(pwd) && snapcraft && mv jabref*.snap build/distribution/" + # cd build/distribution/ && mdkir .snapcraft && echo ${SNAPCRAFT_LOGIN_FILE} | base64 --decode --ignore-garbage > .snapcraft/snapcraft.cfg && snapcraft push --release=beta *.snap shell: bash - run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" - id: extract_branch - name: Upload to builds.jabref.org uses: garygrossgarten/github-action-scp@release with: diff --git a/CHANGELOG.md b/CHANGELOG.md index b71f0091dcd..b2aeb6f5e9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# ### Changed -- We added a short DOI field formatter which shortens DOI to more human readable form. [koppor#343](https://github.com/koppor/jabref/issues/343) +- We added a short DOI field formatter which shortens DOI to more human-readable form. [koppor#343](https://github.com/koppor/jabref/issues/343) - We improved the display of group memberships by adding multiple colored bars if the entry belongs to more than one group. [#4574](https://github.com/JabRef/jabref/issues/4574) ### Fixed @@ -22,7 +22,9 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We fixed an issue where it was no longer possible to connect to LibreOffice. [#5261](https://github.com/JabRef/jabref/issues/5261) - The "All entries group" is no longer shown when no library is open. - We fixed an exception which occurred when closing JabRef. [#5348](https://github.com/JabRef/jabref/issues/5348) +- We fixed a few problems that prevented JabFox to communicate with JabRef. [#4737](https://github.com/JabRef/jabref/issues/4737) [#4303](https://github.com/JabRef/jabref/issues/4303) - We fixed an error where the groups containing an entry loose their highlight color when scrolling. [#5022](https://github.com/JabRef/jabref/issues/5022) +- We fixed an error where an exception was thrown when merging entries. [#5169](https://github.com/JabRef/jabref/issues/5169) - After assigning an entry to a group, the item count is now properly colored to reflect the new membership of the entry. [#3112](https://github.com/JabRef/jabref/issues/3112) - The group panel is now properly updated when switching between libraries (or when closing/opening one). [#3142](https://github.com/JabRef/jabref/issues/3142) - We fixed an error where the number of matched entries shown in the group pane was not updated correctly. [#4441](https://github.com/JabRef/jabref/issues/4441) @@ -30,9 +32,15 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We fixed an error where the default color of a new group was white instead of dark gray. [#4868](https://github.com/JabRef/jabref/issues/4868) - We fixed an error mentioning "javafx.controls/com.sun.javafx.scene.control" that was thrown when interacting with the toolbar. - We fixed an error where a cleared search was restored after switching libraries. [#4846](https://github.com/JabRef/jabref/issues/4846) -- We fixed an exception which occured when trying to open a non existing file from the "Recent files"-menu [#5334](https://github.com/JabRef/jabref/issues/5334) +- We fixed an exception which occurred when trying to open a non-existing file from the "Recent files"-menu [#5334](https://github.com/JabRef/jabref/issues/5334) - The context menu for fields in the entry editor is back. [#5254](https://github.com/JabRef/jabref/issues/5254) -- We fixed an exception which occurred when trying to open a non existing file from the "Recent files"-menu [#5334](https://github.com/JabRef/jabref/issues/5334) +- We fixed an exception which occurred when trying to open a non-existing file from the "Recent files"-menu [#5334](https://github.com/JabRef/jabref/issues/5334) +- We fixed a problem where the "editor" information has been duplicated during saving a .bib-Database. [#5359](https://github.com/JabRef/jabref/issues/5359) +- We re-introduced the feature to switch between different preview styles. [#5221](https://github.com/JabRef/jabref/issues/5221) +- We fixed various issues (including [#5263](https://github.com/JabRef/jabref/issues/5263)) related to copying entries to the clipboard + + + ### Removed @@ -101,11 +109,11 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Moreover, empty deprecated fields are no longer shown - Added server timezone parameter when connecting to a shared database. - We updated the dialog for setting up general fields. -- URL field formatting is updated. All whitespace chars, located at the beginning/ending of the url, are trimmed automatically +- URL field formatting is updated. All whitespace chars, located at the beginning/ending of the URL, are trimmed automatically - We changed the behavior of the field formatting dialog such that the `bibtexkey` is not changed when formatting all fields or all text fields. - We added a "Move file to file directory and rename file" option for simultaneously moving and renaming of document file. [#4166](https://github.com/JabRef/jabref/issues/4166) - Use integrated graphics card instead of discrete on macOS [#4070](https://github.com/JabRef/jabref/issues/4070) -- We added a cleanup operation that detects an arXiv identifier in the note, journal or url field and moves it to the `eprint` field. +- We added a cleanup operation that detects an arXiv identifier in the note, journal or URL field and moves it to the `eprint` field. Because of this change, the last-used cleanup operations were reset. - We changed the minimum required version of Java to 1.8.0_171, as this is the latest release for which the automatic Java update works. [#4093](https://github.com/JabRef/jabref/issues/4093) - The special fields like `Printed` and `Read status` now show gray icons when the row is hovered. @@ -124,18 +132,19 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Files without a defined external file type are now directly opened with the default application of the operating system - We streamlined the process to rename and move files by removing the confirmation dialogs. - We removed the redundant new lines of markings and wrapped the summary in the File annotation tab. [#3823](https://github.com/JabRef/jabref/issues/3823) -- We add auto url formatting when user paste link to URL field in entry editor. [koppor#254](https://github.com/koppor/jabref/issues/254) -- We added a minimal height for the entry editor so that it can no longer be hidden by accident. [#4279](https://github.com/JabRef/jabref/issues/4279) +- We add auto URL formatting when user paste link to URL field in entry editor. [koppor#254](https://github.com/koppor/jabref/issues/254) +- We added a minimum height for the entry editor so that it can no longer be hidden by accident. [#4279](https://github.com/JabRef/jabref/issues/4279) - We added a new keyboard shortcut so that the entry editor could be closed by Ctrl + E. [#4222] (https://github.com/JabRef/jabref/issues/4222) - We added an option in the preference dialog box, that allows user to pick the dark or light theme option. [#4130] (https://github.com/JabRef/jabref/issues/4130) -- We updated updated the Related Articles tab to accept JSON from the new version of the Mr. DLib service +- We updated the Related Articles tab to accept JSON from the new version of the Mr. DLib service - We added an option in the preference dialog box that allows user to choose behavior after dragging and dropping files in Entry Editor. [#4356](https://github.com/JabRef/jabref/issues/4356) - We added the ability to have an export preference where previously "File"-->"Export"/"Export selected entries" would not save the user's preference[#4495](https://github.com/JabRef/jabref/issues/4495) - We optimized the code responsible for connecting to an external database, which should lead to huge improvements in performance. - For automatically created groups, added ability to filter groups by entry type. [#4539](https://github.com/JabRef/jabref/issues/4539) - We added the ability to add field names from the Preferences Dialog [#4546](https://github.com/JabRef/jabref/issues/4546) -- We added the ability change the column widths directly in the main table. [#4546](https://github.com/JabRef/jabref/issues/4546) -- We added description of how recommendations where chosen and better error handling to Related Articles tab +- We added the ability to change the column widths directly in the main +. [#4546](https://github.com/JabRef/jabref/issues/4546) +- We added a description of how recommendations were chosen and better error handling to Related Articles tab - We added the ability to execute default action in dialog by using with Ctrl + Enter combination [#4496](https://github.com/JabRef/jabref/issues/4496) - We grouped and reordered the Main Menu (File, Edit, Library, Quality, Tools, and View tabs & icons). [#4666](https://github.com/JabRef/jabref/issues/4666) [#4667](https://github.com/JabRef/jabref/issues/4667) [#4668](https://github.com/JabRef/jabref/issues/4668) [#4669](https://github.com/JabRef/jabref/issues/4669) [#4670](https://github.com/JabRef/jabref/issues/4670) [#4671](https://github.com/JabRef/jabref/issues/4671) [#4672](https://github.com/JabRef/jabref/issues/4672) [#4673](https://github.com/JabRef/jabref/issues/4673) - We added additional modifiers (capitalize, titlecase and sentencecase) to the Bibtex key generator. [#1506](https://github.com/JabRef/jabref/issues/1506) @@ -144,7 +153,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We added a browse button next to the path text field for aux-based groups. [#4586](https://github.com/JabRef/jabref/issues/4586) - We changed the title of Group Dialog to "Add subgroup" from "Edit group" when we select Add subgroup option. - We enable import button only if entries are selected. [#4755](https://github.com/JabRef/jabref/issues/4755) -- We made modifications to improve contrast of UI elements. [#4583](https://github.com/JabRef/jabref/issues/4583) +- We made modifications to improve the contrast of UI elements. [#4583](https://github.com/JabRef/jabref/issues/4583) - We added a warning for empty BibTeX keys in the entry editor. [#4440](https://github.com/JabRef/jabref/issues/4440) - We added an option in the settings to set the default action in JabRef when right clicking on any entry in any database and selecting "Open folder". [#4763](https://github.com/JabRef/jabref/issues/4763) - The Medline fetcher now normalizes the author names according to the BibTeX-Standard [#4345](https://github.com/JabRef/jabref/issues/4345) @@ -171,7 +180,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We fixed an issue where the group tree was not updated correctly after an entry was changed. https://github.com/JabRef/jabref/issues/3618 - We fixed an issue where a right-click in the main table selected a wrong entry. https://github.com/JabRef/jabref/issues/3267 - We fixed an issue where in rare cases entries where overlayed in the main table. https://github.com/JabRef/jabref/issues/3281 -- We fixed an issue where selecting a group messed up the focus of the main table / entry editor. https://github.com/JabRef/jabref/issues/3367 +- We fixed an issue where selecting a group messed up the focus of the main table and the entry editor. https://github.com/JabRef/jabref/issues/3367 - We fixed an issue where composite author names were sorted incorrectly. https://github.com/JabRef/jabref/issues/2828 - We fixed an issue where commands followed by `-` didn't work. [#3805](https://github.com/JabRef/jabref/issues/3805) - We fixed an issue where a non-existing aux file in a group made it impossible to open the library. [#4735](https://github.com/JabRef/jabref/issues/4735) @@ -204,9 +213,9 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - We fixed an issue where "Move to group" would always move the first entry in the library and not the selected [#4414](https://github.com/JabRef/jabref/issues/4414) - We fixed an issue where an older dialog appears when downloading full texts from the quality menu. [#4489](https://github.com/JabRef/jabref/issues/4489) - We fixed an issue where right clicking on any entry in any database and selecting "Open folder" results in the NullPointer exception. [#4763](https://github.com/JabRef/jabref/issues/4763) -- We fixed an issue where option 'open terminal here' with custom command was passing wrong argument. [#4802](https://github.com/JabRef/jabref/issues/4802) +- We fixed an issue where option 'open terminal here' with custom command was passing the wrong argument. [#4802](https://github.com/JabRef/jabref/issues/4802) - We fixed an issue where ranking an entry would generate an IllegalArgumentException. [#4754](https://github.com/JabRef/jabref/issues/4754) -- We fixed an issue where special characters where removed from non label key generation pattern parts [#4767](https://github.com/JabRef/jabref/issues/4767) +- We fixed an issue where special characters where removed from non-label key generation pattern parts [#4767](https://github.com/JabRef/jabref/issues/4767) - We fixed an issue where the RIS import would overwite the article date with the value of the acessed date [#4816](https://github.com/JabRef/jabref/issues/4816) - We fixed an issue where an NullPointer exception was thrown when a referenced entry in an Open/Libre Office document was no longer present in the library. Now an error message with the reference marker of the missing entry is shown. [#4932](https://github.com/JabRef/jabref/issues/4932) - We fixed an issue where a database exception related to a missing timezone was too big. [#4827](https://github.com/JabRef/jabref/issues/4827) @@ -222,13 +231,13 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - The feature to "mark entries" was removed and merged with the groups functionality. For migration, a group is created for every value of the `__markedentry` field and the entry is added to this group. - The number column was removed. - We removed the global search feature. -- We removed the coloring of cells in the maintable according to whether the field is optional/required. +- We removed the coloring of cells in the main table according to whether the field is optional/required. - We removed the feature to find and resolve duplicate BibTeX keys (as this use case is already covered by the integrity check). - We removed a few commands from the right-click menu that are not needed often and thus don't need to be placed that prominently: - Print entry preview: available through entry preview - All commands related to marking: marking is not yet reimplemented - Set/clear/append/rename fields: available through Edit menu - - Manage keywords: available through Edit menu + - Manage keywords: available through the Edit menu - Copy linked files to folder: available through File menu - Add/move/remove from group: removed completely (functionality still available through group interface) - We removed the option to change the column widths in the preferences dialog. [#4546](https://github.com/JabRef/jabref/issues/4546) diff --git a/README.md b/README.md index 40910c6466a..880a8eaa086 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# JabRef Bibliography Management +# JabRef Bibliography Management [![Hacktoberfest](https://img.shields.io/github/hacktoberfest/2019/JabRef/jabref?suggestion_label=hacktoberfest)](https://www.jabref.org/hacktoberfest/2019.html) [![Build Status](https://travis-ci.org/JabRef/jabref.svg?branch=master)](https://travis-ci.org/JabRef/jabref) [![codecov.io](https://codecov.io/github/JabRef/jabref/coverage.svg?branch=master)](https://codecov.io/github/JabRef/jabref?branch=master) diff --git a/build.gradle b/build.gradle index 2c4f578b294..898b4338fb0 100644 --- a/build.gradle +++ b/build.gradle @@ -138,7 +138,7 @@ dependencies { antlr4 'org.antlr:antlr4:4.7.2' compile 'org.antlr:antlr4-runtime:4.7.2' - compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.4.4' + compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.5.0' compile 'org.postgresql:postgresql:42.2.8' @@ -164,9 +164,10 @@ dependencies { compile 'org.jsoup:jsoup:1.12.1' compile 'com.mashape.unirest:unirest-java:1.4.9' - compile 'org.slf4j:slf4j-api:2.0.0-alpha0' + compile 'org.slf4j:slf4j-api:2.0.0-alpha1' compile group: 'org.apache.logging.log4j', name: 'log4j-jcl', version: '3.0.0-20190915.182410-364' compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j18-impl', version: '3.0.0-20190915.182922-250' + compile group: 'org.apache.logging.log4j', name: 'log4j-plugins', version: '3.0.0-20190915.182837-57' implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '3.0.0-20190915.182113-372' compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '3.0.0-20190915.182215-368' annotationProcessor group: 'org.apache.logging.log4j', name: 'log4j-core', version: '3.0.0-20190915.182215-368' @@ -204,7 +205,7 @@ dependencies { testCompile 'net.bytebuddy:byte-buddy-parent:1.10.1' testRuntime group: 'org.apache.logging.log4j', name: 'log4j-core', version: '3.0.0-20190915.182215-368' testRuntime group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '3.0.0-20190915.182552-364' - testCompile 'org.mockito:mockito-core:3.0.0' + testCompile 'org.mockito:mockito-core:3.1.0' //testCompile 'com.github.tomakehurst:wiremock:2.24.1' testCompile ('org.reflections:reflections:0.9.11') { exclude module: "jsr305" @@ -505,14 +506,11 @@ modernizer { } // Release tasks -task generateFinalJabRefPS1File(type: Copy) { - from('buildres') { - include 'JabRef.ps1' - } - into 'build' - filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [jabRefJarFileName: jar.archiveName]) +task deleteInstallerTemp(type: Delete) { + delete "$buildDir/installer" } +jpackage.dependsOn deleteInstallerTemp jlink { options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages'] launcher { @@ -583,7 +581,9 @@ jlink { '--app-version', "${project.version}", '--win-upgrade-uuid', 'd636b4ee-6f10-451e-bf57-c89656780e36', '--win-dir-chooser', - '--win-shortcut' + '--win-shortcut', + '--temp', "$buildDir/installer", + '--resource-dir', "${projectDir}/buildres" ] } @@ -608,6 +608,14 @@ jlink { } } } +tasks.jpackageImage.doLast { + copy { + from("/buildres/") { + include "jabref.json", "JabRefHost.bat", "JabRefHost.ps1" + } + into "$buildDir/distribution/JabRef" + } +} jmh { warmupIterations = 5 diff --git a/buildres/JabRef-post-image.wsf b/buildres/JabRef-post-image.wsf new file mode 100644 index 00000000000..56ddd9097f4 --- /dev/null +++ b/buildres/JabRef-post-image.wsf @@ -0,0 +1,35 @@ + + + + + + diff --git a/buildres/JabRef.bat b/buildres/JabRefHost.bat similarity index 60% rename from buildres/JabRef.bat rename to buildres/JabRefHost.bat index 7a2cee363b0..d44d94f282c 100644 --- a/buildres/JabRef.bat +++ b/buildres/JabRefHost.bat @@ -1,3 +1,3 @@ @echo off pushd %~dp0 -@powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File ".\JabRef.ps1" +@powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File ".\JabRefHost.ps1" diff --git a/buildres/JabRef.ps1 b/buildres/JabRefHost.ps1 similarity index 72% rename from buildres/JabRef.ps1 rename to buildres/JabRefHost.ps1 index fe814e6013e..f31df86f74e 100644 --- a/buildres/JabRef.ps1 +++ b/buildres/JabRefHost.ps1 @@ -11,8 +11,7 @@ function Respond($response) { } } -$jabRefJarFileName = "@jabRefJarFileName@" -$jabRefJar = [System.IO.Path]::Combine($PSScriptRoot, $jabRefJarFileName) +$jabRefExe = [System.IO.Path]::Combine($PSScriptRoot, "JabRef.exe") try { $reader = New-Object System.IO.BinaryReader([System.Console]::OpenStandardInput()) @@ -21,16 +20,16 @@ try { $message = $messageRaw | ConvertFrom-Json if ($message.Status -eq "validate") { - if (-not (Test-Path $jabRefJar)) { - return Respond @{message="jarNotFound";path=$jabRefJar} + if (-not (Test-Path $jabRefExe)) { + return Respond @{message="jarNotFound";path=$jabRefExe} } else { return Respond @{message="jarFound"} } } - - if (-not (Test-Path $jabRefJar)) { + + if (-not (Test-Path $jabRefExe)) { $wshell = New-Object -ComObject Wscript.Shell - $popup = "Unable to locate '$jabRefJarFileName' in '$([System.IO.Path]::GetDirectoryName($jabRefJar))'." + $popup = "Unable to locate '$jabRefExe'." $wshell.Popup($popup,0,"JabRef", 0x0 + 0x30) return } @@ -39,7 +38,7 @@ try { #$wshell.Popup($message.Text,0,"JabRef", 0x0 + 0x30) $messageText = $message.Text - $output = & java -jar $jabRefJar -importBibtex "$messageText" 2>&1 + $output = & $jabRefExe -importBibtex "$messageText" 2>&1 #$output = & echoargs -importBibtex $messageText 2>&1 #$wshell.Popup($output,0,"JabRef", 0x0 + 0x30) return Respond @{message="ok";output="$output"} diff --git a/buildres/JabRefTopBanner.bmp b/buildres/JabRefTopBanner.bmp new file mode 100644 index 00000000000..7e95c3b8fd7 Binary files /dev/null and b/buildres/JabRefTopBanner.bmp differ diff --git a/buildres/jabref.json b/buildres/jabref.json index dee50f008fe..9024c5b17f4 100644 --- a/buildres/jabref.json +++ b/buildres/jabref.json @@ -1,7 +1,7 @@ { "name": "org.jabref.jabref", "description": "JabRef", - "path": "JabRef.bat", + "path": "JabRefHost.bat", "type": "stdio", "allowed_extensions": [ "@jabfox" diff --git a/snap/plugins/x_gradle.py b/snap/plugins/x_gradle.py deleted file mode 100644 index 899d6567712..00000000000 --- a/snap/plugins/x_gradle.py +++ /dev/null @@ -1,301 +0,0 @@ -# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- -# -# Copyright (C) 2016, 2018 Canonical Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 3 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -"""This plugin is useful for building parts that use gradle. - -The gradle build system is commonly used to build Java projects. -The plugin requires a pom.xml in the root of the source tree. - -This plugin uses the common plugin keywords as well as those for "sources". -For more information check the 'plugins' topic for the former and the -'sources' topic for the latter. - -Additionally, this plugin uses the following plugin-specific keywords: - - - gradle-options: - (list of strings) - Flags to pass to the build using the gradle semantics for parameters. - The 'jar' option is always passed in as the last parameter. - - - gradle-output-dir: - (string; default: 'build/libs') - The output directory where the resulting jar or war files from gradle[w] - are generated. - - - gradle-version: - (string) - The version of gradle you want to use to build the source artifacts. - Defaults to the current release downloadable from - https://services.gradle.org/distributions/ - The entry is ignored if gradlew is found. - - - gradle-version-checksum: - (string) - The checksum for gradle-version in the form of /. - As an example "sha512/2a803f578f341e164f6753e410413d16ab60fab...". - - - gradle-openjdk-version: - (string) - openjdk version available to the base to use. If not set the latest - version available to the base will be used. -""" - -import logging -import os -import urllib.parse -from glob import glob -from typing import Sequence - -import snapcraft -from snapcraft import file_utils, formatting_utils -from snapcraft.internal import errors, sources - -logger = logging.getLogger(__name__) - - -_DEFAULT_GRADLE_VERSION = "4.10.2" -_DEFAULT_GRADLE_CHECKSUM = ( - "sha256/b49c6da1b2cb67a0caf6c7480630b51c70a11ca2016ff2f555eaeda863143a29" -) -_GRADLE_URL = "https://services.gradle.org/distributions/gradle-{version}-bin.zip" - - -class UnsupportedJDKVersionError(errors.SnapcraftError): - - fmt = ( - "The gradle-openjdk-version plugin property was set to {version!r}.\n" - "Valid values for the {base!r} base are: {valid_versions}." - ) - - def __init__( - self, *, base: str, version: str, valid_versions: Sequence[str] - ) -> None: - super().__init__( - base=base, - version=version, - valid_versions=formatting_utils.humanize_list( - valid_versions, conjunction="or" - ), - ) - - -class GradlePlugin(snapcraft.BasePlugin): - @classmethod - def schema(cls): - schema = super().schema() - schema["properties"]["gradle-options"] = { - "type": "array", - "minitems": 1, - "uniqueItems": True, - "items": {"type": "string"}, - "default": [], - } - schema["properties"]["gradle-output-dir"] = { - "type": "string", - "default": "build/libs", - } - - schema["properties"]["gradle-version"] = {"type": "string"} - - schema["properties"]["gradle-version-checksum"] = {"type": "string"} - - schema["properties"]["gradle-openjdk-version"] = { - "type": "string", - "default": "", - } - - schema["required"] = ["source"] - - return schema - - @classmethod - def get_pull_properties(cls): - # Inform Snapcraft of the properties associated with pulling. If these - # change in the YAML Snapcraft will consider the pull step dirty. - return ["gradle-version", "gradle-version-checksum", "gradle-openjdk-version"] - - @classmethod - def get_build_properties(cls): - # Inform Snapcraft of the properties associated with building. If these - # change in the YAML Snapcraft will consider the build step dirty. - return super().get_build_properties() + ["gradle-options", "gradle-output-dir"] - - @property - def _gradle_tar(self): - if self._gradle_tar_handle is None: - gradle_uri = _GRADLE_URL.format(version=self._gradle_version) - self._gradle_tar_handle = sources.Zip( - gradle_uri, self._gradle_dir, source_checksum=self._gradle_checksum - ) - return self._gradle_tar_handle - - def __init__(self, name, options, project): - super().__init__(name, options, project) - - self._setup_gradle() - self._setup_base_tools(project.info.get_build_base()) - - def _setup_base_tools(self, base): - if base not in ("core", "core16", "core18"): - raise errors.PluginBaseError( - part_name=self.name, base=self.project.info.get_build_base() - ) - - if base in ("core", "core16"): - valid_versions = ["8", "9"] - elif base == "core18": - valid_versions = ["8", "11"] - - version = self.options.gradle_openjdk_version - if not version: - version = valid_versions[-1] - elif version not in valid_versions: - raise UnsupportedJDKVersionError( - version=version, base=base, valid_versions=valid_versions - ) - - self.stage_packages.append("openjdk-{}-jre-headless".format(version)) - self.build_packages.append("openjdk-{}-jdk-headless".format(version)) - self.build_packages.append("ca-certificates-java") - self._java_version = version - - def _using_gradlew(self) -> bool: - return os.path.isfile(os.path.join(self.sourcedir, "gradlew")) - - def _setup_gradle(self): - self._gradle_tar_handle = None - self._gradle_dir = os.path.join(self.partdir, "gradle") - if self.options.gradle_version: - self._gradle_version = self.options.gradle_version - self._gradle_checksum = self.options.gradle_version_checksum - else: - self._gradle_version = _DEFAULT_GRADLE_VERSION - self._gradle_checksum = _DEFAULT_GRADLE_CHECKSUM - - def pull(self): - super().pull() - - if self._using_gradlew(): - logger.info("Found gradlew, skipping gradle setup.") - return - - os.makedirs(self._gradle_dir, exist_ok=True) - self._gradle_tar.download() - - def build(self): - super().build() - - if self._using_gradlew(): - gradle_cmd = ["./gradlew"] - else: - self._gradle_tar.provision(self._gradle_dir, keep_zip=True) - gradle_cmd = ["gradle"] - self.run( - gradle_cmd - + self._get_proxy_options() - + self.options.gradle_options, - rootdir=self.builddir, - ) - - src = os.path.join(self.builddir, self.options.gradle_output_dir) - basedir = "jabref" - # jarfiles = glob(os.path.join(src, "*.jar")) - # warfiles = glob(os.path.join(src, "*.war")) - - # if len(jarfiles) > 0: - # basedir = "jar" - # elif len(warfiles) > 0: - # basedir = "war" - # jarfiles = warfiles - # else: - # raise RuntimeError("Could not find any built jar files for part") - - file_utils.link_or_copy_tree( - src, - os.path.join(self.installdir, basedir), - copy_function=lambda src, dst: file_utils.link_or_copy( - src, dst, self.installdir - ), - ) - - self._create_symlinks() - - def _create_symlinks(self): - if self.project.info.get_build_base() not in ("core18", "core16", "core"): - raise errors.PluginBaseError( - part_name=self.name, base=self.project.info.get_build_base() - ) - - os.makedirs(os.path.join(self.installdir, "bin"), exist_ok=True) - java_bin = glob( - os.path.join( - self.installdir, - "usr", - "lib", - "jvm", - "java-{}-openjdk-*".format(self._java_version), - "bin", - "java", - ) - )[0] - os.symlink( - os.path.relpath(java_bin, os.path.join(self.installdir, "bin")), - os.path.join(self.installdir, "bin", "java"), - ) - - def run(self, cmd, rootdir): - super().run(cmd, cwd=rootdir, env=self._build_environment()) - - def _build_environment(self): - if self._using_gradlew(): - return - - env = os.environ.copy() - gradle_bin = os.path.join( - self._gradle_dir, "gradle-{}".format(self._gradle_version), "bin" - ) - print(gradle_bin) - - if env.get("PATH"): - new_path = "{}:{}".format(gradle_bin, env.get("PATH")) - else: - new_path = gradle_bin - - env["PATH"] = new_path - return env - - def _get_proxy_options(self): - proxy_options = [] - for var in ("http", "https"): - proxy = os.environ.get("{}_proxy".format(var), False) - if proxy: - parsed_url = urllib.parse.urlparse(proxy) - proxy_options.append( - "-D{}.proxyHost={}".format(var, parsed_url.hostname) - ) - if parsed_url.port: - proxy_options.append( - "-D{}.proxyPort={}".format(var, parsed_url.port) - ) - if parsed_url.username: - proxy_options.append( - "-D{}.proxyUser={}".format(var, parsed_url.username) - ) - if parsed_url.password: - proxy_options.append( - "-D{}.proxyPassword={}".format(var, parsed_url.password) - ) - return proxy_options diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index b62d2d571e3..a60eadd2d4d 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,7 +1,9 @@ name: jabref -version: "git" +# adopt-info: jabref +version: 'master' version-script: cat build.gradle | grep "^version =" | cut -d'"' -f2 -#icon: snap/gui/jabref.png +icon: snap/gui/jabref.png +license: MIT summary: Bibliography manager description: JabRef is an open source bibliography reference manager. The native file format used by JabRef is BibTeX, the standard LaTeX bibliography format. @@ -14,11 +16,10 @@ architectures: apps: jabref: - command: desktop-launch $SNAP/jabref/bin/JabRefMain + command: bin/JabRef + extensions: [gnome-3-28] environment: _JAVA_OPTIONS: "-Duser.home=$SNAP_USER_DATA" - XDG_DATA_DIRS: $SNAP/share:$XDG_DATA_DIRS - GSETTINGS_SCHEMA_DIR: $SNAP/share/glib-2.0/schemas plugs: - desktop - desktop-legacy @@ -28,43 +29,13 @@ apps: - opengl - network-bind - removable-media - - gnome-3-28-1804 - -plugs: - gnome-3-28-1804: - interface: content - target: gnome-platform - default-provider: gnome-3-28-1804:gnome-3-28-1804 - content: gnome-3-28-1804 - gtk-3-themes: - interface: content - target: $SNAP/data-dir/themes - default-provider: gtk-common-themes:gtk-3-themes - icon-themes: - interface: content - target: $SNAP/data-dir/icons - default-provider: gtk-common-themes:icon-themes - parts: jabref: - plugin: x_gradle - source: . - source-type: git + plugin: dump + source: build/distribution/JabRef-portable_linux.tar.gz + # override-pull: | + # snapcraftctl pull + # snapcraftctl set-version "$(cat app/JabRef.cfg | grep "app.version=" | cut -d'=' -f2)" stage-packages: - - openjdk-11-jre - - openjfx - x11-utils - gradle-options: [jlink, -xtest] - gradle-output-dir: 'build/image' - desktop-gnome-platform: - source: https://github.com/ubuntu/snapcraft-desktop-helpers.git - source-subdir: gtk - plugin: make - make-parameters: ["FLAVOR=gtk3"] - build-packages: - - build-essential - - libgtk-3-dev - override-build: | - snapcraftctl build - mkdir -pv $SNAPCRAFT_PART_INSTALL/gnome-platform diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index b35a6bdce4d..30cc6f4aecb 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -95,7 +95,6 @@ import org.jabref.model.entry.field.SpecialFieldValue; import org.jabref.model.entry.field.StandardField; import org.jabref.preferences.JabRefPreferences; -import org.jabref.preferences.PreviewPreferences; import com.google.common.eventbus.Subscribe; import org.fxmisc.easybind.EasyBind; @@ -352,6 +351,13 @@ private void setupActions() { new SpecialFieldViewModel(SpecialField.READ_STATUS, undoManager).getSpecialFieldAction(status, this.frame)); } + actions.put(Actions.NEXT_PREVIEW_STYLE, () -> { + entryEditor.nextPreviewStyle(); + }); + actions.put(Actions.PREVIOUS_PREVIEW_STYLE, () -> { + entryEditor.previousPreviewStyle(); + }); + actions.put(Actions.SEND_AS_EMAIL, new SendAsEMailAction(frame)); actions.put(Actions.WRITE_XMP, new WriteXMPAction(this)::execute); @@ -844,23 +850,6 @@ private void showAndEdit() { } } - public void nextPreviewStyle() { - cyclePreview(Globals.prefs.getPreviewPreferences().getPreviewCyclePosition() + 1); - } - - public void previousPreviewStyle() { - cyclePreview(Globals.prefs.getPreviewPreferences().getPreviewCyclePosition() - 1); - } - - private void cyclePreview(int newPosition) { - PreviewPreferences previewPreferences = Globals.prefs.getPreviewPreferences() - .getBuilder() - .withPreviewCyclePosition(newPosition) - .build(); - Globals.prefs.storePreviewPreferences(previewPreferences); - entryEditor.updatePreviewInTabs(previewPreferences); - } - /** * Removes the bottom component. */ diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java index dadcad8be9c..9bd2a2a9c4c 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java @@ -50,7 +50,6 @@ import org.jabref.model.entry.field.Field; import org.jabref.model.util.FileUpdateMonitor; import org.jabref.preferences.PreferencesService; -import org.jabref.preferences.PreviewPreferences; import com.airhacks.afterburner.views.ViewLoader; import org.fxmisc.easybind.EasyBind; @@ -404,11 +403,11 @@ public void setFocusToField(Field field) { }); } - public void updatePreviewInTabs(PreviewPreferences previewPreferences) { - for (Tab tab : this.entryEditorTabs) { - if (tab instanceof FieldsEditorTab) { - ((FieldsEditorTab) tab).previewPanel.updateLayout(previewPreferences); - } - } + public void nextPreviewStyle() { + this.entryEditorTabs.forEach(EntryEditorTab::nextPreviewStyle); + } + + public void previousPreviewStyle() { + this.entryEditorTabs.forEach(EntryEditorTab::previousPreviewStyle); } } diff --git a/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java b/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java index a0b91a914f7..6c5da5ec0f6 100644 --- a/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/EntryEditorTab.java @@ -44,4 +44,18 @@ public void notifyAboutFocus(BibEntry entry) { handleFocus(); } + /** + * Switch to next Preview style - should be overriden if a EntryEditorTab is actually showing a preview + */ + protected void nextPreviewStyle() { + // do nothing by default + } + + /** + * Switch to previous Preview style - should be overriden if a EntryEditorTab is actually showing a preview + */ + protected void previousPreviewStyle() { + // do nothing by default + } + } diff --git a/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java b/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java index ce226b512f8..eba5b206523 100644 --- a/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java +++ b/src/main/java/org/jabref/gui/entryeditor/FieldsEditorTab.java @@ -40,12 +40,12 @@ * A single tab displayed in the EntryEditor holding several FieldEditors. */ abstract class FieldsEditorTab extends EntryEditorTab { - public PreviewPanel previewPanel; protected final BibDatabaseContext databaseContext; private final Map editors = new LinkedHashMap<>(); private final boolean isCompressed; private final SuggestionProviders suggestionProviders; private final DialogService dialogService; + private PreviewPanel previewPanel; private FieldEditorFX activeField; private UndoManager undoManager; private Collection fields = new ArrayList<>(); @@ -197,6 +197,16 @@ protected void bindToEntry(BibEntry entry) { }); } + @Override + protected void nextPreviewStyle() { + previewPanel.nextPreviewStyle(); + } + + @Override + protected void previousPreviewStyle() { + previewPanel.previousPreviewStyle(); + } + protected abstract SortedSet determineFieldsToShow(BibEntry entry); public Collection getShownFields() { @@ -208,7 +218,7 @@ private void initPanel() { gridPane = new GridPane(); gridPane.getStyleClass().add("editorPane"); - previewPanel = new PreviewPanel(databaseContext, null, dialogService, ExternalFileTypes.getInstance(), Globals.getKeyPrefs(), Globals.prefs.getPreviewPreferences()); + previewPanel = new PreviewPanel(databaseContext, dialogService, ExternalFileTypes.getInstance(), Globals.getKeyPrefs(), Globals.prefs); // Warp everything in a scroll-pane ScrollPane scrollPane = new ScrollPane(); diff --git a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java index 122b5baf610..94b63150d15 100644 --- a/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java +++ b/src/main/java/org/jabref/gui/exporter/ExportToClipboardAction.java @@ -5,6 +5,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Optional; @@ -20,6 +21,7 @@ import org.jabref.gui.util.BackgroundTask; import org.jabref.logic.exporter.Exporter; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.util.FileType; import org.jabref.logic.util.OS; import org.jabref.model.entry.BibEntry; import org.jabref.preferences.JabRefPreferences; @@ -31,6 +33,9 @@ public class ExportToClipboardAction extends SimpleCommand { private static final Logger LOGGER = LoggerFactory.getLogger(ExportToClipboardAction.class); + // Only text based exporters can be used + private static final List SUPPORTED_FILETYPES = Arrays.asList("txt", "rtf", "rdf", "xml", "html", "htm", "csv", "ris"); + private JabRefFrame frame; private final DialogService dialogService; private BasePanel panel; @@ -59,6 +64,7 @@ public void execute() { List exporters = Globals.exportFactory.getExporters().stream() .sorted(Comparator.comparing(Exporter::getName)) + .filter(exporter -> SUPPORTED_FILETYPES.containsAll(exporter.getFileType().getExtensions())) .collect(Collectors.toList()); //Find default choice, if any @@ -71,12 +77,12 @@ public void execute() { Localization.lang("Export"), defaultChoice, exporters); selectedExporter.ifPresent(exporter -> BackgroundTask.wrap(() -> exportToClipboard(exporter)) - .onSuccess(this::setContentToClipboard) - .executeWith(Globals.TASK_EXECUTOR)); - + .onSuccess(this::setContentToClipboard) + .onFailure(ex -> { /* swallow as already logged */ }) + .executeWith(Globals.TASK_EXECUTOR)); } - private String exportToClipboard(Exporter exporter) { + private ExportResult exportToClipboard(Exporter exporter) throws Exception { // Set the global variable for this database's file directory before exporting, // so formatters can resolve linked files correctly. // (This is an ugly hack!) @@ -102,9 +108,10 @@ private String exportToClipboard(Exporter exporter) { entries); // Read the file and put the contents on the clipboard: - return readFileToString(tmp); + return new ExportResult(readFileToString(tmp), exporter.getFileType()); } catch (Exception e) { LOGGER.error("Error exporting to clipboard", e); + throw new Exception("Rethrow ", e); } finally { // Clean up: if ((tmp != null) && Files.exists(tmp)) { @@ -115,12 +122,19 @@ private String exportToClipboard(Exporter exporter) { } } } - return ""; } - private void setContentToClipboard(String content) { + private void setContentToClipboard(ExportResult result) { ClipboardContent clipboardContent = new ClipboardContent(); - clipboardContent.putRtf(content); + List extensions = result.fileType.getExtensions(); + if (extensions.contains("html")) { + clipboardContent.putHtml(result.content); + } else if (extensions.contains("rtf")) { + clipboardContent.putRtf(result.content); + } else if (extensions.contains("rdf")) { + clipboardContent.putRtf(result.content); + } + clipboardContent.putString(result.content); Globals.clipboardManager.setContent(clipboardContent); dialogService.notify(Localization.lang("Entries exported to clipboard") + ": " + entries.size()); @@ -135,4 +149,14 @@ private String readFileToString(Path tmp) throws IOException { return reader.lines().collect(Collectors.joining(OS.NEWLINE)); } } + + private class ExportResult { + final String content; + final FileType fileType; + + ExportResult(String content, FileType fileType) { + this.content = content; + this.fileType = fileType; + } + } } diff --git a/src/main/java/org/jabref/gui/preview/CitationStyleToClipboardWorker.java b/src/main/java/org/jabref/gui/preview/CitationStyleToClipboardWorker.java index 80299068046..23a4f056d36 100644 --- a/src/main/java/org/jabref/gui/preview/CitationStyleToClipboardWorker.java +++ b/src/main/java/org/jabref/gui/preview/CitationStyleToClipboardWorker.java @@ -87,8 +87,11 @@ private List generateCitations() throws IOException { * Generates a plain text string out of the preview and copies it additionally to the html to the clipboard * (WYSIWYG Editors use the HTML, plain text editors the text) */ - protected static String processPreview(List citations) { - return String.join(CitationStyleOutputFormat.HTML.getLineSeparator(), citations); + protected static ClipboardContent processPreview(List citations) { + ClipboardContent content = new ClipboardContent(); + content.putHtml(String.join(CitationStyleOutputFormat.HTML.getLineSeparator(), citations)); + content.putString(String.join(CitationStyleOutputFormat.HTML.getLineSeparator(), citations)); + return content; } /** @@ -108,6 +111,7 @@ protected static ClipboardContent processRtf(List citations) { String.join(CitationStyleOutputFormat.RTF.getLineSeparator(), citations) + "}"; ClipboardContent content = new ClipboardContent(); + content.putString(result); content.putRtf(result); return content; } @@ -134,6 +138,7 @@ protected static ClipboardContent processXslFo(List citations) { "" + OS.NEWLINE; ClipboardContent content = new ClipboardContent(); + content.putString(result); content.put(ClipBoardManager.XML, result); return content; } @@ -155,6 +160,7 @@ protected static ClipboardContent processHtml(List citations) { "" + OS.NEWLINE; ClipboardContent content = new ClipboardContent(); + content.putString(result); content.putHtml(result); return content; } @@ -162,7 +168,7 @@ protected static ClipboardContent processHtml(List citations) { private void setClipBoardContent(List citations) { // if it's not a citation style take care of the preview if (!(style instanceof CitationStylePreviewLayout)) { - clipBoardManager.setHtmlContent(processPreview(citations)); + clipBoardManager.setContent(processPreview(citations)); } else { // if it's generated by a citation style take care of each output format ClipboardContent content; diff --git a/src/main/java/org/jabref/gui/preview/PreviewPanel.java b/src/main/java/org/jabref/gui/preview/PreviewPanel.java index c4fbde25a1e..3f25375cf5b 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewPanel.java +++ b/src/main/java/org/jabref/gui/preview/PreviewPanel.java @@ -17,7 +17,6 @@ import javafx.scene.layout.VBox; import org.jabref.Globals; -import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.externalfiles.ExternalFilesEntryLinker; import org.jabref.gui.externalfiletype.ExternalFileTypes; @@ -28,6 +27,7 @@ import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; +import org.jabref.preferences.JabRefPreferences; import org.jabref.preferences.PreviewPreferences; import org.slf4j.Logger; @@ -40,18 +40,19 @@ public class PreviewPanel extends VBox { private final ExternalFilesEntryLinker fileLinker; private final KeyBindingRepository keyBindingRepository; private final PreviewViewer previewView; + private final JabRefPreferences preferences; private BibEntry entry; - private BasePanel basePanel; private DialogService dialogService; - public PreviewPanel(BibDatabaseContext database, BasePanel basePanel, DialogService dialogService, ExternalFileTypes externalFileTypes, KeyBindingRepository keyBindingRepository, PreviewPreferences preferences) { - this.basePanel = basePanel; + public PreviewPanel(BibDatabaseContext database, DialogService dialogService, ExternalFileTypes externalFileTypes, KeyBindingRepository keyBindingRepository, JabRefPreferences preferences) { this.keyBindingRepository = keyBindingRepository; this.dialogService = dialogService; - fileLinker = new ExternalFilesEntryLinker(externalFileTypes, Globals.prefs.getFilePreferences(), database); + this.preferences = preferences; + fileLinker = new ExternalFilesEntryLinker(externalFileTypes, preferences.getFilePreferences(), database); + PreviewPreferences previewPreferences = preferences.getPreviewPreferences(); previewView = new PreviewViewer(database, dialogService, Globals.stateManager); - previewView.setLayout(preferences.getCurrentPreviewStyle()); + previewView.setLayout(previewPreferences.getCurrentPreviewStyle()); previewView.setContextMenu(createPopupMenu()); previewView.setOnDragDetected(event -> { previewView.startFullDrag(); @@ -97,11 +98,7 @@ public PreviewPanel(BibDatabaseContext database, BasePanel basePanel, DialogServ this.getChildren().add(previewView); createKeyBindings(); - updateLayout(preferences, true); - } - - public void close() { - basePanel.closeBottomPane(); + updateLayout(previewPreferences, true); } public void updateLayout(PreviewPreferences previewPreferences) { @@ -111,6 +108,7 @@ public void updateLayout(PreviewPreferences previewPreferences) { private void updateLayout(PreviewPreferences previewPreferences, boolean init) { PreviewLayout currentPreviewStyle = previewPreferences.getCurrentPreviewStyle(); previewView.setLayout(currentPreviewStyle); + preferences.storePreviewPreferences(previewPreferences); if (!init) { dialogService.notify(Localization.lang("Preview style changed to: %0", currentPreviewStyle.getName())); } @@ -125,10 +123,6 @@ private void createKeyBindings() { previewView.copyPreviewToClipBoard(); event.consume(); break; - case CLOSE: - close(); - event.consume(); - break; default: } } @@ -141,21 +135,19 @@ private ContextMenu createPopupMenu() { copyPreview.setOnAction(event -> previewView.copyPreviewToClipBoard()); MenuItem printEntryPreview = new MenuItem(Localization.lang("Print entry preview"), IconTheme.JabRefIcons.PRINTED.getGraphicNode()); printEntryPreview.setOnAction(event -> previewView.print()); - /* Deleted since it does not work anymore. Needs refactoring. MenuItem previousPreviewLayout = new MenuItem(Localization.lang("Previous preview layout")); previousPreviewLayout.setAccelerator(keyBindingRepository.getKeyCombination(KeyBinding.PREVIOUS_PREVIEW_LAYOUT)); - previousPreviewLayout.setOnAction(event -> basePanel.previousPreviewStyle()); + previousPreviewLayout.setOnAction(event -> this.previousPreviewStyle()); MenuItem nextPreviewLayout = new MenuItem(Localization.lang("Next preview layout")); nextPreviewLayout.setAccelerator(keyBindingRepository.getKeyCombination(KeyBinding.NEXT_PREVIEW_LAYOUT)); - nextPreviewLayout.setOnAction(event -> basePanel.nextPreviewStyle()); - */ + nextPreviewLayout.setOnAction(event -> this.nextPreviewStyle()); ContextMenu menu = new ContextMenu(); menu.getItems().add(copyPreview); menu.getItems().add(printEntryPreview); menu.getItems().add(new SeparatorMenuItem()); - // menu.getItems().add(nextPreviewLayout); - // menu.getItems().add(previousPreviewLayout); + menu.getItems().add(nextPreviewLayout); + menu.getItems().add(previousPreviewLayout); return menu; } @@ -167,4 +159,20 @@ public void setEntry(BibEntry entry) { public void print() { previewView.print(); } + + public void nextPreviewStyle() { + cyclePreview(preferences.getPreviewPreferences().getPreviewCyclePosition() + 1); + } + + public void previousPreviewStyle() { + cyclePreview(preferences.getPreviewPreferences().getPreviewCyclePosition() - 1); + } + + private void cyclePreview(int newPosition) { + PreviewPreferences previewPreferences = preferences.getPreviewPreferences() + .getBuilder() + .withPreviewCyclePosition(newPosition) + .build(); + updateLayout(previewPreferences); + } } diff --git a/src/main/java/org/jabref/gui/preview/PreviewViewer.java b/src/main/java/org/jabref/gui/preview/PreviewViewer.java index 8811d398b88..c3d0ec4b405 100644 --- a/src/main/java/org/jabref/gui/preview/PreviewViewer.java +++ b/src/main/java/org/jabref/gui/preview/PreviewViewer.java @@ -29,8 +29,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; /** * Displays an BibEntry using the given layout format. @@ -175,16 +173,8 @@ public void copyPreviewToClipBoard() { StringBuilder previewStringContent = new StringBuilder(); Document document = previewView.getEngine().getDocument(); - NodeList nodeList = document.getElementsByTagName("html"); - - //Nodelist does not implement iterable - for (int i = 0; i < nodeList.getLength(); i++) { - Element element = (Element) nodeList.item(i); - previewStringContent.append(element.getTextContent()); - } - ClipboardContent content = new ClipboardContent(); - content.putString(previewStringContent.toString()); + content.putString(document.getElementById("content").getTextContent()); content.putHtml((String) previewView.getEngine().executeScript("document.documentElement.outerHTML")); clipBoardManager.setContent(content); diff --git a/src/main/java/org/jabref/gui/util/UiThreadList.java b/src/main/java/org/jabref/gui/util/UiThreadList.java index a09efa8957c..b9f8b8853c7 100644 --- a/src/main/java/org/jabref/gui/util/UiThreadList.java +++ b/src/main/java/org/jabref/gui/util/UiThreadList.java @@ -1,18 +1,38 @@ package org.jabref.gui.util; +import java.util.concurrent.CountDownLatch; + import javafx.application.Platform; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.collections.transformation.TransformationList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + class UiThreadList extends TransformationList { + private static final Logger LOGGER = LoggerFactory.getLogger(UiThreadList.class); public UiThreadList(ObservableList source) { super(source); } @Override protected void sourceChanged(ListChangeListener.Change change) { - Platform.runLater(() -> fireChange(change)); + if (Platform.isFxApplicationThread()) { + fireChange(change); + } else { + CountDownLatch latch = new CountDownLatch(1); + Platform.runLater(() -> { + fireChange(change); + latch.countDown(); + }); + + try { + latch.await(); + } catch (InterruptedException e) { + LOGGER.error("Error while running on JavaFX thread", e); + } + } } @Override diff --git a/src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java b/src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java index 4169df2da8f..2f1bce49674 100644 --- a/src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java +++ b/src/main/java/org/jabref/logic/bibtex/BibEntryWriter.java @@ -111,7 +111,7 @@ private void writeRequiredFieldsFirstRemainingFieldsSecond(BibEntry entry, Write for (OrFields value : type.get().getRequiredFields()) { for (Field field : value) { writeField(entry, out, field, indentation); - written.add(value.getPrimary()); + written.add(field); } } // Then optional fields. diff --git a/src/main/resources/csl-locales b/src/main/resources/csl-locales index e89e6b08b5c..9785a6e3584 160000 --- a/src/main/resources/csl-locales +++ b/src/main/resources/csl-locales @@ -1 +1 @@ -Subproject commit e89e6b08b5c621a414fc7114f2129efac5f8c7d5 +Subproject commit 9785a6e3584e8c903df3d5a53f0e800dcabd282b diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index 36ac1f63004..6169061a140 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit 36ac1f63004b1b85c8aed51f7111a8bed3fb7208 +Subproject commit 6169061a140068e897337de95f917008037fcd3b diff --git a/src/test/java/org/jabref/gui/preview/CitationStyleToClipboardWorkerTest.java b/src/test/java/org/jabref/gui/preview/CitationStyleToClipboardWorkerTest.java index 0ac88a6d323..82501d0e182 100644 --- a/src/test/java/org/jabref/gui/preview/CitationStyleToClipboardWorkerTest.java +++ b/src/test/java/org/jabref/gui/preview/CitationStyleToClipboardWorkerTest.java @@ -39,7 +39,8 @@ void processPreviewText() throws Exception { OS.NEWLINE + "Abstract: This entry describes a test scenario which may be useful in JabRef. By providing a test entry it is possible to see how certain things will look in this graphical BIB-file mananger. "; - String actual = CitationStyleToClipboardWorker.processPreview(Arrays.asList(citation, citation)); + ClipboardContent clipboardContent = CitationStyleToClipboardWorker.processPreview(Arrays.asList(citation, citation)); + String actual = clipboardContent.getString(); assertEquals(expected, actual); } @@ -91,8 +92,8 @@ void processPreviewHtml() throws Exception { "" + OS.NEWLINE + "

"; - String actual = CitationStyleToClipboardWorker.processPreview(Arrays.asList(citation, citation)); - + ClipboardContent clipboardContent = CitationStyleToClipboardWorker.processPreview(Arrays.asList(citation, citation)); + String actual = clipboardContent.getString(); assertEquals(expected, actual); } diff --git a/src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java b/src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java index 3c158a64d53..5b2d91b77c3 100644 --- a/src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java +++ b/src/test/java/org/jabref/logic/bibtex/BibEntryWriterTest.java @@ -106,6 +106,64 @@ void writeEntryWithFile() throws Exception { + "}" + OS.NEWLINE, stringWriter.toString()); } + @Test + void writeEntryWithOrField() throws Exception { + StringWriter stringWriter = new StringWriter(); + + BibEntry entry = new BibEntry(StandardEntryType.InBook); + //set an required OR field (author/editor) + entry.setField(StandardField.EDITOR, "Foo Bar"); + entry.setField(StandardField.JOURNAL, "International Journal of Something"); + //set an optional field + entry.setField(StandardField.NUMBER, "1"); + entry.setField(StandardField.NOTE, "some note"); + + writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX); + + String actual = stringWriter.toString(); + + // @formatter:off + String expected = OS.NEWLINE + "@InBook{," + OS.NEWLINE + + " editor = {Foo Bar}," + OS.NEWLINE + + " note = {some note}," + OS.NEWLINE + + " number = {1}," + OS.NEWLINE + + " journal = {International Journal of Something}," + OS.NEWLINE + + "}" + OS.NEWLINE; + // @formatter:on + + assertEquals(expected, actual); + } + + @Test + void writeEntryWithOrFieldBothFieldsPresent() throws Exception { + StringWriter stringWriter = new StringWriter(); + + BibEntry entry = new BibEntry(StandardEntryType.InBook); + //set an required OR field with both fields(author/editor) + entry.setField(StandardField.AUTHOR, "Foo Thor"); + entry.setField(StandardField.EDITOR, "Edi Bar"); + entry.setField(StandardField.JOURNAL, "International Journal of Something"); + //set an optional field + entry.setField(StandardField.NUMBER, "1"); + entry.setField(StandardField.NOTE, "some note"); + + writer.write(entry, stringWriter, BibDatabaseMode.BIBTEX); + + String actual = stringWriter.toString(); + + // @formatter:off + String expected = OS.NEWLINE + "@InBook{," + OS.NEWLINE + + " author = {Foo Thor}," + OS.NEWLINE + + " editor = {Edi Bar}," + OS.NEWLINE + + " note = {some note}," + OS.NEWLINE + + " number = {1}," + OS.NEWLINE + + " journal = {International Journal of Something}," + OS.NEWLINE + + "}" + OS.NEWLINE; + // @formatter:on + + assertEquals(expected, actual); + } + @Test public void writeReallyUnknownTypeTest() throws Exception { String expected = OS.NEWLINE + "@Reallyunknowntype{test," + OS.NEWLINE + diff --git a/src/test/java/org/jabref/logic/util/BracketedPatternTest.java b/src/test/java/org/jabref/logic/util/BracketedPatternTest.java index 5e2cd0511e9..41bfbad9622 100644 --- a/src/test/java/org/jabref/logic/util/BracketedPatternTest.java +++ b/src/test/java/org/jabref/logic/util/BracketedPatternTest.java @@ -14,14 +14,14 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -public class BracketedPatternTest { +class BracketedPatternTest { private BibEntry bibentry; private BibDatabase database; private BibEntry dbentry; @BeforeEach - public void setUp() throws Exception { + void setUp() throws Exception { bibentry = new BibEntry(); bibentry.setField(StandardField.AUTHOR, "O. Kitsune"); bibentry.setField(StandardField.YEAR, "2017"); @@ -47,27 +47,27 @@ public void setUp() throws Exception { } @Test - public void bibentryExpansionTest() { + void bibentryExpansionTest() { BracketedPattern pattern = new BracketedPattern("[year]_[auth]_[firstpage]"); assertEquals("2017_Kitsune_213", pattern.expand(bibentry)); } @Test - public void nullDatabaseExpansionTest() { + void nullDatabaseExpansionTest() { BibDatabase another_database = null; BracketedPattern pattern = new BracketedPattern("[year]_[auth]_[firstpage]"); assertEquals("2017_Kitsune_213", pattern.expand(bibentry, another_database)); } @Test - public void pureauthReturnsAuthorIfEditorIsAbsent() { + void pureauthReturnsAuthorIfEditorIsAbsent() { BibDatabase emptyDatabase = new BibDatabase(); BracketedPattern pattern = new BracketedPattern("[pureauth]"); assertEquals("Kitsune", pattern.expand(bibentry, emptyDatabase)); } @Test - public void pureauthReturnsAuthorIfEditorIsPresent() { + void pureauthReturnsAuthorIfEditorIsPresent() { BibDatabase emptyDatabase = new BibDatabase(); BracketedPattern pattern = new BracketedPattern("[pureauth]"); bibentry.setField(StandardField.EDITOR, "Editorlastname, Editorfirstname"); @@ -75,7 +75,7 @@ public void pureauthReturnsAuthorIfEditorIsPresent() { } @Test - public void pureauthReturnsEmptyStringIfAuthorIsAbsent() { + void pureauthReturnsEmptyStringIfAuthorIsAbsent() { BibDatabase emptyDatabase = new BibDatabase(); BracketedPattern pattern = new BracketedPattern("[pureauth]"); bibentry.clearField(StandardField.AUTHOR); @@ -83,7 +83,7 @@ public void pureauthReturnsEmptyStringIfAuthorIsAbsent() { } @Test - public void pureauthReturnsEmptyStringIfAuthorIsAbsentAndEditorIsPresent() { + void pureauthReturnsEmptyStringIfAuthorIsAbsentAndEditorIsPresent() { BibDatabase emptyDatabase = new BibDatabase(); BracketedPattern pattern = new BracketedPattern("[pureauth]"); bibentry.clearField(StandardField.AUTHOR); @@ -92,14 +92,14 @@ public void pureauthReturnsEmptyStringIfAuthorIsAbsentAndEditorIsPresent() { } @Test - public void emptyDatabaseExpansionTest() { + void emptyDatabaseExpansionTest() { BibDatabase another_database = new BibDatabase(); BracketedPattern pattern = new BracketedPattern("[year]_[auth]_[firstpage]"); assertEquals("2017_Kitsune_213", pattern.expand(bibentry, another_database)); } @Test - public void databaseWithStringsExpansionTest() { + void databaseWithStringsExpansionTest() { BibDatabase another_database = new BibDatabase(); BibtexString string = new BibtexString("sgr", "Saulius Gražulis"); another_database.addString(string); @@ -113,31 +113,31 @@ public void databaseWithStringsExpansionTest() { } @Test - public void unbalancedBracketsExpandToSomething() { + void unbalancedBracketsExpandToSomething() { BracketedPattern pattern = new BracketedPattern("[year]_[auth_[firstpage]"); assertNotEquals("", pattern.expand(bibentry)); } @Test - public void unbalancedLastBracketExpandsToSomething() { + void unbalancedLastBracketExpandsToSomething() { BracketedPattern pattern = new BracketedPattern("[year]_[auth]_[firstpage"); assertNotEquals("", pattern.expand(bibentry)); } @Test - public void entryTypeExpansionTest() { + void entryTypeExpansionTest() { BracketedPattern pattern = new BracketedPattern("[entrytype]:[year]_[auth]_[pages]"); assertEquals("Misc:2017_Kitsune_213--216", pattern.expand(bibentry)); } @Test - public void entryTypeExpansionLowercaseTest() { + void entryTypeExpansionLowercaseTest() { BracketedPattern pattern = new BracketedPattern("[entrytype:lower]:[year]_[auth]_[firstpage]"); assertEquals("misc:2017_Kitsune_213", pattern.expand(bibentry)); } @Test - public void suppliedBibentryBracketExpansionTest() { + void suppliedBibentryBracketExpansionTest() { BibDatabase another_database = null; BracketedPattern pattern = new BracketedPattern("[year]_[auth]_[firstpage]"); BibEntry another_bibentry = new BibEntry(); @@ -148,7 +148,7 @@ public void suppliedBibentryBracketExpansionTest() { } @Test - public void nullBibentryBracketExpansionTest() { + void nullBibentryBracketExpansionTest() { BibDatabase another_database = null; BibEntry another_bibentry = null; BracketedPattern pattern = new BracketedPattern("[year]_[auth]_[firstpage]"); @@ -156,58 +156,53 @@ public void nullBibentryBracketExpansionTest() { } @Test - public void bracketedExpressionDefaultConstructorTest() { + void bracketedExpressionDefaultConstructorTest() { BibDatabase another_database = null; BracketedPattern pattern = new BracketedPattern(); assertThrows(NullPointerException.class, () -> pattern.expand(bibentry, ';', another_database)); } @Test - public void unknownKeyExpandsToEmptyString() { - Character separator = ';'; - assertEquals("", BracketedPattern.expandBrackets("[unknownkey]", separator, dbentry, database)); + void unknownKeyExpandsToEmptyString() { + assertEquals("", BracketedPattern.expandBrackets("[unknownkey]", ';', dbentry, database)); } @Test - public void emptyPatternAndEmptyModifierExpandsToEmptyString() { - Character separator = ';'; - assertEquals("", BracketedPattern.expandBrackets("[:]", separator, dbentry, database)); + void emptyPatternAndEmptyModifierExpandsToEmptyString() { + assertEquals("", BracketedPattern.expandBrackets("[:]", ';', dbentry, database)); } @Test - public void emptyPatternAndValidModifierExpandsToEmptyString() { + void emptyPatternAndValidModifierExpandsToEmptyString() { Character separator = ';'; assertEquals("", BracketedPattern.expandBrackets("[:lower]", separator, dbentry, database)); } @Test - public void bibtexkeyPatternExpandsToBibTeXKey() { + void bibtexkeyPatternExpandsToBibTeXKey() { Character separator = ';'; assertEquals("HipKro03", BracketedPattern.expandBrackets("[bibtexkey]", separator, dbentry, database)); } @Test - public void bibtexkeyPatternWithEmptyModifierExpandsToBibTeXKey() { - Character separator = ';'; - assertEquals("HipKro03", BracketedPattern.expandBrackets("[bibtexkey:]", separator, dbentry, database)); + void bibtexkeyPatternWithEmptyModifierExpandsToBibTeXKey() { + assertEquals("HipKro03", BracketedPattern.expandBrackets("[bibtexkey:]", ';', dbentry, database)); } @Test - public void authorPatternTreatsVonNamePrefixCorrectly() { - Character separator = ';'; + void authorPatternTreatsVonNamePrefixCorrectly() { assertEquals("Eric von Hippel and Georg von Krogh", - BracketedPattern.expandBrackets("[author]", separator, dbentry, database)); + BracketedPattern.expandBrackets("[author]", ';', dbentry, database)); } @Test - public void lowerFormatterWorksOnVonNamePrefixes() { - Character separator = ';'; + void lowerFormatterWorksOnVonNamePrefixes() { assertEquals("eric von hippel and georg von krogh", - BracketedPattern.expandBrackets("[author:lower]", separator, dbentry, database)); + BracketedPattern.expandBrackets("[author:lower]", ';', dbentry, database)); } @Test - public void testResolvedFieldAndFormat() { + void testResolvedFieldAndFormat() { BibEntry child = new BibEntry(); child.setField(StandardField.CROSSREF, "HipKro03"); database.insertEntry(child); @@ -232,7 +227,7 @@ public void testResolvedFieldAndFormat() { } @Test - public void testResolvedParentNotInDatabase() { + void testResolvedParentNotInDatabase() { BibEntry child = new BibEntry(); child.setField(StandardField.CROSSREF, "HipKro03"); database.removeEntry(dbentry); @@ -240,4 +235,10 @@ public void testResolvedParentNotInDatabase() { assertEquals("", BracketedPattern.expandBrackets("[author]", ';', child, database)); } + + @Test + void regularExpressionReplace() { + assertEquals("2003-JabRef Science", + BracketedPattern.expandBrackets("[year]-[journal:regex(\"Organization\",\"JabRef\")]", ';', dbentry, database)); + } }