/* 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+"));
}
}