Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
eea1b37
Remove SmartGroup and refactor groups factory
shubhamk0205 Nov 23, 2025
ad813ad
Merge branch 'main' of https://github.com/JabRef/jabref
shubhamk0205 Nov 23, 2025
50bdad8
Removed obsolete SmartGroup localization key & Fixed KeyCollision
shubhamk0205 Nov 24, 2025
5aaadc6
Fix the code so the @NonNull field id in KeyCollisionException.java i…
shubhamk0205 Nov 24, 2025
5b257a0
added a test for the migraiton of the SmartGroup to the new Explicit …
shubhamk0205 Nov 25, 2025
67ce491
Merge branch 'main' into fix-for-issue-14143
shubhamk0205 Nov 25, 2025
84d7c98
Remove SmartGroup and refactor groups factory
shubhamk0205 Nov 23, 2025
d8a2d43
Removed obsolete SmartGroup localization key & Fixed KeyCollision
shubhamk0205 Nov 24, 2025
12bff58
Fix the code so the @NonNull field id in KeyCollisionException.java i…
shubhamk0205 Nov 24, 2025
67830d7
added a test for the migration of the SmartGroup to the new Explicit …
shubhamk0205 Nov 25, 2025
9f851ca
Added a test for the migration of SmartGroup to the new Explicit grou…
shubhamk0205 Nov 25, 2025
00a54f8
fixed format errors
shubhamk0205 Nov 25, 2025
d2141eb
fixed format
shubhamk0205 Nov 25, 2025
50970ab
fixed importing issue
shubhamk0205 Nov 25, 2025
4024bf0
fixed openwrite by commenting out in rewrite.yml
shubhamk0205 Nov 26, 2025
8720aa9
runned rewriteRun gradel
shubhamk0205 Nov 26, 2025
a989e72
restoring rewrite.yml
shubhamk0205 Nov 26, 2025
d881d3d
Remove duplicate test
koppor Nov 30, 2025
691d5eb
refine comments
Siedlerchr Nov 30, 2025
221e85f
Merge branch 'fix-for-issue-14143' of github.com:shubhamk0205/jabref …
Siedlerchr Nov 30, 2025
1293aa5
Undo changes to KeyCollisionException
calixtus Nov 30, 2025
3e8e072
usse separator
Siedlerchr Nov 30, 2025
d8802f9
Merge branch 'fix-for-issue-14143' of github.com:shubhamk0205/jabref …
Siedlerchr Nov 30, 2025
e8094af
Fix variable names
koppor Nov 30, 2025
7a9d914
Use _
koppor Nov 30, 2025
e7e23df
Fix name
koppor Nov 30, 2025
fe98c8b
Reduce scope of migration constant and remove superfluous throws
calixtus Nov 30, 2025
d5da74c
Merge remote-tracking branch 'shubhamk0205/fix-for-issue-14143' into …
calixtus Nov 30, 2025
b8d1cc4
add hint
Siedlerchr Nov 30, 2025
7a62841
Merge branch 'fix-for-issue-14143' of github.com:shubhamk0205/jabref …
Siedlerchr Nov 30, 2025
9a49033
Merge remote-tracking branch 'shubhamk0205/fix-for-issue-14143' into …
calixtus Nov 30, 2025
7568146
Fix format
koppor Nov 30, 2025
dfe948f
Add `@deprecated`
koppor Nov 30, 2025
44fc1cb
Fix tests
koppor Nov 30, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.jabref.gui.groups.UndoableModifySubtree;
import org.jabref.gui.undo.NamedCompoundEdit;
import org.jabref.logic.bibtex.comparator.GroupDiff;
import org.jabref.logic.groups.DefaultGroupsFactory;
import org.jabref.logic.groups.GroupsFactory;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.groups.GroupTreeNode;
Expand All @@ -27,7 +27,7 @@ public void applyChange(NamedCompoundEdit undoEdit) {
GroupTreeNode newRoot = groupDiff.getNewGroupRoot();

GroupTreeNode root = databaseContext.getMetaData().getGroups().orElseGet(() -> {
GroupTreeNode groupTreeNode = new GroupTreeNode(DefaultGroupsFactory.getAllEntriesGroup());
GroupTreeNode groupTreeNode = new GroupTreeNode(GroupsFactory.createAllEntriesGroup());
databaseContext.getMetaData().setGroups(groupTreeNode);
return groupTreeNode;
});
Expand All @@ -38,7 +38,7 @@ public void applyChange(NamedCompoundEdit undoEdit) {
root.removeAllChildren();
if (newRoot == null) {
// I think setting root to null is not possible
root.setGroup(DefaultGroupsFactory.getAllEntriesGroup(), false, false, null);
root.setGroup(GroupsFactory.createAllEntriesGroup(), false, false, null);
} else {
// change root group, even though it'll be AllEntries anyway
root.setGroup(newRoot.getGroup(), false, false, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@
import org.jabref.model.entry.BibtexString;
import org.jabref.model.entry.LinkedFile;
import org.jabref.model.entry.field.StandardField;
import org.jabref.model.groups.ExplicitGroup;
import org.jabref.model.groups.GroupEntryChanger;
import org.jabref.model.groups.GroupTreeNode;
import org.jabref.model.groups.SmartGroup;
import org.jabref.model.util.FileUpdateMonitor;
import org.jabref.model.util.OptionalUtil;

Expand Down Expand Up @@ -533,14 +533,17 @@ private List<BibEntry> handlePdfUrl(String pdfUrl) throws IOException {

private void addToImportEntriesGroup(List<BibEntry> entriesToInsert) {
if (preferences.getLibraryPreferences().isAddImportedEntriesEnabled()) {
// Only one SmartGroup
String groupName = preferences.getLibraryPreferences().getAddImportedEntriesGroupName();
// We cannot add the new group here directly because we don't have access to the group node viewmoel stuff here
// We would need to add the groups to the metadata first which is a bit more complicated, thus we decided against it atm
this.targetBibDatabaseContext.getMetaData()
.getGroups()
.flatMap(grp -> grp.getChildren()
.stream()
.filter(node -> node.getGroup() instanceof SmartGroup)
.filter(node -> node.getGroup() instanceof ExplicitGroup
&& node.getGroup().getName().equals(groupName))
.findFirst())
.ifPresent(smtGrp -> smtGrp.addEntriesToGroup(entriesToInsert));
.ifPresent(importGroup -> importGroup.addEntriesToGroup(entriesToInsert));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.jabref.model.groups.ExplicitGroup;
import org.jabref.model.groups.KeywordGroup;
import org.jabref.model.groups.SearchGroup;
import org.jabref.model.groups.SmartGroup;

public class GroupDescriptions {

Expand Down Expand Up @@ -62,10 +61,6 @@ public static String getShortDescriptionAllEntriesGroup() {
return Localization.lang("<b>All Entries</b> (this group cannot be edited or removed)");
}

public static String getShortDescriptionSmartGroup(SmartGroup smartGroup) {
return Localization.lang("<b>Smart Group</b> (Import Entries)");
}

public static String getShortDescription(SearchGroup searchGroup, boolean showDynamic) {
StringBuilder sb = new StringBuilder();
sb.append("<b>");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.gui.util.FileDialogConfiguration;
import org.jabref.logic.auxparser.DefaultAuxParser;
import org.jabref.logic.groups.DefaultGroupsFactory;
import org.jabref.logic.groups.GroupsFactory;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.search.IndexManager;
import org.jabref.logic.util.StandardFileType;
Expand Down Expand Up @@ -416,14 +416,14 @@ public void setValues() {

if (editedGroup == null) {
// creating new group -> defaults!
// TODO: Create default group (via org.jabref.logic.groups.DefaultGroupsFactory) and use values
// TODO: Create default group (via org.jabref.logic.groups.GroupsFactory) and use values

colorUseProperty.setValue(false);
colorProperty.setValue(determineColor());
if (parentNode != null) {
parentNode.getGroup()
.getIconName()
.filter(iconName -> !DefaultGroupsFactory.ALL_ENTRIES_GROUP_DEFAULT_ICON.equals(iconName))
.filter(iconName -> !GroupsFactory.ALL_ENTRIES_GROUP_DEFAULT_ICON.equals(iconName))
.ifPresent(iconProperty::setValue);
parentNode.getGroup().getColor().ifPresent(color -> colorUseProperty.setValue(true));
}
Expand Down
23 changes: 8 additions & 15 deletions jabgui/src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.jabref.gui.util.CustomLocalDragboard;
import org.jabref.gui.util.DroppingMouseLocation;
import org.jabref.gui.util.UiTaskExecutor;
import org.jabref.logic.groups.DefaultGroupsFactory;
import org.jabref.logic.groups.GroupsFactory;
import org.jabref.logic.layout.format.LatexToUnicodeFormatter;
import org.jabref.logic.util.BackgroundTask;
import org.jabref.logic.util.TaskExecutor;
Expand All @@ -48,7 +48,6 @@
import org.jabref.model.groups.LastNameGroup;
import org.jabref.model.groups.RegexKeywordGroup;
import org.jabref.model.groups.SearchGroup;
import org.jabref.model.groups.SmartGroup;
import org.jabref.model.groups.TexGroup;
import org.jabref.model.search.event.IndexAddedOrUpdatedEvent;
import org.jabref.model.search.event.IndexClosedEvent;
Expand Down Expand Up @@ -141,7 +140,7 @@ public GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager state
}

static GroupNodeViewModel getAllEntriesGroup(BibDatabaseContext newDatabase, StateManager stateManager, TaskExecutor taskExecutor, CustomLocalDragboard localDragBoard, GuiPreferences preferences) {
return new GroupNodeViewModel(newDatabase, stateManager, taskExecutor, DefaultGroupsFactory.getAllEntriesGroup(), localDragBoard, preferences);
return new GroupNodeViewModel(newDatabase, stateManager, taskExecutor, GroupsFactory.createAllEntriesGroup(), localDragBoard, preferences);
}

private GroupNodeViewModel toViewModel(GroupTreeNode child) {
Expand Down Expand Up @@ -437,16 +436,14 @@ public boolean hasSimilarSearchGroup(SearchGroup searchGroup) {
}

public boolean hasAllSuggestedGroups() {
return hasSimilarSearchGroup(JabRefSuggestedGroups.createWithoutFilesGroup())
&& hasSimilarSearchGroup(JabRefSuggestedGroups.createWithoutGroupsGroup());
return hasSimilarSearchGroup(GroupsFactory.createWithoutFilesGroup())
&& hasSimilarSearchGroup(GroupsFactory.createWithoutGroupsGroup());
}

public boolean canAddEntriesIn() {
AbstractGroup group = groupNode.getGroup();
if (group instanceof AllEntriesGroup) {
return false;
} else if (group instanceof SmartGroup) {
return false;
} else if (group instanceof ExplicitGroup) {
return true;
} else if (group instanceof LastNameGroup || group instanceof RegexKeywordGroup) {
Expand Down Expand Up @@ -477,8 +474,7 @@ public boolean canAddEntriesIn() {
public boolean canBeDragged() {
AbstractGroup group = groupNode.getGroup();
return switch (group) {
case AllEntriesGroup _,
SmartGroup _ ->
case AllEntriesGroup _ ->
false;
case ExplicitGroup _,
SearchGroup _,
Expand Down Expand Up @@ -513,8 +509,7 @@ public boolean canAddGroupsIn() {
case AutomaticKeywordGroup _,
AutomaticPersonsGroup _,
AutomaticDateGroup _,
DateGroup _,
SmartGroup _ ->
DateGroup _ ->
false;
case KeywordGroup _ ->
// KeywordGroup is parent of LastNameGroup, RegexKeywordGroup and WordKeywordGroup
Expand All @@ -532,8 +527,7 @@ public boolean canAddGroupsIn() {
public boolean canRemove() {
AbstractGroup group = groupNode.getGroup();
return switch (group) {
case AllEntriesGroup _,
SmartGroup _ ->
case AllEntriesGroup _ ->
false;
case ExplicitGroup _,
SearchGroup _,
Expand All @@ -560,8 +554,7 @@ public boolean isEditable() {
AbstractGroup group = groupNode.getGroup();
return switch (group) {
case AllEntriesGroup _,
DateGroup _,
SmartGroup _ ->
DateGroup _ ->
false;
case ExplicitGroup _,
SearchGroup _,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import org.jabref.model.groups.GroupTreeNode;
import org.jabref.model.groups.KeywordGroup;
import org.jabref.model.groups.SearchGroup;
import org.jabref.model.groups.SmartGroup;

public class GroupTreeNodeViewModel {
private final GroupTreeNode node;
Expand Down Expand Up @@ -52,8 +51,6 @@ public String getDescription() {
String shortDescription = "";
boolean showDynamic = true;
shortDescription = switch (group) {
case SmartGroup smartGroup ->
GroupDescriptions.getShortDescriptionSmartGroup(smartGroup);
case ExplicitGroup explicitGroup ->
GroupDescriptions.getShortDescriptionExplicitGroup(explicitGroup);
case KeywordGroup keywordGroup ->
Expand Down
25 changes: 13 additions & 12 deletions jabgui/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.gui.util.CustomLocalDragboard;
import org.jabref.logic.ai.AiService;
import org.jabref.logic.groups.GroupsFactory;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.util.TaskExecutor;
import org.jabref.model.database.BibDatabaseContext;
Expand All @@ -41,7 +42,6 @@
import org.jabref.model.groups.GroupTreeNode;
import org.jabref.model.groups.RegexKeywordGroup;
import org.jabref.model.groups.SearchGroup;
import org.jabref.model.groups.SmartGroup;
import org.jabref.model.groups.TexGroup;
import org.jabref.model.groups.WordKeywordGroup;
import org.jabref.model.metadata.MetaData;
Expand Down Expand Up @@ -179,23 +179,24 @@ private void onActiveDatabaseChanged(Optional<BibDatabaseContext> newDatabase) {
rootGroup.setValue(null);
}
currentDatabase = newDatabase;
newDatabase.ifPresent(db -> addGroupImportEntries(rootGroup.get()));
newDatabase.ifPresent(_ -> addGroupImportEntries(rootGroup.get()));
}

private void addGroupImportEntries(GroupNodeViewModel parent) {
if (!preferences.getLibraryPreferences().isAddImportedEntriesEnabled()) {
return;
}

String grpName = preferences.getLibraryPreferences().getAddImportedEntriesGroupName();
AbstractGroup importEntriesGroup = new SmartGroup(grpName, GroupHierarchyType.INDEPENDENT, ',');
boolean isGrpExist = parent.getGroupNode()
.getChildren()
.stream()
.map(GroupTreeNode::getGroup)
.anyMatch(grp -> grp instanceof SmartGroup);
if (!isGrpExist) {
String groupName = preferences.getLibraryPreferences().getAddImportedEntriesGroupName();
boolean groupExists = parent.getGroupNode()
.getChildren()
.stream()
.map(GroupTreeNode::getGroup)
.anyMatch(grp -> grp instanceof ExplicitGroup && grp.getName().equals(groupName));
if (!groupExists) {
currentDatabase.ifPresent(db -> {
char keywordSeparator = preferences.getBibEntryPreferences().getKeywordSeparator();
AbstractGroup importEntriesGroup = new ExplicitGroup(groupName, GroupHierarchyType.INDEPENDENT, keywordSeparator);
GroupTreeNode newSubgroup = parent.addSubgroup(importEntriesGroup);
newSubgroup.moveTo(parent.getGroupNode(), 0);
selectedGroups.setAll(new GroupNodeViewModel(db, stateManager, taskExecutor, newSubgroup, localDragboard, preferences));
Expand Down Expand Up @@ -251,14 +252,14 @@ public void addSuggestedGroups(GroupNodeViewModel parent) {
List<GroupTreeNode> newSuggestedSubgroups = new ArrayList<>();

// 1. Create "Entries without linked files" group if it doesn't exist
SearchGroup withoutFilesGroup = JabRefSuggestedGroups.createWithoutFilesGroup();
SearchGroup withoutFilesGroup = GroupsFactory.createWithoutFilesGroup();
if (!parent.hasSimilarSearchGroup(withoutFilesGroup)) {
GroupTreeNode subGroup = rootNode.addSubgroup(withoutFilesGroup);
newSuggestedSubgroups.add(subGroup);
}

// 2. Create "Entries without groups" group if it doesn't exist
SearchGroup withoutGroupsGroup = JabRefSuggestedGroups.createWithoutGroupsGroup();
SearchGroup withoutGroupsGroup = GroupsFactory.createWithoutGroupsGroup();
if (!parent.hasSimilarSearchGroup(withoutGroupsGroup)) {
GroupTreeNode subGroup = rootNode.addSubgroup(withoutGroupsGroup);
newSuggestedSubgroups.add(subGroup);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import javafx.collections.ObservableList;

import org.jabref.logic.groups.DefaultGroupsFactory;
import org.jabref.logic.groups.GroupsFactory;
import org.jabref.logic.importer.ParserResult;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
Expand Down Expand Up @@ -48,7 +48,7 @@ public void performMigration(@NonNull ParserResult parserResult) {
}

if (parserResult.getMetaData().getGroups().isEmpty()) {
parserResult.getMetaData().setGroups(GroupTreeNode.fromGroup(DefaultGroupsFactory.getAllEntriesGroup()));
parserResult.getMetaData().setGroups(GroupTreeNode.fromGroup(GroupsFactory.createAllEntriesGroup()));
}
GroupTreeNode root = parserResult.getMetaData().getGroups().get();
root.addChild(markingRoot, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
import org.jabref.gui.util.CustomLocalDragboard;
import org.jabref.logic.LibraryPreferences;
import org.jabref.logic.ai.AiService;
import org.jabref.logic.groups.GroupsFactory;
import org.jabref.logic.util.CurrentThreadTaskExecutor;
import org.jabref.logic.util.TaskExecutor;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.BibEntryPreferences;
import org.jabref.model.entry.field.StandardField;
import org.jabref.model.groups.AbstractGroup;
import org.jabref.model.groups.AllEntriesGroup;
Expand Down Expand Up @@ -63,6 +65,9 @@ void setUp() {
true,
true,
GroupHierarchyType.INDEPENDENT));
BibEntryPreferences bibEntryPreferences = mock(BibEntryPreferences.class);
when(bibEntryPreferences.getKeywordSeparator()).thenReturn(',');
when(preferences.getBibEntryPreferences()).thenReturn(bibEntryPreferences);
groupTree = new GroupTreeViewModel(stateManager, mock(DialogService.class), mock(AiService.class), preferences, mock(AdaptVisibleTabs.class), taskExecutor, new CustomLocalDragboard());
}

Expand Down Expand Up @@ -173,7 +178,7 @@ void shouldAddsAllSuggestedGroupsWhenNoneExist() {
void shouldAddOnlyMissingGroup() {
GroupTreeViewModel model = new GroupTreeViewModel(stateManager, dialogService, mock(AiService.class), preferences, mock(AdaptVisibleTabs.class), taskExecutor, new CustomLocalDragboard());
GroupNodeViewModel rootGroup = model.rootGroupProperty().getValue();
rootGroup.getGroupNode().addSubgroup(JabRefSuggestedGroups.createWithoutFilesGroup());
rootGroup.getGroupNode().addSubgroup(GroupsFactory.createWithoutFilesGroup());
assertEquals(1, rootGroup.getChildren().size());

model.addSuggestedGroups(rootGroup);
Expand All @@ -186,8 +191,8 @@ void shouldAddOnlyMissingGroup() {
void shouldNotAddSuggestedGroupsWhenAllExist() {
GroupTreeViewModel model = new GroupTreeViewModel(stateManager, dialogService, mock(AiService.class), preferences, mock(AdaptVisibleTabs.class), taskExecutor, new CustomLocalDragboard());
GroupNodeViewModel rootGroup = model.rootGroupProperty().getValue();
rootGroup.getGroupNode().addSubgroup(JabRefSuggestedGroups.createWithoutFilesGroup());
rootGroup.getGroupNode().addSubgroup(JabRefSuggestedGroups.createWithoutGroupsGroup());
rootGroup.getGroupNode().addSubgroup(GroupsFactory.createWithoutFilesGroup());
rootGroup.getGroupNode().addSubgroup(GroupsFactory.createWithoutGroupsGroup());
assertEquals(2, rootGroup.getChildren().size());

model.addSuggestedGroups(rootGroup);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.Optional;
import java.util.Set;

import org.jabref.logic.groups.DefaultGroupsFactory;
import org.jabref.logic.groups.GroupsFactory;
import org.jabref.logic.importer.ParserResult;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.InternalField;
Expand All @@ -24,7 +24,7 @@ void performMigrationForSingleEntry() {

new ConvertMarkingToGroups().performMigration(parserResult);

GroupTreeNode rootExpected = GroupTreeNode.fromGroup(DefaultGroupsFactory.getAllEntriesGroup());
GroupTreeNode rootExpected = GroupTreeNode.fromGroup(GroupsFactory.createAllEntriesGroup());
GroupTreeNode markings = rootExpected.addSubgroup(new ExplicitGroup("Markings", GroupHierarchyType.INCLUDING, ','));
markings.addSubgroup(new ExplicitGroup("Nicolas:6", GroupHierarchyType.INCLUDING, ','));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import org.jabref.logic.citationkeypattern.CitationKeyPattern;
import org.jabref.logic.citationkeypattern.GlobalCitationKeyPatterns;
import org.jabref.logic.groups.DefaultGroupsFactory;
import org.jabref.logic.groups.GroupsFactory;
import org.jabref.model.entry.field.Field;
import org.jabref.model.groups.GroupTreeNode;
import org.jabref.model.metadata.ContentSelectors;
Expand Down Expand Up @@ -94,7 +94,7 @@ private boolean isDefaultGroup(Optional<GroupTreeNode> groups) {
if (!groupRoot.getChildren().isEmpty()) {
return false;
}
return groupRoot.getGroup().equals(DefaultGroupsFactory.getAllEntriesGroup());
return groupRoot.getGroup().equals(GroupsFactory.createAllEntriesGroup());
}

/**
Expand Down
Loading