Skip to content
Open
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
47 changes: 38 additions & 9 deletions jabgui/src/main/java/org/jabref/gui/LibraryTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public class LibraryTab extends Tab implements CommandSelectionTab {
private final BooleanProperty canGoBackProperty = new SimpleBooleanProperty(false);
private final BooleanProperty canGoForwardProperty = new SimpleBooleanProperty(false);
private boolean backOrForwardNavigationActionTriggered = false;
private boolean bulkImportInProgress = false;

private BibDatabaseContext bibDatabaseContext;

Expand Down Expand Up @@ -239,7 +240,9 @@ private void initializeComponentsAndListeners(boolean isDummyContext) {
undoManager,
stateManager,
dialogService,
taskExecutor);
taskExecutor,
this::startBulkImport,
this::endBulkImport);

setupMainPanel();
setupAutoCompletion();
Expand Down Expand Up @@ -825,14 +828,19 @@ public void insertEntries(final List<BibEntry> entries) {
return;
}

importHandler.importCleanedEntries(null, entries);
getUndoManager().addEdit(new UndoableInsertEntries(bibDatabaseContext.getDatabase(), entries));
markBaseChanged();
stateManager.setSelectedEntries(entries);
if (preferences.getEntryEditorPreferences().shouldOpenOnNewEntry()) {
showAndEdit(entries.getFirst());
} else {
clearAndSelect(entries.getFirst());
startBulkImport();
try {
importHandler.importCleanedEntries(null, entries);
getUndoManager().addEdit(new UndoableInsertEntries(bibDatabaseContext.getDatabase(), entries));
markBaseChanged();
stateManager.setSelectedEntries(entries);
if (preferences.getEntryEditorPreferences().shouldOpenOnNewEntry()) {
showAndEdit(entries.getFirst());
} else {
clearAndSelect(entries.getFirst());
}
} finally {
endBulkImport();
}
}

Expand Down Expand Up @@ -1025,6 +1033,11 @@ private void newEntryShowing(BibEntry entry) {
return;
}

// skip history updates if this is from a bulk import operation
if (bulkImportInProgress) {
return;
}

navigationHistory.add(entry);
updateNavigationState();
}
Expand All @@ -1038,6 +1051,22 @@ public void updateNavigationState() {
canGoForwardProperty.set(canGoForward());
}

/**
* Marks the start of a bulk import operation.
* During bulk import, selection changes will not be added to navigation history.
*/
public void startBulkImport() {
bulkImportInProgress = true;
}

/**
* Marks the end of a bulk import operation.
* Normal navigation history tracking resumes after this call.
*/
public void endBulkImport() {
bulkImportInProgress = false;
}

Comment on lines +1054 to +1069
Copy link
Member

Choose a reason for hiding this comment

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

This is hacky as hell

/**
* Creates a new library tab. Contents are loaded by the {@code dataLoadingTask}. Most of the other parameters are required by {@code resetChangeMonitor()}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ public void importEntries(List<CitationRelationItem> entriesToImport, CitationFe
undoManager,
stateManager,
dialogService,
taskExecutor);
taskExecutor,
null,
null);
CitationKeyGenerator generator = new CitationKeyGenerator(databaseContext, preferences.getCitationKeyPatternPreferences());
boolean generateNewKeyOnImport = preferences.getImporterPreferences().generateNewKeyOnImportProperty().get();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,28 @@ public class ImportHandler {
private final DialogService dialogService;
private final TaskExecutor taskExecutor;
private final FilePreferences filePreferences;
@Nullable
private final Runnable onBulkImportStart;
@Nullable
private final Runnable onBulkImportEnd;

public ImportHandler(BibDatabaseContext targetBibDatabaseContext,
GuiPreferences preferences,
FileUpdateMonitor fileupdateMonitor,
UndoManager undoManager,
StateManager stateManager,
DialogService dialogService,
TaskExecutor taskExecutor) {
TaskExecutor taskExecutor,
@Nullable Runnable onBulkImportStart,
@Nullable Runnable onBulkImportEnd) {
this.targetBibDatabaseContext = targetBibDatabaseContext;
this.preferences = preferences;
this.fileUpdateMonitor = fileupdateMonitor;
this.stateManager = stateManager;
this.dialogService = dialogService;
this.taskExecutor = taskExecutor;
this.onBulkImportStart = onBulkImportStart;
this.onBulkImportEnd = onBulkImportEnd;

this.filePreferences = preferences.getFilePreferences();

Expand Down Expand Up @@ -236,21 +244,31 @@ public void importEntries(List<BibEntry> entries) {
}

public void importCleanedEntries(@Nullable TransferInformation transferInformation, List<BibEntry> entries) {
targetBibDatabaseContext.getDatabase().insertEntries(entries);
generateKeys(entries);
setAutomaticFields(entries);
addToGroups(entries, stateManager.getSelectedGroups(targetBibDatabaseContext));
addToImportEntriesGroup(entries);

if (transferInformation != null) {
entries.stream().forEach(entry -> {
LinkedFileTransferHelper
.adjustLinkedFilesForTarget(filePreferences, transferInformation, targetBibDatabaseContext, entry);
});
boolean isBulkImport = entries.size() > 1;
if (isBulkImport && onBulkImportStart != null) {
onBulkImportStart.run();
}
try {
targetBibDatabaseContext.getDatabase().insertEntries(entries);
generateKeys(entries);
setAutomaticFields(entries);
addToGroups(entries, stateManager.getSelectedGroups(targetBibDatabaseContext));
addToImportEntriesGroup(entries);

if (transferInformation != null) {
entries.stream().forEach(entry -> {
LinkedFileTransferHelper
.adjustLinkedFilesForTarget(filePreferences, transferInformation, targetBibDatabaseContext, entry);
});
}

// TODO: Should only be done if NOT copied from other library
entries.stream().forEach(entry -> downloadLinkedFiles(entry));
// TODO: Should only be done if NOT copied from other library
entries.stream().forEach(entry -> downloadLinkedFiles(entry));
} finally {
if (isBulkImport && onBulkImportEnd != null) {
onBulkImportEnd.run();
}
}
}

public void importEntryWithDuplicateCheck(@Nullable TransferInformation transferInformation, BibEntry entry) {
Expand Down Expand Up @@ -472,21 +490,31 @@ public void importEntriesWithDuplicateCheck(@Nullable TransferInformation transf
}

public void importEntriesWithDuplicateCheck(@Nullable TransferInformation transferInformation, List<BibEntry> entriesToAdd, EntryImportHandlerTracker tracker) {
boolean firstEntry = true;
for (BibEntry entry : entriesToAdd) {
if (firstEntry) {
LOGGER.debug("First entry to import, we use BREAK (\"Ask every time\") as decision");
importEntryWithDuplicateCheck(transferInformation, entry, BREAK, tracker);
firstEntry = false;
continue;
boolean isBulkImport = entriesToAdd.size() > 1;
if (isBulkImport && onBulkImportStart != null) {
onBulkImportStart.run();
}
try {
boolean firstEntry = true;
for (BibEntry entry : entriesToAdd) {
if (firstEntry) {
LOGGER.debug("First entry to import, we use BREAK (\"Ask every time\") as decision");
importEntryWithDuplicateCheck(transferInformation, entry, BREAK, tracker);
firstEntry = false;
continue;
}
if (preferences.getMergeDialogPreferences().shouldMergeApplyToAllEntries()) {
DuplicateResolverDialog.DuplicateResolverResult decision = preferences.getMergeDialogPreferences().getAllEntriesDuplicateResolverDecision();
LOGGER.debug("Not first entry, pref flag is true, we use {}", decision);
importEntryWithDuplicateCheck(transferInformation, entry, decision, tracker);
} else {
LOGGER.debug("not first entry, not pref flag, break will be used");
importEntryWithDuplicateCheck(transferInformation, entry, BREAK, tracker);
}
}
if (preferences.getMergeDialogPreferences().shouldMergeApplyToAllEntries()) {
DuplicateResolverDialog.DuplicateResolverResult decision = preferences.getMergeDialogPreferences().getAllEntriesDuplicateResolverDecision();
LOGGER.debug("Not first entry, pref flag is true, we use {}", decision);
importEntryWithDuplicateCheck(transferInformation, entry, decision, tracker);
} else {
LOGGER.debug("not first entry, not pref flag, break will be used");
importEntryWithDuplicateCheck(transferInformation, entry, BREAK, tracker);
} finally {
if (isBulkImport && onBulkImportEnd != null) {
onBulkImportEnd.run();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ public UnlinkedFilesDialogViewModel(DialogService dialogService,
undoManager,
stateManager,
dialogService,
taskExecutor);
taskExecutor,
null,
null);

this.fileFilterList = FXCollections.observableArrayList(
new FileExtensionViewModel(StandardFileType.ANY_FILE, preferences.getExternalApplicationsPreferences()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,9 @@ private void handleOnDragDropped(TreeTableRow<GroupNodeViewModel> row, GroupNode
undoManager,
stateManager,
dialogService,
taskExecutor);
taskExecutor,
null,
null);
List<Path> files = dragboard.getFiles().stream().map(File::toPath).collect(Collectors.toList());
stateManager.setSelectedGroups(database, List.of(row.getItem().getGroupNode()));
importHandler.importFilesInBackground(files, event.getTransferMode())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ public void importEntries(List<BibEntry> entriesToImport, boolean shouldDownload
undoManager,
stateManager,
dialogService,
taskExecutor);
taskExecutor,
null,
null);
importHandler.importEntriesWithDuplicateCheck(null, entriesToImport);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,9 @@ public void executeLookupIdentifier(boolean searchComposite) {
libraryTab.getUndoManager(),
stateManager,
dialogService,
taskExecutor);
taskExecutor,
null,
null);
handler.importEntryWithDuplicateCheck(new TransferInformation(libraryTab.getBibDatabaseContext(), TransferMode.NONE), result.get());

executedSuccessfully.set(true);
Expand Down Expand Up @@ -420,7 +422,9 @@ public void executeInterpretCitations() {
libraryTab.getUndoManager(),
stateManager,
dialogService,
taskExecutor);
taskExecutor,
null,
null);
handler.importEntriesWithDuplicateCheck(null, result.get());

executedSuccessfully.set(true);
Expand Down Expand Up @@ -505,7 +509,9 @@ public void executeSpecifyBibtex() {
libraryTab.getUndoManager(),
stateManager,
dialogService,
taskExecutor);
taskExecutor,
null,
null);
handler.importEntriesWithDuplicateCheck(null, result.get());

executedSuccessfully.set(true);
Expand Down
Loading