Verified Owner
Top Fields Constructors Methods
org.jabref.gui.groups

public Class GroupTreeViewModel

extends AbstractViewModel
Class Inheritance
Imports
java.util.ArrayList, .Comparator, .List, .Objects, .Optional, java.util.function.Consumer, .Predicate, java.util.stream.Collectors, javafx.beans.property.ListProperty, .ObjectProperty, .SimpleListProperty, .SimpleObjectProperty, .SimpleStringProperty, .StringProperty, javafx.collections.FXCollections, .ObservableList, javafx.scene.control.Alert, .ButtonBar, .ButtonType, javafx.stage.WindowEvent, org.jabref.gui.AbstractViewModel, .DialogService, .StateManager, org.jabref.gui.actions.StandardActions, org.jabref.gui.ai.chat.AiGroupChatWindow, org.jabref.gui.preferences.GuiPreferences, org.jabref.gui.util.BaseDialog, .CustomLocalDragboard, .UiTaskExecutor, org.jabref.logic.ai.AiService, org.jabref.logic.ai.ingestion.tasks.generateembeddingsforseveral.GenerateEmbeddingsForSeveralTaskRequest, org.jabref.logic.ai.summarization.tasks.GenerateSummaryTaskRequest, org.jabref.logic.groups.GroupsFactory, org.jabref.logic.l10n.Localization, org.jabref.logic.search.query.GroupNameFilterVisitor, org.jabref.logic.util.TaskExecutor, org.jabref.model.ai.identifiers.FullBibEntry, org.jabref.model.database.BibDatabaseContext, org.jabref.model.entry.BibEntry, .BibEntryTypesManager, .LinkedFile, org.jabref.model.groups.AbstractGroup, .AutomaticKeywordGroup, .AutomaticPersonsGroup, .ExplicitGroup, .GroupTreeNode, .RegexKeywordGroup, .SearchGroup, .TexGroup, .WordKeywordGroup, org.jabref.model.groups.event.GroupUpdatedEvent, org.jabref.model.metadata.MetaData, org.jabref.model.metadata.event.MetaDataChangeSource, org.jabref.model.undo.CompoundEdit, .UndoableGroupTreeChange, com.google.common.eventbus.Subscribe, com.tobiasdiez.easybind.EasyBind, org.jspecify.annotations.NonNull, .Nullable

Field Summary

Modifier and TypeField and Description
private final AiService
private final Comparator<GroupTreeNode>
private final Comparator<GroupTreeNode>
private final Comparator<GroupTreeNode>
private final Comparator<GroupTreeNode>
private Optional<BibDatabaseContext>
private final DialogService
private final ObjectProperty<Predicate<GroupNodeViewModel>>
private final StringProperty
private final CustomLocalDragboard
private @Nullable MetaData
private final GuiPreferences
private final ObjectProperty<GroupNodeViewModel>
private final ListProperty<GroupNodeViewModel>
private final StateManager
private final TaskExecutor

Constructor Summary

AccessConstructor and Description
public
GroupTreeViewModel(@NonNull StateManager stateManager, @NonNull BibEntryTypesManager entryTypesManager, @NonNull GuiPreferences preferences, @NonNull DialogService dialogService, @NonNull AiService aiService, @NonNull CustomLocalDragboard localDragboard, @NonNull TaskExecutor taskExecutor)

Method Summary

Modifier and TypeMethod and Description
public void
addNewGroupToRoot()

Opens "New Group Dialog" and add the resulting group to the root

public void
addNewSubgroup(GroupNodeViewModel parent, GroupDialogHeader groupDialogHeader)

Opens "New Group Dialog" and adds the resulting group as subgroup to the specified group

public void
addSelectedEntries(GroupNodeViewModel group)

Todo

warn before assigning to a group whose membership is written to a field other than keywords, since that edits the entries in a way the user may not expect.

public void
addSuggestedGroups(GroupNodeViewModel
The "All Entries" parent node.
parent
)

Adds JabRef suggested groups under the "All Entries" parent node.

public void
public void
private void
public void
editGroup(GroupNodeViewModel oldGroup)

Opens "Edit Group Dialog" and changes the given group to the edited one.

public ObjectProperty<Predicate<GroupNodeViewModel>>
public StringProperty
public void
public void
private boolean
public void
listen(GroupUpdatedEvent event)

Rebuilds the displayed group tree when the group root was replaced underneath it - e.g. applied from a shared database (see DBMSSynchronizer#synchronizeLocalMetaData).

private void
onActiveDatabaseChanged(Optional<BibDatabaseContext> newDatabase)

Gets invoked if the user changes the active database.

pack-priv boolean

Returns:

true if just trivial modifications (e.g. color or description) or the relevant group properties are equal, false otherwise
onlyMinorChanges
(AbstractGroup
Original Group
oldGroup
,
AbstractGroup
Edited group
newGroup
)

Check if it is necessary to show a group modified, reassign entry dialog

Group name change is handled separately

private void
onSelectedGroupChanged(ObservableList<GroupNodeViewModel> newValue)

Gets invoked if the user selects a different group.

private void
recordEntryChange(String name, Consumer<CompoundEdit> operation)

Records entry assignments as one undo step.

public void
recordTreeChange(String name, Consumer<CompoundEdit> operation)

Runs a group operation and records it as one undo step, tree and entries together.

public void
recordTreeChange(String name, Runnable operation)

For a gesture handler that has no changes of its own to hand over — see recordTreeChange(String, Consumer).

private void
public void
removeGroupAndSubgroups(GroupNodeViewModel group)

Removes the specified group and its subgroups (after asking for confirmation).

public void
public void
removeGroupNoSubgroups(GroupNodeViewModel group)

Removes the specified group (after asking for confirmation).

pack-priv void
removeGroupsAndSubGroupsFromEntries(GroupNodeViewModel group, CompoundEdit
collects the entry changes, so that undoing the removal puts the assignments back
edit
)

public void
removeSelectedEntries(GroupNodeViewModel group)

See addSelectedEntries for the warning this still owes the user.

public void
public ObjectProperty<GroupNodeViewModel>
public ListProperty<GroupNodeViewModel>
public void
public void
public void
public void
private void
writeBackAndRecord(MetaData metaData, Optional<GroupTreeNode> before, CompoundEdit edit)

Writes the view models back to the metadata and records the tree change, if there is one.

public void
private void

Field Detail

aiServiceback to summary
private final AiService aiService
compAlphabetIgnoreCaseback to summary
private final Comparator<GroupTreeNode> compAlphabetIgnoreCase
compAlphabetIgnoreCaseReverseback to summary
private final Comparator<GroupTreeNode> compAlphabetIgnoreCaseReverse
compEntriesback to summary
private final Comparator<GroupTreeNode> compEntries
compEntriesReverseback to summary
private final Comparator<GroupTreeNode> compEntriesReverse
currentDatabaseback to summary
private Optional<BibDatabaseContext> currentDatabase
dialogServiceback to summary
private final DialogService dialogService
filterPredicateback to summary
private final ObjectProperty<Predicate<GroupNodeViewModel>> filterPredicate
filterTextback to summary
private final StringProperty filterText
localDragboardback to summary
private final CustomLocalDragboard localDragboard
observedMetaDataback to summary
private @Nullable MetaData observedMetaData
preferencesback to summary
private final GuiPreferences preferences
rootGroupback to summary
private final ObjectProperty<GroupNodeViewModel> rootGroup
selectedGroupsback to summary
private final ListProperty<GroupNodeViewModel> selectedGroups
stateManagerback to summary
private final StateManager stateManager
taskExecutorback to summary
private final TaskExecutor taskExecutor

Constructor Detail

GroupTreeViewModelback to summary
public GroupTreeViewModel(@NonNull StateManager stateManager, @NonNull BibEntryTypesManager entryTypesManager, @NonNull GuiPreferences preferences, @NonNull DialogService dialogService, @NonNull AiService aiService, @NonNull CustomLocalDragboard localDragboard, @NonNull TaskExecutor taskExecutor)

Method Detail

addNewGroupToRootback to summary
public void addNewGroupToRoot()

Opens "New Group Dialog" and add the resulting group to the root

addNewSubgroupback to summary
public void addNewSubgroup(GroupNodeViewModel parent, GroupDialogHeader groupDialogHeader)

Opens "New Group Dialog" and adds the resulting group as subgroup to the specified group

addSelectedEntriesback to summary
public void addSelectedEntries(GroupNodeViewModel group)

Todo

warn before assigning to a group whose membership is written to a field other than keywords, since that edits the entries in a way the user may not expect.

addSuggestedGroupsback to summary
public void addSuggestedGroups(GroupNodeViewModel parent)

Adds JabRef suggested groups under the "All Entries" parent node. Assumes the parent is already validated as "All Entries" by the caller.

Parameters
parent:GroupNodeViewModel

The "All Entries" parent node.

chatWithGroupback to summary
public void chatWithGroup(GroupNodeViewModel group)
clearGroupback to summary
public void clearGroup(GroupNodeViewModel group)
disposeDisplayedGroupsback to summary
private void disposeDisplayedGroups()
editGroupback to summary
public void editGroup(GroupNodeViewModel oldGroup)

Opens "Edit Group Dialog" and changes the given group to the edited one.

filterPredicatePropertyback to summary
public ObjectProperty<Predicate<GroupNodeViewModel>> filterPredicateProperty()
filterTextPropertyback to summary
public StringProperty filterTextProperty()
generateEmbeddingsback to summary
public void generateEmbeddings(GroupNodeViewModel groupNode)
generateSummariesback to summary
public void generateSummaries(GroupNodeViewModel groupNode)
isGroupTypeEqualback to summary
private boolean isGroupTypeEqual(AbstractGroup oldGroup, AbstractGroup newGroup)
listenback to summary
public void listen(GroupUpdatedEvent event)

Rebuilds the displayed group tree when the group root was replaced underneath it - e.g. applied from a shared database (see DBMSSynchronizer#synchronizeLocalMetaData). Local edits only mutate nodes below the existing root, which the view models observe themselves - rebuilding on those would reset selection and expansion state.

Annotations
@Subscribe
onActiveDatabaseChangedback to summary
private void onActiveDatabaseChanged(Optional<BibDatabaseContext> newDatabase)

Gets invoked if the user changes the active database. We need to get the new group tree and update the view

onlyMinorChangesback to summary
pack-priv boolean onlyMinorChanges(AbstractGroup oldGroup, AbstractGroup newGroup)

Check if it is necessary to show a group modified, reassign entry dialog

Group name change is handled separately

Parameters
oldGroup:AbstractGroup

Original Group

newGroup:AbstractGroup

Edited group

Returns:boolean

true if just trivial modifications (e.g. color or description) or the relevant group properties are equal, false otherwise

onSelectedGroupChangedback to summary
private void onSelectedGroupChanged(ObservableList<GroupNodeViewModel> newValue)

Gets invoked if the user selects a different group. We need to notify the StateManager about this change so that the main table gets updated.

recordEntryChangeback to summary
private void recordEntryChange(String name, Consumer<CompoundEdit> operation)

Records entry assignments as one undo step. The tree is untouched, so only the entries' group fields are recorded — recordTreeChange is for operations that change the tree.

recordTreeChangeback to summary
public void recordTreeChange(String name, Consumer<CompoundEdit> operation)

Runs a group operation and records it as one undo step, tree and entries together.

Public because the gesture and the operation do not always belong to the same class: a drag moves several groups at once, and that is one step, opened here by the view that handles the drop.

The tree is recorded as a whole because that is how every operation reaches the model: the nodes are edited in place and the root is written back afterwards. Operations that also change entries hand their org.jabref.model.FieldChanges to the recorder, so that taking the group back takes the assignments with it.

The prior tree is copied before the operation runs — it is the very tree the operation is about to mutate.

recordTreeChangeback to summary
public void recordTreeChange(String name, Runnable operation)

For a gesture handler that has no changes of its own to hand over — see recordTreeChange(String, Consumer).

refreshback to summary
private void refresh()
removeGroupAndSubgroupsback to summary
public void removeGroupAndSubgroups(GroupNodeViewModel group)

Removes the specified group and its subgroups (after asking for confirmation).

removeGroupKeepSubgroupsback to summary
public void removeGroupKeepSubgroups(GroupNodeViewModel group)
removeGroupNoSubgroupsback to summary
public void removeGroupNoSubgroups(GroupNodeViewModel group)

Removes the specified group (after asking for confirmation).

removeGroupsAndSubGroupsFromEntriesback to summary
pack-priv void removeGroupsAndSubGroupsFromEntries(GroupNodeViewModel group, CompoundEdit edit)
Parameters
edit:CompoundEdit

collects the entry changes, so that undoing the removal puts the assignments back

removeSelectedEntriesback to summary
public void removeSelectedEntries(GroupNodeViewModel group)

See addSelectedEntries for the warning this still owes the user.

removeSubgroupsback to summary
public void removeSubgroups(GroupNodeViewModel group)
rootGroupPropertyback to summary
public ObjectProperty<GroupNodeViewModel> rootGroupProperty()
selectedGroupsPropertyback to summary
public ListProperty<GroupNodeViewModel> selectedGroupsProperty()
sortAlphabeticallyRecursiveback to summary
public void sortAlphabeticallyRecursive(GroupTreeNode group)
sortEntriesRecursiveback to summary
public void sortEntriesRecursive(GroupTreeNode group)
sortReverseAlphabeticallyRecursiveback to summary
public void sortReverseAlphabeticallyRecursive(GroupTreeNode group)
sortReverseEntriesRecursiveback to summary
public void sortReverseEntriesRecursive(GroupTreeNode group)
writeBackAndRecordback to summary
private void writeBackAndRecord(MetaData metaData, Optional<GroupTreeNode> before, CompoundEdit edit)

Writes the view models back to the metadata and records the tree change, if there is one.

Called also when the operation failed part-way: the tree holds what it managed to change, and a step that took back only the entry assignments would leave the library in a state nothing describes. The journal hands over a failed block's changes for the same reason.

writeGroupChangesToMetaDataback to summary
public void writeGroupChangesToMetaData()
writeGroupChangesToMetaDataback to summary
private void writeGroupChangesToMetaData(MetaDataChangeSource source)