/* * Copyright 2015 Mirosław Romaniuk (mi9rom@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.vaadHL.utl.action; import java.util.HashMap; import java.util.Map; import org.vaadin.peter.contextmenu.ContextMenu.ContextMenuItem; import org.vaadin.peter.contextmenu.ContextMenu.ContextMenuItemClickEvent; import org.vaadin.peter.contextmenu.ContextMenu.ContextMenuItemClickListener; import com.vaadHL.IAppContext; import com.vaadHL.utl.data.WrongObjectTypeException; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.MenuBar; import com.vaadin.ui.MenuBar.MenuItem; /** * Something important to run you have to control, especially to control * externally. The Action can be associated with widgets to control their state * and respond for particular events. * * @author Miroslaw Romaniuk * */ public class Action implements IActionsManipulate { /** * action identifier */ int id; /** * (Object the action is attached to, object info) */ Map<Object, ObjInfo> attached; Command command; boolean enabled = true; boolean visible = true; IAppContext appContext; boolean permChecking = true; public Action(IAppContext appContext, int actionId) { this(appContext, actionId, null); } public Action(IAppContext appContext, int actionId, Command command) { this.id = actionId; this.appContext = appContext; this.command = command; } /** * Creates an action without permission checking. Only internal state. * * @param appContext * @param actionId * @param command * @param enabled */ public Action(IAppContext appContext, int actionId, Command command, boolean enabled) { this.id = actionId; this.appContext = appContext; this.command = command; this.enabled = enabled; this.permChecking = false; } public Action(IAppContext appContext, int actionId, Command command, Object... objs) { this(appContext, actionId, command, true, true, true, objs); } public Action(IAppContext appContext, int actionId, Command command, boolean runAction, boolean enabling, boolean hiding, Object... objs) { this.id = actionId; this.command = command; this.appContext = appContext; if (objs != null) for (Object o : objs) { attach(o, runAction, enabling, hiding); } } @Override public Map<Object, ObjInfo> getAttached() { if (attached == null) attached = new HashMap<Object, ObjInfo>(); return attached; } /** * Attach the action to the object.<br> * Depending on the object type attaches the action command if * runAction=true * * @param runAction * do attach the action command * @param o * the Object to attach to * @param enabling * true- the action changes enabled state of the object * * @param hiding * true - the action can hide the object */ public void attach(Object o, boolean runAction, boolean enabling, boolean hiding) { if (!getAttached().containsKey(o)) { Object listener = null; if (runAction) { if (o instanceof Button) { listener = new Button.ClickListener() { private static final long serialVersionUID = -6387554438687264016L; @Override public void buttonClick(ClickEvent event) { if (enabled && command != null) command.run(Action.this); } }; ((Button) o) .addClickListener((Button.ClickListener) listener); } else if (o instanceof MenuItem) { listener = new MenuBar.Command() { private static final long serialVersionUID = 9067240940931195222L; @Override public void menuSelected(MenuItem selectedItem) { if (enabled && command != null) command.run(Action.this); } }; ((MenuItem) o).setCommand((MenuBar.Command) listener); } else if (o instanceof ContextMenuItem) { listener = new ContextMenuItemClickListener() { @Override public void contextMenuItemClicked( ContextMenuItemClickEvent event) { if (enabled && command != null) command.run(Action.this); } }; ((ContextMenuItem) o) .addItemClickListener((ContextMenuItemClickListener) listener); } else { throw new WrongObjectTypeException( "VHL-014: Only Buttons, MenuItems, ContextMenus are allowed to attach."); } } getAttached().put(o, new ObjInfo(o, listener, enabling, hiding)); setEnabled(o, enabled); } } /** * Attach the action to the object.<br> * * @param o * the Object to attach to */ public void attach(Object o) { attach(o, true, true, true); } @Override public void detach(Object o) { if (attached == null) return; detachLsnr(o); attached.remove(o); } /** * Detach the action run listener from the object. * * @param o */ protected void detachLsnr(Object o) { if (o == null) return; ObjInfo objInfo = attached.get(o); if (objInfo == null) return; if (o instanceof Button) { Button.ClickListener al = (ClickListener) objInfo.listener; if (al != null) ((Button) o).removeClickListener(al); } else if (o instanceof MenuItem) { ((MenuItem) o).setCommand(null); } else if (o instanceof ContextMenuItem) { ((ContextMenuItem) o) .removeItemClickListener((ContextMenuItemClickListener) objInfo.listener); } } @Override public void detachAll() { if (attached == null) return; for (Object o : attached.keySet()) { detachLsnr(o); } attached = null; } /** * Run the command. */ public void run() { if (enabled && command != null) command.run(this); } public interface Command { public void run(Action action); } @Override public void setEnabled(boolean enabled) { setEnabled(enabled, true); } @Override public void setEnabled(boolean enabled, boolean changeAttached, boolean force) { if (force == false && this.enabled == enabled) return; // no change this.enabled = enabled; if (attached == null) return; if (changeAttached) { for (ObjInfo oi : attached.values()) { if (oi.enabling) setEnabled(oi.o, enabled); } } } @Override public void setEnabled(boolean enabled, boolean changeAttached) { setEnabled(enabled, changeAttached, false); } /** * Sets enabled state of the object attached to. * * @param o * @param enabled */ protected void setEnabled(Object o, boolean enabled) { if (o instanceof AbstractComponent) { ((AbstractComponent) o).setEnabled(enabled); } else if (o instanceof MenuItem) { ((MenuItem) o).setEnabled(enabled); } else if (o instanceof ContextMenuItem) { ((ContextMenuItem) o).setEnabled(enabled); } else { throw new WrongObjectTypeException("VHL-013: " + appContext.getI18().getString("MVHL-013") + o.getClass().getName()); } } @Override public void setVisible(boolean visible) { setVisible(visible, false); } @Override public void setVisible(boolean visible, boolean force) { if (attached == null) return; if (force == false && this.visible == visible) return; // no change this.visible = visible; for (ObjInfo oi : attached.values()) { if (oi.enabling) setVisible(oi.o, visible); } } /** * Sets visibility of the object attached to. * * @param o * @param visible */ protected void setVisible(Object o, boolean visible) { if (attached == null) return; if (o instanceof AbstractComponent) { ((AbstractComponent) o).setVisible(visible); } else if (o instanceof MenuItem) { ((MenuItem) o).setVisible(visible); } else if (o instanceof ContextMenuItem) { ((ContextMenuItem) o).setEnabled(enabled); // not possible to hide } else { throw new WrongObjectTypeException( "VHL-014: Cannot control visibility state of the object type:" + o.getClass().getName()); } } @Override public boolean isVisible() { return visible; } /** * Gets the Action id */ public int getId() { return id; } @Override public boolean equals(Object obj) { if (obj instanceof Action) { return (getId() == ((Action) obj).getId()); } else return false; } @Override public int hashCode() { return id; } @Override public boolean isEnabled() { return enabled; } /** * Object info the action is attached to. * */ public class ObjInfo { public Object o; public Object listener; public boolean enabling; public boolean hiding; public ObjInfo(Object o, Object listener, boolean enabling, boolean hiding) { super(); this.o = o; this.listener = listener; this.enabling = enabling; this.hiding = hiding; } public ObjInfo(Object o, Object listener) { this(o, listener, true, true); } } public boolean isPermChecking() { return permChecking; } }