/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.designer.core.xul;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.Action;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.KeyStroke;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.designer.core.DesignerContextComponent;
import org.pentaho.reporting.designer.core.ReportDesignerContext;
import org.pentaho.reporting.designer.core.actions.DesignerContextAction;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import org.pentaho.ui.xul.XulComponent;
import org.pentaho.ui.xul.XulDomContainer;
import org.pentaho.ui.xul.components.XulMenuitem;
import org.pentaho.ui.xul.dom.Element;
import org.pentaho.ui.xul.impl.AbstractXulComponent;
import org.pentaho.ui.xul.swing.SwingElement;
/**
* Todo: Document Me
*
* @author Thomas Morgner
*/
public class ActionSwingMenuitem extends SwingElement implements DesignerContextComponent, XulMenuitem
{
private class InlineActionForward implements ActionListener
{
protected InlineActionForward()
{
}
public void actionPerformed(final ActionEvent evt)
{
final String command = getCommand();
if (command != null)
{
invoke(command);
}
}
}
private static final Log logger = LogFactory.getLog(ActionSwingMenuitem.class);
protected class ActionChangeHandler implements PropertyChangeListener
{
protected ActionChangeHandler()
{
}
/**
* Receives notification of a property change event.
*
* @param event the property change event.
*/
public void propertyChange(final PropertyChangeEvent event)
{
try
{
final String propertyName = event.getPropertyName();
final Action actionImpl = getActionImpl();
if ("selected".equals(propertyName) ||//NON-NLS
Action.SELECTED_KEY.equals(propertyName))
{
setSelected(Boolean.TRUE.equals(event.getNewValue()));
}
else if ("enabled".equals(propertyName))//NON-NLS
{
setDisabled(actionImpl.isEnabled() == false);
}
else if ("visible".equals(propertyName)) //NON-NLS
{
setVisible(Boolean.TRUE.equals(event.getNewValue()));
}
else if (propertyName.equals(Action.NAME))
{
setLabel((String) actionImpl.getValue(Action.NAME));
}
else if (propertyName.equals(Action.SHORT_DESCRIPTION))
{
ActionSwingMenuitem.this.setTooltiptext((String)
actionImpl.getValue(Action.SHORT_DESCRIPTION));
}
if (propertyName.equals(Action.ACCELERATOR_KEY))
{
refreshKeystroke(actionImpl);
}
else if (propertyName.equals(Action.MNEMONIC_KEY))
{
refreshMnemonic(actionImpl);
}
}
catch (Exception e)
{
ActionSwingMenuitem.logger.warn("Error on PropertyChange in ActionSwingMenuItem: ", e);//NON-NLS
}
}
}
private String image;
private String onCommand;
private JMenuItem menuitem;
private Action action;
private String actionClass;
private ActionChangeHandler actionChangeHandler;
private ReportDesignerContext reportDesignerContext;
public static final String RADIO_MENUITEM = "radio-menuitem";
public static final String CHECKBOX_MENUITEM = "checkbox-menuitem";
public static final String MENUITEM = "menuitem";
public ActionSwingMenuitem(final Element self,
final XulComponent parent,
final XulDomContainer domContainer,
final String tagName)
{
this(tagName);
}
public ActionSwingMenuitem(final String tagName)
{
super(tagName);
this.actionChangeHandler = new ActionChangeHandler();
this.menuitem = createComponent(tagName);
this.menuitem.addActionListener(new InlineActionForward());
setManagedObject(menuitem);
}
protected ActionChangeHandler getActionChangeHandler()
{
return actionChangeHandler;
}
protected void setActionChangeHandler(final ActionChangeHandler actionChangeHandler)
{
this.actionChangeHandler = actionChangeHandler;
}
protected JMenuItem createComponent(final String tagName)
{
if (RADIO_MENUITEM.equalsIgnoreCase(tagName))
{
return new JRadioButtonMenuItem();
}
else if (CHECKBOX_MENUITEM.equalsIgnoreCase(tagName))
{
return new JCheckBoxMenuItem();
}
else
{
return new JMenuItem();
}
}
public String getAcceltext()
{
return String.valueOf(menuitem.getAccelerator().getKeyChar());
}
public String getAccesskey()
{
if (menuitem.getDisplayedMnemonicIndex() == -1)
{
return null;
}
return String.valueOf(menuitem.getText().charAt(menuitem.getDisplayedMnemonicIndex()));
}
protected Action getActionImpl()
{
return action;
}
public String getAction()
{
return actionClass;
}
public void setAction(final Action action)
{
if (this.action != null)
{
this.action.removePropertyChangeListener(actionChangeHandler);
uninstallAction(this.action);
}
if (action != null)
{
this.actionClass = action.getClass().getName();
this.action = action;
}
else
{
this.actionClass = null;
this.action = null;
}
if (this.action != null)
{
this.action.addPropertyChangeListener(actionChangeHandler);
installAction(this.action);
}
}
public void setAction(final String action)
{
if (this.action != null)
{
this.action.removePropertyChangeListener(actionChangeHandler);
uninstallAction(this.action);
}
this.actionClass = action;
if (this.actionClass != null)
{
this.action = ObjectUtilities.loadAndInstantiate(actionClass, ActionSwingMenuitem.class, Action.class);
}
if (this.action != null)
{
this.action.addPropertyChangeListener(actionChangeHandler);
installAction(this.action);
}
}
protected void uninstallAction(final Action oldAction)
{
if (oldAction != null)
{
menuitem.removeActionListener(oldAction);
oldAction.removePropertyChangeListener(actionChangeHandler);
final Object o = oldAction.getValue(Action.ACCELERATOR_KEY);
if (o instanceof KeyStroke)
{
final KeyStroke k = (KeyStroke) o;
menuitem.unregisterKeyboardAction(k);
}
}
}
protected void installAction(final Action newAction)
{
if (newAction != null)
{
menuitem.addActionListener(newAction);
newAction.addPropertyChangeListener(actionChangeHandler);
setLabel((String) (newAction.getValue(Action.NAME)));
setTooltiptext((String) (newAction.getValue(Action.SHORT_DESCRIPTION)));
setDisabled(this.action.isEnabled() == false);
refreshMnemonic(newAction);
refreshKeystroke(newAction);
final Object rawSelectedSwing = action.getValue(Action.SELECTED_KEY);
if (rawSelectedSwing != null)
{
setSelected(Boolean.TRUE.equals(rawSelectedSwing));
}
else
{
final Object rawSelectedPrd = action.getValue("selected");
setSelected(Boolean.TRUE.equals(rawSelectedPrd));
}
final Object rawVisible = action.getValue("visible");
if (rawVisible != null)
{
setVisible(Boolean.TRUE.equals(rawVisible));
}
}
}
public void setReportDesignerContext(final ReportDesignerContext context)
{
this.reportDesignerContext = context;
if (action instanceof DesignerContextAction)
{
final DesignerContextAction dca = (DesignerContextAction) action;
dca.setReportDesignerContext(reportDesignerContext);
}
}
public ReportDesignerContext getReportDesignerContext()
{
return reportDesignerContext;
}
public boolean isDisabled()
{
return !menuitem.isEnabled();
}
public String getLabel()
{
return menuitem.getText();
}
public void setAcceltext(final String accel)
{
menuitem.setAccelerator(KeyStroke.getKeyStroke(accel));
}
public void setAccesskey(final String accessKey)
{
if (accessKey == null || accessKey.length() == 0)
{
menuitem.setMnemonic(0);
}
else
{
menuitem.setMnemonic(accessKey.charAt(0));
}
}
public void setDisabled(final boolean disabled)
{
menuitem.setEnabled(!disabled);
}
public void setDisabled(final String disabled)
{
menuitem.setEnabled(!Boolean.parseBoolean(disabled));
}
public void setVisible(final boolean visible)
{
super.setVisible(visible);
menuitem.setVisible(visible);
final XulComponent parent = getParent();
if (parent instanceof AbstractXulComponent)
{
final AbstractXulComponent parentComp = (AbstractXulComponent) parent;
parentComp.layout();
}
}
public void setLabel(final String label)
{
menuitem.setText(label);
}
public String getImage()
{
return image;
}
public boolean isSelected()
{
return menuitem.isSelected();
}
public void setSelected(final boolean selected)
{
menuitem.setSelected(selected);
}
public void setImage(final String image)
{
this.image = image;
}
public String getCommand()
{
return this.onCommand;
}
public void setCommand(final String command)
{
this.onCommand = command;
}
public String toString()
{
return getLabel();
}
private void refreshKeystroke(final Action actionImpl)
{
final Object keyStroke = actionImpl.getValue(Action.ACCELERATOR_KEY);
if (keyStroke instanceof KeyStroke == false)
{
setAcceltext(null);
}
else
{
setAcceltext(keyStroke.toString());
}
}
private void refreshMnemonic(final Action actionImpl)
{
final Object o = actionImpl.getValue(Action.MNEMONIC_KEY);
if (o != null)
{
if (o instanceof Character)
{
final Character c = (Character) o;
setAccesskey(String.valueOf(c.charValue()));
}
else if (o instanceof Integer)
{
final Integer c = (Integer) o;
setAccesskey(String.valueOf(c.intValue()));
}
}
else
{
setAccesskey("\0");
}
}
}