/* Copyright (C) 2003-2011 JabRef contributors. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package net.sf.jabref.groups; import java.awt.BorderLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashSet; import java.util.List; import java.util.ArrayList; import java.util.Set; import javax.swing.*; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import net.sf.jabref.BasePanel; import net.sf.jabref.Globals; import net.sf.jabref.JabRefFrame; import net.sf.jabref.Util; import net.sf.jabref.undo.NamedCompound; import com.jgoodies.forms.builder.DefaultFormBuilder; import com.jgoodies.forms.builder.ButtonBarBuilder; import com.jgoodies.forms.layout.FormLayout; /** * Dialog for creating or modifying groups. Operates directly on the Vector * containing group information. */ class AutoGroupDialog extends JDialog implements CaretListener { JTextField remove = new JTextField(60), field = new JTextField(60), deliminator = new JTextField(60); JLabel nf = new JLabel(Globals.lang("Field to group by") + ":"), nr = new JLabel(Globals.lang("Characters to ignore") + ":"); JRadioButton keywords = new JRadioButton(Globals.lang("Generate groups from keywords in a BibTeX field")), authors = new JRadioButton(Globals.lang("Generate groups for author last names")), editors = new JRadioButton(Globals.lang("Generate groups for editor last names")); JCheckBox nd = new JCheckBox(Globals.lang("Use the following delimiter character(s):")); JButton ok = new JButton(Globals.lang("Ok")), cancel = new JButton(Globals.lang("Cancel")); JPanel main = new JPanel(), opt = new JPanel(); private boolean ok_pressed = false; private GroupTreeNode m_groupsRoot; private JabRefFrame frame; private BasePanel panel; private GroupSelector gs; private String oldRemove, oldField; GridBagLayout gbl = new GridBagLayout(); GridBagConstraints con = new GridBagConstraints(); /** * @param groupsRoot * The original set of groups, which is required as undo * information when all groups are cleared. */ public AutoGroupDialog(JabRefFrame jabrefFrame, BasePanel basePanel, GroupSelector groupSelector, GroupTreeNode groupsRoot, String defaultField, String defaultRemove, String defaultDeliminator) { super(jabrefFrame, Globals.lang("Automatically create groups"), true); frame = jabrefFrame; gs = groupSelector; panel = basePanel; m_groupsRoot = groupsRoot; field.setText(defaultField); remove.setText(defaultRemove); deliminator.setText(defaultDeliminator); nd.setSelected(true); ActionListener okListener = new ActionListener() { public void actionPerformed(ActionEvent e) { ok_pressed = true; dispose(); GroupTreeNode autoGroupsRoot = new GroupTreeNode( new ExplicitGroup(Globals.lang("Automatically created groups"), AbstractGroup.INCLUDING)); Set<String> hs = null; String field = field(); if (keywords.isSelected()) { if (nd.isSelected()) { hs = Util .findDeliminatedWordsInField(panel.getDatabase(), field().toLowerCase().trim(), deliminator .getText()); } else { hs = Util.findAllWordsInField(panel.getDatabase(), field().toLowerCase().trim(), remove()); } } else if (authors.isSelected()) { List<String> fields = new ArrayList<String>(2); fields.add("author"); hs = Util.findAuthorLastNames(panel.getDatabase(), fields); field = "author"; } else if (editors.isSelected()) { List<String> fields = new ArrayList<String>(2); fields.add("editor"); hs = Util.findAuthorLastNames(panel.getDatabase(), fields); field = "editor"; } for (String keyword : hs){ KeywordGroup group = new KeywordGroup(keyword, field, keyword, false, false, AbstractGroup.INDEPENDENT); autoGroupsRoot.add(new GroupTreeNode(group)); } m_groupsRoot.add(autoGroupsRoot); NamedCompound ce = new NamedCompound(Globals .lang("Autogenerate groups")); UndoableAddOrRemoveGroup undo = new UndoableAddOrRemoveGroup( gs, m_groupsRoot, autoGroupsRoot, UndoableAddOrRemoveGroup.ADD_NODE); undo.setRevalidate(true); ce.addEdit(undo); panel.markBaseChanged(); // a change always occurs gs.revalidateGroups(); frame.output(Globals.lang("Created groups.")); ce.end(); panel.undoManager.addEdit(ce); } }; remove.addActionListener(okListener); field.addActionListener(okListener); field.addCaretListener(this); AbstractAction cancelAction = new AbstractAction() { public void actionPerformed(ActionEvent e) { dispose(); } }; cancel.addActionListener(cancelAction); ok.addActionListener(okListener); // Key bindings: ActionMap am = main.getActionMap(); InputMap im = main.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); im.put(frame.prefs().getKey("Close dialog"), "close"); am.put("close", cancelAction); ButtonGroup bg = new ButtonGroup(); bg.add(keywords); bg.add(authors); bg.add(editors); keywords.setSelected(true); DefaultFormBuilder b = new DefaultFormBuilder(new FormLayout ("left:20dlu, 4dlu, left:pref, 4dlu, fill:60dlu, 4dlu, fill:0dlu", ""), main); b.append(keywords, 5); b.nextLine(); b.append(new JPanel()); b.append(Globals.lang("Field to group by")+":"); b.append(field); b.nextLine(); b.append(new JPanel()); b.append(Globals.lang("Characters to ignore")+":"); b.append(remove); b.nextLine(); b.append(new JPanel()); b.append(nd); b.append(deliminator); b.nextLine(); b.append(authors, 5); b.nextLine(); b.append(editors, 5); b.nextLine(); ButtonBarBuilder bb = new ButtonBarBuilder(opt); bb.addGlue(); bb.addButton(ok); bb.addButton(cancel); bb.addGlue(); // Layout starts here. /*main.setLayout(gbl); opt.setLayout(gbl); main.setBorder(BorderFactory.createTitledBorder(BorderFactory .createEtchedBorder(), Globals.lang("Group properties"))); // Main panel: con.weightx = 0; con.gridwidth = 1; con.insets = new Insets(3, 5, 3, 5); con.anchor = GridBagConstraints.EAST; con.fill = GridBagConstraints.NONE; con.gridx = 0; con.gridy = 0; gbl.setConstraints(nf, con); main.add(nf); con.gridy = 1; gbl.setConstraints(nr, con); main.add(nr); con.gridy = 2; gbl.setConstraints(nd, con); main.add(nd); con.weightx = 1; con.anchor = GridBagConstraints.WEST; con.fill = GridBagConstraints.HORIZONTAL; con.gridy = 0; con.gridx = 1; gbl.setConstraints(field, con); main.add(field); con.gridy = 1; gbl.setConstraints(remove, con); main.add(remove); con.gridy = 2; gbl.setConstraints(deliminator, con); main.add(deliminator); // Option buttons: con.gridx = GridBagConstraints.RELATIVE; con.gridy = GridBagConstraints.RELATIVE; con.weightx = 1; con.gridwidth = 1; con.anchor = GridBagConstraints.EAST; con.fill = GridBagConstraints.NONE; gbl.setConstraints(ok, con); opt.add(ok); con.anchor = GridBagConstraints.WEST; con.gridwidth = GridBagConstraints.REMAINDER; gbl.setConstraints(cancel, con); opt.add(cancel);*/ main.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); opt.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); getContentPane().add(main, BorderLayout.CENTER); getContentPane().add(opt, BorderLayout.SOUTH); // pack(); updateComponents(); pack(); Util.placeDialog(this, frame); } public boolean okPressed() { return ok_pressed; } public String oldField() { return oldField; } public String oldRemove() { return oldRemove; } public String field() { return field.getText(); } public String remove() { return remove.getText(); } public void caretUpdate(CaretEvent e) { updateComponents(); } protected void updateComponents() { String groupField = field.getText().trim(); ok.setEnabled(groupField.matches("\\w+")); } }