diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b6c5291bcb..59da38137df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - We added an exporter and improved the importer for Endnote XML format. [#11137](https://github.com/JabRef/jabref/issues/11137) - We added support for using BibTeX Style files (BST) in the Preview. [#11102](https://github.com/JabRef/jabref/issues/11102) - We added support for automatically update LaTeX citations when a LaTeX file is created, removed, or modified. [#10585](https://github.com/JabRef/jabref/issues/10585) +- We added the ability to add the current selection to a newly created group. [#11449](https://github.com/JabRef/jabref/issues/11449) ### Changed diff --git a/src/main/java/org/jabref/gui/groups/GroupDialog.fxml b/src/main/java/org/jabref/gui/groups/GroupDialog.fxml index 02b19876250..cb26bcf91e4 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialog.fxml +++ b/src/main/java/org/jabref/gui/groups/GroupDialog.fxml @@ -99,6 +99,12 @@ + + + + + diff --git a/src/main/java/org/jabref/gui/groups/GroupDialogView.java b/src/main/java/org/jabref/gui/groups/GroupDialogView.java index b06c26503b1..4a0d72e0cd3 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialogView.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialogView.java @@ -41,6 +41,7 @@ import org.jabref.logic.help.HelpFile; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.BibEntry; import org.jabref.model.groups.AbstractGroup; import org.jabref.model.groups.GroupHierarchyType; import org.jabref.model.groups.GroupTreeNode; @@ -81,6 +82,7 @@ public class GroupDialogView extends BaseDialog { @FXML private RadioButton searchRadioButton; @FXML private RadioButton autoRadioButton; @FXML private RadioButton texRadioButton; + @FXML private RadioButton selectionRadioButton; // Option Groups @FXML private TextField keywordGroupSearchTerm; @@ -109,6 +111,7 @@ public class GroupDialogView extends BaseDialog { private final BibDatabaseContext currentDatabase; private final @Nullable GroupTreeNode parentNode; private final @Nullable AbstractGroup editedGroup; + private final List selectedEntries; private GroupDialogViewModel viewModel; @@ -119,10 +122,12 @@ public class GroupDialogView extends BaseDialog { public GroupDialogView(BibDatabaseContext currentDatabase, @Nullable GroupTreeNode parentNode, @Nullable AbstractGroup editedGroup, - GroupDialogHeader groupDialogHeader) { + GroupDialogHeader groupDialogHeader, + List selectedEntries) { this.currentDatabase = currentDatabase; this.parentNode = parentNode; this.editedGroup = editedGroup; + this.selectedEntries = selectedEntries; ViewLoader.view(this) .load() @@ -172,7 +177,7 @@ public GroupDialogView(BibDatabaseContext currentDatabase, @FXML public void initialize() { - viewModel = new GroupDialogViewModel(dialogService, currentDatabase, preferencesService, editedGroup, parentNode, fileUpdateMonitor); + viewModel = new GroupDialogViewModel(dialogService, currentDatabase, preferencesService, editedGroup, parentNode, fileUpdateMonitor, selectedEntries); setResultConverter(viewModel::resultConverter); @@ -200,6 +205,8 @@ public void initialize() { searchRadioButton.selectedProperty().bindBidirectional(viewModel.typeSearchProperty()); autoRadioButton.selectedProperty().bindBidirectional(viewModel.typeAutoProperty()); texRadioButton.selectedProperty().bindBidirectional(viewModel.typeTexProperty()); + selectionRadioButton.selectedProperty().bindBidirectional(viewModel.typeSelectionProperty()); + selectionRadioButton.disableProperty().bind(viewModel.entriesAreSelectedProperty().not()); keywordGroupSearchTerm.textProperty().bindBidirectional(viewModel.keywordGroupSearchTermProperty()); keywordGroupSearchField.textProperty().bindBidirectional(viewModel.keywordGroupSearchFieldProperty()); diff --git a/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java b/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java index 73f671e65e2..20cee1d176a 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java @@ -33,6 +33,7 @@ import org.jabref.logic.util.io.FileUtil; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.Keyword; import org.jabref.model.entry.field.FieldFactory; import org.jabref.model.groups.AbstractGroup; @@ -76,6 +77,7 @@ public class GroupDialogViewModel { private final BooleanProperty typeSearchProperty = new SimpleBooleanProperty(); private final BooleanProperty typeAutoProperty = new SimpleBooleanProperty(); private final BooleanProperty typeTexProperty = new SimpleBooleanProperty(); + private final BooleanProperty typeSelectionProperty = new SimpleBooleanProperty(); // Option Groups private final StringProperty keywordGroupSearchTermProperty = new SimpleStringProperty(""); @@ -94,6 +96,7 @@ public class GroupDialogViewModel { private final StringProperty autoGroupPersonsFieldProperty = new SimpleStringProperty(""); private final StringProperty texGroupFilePathProperty = new SimpleStringProperty(""); + private final BooleanProperty entriesAreSelected = new SimpleBooleanProperty(false); private Validator nameValidator; private Validator nameContainsDelimiterValidator; @@ -112,24 +115,38 @@ public class GroupDialogViewModel { private final AbstractGroup editedGroup; private final GroupTreeNode parentNode; private final FileUpdateMonitor fileUpdateMonitor; + private final List selectedEntries; public GroupDialogViewModel(DialogService dialogService, BibDatabaseContext currentDatabase, PreferencesService preferencesService, @Nullable AbstractGroup editedGroup, @Nullable GroupTreeNode parentNode, - FileUpdateMonitor fileUpdateMonitor) { + FileUpdateMonitor fileUpdateMonitor, + List selectedEntries) { this.dialogService = dialogService; this.preferencesService = preferencesService; this.currentDatabase = currentDatabase; this.editedGroup = editedGroup; this.parentNode = parentNode; this.fileUpdateMonitor = fileUpdateMonitor; + this.selectedEntries = selectedEntries; setupValidation(); setValues(); } + public GroupDialogViewModel( + DialogService dialogService, + BibDatabaseContext currentDatabase, + PreferencesService preferencesService, + @Nullable AbstractGroup editedGroup, + @Nullable GroupTreeNode parentNode, + FileUpdateMonitor fileUpdateMonitor + ) { + this(dialogService, currentDatabase, preferencesService, editedGroup, parentNode, fileUpdateMonitor, new ArrayList<>()); + } + private void setupValidation() { validator = new CompositeValidator(); @@ -371,6 +388,14 @@ public AbstractGroup resultConverter(ButtonType button) { new DefaultAuxParser(new BibDatabase()), fileUpdateMonitor, currentDatabase.getMetaData()); + } else if (typeSelectionProperty.getValue()) { + ExplicitGroup tempResultingGroup = new ExplicitGroup( + groupName, + groupHierarchySelectedProperty.getValue(), + preferencesService.getBibEntryPreferences().getKeywordSeparator() + ); + tempResultingGroup.add(selectedEntries); + resultingGroup = tempResultingGroup; } if (resultingGroup != null) { @@ -405,7 +430,16 @@ public void setValues() { .ifPresent(iconProperty::setValue); parentNode.getGroup().getColor().ifPresent(color -> colorUseProperty.setValue(true)); } - typeExplicitProperty.setValue(true); + if (!selectedEntries.isEmpty()) { + entriesAreSelected.setValue(true); + if (selectedEntries.size() > 1) { + typeSelectionProperty.setValue(true); + } else { + typeExplicitProperty.setValue(true); + } + } else { + typeExplicitProperty.setValue(true); + } groupHierarchySelectedProperty.setValue(preferencesService.getGroupsPreferences().getDefaultHierarchicalContext()); autoGroupKeywordsOptionProperty.setValue(Boolean.TRUE); } else { @@ -587,6 +621,10 @@ public BooleanProperty typeTexProperty() { return typeTexProperty; } + public BooleanProperty typeSelectionProperty() { + return typeSelectionProperty; + } + public StringProperty keywordGroupSearchTermProperty() { return keywordGroupSearchTermProperty; } @@ -638,4 +676,8 @@ public StringProperty autoGroupPersonsFieldProperty() { public StringProperty texGroupFilePathProperty() { return texGroupFilePathProperty; } + + public BooleanProperty entriesAreSelectedProperty() { + return entriesAreSelected; + } } diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeView.java b/src/main/java/org/jabref/gui/groups/GroupTreeView.java index a200d03c045..814ae2ed4e8 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeView.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeView.java @@ -399,7 +399,7 @@ private void updateSelection(List> newSelectedGroup } private void selectNode(GroupNodeViewModel value) { - selectNode(value, false); + selectNode(value, true); } private void selectNode(GroupNodeViewModel value, boolean expandParents) { diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java b/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java index de0c579699b..4dbbc4d68f4 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java @@ -175,7 +175,9 @@ public void addNewSubgroup(GroupNodeViewModel parent, GroupDialogHeader groupDia database, parent.getGroupNode(), null, - groupDialogHeader)); + groupDialogHeader, + stateManager.getSelectedEntries() + )); newGroup.ifPresent(group -> { parent.addSubgroup(group); @@ -260,7 +262,9 @@ public void editGroup(GroupNodeViewModel oldGroup) { database, oldGroup.getGroupNode().getParent().orElse(null), oldGroup.getGroupNode().getGroup(), - GroupDialogHeader.SUBGROUP)); + GroupDialogHeader.SUBGROUP, + stateManager.getSelectedEntries() + )); newGroup.ifPresent(group -> { AbstractGroup oldGroupDef = oldGroup.getGroupNode().getGroup(); diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 70307993aca..e4f5facb83f 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2649,3 +2649,5 @@ Note\:\ The\ study\ directory\ should\ be\ empty.=Note: The study directory shou Warning\:\ The\ selected\ directory\ is\ not\ empty.=Warning: The selected directory is not empty. Warning\:\ Failed\ to\ check\ if\ the\ directory\ is\ empty.=Warning: Failed to check if the directory is empty. Warning\:\ The\ selected\ directory\ is\ not\ a\ valid\ directory.=Warning: The selected directory is not a valid directory. +Current\ selection=Current selection +Group\ all\ entries\ currently\ selected=Group all entries currently selected