Skip to content

Commit

Permalink
Add confirmation dialog for empty entries in JabRef (#8218)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruoyu-qian authored Nov 13, 2021
1 parent 5e88576 commit c593f35
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve

### Added

- We added confirmation dialog when user wants to close a library where any empty entires are detected. [#8096](https://github.com/JabRef/jabref/issues/8096)
- We added import support for CFF files. [#7945](https://github.com/JabRef/jabref/issues/7945)
- We added the option to copy the DOI of an entry directly from the context menu copy submenu. [#7826](https://github.com/JabRef/jabref/issues/7826)
- We added a fulltext search feature. [#2838](https://github.com/JabRef/jabref/pull/2838)
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/org/jabref/gui/JabRefFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
import org.jabref.logic.undo.UndoRedoEvent;
import org.jabref.logic.util.OS;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.SpecialField;
import org.jabref.model.entry.types.StandardEntryType;
import org.jabref.preferences.PreferencesService;
Expand Down Expand Up @@ -398,6 +399,12 @@ public boolean quit() {
LibraryTab libraryTab = getLibraryTabAt(i);
final BibDatabaseContext context = libraryTab.getBibDatabaseContext();

if (context.hasEmptyEntries()) {
if (!confirmEmptyEntry(libraryTab, context)) {
return false;
}
}

if (libraryTab.isModified() && (context.getLocation() == DatabaseLocation.LOCAL)) {
tabbedPane.getSelectionModel().select(i);
if (!confirmClose(libraryTab)) {
Expand Down Expand Up @@ -1164,13 +1171,60 @@ private boolean confirmClose(LibraryTab libraryTab) {
return response.isEmpty() || !response.get().equals(cancel);
}

/**
* Ask if the user really wants to remove any empty entries
*/
private Boolean confirmEmptyEntry(LibraryTab libraryTab, BibDatabaseContext context) {
String filename = libraryTab.getBibDatabaseContext()
.getDatabasePath()
.map(Path::toAbsolutePath)
.map(Path::toString)
.orElse(Localization.lang("untitled"));

ButtonType deleteEmptyEntries = new ButtonType(Localization.lang("Delete empty entries"), ButtonBar.ButtonData.YES);
ButtonType keepEmptyEntries = new ButtonType(Localization.lang("Keep empty entries"), ButtonBar.ButtonData.NO);
ButtonType cancel = new ButtonType(Localization.lang("Return to JabRef"), ButtonBar.ButtonData.CANCEL_CLOSE);

Optional<ButtonType> response = dialogService.showCustomButtonDialogAndWait(Alert.AlertType.CONFIRMATION,
Localization.lang("Empty entries"),
Localization.lang("Library '%0' has empty entries. Do you want to delete them?", filename),
deleteEmptyEntries, keepEmptyEntries, cancel);
if (response.isPresent() && response.get().equals(deleteEmptyEntries)) {
// The user wants to delete.
try {
for (BibEntry currentEntry : new ArrayList<BibEntry>(context.getEntries())) {
if (currentEntry.getFields().isEmpty()) {
context.getDatabase().removeEntries(Collections.singletonList(currentEntry));
}
}
SaveDatabaseAction saveAction = new SaveDatabaseAction(libraryTab, prefs, Globals.entryTypesManager);
if (saveAction.save()) {
return true;
}
// The action was either canceled or unsuccessful.
dialogService.notify(Localization.lang("Unable to save library"));
} catch (Throwable ex) {
LOGGER.error("A problem occurred when trying to delete the empty entries", ex);
dialogService.showErrorDialogAndWait(Localization.lang("Delete empty entries"), Localization.lang("Could not delete empty entries."), ex);
}
// Save was cancelled or an error occurred.
return false;
}
return !response.get().equals(cancel);
}

private void closeTab(LibraryTab libraryTab) {
// empty tab without database
if (libraryTab == null) {
return;
}

final BibDatabaseContext context = libraryTab.getBibDatabaseContext();
if (context.hasEmptyEntries()) {
if (!confirmEmptyEntry(libraryTab, context)) {
return;
}
}

if (libraryTab.isModified() && (context.getLocation() == DatabaseLocation.LOCAL)) {
if (confirmClose(libraryTab)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,14 @@ public List<BibEntry> getEntries() {
return database.getEntries();
}

/**
* check if the database has any empty entries
* @return true if the database has any empty entries; otherwise false
*/
public boolean hasEmptyEntries() {
return this.getEntries().stream().anyMatch(entry->entry.getFields().isEmpty());
}

public static Path getFulltextIndexBasePath() {
return Path.of(AppDirsFactory.getInstance().getUserDataDir(SEARCH_INDEX_BASE_PATH, SearchFieldConstants.VERSION, "org.jabref"));
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Could\ not\ delete\ empty\ entries.=Could not delete empty entries.

Delete\ empty\ entries=Delete empty entries

Empty\ entries=Empty entries

Keep\ empty\ entries=Keep empty entries

Library\ '%0'\ has\ empty\ entries.\ Do\ you\ want\ to\ delete\ them?=Library '%0' has empty entries. Do you want to delete them?

Unable\ to\ monitor\ file\ changes.\ Please\ close\ files\ and\ processes\ and\ restart.\ You\ may\ encounter\ errors\ if\ you\ continue\ with\ this\ session.=Unable to monitor file changes. Please close files and processes and restart. You may encounter errors if you continue with this session.
%0\ contains\ the\ regular\ expression\ <b>%1</b>=%0 contains the regular expression <b>%1</b>

Expand Down
20 changes: 20 additions & 0 deletions src/test/java/org/jabref/model/database/BibDatabaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.jabref.model.entry.field.UnknownField;
import org.jabref.model.entry.types.StandardEntryType;
import org.jabref.model.event.TestEventListener;
import org.jabref.model.metadata.MetaData;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -36,6 +37,25 @@ void setUp() {
database = new BibDatabase();
}

@Test
void noEmptyEntry() {
BibEntry entry = new BibEntry();
entry.setField(StandardField.AUTHOR, "#AAA#");
database.insertEntry(entry);
BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(database, new MetaData());
assertEquals(false, bibDatabaseContext.hasEmptyEntries());
}

@Test
void withEmptyEntry() {
BibEntry entry = new BibEntry();
database.insertEntry(entry);
BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(database, new MetaData());
assertEquals(true, bibDatabaseContext.hasEmptyEntries());
bibDatabaseContext.getDatabase().removeEntries(Collections.singletonList(entry));
assertEquals(Collections.emptyList(), bibDatabaseContext.getEntries());
}

@Test
void insertEntryAddsEntryToEntriesList() {
BibEntry entry = new BibEntry();
Expand Down

0 comments on commit c593f35

Please sign in to comment.