Browse Source

Merged shortcut action fix from 6.8 (#8484)

Change-Id: I1bc200afa9f4a4f3c5e469eb0b2f93278cca97a7
tags/7.0.0.beta3
John Alhroos 11 years ago
parent
commit
a003c8724c

+ 108
- 0
client/src/com/vaadin/client/ui/ShortcutAction.java View File

@@ -0,0 +1,108 @@
/*
* Copyright 2011 Vaadin Ltd.
*
* 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.vaadin.client.ui;

import com.vaadin.client.ApplicationConnection;
import com.vaadin.server.KeyMapper;

public class ShortcutAction {

private final ShortcutKeyCombination sc;
private final String caption;
private final String key;
private String targetCID;
private String targetAction;

/**
* Constructor
*
* @param key
* The @link {@link KeyMapper} key of the action.
* @param sc
* The key combination that triggers the action
* @param caption
* The caption of the action
*/
public ShortcutAction(String key, ShortcutKeyCombination sc, String caption) {
this(key, sc, caption, null, null);
}

/**
* Constructor
*
* @param key
* The @link {@link KeyMapper} key of the action.
* @param sc
* The key combination that triggers the action
* @param caption
* The caption of the action
* @param targetPID
* The pid of the component the action is targeting. We use the
* pid, instead of the actual Paintable here, so we can delay the
* fetching of the Paintable in cases where the Paintable does
* not yet exist when the action is painted.
* @param targetAction
* The target string of the action. The target string is given to
* the targeted Paintable if the paintable implements the
* {@link ShortcutActionTarget} interface.
*/
public ShortcutAction(String key, ShortcutKeyCombination sc,
String caption, String targetCID, String targetAction) {
this.sc = sc;
this.key = key;
this.caption = caption;
this.targetCID = targetCID;
this.targetAction = targetAction;
}

/**
* Get the key combination that triggers the action
*/
public ShortcutKeyCombination getShortcutCombination() {
return sc;
}

/**
* Get the caption of the action
*/
public String getCaption() {
return caption;
}

/**
* Get the {@link KeyMapper} key for the action
*/
public String getKey() {
return key;
}

/**
* Get the pid of the target of the action. Use
* {@link ApplicationConnection#getPaintable(String)} to get the actual
* Paintable
*/
public String getTargetCID() {
return targetCID;
}

/**
* Get the target string of the action
*/
public String getTargetAction() {
return targetAction;
}

}

+ 40
- 36
client/src/com/vaadin/client/ui/ShortcutActionHandler.java View File

@@ -30,9 +30,11 @@ import com.google.gwt.user.client.ui.KeyboardListenerCollection;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorMap;
import com.vaadin.client.UIDL;
import com.vaadin.client.Util;
import com.vaadin.client.ui.richtextarea.VRichTextArea;
import com.vaadin.shared.Connector;

/**
* A helper class to implement keyboard shorcut handling. Keeps a list of owners
@@ -43,6 +45,15 @@ import com.vaadin.client.ui.richtextarea.VRichTextArea;
*/
public class ShortcutActionHandler {

public static final String ACTION_TARGET_ATTRIBUTE = "sat";
public static final String ACTION_TARGET_ACTION_ATTRIBUTE = "sata";
public static final String ACTION_CAPTION_ATTRIBUTE = "caption";
public static final String ACTION_KEY_ATTRIBUTE = "key";
public static final String ACTION_SHORTCUT_KEY_ATTRIBUTE = "kc";
public static final String ACTION_MODIFIER_KEYS_ATTRIBUTE = "mk";
public static final String ACTION_TARGET_VARIABLE = "actiontarget";
public static final String ACTION_TARGET_ACTION_VARIABLE = "action";

/**
* An interface implemented by those users of this helper class that want to
* support special components like {@link VRichTextArea} that don't properly
@@ -108,15 +119,23 @@ public class ShortcutActionHandler {
final UIDL action = (UIDL) it.next();

int[] modifiers = null;
if (action.hasAttribute("mk")) {
modifiers = action.getIntArrayAttribute("mk");
if (action.hasAttribute(ACTION_MODIFIER_KEYS_ATTRIBUTE)) {
modifiers = action
.getIntArrayAttribute(ACTION_MODIFIER_KEYS_ATTRIBUTE);
}

final ShortcutKeyCombination kc = new ShortcutKeyCombination(
action.getIntAttribute("kc"), modifiers);
final String key = action.getStringAttribute("key");
final String caption = action.getStringAttribute("caption");
actions.add(new ShortcutAction(key, kc, caption));
action.getIntAttribute(ACTION_SHORTCUT_KEY_ATTRIBUTE),
modifiers);
final String key = action.getStringAttribute(ACTION_KEY_ATTRIBUTE);
final String caption = action
.getStringAttribute(ACTION_CAPTION_ATTRIBUTE);
final String targetPID = action
.getStringAttribute(ACTION_TARGET_ATTRIBUTE);
final String targetAction = action
.getStringAttribute(ACTION_TARGET_ACTION_ATTRIBUTE);
actions.add(new ShortcutAction(key, kc, caption, targetPID,
targetAction));
}
}

@@ -171,11 +190,22 @@ public class ShortcutActionHandler {
Scheduler.get().scheduleDeferred(new Command() {
@Override
public void execute() {
if (finalTarget != null) {
client.updateVariable(paintableId, "actiontarget",
finalTarget, false);
Connector shortcutTarget = ConnectorMap.get(client)
.getConnector(a.getTargetCID());

boolean handledClientSide = false;
if (shortcutTarget instanceof ShortcutActionTarget) {
handledClientSide = ((ShortcutActionTarget) shortcutTarget)
.handleAction(a);
}
if (!handledClientSide) {
if (finalTarget != null) {
client.updateVariable(paintableId,
ACTION_TARGET_VARIABLE, finalTarget, false);
}
client.updateVariable(paintableId,
ACTION_TARGET_ACTION_VARIABLE, a.getKey(), true);
}
client.updateVariable(paintableId, "action", a.getKey(), true);
}
});
}
@@ -282,29 +312,3 @@ class ShortcutKeyCombination {
return false;
}
}

class ShortcutAction {

private final ShortcutKeyCombination sc;
private final String caption;
private final String key;

public ShortcutAction(String key, ShortcutKeyCombination sc, String caption) {
this.sc = sc;
this.key = key;
this.caption = caption;
}

public ShortcutKeyCombination getShortcutCombination() {
return sc;
}

public String getCaption() {
return caption;
}

public String getKey() {
return key;
}

}

+ 24
- 0
client/src/com/vaadin/client/ui/ShortcutActionTarget.java View File

@@ -0,0 +1,24 @@
/*
@VaadinApache2LicenseForJavaFiles@
*/
package com.vaadin.client.ui;

/**
* Widgets who wish to be notificed when a shortcut action has been triggered
* with the widget as a target should implement this interface. The
* {@link #handleAction(ShortcutAction)} method will be called just before the
* action is communicated to the server
*
*/
public interface ShortcutActionTarget {

/**
* Called by the {@link ShortcutActionHandler} just before the shortcut
* action is sent to the server side
*
* @param action
* The action which will be performed on the server side
* @return Returns true if the shortcut was handled
*/
boolean handleAction(ShortcutAction action);
}

+ 19
- 1
client/src/com/vaadin/client/ui/button/ButtonConnector.java View File

@@ -33,6 +33,8 @@ import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.client.ui.Icon;
import com.vaadin.client.ui.ShortcutAction;
import com.vaadin.client.ui.ShortcutActionTarget;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.communication.FieldRpc.FocusAndBlurServerRpc;
import com.vaadin.shared.ui.Connect;
@@ -43,7 +45,7 @@ import com.vaadin.ui.Button;

@Connect(value = Button.class, loadStyle = LoadStyle.EAGER)
public class ButtonConnector extends AbstractComponentConnector implements
BlurHandler, FocusHandler, ClickHandler {
BlurHandler, FocusHandler, ClickHandler, ShortcutActionTarget {

private ButtonServerRpc rpc = RpcProxy.create(ButtonServerRpc.class, this);
private FocusAndBlurServerRpc focusBlurProxy = RpcProxy.create(
@@ -165,4 +167,20 @@ public class ButtonConnector extends AbstractComponentConnector implements
rpc.click(details);

}

/*
* (non-Javadoc)
*
* @see
* com.vaadin.terminal.gwt.client.ui.ShortcutActionTarget#handleAction(com
* .vaadin.terminal.gwt.client.ui.ShortcutAction)
*/
public boolean handleAction(ShortcutAction action) {
if ("click".equals(action.getTargetAction())) {
getWidget().onClick();
return true;
}
return false;
}

}

+ 25
- 5
server/src/com/vaadin/event/ActionManager.java View File

@@ -18,6 +18,7 @@ package com.vaadin.event;
import java.util.HashSet;
import java.util.Map;

import com.vaadin.client.ui.ShortcutActionHandler;
import com.vaadin.event.Action.Container;
import com.vaadin.event.Action.Handler;
import com.vaadin.server.KeyMapper;
@@ -187,14 +188,29 @@ public class ActionManager implements Action.Container, Action.Handler,
}
if (a instanceof ShortcutAction) {
final ShortcutAction sa = (ShortcutAction) a;
paintTarget.addAttribute("kc", sa.getKeyCode());
paintTarget
.addAttribute(
ShortcutActionHandler.ACTION_SHORTCUT_KEY_ATTRIBUTE,
sa.getKeyCode());
final int[] modifiers = sa.getModifiers();
if (modifiers != null) {
final String[] smodifiers = new String[modifiers.length];
for (int i = 0; i < modifiers.length; i++) {
smodifiers[i] = String.valueOf(modifiers[i]);
}
paintTarget.addAttribute("mk", smodifiers);
paintTarget
.addAttribute(
ShortcutActionHandler.ACTION_MODIFIER_KEYS_ATTRIBUTE,
smodifiers);
}
if (sa.getTarget() != null) {
paintTarget.addAttribute(
ShortcutActionHandler.ACTION_TARGET_ATTRIBUTE,
sa.getTarget());
paintTarget
.addAttribute(
ShortcutActionHandler.ACTION_TARGET_ACTION_ATTRIBUTE,
sa.getTargetAction());
}
}
paintTarget.endTag("action");
@@ -212,10 +228,14 @@ public class ActionManager implements Action.Container, Action.Handler,
}

public void handleActions(Map<String, Object> variables, Container sender) {
if (variables.containsKey("action") && actionMapper != null) {
final String key = (String) variables.get("action");
if (variables
.containsKey(ShortcutActionHandler.ACTION_TARGET_ACTION_VARIABLE)
&& actionMapper != null) {
final String key = (String) variables
.get(ShortcutActionHandler.ACTION_TARGET_ACTION_VARIABLE);
final Action action = actionMapper.get(key);
final Object target = variables.get("actiontarget");
final Object target = variables
.get(ShortcutActionHandler.ACTION_TARGET_VARIABLE);
if (action != null) {
handleAction(action, sender, target);
}

+ 45
- 0
server/src/com/vaadin/event/ShortcutAction.java View File

@@ -21,6 +21,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.vaadin.server.Resource;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Window;
@@ -57,6 +58,10 @@ public class ShortcutAction extends Action {

private final int[] modifiers;

private Component target;

private String targetAction;

/**
* Creates a shortcut that reacts to the given {@link KeyCode} and
* (optionally) {@link ModifierKey}s. <br/>
@@ -236,6 +241,46 @@ public class ShortcutAction extends Action {
return modifiers;
}

/**
* Set the target for the shortcut action. If the target widget on the
* client side implements {@link ShortcutActionTarget} it will be notified
* of the action before the action is communicated to the server side
*
* @param target
* The component which will be thet target of the action
*/
public void setTarget(Component target) {
this.target = target;
}

/**
* Get the target of the shortcut action
*/
public Component getTarget() {
return target;
}

/**
* Get the action string that is given to the {@link ShortcutActionTarget}
* on the client side
*
* @return
*/
public String getTargetAction() {
return targetAction;
}

/**
* Set the action string that is give to the {@link ShortcutActionTarget} on
* the client side
*
* @param targetAction
* The target action string
*/
public void setTargetAction(String targetAction) {
this.targetAction = targetAction;
}

/**
* Key codes that can be used for shortcuts
*

+ 5
- 4
server/src/com/vaadin/ui/Button.java View File

@@ -463,7 +463,6 @@ public class Button extends AbstractComponent implements
*
*/
public static class ClickShortcut extends ShortcutListener {
protected Button button;

/**
* Creates a keyboard shortcut for clicking the given button using the
@@ -476,7 +475,8 @@ public class Button extends AbstractComponent implements
*/
public ClickShortcut(Button button, String shorthandCaption) {
super(shorthandCaption);
this.button = button;
setTarget(button);
setTargetAction("click");
}

/**
@@ -492,7 +492,8 @@ public class Button extends AbstractComponent implements
*/
public ClickShortcut(Button button, int keyCode, int... modifiers) {
super(null, keyCode, modifiers);
this.button = button;
setTarget(button);
setTargetAction("click");
}

/**
@@ -510,7 +511,7 @@ public class Button extends AbstractComponent implements

@Override
public void handleAction(Object sender, Object target) {
button.click();
// Action handled on the client side
}
}


Loading…
Cancel
Save