/** Store changes to table preferences. This method is called when the user clicks Ok. */ @Override public void storeSettings() { prefs.putBoolean(JabRefPreferences.NAMES_AS_IS, namesAsIs.isSelected()); prefs.putBoolean(JabRefPreferences.NAMES_FIRST_LAST, namesFf.isSelected()); prefs.putBoolean(JabRefPreferences.NAMES_NATBIB, namesNatbib.isSelected()); prefs.putBoolean(JabRefPreferences.NAMES_LAST_ONLY, lastNamesOnly.isSelected()); prefs.putBoolean(JabRefPreferences.ABBR_AUTHOR_NAMES, abbrNames.isSelected()); prefs.putInt( JabRefPreferences.AUTO_RESIZE_MODE, autoResizeMode.isSelected() ? JTable.AUTO_RESIZE_ALL_COLUMNS : JTable.AUTO_RESIZE_OFF); prefs.putBoolean(JabRefPreferences.PRIMARY_SORT_DESCENDING, priDesc.isSelected()); prefs.putBoolean(JabRefPreferences.SECONDARY_SORT_DESCENDING, secDesc.isSelected()); prefs.putBoolean(JabRefPreferences.TERTIARY_SORT_DESCENDING, terDesc.isSelected()); prefs.put(JabRefPreferences.PRIMARY_SORT_FIELD, priField.getText().toLowerCase().trim()); prefs.put(JabRefPreferences.SECONDARY_SORT_FIELD, secField.getText().toLowerCase().trim()); prefs.put(JabRefPreferences.TERTIARY_SORT_FIELD, terField.getText().toLowerCase().trim()); prefs.putBoolean(JabRefPreferences.FLOAT_MARKED_ENTRIES, floatMarked.isSelected()); // updatefont String oldVal = prefs.get(JabRefPreferences.NUMERIC_FIELDS); String newVal = numericFields.getText().trim(); if (newVal.isEmpty()) { newVal = null; } if (newVal != null && oldVal == null || newVal == null && oldVal != null || newVal != null && !newVal.equals(oldVal)) { prefs.put(JabRefPreferences.NUMERIC_FIELDS, newVal); BibtexFields.setNumericFieldsFromPrefs(); } }
/** * Set column widths according to which field is shown, and lock icon columns to a suitable width. */ protected void setWidths() { TableColumnModel cm = entryTable.getColumnModel(); for (int i = 0; i < PAD; i++) { // Lock the width of icon columns. cm.getColumn(i).setPreferredWidth(GUIGlobals.WIDTH_ICON_COL); cm.getColumn(i).setMinWidth(GUIGlobals.WIDTH_ICON_COL); cm.getColumn(i).setMaxWidth(GUIGlobals.WIDTH_ICON_COL); } for (int i = 0; i < fields.length; i++) { int width = BibtexFields.getFieldLength(fields[i]); cm.getColumn(i + PAD).setPreferredWidth(width); } }
/** * Customization of external program paths. * * @param prefs a <code>JabRefPreferences</code> value */ public TablePrefsTab(JabRefPreferences prefs) { this.prefs = prefs; setLayout(new BorderLayout()); /** * Added Bibtexkey to combobox. * * <p>[ 1540646 ] default sort order: bibtexkey * * <p>http://sourceforge.net/tracker/index.php?func=detail&aid=1540646&group_id=92314&atid=600306 */ Vector<String> fieldNames = new Vector<String>(Arrays.asList(BibtexFields.getAllFieldNames())); fieldNames.add(BibtexFields.KEY_FIELD); Collections.sort(fieldNames); String[] allPlusKey = fieldNames.toArray(new String[fieldNames.size()]); priSort = new JComboBox(allPlusKey); secSort = new JComboBox(allPlusKey); terSort = new JComboBox(allPlusKey); autoResizeMode = new JCheckBox(Localization.lang("Fit table horizontally on screen")); namesAsIs = new JRadioButton(Localization.lang("Show names unchanged")); namesFf = new JRadioButton(Localization.lang("Show 'Firstname Lastname'")); namesFl = new JRadioButton(Localization.lang("Show 'Lastname, Firstname'")); namesNatbib = new JRadioButton(Localization.lang("Natbib style")); noAbbrNames = new JRadioButton(Localization.lang("Do not abbreviate names")); abbrNames = new JRadioButton(Localization.lang("Abbreviate names")); lastNamesOnly = new JRadioButton(Localization.lang("Show last names only")); floatMarked = new JCheckBox(Localization.lang("Float marked entries")); priField = new JTextField(10); secField = new JTextField(10); terField = new JTextField(10); numericFields = new JTextField(30); priSort.insertItemAt(Localization.lang("<select>"), 0); secSort.insertItemAt(Localization.lang("<select>"), 0); terSort.insertItemAt(Localization.lang("<select>"), 0); priSort.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (priSort.getSelectedIndex() > 0) { priField.setText(priSort.getSelectedItem().toString()); priSort.setSelectedIndex(0); } } }); secSort.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (secSort.getSelectedIndex() > 0) { secField.setText(secSort.getSelectedItem().toString()); secSort.setSelectedIndex(0); } } }); terSort.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (terSort.getSelectedIndex() > 0) { terField.setText(terSort.getSelectedItem().toString()); terSort.setSelectedIndex(0); } } }); ButtonGroup nameStyle = new ButtonGroup(); nameStyle.add(namesAsIs); nameStyle.add(namesNatbib); nameStyle.add(namesFf); nameStyle.add(namesFl); ButtonGroup nameAbbrev = new ButtonGroup(); nameAbbrev.add(lastNamesOnly); nameAbbrev.add(abbrNames); nameAbbrev.add(noAbbrNames); priDesc = new JCheckBox(Localization.lang("Descending")); secDesc = new JCheckBox(Localization.lang("Descending")); terDesc = new JCheckBox(Localization.lang("Descending")); FormLayout layout = new FormLayout( "1dlu, 8dlu, left:pref, 4dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, fill:pref", ""); DefaultFormBuilder builder = new DefaultFormBuilder(layout); JLabel lab; JPanel pan = new JPanel(); builder.appendSeparator(Localization.lang("Format of author and editor names")); DefaultFormBuilder nameBuilder = new DefaultFormBuilder(new FormLayout("left:pref, 8dlu, left:pref", "")); nameBuilder.append(namesAsIs); nameBuilder.append(noAbbrNames); nameBuilder.nextLine(); nameBuilder.append(namesFf); nameBuilder.append(abbrNames); nameBuilder.nextLine(); nameBuilder.append(namesFl); nameBuilder.append(lastNamesOnly); nameBuilder.nextLine(); nameBuilder.append(namesNatbib); builder.append(pan); builder.append(nameBuilder.getPanel()); builder.nextLine(); builder.appendSeparator(Localization.lang("Default sort criteria")); // Create a new panel with its own FormLayout for these items: FormLayout layout2 = new FormLayout("left:pref, 8dlu, fill:pref, 4dlu, fill:60dlu, 4dlu, left:pref", ""); DefaultFormBuilder builder2 = new DefaultFormBuilder(layout2); lab = new JLabel(Localization.lang("Primary sort criterion")); builder2.append(lab); builder2.append(priSort); builder2.append(priField); builder2.append(priDesc); builder2.nextLine(); lab = new JLabel(Localization.lang("Secondary sort criterion")); builder2.append(lab); builder2.append(secSort); builder2.append(secField); builder2.append(secDesc); builder2.nextLine(); lab = new JLabel(Localization.lang("Tertiary sort criterion")); builder2.append(lab); builder2.append(terSort); builder2.append(terField); builder2.append(terDesc); builder.nextLine(); builder.append(pan); builder.append(builder2.getPanel()); builder.nextLine(); builder.append(pan); builder.append(floatMarked); builder.nextLine(); builder.append(pan); builder2 = new DefaultFormBuilder(new FormLayout("left:pref, 8dlu, fill:pref", "")); builder2.append(Localization.lang("Sort the following fields as numeric fields") + ':'); builder2.append(numericFields); builder.append(builder2.getPanel(), 5); builder.nextLine(); builder.appendSeparator(Localization.lang("General")); builder.append(pan); builder.append(autoResizeMode); builder.nextLine(); pan = builder.getPanel(); pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(pan, BorderLayout.CENTER); namesNatbib.addChangeListener( new ChangeListener() { @Override public void stateChanged(ChangeEvent changeEvent) { abbrNames.setEnabled(!namesNatbib.isSelected()); lastNamesOnly.setEnabled(!namesNatbib.isSelected()); noAbbrNames.setEnabled(!namesNatbib.isSelected()); } }); }
public class EntryCustomizationDialog2 extends JDialog implements ListSelectionListener, ActionListener { private final JabRefFrame frame; protected GridBagLayout gbl = new GridBagLayout(); protected GridBagConstraints con = new GridBagConstraints(); private FieldSetComponent reqComp; private FieldSetComponent optComp; private FieldSetComponent optComp2; private EntryTypeList typeComp; private JButton ok; private JButton cancel; private JButton apply; protected JButton helpButton; protected JButton delete; protected JButton importTypes; protected JButton exportTypes; private final List<String> preset = java.util.Arrays.asList(BibtexFields.getAllFieldNames()); private String lastSelected = null; private final Map<String, List<String>> reqLists = new HashMap<String, List<String>>(); private final Map<String, List<String>> optLists = new HashMap<String, List<String>>(); private final Map<String, List<String>> opt2Lists = new HashMap<String, List<String>>(); private final Set<String> defaulted = new HashSet<String>(); private final Set<String> changed = new HashSet<String>(); private boolean biblatexMode; /** Creates a new instance of EntryCustomizationDialog2 */ public EntryCustomizationDialog2(JabRefFrame frame) { super(frame, Globals.lang("Customize entry types"), false); this.frame = frame; initGui(); } private void initGui() { Container pane = getContentPane(); pane.setLayout(new BorderLayout()); biblatexMode = Globals.prefs.getBoolean("biblatexMode"); JPanel main = new JPanel(), buttons = new JPanel(), right = new JPanel(); main.setLayout(new BorderLayout()); right.setLayout(new GridLayout(biblatexMode ? 2 : 1, 2)); java.util.List<String> entryTypes = new ArrayList<String>(); for (String s : BibtexEntryType.ALL_TYPES.keySet()) { entryTypes.add(s); } typeComp = new EntryTypeList(entryTypes); typeComp.addListSelectionListener(this); typeComp.addAdditionActionListener(this); typeComp.addDefaultActionListener(new DefaultListener()); typeComp.setListSelectionMode(ListSelectionModel.SINGLE_SELECTION); // typeComp.setEnabled(false); reqComp = new FieldSetComponent( Globals.lang("Required fields"), new ArrayList<String>(), preset, true, true); reqComp.setEnabled(false); reqComp.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); ListDataListener dataListener = new DataListener(); reqComp.addListDataListener(dataListener); optComp = new FieldSetComponent( Globals.lang("Optional fields"), new ArrayList<String>(), preset, true, true); optComp.setEnabled(false); optComp.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); optComp.addListDataListener(dataListener); right.add(reqComp); right.add(optComp); if (biblatexMode) { optComp2 = new FieldSetComponent( Globals.lang("Optional fields") + " 2", new ArrayList<String>(), preset, true, true); optComp2.setEnabled(false); optComp2.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); optComp2.addListDataListener(dataListener); right.add(new JPanel()); right.add(optComp2); } // right.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), // Globals.lang("Fields"))); right.setBorder(BorderFactory.createEtchedBorder()); ok = new JButton("Ok"); cancel = new JButton(Globals.lang("Cancel")); apply = new JButton(Globals.lang("Apply")); ok.addActionListener(this); apply.addActionListener(this); cancel.addActionListener(this); ButtonBarBuilder bb = new ButtonBarBuilder(buttons); buttons.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); bb.addGlue(); bb.addButton(ok); bb.addButton(apply); bb.addButton(cancel); bb.addGlue(); AbstractAction closeAction = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { dispose(); } }; ActionMap am = main.getActionMap(); InputMap im = main.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); im.put(Globals.prefs.getKey("Close dialog"), "close"); am.put("close", closeAction); // con.fill = GridBagConstraints.BOTH; // con.weightx = 0.3; // con.weighty = 1; // gbl.setConstraints(typeComp, con); main.add(typeComp, BorderLayout.WEST); main.add(right, BorderLayout.CENTER); main.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); pane.add(main, BorderLayout.CENTER); pane.add(buttons, BorderLayout.SOUTH); pack(); } @Override public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) { return; } if (lastSelected != null) { // The entry type lastSelected is now unselected, so we store the current settings // for that type in our two maps. reqLists.put(lastSelected, reqComp.getFields()); optLists.put(lastSelected, optComp.getFields()); if (biblatexMode) { opt2Lists.put(lastSelected, optComp2.getFields()); } } String s = typeComp.getFirstSelected(); if (s == null) { return; } List<String> rl = reqLists.get(s); if (rl == null) { BibtexEntryType type = BibtexEntryType.getType(s); if (type != null) { String[] rf = type.getRequiredFieldsForCustomization(), of = type.getOptionalFields(); List<String> req, opt; if (rf != null) { req = java.util.Arrays.asList(rf); } else { req = new ArrayList<String>(); } if (!biblatexMode) { if (of != null) { opt = java.util.Arrays.asList(of); } else { opt = new ArrayList<String>(); } } else { String[] priOf = type.getPrimaryOptionalFields(); if (priOf != null) { opt = java.util.Arrays.asList(priOf); } else { opt = new ArrayList<String>(); } List<String> opt2 = new ArrayList<String>(); if (of != null) { for (String anOf : of) { if (!opt.contains(anOf)) { opt2.add(anOf); } } } optComp2.setFields(opt2); optComp2.setEnabled(true); } reqComp.setFields(req); reqComp.setEnabled(true); optComp.setFields(opt); optComp.setEnabled(true); } else { // New entry, veintle reqComp.setFields(new ArrayList<String>()); reqComp.setEnabled(true); optComp.setFields(new ArrayList<String>()); optComp.setEnabled(true); if (biblatexMode) { optComp2.setFields(new ArrayList<String>()); optComp2.setEnabled(true); } new FocusRequester(reqComp); } } else { reqComp.setFields(rl); optComp.setFields(optLists.get(s)); if (biblatexMode) { optComp2.setFields(opt2Lists.get(s)); } } lastSelected = s; typeComp.enable(s, changed.contains(lastSelected) && !defaulted.contains(lastSelected)); } private void applyChanges() { valueChanged(new ListSelectionEvent(new JList(), 0, 0, false)); // Iterate over our map of required fields, and list those types if necessary: List<String> types = typeComp.getFields(); for (Map.Entry<String, List<String>> stringListEntry : reqLists.entrySet()) { if (!types.contains(stringListEntry.getKey())) { continue; } List<String> reqFields = stringListEntry.getValue(); List<String> optFields = optLists.get(stringListEntry.getKey()); List<String> opt2Fields = opt2Lists.get(stringListEntry.getKey()); String[] reqStr = new String[reqFields.size()]; reqStr = reqFields.toArray(reqStr); String[] optStr = new String[optFields.size()]; optStr = optFields.toArray(optStr); String[] opt2Str; if (opt2Fields != null) { opt2Str = opt2Fields.toArray(new String[opt2Fields.size()]); } else { opt2Str = new String[0]; } // If this type is already existing, check if any changes have // been made boolean changesMade = true; if (defaulted.contains(stringListEntry.getKey())) { // This type should be reverted to its default setup. // System.out.println("Defaulting: "+typeName); String nm = StringUtil.nCase(stringListEntry.getKey()); BibtexEntryType.removeType(nm); updateTypesForEntries(nm); continue; } BibtexEntryType oldType = BibtexEntryType.getType(stringListEntry.getKey()); if (oldType != null) { String[] oldReq = oldType.getRequiredFields(), oldOpt = oldType.getOptionalFields(); if (biblatexMode) { String[] priOpt = oldType.getPrimaryOptionalFields(); String[] secOpt = Util.getRemainder(oldOpt, priOpt); if (equalArrays(oldReq, reqStr) && equalArrays(oldOpt, optStr) && equalArrays(secOpt, opt2Str)) { changesMade = false; } } else if (equalArrays(oldReq, reqStr) && equalArrays(oldOpt, optStr)) { changesMade = false; } } if (changesMade) { // System.out.println("Updating: "+typeName); CustomEntryType typ = biblatexMode ? new CustomEntryType( StringUtil.nCase(stringListEntry.getKey()), reqStr, optStr, opt2Str) : new CustomEntryType(StringUtil.nCase(stringListEntry.getKey()), reqStr, optStr); BibtexEntryType.ALL_TYPES.put(stringListEntry.getKey().toLowerCase(), typ); updateTypesForEntries(typ.getName()); } } Set<Object> toRemove = new HashSet<Object>(); for (String o : BibtexEntryType.ALL_TYPES.keySet()) { if (!types.contains(o)) { toRemove.add(o); } } // Remove those that should be removed: if (!toRemove.isEmpty()) { for (Object aToRemove : toRemove) { typeDeletion((String) aToRemove); } } updateTables(); } private void typeDeletion(String name) { BibtexEntryType type = BibtexEntryType.getType(name); if (type instanceof CustomEntryType) { if (BibtexEntryType.getStandardType(name) == null) { int reply = JOptionPane.showConfirmDialog( frame, Globals.lang( "All entries of this " + "type will be declared " + "typeless. Continue?"), Globals.lang("Delete custom format") + " '" + StringUtil.nCase(name) + '\'', JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (reply != JOptionPane.YES_OPTION) { return; } } BibtexEntryType.removeType(name); updateTypesForEntries(StringUtil.nCase(name)); changed.remove(name); reqLists.remove(name); optLists.remove(name); if (biblatexMode) { opt2Lists.remove(name); } } // messageLabel.setText("'"+type.getName()+"' "+ // Globals.lang("is a standard type.")); } private boolean equalArrays(String[] one, String[] two) { if ((one == null) && (two == null)) { return true; // Both null. } if ((one == null) || (two == null)) { return false; // One of them null, the other not. } if (one.length != two.length) { return false; // Different length. } // If we get here, we know that both are non-null, and that they have the same length. for (int i = 0; i < one.length; i++) { if (!one[i].equals(two[i])) { return false; } } // If we get here, all entries have matched. return true; } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == ok) { applyChanges(); dispose(); } else if (e.getSource() == cancel) { dispose(); } else if (e.getSource() == apply) { applyChanges(); } else if (e.getSource() == typeComp) { // System.out.println("add: "+e.getActionCommand()); typeComp.selectField(e.getActionCommand()); } } /** * Cycle through all databases, and make sure everything is updated with the new type * customization. This includes making sure all entries have a valid type, that no obsolete entry * editors are around, and that the right-click menus' change type menu is up-to-date. */ private void updateTypesForEntries(String typeName) { if (frame.getTabbedPane().getTabCount() == 0) { return; } for (int i = 0; i < frame.getTabbedPane().getTabCount(); i++) { BasePanel bp = (BasePanel) frame.getTabbedPane().getComponentAt(i); // Invalidate associated cached entry editor bp.entryEditors.remove(typeName); for (BibtexEntry entry : bp.database().getEntries()) { entry.updateType(); } } } private void updateTables() { if (frame.getTabbedPane().getTabCount() == 0) { return; } for (int i = 0; i < frame.getTabbedPane().getTabCount(); i++) { frame.getTabbedPane().getComponentAt(i); } } // DEFAULT button pressed. Remember that this entry should be reset to default, // unless changes are made later. private class DefaultListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { if (lastSelected == null) { return; } defaulted.add(lastSelected); BibtexEntryType type = BibtexEntryType.getStandardType(lastSelected); if (type != null) { String[] rf = type.getRequiredFieldsForCustomization(), of = type.getOptionalFields(); List<String> req, opt1, opt2; if (rf != null) { req = java.util.Arrays.asList(rf); } else { req = new ArrayList<String>(); } opt1 = new ArrayList<String>(); opt2 = new ArrayList<String>(); if (biblatexMode) { if (of != null) { String[] priOptArray = type.getPrimaryOptionalFields(); String[] secOptArray = Util.getRemainder(of, priOptArray); if (priOptArray != null) { opt1 = java.util.Arrays.asList(priOptArray); } if (secOptArray != null) { opt2 = java.util.Arrays.asList(secOptArray); } } } else { if (of != null) { opt1 = java.util.Arrays.asList(of); } } reqComp.setFields(req); reqComp.setEnabled(true); optComp.setFields(opt1); if (biblatexMode) { optComp2.setFields(opt2); } } } } class DataListener implements ListDataListener { @Override public void intervalAdded(javax.swing.event.ListDataEvent e) { record(); } @Override public void intervalRemoved(javax.swing.event.ListDataEvent e) { record(); } @Override public void contentsChanged(javax.swing.event.ListDataEvent e) { record(); } private void record() { if (lastSelected == null) { return; } defaulted.remove(lastSelected); changed.add(lastSelected); typeComp.enable(lastSelected, true); } } }