]> source.dussan.org Git - vaadin-framework.git/commitdiff
#8429 Made shortcuts in sub window work again
authorArtur Signell <artur@vaadin.com>
Fri, 2 Mar 2012 14:17:27 +0000 (16:17 +0200)
committerArtur Signell <artur@vaadin.com>
Fri, 2 Mar 2012 14:18:13 +0000 (16:18 +0200)
src/com/vaadin/ui/AbstractComponent.java

index 40e4771aa44b7489412c076eb2009aaaeb487ca8..12b67355ceee8e26fc571044979f984775d7f0d8 100644 (file)
@@ -680,9 +680,7 @@ public abstract class AbstractComponent implements Component, MethodEventSource
         if (delayedFocus) {
             focus();
         }
-        if (actionManager != null) {
-            actionManager.setViewer(getRoot());
-        }
+        setActionManagerViewer();
     }
 
     /*
@@ -691,6 +689,8 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      */
     public void detach() {
         if (actionManager != null) {
+            // Remove any existing viewer. Root cast is just to make the
+            // compiler happy
             actionManager.setViewer((Root) null);
         }
     }
@@ -1605,11 +1605,55 @@ public abstract class AbstractComponent implements Component, MethodEventSource
     protected ActionManager getActionManager() {
         if (actionManager == null) {
             actionManager = new ActionManager();
-            if (getRoot() != null) {
+            setActionManagerViewer();
+        }
+        return actionManager;
+    }
+
+    /**
+     * Set a viewer for the action manager to be the parent sub window (if the
+     * component is in a window) or the root (otherwise). This is still a
+     * simplification of the real case as this should be handled by the parent
+     * VOverlay (on the client side) if the component is inside an VOverlay
+     * component.
+     */
+    private void setActionManagerViewer() {
+        if (actionManager != null && getRoot() != null) {
+            // Attached and has action manager
+            Window w = findParentOfType(Window.class, this);
+            if (w != null) {
+                actionManager.setViewer(w);
+            } else {
                 actionManager.setViewer(getRoot());
             }
         }
-        return actionManager;
+
+    }
+
+    /**
+     * Helper method for finding the first parent component of a given type.
+     * Useful e.g. for finding the Window the component is inside.
+     * 
+     * @param <T>
+     * @param parentType
+     *            The type to look for
+     * @param c
+     *            The target component
+     * @return A parent component of type {@literal parentType} or null if no
+     *         parent component in the hierarchy can be assigned to the given
+     *         type.
+     */
+    private static <T extends Component> T findParentOfType(
+            Class<T> parentType, Component c) {
+        Component p = c.getParent();
+        if (p == null) {
+            return null;
+        }
+
+        if (parentType.isAssignableFrom(p.getClass())) {
+            return (T) p;
+        }
+        return findParentOfType(parentType, p);
     }
 
     public void addShortcutListener(ShortcutListener shortcut) {