diff --git a/.github/workflows/deployment-jdk-ea.yml b/.github/workflows/deployment-jdk-ea.yml index 969791c88c8..6f72a96b42e 100644 --- a/.github/workflows/deployment-jdk-ea.yml +++ b/.github/workflows/deployment-jdk-ea.yml @@ -31,32 +31,26 @@ concurrency: cancel-in-progress: true jobs: - setup-matrix: - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.javafx_versions.outputs.matrix }} - steps: - - id: javafx_versions - run: | - curl -s "https://search.maven.org/solrsearch/select?q=g:org.openjfx+AND+a:javafx&rows=10&core=gav" > /tmp/versions.json - jq '[.response.docs[] | select(.v | test(".*-ea\\+.*")) | select(.v | test("^17|^18|^19|^20|^21|^22") | not) | {version: .v}] | group_by(.version | capture("^(?\\d+).*").major) | map(max_by(.version))' < /tmp/versions.json > /tmp/versions-latest.json - versions_json=$(jq -r '[.[].version]' /tmp/versions-latest.json | jq -r tostring) - include_json=$(jq -n '[ - {"os": "ubuntu-latest", "displayName": "linux", "archivePortable": "tar -c -C build/distribution JabRef | pigz --rsyncable > build/distribution/JabRef-portable_linux.tar.gz && rm -R build/distribution/JabRef"}, - {"os": "buildjet-4vcpu-ubuntu-2204-arm", "displayName": "linux-arm", "archivePortable": "tar -c -C build/distribution JabRef | pigz --rsyncable > build/distribution/JabRef-portable_linux-arm64.tar.gz && rm -R build/distribution/JabRef"}, - {"os": "windows-latest", "displayName": "windows", "archivePortable": "7z a -r build/distribution/JabRef-portable_windows.zip ./build/distribution/JabRef && rm -R build/distribution/JabRef"}, - {"os": "macos-latest", "displayName": "macOS", "archivePortable": "brew install pigz && tar -c -C build/distribution JabRef.app | pigz --rsyncable > build/distribution/JabRef-portable_macos.tar.gz && rm -R build/distribution/JabRef.app"} - ]') - matrix=$(jq -n \ - --argjson versionsContent "$versions_json" \ - --argjson includeContent "$include_json" \ - '{"os": ["ubuntu-latest", "windows-latest", "macos-latest", "buildjet-4vcpu-ubuntu-2204-arm"], "jdk": [23], "javafx": $versionsContent, "include": $includeContent}') - echo matrix=$matrix >> $GITHUB_OUTPUT build: - needs: setup-matrix strategy: fail-fast: false - matrix: ${{fromJson(needs.setup-matrix.outputs.matrix)}} + matrix: + os: [ubuntu-latest, windows-latest, macos-latest, buildjet-4vcpu-ubuntu-2204-arm] + jdk: [22] + javafx: [23] + include: + - os: ubuntu-latest + displayName: linux + archivePortable: tar -c -C build/distribution JabRef | pigz --rsyncable > build/distribution/JabRef-portable_linux.tar.gz && rm -R build/distribution/JabRef + - os: windows-latest + displayName: windows + archivePortable: 7z a -r build/distribution/JabRef-portable_windows.zip ./build/distribution/JabRef && rm -R build/distribution/JabRef + - os: buildjet-4vcpu-ubuntu-2204-arm + displayName: "linux-arm" + archivePortable: "tar -c -C build/distribution JabRef | pigz --rsyncable > build/distribution/JabRef-portable_linux-arm64.tar.gz && rm -R build/distribution/JabRef" + - os: macos-latest + displayName: macOS + archivePortable: "brew install pigz && tar -c -C build/distribution JabRef.app | pigz --rsyncable > build/distribution/JabRef-portable_macos.tar.gz && rm -R build/distribution/JabRef.app" runs-on: ${{ matrix.os }} outputs: major: ${{ steps.gitversion.outputs.Major }} @@ -81,6 +75,46 @@ jobs: fetch-depth: 0 submodules: 'true' show-progress: 'false' + - name: Download and extract JavaFX ${{ matrix.javafx }} + if: (matrix.os != 'buildjet-4vcpu-ubuntu-2204-arm') + shell: bash + run: | + cd javafx + curl --no-progress-meter https://jdk.java.net/javafx${{ matrix.javafx }}/ > javafx.html + + case "${{ matrix.os }}" in + "ubuntu-latest") + OS="linux" + EXTRACT="tar xzf *.tar.gz" + EXT="tar.gz" + ;; + "buildjet-4vcpu-ubuntu-2204-arm") + OS="linux" + EXTRACT="tar xzf *.tar.gz" + EXT="tar.gz" + echo "There are no ARM EA builds" + exit 0 + ;; + "windows-latest") + OS="windows" + EXTRACT="unzip -qq *.zip" + EXT="zip" + ;; + "macos-latest") + OS="macos" + EXTRACT="tar xzf *.tar.gz" + EXT="tar.gz" + ;; + *) + echo "Unsupported OS" + exit 1 + ;; + esac + echo "OS set to $OS" + URL=$(grep -o "https://download.java.net/java/.*/javafx.*${OS}-x64_bin-sdk.${EXT}" javafx.html | head -n 1) + echo "Downloading $URL..." + curl -OJ --no-progress-meter $URL + $EXTRACT - name: Install pigz and cache (linux) if: (matrix.os == 'ubuntu-latest') || (matrix.os == 'buildjet-4vcpu-ubuntu-2204-arm') uses: awalsh128/cache-apt-pkgs-action@master @@ -95,11 +129,10 @@ jobs: id: gitversion uses: gittools/actions/gitversion/execute@v1.1.1 - name: 'Set up JDK ${{ matrix.jdk }}' - uses: oracle-actions/setup-java@v1.3.3 + uses: actions/setup-java@v4 with: - website: jdk.java.net - release: ${{ matrix.jdk }} - version: latest + java-version: ${{ matrix.jdk }} + distribution: 'temurin' - name: 'Set JDK${{ matrix.jdk }} env var' shell: bash run: echo "JDK${{ matrix.jdk }}=$JAVA_HOME" >> $GITHUB_ENV @@ -115,17 +148,26 @@ jobs: run: | sed -i'.bak' 's/JavaLanguageVersion.of(.*)/JavaLanguageVersion.of(${{ matrix.jdk }})/' build.gradle sed -i'.bak' 's/JavaVersion.VERSION_(.*)/JavaVersion.VERSION_(${{ matrix.jdk }})/' build.gradle - - name: 'Set JavaFX (linux, Windows)' - if: (matrix.os != 'macos-latest') - run: sed -i '/javafx {/{n;s/version = ".*"/version = "${{ matrix.javafx }}"/}' build.gradle - - name: 'Set JavaFX (macOS)' - if: (matrix.os == 'macos-latest') - run: sed -i '.bak' -e '/javafx {/{n' -e 's/version = ".*"/version = "${{ matrix.javafx }}"/;}' build.gradle + - name: 'Set JavaFX ${{ matrix.javafx }} (linux, Windows)' + if: (matrix.os != 'macos-latest') && (matrix.os != 'buildjet-4vcpu-ubuntu-2204-arm') + run: sed -i '/javafx {/{n;s#version = ".*"#sdk = "javafx/javafx-sdk-${{ matrix.javafx }}"#}' build.gradle + - name: 'Set JavaFX ${{ matrix.javafx }} (linux-arm)' + if: (matrix.os == 'buildjet-4vcpu-ubuntu-2204-arm') + # No JavaFX EA build for ARM at https://jdk.java.net/javafx23/, therefore using Maven Central artifact + run: | + curl -s "https://search.maven.org/solrsearch/select?q=g:org.openjfx+AND+a:javafx&rows=10&core=gav" > /tmp/versions.json + jq '[.response.docs[] | select(.v | test(".*-ea\\+.*")) | select(.v | test("^17|^18|^19|^20|^21|^22") | not) | {version: .v}] | group_by(.version | capture("^(?\\d+).*").major) | map(max_by(.version))' < /tmp/versions.json > /tmp/versions-latest.json + JAVAFX=$(jq -r '.[-1].version' /tmp/versions-latest.json) + echo "Using JavaFX ${JAVAFX}" + sed -i "/javafx {/{n;s#version = \".*\"#version = \"${JAVAFX}\"#}" build.gradle && cat build.gradle + - name: 'Set JavaFX ${{ matrix.javafx }} (macOS)' + if: (matrix.os == 'macos-latest') && (matrix.os != 'buildjet-4vcpu-ubuntu-2204-arm') + run: sed -i '.bak' -e '/javafx {/{n' -e 's#version = ".*"#sdk = "javafx/javafx-sdk-${{ matrix.javafx }}"#;}' build.gradle - name: Setup JDK uses: actions/setup-java@v4 with: - java-version: 21.0.2 - distribution: 'liberica' + java-version: 21 + distribution: 'temurin' - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 - name: Prepare merged jars and modules dir @@ -192,7 +234,7 @@ jobs: # We do not use egor-tensin/setup-cygwin@v4, because it replaces the default shell run: choco install --no-progress rsync - name: Setup SSH key - if: ${{ (steps.checksecrets.outputs.secretspresent == 'YES') && (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && ((matrix.os != 'macos-latest') || !((startsWith(github.ref, 'refs/tags/') || (inputs.notarization == true)))) }} + if: (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main') run: | echo "${{ secrets.buildJabRefPrivateKey }}" > sshkey chmod 600 sshkey @@ -214,28 +256,3 @@ jobs: name: JabRef-${{ matrix.os }} path: build/distribution compression-level: 0 # no compression - announce: - name: Comment on pull request - runs-on: ubuntu-latest - needs: [build] - if: ${{ github.event_name == 'pull_request' }} - steps: - - name: Check secrets presence - id: checksecrets - shell: bash - run: | - if [ "$BUILDJABREFPRIVATEKEY" == "" ]; then - echo "secretspresent=NO" >> $GITHUB_OUTPUT - else - echo "secretspresent=YES" >> $GITHUB_OUTPUT - fi - env: - BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }} - - name: Comment PR - if: (steps.checksecrets.outputs.secretspresent == 'YES') - uses: thollander/actions-comment-pull-request@v2 - with: - message: | - The build of this PR is available at . - comment_tag: download-link - mode: recreate diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1016762e4aa..2cb29ebf9c3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -100,7 +100,7 @@ jobs: submodules: 'false' show-progress: 'false' - name: markdownlint-cli2-action - uses: DavidAnson/markdownlint-cli2-action@v15 + uses: DavidAnson/markdownlint-cli2-action@v16 with: globs: | *.md diff --git a/.gitignore b/.gitignore index 28c62cbe9f0..ce4ac4f2c73 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,11 @@ src-gen/ .lycheecache +javafx/javafx-sdk-* +javafx/javafx.html +javafx/*.tar.gz +javafx/*.zip + # generated by https://plugins.jetbrains.com/plugin/15991-plantuml-diagram-generator *.puml diff --git a/CHANGELOG.md b/CHANGELOG.md index e8c6d31f61a..594eb8b6a22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - We added support for offline extracting refereferences from PDFs following the IEEE format. [#11156](https://github.com/JabRef/jabref/pull/11156) - We added a new keyboard shortcut ctrl + , to open the preferences. [#11154](https://github.com/JabRef/jabref/pull/11154) +- We added value selection (such as for month) for content selectors in custom entry types. [#11109](https://github.com/JabRef/jabref/issues/11109) - We added an exporter for Endnote XML format. [#11137](https://github.com/JabRef/jabref/issues/11137) ### Changed diff --git a/build.gradle b/build.gradle index 754af034fd6..1005627eac7 100644 --- a/build.gradle +++ b/build.gradle @@ -185,9 +185,10 @@ dependencies { implementation('com.tobiasdiez:easybind:2.2.1-SNAPSHOT') implementation 'org.fxmisc.flowless:flowless:0.7.2' implementation 'org.fxmisc.richtext:richtextfx:0.11.2' - implementation (group: 'com.dlsc.gemsfx', name: 'gemsfx', version: '2.7.2') { + implementation (group: 'com.dlsc.gemsfx', name: 'gemsfx', version: '2.7.4') { exclude module: 'javax.inject' // Split package, use only jakarta.inject exclude module: 'commons-lang3' + exclude group: 'org.openjfx' exclude group: 'org.apache.logging.log4j' } @@ -233,17 +234,17 @@ dependencies { // API implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' // Implementation of the API - implementation 'org.glassfish.jersey.core:jersey-server:3.1.5' + implementation 'org.glassfish.jersey.core:jersey-server:3.1.6' // injection framework - implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.5' + implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.6' implementation 'org.glassfish.hk2:hk2-api:3.1.0' // testImplementation 'org.glassfish.hk2:hk2-testing:3.0.4' // implementation 'org.glassfish.hk2:hk2-testing-jersey:3.0.4' // testImplementation 'org.glassfish.hk2:hk2-junitrunner:3.0.4' // HTTP server // implementation 'org.glassfish.jersey.containers:jersey-container-netty-http:3.1.1' - implementation 'org.glassfish.jersey.containers:jersey-container-grizzly2-http:3.1.5' - testImplementation 'org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:3.1.5' + implementation 'org.glassfish.jersey.containers:jersey-container-grizzly2-http:3.1.6' + testImplementation 'org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:3.1.6' // Allow objects "magically" to be mapped to JSON using GSON // implementation 'org.glassfish.jersey.media:jersey-media-json-gson:3.1.1' diff --git a/src/main/java/org/jabref/gui/fieldeditors/CustomFieldEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/CustomFieldEditorViewModel.java new file mode 100644 index 00000000000..d51d99568e8 --- /dev/null +++ b/src/main/java/org/jabref/gui/fieldeditors/CustomFieldEditorViewModel.java @@ -0,0 +1,39 @@ +package org.jabref.gui.fieldeditors; + +import java.util.List; + +import javax.swing.undo.UndoManager; + +import org.jabref.gui.autocompleter.SuggestionProvider; +import org.jabref.logic.integrity.FieldCheckers; +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.field.Field; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; + +public class CustomFieldEditorViewModel extends MapBasedEditorViewModel { + + private BiMap itemMap; + + public CustomFieldEditorViewModel(Field field, SuggestionProvider suggestionProvider, + FieldCheckers fieldCheckers, UndoManager undoManager, BibDatabaseContext databaseContext) { + super(field, suggestionProvider, fieldCheckers, undoManager); + + List values = databaseContext.getMetaData().getContentSelectorValuesForField(field); + itemMap = HashBiMap.create(values.size()); + for (String value : values) { + itemMap.put(value, value); + } + } + + @Override + protected BiMap getItemMap() { + return itemMap; + } + + @Override + public String convertToDisplayText(String object) { + return object; + } +} diff --git a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java index bbdefc05f1c..c86b5fc4a67 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java +++ b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java @@ -98,6 +98,8 @@ public static FieldEditorFX getForField(final Field field, return new CitationKeyEditor(field, suggestionProvider, fieldCheckers, databaseContext); } else if (fieldProperties.contains(FieldProperty.MARKDOWN)) { return new MarkdownEditor(field, suggestionProvider, fieldCheckers, preferences, undoManager); + } else if (fieldProperties.contains(FieldProperty.CUSTOM_FIELD) && !isMultiLine) { + return new OptionEditor<>(new CustomFieldEditorViewModel(field, suggestionProvider, fieldCheckers, undoManager, databaseContext)); } else { // default return new SimpleEditor(field, suggestionProvider, fieldCheckers, preferences, isMultiLine, undoManager); diff --git a/src/main/java/org/jabref/model/entry/field/FieldProperty.java b/src/main/java/org/jabref/model/entry/field/FieldProperty.java index 28030da53ec..bf9bc58dd6d 100644 --- a/src/main/java/org/jabref/model/entry/field/FieldProperty.java +++ b/src/main/java/org/jabref/model/entry/field/FieldProperty.java @@ -26,5 +26,6 @@ public enum FieldProperty { TYPE, VERBATIM, YES_NO, - COMMENT + COMMENT, + CUSTOM_FIELD } diff --git a/src/main/java/org/jabref/model/entry/field/UnknownField.java b/src/main/java/org/jabref/model/entry/field/UnknownField.java index 5e4ff7bc39d..3fee64991c1 100644 --- a/src/main/java/org/jabref/model/entry/field/UnknownField.java +++ b/src/main/java/org/jabref/model/entry/field/UnknownField.java @@ -32,7 +32,7 @@ public UnknownField(String name, String displayName, FieldProperty first, FieldP } public static UnknownField fromDisplayName(String displayName) { - return new UnknownField(displayName.toLowerCase(Locale.ROOT), displayName); + return new UnknownField(displayName.toLowerCase(Locale.ROOT), displayName, FieldProperty.CUSTOM_FIELD); } @Override diff --git a/src/test/java/org/jabref/gui/theme/ThemeManagerTest.java b/src/test/java/org/jabref/gui/theme/ThemeManagerTest.java index 87e1d1a654c..6dc7acfc99c 100644 --- a/src/test/java/org/jabref/gui/theme/ThemeManagerTest.java +++ b/src/test/java/org/jabref/gui/theme/ThemeManagerTest.java @@ -16,6 +16,7 @@ import org.jabref.gui.util.DefaultFileUpdateMonitor; import org.jabref.model.util.DummyFileUpdateMonitor; import org.jabref.preferences.WorkspacePreferences; +import org.jabref.support.DisabledOnCIServer; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -157,6 +158,7 @@ public void largeCustomThemeNotHeldInMemory() throws IOException { } @Test + @DisabledOnCIServer("Randomly fails on CI server") public void installThemeOnScene() throws IOException { Scene scene = mock(Scene.class); when(scene.getStylesheets()).thenReturn(FXCollections.observableArrayList());