Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We improved the event viewer for debugging [#13783](https://github.com/JabRef/jabref/pull/13783).
- We improved "REDACTED" replacement of API key value in web fetcher search URL [#13796](https://github.com/JabRef/jabref/issues/13796)
- When the pin "Keep dialog always on top" in the global search dialog is selected, the search window stays open when double-clicking on an entry. [#13840](https://github.com/JabRef/jabref/issues/13840)
- We improved the UI of regex replacement in the citation key generator tab. [#13939](https://github.com/JabRef/jabref/pull/13939)
- We improved the way we check for matching curly braces in BibTeX fields and made error messages easier to understand. [#12605](https://github.com/JabRef/jabref/issues/12605)

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ public enum StandardActions implements Action {

HELP(Localization.lang("Online help"), IconTheme.JabRefIcons.HELP, KeyBinding.HELP),
HELP_GROUPS(Localization.lang("Open Help page"), IconTheme.JabRefIcons.HELP, KeyBinding.HELP),
HELP_KEY_PATTERNS(Localization.lang("Help on key patterns"), IconTheme.JabRefIcons.HELP, KeyBinding.HELP),
HELP_REGEX_SEARCH(Localization.lang("Help on regular expression search"), IconTheme.JabRefIcons.HELP, KeyBinding.HELP),
HELP_NAME_FORMATTER(Localization.lang("Help on Name Formatting"), IconTheme.JabRefIcons.HELP, KeyBinding.HELP),
HELP_SPECIAL_FIELDS(Localization.lang("Help on special fields"), IconTheme.JabRefIcons.HELP, KeyBinding.HELP),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package org.jabref.gui.libraryproperties.keypattern;

import javafx.fxml.FXML;
import javafx.scene.control.Button;

import org.jabref.gui.actions.ActionFactory;
import org.jabref.gui.actions.StandardActions;
import org.jabref.gui.commonfxcontrols.CitationKeyPatternsPanel;
import org.jabref.gui.help.HelpAction;
import org.jabref.gui.libraryproperties.AbstractPropertiesTabView;
import org.jabref.gui.libraryproperties.PropertiesTab;
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.logic.help.HelpFile;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntryTypesManager;
Expand All @@ -20,7 +15,6 @@

public class KeyPatternPropertiesView extends AbstractPropertiesTabView<KeyPatternPropertiesViewModel> implements PropertiesTab {

@FXML private Button keyPatternHelp;
@FXML private CitationKeyPatternsPanel bibtexKeyPatternTable;

@Inject private GuiPreferences preferences;
Expand All @@ -44,9 +38,6 @@ public void initialize() {

bibtexKeyPatternTable.patternListProperty().bindBidirectional(viewModel.patternListProperty());
bibtexKeyPatternTable.defaultKeyPatternProperty().bindBidirectional(viewModel.defaultKeyPatternProperty());

ActionFactory actionFactory = new ActionFactory();
actionFactory.configureIconButton(StandardActions.HELP_KEY_PATTERNS, new HelpAction(HelpFile.CITATION_KEY_PATTERN, dialogService, preferences.getExternalApplicationsPreferences()), keyPatternHelp);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package org.jabref.gui.preferences.citationkeypattern;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;

import org.jabref.gui.actions.ActionFactory;
import org.jabref.gui.actions.StandardActions;
import org.jabref.gui.commonfxcontrols.CitationKeyPatternsPanel;
import org.jabref.gui.help.HelpAction;
import org.jabref.gui.preferences.AbstractPreferenceTabView;
import org.jabref.gui.preferences.PreferencesTab;
import org.jabref.logic.help.HelpFile;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntryTypesManager;

Expand All @@ -31,7 +26,6 @@ public class CitationKeyPatternTab extends AbstractPreferenceTabView<CitationKey
@FXML private TextField keyPatternRegex;
@FXML private TextField keyPatternReplacement;
@FXML private TextField unwantedCharacters;
@FXML private Button keyPatternHelp;
@FXML private CitationKeyPatternsPanel bibtexKeyPatternTable;

public CitationKeyPatternTab() {
Expand Down Expand Up @@ -61,9 +55,6 @@ public void initialize() {

bibtexKeyPatternTable.patternListProperty().bindBidirectional(viewModel.patternListProperty());
bibtexKeyPatternTable.defaultKeyPatternProperty().bindBidirectional(viewModel.defaultKeyPatternProperty());

ActionFactory actionFactory = new ActionFactory();
actionFactory.configureIconButton(StandardActions.HELP_KEY_PATTERNS, new HelpAction(HelpFile.CITATION_KEY_PATTERN, dialogService, preferences.getExternalApplicationsPreferences()), keyPatternHelp);
}

@Override
Expand Down
56 changes: 46 additions & 10 deletions jabgui/src/main/java/org/jabref/gui/util/component/HelpButton.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jabref.gui.util.component;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.Button;

import org.jabref.gui.DialogService;
Expand All @@ -8,34 +10,68 @@
import org.jabref.gui.help.HelpAction;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.gui.util.BindingsHelper;
import org.jabref.logic.help.HelpFile;

import com.airhacks.afterburner.injection.Injector;
import org.jspecify.annotations.NonNull;

public class HelpButton extends Button {
private final StringProperty helpUrl = new SimpleStringProperty("");
private boolean isHelpFileSet = false;

public HelpButton() {
setGraphic(IconTheme.JabRefIcons.HELP.getGraphicNode());
getStyleClass().add("icon-button");
setPrefSize(28, 28);
setMinSize(28, 28);
BindingsHelper.subscribeFuture(helpUrl, (url) -> {
if (url == null || url.isBlank()) {
throw new IllegalArgumentException("Help URL must be non-null and non-blank");
}
if (isHelpFileSet) {
throw new IllegalStateException("Help file has already been set");
}

setOnAction(_ -> new OpenBrowserAction(
helpUrl.get(),
Injector.instantiateModelOrService(DialogService.class),
Injector.instantiateModelOrService(GuiPreferences.class).getExternalApplicationsPreferences()
).execute());
});
}

public HelpButton(@NonNull String url) {
this();
setHelpPage(url);
setHelpUrl(url);
}

public void setHelpPage(@NonNull String helpDocumentationUrl) {
setOnAction(
_ -> new OpenBrowserAction(helpDocumentationUrl,
Injector.instantiateModelOrService(DialogService.class),
Injector.instantiateModelOrService(GuiPreferences.class).getExternalApplicationsPreferences()
).execute()
);
public void setHelpFile(@NonNull HelpFile helpFile,
@NonNull DialogService dialogService,
@NonNull ExternalApplicationsPreferences externalApplicationsPreferences) {
if (isHelpFileSet) {
throw new IllegalStateException("Help file has already been set");
}
isHelpFileSet = true;
if (!helpUrl.get().isBlank()) {
throw new IllegalArgumentException("You cannot set both a help URL and a help file");
}
setOnAction(_ -> new HelpAction(helpFile, dialogService, externalApplicationsPreferences).execute());
}

public void setHelpFile(@NonNull HelpFile helpFile, @NonNull DialogService dialogService, @NonNull ExternalApplicationsPreferences externalApplicationsPreferences) {
setOnAction(_ -> new HelpAction(helpFile, dialogService, externalApplicationsPreferences).execute());
/// This method is not used by JabRef, but provided for FXML usage.
public StringProperty helpUrlProperty() {
return helpUrl;
}

/// This method is not used by JabRef, but provided for FXML usage.
public String getHelpUrl() {
return helpUrl.get();
}

/// This method is used both internally in JabRef's code base, but also
/// for FXML usage. Do not refactor this.
public void setHelpUrl(@NonNull String helpUrl) {
this.helpUrl.setValue(helpUrl);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ private void initialize() {

showCitationKeyBox.selectedProperty().bindBidirectional(viewModel.showCitationKeyProperty());

helpButton.setHelpPage(URLs.ENTRY_TABLE_COLUMNS_DOC);
helpButton.setHelpUrl(URLs.ENTRY_TABLE_COLUMNS_DOC);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ private void initialize() {
disableAutosave.selectedProperty().bindBidirectional(viewModel.disableAutosaveProperty());
disableGroupCount.selectedProperty().bindBidirectional(viewModel.disableGroupCountProperty());

helpButton.setHelpPage(URLs.PERFORMANCE_DOC);
helpButton.setHelpUrl(URLs.PERFORMANCE_DOC);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private void initialize() {
viewModel = new MainFileDirectoryDialogViewModel(preferences, dialogService);

pathField.textProperty().bindBidirectional(viewModel.pathProperty());
helpButton.setHelpPage(URLs.FILE_LINKS_DOC);
helpButton.setHelpUrl(URLs.FILE_LINKS_DOC);
}

@FXML
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ private void initialize() {

populateFetchers();

helpButton.setHelpPage(URLs.ONLINE_SERVICES_DOC);
grobidHelpButton.setHelpPage(URLs.GROBID_DOC);
fetchersHelpButton.setHelpPage(URLs.ONLINE_SERVICES_DOC);
helpButton.setHelpUrl(URLs.ONLINE_SERVICES_DOC);
grobidHelpButton.setHelpUrl(URLs.GROBID_DOC);
fetchersHelpButton.setHelpUrl(URLs.ONLINE_SERVICES_DOC);
}

private void populateFetchers() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private void initialize() {

pathField.textProperty().bindBidirectional(viewModel.pathProperty());
pathField.textProperty().addListener((_, _, newText) -> updatePathValidation(newText));
helpButton.setHelpPage(URLs.PUSH_TO_APPLICATIONS_DOC);
helpButton.setHelpUrl(URLs.PUSH_TO_APPLICATIONS_DOC);
}

private void updatePathValidation(String newText) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ private void initialize() {
selectInitialTheme();
updateCustomThemeVisibility(viewModel.getSelectedTheme() == ThemeTypes.CUSTOM);

helpButton.setHelpPage(URLs.CUSTOM_THEME_DOC);
helpButton.setHelpUrl(URLs.CUSTOM_THEME_DOC);
}

private void selectInitialTheme() {
Expand Down
9 changes: 9 additions & 0 deletions jabgui/src/main/resources/org/jabref/gui/Base.css
Original file line number Diff line number Diff line change
Expand Up @@ -1404,6 +1404,15 @@ We want to have a look that matches our icons in the tool-bar */
-fx-background-color: -fx-control-inner-background;
}

.innerGridPane {
-fx-hgap: 1em;
-fx-vgap: 1em;
}

.prefIndent {
-fx-padding: 0 0 0 1.667em;
}

.code-area .text {
-fx-fill: -fx-text-background-color;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import org.jabref.gui.commonfxcontrols.CitationKeyPatternsPanel?>
<?import org.jabref.gui.util.component.HelpButton?>
<fx:root spacing="10.0" type="VBox"
xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="org.jabref.gui.libraryproperties.keypattern.KeyPatternPropertiesView">
<HBox alignment="BOTTOM_LEFT" spacing="8.0">
<Label styleClass="sectionHeader" text="%Key patterns"/>
<Button fx:id="keyPatternHelp" styleClass="icon-button,narrow" />
<HelpButton helpUrl="https://docs.jabref.org/setup/citationkeypatterns"/>
</HBox>
<Label text="%( Note: Press return to commit changes in the table! )"/>
<AnchorPane VBox.vgrow="ALWAYS">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import org.jabref.gui.commonfxcontrols.CitationKeyPatternsPanel?>
<?import org.jabref.gui.util.component.HelpButton?>
<fx:root spacing="10.0" type="VBox"
xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="org.jabref.gui.preferences.citationkeypattern.CitationKeyPatternTab">
Expand All @@ -19,49 +21,73 @@
</fx:define>
<Label styleClass="titleHeader" text="%Citation key patterns"/>

<Label styleClass="sectionHeader" text="%General"/>
<CheckBox fx:id="overwriteAllow" text="%Overwrite existing keys"/>
<CheckBox fx:id="overwriteWarning" text="%Warn before overwriting existing keys" disable="${!overwriteAllow.selected}">
<padding>
<Insets left="20.0"/>
</padding>
</CheckBox>
<CheckBox fx:id="generateOnSave" text="%Generate keys before saving (for entries without a key)"/>
<CheckBox fx:id="generateNewKeyOnImport" text="%Generate a new key for imported entries (overwriting their default)"/>
<GridPane styleClass="innerGridPane">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" percentWidth="30.0"/>
<ColumnConstraints hgrow="SOMETIMES"/>
<ColumnConstraints hgrow="NEVER"/>
</columnConstraints>

<Label text="%Letters after duplicate generated keys"/>
<VBox spacing="10.0">
<RadioButton fx:id="letterStartA" text="%Start on second duplicate key with letter A (a, b, ...)" toggleGroup="$uniqueKeyLetters"/>
<RadioButton fx:id="letterStartB" text="%Start on second duplicate key with letter B (b, c, ...)" toggleGroup="$uniqueKeyLetters"/>
<RadioButton fx:id="letterAlwaysAdd" text="%Always add letter (a, b, ...) to generated keys" toggleGroup="$uniqueKeyLetters"/>
<padding>
<Insets left="20.0"/>
</padding>
</VBox>
<Label styleClass="sectionHeader" text="%General"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="0"/>

<Label text="%Replace (regular expression)"/>
<HBox spacing="4.0" alignment="CENTER">
<TextField fx:id="keyPatternRegex" HBox.hgrow="ALWAYS"/>
<Label text="%by"/>
<TextField fx:id="keyPatternReplacement" HBox.hgrow="ALWAYS"/>
<padding>
<Insets left="20.0"/>
</padding>
</HBox>
<CheckBox fx:id="overwriteAllow" text="%Overwrite existing keys"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="1"/>
<HBox styleClass="prefIndent"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="2">
<CheckBox fx:id="overwriteWarning"
text="%Warn before overwriting existing keys"
disable="${!overwriteAllow.selected}"/>
</HBox>
<CheckBox fx:id="generateOnSave" text="%Generate keys before saving (for entries without a key)"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="3"/>
<CheckBox fx:id="generateNewKeyOnImport" text="%Generate a new key for imported entries (overwriting their default)"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="4"/>

<HBox alignment="CENTER_LEFT" spacing="10.0">
<Label text="%Remove the following characters:"/>
<TextField fx:id="unwantedCharacters" HBox.hgrow="ALWAYS"/>
</HBox>
<Label text="%Letters after duplicate generated keys" GridPane.columnIndex="0"
GridPane.columnSpan="3" GridPane.rowIndex="5"/>
<VBox spacing="10.0" styleClass="prefIndent"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="6">
<RadioButton fx:id="letterStartA"
text="%Start on second duplicate key with letter A (a, b, ...)"
toggleGroup="$uniqueKeyLetters"/>
<RadioButton fx:id="letterStartB"
text="%Start on second duplicate key with letter B (b, c, ...)"
toggleGroup="$uniqueKeyLetters"/>
<RadioButton fx:id="letterAlwaysAdd"
text="%Always add letter (a, b, ...) to generated keys"
toggleGroup="$uniqueKeyLetters"/>
</VBox>

<Label text="%Replace (regular expression)"
GridPane.columnIndex="0" GridPane.rowIndex="7"/>
<HBox spacing="4.0" alignment="CENTER_LEFT"
GridPane.columnIndex="1" GridPane.rowIndex="7">
<TextField fx:id="keyPatternRegex" HBox.hgrow="ALWAYS"/>
<Label text="%by"/>
<TextField fx:id="keyPatternReplacement" HBox.hgrow="ALWAYS"/>
</HBox>
<HelpButton helpUrl="https://docs.jabref.org/setup/citationkeypatterns#replace-via-regular-expression"
GridPane.columnIndex="2" GridPane.rowIndex="7"/>

<HBox>
<Label text="%Remove the following characters:"
GridPane.columnIndex="0" GridPane.rowIndex="8"/>
<TextField fx:id="unwantedCharacters"
GridPane.columnIndex="1" GridPane.rowIndex="8"/>
</GridPane>

<HBox spacing="8.0">
<Label styleClass="sectionHeader" text="%Key patterns"/>
<HBox HBox.hgrow="ALWAYS"/>
<Button fx:id="keyPatternHelp" prefWidth="20.0"/>
<VBox alignment="BOTTOM_CENTER">
<HelpButton helpUrl="https://docs.jabref.org/setup/citationkeypatterns" styleClass="headerHelpButton"/>
</VBox>
</HBox>

<Label text="%( Note: Press return to commit changes in the table! )"/>
<AnchorPane>
<CitationKeyPatternsPanel fx:id="bibtexKeyPatternTable" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" prefHeight="180.0"/>
<Button text="%Reset All" onAction="#resetAllKeyPatterns" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
<CitationKeyPatternsPanel fx:id="bibtexKeyPatternTable"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" prefHeight="180.0"/>
<Button text="%Reset All" onAction="#resetAllKeyPatterns"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
</AnchorPane>
</fx:root>
Loading