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

Rework external changes dialog in JavaFX #4693

Merged
merged 5 commits into from
Mar 12, 2019
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
26 changes: 7 additions & 19 deletions src/main/java/org/jabref/gui/BasePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import org.jabref.gui.autocompleter.PersonNameSuggestionProvider;
import org.jabref.gui.autocompleter.SuggestionProviders;
import org.jabref.gui.collab.DatabaseChangeMonitor;
import org.jabref.gui.collab.FileUpdatePanel;
import org.jabref.gui.collab.DatabaseChangePane;
import org.jabref.gui.desktop.JabRefDesktop;
import org.jabref.gui.edit.ReplaceStringAction;
import org.jabref.gui.entryeditor.EntryEditor;
Expand Down Expand Up @@ -116,6 +116,7 @@ public class BasePanel extends StackPane {

private final BibDatabaseContext bibDatabaseContext;
private final MainTableDataModel tableModel;
private final DatabaseChangePane changePane;

private final CitationStyleCache citationStyleCache;
private final FileAnnotationCache annotationCache;
Expand Down Expand Up @@ -189,14 +190,17 @@ public BasePanel(JabRefFrame frame, BasePanelPreferences preferences, BibDatabas
Optional<File> file = bibDatabaseContext.getDatabaseFile();
if (file.isPresent()) {
// Register so we get notifications about outside changes to the file.
changeMonitor = Optional.of(new DatabaseChangeMonitor(bibDatabaseContext, Globals.getFileUpdateMonitor(), this));
changeMonitor = Optional.of(new DatabaseChangeMonitor(bibDatabaseContext, Globals.getFileUpdateMonitor(), Globals.TASK_EXECUTOR));
changePane = new DatabaseChangePane(mainTable.getPane(), bibDatabaseContext, changeMonitor.get());
getChildren().add(changePane);
} else {
if (bibDatabaseContext.getDatabase().hasEntries()) {
// if the database is not empty and no file is assigned,
// the database came from an import and has to be treated somehow
// -> mark as changed
this.baseChanged = true;
}
changePane = null;
}

this.getDatabase().registerListener(new UpdateTimestampListener(Globals.prefs));
Expand Down Expand Up @@ -1098,14 +1102,6 @@ private void saveDividerLocation(Number position) {
*/
public void cleanUp() {
changeMonitor.ifPresent(DatabaseChangeMonitor::unregister);

// Check if there is a FileUpdatePanel for this BasePanel being shown. If so remove it:
if (sidePaneManager.isComponentVisible(SidePaneType.FILE_UPDATE_NOTIFICATION)) {
FileUpdatePanel fup = (FileUpdatePanel) sidePaneManager.getComponent(SidePaneType.FILE_UPDATE_NOTIFICATION);
if (fup.getPanel() == this) {
sidePaneManager.hide(SidePaneType.FILE_UPDATE_NOTIFICATION);
}
}
}

/**
Expand All @@ -1122,10 +1118,6 @@ public BibDatabaseContext getBibDatabaseContext() {
return this.bibDatabaseContext;
}

public boolean isUpdatedExternally() {
return changeMonitor.map(DatabaseChangeMonitor::hasBeenModifiedExternally).orElse(false);
}

public void markExternalChangesAsResolved() {
changeMonitor.ifPresent(DatabaseChangeMonitor::markExternalChangesAsResolved);
}
Expand Down Expand Up @@ -1210,17 +1202,13 @@ public FileAnnotationCache getAnnotationCache() {

public void resetChangeMonitor() {
changeMonitor.ifPresent(DatabaseChangeMonitor::unregister);
changeMonitor = Optional.of(new DatabaseChangeMonitor(bibDatabaseContext, Globals.getFileUpdateMonitor(), this));
changeMonitor = Optional.of(new DatabaseChangeMonitor(bibDatabaseContext, Globals.getFileUpdateMonitor(), Globals.TASK_EXECUTOR));
}

public void updateTimeStamp() {
changeMonitor.ifPresent(DatabaseChangeMonitor::markAsSaved);
}

public Path getTempFile() {
return changeMonitor.map(DatabaseChangeMonitor::getTempFile).orElse(null);
}

public void copy() {
mainTable.copy();
}
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/org/jabref/gui/SidePaneManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.util.stream.Stream;

import org.jabref.Globals;
import org.jabref.gui.collab.FileUpdatePanel;
import org.jabref.gui.groups.GroupSidePane;
import org.jabref.gui.importer.fetcher.WebSearchPane;
import org.jabref.gui.openoffice.OpenOfficeSidePanel;
Expand All @@ -31,7 +30,6 @@ public SidePaneManager(JabRefPreferences preferences, JabRefFrame frame) {

OpenOfficePreferences openOfficePreferences = preferences.getOpenOfficePreferences();
Stream.of(
new FileUpdatePanel(this),
new GroupSidePane(this, preferences, frame.getDialogService()),
new WebSearchPane(this, preferences, frame),
new OpenOfficeSidePanel(this, preferences, frame))
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/jabref/gui/SidePaneType.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
* Definition of all possible components in the side pane.
*/
public enum SidePaneType {
OPEN_OFFICE, WEB_SEARCH, FILE_UPDATE_NOTIFICATION, GROUPS
OPEN_OFFICE,
WEB_SEARCH,
GROUPS
}
194 changes: 65 additions & 129 deletions src/main/java/org/jabref/gui/collab/ChangeDisplayDialog.java
Original file line number Diff line number Diff line change
@@ -1,145 +1,81 @@
package org.jabref.gui.collab;

import java.awt.BorderLayout;
import java.awt.Insets;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javafx.collections.FXCollections;
import javafx.scene.control.ButtonBar;
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 javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;

import org.jabref.gui.BasePanel;
import org.jabref.gui.JabRefDialog;
import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.util.BaseDialog;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabase;

class ChangeDisplayDialog extends JabRefDialog implements TreeSelectionListener {

private final JTree tree;
private final JPanel infoPanel = new JPanel();
private final JCheckBox cb = new JCheckBox(Localization.lang("Accept change"));
private final JLabel rootInfo = new JLabel(Localization.lang("Select the tree nodes to view and accept or reject changes") + '.');
private ChangeViewModel selected;
private JComponent infoShown;
private boolean okPressed;

public ChangeDisplayDialog(final BasePanel panel,
BibDatabase secondary, final DefaultMutableTreeNode root) {
super(Localization.lang("External changes"), true, ChangeDisplayDialog.class);
BibDatabase localSecondary;

// Just to be sure, put in an empty secondary base if none is given:
if (secondary == null) {
localSecondary = new BibDatabase();
} else {
localSecondary = secondary;
}
tree = new JTree(root);
tree.addTreeSelectionListener(this);

JSplitPane pane = new JSplitPane();
pane.setLeftComponent(new JScrollPane(tree));
JPanel infoBorder = new JPanel();
pane.setRightComponent(infoBorder);

cb.setMargin(new Insets(2, 2, 2, 2));
cb.setEnabled(false);
infoPanel.setLayout(new BorderLayout());
infoBorder.setLayout(new BorderLayout());
infoBorder.setBorder(BorderFactory.createEtchedBorder());
infoBorder.add(infoPanel, BorderLayout.CENTER);
setInfo(rootInfo);
infoPanel.add(cb, BorderLayout.SOUTH);

JButton ok = new JButton(Localization.lang("OK"));
JPanel buttonPanel = new JPanel();
buttonPanel.add(ok);
JButton cancel = new JButton(Localization.lang("Cancel"));
buttonPanel.add(cancel);

getContentPane().add(pane, BorderLayout.CENTER);
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
import org.jabref.model.database.BibDatabaseContext;

import org.fxmisc.easybind.EasyBind;

class ChangeDisplayDialog extends BaseDialog<Boolean> {

private final ListView<DatabaseChangeViewModel> tree;
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(190);
EasyBind.subscribe(tree.getSelectionModel().selectedItemProperty(), this::selectedChangeChanged);

SplitPane pane = new SplitPane();
pane.setDividerPositions(0.25);
pane.getItems().addAll(new ScrollPane(tree), infoPanel);
getDialogPane().setContent(pane);

infoPanel.setBottom(cb);
Label rootInfo = new Label(Localization.lang("Select the tree nodes to view and accept or reject changes") + '.');
infoPanel.setCenter(rootInfo);

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

setResultConverter(button -> {
if (button == ButtonType.CANCEL) {
return false;
} else {
// Perform all accepted changes
NamedCompound ce = new NamedCompound(Localization.lang("Merged external changes"));
for (DatabaseChangeViewModel change : changes) {
if (change.isAccepted()) {
change.makeChange(database, ce);
}
}
ce.end();
//TODO: panel.getUndoManager().addEdit(ce);

cb.addChangeListener(e -> {
if (selected != null) {
selected.setAccepted(cb.isSelected());
return true;
}
});

cancel.addActionListener(e -> dispose());

ok.addActionListener(e -> {

// Perform all accepted changes:
// Store all edits in an Undoable object:
NamedCompound ce = new NamedCompound(Localization.lang("Merged external changes"));
Enumeration<ChangeViewModel> enumer = root.children();
boolean anyDisabled = false;
for (ChangeViewModel c : Collections.list(enumer)) {
boolean allAccepted = false;
if (c.isAcceptable() && c.isAccepted()) {
allAccepted = c.makeChange(panel, localSecondary, ce);
}

if (!allAccepted) {
anyDisabled = true;
}
}
ce.end();
panel.getUndoManager().addEdit(ce);
if (anyDisabled) {
panel.markBaseChanged();
EasyBind.subscribe(cb.selectedProperty(), selected -> {
if (selected != null && tree.getSelectionModel().getSelectedItem() != null) {
tree.getSelectionModel().getSelectedItem().setAccepted(selected);
}
panel.markExternalChangesAsResolved();
dispose();
okPressed = true;
});

pack();
}

public boolean isOkPressed() {
return okPressed;
}

private void setInfo(JComponent comp) {
if (infoShown != null) {
infoPanel.remove(infoShown);
}
infoShown = comp;
infoPanel.add(infoShown, BorderLayout.CENTER);
infoPanel.revalidate();
infoPanel.repaint();
}

/**
* valueChanged
*
* @param e TreeSelectionEvent
*/
@Override
public void valueChanged(TreeSelectionEvent e) {
Object o = tree.getLastSelectedPathComponent();
if (o instanceof ChangeViewModel) {
selected = (ChangeViewModel) o;
setInfo(selected.description());
cb.setSelected(selected.isAccepted());
cb.setEnabled(selected.isAcceptable());
} else {
setInfo(rootInfo);
selected = null;
cb.setEnabled(false);
private void selectedChangeChanged(DatabaseChangeViewModel currentChange) {
if (currentChange != null) {
infoPanel.setCenter(currentChange.description());
cb.setSelected(currentChange.isAccepted());
}
}
}
Loading