From f7386295fe262f6d3b4fd2f2fb4c9c4d6dd96b33 Mon Sep 17 00:00:00 2001 From: Loay Ghreeb Date: Tue, 24 Sep 2024 20:02:45 +0300 Subject: [PATCH] Hide completed background tasks (#11821) * Reformat code comments * Finished tasks have 100% completeness Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> * Remove finished tasks * Restructure if/then to avoid unnecessary creation of TaskProgressView * Remove subscription on hide * Try to show running tasks only * At shutdown at end, also do not show tasks * Add CHANGELOG.md entry * Fix IndexOutOfBoundsException * Fix hiding task progress view * Update CHANGELOG.md --------- Co-authored-by: Oliver Kopp Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> --- CHANGELOG.md | 1 + .../org/jabref/gui/JabRefDialogService.java | 2 +- .../java/org/jabref/gui/StateManager.java | 23 +++++++++---- .../org/jabref/gui/frame/MainToolBar.java | 32 +++++++++---------- .../org/jabref/gui/util/UiTaskExecutor.java | 11 +++++-- 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aa4a1b7eb8..75c4c7e1552 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - The Pubmed/Medline Plain importer now imports the PMID field as well [#11488](https://github.com/JabRef/jabref/issues/11488) - The 'Check for updates' menu bar button is now always enabled. [#11485](https://github.com/JabRef/jabref/pull/11485) - JabRef respects the [configuration for storing files relative to the .bib file](https://docs.jabref.org/finding-sorting-and-cleaning-entries/filelinks#directories-for-files) in more cases. [#11492](https://github.com/JabRef/jabref/pull/11492) +- JabRef does not show finished background tasks in the status bar popup. [#11821](https://github.com/JabRef/jabref/pull/11821) - We enhanced the indexing speed. [#11502](https://github.com/JabRef/jabref/pull/11502) - ⚠️ Renamed command line parameters `embeddBibfileInPdf` to `embedBibFileInPdf`, `writeMetadatatoPdf` to `writeMetadataToPdf`, and `writeXMPtoPdf` to `writeXmpToPdf`. [#11575](https://github.com/JabRef/jabref/pull/11575) - The browse button for a Custom theme now opens in the directory of the current used CSS file. [#11597](https://github.com/JabRef/jabref/pull/11597) diff --git a/src/main/java/org/jabref/gui/JabRefDialogService.java b/src/main/java/org/jabref/gui/JabRefDialogService.java index a1d97316a25..dccdc17898d 100644 --- a/src/main/java/org/jabref/gui/JabRefDialogService.java +++ b/src/main/java/org/jabref/gui/JabRefDialogService.java @@ -379,7 +379,7 @@ public void showProgressDialogAndWait(String title, String content, Task @Override public Optional showBackgroundProgressDialogAndWait(String title, String content, StateManager stateManager) { TaskProgressView> taskProgressView = new TaskProgressView<>(); - EasyBind.bindContent(taskProgressView.getTasks(), stateManager.getBackgroundTasks()); + EasyBind.bindContent(taskProgressView.getTasks(), stateManager.getRunningBackgroundTasks()); taskProgressView.setRetainTasks(false); taskProgressView.setGraphicFactory(task -> ThemeManager.getDownloadIconTitleMap.getOrDefault(task.getTitle(), null)); diff --git a/src/main/java/org/jabref/gui/StateManager.java b/src/main/java/org/jabref/gui/StateManager.java index 94c4a359467..e75ffcdc89e 100644 --- a/src/main/java/org/jabref/gui/StateManager.java +++ b/src/main/java/org/jabref/gui/StateManager.java @@ -6,6 +6,8 @@ import java.util.Optional; import javafx.beans.Observable; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.BooleanBinding; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleIntegerProperty; @@ -13,6 +15,7 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.ObservableMap; +import javafx.collections.transformation.FilteredList; import javafx.concurrent.Task; import javafx.scene.Node; import javafx.util.Pair; @@ -64,10 +67,12 @@ public class StateManager { private final IntegerProperty searchResultSize = new SimpleIntegerProperty(0); private final IntegerProperty globalSearchResultSize = new SimpleIntegerProperty(0); private final OptionalObjectProperty focusOwner = OptionalObjectProperty.empty(); - private final ObservableList, Task>> backgroundTasks = FXCollections.observableArrayList(task -> new Observable[] {task.getValue().progressProperty(), task.getValue().runningProperty()}); - private final EasyBinding anyTaskRunning = EasyBind.reduce(backgroundTasks, tasks -> tasks.map(Pair::getValue).anyMatch(Task::isRunning)); - private final EasyBinding anyTasksThatWillNotBeRecoveredRunning = EasyBind.reduce(backgroundTasks, tasks -> tasks.anyMatch(task -> !task.getKey().willBeRecoveredAutomatically() && task.getValue().isRunning())); - private final EasyBinding tasksProgress = EasyBind.reduce(backgroundTasks, tasks -> tasks.map(Pair::getValue).filter(Task::isRunning).mapToDouble(Task::getProgress).average().orElse(1)); + private final ObservableList, Task>> backgroundTasksPairs = FXCollections.observableArrayList(task -> new Observable[] {task.getValue().progressProperty(), task.getValue().runningProperty()}); + private final ObservableList> backgroundTasks = EasyBind.map(backgroundTasksPairs, Pair::getValue); + private final FilteredList> runningBackgroundTasks = new FilteredList<>(backgroundTasks, Task::isRunning); + private final BooleanBinding anyTaskRunning = Bindings.createBooleanBinding(() -> !runningBackgroundTasks.isEmpty(), runningBackgroundTasks); + private final EasyBinding anyTasksThatWillNotBeRecoveredRunning = EasyBind.reduce(backgroundTasksPairs, tasks -> tasks.anyMatch(task -> !task.getKey().willBeRecoveredAutomatically() && task.getValue().isRunning())); + private final EasyBinding tasksProgress = EasyBind.reduce(backgroundTasksPairs, tasks -> tasks.map(Pair::getValue).filter(Task::isRunning).mapToDouble(Task::getProgress).average().orElse(1)); private final ObservableMap dialogWindowStates = FXCollections.observableHashMap(); private final ObservableList visibleSidePanes = FXCollections.observableArrayList(); private final ObjectProperty lastAutomaticFieldEditorEdit = new SimpleObjectProperty<>(); @@ -153,14 +158,18 @@ public Optional getFocusOwner() { } public ObservableList> getBackgroundTasks() { - return EasyBind.map(backgroundTasks, Pair::getValue); + return backgroundTasks; + } + + public ObservableList> getRunningBackgroundTasks() { + return runningBackgroundTasks; } public void addBackgroundTask(BackgroundTask backgroundTask, Task task) { - this.backgroundTasks.addFirst(new Pair<>(backgroundTask, task)); + this.backgroundTasksPairs.addFirst(new Pair<>(backgroundTask, task)); } - public EasyBinding getAnyTaskRunning() { + public BooleanBinding getAnyTaskRunning() { return anyTaskRunning; } diff --git a/src/main/java/org/jabref/gui/frame/MainToolBar.java b/src/main/java/org/jabref/gui/frame/MainToolBar.java index 57c5e4b30d6..03bbc72e3b0 100644 --- a/src/main/java/org/jabref/gui/frame/MainToolBar.java +++ b/src/main/java/org/jabref/gui/frame/MainToolBar.java @@ -46,6 +46,7 @@ import org.jabref.model.util.FileUpdateMonitor; import com.tobiasdiez.easybind.EasyBind; +import com.tobiasdiez.easybind.Subscription; import org.controlsfx.control.PopOver; import org.controlsfx.control.TaskProgressView; @@ -65,6 +66,7 @@ public class MainToolBar extends ToolBar { private PopOver entryFromIdPopOver; private PopOver progressViewPopOver; + private Subscription taskProgressSubscription; public MainToolBar(LibraryTabContainer tabContainer, PushToApplicationCommand pushToApplicationCommand, @@ -209,15 +211,11 @@ Group createTaskIndicator() { } }); - /* - The label of the indicator cannot be removed with styling. Therefore, - hide it and clip it to a square of (width x width) each time width is updated. - */ + // The label of the indicator cannot be removed with styling. Therefore, + // hide it and clip it to a square of (width x width) each time width is updated. indicator.widthProperty().addListener((observable, oldValue, newValue) -> { - /* - The indeterminate spinner is wider than the determinate spinner. - We must make sure they are the same width for the clipping to result in a square of the same size always. - */ + // The indeterminate spinner is wider than the determinate spinner. + // We must make sure they are the same width for the clipping to result in a square of the same size always. if (!indicator.isIndeterminate()) { indicator.setPrefWidth(newValue.doubleValue()); } @@ -228,8 +226,14 @@ hide it and clip it to a square of (width x width) each time width is updated. }); indicator.setOnMouseClicked(event -> { + if ((progressViewPopOver != null) && (progressViewPopOver.isShowing())) { + progressViewPopOver.hide(); + taskProgressSubscription.unsubscribe(); + return; + } + TaskProgressView> taskProgressView = new TaskProgressView<>(); - EasyBind.bindContent(taskProgressView.getTasks(), stateManager.getBackgroundTasks()); + taskProgressSubscription = EasyBind.bindContent(taskProgressView.getTasks(), stateManager.getRunningBackgroundTasks()); taskProgressView.setRetainTasks(false); taskProgressView.setGraphicFactory(task -> ThemeManager.getDownloadIconTitleMap.getOrDefault(task.getTitle(), null)); @@ -237,14 +241,10 @@ hide it and clip it to a square of (width x width) each time width is updated. progressViewPopOver = new PopOver(taskProgressView); progressViewPopOver.setTitle(Localization.lang("Background Tasks")); progressViewPopOver.setArrowLocation(PopOver.ArrowLocation.RIGHT_TOP); - progressViewPopOver.setContentNode(taskProgressView); - progressViewPopOver.show(indicator); - } else if (progressViewPopOver.isShowing()) { - progressViewPopOver.hide(); - } else { - progressViewPopOver.setContentNode(taskProgressView); - progressViewPopOver.show(indicator); } + + progressViewPopOver.setContentNode(taskProgressView); + progressViewPopOver.show(indicator); }); return new Group(indicator); diff --git a/src/main/java/org/jabref/gui/util/UiTaskExecutor.java b/src/main/java/org/jabref/gui/util/UiTaskExecutor.java index eab7922ed9d..c346cb81ddd 100644 --- a/src/main/java/org/jabref/gui/util/UiTaskExecutor.java +++ b/src/main/java/org/jabref/gui/util/UiTaskExecutor.java @@ -196,9 +196,14 @@ protected V call() throws Exception { javaTask.setOnRunning(event -> onRunning.run()); } Consumer onSuccess = task.getOnSuccess(); - if (onSuccess != null) { - javaTask.setOnSucceeded(event -> onSuccess.accept(javaTask.getValue())); - } + javaTask.setOnSucceeded(event -> { + // Set to 100% completed on completion + task.updateProgress(1, 1); + + if (onSuccess != null) { + onSuccess.accept(javaTask.getValue()); + } + }); Consumer onException = task.getOnException(); if (onException != null) { javaTask.setOnFailed(event -> onException.accept(convertToException(javaTask.getException())));