From 62ed1b5e80e222ff776a3bc5e27f3a425075d91a Mon Sep 17 00:00:00 2001 From: Ritij Paudel <43158841+paudelritij@users.noreply.github.com> Date: Mon, 7 Jul 2025 14:33:56 +0930 Subject: [PATCH 01/14] Add Pagination for fetchers --- .../gui/importer/ImportEntriesDialog.java | 36 +++++++++++++ .../gui/importer/ImportEntriesViewModel.java | 50 ++++++++++++++++++- .../gui/importer/ImportEntriesDialog.fxml | 4 ++ .../main/resources/l10n/JabRef_en.properties | 2 + 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/jabgui/src/main/java/org/jabref/gui/importer/ImportEntriesDialog.java b/jabgui/src/main/java/org/jabref/gui/importer/ImportEntriesDialog.java index 46298d897a1..69de0afdbb6 100644 --- a/jabgui/src/main/java/org/jabref/gui/importer/ImportEntriesDialog.java +++ b/jabgui/src/main/java/org/jabref/gui/importer/ImportEntriesDialog.java @@ -6,6 +6,7 @@ import javafx.beans.binding.Bindings; import javafx.beans.binding.BooleanBinding; +import javafx.collections.ListChangeListener; import javafx.css.PseudoClass; import javafx.fxml.FXML; import javafx.geometry.Insets; @@ -35,6 +36,7 @@ import org.jabref.gui.util.BaseDialog; import org.jabref.gui.util.NoSelectionModel; import org.jabref.gui.util.ViewModelListCellFactory; +import org.jabref.logic.importer.PagedSearchBasedFetcher; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.l10n.Localization; import org.jabref.logic.shared.DatabaseLocation; @@ -114,6 +116,20 @@ private void initialize() { placeholder.textProperty().bind(viewModel.messageProperty()); entriesListView.setPlaceholder(placeholder); entriesListView.setItems(viewModel.getEntries()); + entriesListView.getCheckModel().getCheckedItems().addListener((ListChangeListener) change -> { + while (change.next()) { + if (change.wasAdded()) { + for (BibEntry entry : change.getAddedSubList()) { + viewModel.getCheckedEntries().add(entry); + } + } + if (change.wasRemoved()) { + for (BibEntry entry : change.getRemoved()) { + viewModel.getCheckedEntries().remove(entry); + } + } + } + }); libraryListView.setEditable(false); libraryListView.getItems().addAll(stateManager.getOpenDatabases()); @@ -225,4 +241,24 @@ public void selectAllEntries() { unselectAll(); entriesListView.getCheckModel().checkAll(); } + + @FXML + private void onPrevPage() { + viewModel.prevPage(); + restoreCheckedEntries(); + } + + @FXML + private void onNextPage() { + viewModel.nextPage(); + restoreCheckedEntries(); + } + + private void restoreCheckedEntries() { + for (BibEntry entry : viewModel.getEntries()) { + if (viewModel.getCheckedEntries().contains(entry)) { + entriesListView.getCheckModel().check(entry); + } + } + } } diff --git a/jabgui/src/main/java/org/jabref/gui/importer/ImportEntriesViewModel.java b/jabgui/src/main/java/org/jabref/gui/importer/ImportEntriesViewModel.java index 8dc031f249a..b329ee3ece0 100644 --- a/jabgui/src/main/java/org/jabref/gui/importer/ImportEntriesViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/importer/ImportEntriesViewModel.java @@ -2,8 +2,10 @@ import java.io.IOException; import java.io.StringWriter; +import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Set; import javax.swing.undo.UndoManager; @@ -13,6 +15,7 @@ import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import javafx.collections.ObservableSet; import org.jabref.gui.AbstractViewModel; import org.jabref.gui.DialogService; @@ -40,6 +43,7 @@ public class ImportEntriesViewModel extends AbstractViewModel { private static final Logger LOGGER = LoggerFactory.getLogger(ImportEntriesViewModel.class); + private static final int PAGE_SIZE = 20; private final StringProperty message; private final TaskExecutor taskExecutor; @@ -53,6 +57,11 @@ public class ImportEntriesViewModel extends AbstractViewModel { private final GuiPreferences preferences; private final BibEntryTypesManager entryTypesManager; private final ObjectProperty selectedDb; + private final ObservableList pagedEntries = FXCollections.observableArrayList(); + private final ObservableSet checkedEntries = FXCollections.observableSet(); + private List allEntries = new ArrayList<>(); + + private int currentPage = 0; /** * @param databaseContext the database to import into @@ -85,6 +94,7 @@ public ImportEntriesViewModel(BackgroundTask task, this.parserResult = parserResult; // fill in the list for the user, where one can select the entries to import entries.addAll(parserResult.getDatabase().getEntries()); + loadAllEntries(entries); if (entries.isEmpty()) { task.updateMessage(Localization.lang("No entries corresponding to given query")); } @@ -111,7 +121,7 @@ public BibDatabaseContext getSelectedDb() { } public ObservableList getEntries() { - return entries; + return pagedEntries; } public boolean hasDuplicate(BibEntry entry) { @@ -177,4 +187,42 @@ private Optional findInternalDuplicate(BibEntry entry) { } return Optional.empty(); } + + public Set getCheckedEntries() { + return checkedEntries; + } + + public void loadAllEntries(List entries) { + this.allEntries = new ArrayList<>(entries); + this.currentPage = 0; + updatePagedEntries(); + } + + public void nextPage() { + if (hasNextPage()) { + currentPage++; + updatePagedEntries(); + } + } + + public void prevPage() { + if (hasPrevPage()) { + currentPage--; + updatePagedEntries(); + } + } + + public boolean hasNextPage() { + return (currentPage + 1) * PAGE_SIZE < allEntries.size(); + } + + public boolean hasPrevPage() { + return currentPage > 0; + } + + private void updatePagedEntries() { + int fromIdx = currentPage * PAGE_SIZE; + int toIdx = Math.min(fromIdx + PAGE_SIZE, allEntries.size()); + pagedEntries.setAll(allEntries.subList(fromIdx, toIdx)); + } } diff --git a/jabgui/src/main/resources/org/jabref/gui/importer/ImportEntriesDialog.fxml b/jabgui/src/main/resources/org/jabref/gui/importer/ImportEntriesDialog.fxml index a7061744df7..d747c905e4a 100644 --- a/jabgui/src/main/resources/org/jabref/gui/importer/ImportEntriesDialog.fxml +++ b/jabgui/src/main/resources/org/jabref/gui/importer/ImportEntriesDialog.fxml @@ -20,6 +20,10 @@