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

Add select all buttons to change dialog #5803

Merged
merged 5 commits into from
Jan 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
72 changes: 49 additions & 23 deletions src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
import java.util.List;

import javafx.collections.FXCollections;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;

import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.util.BaseDialog;
Expand All @@ -21,47 +25,68 @@

class ChangeDisplayDialog extends BaseDialog<Boolean> {

private final ListView<DatabaseChangeViewModel> tree;
private final ListView<DatabaseChangeViewModel> changesList;
private final BorderPane infoPanel = new BorderPane();
private final CheckBox cb = new CheckBox(Localization.lang("Accept change"));

public ChangeDisplayDialog(BibDatabaseContext database, List<DatabaseChangeViewModel> changes) {
this.setTitle(Localization.lang("External changes"));
this.getDialogPane().setPrefSize(800, 600);

tree = new ListView<>(FXCollections.observableArrayList(changes));
tree.setPrefWidth(160);
EasyBind.subscribe(tree.getSelectionModel().selectedItemProperty(), this::selectedChangeChanged);
changesList = new ListView<>(FXCollections.observableArrayList(changes));
changesList.setPrefWidth(200);
EasyBind.subscribe(changesList.getSelectionModel().selectedItemProperty(), this::selectedChangeChanged);

SplitPane pane = new SplitPane();
pane.setDividerPositions(0.2);
ScrollPane scroll = new ScrollPane(tree);
scroll.setFitToHeight(true);
scroll.setFitToWidth(true);
pane.getItems().addAll(scroll, infoPanel);
pane.setResizableWithParent(scroll, false);

getDialogPane().setContent(pane);
Button selectAllChangesFromDisk = new Button(Localization.lang("Mark all changes as accepted"));
selectAllChangesFromDisk.setMinWidth(Region.USE_PREF_SIZE);
selectAllChangesFromDisk.setOnAction(evt -> {
for (DatabaseChangeViewModel change : changes) {
change.setAccepted(true);
}
});
Button unselectAllAcceptChanges = new Button(Localization.lang("Unmark all changes"));
unselectAllAcceptChanges.setOnAction(evt -> {
for (DatabaseChangeViewModel change : changes) {
change.setAccepted(false);
}
});

VBox leftContent = new VBox(changesList,
selectAllChangesFromDisk,
unselectAllAcceptChanges);

ScrollPane leftScroll = new ScrollPane(leftContent);
leftScroll.setFitToHeight(true);
leftScroll.setFitToWidth(true);

pane.getItems().addAll(leftScroll, infoPanel);
pane.setResizableWithParent(leftScroll, false);

getDialogPane().setContent(pane);

Label rootInfo = new Label(Localization.lang("Select the tree nodes to view and accept or reject changes") + '.');
infoPanel.setCenter(rootInfo);
tree.getSelectionModel().select(0);
changesList.getSelectionModel().selectFirst();

ButtonType dismissChanges = new ButtonType(Localization.lang("Dismiss changes"), ButtonBar.ButtonData.CANCEL_CLOSE);
getDialogPane().getButtonTypes().setAll(
new ButtonType(Localization.lang("Accept changes"), ButtonBar.ButtonData.APPLY),
dismissChanges
);
ButtonType dismissChanges = new ButtonType(Localization.lang("Dismiss"), ButtonData.CANCEL_CLOSE);

getDialogPane().getButtonTypes().setAll(new ButtonType(Localization.lang("Accept changes"), ButtonBar.ButtonData.APPLY),
dismissChanges);

setResultConverter(button -> {
if (button == dismissChanges) {
return false;

} else {
// Perform all accepted changes
NamedCompound ce = new NamedCompound(Localization.lang("Merged external changes"));
for (DatabaseChangeViewModel change : changes) {
if (change.isAccepted()) {
if (change instanceof EntryChangeViewModel) {
change.makeChange(database, ce); //We don't have a checkbox for accept and always get the correct merged entry, the accept property in this special case only controls the radio buttons selection
} else if (change.isAccepted()) {
change.makeChange(database, ce);
}
}
Expand All @@ -72,20 +97,21 @@ public ChangeDisplayDialog(BibDatabaseContext database, List<DatabaseChangeViewM
}
});

EasyBind.subscribe(cb.selectedProperty(), selected -> {
if ((selected != null) && (tree.getSelectionModel().getSelectedItem() != null)) {
tree.getSelectionModel().getSelectedItem().setAccepted(selected);
}
});
}

private void selectedChangeChanged(DatabaseChangeViewModel currentChange) {
if (currentChange != null) {
infoPanel.setCenter(currentChange.description());

if (!(currentChange instanceof EntryChangeViewModel)) {
cb.setManaged(true);
infoPanel.setBottom(cb);
cb.setSelected(currentChange.isAccepted());
cb.selectedProperty().bindBidirectional(currentChange.acceptedProperty());

} else {
cb.setManaged(false);
}

}
}
}
14 changes: 10 additions & 4 deletions src/main/java/org/jabref/gui/collab/DatabaseChangeViewModel.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jabref.gui.collab;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Node;

import org.jabref.gui.undo.NamedCompound;
Expand All @@ -8,7 +10,7 @@
abstract class DatabaseChangeViewModel {

protected String name;
private boolean accepted = true;
private BooleanProperty acceptedProperty = new SimpleBooleanProperty(true);

DatabaseChangeViewModel() {
name = "";
Expand All @@ -24,11 +26,15 @@ public String toString() {
}

public boolean isAccepted() {
return accepted;
return acceptedProperty.getValue();
}

public void setAccepted(boolean a) {
accepted = a;
public BooleanProperty acceptedProperty() {
return this.acceptedProperty;
}

public void setAccepted(boolean accepted) {
this.acceptedProperty.setValue(accepted);
}

/**
Expand Down
15 changes: 13 additions & 2 deletions src/main/java/org/jabref/gui/collab/EntryChangeViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ public EntryChangeViewModel(BibEntry entry, BibEntry newEntry, BibDatabaseContex

}

/**
* We override this here to select the radio buttons accordingly
*/
@Override
public void setAccepted(boolean accepted) {
super.setAccepted(accepted);
if (accepted) {
Copy link
Member

Choose a reason for hiding this comment

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

This is no longer needed now, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope, this is still needed. It ensures that when you click on "mark all changes" that the radio buttons on the right are selected and the merge entry will be the correct one.

mergePanel.selectAllRightRadioButtons();
} else {
mergePanel.selectAllLeftRadioButtons();
}
}

@Override
public void makeChange(BibDatabaseContext database, NamedCompound undoEdit) {
database.getDatabase().removeEntry(oldEntry);
Expand All @@ -49,9 +62,7 @@ public void makeChange(BibDatabaseContext database, NamedCompound undoEdit) {

@Override
public Node description() {

mergePanel = new MergeEntries(oldEntry, newEntry, Localization.lang("In JabRef"), Localization.lang("On disk"), DefaultRadioButtonSelectionMode.LEFT);

VBox container = new VBox(10);
Label header = new Label(name);
header.getStyleClass().add("sectionHeader");
Expand Down
58 changes: 45 additions & 13 deletions src/main/java/org/jabref/gui/mergeentries/MergeEntries.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
import javafx.collections.FXCollections;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
Expand Down Expand Up @@ -68,6 +70,8 @@ public class MergeEntries extends BorderPane {
private Boolean identicalTypes;
private List<RadioButton> typeRadioButtons;
private final DefaultRadioButtonSelectionMode defaultRadioButtonSelectionMode;
private final List<RadioButton> leftRadioButtons = new ArrayList<>();
private final List<RadioButton> rightRadioButtons = new ArrayList<>();

/**
* Constructor with optional column captions for the two entries
Expand Down Expand Up @@ -218,15 +222,20 @@ private void setupFieldRows(GridPane mergePanel) {
}
radioButtons.put(field, list);
if (leftString.isPresent()) {
leftRadioButtons.add(list.get(LEFT_RADIOBUTTON_INDEX));
list.get(LEFT_RADIOBUTTON_INDEX).setSelected(true);
if (!rightString.isPresent()) {
list.get(RIGHT_RADIOBUTTON_INDEX).setDisable(true);
} else if (this.defaultRadioButtonSelectionMode == DefaultRadioButtonSelectionMode.RIGHT) {
list.get(RIGHT_RADIOBUTTON_INDEX).setSelected(true);
rightRadioButtons.add(list.get(RIGHT_RADIOBUTTON_INDEX));
} else {
rightRadioButtons.add(list.get(RIGHT_RADIOBUTTON_INDEX));
}
} else {
list.get(LEFT_RADIOBUTTON_INDEX).setDisable(true);
list.get(RIGHT_RADIOBUTTON_INDEX).setSelected(true);
rightRadioButtons.add(list.get(RIGHT_RADIOBUTTON_INDEX));
}
}

Expand All @@ -242,46 +251,57 @@ private void setupFieldRows(GridPane mergePanel) {

private void setupEntryTypeRow(GridPane mergePanel) {
// Start with entry type
mergePanel.add(new Label(Localization.lang("Entry type")), 0, 1);

int rowIndex = 1;
mergePanel.add(new Label(Localization.lang("Entry type")), 0, rowIndex);
if (leftEntry.getType().equals(rightEntry.getType())) {
mergePanel.add(DiffHighlighting.forUnchanged(leftEntry.getType().getDisplayName()), 1, 1);
mergePanel.add(DiffHighlighting.forUnchanged(rightEntry.getType().getDisplayName()), 5, 1);
mergePanel.add(DiffHighlighting.forUnchanged(leftEntry.getType().getDisplayName()), 1, rowIndex);
mergePanel.add(DiffHighlighting.forUnchanged(rightEntry.getType().getDisplayName()), 5, rowIndex);
identicalTypes = true;
} else {
mergePanel.add(DiffHighlighting.forChanged(leftEntry.getType().getDisplayName()), 1, 1);
mergePanel.add(DiffHighlighting.forChanged(rightEntry.getType().getDisplayName()), 5, 1);
mergePanel.add(DiffHighlighting.forChanged(leftEntry.getType().getDisplayName()), 1, rowIndex);
mergePanel.add(DiffHighlighting.forChanged(rightEntry.getType().getDisplayName()), 5, rowIndex);
identicalTypes = false;
ToggleGroup group = new ToggleGroup();
typeRadioButtons = new ArrayList<>(2);

for (int k = 0; k < 3; k += 2) {
RadioButton button = new RadioButton();
EasyBind.subscribe(button.selectedProperty(), selected -> updateMergedEntry());
typeRadioButtons.add(button);
group.getToggles().add(button);
mergePanel.add(button, 2 + k, 1);
mergePanel.add(button, 2 + k, rowIndex);
}
if (defaultRadioButtonSelectionMode == DefaultRadioButtonSelectionMode.RIGHT) {
typeRadioButtons.get(1).setSelected(true); //This Radio Button list does not have a third option as compared to the fields, so do not use the constants here
rightRadioButtons.add(typeRadioButtons.get(1));
} else {
typeRadioButtons.get(0).setSelected(true);
leftRadioButtons.add(typeRadioButtons.get(0));
}
}
}

private void setupHeadingRows(GridPane mergePanel) {
// Set headings
for (int i = 0; i < NUMBER_OF_COLUMNS; i++) {
Label colHeading = new Label();
if (i == 2) {
colHeading.setGraphic(JabRefIcons.LEFT.getGraphicNode());
Button selectAllLeft = new Button();
selectAllLeft.setGraphic(JabRefIcons.LEFT.getGraphicNode());
selectAllLeft.setOnAction(evt -> this.selectAllLeftRadioButtons());
selectAllLeft.setTooltip(new Tooltip(Localization.lang("Select all changes on the left")));
mergePanel.add(selectAllLeft, i, 0);
} else if (i == 4) {
colHeading.setGraphic(JabRefIcons.RIGHT.getGraphicNode());
Button selectAllRight = new Button();
selectAllRight.setOnAction(evt -> this.selectAllRightRadioButtons());
selectAllRight.setGraphic(JabRefIcons.RIGHT.getGraphicNode());
selectAllRight.setTooltip(new Tooltip(Localization.lang("Select all changes on the right")));
mergePanel.add(selectAllRight, i, 0);
} else {
colHeading.setText(columnHeadings.get(i));
Label colHeading = new Label(columnHeadings.get(i));
colHeading.setMinWidth(USE_PREF_SIZE);
mergePanel.add(colHeading, i, 0);
}
colHeading.setMinWidth(USE_PREF_SIZE);
mergePanel.add(colHeading, i, 0);

}
}

Expand Down Expand Up @@ -349,6 +369,18 @@ private void updateFieldValues(Collection<Field> fields) {
}
}

public void selectAllRightRadioButtons() {
for (RadioButton radioButton : rightRadioButtons) {
radioButton.setSelected(true);
}
}

public void selectAllLeftRadioButtons() {
for (RadioButton radioButton : leftRadioButtons) {
radioButton.setSelected(true);
}
}

/**
* @return Merged BibEntry
*/
Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2091,3 +2091,10 @@ Special\ field\ type\ %0\ is\ unknown.\ Using\ normal\ column\ type.=Special fie
insert\ entries=insert entries
In\ JabRef=In JabRef
On\ disk=On disk

Select\ all\ changes\ on\ the\ left=Select all changes on the left
Select\ all\ changes\ on\ the\ right=Select all changes on the right

Dismiss=Dismiss
Mark\ all\ changes\ as\ accepted=Mark all changes as accepted
Unmark\ all\ changes=Unmark all changes