Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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 @@ -56,6 +56,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,12 @@
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Tooltip;

import org.jabref.gui.AbstractViewModel;
import org.jabref.gui.DialogService;
Expand All @@ -37,6 +45,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 @@ -263,25 +272,59 @@ public void renameFileToName(String targetFileName) {
}
}

private void performRenameWithConflictCheck(String targetFileName) {
public 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.OTHER);
Copy link
Member

Choose a reason for hiding this comment

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

should be cancel close for button data


// 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