package org.alastairmailer;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.net.URL;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import net.sf.jabref.BasePanel;
import net.sf.jabref.JabRefFrame;
import net.sf.jabref.SidePaneComponent;
import net.sf.jabref.SidePaneManager;
import net.sf.jabref.plugin.PluginCore;
import net.sf.jabref.plugin.SidePanePlugin;
import org.java.plugin.Plugin;
import org.java.plugin.registry.PluginDescriptor;
/**
* The base class for the plugin. Basically, presents a LuceneSidePanel when requested
* to by JabRef and keeps track of any static plugin resources.
*
* @author agm
*
*/
public class LuceneSidePanelPlugin extends Plugin implements SidePanePlugin {
/**
* A little logo for the plugin.
*/
public static final ImageIcon SEARCH_ICON = new ImageIcon(getResourceURL("./images/search-button.png"));
/**
* Converts a plugin local path to a URL for the system the plugin is running on.
*
* @param local Local path to resource
* @return Absolute URL to resource
*/
public static URL getResourceURL(String local) {
PluginDescriptor myPlugin = PluginCore.getManager().getRegistry().getPluginDescriptor("org.alastairmailer.luceneplugin");
return PluginCore.getManager().getPathResolver().resolvePath(myPlugin, local);
}
private SidePaneManager myManager;
private LuceneSidePanel myPanel;
private JMenuItem myMenuItem;
private JabRefFrame jrFrame;
private Vector<LuceneBibtexDatabase> databases;
private JTabbedPane tp;
/**
* Returns the list of LuceneBibtexDatabase objects representing currently open DBs
* @return
*/
public synchronized Vector<LuceneBibtexDatabase> getDatabases() {
return databases;
}
/* This method run on plugin initialisation. doStart() doesn't seem to be called
* before the plugin has to do stuff, so loadHandlers and setupDatabases are done
* here
*
* (non-Javadoc)
* @see net.sf.jabref.plugin.SidePanePlugin#init(net.sf.jabref.JabRefFrame, net.sf.jabref.SidePaneManager)
*/
public void init(JabRefFrame frame, SidePaneManager manager) {
myManager = manager;
jrFrame = frame;
myPanel = new LuceneSidePanel(this, manager, getResourceURL("images/search-button.png"), "Search file directory");
myMenuItem = new JMenuItem("Search file directory", SEARCH_ICON);
myMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a) {
myManager.show(myPanel.getName());
checkDatabases();
}
});
FiletypeHandler.loadHandlers();
setupDatabases();
}
private void checkDatabases() {
// Check to see if currently open databases are searchable, and ask to recify the situation if not
for (LuceneBibtexDatabase ldb : databases) {
String lDBName = ldb.toString();
if (!ldb.isIndexed()) {
int confirmOptions = JOptionPane.showConfirmDialog(this.myPanel, "The database \'" + lDBName + "\' is not currently searchable.\nWould you like to open the settings dialog to configure searching now?", "Configure options now?", JOptionPane.YES_NO_OPTION);
if (confirmOptions == JOptionPane.YES_OPTION) {
LuceneOptionsUI options = new LuceneOptionsUI(jrFrame, true, this, ldb);
options.setVisible(true);
}
}
}
}
private void setupDatabases() {
// Fill databases variable
databases = new Vector<LuceneBibtexDatabase>();
for (int i = 0; i < jrFrame.baseCount(); i++) {
databases.add(new LuceneBibtexDatabase(jrFrame.baseAt(i)));
}
// Setup open/close database listeners
tp = jrFrame.getTabbedPane();
tp.addContainerListener(new ContainerListener() {
public void componentAdded(ContainerEvent ce) {
BasePanel bp = (BasePanel) ce.getChild();
databases.add(new LuceneBibtexDatabase(bp));
}
public void componentRemoved(ContainerEvent ce) {
BasePanel bp = (BasePanel) ce.getChild();
LuceneBibtexDatabase toRemove = null;
for (LuceneBibtexDatabase ldb : databases) {
if (ldb.getBp() == bp) {
toRemove = ldb;
}
}
toRemove.stopUpdateMonitor();
databases.remove(toRemove);
}
});
}
public JabRefFrame getFrame() {
return jrFrame;
}
public JMenuItem getMenuItem() {
return myMenuItem;
}
public String getShortcutKey() {
return "Ctrl-A";
}
public SidePaneComponent getSidePaneComponent() {
return myPanel;
}
/**
* This class represents the graphical side panel which appears when you activate
* the plugin from the Plugins menu in JabRef.
*
* @author agm
*
*/
@SuppressWarnings("serial")
private class LuceneSidePanel extends SidePaneComponent {
JPanel myPanel;
JTextField searchQuery;
JButton searchButton;
JButton optionsButton;
LuceneSidePanelPlugin plugin;
public LuceneSidePanel(final LuceneSidePanelPlugin plugin, SidePaneManager manager, URL icon, String title) {
super(manager, icon, title);
this.plugin = plugin;
myPanel = new JPanel(new GridLayout(3, 1));
searchQuery = new JTextField();
myPanel.add(searchQuery);
searchButton = new JButton("Search");
myPanel.add(searchButton);
optionsButton = new JButton("Options");
myPanel.add(optionsButton);
setContent(myPanel);
searchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a) { runQuery(); }
});
searchQuery.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a) { runQuery(); }
});
optionsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
LuceneOptionsUI options = new LuceneOptionsUI(jrFrame, true, plugin);
options.setVisible(true);
}
});
}
private void runQuery() {
// Check if current db is in searchable state
LuceneBibtexDatabase ldb = null;
BasePanel current = jrFrame.basePanel();
for (LuceneBibtexDatabase db: databases) {
if (db.getBp() == current) {
ldb = db;
}
}
if (!ldb.isIndexed()) {
JOptionPane.showMessageDialog(jrFrame, "Database \'" + ldb.toString() + "\' is not searchable. Please check search options.", "Database not searchable", JOptionPane.ERROR_MESSAGE);
return;
} else {
LuceneSearchPanel search = new LuceneSearchPanel(plugin, ldb);
search.setVisible(true);
search.runQuery(searchQuery.getText());
}
}
@Override
public String getName() {
return "Lucene";
}
}
@Override
protected void doStart() throws Exception {
}
@Override
protected void doStop() throws Exception {
}
}