Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Right click create group #11476

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
910c857
Auto-Select Newly Created Group
m-peeler Jul 5, 2024
cbc0d7d
Update CHANGELOG.md
m-peeler Jul 5, 2024
f126974
Implemented "Current selection" group option
m-peeler Jul 5, 2024
e4c2281
Addressed Style and Property Name Errors
m-peeler Jul 5, 2024
9b4d2db
Created 'Create Group From Selection' action
m-peeler Jul 5, 2024
9631067
Merge branch 'focus-group-on-creation' into right-click-create-group
m-peeler Jul 5, 2024
d4222a7
Merge branch 'new-group-from-selected' into right-click-create-group
m-peeler Jul 5, 2024
faca154
Worked to implement right-click-to-make-group functionality
m-peeler Jul 7, 2024
ca5e69f
Merge branch 'focus-group-on-creation'
m-peeler Jul 7, 2024
3a6037e
Feature added: Right Click on entries to create group from selection
m-peeler Jul 9, 2024
8dd474a
Update CHANGELOG.md
m-peeler Jul 9, 2024
12dedd4
Merge branch 'main' into right-click-create-group
m-peeler Jul 9, 2024
2c87cda
Merge branch 'main' of https://github.com/JabRef/jabref
m-peeler Jul 9, 2024
f3011ed
Merge branch 'main' into right-click-create-group
m-peeler Jul 9, 2024
53f1544
Update CHANGELOG.md
m-peeler Jul 9, 2024
ec9b081
Update CHANGELOG.md
m-peeler Jul 10, 2024
aabb4a3
Fixed formatting issues & addressed test failures
m-peeler Jul 10, 2024
f654aba
Merge branch 'right-click-create-group' of https://github.com/m-peele…
m-peeler Jul 10, 2024
d772aaa
Fixed unnecessary module
m-peeler Jul 10, 2024
d3e1f1e
Style & Bug Fixes
m-peeler Jul 10, 2024
e4ec775
Inverted conditional & removed unnecessary dependency
m-peeler Jul 10, 2024
fd088d1
Merge branch 'main' into right-click-create-group
Siedlerchr Jul 10, 2024
e2ad784
Added "Add Subgroup from Selection" to groups context menu.
m-peeler Jul 10, 2024
cf33b73
Merge branch 'right-click-create-group' of https://github.com/m-peele…
m-peeler Jul 10, 2024
85d42b9
Fixed text comparison issue
m-peeler Jul 10, 2024
ea49e46
Merge branch 'main' of https://github.com/JabRef/jabref
m-peeler Jul 11, 2024
00de24b
Fixed bad bindings
m-peeler Jul 11, 2024
a1dfe75
Removed accidential imports
m-peeler Jul 11, 2024
77f927b
Reverted Main Table Context-Menu change; Added 'include selected' che…
m-peeler Jul 11, 2024
f80e515
Discard changes to src/main/java/org/jabref/gui/exporter/ExportComman…
koppor Jul 12, 2024
c5241f0
Bug fixes, variable ordering & unnecessary change reversions
m-peeler Jul 13, 2024
bba0522
Merge branch 'right-click-create-group' of https://github.com/m-peele…
m-peeler Jul 13, 2024
1912281
Update src/main/java/org/jabref/gui/groups/GroupDialog.fxml
m-peeler Jul 13, 2024
4931eac
Removed context menu option, disabled 'include selected' when editing…
m-peeler Jul 13, 2024
f928a36
Fixed imports
m-peeler Jul 13, 2024
93f2df5
Merge branch 'main' into right-click-create-group
Siedlerchr Jul 24, 2024
0367f7b
Merge branch 'main' into right-click-create-group
koppor Aug 4, 2024
e87af8e
Merge branch 'main' into right-click-create-group
m-peeler Sep 28, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv

### Added

- We added the ability to add the current selection to a newly created group. [#11449](https://github.com/JabRef/jabref/issues/11449)
- We added support for selecting and using CSL Styles in JabRef's OpenOffice/LibreOffice integration for inserting bibliographic and in-text citations into a document. [#2146](https://github.com/JabRef/jabref/issues/2146), [#8893](https://github.com/JabRef/jabref/issues/8893)
- We added Tools > New library based on references in PDF file... to create a new library based on the references section in a PDF file. [#11522](https://github.com/JabRef/jabref/pull/11522)
- When converting the references section of a paper (PDF file), more than the last page is treated. [#11522](https://github.com/JabRef/jabref/pull/11522)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
// endregion

provides org.tinylog.writers.Writer
with org.jabref.gui.logging.GuiWriter;
with org.jabref.gui.logging.GuiWriter;

// Preferences and XML
requires java.prefs;
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/org/jabref/gui/StateManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ public class StateManager {
private final ObservableList<String> searchHistory = FXCollections.observableArrayList();

public StateManager() {
activeGroups.bind(Bindings.valueAt(selectedGroups, activeDatabase.orElseOpt(null).map(BibDatabaseContext::getUid)));
koppor marked this conversation as resolved.
Show resolved Hide resolved
activeGroups.bind(Bindings.valueAt(
selectedGroups,
activeDatabase
.orElseOpt(null)
.map(BibDatabaseContext::getUid))
.orElse(FXCollections.observableArrayList()));
}

public ObservableList<SidePaneType> getVisibleSidePaneComponents() {
Expand Down Expand Up @@ -162,6 +167,7 @@ public void setActiveDatabase(BibDatabaseContext database) {
LOGGER.info("No open database detected");
activeDatabaseProperty().set(Optional.empty());
} else {
selectedGroups.computeIfAbsent(database.getUid(), k -> FXCollections.emptyObservableList());
activeDatabaseProperty().set(Optional.of(database));
}
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/jabref/gui/actions/StandardActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public enum StandardActions implements Action {
EXTRACT_FILE_REFERENCES_OFFLINE(Localization.lang("Extract references from file (offline)"), IconTheme.JabRefIcons.FILE_STAR),
OPEN_URL(Localization.lang("Open URL or DOI"), IconTheme.JabRefIcons.WWW, KeyBinding.OPEN_URL_OR_DOI),
SEARCH_SHORTSCIENCE(Localization.lang("Search ShortScience")),
ADD_SUBGROUP_FROM_SELECTION(Localization.lang("Add subgroup from selection")),
MERGE_WITH_FETCHED_ENTRY(Localization.lang("Get bibliographic data from %0", "DOI/ISBN/...")),
ATTACH_FILE(Localization.lang("Attach file"), IconTheme.JabRefIcons.ATTACH_FILE),
ATTACH_FILE_FROM_URL(Localization.lang("Attach file from URL"), IconTheme.JabRefIcons.DOWNLOAD_FILE),
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/jabref/gui/exporter/ExportCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import javafx.collections.FXCollections;
import javafx.stage.FileChooser;
import javafx.util.Duration;

Expand Down Expand Up @@ -111,7 +111,7 @@ private void export(Path file, FileChooser.ExtensionFilter selectedExtensionFilt
// All entries
entries = stateManager.getActiveDatabase()
.map(BibDatabaseContext::getEntries)
.orElse(Collections.emptyList());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change needed? I checked the caller - and it seems it is passed to org.jabref.logic.exporter.Exporter#export(org.jabref.model.database.BibDatabaseContext, java.nio.file.Path, java.util.List<org.jabref.model.entry.BibEntry>, java.util.List<java.nio.file.Path>, org.jabref.logic.journals.JournalAbbreviationRepository), which requires a list and nothing observable.

I would even try to use toList() since the list should not be modified (should it?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I just did this because the function signature changed (from Optional<List<..>> to Optional<ObservableList<...>> and I was trying to minimally fix to comply. Will add in the toList call and change it back.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will just revert and see if the CI is green.

Reason: BibDatbase context code:

    public List<BibEntry> getEntries() {
        return database.getEntries();
    }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did my revert go through, because I did not see it?

Please double check that this file is not changed!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per my earlier comment -

This push changes the method signature of getEntries() (since it was already an ObservableList and something needed to be able to bind to it). Removing the .map(List::stream).map(Stream::toList) causes compile errors and seems to be the reason tests are currently failing. I've changed it to instead do .orElse(FXCollections.emptyObservableList()) and that seems to address the compile issue.

.orElse(FXCollections.emptyObservableList());
}

List<Path> fileDirForDatabase = stateManager.getActiveDatabase()
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/jabref/gui/groups/GroupDialog.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@
</VBox>
<Separator orientation="VERTICAL"/>
<StackPane HBox.hgrow="ALWAYS">
<VBox visible="${explicitRadioButton.selected}" spacing="10.0">
<CheckBox fx:id="explicitIncludeSelected" text="%Include selected entries in created subgroup"/>
</VBox>
<VBox visible="${keywordsRadioButton.selected}" spacing="10.0">
<VBox>
<Label text="%Field"/>
Expand Down
32 changes: 25 additions & 7 deletions src/main/java/org/jabref/gui/groups/GroupDialogView.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@
import org.jabref.gui.help.HelpAction;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.icon.JabrefIconProvider;
import org.jabref.gui.maintable.Selection;
import org.jabref.gui.util.BaseDialog;
import org.jabref.gui.util.IconValidationDecorator;
import org.jabref.gui.util.ViewModelListCellFactory;
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;
Expand Down Expand Up @@ -83,6 +85,8 @@ public class GroupDialogView extends BaseDialog<AbstractGroup> {
@FXML private RadioButton texRadioButton;

// Option Groups
@FXML private CheckBox explicitIncludeSelected;

@FXML private TextField keywordGroupSearchTerm;
@FXML private TextField keywordGroupSearchField;
@FXML private CheckBox keywordGroupCaseSensitive;
Expand All @@ -109,6 +113,8 @@ public class GroupDialogView extends BaseDialog<AbstractGroup> {
private final BibDatabaseContext currentDatabase;
private final @Nullable GroupTreeNode parentNode;
private final @Nullable AbstractGroup editedGroup;
private final List<BibEntry> selectedEntries;
private final Selection includeSelectedEntries;

private GroupDialogViewModel viewModel;

Expand All @@ -119,10 +125,15 @@ public class GroupDialogView extends BaseDialog<AbstractGroup> {
public GroupDialogView(BibDatabaseContext currentDatabase,
@Nullable GroupTreeNode parentNode,
@Nullable AbstractGroup editedGroup,
GroupDialogHeader groupDialogHeader) {
GroupDialogHeader groupDialogHeader,
List<BibEntry> selectedEntries,
Selection includeSelectedEntries
) {
this.currentDatabase = currentDatabase;
this.parentNode = parentNode;
this.editedGroup = editedGroup;
this.selectedEntries = selectedEntries;
this.includeSelectedEntries = includeSelectedEntries;

ViewLoader.view(this)
.load()
Expand Down Expand Up @@ -172,7 +183,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, includeSelectedEntries);

setResultConverter(viewModel::resultConverter);

Expand Down Expand Up @@ -201,6 +212,9 @@ public void initialize() {
autoRadioButton.selectedProperty().bindBidirectional(viewModel.typeAutoProperty());
texRadioButton.selectedProperty().bindBidirectional(viewModel.typeTexProperty());

explicitIncludeSelected.selectedProperty().bindBidirectional(viewModel.explicitIncludeSelectedProperty());
explicitIncludeSelected.disableProperty().bindBidirectional(viewModel.editingGroupProperty());

keywordGroupSearchTerm.textProperty().bindBidirectional(viewModel.keywordGroupSearchTermProperty());
keywordGroupSearchField.textProperty().bindBidirectional(viewModel.keywordGroupSearchFieldProperty());
keywordGroupCaseSensitive.selectedProperty().bindBidirectional(viewModel.keywordGroupCaseSensitiveProperty());
Expand Down Expand Up @@ -247,7 +261,7 @@ public void initialize() {
validationVisualizer.initVisualization(viewModel.keywordRegexValidationStatus(), keywordGroupSearchTerm);
validationVisualizer.initVisualization(viewModel.keywordSearchTermEmptyValidationStatus(), keywordGroupSearchTerm);
validationVisualizer.initVisualization(viewModel.keywordFieldEmptyValidationStatus(), keywordGroupSearchField);
validationVisualizer.initVisualization(viewModel.texGroupFilePathValidatonStatus(), texGroupFilePath);
validationVisualizer.initVisualization(viewModel.texGroupFilePathValidationStatus(), texGroupFilePath);
nameField.requestFocus();
});

Expand All @@ -261,10 +275,14 @@ public void initialize() {
viewModel.colorFieldProperty().setValue(IconTheme.getDefaultGroupColor());
return;
}
List<Color> colorsOfSiblings = parentNode.getChildren().stream().map(child -> child.getGroup().getColor())
.flatMap(Optional::stream)
.toList();
Optional<Color> parentColor = parentGroup().getColor();

List<Color> colorsOfSiblings = parentNode.getChildren()
.stream()
.map(GroupTreeNode::getGroup)
.map(AbstractGroup::getColor)
.flatMap(Optional::stream)
.toList();
Optional<Color> parentColor = parentNode.getGroup().getColor();
Color color;
color = parentColor.map(value -> GroupColorPicker.generateColor(colorsOfSiblings, value)).orElseGet(() -> GroupColorPicker.generateColor(colorsOfSiblings));
viewModel.colorFieldProperty().setValue(color);
Expand Down
59 changes: 45 additions & 14 deletions src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import org.jabref.gui.DialogService;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.maintable.Selection;
import org.jabref.gui.util.FileDialogConfiguration;
import org.jabref.logic.auxparser.DefaultAuxParser;
import org.jabref.logic.groups.DefaultGroupsFactory;
Expand All @@ -33,6 +34,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;
Expand Down Expand Up @@ -77,6 +79,10 @@ public class GroupDialogViewModel {
private final BooleanProperty typeAutoProperty = new SimpleBooleanProperty();
private final BooleanProperty typeTexProperty = new SimpleBooleanProperty();

// Explicit Groups
private final BooleanProperty explicitIncludeSelectedProperty = new SimpleBooleanProperty(false);
private final BooleanProperty editingGroupProperty = new SimpleBooleanProperty(false);

// Option Groups
private final StringProperty keywordGroupSearchTermProperty = new SimpleStringProperty("");
private final StringProperty keywordGroupSearchFieldProperty = new SimpleStringProperty("");
Expand Down Expand Up @@ -112,24 +118,42 @@ public class GroupDialogViewModel {
private final AbstractGroup editedGroup;
private final GroupTreeNode parentNode;
private final FileUpdateMonitor fileUpdateMonitor;
private final List<BibEntry> selectedEntries;
private final Selection includeSelectedEntries;

public GroupDialogViewModel(DialogService dialogService,
BibDatabaseContext currentDatabase,
PreferencesService preferencesService,
@Nullable AbstractGroup editedGroup,
@Nullable GroupTreeNode parentNode,
FileUpdateMonitor fileUpdateMonitor) {
FileUpdateMonitor fileUpdateMonitor,
List<BibEntry> selectedEntries,
Selection includeSelectedEntries
) {
this.dialogService = dialogService;
this.preferencesService = preferencesService;
this.currentDatabase = currentDatabase;
this.editedGroup = editedGroup;
this.parentNode = parentNode;
this.fileUpdateMonitor = fileUpdateMonitor;
this.selectedEntries = selectedEntries;
this.includeSelectedEntries = includeSelectedEntries;

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<>(), Selection.IGNORE_SELECTED_ENTRIES);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

USe List.of() instead of new ArrayList<>()

}

private void setupValidation() {
validator = new CompositeValidator();

Expand Down Expand Up @@ -246,7 +270,7 @@ private void setupValidation() {
return false;
}
return FileUtil.getFileExtension(input)
.map(extension -> "aux".equalsIgnoreCase(extension))
.map("aux"::equalsIgnoreCase)
.orElse(false);
}
},
Expand Down Expand Up @@ -311,9 +335,13 @@ public AbstractGroup resultConverter(ButtonType button) {
String groupName = nameProperty.getValue().trim();
if (typeExplicitProperty.getValue()) {
resultingGroup = new ExplicitGroup(
groupName,
groupHierarchySelectedProperty.getValue(),
preferencesService.getBibEntryPreferences().getKeywordSeparator());
groupName,
groupHierarchySelectedProperty.getValue(),
preferencesService.getBibEntryPreferences().getKeywordSeparator()
);
if (explicitIncludeSelectedProperty.getValue()) {
((ExplicitGroup) resultingGroup).add(selectedEntries);
}
} else if (typeKeywordsProperty.getValue()) {
if (keywordGroupRegexProperty.getValue()) {
resultingGroup = new RegexKeywordGroup(
Expand Down Expand Up @@ -372,7 +400,6 @@ public AbstractGroup resultConverter(ButtonType button) {
fileUpdateMonitor,
currentDatabase.getMetaData());
}

if (resultingGroup != null) {
preferencesService.getGroupsPreferences().setDefaultHierarchicalContext(groupHierarchySelectedProperty.getValue());

Expand All @@ -391,7 +418,7 @@ public AbstractGroup resultConverter(ButtonType button) {

public void setValues() {
groupHierarchyListProperty.setValue(FXCollections.observableArrayList(GroupHierarchyType.values()));

explicitIncludeSelectedProperty.setValue(includeSelectedEntries == Selection.INCLUDE_SELECTED_ENTRIES || preferencesService.getGroupsPreferences().shouldAutoIncludeSelected());
if (editedGroup == null) {
// creating new group -> defaults!
// TODO: Create default group (via org.jabref.logic.groups.DefaultGroupsFactory) and use values
Expand All @@ -415,6 +442,7 @@ public void setValues() {
descriptionProperty.setValue(editedGroup.getDescription().orElse(""));
iconProperty.setValue(editedGroup.getIconName().orElse(""));
groupHierarchySelectedProperty.setValue(editedGroup.getHierarchicalContext());
editingGroupProperty.setValue(true);

if (editedGroup.getClass() == WordKeywordGroup.class) {
typeKeywordsProperty.setValue(true);
Expand Down Expand Up @@ -454,11 +482,6 @@ public void setValues() {
autoGroupPersonsOptionProperty.setValue(Boolean.TRUE);
autoGroupPersonsFieldProperty.setValue(group.getField().getName());
}
} else if (editedGroup.getClass() == TexGroup.class) {
typeTexProperty.setValue(true);

TexGroup group = (TexGroup) editedGroup;
texGroupFilePathProperty.setValue(group.getFilePath().toString());
}
}
}
Expand Down Expand Up @@ -492,7 +515,7 @@ public void texGroupBrowse() {
}

private List<Path> getFileDirectoriesAsPaths() {
List<Path> fileDirs = new ArrayList<>();
List<Path> fileDirs = List.of();
MetaData metaData = currentDatabase.getMetaData();
metaData.getLatexFileDirectory(preferencesService.getFilePreferences().getUserAndHost()).ifPresent(fileDirs::add);

Expand Down Expand Up @@ -535,7 +558,7 @@ public ValidationStatus keywordSearchTermEmptyValidationStatus() {
return keywordSearchTermEmptyValidator.getValidationStatus();
}

public ValidationStatus texGroupFilePathValidatonStatus() {
public ValidationStatus texGroupFilePathValidationStatus() {
return texGroupFilePathValidator.getValidationStatus();
}

Expand Down Expand Up @@ -587,6 +610,14 @@ public BooleanProperty typeTexProperty() {
return typeTexProperty;
}

public BooleanProperty explicitIncludeSelectedProperty() {
return explicitIncludeSelectedProperty;
}

public BooleanProperty editingGroupProperty() {
return editingGroupProperty;
}

public StringProperty keywordGroupSearchTermProperty() {
return keywordGroupSearchTermProperty;
}
Expand Down
Loading