package org.jabref.collab;
import java.awt.BorderLayout;
import java.awt.Insets;
import java.util.Collections;
import java.util.Enumeration;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
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.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 Change selected;
private JComponent infoShown;
private boolean okPressed;
public ChangeDisplayDialog(JFrame owner, final BasePanel panel,
BibDatabase secondary, final DefaultMutableTreeNode root) {
super(owner, 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);
cb.addChangeListener(e -> {
if (selected != null) {
selected.setAccepted(cb.isSelected());
}
});
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<Change> enumer = root.children();
boolean anyDisabled = false;
for (Change 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();
}
panel.setUpdatedExternally(false);
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 Change) {
selected = (Change) o;
setInfo(selected.description());
cb.setSelected(selected.isAccepted());
cb.setEnabled(selected.isAcceptable());
} else {
setInfo(rootInfo);
selected = null;
cb.setEnabled(false);
}
}
}