From f6a334603790144155902d0b043ca4b2d5e384ee Mon Sep 17 00:00:00 2001 From: 1160300712 Date: Mon, 13 Aug 2018 22:46:50 +0800 Subject: [PATCH 01/13] issue_3861 --- src/main/java/org/jabref/gui/MergeDialog.java | 128 ++++--- .../org/jabref/gui/ReplaceStringDialog.java | 193 +++++++++++ .../gui/actions/MassSetFieldAction.java | 324 ++++++++++-------- .../jabref/gui/actions/WriteXMPAction.java | 153 ++++----- .../org/jabref/gui/groups/GroupDialog.java | 3 +- .../jabref/gui/groups/GroupTreeViewModel.java | 18 +- .../jabref/gui/mergeentries/MergeEntries.java | 58 ++-- 7 files changed, 551 insertions(+), 326 deletions(-) create mode 100644 src/main/java/org/jabref/gui/ReplaceStringDialog.java diff --git a/src/main/java/org/jabref/gui/MergeDialog.java b/src/main/java/org/jabref/gui/MergeDialog.java index 09ddfb6677d..a702897a076 100644 --- a/src/main/java/org/jabref/gui/MergeDialog.java +++ b/src/main/java/org/jabref/gui/MergeDialog.java @@ -1,48 +1,38 @@ package org.jabref.gui; -import java.awt.BorderLayout; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; - -import javax.swing.AbstractAction; -import javax.swing.ActionMap; -import javax.swing.BorderFactory; -import javax.swing.InputMap; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComponent; -import javax.swing.JPanel; - -import org.jabref.Globals; -import org.jabref.gui.keyboard.KeyBinding; import org.jabref.logic.l10n.Localization; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.stage.Stage; /** * Asks for details about merge database operation. */ -public class MergeDialog extends JabRefDialog { +public class MergeDialog extends FXDialog { - private final JPanel panel1 = new JPanel(); - private final BorderLayout borderLayout1 = new BorderLayout(); - private final JPanel jPanel1 = new JPanel(); - private final JPanel jPanel2 = new JPanel(); - private final JButton ok = new JButton(); - private final JButton cancel = new JButton(); - private final JCheckBox entries = new JCheckBox(); - private final JCheckBox strings = new JCheckBox(); - private final GridBagLayout gridBagLayout1 = new GridBagLayout(); - private final JCheckBox groups = new JCheckBox(); - private final JCheckBox selector = new JCheckBox(); + private final Pane panel1 = new Pane(); + private final Pane Panel1 = new Pane(); + private final Pane Panel2 = new Pane(); + private final Button ok = new Button(); + private final Button cancel = new Button(); + private final CheckBox entries = new CheckBox(); + private final CheckBox strings = new CheckBox(); + private final GridPane gridPane1 = new GridPane(); + private final CheckBox groups = new CheckBox(); + private final CheckBox selector = new CheckBox(); private boolean okPressed; public MergeDialog(JabRefFrame frame, String title, boolean modal) { - super(title, modal, MergeDialog.class); + super(AlertType.NONE, Localization.lang("Append Library")); jbInit(); - pack(); + } public boolean isOkPressed() { @@ -50,16 +40,18 @@ public boolean isOkPressed() { } private void jbInit() { - panel1.setLayout(borderLayout1); + ok.setText(Localization.lang("OK")); - ok.addActionListener(e -> { - okPressed = true; - dispose(); + ok.setOnAction(oa->{ + okPressed = true; + dispose(); }); + ok.setPrefWidth(100); + ok.setPrefHeight(30); cancel.setText(Localization.lang("Cancel")); - cancel.addActionListener(e -> dispose()); - jPanel1.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - jPanel1.setLayout(gridBagLayout1); + cancel.setOnAction(oa-> dispose()); + cancel.setPrefWidth(100); + cancel.setPrefHeight(30); entries.setSelected(true); entries.setText(Localization.lang("Import entries")); strings.setSelected(true); @@ -67,33 +59,26 @@ private void jbInit() { groups.setText(Localization.lang("Import group definitions")); selector.setText(Localization.lang("Import word selector definitions")); - this.setModal(true); - this.setResizable(false); - getContentPane().add(panel1); - panel1.add(jPanel2, BorderLayout.SOUTH); - jPanel2.add(ok, null); - jPanel2.add(cancel, null); - panel1.add(jPanel1, BorderLayout.CENTER); - jPanel1.add(entries, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - , GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - jPanel1.add(strings, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0 - , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); - jPanel1.add(groups, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0 - , GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); - jPanel1.add(selector, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, - GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); - - // Key bindings: - ActionMap am = jPanel1.getActionMap(); - InputMap im = jPanel1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); - im.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE), "close"); - am.put("close", new AbstractAction() { - - @Override - public void actionPerformed(ActionEvent e) { - dispose(); - } - }); + + GridPane gp= new GridPane(); + HBox optionButtons = new HBox(); + getDialogPane().setContent(gp); + gp.setHgap(10); + gp.setVgap(10); + gp.setPadding(new Insets(15,5,0,0)); + gp.add(entries, 0, 0); + gp.add(strings, 0, 1); + gp.add(groups, 0, 2); + gp.add(selector, 0, 3); + gp.add(optionButtons,0,4); + gp.setPadding(new Insets(15,5,0,0)); + gp.setGridLinesVisible(false); + + optionButtons.setAlignment(Pos.BOTTOM_CENTER); + optionButtons.setPadding(new Insets(15, 0, 0, 0)); + optionButtons.setSpacing(35); + optionButtons.getChildren().add(ok); + optionButtons.getChildren().add(cancel); } @@ -112,6 +97,15 @@ public boolean importStrings() { public boolean importSelectorWords() { return selector.isSelected(); } -} - + public void setVisible(boolean b) { + if (b) { + show(); + } else { + hide(); + } + } + private void dispose() { + ((Stage) (getDialogPane().getScene().getWindow())).close(); + } +} diff --git a/src/main/java/org/jabref/gui/ReplaceStringDialog.java b/src/main/java/org/jabref/gui/ReplaceStringDialog.java new file mode 100644 index 00000000000..5abae42e266 --- /dev/null +++ b/src/main/java/org/jabref/gui/ReplaceStringDialog.java @@ -0,0 +1,193 @@ +package org.jabref.gui; + +import java.util.Locale; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.control.ToggleGroup; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.paint.Color; +import javafx.stage.Stage; + +import org.jabref.gui.undo.NamedCompound; +import org.jabref.gui.undo.UndoableFieldChange; +import org.jabref.logic.l10n.Localization; +import org.jabref.model.entry.BibEntry; + +/** + * Dialog for replacing strings. + */ +class ReplaceStringDialog extends FXDialog { + private final TextField fieldsField = new TextField(); + private final TextField fromField = new TextField(); + private final TextField toField = new TextField(); + + private final CheckBox selOnly = new CheckBox(Localization.lang("Limit to selected entries")); + private final RadioButton allFi = new RadioButton(Localization.lang("All fields")); + private final RadioButton field = new RadioButton(Localization.lang("Limit to fields") + ":"); + private boolean okPressed; + private String[] fieldStrings; + private String fromString; + private String toString; + + + public ReplaceStringDialog(JabRefFrame parent) { + super(AlertType.NONE, Localization.lang("Replace string")); + + ToggleGroup tg = new ToggleGroup(); + selOnly.setSelected(false); + allFi.setSelected(true); + allFi.setToggleGroup(tg); + field.setToggleGroup(tg); + fieldsField.setPrefColumnCount(30); + fromField.setPrefColumnCount(30); + toField.setPrefColumnCount(30); + + Button ok = new Button(Localization.lang("OK")); + ok.setOnAction(oa -> { + fromString = fromField.getText(); + toString = toField.getText(); + if ("".equals(fromString)) { + return; + } + okPressed = true; + fieldStrings = fieldsField.getText().toLowerCase(Locale.ROOT).split(";"); + dispose(); + }); + ok.setPrefSize(100, 30); + Button cancel = new Button(Localization.lang("Cancel")); + cancel.setOnAction(oa -> dispose()); + cancel.setPrefSize(100, 30); + + // Layout starts here. + GridPane main = new GridPane(); + GridPane settings = new GridPane(); + HBox title1 = new HBox(); + HBox title2 = new HBox(); + GridPane gp = new GridPane(); + HBox optionButtons = new HBox(); + getDialogPane().setContent(gp); + gp.add(title1, 0, 0); + gp.add(main, 0, 1); + gp.add(title2, 0, 2); + gp.add(settings, 0, 3); + gp.add(optionButtons, 0, 4); + gp.setPadding(new Insets(15, 5, 0, 0)); + gp.setGridLinesVisible(false); + + // Border title: + Label str = new Label(Localization.lang("Strings")); + Label rplStr = new Label(Localization.lang("Replace string")); + str.setTextFill(Color.web("#778899")); + rplStr.setTextFill(Color.web("#778899")); + title1.getChildren().add(str); + title1.setPadding(new Insets(10, 0, 0, 0)); + title2.getChildren().add(rplStr); + title2.setPadding(new Insets(10, 0, 0, 0)); + + // Settings panel: + settings.setHgap(10); + settings.setVgap(10); + settings.setPadding(new Insets(5, 15, 5, 15)); + settings.add(selOnly, 0, 0, 2, 1); + settings.add(allFi, 0, 2); + settings.add(field, 0, 3); + settings.add(fieldsField, 1, 3); + settings.setStyle("-fx-content-display:top;" + + "-fx-border-insets:0 0 0 0;" + + "-fx-border-color:#D3D3D3"); + + // Main panel: + main.setHgap(34); + main.setVgap(5); + main.setPadding(new Insets(5, 15, 5, 15)); + main.add(new Label(Localization.lang("Search for") + ":"), 0, 0); + main.add(new Label(Localization.lang("Replace with") + ":"), 0, 1); + main.add(fromField, 1, 0); + main.add(toField, 1, 1); + main.setStyle("-fx-content-display:top;" + + "-fx-border-insets:0 0 0 0;" + + "-fx-border-color:#D3D3D3"); + + //Option buttons: + optionButtons.setAlignment(Pos.BOTTOM_CENTER); + optionButtons.setPadding(new Insets(15, 0, 0, 0)); + optionButtons.setSpacing(35); + optionButtons.getChildren().add(ok); + optionButtons.getChildren().add(cancel); + } + + public void setVisible(boolean b) { + if (b) { + show(); + } else { + hide(); + } + } + + public boolean okPressed() { + return okPressed; + } + + private boolean allFields() { + return allFi.isSelected(); + } + + public boolean selOnly() { + return selOnly.isSelected(); + } + + /** + * Does the actual operation on a Bibtex entry based on the + * settings specified in this same dialog. Returns the number of + * occurences replaced. + */ + public int replace(BibEntry be, NamedCompound ce) { + int counter = 0; + if (allFields()) { + for (String s : be.getFieldNames()) { + counter += replaceField(be, s, ce); + } + } else { + for (String fld : fieldStrings) { + counter += replaceField(be, fld, ce); + } + } + return counter; + } + + private int replaceField(BibEntry be, String fieldname, NamedCompound ce) { + if (!be.hasField(fieldname)) { + return 0; + } + String txt = be.getField(fieldname).get(); + StringBuilder sb = new StringBuilder(); + int ind; + int piv = 0; + int counter = 0; + int len1 = fromString.length(); + while ((ind = txt.indexOf(fromString, piv)) >= 0) { + counter++; + sb.append(txt.substring(piv, ind)); // Text leading up to s1 + sb.append(toString); // Insert s2 + piv = ind + len1; + } + sb.append(txt.substring(piv)); + String newStr = sb.toString(); + be.setField(fieldname, newStr); + ce.addEdit(new UndoableFieldChange(be, fieldname, txt, newStr)); + return counter; + } + + /** + * close the dialog + */ + private void dispose() { + ((Stage) (getDialogPane().getScene().getWindow())).close(); + } +} diff --git a/src/main/java/org/jabref/gui/actions/MassSetFieldAction.java b/src/main/java/org/jabref/gui/actions/MassSetFieldAction.java index a93aaebe2b8..3a67ee9993c 100644 --- a/src/main/java/org/jabref/gui/actions/MassSetFieldAction.java +++ b/src/main/java/org/jabref/gui/actions/MassSetFieldAction.java @@ -1,42 +1,35 @@ package org.jabref.gui.actions; -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; import java.util.Collection; import java.util.List; -import java.util.Locale; import java.util.Optional; import java.util.Set; -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.ActionMap; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.InputMap; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JComponent; -import javax.swing.JDialog; -import javax.swing.JFrame; -import javax.swing.JRadioButton; -import javax.swing.JTextField; import javax.swing.undo.UndoableEdit; -import org.jabref.Globals; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.stage.Stage; + import org.jabref.gui.BasePanel; +import org.jabref.gui.FXDialog; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.logic.l10n.Localization; import org.jabref.model.entry.BibEntry; - -import com.jgoodies.forms.builder.ButtonBarBuilder; -import com.jgoodies.forms.builder.FormBuilder; -import com.jgoodies.forms.layout.FormLayout; - /** * An Action for launching mass field. * @@ -47,22 +40,25 @@ */ public class MassSetFieldAction extends SimpleCommand { + public javafx.scene.control.Dialog FXDialog = new javafx.scene.control.Dialog(); private final JabRefFrame frame; - private JDialog diag; - private JRadioButton all; - private JRadioButton selected; - private JRadioButton clear; - private JRadioButton set; - private JRadioButton append; - private JRadioButton rename; - private JComboBox field; - private JTextField textFieldSet; - private JTextField textFieldAppend; - private JTextField textFieldRename; + private FXDialog diag; + private RadioButton all; + private RadioButton selected; + private RadioButton clear; + private RadioButton set; + private RadioButton append; + private RadioButton rename; + private ComboBox field; + private TextField textFieldSet; + private TextField textFieldAppend; + private TextField textFieldRename; private boolean canceled = true; - private JCheckBox overwrite; + private CheckBox overwrite; + public MassSetFieldAction(JabRefFrame frame) { + //super(AlertType.NONE, Localization.lang("Set/clear/append/rename fields"), true); this.frame = frame; } @@ -100,7 +96,8 @@ private static UndoableEdit massSetField(Collection entries, String fi } private void prepareDialog(boolean selection) { - selected.setEnabled(selection); + + //selected.setEnabled(selection); if (selection) { selected.setSelected(true); } else { @@ -112,8 +109,10 @@ private void prepareDialog(boolean selection) { } } + @Override public void execute() { + BasePanel bp = frame.getCurrentBasePanel(); if (bp == null) { return; @@ -125,9 +124,7 @@ public void execute() { } canceled = true; prepareDialog(!entries.isEmpty()); - if (diag != null) { - diag.setVisible(true); - } + if (canceled) { return; } @@ -145,7 +142,11 @@ public void execute() { toSet = null; } - String[] fields = getFieldNames(((String) field.getSelectedItem()).trim().toLowerCase(Locale.ROOT)); + String[] fields = (String[]) field.getItems().toArray(); + for (String s : fields) { + s = s.toLowerCase(); + } + NamedCompound compoundEdit = new NamedCompound(Localization.lang("Set field")); if (rename.isSelected()) { if (fields.length > 1) { @@ -234,94 +235,29 @@ private static UndoableEdit massRenameField(Collection entries, String } private void createDialog() { - diag = new JDialog((JFrame) null, Localization.lang("Set/clear/append/rename fields"), true); + diag = new FXDialog(AlertType.NONE, Localization.lang("Set/clear/append/rename fields"), true); + FXDialog.setTitle("Set/clear/append/rename fields"); - field = new JComboBox<>(); + + field = new ComboBox<>(); field.setEditable(true); - textFieldSet = new JTextField(); - textFieldSet.setEnabled(false); - textFieldAppend = new JTextField(); - textFieldAppend.setEnabled(false); - textFieldRename = new JTextField(); - textFieldRename.setEnabled(false); - - JButton ok = new JButton(Localization.lang("OK")); - JButton cancel = new JButton(Localization.lang("Cancel")); - - all = new JRadioButton(Localization.lang("All entries")); - selected = new JRadioButton(Localization.lang("Selected entries")); - clear = new JRadioButton(Localization.lang("Clear fields")); - set = new JRadioButton(Localization.lang("Set fields")); - append = new JRadioButton(Localization.lang("Append to fields")); - rename = new JRadioButton(Localization.lang("Rename field to") + ":"); - rename.setToolTipText(Localization.lang("Move contents of a field into a field with a different name")); + textFieldSet = new TextField(); - Set allFields = frame.getCurrentBasePanel().getDatabase().getAllVisibleFields(); + textFieldSet.setDisable(true); + textFieldAppend = new TextField(); - for (String f : allFields) { - field.addItem(f); - } + textFieldAppend.setDisable(true); + textFieldRename = new TextField(); - set.addChangeListener(e -> - // Entering a setText is only relevant if we are setting, not clearing: - textFieldSet.setEnabled(set.isSelected())); + textFieldRename.setDisable(true); - append.addChangeListener(e -> { - // Text to append is only required if we are appending: - textFieldAppend.setEnabled(append.isSelected()); - // Overwrite protection makes no sense if we are appending to a field: - overwrite.setEnabled(!clear.isSelected() && !append.isSelected()); - }); - clear.addChangeListener(e -> - // Overwrite protection makes no sense if we are clearing the field: - overwrite.setEnabled(!clear.isSelected() && !append.isSelected())); - - rename.addChangeListener(e -> - // Entering a setText is only relevant if we are renaming - textFieldRename.setEnabled(rename.isSelected())); - - overwrite = new JCheckBox(Localization.lang("Overwrite existing field values"), true); - ButtonGroup bg = new ButtonGroup(); - bg.add(all); - bg.add(selected); - bg = new ButtonGroup(); - bg.add(clear); - bg.add(set); - bg.add(append); - bg.add(rename); - FormBuilder builder = FormBuilder.create().layout(new FormLayout( - "left:pref, 4dlu, fill:100dlu:grow", "pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref")); - builder.addSeparator(Localization.lang("Field name")).xyw(1, 1, 3); - builder.add(Localization.lang("Field name")).xy(1, 3); - builder.add(field).xy(3, 3); - builder.addSeparator(Localization.lang("Include entries")).xyw(1, 5, 3); - builder.add(all).xyw(1, 7, 3); - builder.add(selected).xyw(1, 9, 3); - builder.addSeparator(Localization.lang("New field value")).xyw(1, 11, 3); - builder.add(set).xy(1, 13); - builder.add(textFieldSet).xy(3, 13); - builder.add(clear).xyw(1, 15, 3); - builder.add(append).xy(1, 17); - builder.add(textFieldAppend).xy(3, 17); - builder.add(rename).xy(1, 19); - builder.add(textFieldRename).xy(3, 19); - builder.add(overwrite).xyw(1, 21, 3); - - ButtonBarBuilder bb = new ButtonBarBuilder(); - bb.addGlue(); - bb.addButton(ok); - bb.addButton(cancel); - bb.addGlue(); - builder.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - bb.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - diag.getContentPane().add(builder.getPanel(), BorderLayout.CENTER); - diag.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH); - diag.pack(); - - ok.addActionListener(e -> { + Button ok = new Button(Localization.lang("OK")); + Button cancel = new Button(Localization.lang("Cancel")); + ok.setOnAction(e -> { // Check that any field name is set - String fieldText = (String) field.getSelectedItem(); + + String fieldText = field.getItems().toString(); if ((fieldText == null) || fieldText.trim().isEmpty()) { frame.getDialogService().showErrorDialogAndWait(Localization.lang("You must enter at least one field name")); @@ -340,27 +276,147 @@ private void createDialog() { } } canceled = false; - diag.dispose(); + dispose(); }); - Action cancelAction = new AbstractAction() { + cancel.setText(Localization.lang("Cancel")); + cancel.setOnAction(oa -> dispose()); + cancel.setPrefWidth(100); + cancel.setPrefHeight(30); + + all = new RadioButton(Localization.lang("All entries")); + selected = new RadioButton(Localization.lang("Selected entries")); + clear = new RadioButton(Localization.lang("Clear fields")); + set = new RadioButton(Localization.lang("Set fields")); + append = new RadioButton(Localization.lang("Append to fields")); + rename = new RadioButton(Localization.lang("Rename field to") + ":"); + Tooltip aaa = new Tooltip(Localization.lang("Move contents of a field into a field with a different name")); + rename.setTooltip(aaa); + + Set allFields = frame.getCurrentBasePanel().getDatabase().getAllVisibleFields(); + + for (String f : allFields) { + //field.addItem(f); + field.getItems().add(f); + } + set.selectedProperty().addListener(new ChangeListener(){ + @Override + public void changed(ObservableValue ov, Boolean a,Boolean b) { + textFieldSet.setDisable(!set.isSelected()); + } + }); + append.selectedProperty().addListener(new ChangeListener(){ @Override - public void actionPerformed(ActionEvent e) { - canceled = true; - diag.dispose(); + public void changed(ObservableValue ov, Boolean a,Boolean b) { + textFieldSet.setDisable(!(!clear.isSelected() && !append.isSelected())); } - }; - cancel.addActionListener(cancelAction); - - // Key bindings: - ActionMap am = builder.getPanel().getActionMap(); - InputMap im = builder.getPanel().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); - im.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE), "close"); - am.put("close", cancelAction); + }); + clear.selectedProperty().addListener(new ChangeListener(){ + @Override + public void changed(ObservableValue ov, Boolean a,Boolean b) { + textFieldSet.setDisable(!(!clear.isSelected() && !append.isSelected())); + } + }); + rename.selectedProperty().addListener(new ChangeListener(){ + @Override + public void changed(ObservableValue ov, Boolean a,Boolean b) { + textFieldSet.setDisable(!rename.isSelected()); + } + }); + + overwrite = new CheckBox("Overwrite existing field values"); + + GridPane main=new GridPane(); + GridPane fn = new GridPane(); + GridPane ie = new GridPane(); + GridPane nfv = new GridPane(); + HBox title1 = new HBox(); + HBox title2 = new HBox(); + HBox title3 = new HBox(); + HBox optionButtons = new HBox(); + FXDialog.getDialogPane().setContent(main); + main.setPrefSize(400, 400); + + main.add(title1, 0, 0); + main.add(fn, 0, 1); + main.add(title2, 0, 2); + main.add(ie, 0, 3, 2, 1); + main.add(title3, 0, 5); + main.add(nfv, 0, 6, 4, 1); + main.add(optionButtons, 0, 10); + main.setPadding(new Insets(15, 5, 0, 0)); + main.setGridLinesVisible(false); + + Label str1 = new Label(Localization.lang("Field name")); + Label str2 = new Label(Localization.lang("Include entries")); + Label str3 = new Label(Localization.lang("New field value")); + title1.getChildren().add(str1); + title1.setPadding(new Insets(10, 0, 0, 0)); + title1.setAlignment(Pos.CENTER_LEFT); + title2.getChildren().add(str2); + title2.setPadding(new Insets(10, 0, 0, 0)); + title2.setAlignment(Pos.CENTER_LEFT); + title3.getChildren().add(str3); + title3.setPadding(new Insets(10, 0, 0, 0)); + title3.setAlignment(Pos.CENTER_LEFT); + + fn.setHgap(34); + fn.setVgap(5); + fn.setPadding(new Insets(5, 15, 5, 15)); + fn.add(new Label(Localization.lang("Field name") + ":"), 0, 0); + fn.add(field, 1, 0); + fn.setStyle("-fx-content-display:top;" + + "-fx-border-insets:0 0 0 0;" + + "-fx-border-color:#D3D3D3"); + + ie.setHgap(10); + ie.setVgap(10); + ie.setPadding(new Insets(5, 15, 5, 15)); + ie.add(all, 0, 0); + ie.add(selected, 0, 1); + ie.setStyle("-fx-content-display:top;" + + "-fx-border-insets:0 0 0 0;" + + "-fx-border-color:#D3D3D3"); + + nfv.setHgap(34); + nfv.setVgap(5); + nfv.setPadding(new Insets(5, 15, 5, 15)); + nfv.add(set, 0, 0); + nfv.add(clear, 0, 1); + nfv.add(append, 0, 2); + nfv.add(rename, 0, 3); + nfv.add(overwrite, 0, 4); + nfv.setStyle("-fx-content-display:top;" + + "-fx-border-insets:0 0 0 0;" + + "-fx-border-color:#D3D3D3"); + + optionButtons.setAlignment(Pos.BOTTOM_CENTER); + optionButtons.setPadding(new Insets(15, 0, 0, 0)); + optionButtons.setSpacing(35); + optionButtons.getChildren().add(ok); + optionButtons.getChildren().add(cancel); + + FXDialog.showAndWait(); + } + + private static String[] getFieldNames(String s) { return s.split("[\\s;,]"); } + + public void setVisible(boolean b) { + if (b) { + FXDialog.showAndWait(); + } else { + FXDialog.hide(); + } + } + + private void dispose() { + + ((Stage) (FXDialog.getDialogPane().getScene().getWindow())).close(); + } } diff --git a/src/main/java/org/jabref/gui/actions/WriteXMPAction.java b/src/main/java/org/jabref/gui/actions/WriteXMPAction.java index e2d549e2c4e..0c5117544a0 100644 --- a/src/main/java/org/jabref/gui/actions/WriteXMPAction.java +++ b/src/main/java/org/jabref/gui/actions/WriteXMPAction.java @@ -1,9 +1,5 @@ package org.jabref.gui.actions; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.event.ActionEvent; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; @@ -11,31 +7,29 @@ import java.util.Optional; import java.util.stream.Collectors; -import javax.swing.AbstractAction; -import javax.swing.ActionMap; -import javax.swing.BorderFactory; -import javax.swing.InputMap; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingUtilities; +import javafx.application.Platform; +import javafx.geometry.Insets; +import javafx.scene.control.Button; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextArea; +import javafx.scene.input.KeyCode; +import javafx.scene.layout.Background; +import javafx.scene.layout.BackgroundFill; +import javafx.scene.layout.CornerRadii; +import javafx.scene.layout.GridPane; +import javafx.scene.paint.Color; +import javafx.stage.Stage; import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; -import org.jabref.gui.JabRefDialog; -import org.jabref.gui.keyboard.KeyBinding; +import org.jabref.gui.FXDialog; import org.jabref.gui.util.BackgroundTask; import org.jabref.logic.l10n.Localization; import org.jabref.logic.xmp.XmpUtilWriter; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; -import com.jgoodies.forms.builder.ButtonBarBuilder; - public class WriteXMPAction extends SimpleCommand { private final BasePanel basePanel; @@ -116,49 +110,49 @@ private void writeXMP() { .map(Optional::get) .collect(Collectors.toList()); - SwingUtilities.invokeLater(() -> optionsDialog.getProgressArea() - .append(entry.getCiteKeyOptional().orElse(Localization.lang("undefined")) + "\n")); + Platform.runLater(() -> optionsDialog.getProgressArea() + .appendText(entry.getCiteKeyOptional().orElse(Localization.lang("undefined")) + "\n")); if (files.isEmpty()) { skipped++; - SwingUtilities.invokeLater(() -> optionsDialog.getProgressArea() - .append(" " + Localization.lang("Skipped - No PDF linked") + ".\n")); + Platform.runLater(() -> optionsDialog.getProgressArea() + .appendText(" " + Localization.lang("Skipped - No PDF linked") + ".\n")); } else { for (Path file : files) { if (Files.exists(file)) { try { XmpUtilWriter.writeXmp(file, entry, database, Globals.prefs.getXMPPreferences()); - SwingUtilities.invokeLater( - () -> optionsDialog.getProgressArea().append(" " + Localization.lang("OK") + ".\n")); + Platform.runLater( + () -> optionsDialog.getProgressArea().appendText(" " + Localization.lang("OK") + ".\n")); entriesChanged++; } catch (Exception e) { - SwingUtilities.invokeLater(() -> { - optionsDialog.getProgressArea().append(" " + Localization.lang("Error while writing") + " '" + Platform.runLater(() -> { + optionsDialog.getProgressArea().appendText(" " + Localization.lang("Error while writing") + " '" + file.toString() + "':\n"); - optionsDialog.getProgressArea().append(" " + e.getLocalizedMessage() + "\n"); + optionsDialog.getProgressArea().appendText(" " + e.getLocalizedMessage() + "\n"); }); errors++; } } else { skipped++; - SwingUtilities.invokeLater(() -> { + Platform.runLater(() -> { optionsDialog.getProgressArea() - .append(" " + Localization.lang("Skipped - PDF does not exist") + ":\n"); - optionsDialog.getProgressArea().append(" " + file.toString() + "\n"); + .appendText(" " + Localization.lang("Skipped - PDF does not exist") + ":\n"); + optionsDialog.getProgressArea().appendText(" " + file.toString() + "\n"); }); } } } if (optionsDialog.isCanceled()) { - SwingUtilities.invokeLater( - () -> optionsDialog.getProgressArea().append("\n" + Localization.lang("Operation canceled.") + "\n")); + Platform.runLater( + () -> optionsDialog.getProgressArea().appendText("\n" + Localization.lang("Operation canceled.") + "\n")); break; } } - SwingUtilities.invokeLater(() -> { + Platform.runLater(() -> { optionsDialog.getProgressArea() - .append("\n" + .appendText("\n" + Localization.lang("Finished writing XMP for %0 file (%1 skipped, %2 errors).", String .valueOf(entriesChanged), String.valueOf(skipped), String.valueOf(errors))); optionsDialog.done(); @@ -172,92 +166,71 @@ private void writeXMP() { String.valueOf(entriesChanged), String.valueOf(skipped), String.valueOf(errors))); } - class OptionsDialog extends JabRefDialog { + class OptionsDialog extends FXDialog { - private final JButton okButton = new JButton(Localization.lang("OK")); - private final JButton cancelButton = new JButton(Localization.lang("Cancel")); + private final Button okButton = new Button(Localization.lang("OK")); + private final Button cancelButton = new Button(Localization.lang("Cancel")); private boolean isCancelled; - private final JTextArea progressArea; + private final TextArea progressArea; public OptionsDialog() { - super(Localization.lang("Writing XMP-metadata for selected entries..."), false, WriteXMPAction.OptionsDialog.class); - okButton.setEnabled(false); - - okButton.addActionListener(e -> dispose()); - - AbstractAction cancel = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { + super(AlertType.NONE, Localization.lang("Writing XMP-metadata for selected entries..."), false); + okButton.setDisable(true); + okButton.setOnAction(e -> dispose()); + okButton.setPrefSize(100, 30); + cancelButton.setOnAction(e -> isCancelled = true); + cancelButton.setOnKeyPressed(e -> { + if (e.getCode() == KeyCode.ESCAPE) { isCancelled = true; } - }; - cancelButton.addActionListener(cancel); - - InputMap im = cancelButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); - ActionMap am = cancelButton.getActionMap(); - im.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE), "close"); - am.put("close", cancel); - - progressArea = new JTextArea(15, 60); - - JScrollPane scrollPane = new JScrollPane(progressArea, - ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - Dimension d = progressArea.getPreferredSize(); - d.height += scrollPane.getHorizontalScrollBar().getHeight() + 15; - d.width += scrollPane.getVerticalScrollBar().getWidth() + 15; - - progressArea.setBackground(Color.WHITE); + }); + cancelButton.setPrefSize(100, 30); + progressArea = new TextArea(); + ScrollPane scrollPane = new ScrollPane(progressArea); + progressArea.setBackground(new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY))); progressArea.setEditable(false); - progressArea.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, - 3)); progressArea.setText(""); - JPanel tmpPanel = new JPanel(); - tmpPanel.setBorder(BorderFactory.createEmptyBorder(3, 2, 3, 2)); - tmpPanel.add(scrollPane); - - // progressArea.setPreferredSize(new Dimension(300, 300)); - - ButtonBarBuilder bb = new ButtonBarBuilder(); - bb.addGlue(); - bb.addButton(okButton); - bb.addRelatedGap(); - bb.addButton(cancelButton); - bb.addGlue(); - JPanel bbPanel = bb.getPanel(); - bbPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 3, 3)); - getContentPane().add(tmpPanel, BorderLayout.CENTER); - getContentPane().add(bbPanel, BorderLayout.SOUTH); - - pack(); + GridPane tmpPanel = new GridPane(); + getDialogPane().setContent(tmpPanel); + tmpPanel.setHgap(450); + tmpPanel.setVgap(10); + tmpPanel.add(scrollPane, 0, 0, 2, 1); + tmpPanel.add(okButton, 0, 1); + tmpPanel.add(cancelButton, 1, 1); + tmpPanel.setGridLinesVisible(false); this.setResizable(false); } + private void dispose() { + ((Stage) (getDialogPane().getScene().getWindow())).close(); + } + public void done() { - okButton.setEnabled(true); - cancelButton.setEnabled(false); + okButton.setDisable(false); + cancelButton.setDisable(true); } public void open() { progressArea.setText(""); isCancelled = false; - okButton.setEnabled(false); - cancelButton.setEnabled(true); + okButton.setDisable(true); + cancelButton.setDisable(false); okButton.requestFocus(); - optionsDialog.setVisible(true); + optionsDialog.show(); } public boolean isCanceled() { return isCancelled; } - public JTextArea getProgressArea() { + public TextArea getProgressArea() { return progressArea; } } diff --git a/src/main/java/org/jabref/gui/groups/GroupDialog.java b/src/main/java/org/jabref/gui/groups/GroupDialog.java index 043ee954af1..4abd8d6ac83 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialog.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialog.java @@ -20,6 +20,7 @@ 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.JRadioButton; @@ -148,7 +149,7 @@ public Dimension getPreferredSize() { * created. */ public GroupDialog(JabRefFrame jabrefFrame, AbstractGroup editedGroup) { - super(Localization.lang("Edit group"), true, GroupDialog.class); + super((JFrame) null, Localization.lang("Edit group"), true, GroupDialog.class); // set default values (overwritten if editedGroup != null) keywordGroupSearchField.setText(jabrefFrame.prefs().get(JabRefPreferences.GROUPS_DEFAULT_FIELD)); diff --git a/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java b/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java index 14874771dd8..511f8a8e6e7 100644 --- a/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java +++ b/src/main/java/org/jabref/gui/groups/GroupTreeViewModel.java @@ -7,8 +7,6 @@ import java.util.function.Predicate; import java.util.stream.Collectors; -import javax.swing.SwingUtilities; - import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.property.ListProperty; @@ -92,7 +90,7 @@ private void onSelectedGroupChanged(ObservableList newValue) } currentDatabase.ifPresent(database -> { - if (newValue == null || newValue.isEmpty()) { + if ((newValue == null) || newValue.isEmpty()) { stateManager.clearSelectedGroups(database); } else { stateManager.setSelectedGroups(database, newValue.stream().map(GroupNodeViewModel::getGroupNode).collect(Collectors.toList())); @@ -135,8 +133,10 @@ private void onActiveDatabaseChanged(Optional newDatabase) { * Opens "New Group Dialog" and add the resulting group to the specified group */ public void addNewSubgroup(GroupNodeViewModel parent) { - SwingUtilities.invokeLater(() -> { - Optional newGroup = dialogService.showCustomDialogAndWait(new GroupDialog()); + Platform.runLater(() -> { + // SwingUtilities.invokeLater(() -> { + // Optional newGroup = dialogService.showCustomDialogAndWait(new GroupDialog()); + Optional newGroup = new GroupDialog().showAndWaitCustom(); newGroup.ifPresent(group -> { parent.addSubgroup(group); @@ -161,9 +161,11 @@ private void writeGroupChangesToMetaData() { * Opens "Edit Group Dialog" and changes the given group to the edited one. */ public void editGroup(GroupNodeViewModel oldGroup) { - SwingUtilities.invokeLater(() -> { - Optional newGroup = dialogService - .showCustomDialogAndWait(new GroupDialog(oldGroup.getGroupNode().getGroup())); + Platform.runLater(() -> { + // SwingUtilities.invokeLater(() -> { + // Optional newGroup = dialogService + // .showCustomDialogAndWait(new GroupDialog(oldGroup.getGroupNode().getGroup())); + Optional newGroup = new GroupDialog(oldGroup.getGroupNode().getGroup()).showAndWaitCustom(); newGroup.ifPresent(group -> { Platform.runLater(() -> { diff --git a/src/main/java/org/jabref/gui/mergeentries/MergeEntries.java b/src/main/java/org/jabref/gui/mergeentries/MergeEntries.java index 661f5ae8004..d184f8afed9 100644 --- a/src/main/java/org/jabref/gui/mergeentries/MergeEntries.java +++ b/src/main/java/org/jabref/gui/mergeentries/MergeEntries.java @@ -1,6 +1,6 @@ package org.jabref.gui.mergeentries; -import java.awt.Font; +//import java.awt.Font; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; @@ -14,21 +14,27 @@ import java.util.Set; import java.util.TreeSet; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JScrollPane; -import javax.swing.JSeparator; -import javax.swing.JTextArea; -import javax.swing.JTextPane; -import javax.swing.ScrollPaneConstants; -import javax.swing.SwingUtilities; +//import javax.swing.BorderFactory; +//import javax.swing.ButtonGroup; +//import javax.swing.JComboBox; +//import javax.swing.JLabel; +//import javax.swing.JPanel; +//import javax.swing.JRadioButton; +//import javax.swing.JScrollPane; +//import javax.swing.JSeparator; +//import javax.swing.JTextArea; +//import javax.swing.JTextPane; +//import javax.swing.ScrollPaneConstants; +//import javax.swing.SwingUtilities; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextArea; +import javafx.scene.layout.GridPane; import org.jabref.Globals; import org.jabref.gui.FXDialogService; @@ -46,10 +52,10 @@ import org.jabref.model.entry.InternalBibtexFields; import org.jabref.preferences.JabRefPreferences; -import com.jgoodies.forms.layout.CellConstraints; -import com.jgoodies.forms.layout.ColumnSpec; -import com.jgoodies.forms.layout.FormLayout; -import com.jgoodies.forms.layout.RowSpec; +//import com.jgoodies.forms.layout.CellConstraints; +//import com.jgoodies.forms.layout.ColumnSpec; +//import com.jgoodies.forms.layout.FormLayout; +//import com.jgoodies.forms.layout.RowSpec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,7 +66,7 @@ public class MergeEntries { private static final String MARGIN = "10px"; - private static final List HEADING_LABELS = new ArrayList<>(6); + private static final List