/* * Copyright 2003 (C) Ross M. Lodge * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package plugin.dicebag; import gmgen.GMGenSystem; import gmgen.GMGenSystemView; import gmgen.pluginmgr.messages.AddMenuItemToGMGenToolsMenuMessage; import gmgen.pluginmgr.messages.FileMenuNewMessage; import gmgen.pluginmgr.messages.FileMenuOpenMessage; import gmgen.pluginmgr.messages.FileMenuSaveMessage; import gmgen.pluginmgr.messages.GMGenBeingClosedMessage; import gmgen.pluginmgr.messages.RequestAddTabToGMGenMessage; import java.awt.event.ActionEvent; import java.io.File; import java.net.URL; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JTabbedPane; import pcgen.core.SettingsHandler; import pcgen.gui2.tools.Utility; import pcgen.pluginmgr.InteractivePlugin; import pcgen.pluginmgr.PCGenMessage; import pcgen.pluginmgr.PCGenMessageHandler; import pcgen.pluginmgr.messages.FocusOrStateChangeOccurredMessage; import pcgen.system.LanguageBundle; import plugin.dicebag.gui.DiceBagPluginController; /** * @author RossLodge * * <p> * The base plugin class for the DiceBag plugin. This class handles mediation * between the GUI components of in {@code dicebag.gui} and the plugin * framework. This class should <b>not </b> pass framework events directly on to * the {@code dicebag.gui} classes, nor should those classes call the * framework directly. * </p> * */ public class DiceBagPlugin implements InteractivePlugin { /** Menu item command string for tools menu item */ private static final String DICEBAG_TOOLS_COMMAND = "TOOLS_MENU_ENTRY"; //$NON-NLS-1$ /** Name for logger.*/ public static final String LOG_NAME = "DiceBag"; //$NON-NLS-1$ /** * The controller object. Should handle only interface between this object and * the gui components/data. */ private DiceBagPluginController theController = null; /** Menu item for tools menu. Selects this tab. */ private JMenuItem notesToolsItem; private static final String NAME = "DiceBag"; //$NON-NLS-1$ /** Key of dice bag tab. */ private static final String IN_NAME = "in_plugin_dicebag_name"; //$NON-NLS-1$ /** Version number. (NOTE: does this mean anything?) */ private String version = "00.00.00.01"; //$NON-NLS-1$ private PCGenMessageHandler messageHandler; /** * <p> * Default (and only) constructor. Initializes the plugin. * </p> */ public DiceBagPlugin() { // Do Nothing } /** * <p> * Adds view panel via TabAddMessage and initializes the menu items. * </p> */ @Override public void start(PCGenMessageHandler mh) { messageHandler = mh; theController = new DiceBagPluginController(); messageHandler.handleMessage(new RequestAddTabToGMGenMessage(this, getLocalizedName(), theController.getComponent())); initMenus(); } @Override public void stop() { messageHandler = null; } @Override public int getPriority() { return SettingsHandler.getGMGenOption(DiceBagPlugin.LOG_NAME + ".LoadOrder", 20); } @Override public String getPluginName() { return DiceBagPlugin.NAME; } /** * <p> * Listens to messages on the GMGen Bus. Handles the following: * </p> * <ul> * <li>StateChangedMessage</li> * <li>WindowClosedMessage</li> * <li>FileOpenMessage</li> * <li>SaveMessage</li> * <li>LoadMessage</li> * </ul> * <p> * Delegates all these messages to {@code theController}. * </p> * @param message * * @see pcgen.pluginmgr.PCGenMessageHandler#handleMessage */ @Override public void handleMessage(PCGenMessage message) { if (message instanceof FocusOrStateChangeOccurredMessage) { handleStateChangedMessage(); } else if (message instanceof GMGenBeingClosedMessage) { handleWindowClosedMessage(); } else if (message instanceof FileMenuOpenMessage) { handleFileOpenMessage((FileMenuOpenMessage) message); } else if (message instanceof FileMenuSaveMessage) { handleSaveMessage((FileMenuSaveMessage) message); } else if (message instanceof FileMenuNewMessage) { handleLoadMessage((FileMenuNewMessage) message); } } /** * <p> * Selects the DiceBag component if in the tab list. * </p> * * @param evt * ActionEvent that fired this method. */ public void toolMenuItem(ActionEvent evt) { JTabbedPane tp = GMGenSystemView.getTabPane(); for (int i = 0; i < tp.getTabCount(); i++) { if (tp.getComponentAt(i).equals(theController.getComponent())) { tp.setSelectedIndex(i); } } } /** * <p> * Delegates this message to the controller by calling the controller's * {@code fileOpen()} method. We veto the message so it is not passed * on to other plugins. * </p> * * @param message * {@code FileOpenMessage} */ private void handleFileOpenMessage(FileMenuOpenMessage message) { if (GMGenSystemView.getTabPane().getSelectedComponent().equals( theController.getComponent())) { theController.fileOpen(); message.consume(); } } /** * <p> * Handles a LoadMessage. We interpret this as a fileNew command, and pass the * command on to the controller object. We also veto the message so that it is * not passed on to other plugins. * </p> * * @param message */ private void handleLoadMessage(FileMenuNewMessage message) { if (GMGenSystemView.getTabPane().getSelectedComponent().equals( theController.getComponent())) { theController.fileNew(); message.consume(); } } /** * <p> * Handles a SaveMessage. We pass this on to the controller, and veto the * message so that it is not passed on to other plugins. * </p> * * @param message */ private void handleSaveMessage(FileMenuSaveMessage message) { if (isActive()) { theController.fileSave(); message.consume(); } } /** * <p> * Handles a state changed message. Basically enables or disables applicable * menu items, refreshes data. * </p> * */ private void handleStateChangedMessage() { if (GMGenSystemView.getTabPane() != null) { if (isActive()) { notesToolsItem.setEnabled(false); GMGenSystem.inst.openFileItem.setEnabled(true); GMGenSystem.inst.saveFileItem.setEnabled(true); GMGenSystem.inst.newFileItem.setEnabled(true); } else { notesToolsItem.setEnabled(true); } } } /** * <p> * Calls the {@code windowClosed()} method of the controller. * </p> * */ private void handleWindowClosedMessage() { theController.windowClosed(); } /** * isActive * @return TRUE if active */ public boolean isActive() { JTabbedPane tp = Utility.getTabbedPaneFor(theController .getComponent()); return (tp != null) && JOptionPane.getFrameForComponent(tp).isFocused() && tp.getSelectedComponent().equals(theController.getComponent()); } /** * <p> * Adds DiceBag menu items to tools and menu. * </p> */ private void initMenus() { notesToolsItem = makeMenuItem(getLocalizedName(), DiceBagPlugin.DICEBAG_TOOLS_COMMAND, null, LanguageBundle.getString("in_plugin_dicebag_desc"), //$NON-NLS-1$ LanguageBundle.getMnemonic("in_mn_plugin_dicebag_name")); //$NON-NLS-1$ messageHandler.handleMessage(new AddMenuItemToGMGenToolsMenuMessage(this, notesToolsItem)); } private String getLocalizedName() { return LanguageBundle.getString(DiceBagPlugin.IN_NAME); } /** * <p> * Creates a menu item by constructing an action based on the specified * parameters. * </p> * * @param text * Text to appear in label. * @param key * Command string. * @param iconPath * Path to icon resource; may be null. Resolved with * getClass().getResource() * @param desc * Description (tool tip text) * @param mnemonic * Mnemonic integer. Should be from KeyEvents * @return A new JMenuItem */ private JMenuItem makeMenuItem(String text, String key, String iconPath, String desc, Integer mnemonic) { URL imageURL = null; if ((iconPath != null) && (!iconPath.isEmpty())) { imageURL = getClass().getResource(iconPath); } Action action; if (imageURL != null) { action = new ActionDelegate(text, new ImageIcon(imageURL)); } else { action = new ActionDelegate(text); } action.putValue(Action.SHORT_DESCRIPTION, desc); action.putValue(Action.MNEMONIC_KEY, mnemonic); action.putValue(Action.ACTION_COMMAND_KEY, key); return new JMenuItem(action); } /** * @author Ross Lodge * * <p> * Action class to handle all menu item actions. * </p> */ private final class ActionDelegate extends AbstractAction { /** * @see javax.swing.AbstractAction#AbstractAction(String) */ private ActionDelegate(String name) { super(name); } /** * @see javax.swing.AbstractAction#AbstractAction(String, Icon) */ private ActionDelegate(String name, Icon icon) { super(name, icon); } /* * (non-Javadoc) * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ @Override public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if (DiceBagPlugin.DICEBAG_TOOLS_COMMAND.equals(command)) { toolMenuItem(e); } } } /** * Gets the name of the data directory for Plugin object * *@return The data directory name */ @Override public File getDataDirectory() { return new File(SettingsHandler.getGmgenPluginDir(), getPluginName()); } }