@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); } } }
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); } } }
@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)); }