package org.jabref.gui.preftabs; import java.awt.BorderLayout; import java.awt.Insets; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.SpinnerNumberModel; import org.jabref.gui.keyboard.EmacsKeyBindings; import org.jabref.logic.autocompleter.AutoCompleteFirstNameMode; import org.jabref.logic.autocompleter.AutoCompletePreferences; import org.jabref.logic.l10n.Localization; import org.jabref.preferences.JabRefPreferences; import com.jgoodies.forms.builder.DefaultFormBuilder; import com.jgoodies.forms.layout.CellConstraints; import com.jgoodies.forms.layout.FormLayout; class EntryEditorPrefsTab extends JPanel implements PrefsTab { private final JCheckBox autoOpenForm; private final JCheckBox defSource; private final JCheckBox emacsMode; private final JCheckBox emacsRebindCtrlA; private final JCheckBox emacsRebindCtrlF; private final JCheckBox autoComplete; private final JCheckBox recommendations; private final JRadioButton autoCompBoth; private final JRadioButton autoCompFF; private final JRadioButton autoCompLF; private final JRadioButton firstNameModeFull; private final JRadioButton firstNameModeAbbr; private final JRadioButton firstNameModeBoth; private final JSpinner shortestToComplete; private final JTextField autoCompFields; private final JabRefPreferences prefs; private final AutoCompletePreferences autoCompletePreferences; public EntryEditorPrefsTab(JabRefPreferences prefs) { this.prefs = prefs; autoCompletePreferences = new AutoCompletePreferences(prefs); setLayout(new BorderLayout()); autoOpenForm = new JCheckBox(Localization.lang("Open editor when a new entry is created")); defSource = new JCheckBox(Localization.lang("Show BibTeX source by default")); emacsMode = new JCheckBox(Localization.lang("Use Emacs key bindings")); emacsRebindCtrlA = new JCheckBox(Localization.lang("Rebind C-a, too")); emacsRebindCtrlF = new JCheckBox(Localization.lang("Rebind C-f, too")); autoComplete = new JCheckBox(Localization.lang("Enable word/name autocompletion")); recommendations = new JCheckBox(Localization.lang("Show 'Related_Articles' tab")); shortestToComplete = new JSpinner( new SpinnerNumberModel(autoCompletePreferences.getShortestLengthToComplete(), 1, 5, 1)); // allowed name formats autoCompFF = new JRadioButton(Localization.lang("Autocomplete names in 'Firstname Lastname' format only")); autoCompLF = new JRadioButton(Localization.lang("Autocomplete names in 'Lastname, Firstname' format only")); autoCompBoth = new JRadioButton(Localization.lang("Autocomplete names in both formats")); ButtonGroup buttonGroup = new ButtonGroup(); buttonGroup.add(autoCompLF); buttonGroup.add(autoCompFF); buttonGroup.add(autoCompBoth); // treatment of first name firstNameModeFull = new JRadioButton(Localization.lang("Use full firstname whenever possible")); firstNameModeAbbr = new JRadioButton(Localization.lang("Use abbreviated firstname whenever possible")); firstNameModeBoth = new JRadioButton(Localization.lang("Use abbreviated and full firstname")); ButtonGroup firstNameModeButtonGroup = new ButtonGroup(); firstNameModeButtonGroup.add(firstNameModeFull); firstNameModeButtonGroup.add(firstNameModeAbbr); firstNameModeButtonGroup.add(firstNameModeBoth); Insets marg = new Insets(0, 20, 3, 0); emacsRebindCtrlA.setMargin(marg); // We need a listener on showSource to enable and disable the source panel-related choices: emacsMode.addChangeListener(event -> emacsRebindCtrlA.setEnabled(emacsMode.isSelected())); emacsRebindCtrlF.setMargin(marg); // We need a listener on showSource to enable and disable the source panel-related choices: emacsMode.addChangeListener(event -> emacsRebindCtrlF.setEnabled(emacsMode.isSelected())); autoCompFields = new JTextField(40); // We need a listener on autoComplete to enable and disable the // autoCompFields text field: autoComplete.addChangeListener(event -> setAutoCompleteElementsEnabled(autoComplete.isSelected())); FormLayout layout = new FormLayout (// columns "8dlu, left:pref, 8dlu, fill:150dlu, 4dlu, fill:pref", // 4dlu, left:pref, 4dlu", // rows 1 to 10 "pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu, pref, 6dlu, " + // rows 11 to 16 "pref, 6dlu, pref, 6dlu, pref, 6dlu, " + // rows 17 to 27 "pref, 6dlu, pref, pref, pref, pref, 6dlu, pref, pref, pref, pref"); DefaultFormBuilder builder = new DefaultFormBuilder(layout); CellConstraints cc = new CellConstraints(); builder.addSeparator(Localization.lang("Editor options"), cc.xyw(1, 1, 5)); builder.add(autoOpenForm, cc.xy(2, 3)); builder.add(defSource, cc.xy(2, 5)); builder.add(emacsMode, cc.xy(2, 7)); builder.add(emacsRebindCtrlA, cc.xy(2, 9)); builder.add(emacsRebindCtrlF, cc.xy(2, 11)); builder.add(recommendations, cc.xy(2,13)); builder.addSeparator(Localization.lang("Autocompletion options"), cc.xyw(1, 15, 5)); builder.add(autoComplete, cc.xy(2, 17)); DefaultFormBuilder builder3 = new DefaultFormBuilder(new FormLayout("left:pref, 4dlu, fill:150dlu","")); JLabel label = new JLabel(Localization.lang("Use autocompletion for the following fields") + ":"); builder3.append(label); builder3.append(autoCompFields); JLabel label2 = new JLabel(Localization.lang("Autocomplete after following number of characters") + ":"); builder3.append(label2); builder3.append(shortestToComplete); builder.add(builder3.getPanel(), cc.xyw(2, 19, 3)); builder.addSeparator(Localization.lang("Name format used for autocompletion"), cc.xyw(2, 21, 4)); builder.add(autoCompFF, cc.xy(2, 22)); builder.add(autoCompLF, cc.xy(2, 23)); builder.add(autoCompBoth, cc.xy(2, 24)); builder.addSeparator(Localization.lang("Treatment of first names"), cc.xyw(2, 26, 4)); builder.add(firstNameModeAbbr, cc.xy(2, 27)); builder.add(firstNameModeFull, cc.xy(2, 28)); builder.add(firstNameModeBoth, cc.xy(2, 29)); JPanel pan = builder.getPanel(); pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(pan, BorderLayout.CENTER); } private void setAutoCompleteElementsEnabled(boolean enabled) { autoCompFields.setEnabled(enabled); autoCompLF.setEnabled(enabled); autoCompFF.setEnabled(enabled); autoCompBoth.setEnabled(enabled); firstNameModeAbbr.setEnabled(enabled); firstNameModeFull.setEnabled(enabled); firstNameModeBoth.setEnabled(enabled); shortestToComplete.setEnabled(enabled); } @Override public void setValues() { autoOpenForm.setSelected(prefs.getBoolean(JabRefPreferences.AUTO_OPEN_FORM)); defSource.setSelected(prefs.getBoolean(JabRefPreferences.DEFAULT_SHOW_SOURCE)); emacsMode.setSelected(prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS)); emacsRebindCtrlA.setSelected(prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CA)); emacsRebindCtrlF.setSelected(prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CF)); recommendations.setSelected(prefs.getBoolean(JabRefPreferences.SHOW_RECOMMENDATIONS)); autoComplete.setSelected(prefs.getBoolean(JabRefPreferences.AUTO_COMPLETE)); autoCompFields.setText(autoCompletePreferences.getCompleteNamesAsString()); shortestToComplete.setValue(autoCompletePreferences.getShortestLengthToComplete()); if (autoCompletePreferences.getOnlyCompleteFirstLast()) { autoCompFF.setSelected(true); } else if (autoCompletePreferences.getOnlyCompleteLastFirst()) { autoCompLF.setSelected(true); } else { autoCompBoth.setSelected(true); } switch (autoCompletePreferences.getFirstnameMode()) { case ONLY_ABBREVIATED: firstNameModeAbbr.setSelected(true); break; case ONLY_FULL: firstNameModeFull.setSelected(true); break; default: firstNameModeBoth.setSelected(true); break; } // similar for emacs CTRL-a and emacs mode emacsRebindCtrlA.setEnabled(emacsMode.isSelected()); // Autocomplete fields is only enabled when autocompletion is selected setAutoCompleteElementsEnabled(autoComplete.isSelected()); } @Override public void storeSettings() { prefs.putBoolean(JabRefPreferences.AUTO_OPEN_FORM, autoOpenForm.isSelected()); prefs.putBoolean(JabRefPreferences.DEFAULT_SHOW_SOURCE, defSource.isSelected()); prefs.putBoolean(JabRefPreferences.SHOW_RECOMMENDATIONS, recommendations.isSelected()); boolean emacsModeChanged = prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS) != emacsMode.isSelected(); boolean emacsRebindCtrlAChanged = prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CA) != emacsRebindCtrlA.isSelected(); boolean emacsRebindCtrlFChanged = prefs.getBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CF) != emacsRebindCtrlF.isSelected(); if (emacsModeChanged || emacsRebindCtrlAChanged || emacsRebindCtrlFChanged) { prefs.putBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS, emacsMode.isSelected()); prefs.putBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CA, emacsRebindCtrlA.isSelected()); prefs.putBoolean(JabRefPreferences.EDITOR_EMACS_KEYBINDINGS_REBIND_CF, emacsRebindCtrlF.isSelected()); // immediately apply the change if (emacsModeChanged) { if (emacsMode.isSelected()) { EmacsKeyBindings.load(); } else { EmacsKeyBindings.unload(); } } else { // only rebinding of CTRL+a or CTRL+f changed assert emacsMode.isSelected(); // we simply reload the emacs mode to activate the CTRL+a/CTRL+f change EmacsKeyBindings.unload(); EmacsKeyBindings.load(); } } autoCompletePreferences.setShortestLengthToComplete((Integer) shortestToComplete.getValue()); prefs.putBoolean(JabRefPreferences.AUTO_COMPLETE, autoComplete.isSelected()); autoCompletePreferences.setCompleteNames(autoCompFields.getText()); if (autoCompBoth.isSelected()) { autoCompletePreferences.setOnlyCompleteFirstLast(false); autoCompletePreferences.setOnlyCompleteLastFirst(false); } else if (autoCompFF.isSelected()) { autoCompletePreferences.setOnlyCompleteFirstLast(true); autoCompletePreferences.setOnlyCompleteLastFirst(false); } else { autoCompletePreferences.setOnlyCompleteFirstLast(false); autoCompletePreferences.setOnlyCompleteLastFirst(true); } if (firstNameModeAbbr.isSelected()) { autoCompletePreferences.setFirstnameMode(AutoCompleteFirstNameMode.ONLY_ABBREVIATED); } else if (firstNameModeFull.isSelected()) { autoCompletePreferences.setFirstnameMode(AutoCompleteFirstNameMode.ONLY_FULL); } else { autoCompletePreferences.setFirstnameMode(AutoCompleteFirstNameMode.BOTH); } } @Override public boolean validateSettings() { return true; } @Override public String getTabName() { return Localization.lang("Entry editor"); } }