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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- When adding an entry to a library, a warning is displayed if said entry already exists in an active library. [#13261](https://github.com/JabRef/jabref/issues/13261)
- We added the field `monthfiled` to the default list of fields to resolve BibTeX-Strings for [#13375](https://github.com/JabRef/jabref/issues/13375)
- We added a new ID based fetcher for [EuropePMC](https://europepmc.org/). [#13389](https://github.com/JabRef/jabref/pull/13389)
- We added an initial [cite as you write](https://retorque.re/zotero-better-bibtex/citing/cayw/) endpoint. [#13187](https://github.com/JabRef/jabref/issues/13187)
- We added an initial [cite as you write](https://retorque.re/zotero-better-bibtex/citing/cayw/) endpoint. [#13187](https://github.com/JabRef/jabref/issues/13187)

### Changed

Expand Down Expand Up @@ -54,6 +54,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- When importing a PDF, there is no empty entry column shown in the multi merge dialog. [#13132](https://github.com/JabRef/jabref/issues/13132)
- We added a progress dialog to the "Check consistency" action and progress output to the corresponding cli command. [#12487](https://github.com/JabRef/jabref/issues/12487)
- We made the `check-consistency` command of the toolkit always return an exit code; 0 means no issues found, a non-zero exit code reflects any issues, which allows CI to fail in these cases [#13328](https://github.com/JabRef/jabref/issues/13328).
- Improved file exists warning dialog with clearer options and tooltips [#12565](https://github.com/JabRef/jabref/issues/12565)]

### Fixed

Expand Down
17 changes: 17 additions & 0 deletions jabgui/src/main/java/org/jabref/gui/DialogService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;

Expand All @@ -15,6 +16,7 @@
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogPane;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.Tooltip;
import javafx.util.StringConverter;

import org.jabref.gui.util.BaseDialog;
Expand Down Expand Up @@ -204,6 +206,21 @@ boolean showConfirmationDialogWithOptOutAndWait(String title, String content,
Optional<ButtonType> showCustomButtonDialogAndWait(Alert.AlertType type, String title, String content,
ButtonType... buttonTypes);

/**
* This will create and display a new dialog showing a custom {@link DialogPane}
* using custom {@link ButtonType}s, and attaches optional {@link Tooltip}s to the buttons.
* Useful for providing additional context to the user through tooltips
* without cluttering the main dialog content.
*
* @return Optional with the pressed Button as ButtonType
*/

Optional<ButtonType> showCustomButtonDialogWithTooltipsAndWait(Alert.AlertType type,
String title,
String content,
Map<ButtonType, String> tooltips,
ButtonType... buttonTypes);

/**
* This will create and display a new dialog showing a custom {@link DialogPane}
* and using custom {@link ButtonType}s.
Expand Down
30 changes: 30 additions & 0 deletions jabgui/src/main/java/org/jabref/gui/JabRefDialogService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;

import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.print.PrinterJob;
Expand All @@ -27,6 +29,7 @@
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
Expand Down Expand Up @@ -303,6 +306,33 @@ public Optional<ButtonType> showCustomButtonDialogAndWait(AlertType type, String
return alert.showAndWait();
}

@Override
public Optional<ButtonType> showCustomButtonDialogWithTooltipsAndWait(AlertType type,
String title,
String content,
Map<ButtonType, String> tooltips,
ButtonType... buttonTypes) {
// Use a non-editable Label instead of raw text to prevent editing
FXDialog alert = createDialog(type, title, "");
Label contentLabel = new Label(content);
contentLabel.setWrapText(true);
alert.getDialogPane().setContent(contentLabel);

alert.getDialogPane().getButtonTypes().setAll(buttonTypes);

// Attach tooltips to buttons
Platform.runLater(() -> {
for (Map.Entry<ButtonType, String> entry : tooltips.entrySet()) {
Button button = (Button) alert.getDialogPane().lookupButton(entry.getKey());
if (button != null) {
button.setTooltip(new Tooltip(entry.getValue()));
}
}
});

return alert.showAndWait();
}

@Override
public Optional<ButtonType> showCustomDialogAndWait(String title, DialogPane contentPane,
ButtonType... buttonTypes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiPredicate;

Expand All @@ -18,6 +20,9 @@
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;

import org.jabref.gui.AbstractViewModel;
import org.jabref.gui.DialogService;
Expand All @@ -37,6 +42,7 @@
import org.jabref.logic.externalfiles.LinkedFileHandler;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.util.TaskExecutor;
import org.jabref.logic.util.io.FileNameUniqueness;
import org.jabref.logic.util.io.FileUtil;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
Expand Down Expand Up @@ -264,24 +270,58 @@ public void renameFileToName(String targetFileName) {
}

private void performRenameWithConflictCheck(String targetFileName) {
// Check if a file with the same name already exists
Optional<Path> existingFile = linkedFileHandler.findExistingFile(linkedFile, entry, targetFileName);
boolean overwriteFile = false;

if (existingFile.isPresent()) {
overwriteFile = dialogService.showConfirmationDialogAndWait(
Localization.lang("File exists"),
Localization.lang("'%0' exists. Overwrite file?", targetFileName),
Localization.lang("Overwrite"));

if (!overwriteFile) {
// Get existing file path and its directory
Path existingFilePath = existingFile.get();
Path targetDirectory = existingFilePath.getParent();

// Suggest a non-conflicting file name
String suggestedFileName = FileNameUniqueness.getNonOverWritingFileName(targetDirectory, targetFileName);

// Define available dialog options
ButtonType replace = new ButtonType(Localization.lang("Replace"), ButtonBar.ButtonData.OTHER);
ButtonType keepBoth = new ButtonType(Localization.lang("Keep both"), ButtonBar.ButtonData.OTHER);
ButtonType provideAlternative = new ButtonType(Localization.lang("Provide alternative file name"), ButtonBar.ButtonData.OTHER);
ButtonType cancel = new ButtonType(Localization.lang("Cancel"), ButtonBar.ButtonData.CANCEL_CLOSE);

// Define tooltips for dialog buttons
Map<ButtonType, String> tooltips = new HashMap<>();
tooltips.put(keepBoth, Localization.lang("New filename: %0", suggestedFileName));

// Use JabRefDialogService to show a custom dialog with tooltips
Optional<ButtonType> result = dialogService.showCustomButtonDialogWithTooltipsAndWait(
Alert.AlertType.CONFIRMATION,
Localization.lang("File already exists"),
Localization.lang("File name: \n'%0'", targetFileName),
tooltips,
replace, keepBoth, provideAlternative, cancel
);

// Show dialog and handle user response
if (result.isEmpty() || result.get() == cancel) {
return; // User canceled
} else if (result.get() == replace) {
overwriteFile = true;
} else if (result.get() == keepBoth) {
targetFileName = suggestedFileName;
} else if (result.get() == provideAlternative) {
askForNameAndRename();
return;
}
}

try {
// Attempt the rename operation
linkedFileHandler.renameToName(targetFileName, overwriteFile);
} catch (IOException e) {
dialogService.showErrorDialogAndWait(Localization.lang("Rename failed"), Localization.lang("JabRef cannot access the file because it is being used by another process."));
// Display an error dialog if file is locked or inaccessible
dialogService.showErrorDialogAndWait(
Localization.lang("Rename failed"),
Localization.lang("JabRef cannot access the file because it is being used by another process."));
}
}

Expand Down
6 changes: 6 additions & 0 deletions jablib/src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ Do\ not\ abbreviate\ names=Do not abbreviate names

Do\ not\ wrap\ when\ saving=Do not wrap when saving

File\ already\ exists=File already exists
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pleae group to line 2999

(there is File '%0' already exists. Overwriting.)

File\ name\:\ \n'%0'=File name: \n'%0'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be no space before newline

Maybe you can submit a follow-up PR?

New\ filename\:\ %0=New filename: %0
Provide\ alternative\ file\ name=Provide alternative file name


Download\ file=Download file

Download\ '%0'\ was\ a\ HTML\ file.\ Removed.=Download '%0' was a HTML file. Removed.
Expand Down