diff --git a/CHANGELOG.md b/CHANGELOG.md index b4fd6578a7d..448889bf7f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve ### Changed - We refined the 'main directory not found' error message. [#9625](https://github.com/JabRef/jabref/pull/9625) +- We modified the `Add Group` dialog to use the most recently selected group hierarchical context [#9141](https://github.com/JabRef/jabref/issues/9141) diff --git a/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java b/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java index 9e885ec718c..52760352acb 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java @@ -364,6 +364,8 @@ public AbstractGroup resultConverter(ButtonType button) { } if (resultingGroup != null) { + preferencesService.getGroupsPreferences().setDefaultHierarchicalContext(groupHierarchySelectedProperty.getValue()); + resultingGroup.setColor(colorProperty.getValue()); resultingGroup.setDescription(descriptionProperty.getValue()); resultingGroup.setIconName(iconProperty.getValue()); @@ -384,7 +386,7 @@ public void setValues() { // creating new group -> defaults! colorProperty.setValue(IconTheme.getDefaultGroupColor()); typeExplicitProperty.setValue(true); - groupHierarchySelectedProperty.setValue(GroupHierarchyType.INDEPENDENT); + groupHierarchySelectedProperty.setValue(preferencesService.getGroupsPreferences().getDefaultHierarchicalContext()); } else { nameProperty.setValue(editedGroup.getName()); colorProperty.setValue(editedGroup.getColor().orElse(IconTheme.getDefaultGroupColor())); diff --git a/src/main/java/org/jabref/gui/groups/GroupsPreferences.java b/src/main/java/org/jabref/gui/groups/GroupsPreferences.java index 849f7dc808a..e83d5546daa 100644 --- a/src/main/java/org/jabref/gui/groups/GroupsPreferences.java +++ b/src/main/java/org/jabref/gui/groups/GroupsPreferences.java @@ -5,19 +5,24 @@ import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; +import org.jabref.model.groups.GroupHierarchyType; + public class GroupsPreferences { private final ObjectProperty groupViewMode; private final BooleanProperty shouldAutoAssignGroup; private final BooleanProperty shouldDisplayGroupCount; + private final ObjectProperty defaultHierarchicalContext; public GroupsPreferences(GroupViewMode groupViewMode, boolean shouldAutoAssignGroup, - boolean shouldDisplayGroupCount) { + boolean shouldDisplayGroupCount, + GroupHierarchyType defaultHierarchicalContext) { this.groupViewMode = new SimpleObjectProperty<>(groupViewMode); this.shouldAutoAssignGroup = new SimpleBooleanProperty(shouldAutoAssignGroup); this.shouldDisplayGroupCount = new SimpleBooleanProperty(shouldDisplayGroupCount); + this.defaultHierarchicalContext = new SimpleObjectProperty<>(defaultHierarchicalContext); } public GroupViewMode getGroupViewMode() { @@ -55,4 +60,16 @@ public BooleanProperty displayGroupCountProperty() { public void setDisplayGroupCount(boolean shouldDisplayGroupCount) { this.shouldDisplayGroupCount.set(shouldDisplayGroupCount); } + + public GroupHierarchyType getDefaultHierarchicalContext() { + return defaultHierarchicalContext.get(); + } + + public ObjectProperty defaultHierarchicalContextProperty() { + return defaultHierarchicalContext; + } + + public void setDefaultHierarchicalContext(GroupHierarchyType defaultHierarchicalContext) { + this.defaultHierarchicalContext.set(defaultHierarchicalContext); + } } diff --git a/src/main/java/org/jabref/model/groups/GroupHierarchyType.java b/src/main/java/org/jabref/model/groups/GroupHierarchyType.java index 38879112526..63755975d5c 100644 --- a/src/main/java/org/jabref/model/groups/GroupHierarchyType.java +++ b/src/main/java/org/jabref/model/groups/GroupHierarchyType.java @@ -5,17 +5,23 @@ public enum GroupHierarchyType { /** * Group's contents are independent of its hierarchical position. */ - INDEPENDENT, + INDEPENDENT("Independent"), /** * Group's content is the intersection of its own content with its supergroup's content. */ - REFINING, // INTERSECTION + REFINING("Intersection"), // INTERSECTION /** * Group's content is the union of its own content with its subgroups' content. */ - INCLUDING; // UNION + INCLUDING("Union"); // UNION + + private final String displayName; + + GroupHierarchyType(String displayName) { + this.displayName = displayName; + } /** * Returns the hierarchy type from its position in this enum. @@ -29,4 +35,8 @@ public static GroupHierarchyType getByNumberOrDefault(int type) { return INDEPENDENT; } } + + public String getDisplayName() { + return displayName; + } } diff --git a/src/main/java/org/jabref/preferences/JabRefPreferences.java b/src/main/java/org/jabref/preferences/JabRefPreferences.java index 0db7cef661f..3ea8f83a45b 100644 --- a/src/main/java/org/jabref/preferences/JabRefPreferences.java +++ b/src/main/java/org/jabref/preferences/JabRefPreferences.java @@ -110,6 +110,7 @@ import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.types.EntryType; import org.jabref.model.entry.types.EntryTypeFactory; +import org.jabref.model.groups.GroupHierarchyType; import org.jabref.model.metadata.SaveOrderConfig; import org.jabref.model.search.rules.SearchRules; import org.jabref.model.strings.StringUtil; @@ -378,6 +379,7 @@ public class JabRefPreferences implements PreferencesService { // GroupViewMode private static final String GROUP_INTERSECT_UNION_VIEW_MODE = "groupIntersectUnionViewModes"; + private static final String DEFAULT_HIERARCHICAL_CONTEXT = "defaultHierarchicalContext"; // Dialog states private static final String PREFS_EXPORT_PATH = "prefsExportPath"; @@ -598,6 +600,7 @@ private JabRefPreferences() { defaults.put(AUTO_ASSIGN_GROUP, Boolean.TRUE); defaults.put(DISPLAY_GROUP_COUNT, Boolean.TRUE); defaults.put(GROUP_INTERSECT_UNION_VIEW_MODE, GroupViewMode.INTERSECTION.name()); + defaults.put(DEFAULT_HIERARCHICAL_CONTEXT, GroupHierarchyType.INDEPENDENT.name()); defaults.put(KEYWORD_SEPARATOR, ", "); defaults.put(DEFAULT_ENCODING, StandardCharsets.UTF_8.name()); defaults.put(DEFAULT_OWNER, System.getProperty("user.name")); @@ -1367,12 +1370,14 @@ public GroupsPreferences getGroupsPreferences() { groupsPreferences = new GroupsPreferences( GroupViewMode.valueOf(get(GROUP_INTERSECT_UNION_VIEW_MODE)), getBoolean(AUTO_ASSIGN_GROUP), - getBoolean(DISPLAY_GROUP_COUNT) + getBoolean(DISPLAY_GROUP_COUNT), + GroupHierarchyType.valueOf(get(DEFAULT_HIERARCHICAL_CONTEXT)) ); EasyBind.listen(groupsPreferences.groupViewModeProperty(), (obs, oldValue, newValue) -> put(GROUP_INTERSECT_UNION_VIEW_MODE, newValue.name())); EasyBind.listen(groupsPreferences.autoAssignGroupProperty(), (obs, oldValue, newValue) -> putBoolean(AUTO_ASSIGN_GROUP, newValue)); EasyBind.listen(groupsPreferences.displayGroupCountProperty(), (obs, oldValue, newValue) -> putBoolean(DISPLAY_GROUP_COUNT, newValue)); + EasyBind.listen(groupsPreferences.defaultHierarchicalContextProperty(), (obs, oldValue, newValue) -> put(DEFAULT_HIERARCHICAL_CONTEXT, newValue.name())); return groupsPreferences; } diff --git a/src/test/java/org/jabref/gui/groups/GroupDialogViewModelTest.java b/src/test/java/org/jabref/gui/groups/GroupDialogViewModelTest.java index c079ded5d5b..e7ea0f85d13 100644 --- a/src/test/java/org/jabref/gui/groups/GroupDialogViewModelTest.java +++ b/src/test/java/org/jabref/gui/groups/GroupDialogViewModelTest.java @@ -7,6 +7,7 @@ import org.jabref.gui.DialogService; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.groups.AbstractGroup; +import org.jabref.model.groups.GroupHierarchyType; import org.jabref.model.metadata.MetaData; import org.jabref.preferences.BibEntryPreferences; import org.jabref.preferences.FilePreferences; @@ -16,6 +17,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -28,21 +30,23 @@ class GroupDialogViewModelTest { private Path temporaryFolder; private BibDatabaseContext bibDatabaseContext; private final MetaData metaData = mock(MetaData.class); + private final GroupsPreferences groupsPreferences = mock(GroupsPreferences.class); + private final DialogService dialogService = mock(DialogService.class); + private final AbstractGroup group = mock(AbstractGroup.class); + private final PreferencesService preferencesService = mock(PreferencesService.class); @BeforeEach void setUp(@TempDir Path temporaryFolder) { this.temporaryFolder = temporaryFolder; bibDatabaseContext = new BibDatabaseContext(); - DialogService dialogService = mock(DialogService.class); - AbstractGroup group = mock(AbstractGroup.class); when(group.getName()).thenReturn("Group"); - PreferencesService preferencesService = mock(PreferencesService.class); when(preferencesService.getBibEntryPreferences()).thenReturn(mock(BibEntryPreferences.class)); when(preferencesService.getBibEntryPreferences().getKeywordSeparator()).thenReturn(','); when(preferencesService.getFilePreferences()).thenReturn(mock(FilePreferences.class)); when(preferencesService.getFilePreferences().getUser()).thenReturn("MockedUser"); + when(preferencesService.getGroupsPreferences()).thenReturn(groupsPreferences); bibDatabaseContext.setMetaData(metaData); @@ -78,4 +82,22 @@ void validateExistingRelativePath() throws Exception { viewModel.texGroupFilePathProperty().setValue(anAuxFile.toString()); assertTrue(viewModel.texGroupFilePathValidatonStatus().isValid()); } + + @Test + void testHierarchicalContextFromGroup() throws Exception { + GroupHierarchyType groupHierarchyType = GroupHierarchyType.INCLUDING; + when(group.getHierarchicalContext()).thenReturn(groupHierarchyType); + viewModel = new GroupDialogViewModel(dialogService, bibDatabaseContext, preferencesService, group, GroupDialogHeader.SUBGROUP); + + assertEquals(groupHierarchyType, viewModel.groupHierarchySelectedProperty().getValue()); + } + + @Test + void testDefaultHierarchicalContext() throws Exception { + GroupHierarchyType defaultHierarchicalContext = GroupHierarchyType.REFINING; + when(preferencesService.getGroupsPreferences().getDefaultHierarchicalContext()).thenReturn(defaultHierarchicalContext); + viewModel = new GroupDialogViewModel(dialogService, bibDatabaseContext, preferencesService, null, GroupDialogHeader.SUBGROUP); + + assertEquals(defaultHierarchicalContext, viewModel.groupHierarchySelectedProperty().getValue()); + } } diff --git a/src/test/java/org/jabref/gui/groups/GroupNodeViewModelTest.java b/src/test/java/org/jabref/gui/groups/GroupNodeViewModelTest.java index a6ed4ae899f..f05b398d285 100644 --- a/src/test/java/org/jabref/gui/groups/GroupNodeViewModelTest.java +++ b/src/test/java/org/jabref/gui/groups/GroupNodeViewModelTest.java @@ -47,7 +47,8 @@ void setUp() { when(preferencesService.getGroupsPreferences()).thenReturn(new GroupsPreferences( GroupViewMode.UNION, true, - true + true, + GroupHierarchyType.INDEPENDENT )); viewModel = getViewModelForGroup( diff --git a/src/test/java/org/jabref/gui/groups/GroupTreeViewModelTest.java b/src/test/java/org/jabref/gui/groups/GroupTreeViewModelTest.java index 72550c6642a..bdfe4b85bee 100644 --- a/src/test/java/org/jabref/gui/groups/GroupTreeViewModelTest.java +++ b/src/test/java/org/jabref/gui/groups/GroupTreeViewModelTest.java @@ -48,7 +48,8 @@ void setUp() { when(preferencesService.getGroupsPreferences()).thenReturn(new GroupsPreferences( GroupViewMode.UNION, true, - true)); + true, + GroupHierarchyType.INDEPENDENT)); groupTree = new GroupTreeViewModel(stateManager, mock(DialogService.class), preferencesService, taskExecutor, new CustomLocalDragboard()); }