You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ja...@apache.org on 2013/11/01 14:31:47 UTC

svn commit: r1537933 - in /ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin: ./ component/

Author: jawi
Date: Fri Nov  1 13:31:47 2013
New Revision: 1537933

URL: http://svn.apache.org/r1537933
Log:
Added shortcut keys to the most important functions:

- for example, to store changes, one can press CTRL+S or CMD+S.


Added:
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/ShortcutHelper.java   (with props)
Modified:
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/AddArtifactWindow.java
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/EditWindow.java
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/GenericAddWindow.java
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/LoginWindow.java
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinClient.java
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinServlet.java
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/ConfirmationDialog.java
    ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/MainActionToolbar.java

Modified: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/AddArtifactWindow.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/AddArtifactWindow.java?rev=1537933&r1=1537932&r2=1537933&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/AddArtifactWindow.java (original)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/AddArtifactWindow.java Fri Nov  1 13:31:47 2013
@@ -40,6 +40,7 @@ import org.osgi.service.log.LogService;
 
 import com.vaadin.data.Item;
 import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.event.ShortcutAction.KeyCode;
 import com.vaadin.ui.Alignment;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
@@ -67,7 +68,7 @@ abstract class AddArtifactWindow extends
 
     private final List<File> m_uploadedArtifacts = new ArrayList<File>();
     private final Button m_searchButton;
-    private final Button m_closeButton;
+    private final Button m_addButton;
     private final Table m_artifactsTable;
 
     /**
@@ -87,6 +88,7 @@ abstract class AddArtifactWindow extends
 
         setModal(true);
         setWidth("50em");
+        setCloseShortcut(KeyCode.ESCAPE);
 
         m_artifactsTable = new Table("Artifacts in repository");
         m_artifactsTable.addContainerProperty(PROPERTY_SYMBOLIC_NAME, String.class, null);
@@ -175,23 +177,19 @@ abstract class AddArtifactWindow extends
         searchBar.addComponent(searchField);
         searchBar.addComponent(m_searchButton);
 
-        m_closeButton = new Button("Add", new ClickListener() {
+        m_addButton = new Button("Add", new ClickListener() {
             public void buttonClick(ClickEvent event) {
                 // Import all "local" (existing) bundles...
                 importLocalBundles(m_artifactsTable);
                 // Import all "remote" (non existing) bundles...
                 importRemoteBundles(m_uploadedArtifacts);
 
-                closeWindow();
-
-                // TODO: make a decision here so now we have enough information
-                // to show a list of imported artifacts (added) but do we want
-                // to show this list or do we just assume the user will see the
-                // new artifacts in the left most column? do we also report
-                // failures? or only report if there were failures?
+                close();
             }
         });
-        m_closeButton.setImmediate(true);
+        m_addButton.setImmediate(true);
+        m_addButton.setStyleName(Reindeer.BUTTON_DEFAULT);
+        m_addButton.setClickShortcut(KeyCode.ENTER);
 
         VerticalLayout layout = (VerticalLayout) getContent();
         layout.setMargin(true);
@@ -203,8 +201,8 @@ abstract class AddArtifactWindow extends
         layout.addComponent(finalUploadedArtifacts);
         // The components added to the window are actually added to the window's
         // layout; you can use either. Alignments are set using the layout
-        layout.addComponent(m_closeButton);
-        layout.setComponentAlignment(m_closeButton, Alignment.MIDDLE_RIGHT);
+        layout.addComponent(m_addButton);
+        layout.setComponentAlignment(m_addButton, Alignment.MIDDLE_RIGHT);
 
         searchField.focus();
     }
@@ -230,14 +228,6 @@ abstract class AddArtifactWindow extends
     }
 
     /**
-     * Closes this window.
-     */
-    final void closeWindow() {
-        // close the window by removing it from the parent window
-        getParent().removeWindow(this);
-    }
-
-    /**
      * Imports all local, i.e., that are already in our local OBR, bundles.
      * 
      * @param artifacts

Modified: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/EditWindow.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/EditWindow.java?rev=1537933&r1=1537932&r2=1537933&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/EditWindow.java (original)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/EditWindow.java Fri Nov  1 13:31:47 2013
@@ -79,14 +79,6 @@ public abstract class EditWindow extends
     }
 
     /**
-     * Closes this dialog by removing it from the parent window.
-     */
-    protected void closeDialog() {
-        // close the window by removing it from the parent window
-        getParent().removeWindow(this);
-    }
-
-    /**
      * Called when the {@link #onOk(String, String)} method failed with an exception.
      * 
      * @param e the exception to handle, never <code>null</code>.
@@ -127,7 +119,7 @@ public abstract class EditWindow extends
             public void buttonClick(ClickEvent event) {
                 try {
                     onOk((String) m_name.getValue(), (String) m_description.getValue());
-                    closeDialog();
+                    close();
                 }
                 catch (Exception e) {
                     handleError(e);
@@ -140,9 +132,10 @@ public abstract class EditWindow extends
 
         Button cancelButton = new Button("Cancel", new Button.ClickListener() {
             public void buttonClick(ClickEvent event) {
-                closeDialog();
+                close();
             }
         });
+        cancelButton.setClickShortcut(KeyCode.ESCAPE);
 
         HorizontalLayout buttonBar = new HorizontalLayout();
         buttonBar.setSpacing(true);
@@ -159,6 +152,8 @@ public abstract class EditWindow extends
         // The components added to the window are actually added to the window's
         // layout; you can use either. Alignments are set using the layout
         layout.setComponentAlignment(buttonBar, Alignment.BOTTOM_RIGHT);
+        
+        m_name.focus();
     }
     
     protected Map<String, Object> populateContext(Map<String, Object> context) {

Modified: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/GenericAddWindow.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/GenericAddWindow.java?rev=1537933&r1=1537932&r2=1537933&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/GenericAddWindow.java (original)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/GenericAddWindow.java Fri Nov  1 13:31:47 2013
@@ -26,6 +26,7 @@ import com.vaadin.ui.HorizontalLayout;
 import com.vaadin.ui.TextField;
 import com.vaadin.ui.VerticalLayout;
 import com.vaadin.ui.Window;
+import com.vaadin.ui.themes.Reindeer;
 
 public abstract class GenericAddWindow extends Window {
 
@@ -64,14 +65,6 @@ public abstract class GenericAddWindow e
     }
 
     /**
-     * Closes this dialog by removing it from the parent window.
-     */
-    protected void closeDialog() {
-        // close the window by removing it from the parent window
-        getParent().removeWindow(this);
-    }
-
-    /**
      * Called when the {@link #onOk(String, String)} method failed with an exception.
      * 
      * @param e the exception to handle, never <code>null</code>.
@@ -91,7 +84,7 @@ public abstract class GenericAddWindow e
             public void buttonClick(ClickEvent event) {
                 try {
                     onOk((String) m_name.getValue(), (String) m_description.getValue());
-                    closeDialog();
+                    close();
                 }
                 catch (Exception e) {
                     handleError(e);
@@ -100,13 +93,14 @@ public abstract class GenericAddWindow e
         });
         // Allow enter to be used to close this dialog with enter directly...
         okButton.setClickShortcut(KeyCode.ENTER);
-        okButton.addStyleName("primary");
+        okButton.addStyleName(Reindeer.BUTTON_DEFAULT);
 
         Button cancelButton = new Button("Cancel", new Button.ClickListener() {
             public void buttonClick(ClickEvent event) {
-                closeDialog();
+                close();
             }
         });
+        cancelButton.setClickShortcut(KeyCode.ESCAPE);
 
         HorizontalLayout buttonBar = new HorizontalLayout();
         buttonBar.setSpacing(true);
@@ -122,6 +116,9 @@ public abstract class GenericAddWindow e
         // The components added to the window are actually added to the window's
         // layout; you can use either. Alignments are set using the layout
         layout.setComponentAlignment(buttonBar, Alignment.BOTTOM_RIGHT);
+        
+        // Allow direct typing...
+        m_name.focus();
     }
 
     /**

Modified: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/LoginWindow.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/LoginWindow.java?rev=1537933&r1=1537932&r2=1537933&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/LoginWindow.java (original)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/LoginWindow.java Fri Nov  1 13:31:47 2013
@@ -161,7 +161,7 @@ public class LoginWindow extends Window 
      */
     public void closeWindow() {
         getParent().removeParameterHandler(this);
-        getParent().removeWindow(this);
+        close();
     }
 
     @Override

Added: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/ShortcutHelper.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/ShortcutHelper.java?rev=1537933&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/ShortcutHelper.java (added)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/ShortcutHelper.java Fri Nov  1 13:31:47 2013
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.ace.webui.vaadin;
+
+import java.util.Arrays;
+
+import com.vaadin.event.ShortcutAction.ModifierKey;
+import com.vaadin.terminal.gwt.server.WebBrowser;
+import com.vaadin.ui.Button;
+
+/**
+ * Provides utility methods for creating shortcut listeners.
+ */
+public final class ShortcutHelper {
+
+    public static void addCrossPlatformShortcut(WebBrowser browser, Button button, String description, int key, int... modifiers) {
+        modifiers = Arrays.copyOf(modifiers, modifiers.length + 1);
+        int platformModifier = getPlatformSpecificModifier(browser);
+        if (browser.isMacOSX()) {
+            modifiers[modifiers.length - 1] = platformModifier;
+        }
+        else {
+            System.arraycopy(modifiers, 0, modifiers, 1, modifiers.length - 1);
+            modifiers[0] = platformModifier;
+        }
+        addShortcut(browser, button, description, key, modifiers);
+    }
+
+    public static void addShortcut(WebBrowser browser, Button button, String description, int key, int... modifiers) {
+        if (!browser.isTouchDevice()) {
+            button.setClickShortcut(key, modifiers);
+            button.setDescription(String.format("%s (%s)", description, formatShortcut(key, modifiers)));
+        }
+    }
+
+    public static String formatModifier(int modifier) {
+        if (ModifierKey.ALT == modifier) {
+            return "ALT";
+        }
+        else if (ModifierKey.CTRL == modifier) {
+            return "CTRL";
+        }
+        else if (ModifierKey.META == modifier) {
+            return "\u2318";
+        }
+        else if (ModifierKey.SHIFT == modifier) {
+            return "SHIFT";
+        }
+        return "";
+    }
+
+    public static String formatShortcut(int keycode, int... modifiers) {
+        StringBuilder sb = new StringBuilder();
+        for (int modifier : modifiers) {
+            sb.append(formatModifier(modifier));
+            if (modifier != ModifierKey.META) {
+                sb.append(" + ");
+            }
+        }
+        sb.append((char) keycode);
+        return sb.toString();
+    }
+
+    public static int getPlatformSpecificModifier(WebBrowser browser) {
+        if (browser.isMacOSX()) {
+            return ModifierKey.META;
+        }
+        return ModifierKey.CTRL;
+    }
+}

Propchange: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/ShortcutHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinClient.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinClient.java?rev=1537933&r1=1537932&r2=1537933&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinClient.java (original)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinClient.java Fri Nov  1 13:31:47 2013
@@ -85,7 +85,10 @@ import org.osgi.service.useradmin.Author
 import org.osgi.service.useradmin.User;
 import org.osgi.service.useradmin.UserAdmin;
 
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.event.ShortcutAction.ModifierKey;
 import com.vaadin.service.ApplicationContext;
+import com.vaadin.terminal.gwt.server.WebBrowser;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.DragAndDropWrapper;
@@ -319,6 +322,7 @@ public class VaadinClient extends com.va
 
         m_mainWindow = new Window("Apache ACE");
         m_mainWindow.getContent().setSizeFull();
+        m_mainWindow.setBorder(Window.BORDER_NONE);
 
         setMainWindow(m_mainWindow);
 
@@ -467,6 +471,10 @@ public class VaadinClient extends com.va
         return m_statefulTargetRepository.preregister(attributes, tags);
     }
 
+    private void addCrossPlatformAddShortcut(Button button, int keycode, String description) {
+        ShortcutHelper.addCrossPlatformShortcut((WebBrowser) getMainWindow().getTerminal(), button, description, keycode, ModifierKey.SHIFT);
+    }
+
     private void addDependency(Component component, Class service) {
         component.add(m_manager.createServiceDependency()
             .setService(service)
@@ -529,6 +537,7 @@ public class VaadinClient extends com.va
      */
     private Button createAddArtifactButton() {
         Button button = new Button("Add artifact...");
+        addCrossPlatformAddShortcut(button, KeyCode.A, "Add a new artifact");
         button.addListener(new Button.ClickListener() {
             public void buttonClick(ClickEvent event) {
                 showAddArtifactDialog();
@@ -547,6 +556,7 @@ public class VaadinClient extends com.va
      */
     private Button createAddDistributionButton() {
         Button button = new Button("Add Distribution...");
+        addCrossPlatformAddShortcut(button, KeyCode.D, "Add a new distribution");
         button.addListener(new Button.ClickListener() {
             public void buttonClick(ClickEvent event) {
                 GenericAddWindow window = new GenericAddWindow("Add Distribution") {
@@ -576,6 +586,7 @@ public class VaadinClient extends com.va
      */
     private Button createAddFeatureButton() {
         Button button = new Button("Add Feature...");
+        addCrossPlatformAddShortcut(button, KeyCode.F, "Add a new feature");
         button.addListener(new Button.ClickListener() {
             public void buttonClick(ClickEvent event) {
                 GenericAddWindow window = new GenericAddWindow("Add Feature") {
@@ -604,6 +615,7 @@ public class VaadinClient extends com.va
      */
     private Button createAddTargetButton() {
         Button button = new Button("Add target...");
+        addCrossPlatformAddShortcut(button, KeyCode.G, "Add a new target");
         button.addListener(new Button.ClickListener() {
             public void buttonClick(ClickEvent event) {
                 GenericAddWindow window = new GenericAddWindow("Add Target") {
@@ -815,6 +827,8 @@ public class VaadinClient extends com.va
                 m_featuresPanel.populate();
                 m_distributionsPanel.populate();
                 m_targetsPanel.populate();
+
+                m_mainWindow.focus();
             }
         };
     }
@@ -1064,6 +1078,8 @@ public class VaadinClient extends com.va
         addListener(m_targetsPanel, StatefulTargetObject.TOPIC_ALL, TargetObject.TOPIC_ALL, RepositoryAdmin.TOPIC_STATUSCHANGED, RepositoryAdmin.TOPIC_LOGIN, RepositoryAdmin.TOPIC_REFRESH);
 
         m_mainWindow.addComponent(m_grid);
+        // Ensure the focus is properly defined (for the shortcut keys to work)...
+        m_mainWindow.focus();
     }
 
     /**

Modified: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinServlet.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinServlet.java?rev=1537933&r1=1537932&r2=1537933&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinServlet.java (original)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/VaadinServlet.java Fri Nov  1 13:31:47 2013
@@ -159,6 +159,15 @@ public class VaadinServlet extends Abstr
     @Override
     protected SystemMessages getSystemMessages() {
         CustomizedSystemMessages msgs = new CustomizedSystemMessages();
+        msgs.setAuthenticationErrorNotificationEnabled(false);
+        msgs.setAuthenticationErrorURL(m_servletEndpoint.concat("/?authenticationError"));
+        msgs.setCommunicationErrorNotificationEnabled(false);
+        msgs.setCommunicationErrorURL(m_servletEndpoint.concat("/?communicationError"));
+        msgs.setCookiesDisabledNotificationEnabled(false);
+        msgs.setCookiesDisabledURL(m_servletEndpoint.concat("/?cookiesDisabled"));
+        msgs.setInternalErrorNotificationEnabled(false);
+        msgs.setInternalErrorURL(m_servletEndpoint.concat("/?internalError"));
+        msgs.setOutOfSyncNotificationEnabled(false);
         msgs.setSessionExpiredNotificationEnabled(false);
         msgs.setSessionExpiredURL(m_servletEndpoint.concat("/?sessionTimedOut"));
         return msgs;

Modified: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java?rev=1537933&r1=1537932&r2=1537933&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java (original)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java Fri Nov  1 13:31:47 2013
@@ -465,6 +465,9 @@ abstract class BaseObjectPanel<REPO_OBJ 
         Association<LEFT_ASSOC_REPO_OBJ, REPO_OBJ> association = doCreateLeftSideAssociation(String.valueOf(leftObjectId), String.valueOf(rightObjectId));
         if (association != null) {
             m_leftTable.recalculateRelations(Direction.RIGHT);
+            
+            // Request the focus again...
+            focus();
         }
     }
 
@@ -480,6 +483,9 @@ abstract class BaseObjectPanel<REPO_OBJ 
         Association<REPO_OBJ, RIGHT_ASSOC_REPO_OBJ> association = doCreateRightSideAssociation(String.valueOf(leftObjectId), String.valueOf(rightObjectId));
         if (association != null) {
             m_rightTable.recalculateRelations(Direction.LEFT);
+            
+            // Request the focus again...
+            focus();
         }
     }
 
@@ -490,6 +496,8 @@ abstract class BaseObjectPanel<REPO_OBJ 
         m_associations.clear();
         m_associations.updateActiveTable(this);
         recalculateRelations(Direction.BOTH);
+        // request the focus...
+        focus();
     }
 
     /**
@@ -518,6 +526,9 @@ abstract class BaseObjectPanel<REPO_OBJ 
             m_associations.clear();
 
             m_leftTable.recalculateRelations(Direction.RIGHT);
+            
+            // Request the focus again...
+            focus();
         }
     }
 
@@ -534,6 +545,9 @@ abstract class BaseObjectPanel<REPO_OBJ 
             m_associations.clear();
 
             m_rightTable.recalculateRelations(Direction.LEFT);
+            
+            // Request the focus again...
+            focus();
         }
     }
 
@@ -566,6 +580,9 @@ abstract class BaseObjectPanel<REPO_OBJ 
         }
 
         setChildrenAllowed(itemId, false);
+        
+        // Request the focus again...
+        focus();
     }
 
     /**
@@ -853,6 +870,9 @@ abstract class BaseObjectPanel<REPO_OBJ 
                 removeItem(parentID);
             }
         }
+        
+        // Request the focus again...
+        focus();
     }
 
     protected final void setItemIcon(REPO_OBJ object) {

Modified: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/ConfirmationDialog.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/ConfirmationDialog.java?rev=1537933&r1=1537932&r2=1537933&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/ConfirmationDialog.java (original)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/ConfirmationDialog.java Fri Nov  1 13:31:47 2013
@@ -18,6 +18,7 @@
  */
 package org.apache.ace.webui.vaadin.component;
 
+import com.vaadin.event.ShortcutAction.KeyCode;
 import com.vaadin.ui.AbstractComponent;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
@@ -26,9 +27,11 @@ import com.vaadin.ui.GridLayout;
 import com.vaadin.ui.Label;
 import com.vaadin.ui.VerticalLayout;
 import com.vaadin.ui.Window;
+import com.vaadin.ui.themes.Reindeer;
 
 /**
- * Provides a confirmation dialog, based on code found on <a href="https://vaadin.com/forum/-/message_boards/view_message/17883">this forum posting</a>.
+ * Provides a confirmation dialog, based on code found on <a
+ * href="https://vaadin.com/forum/-/message_boards/view_message/17883">this forum posting</a>.
  */
 public class ConfirmationDialog extends Window implements ClickListener {
 
@@ -39,7 +42,8 @@ public class ConfirmationDialog extends 
         /**
          * Called upon pressing a button.
          * 
-         * @param buttonName the name of the button that was clicked, never <code>null</code>.
+         * @param buttonName
+         *            the name of the button that was clicked, never <code>null</code>.
          */
         void onDialogResult(String buttonName);
     }
@@ -53,23 +57,30 @@ public class ConfirmationDialog extends 
     /**
      * Provides a Yes/No confirmation dialog.
      * 
-     * @param caption the caption of this dialog, cannot be <code>null</code>;
-     * @param message the message to display, may be <code>null</code> to omit the message;
-     * @param callback the callback to call for each pressed button.
+     * @param caption
+     *            the caption of this dialog, cannot be <code>null</code>;
+     * @param message
+     *            the message to display, may be <code>null</code> to omit the message;
+     * @param callback
+     *            the callback to call for each pressed button.
      */
     public ConfirmationDialog(String caption, String message, Callback callback) {
-        this(caption, message, callback, YES, NO);
+        this(caption, message, callback, YES, YES, NO);
     }
 
     /**
      * Provides a confirmation dialog with a custom set of buttons.
      * 
-     * @param caption the caption of this dialog, cannot be <code>null</code>;
-     * @param message the message to display, may be <code>null</code> to omit the message;
-     * @param callback the callback to call for each pressed button;
-     * @param buttonNames the names of the buttons to display.
+     * @param caption
+     *            the caption of this dialog, cannot be <code>null</code>;
+     * @param message
+     *            the message to display, may be <code>null</code> to omit the message;
+     * @param callback
+     *            the callback to call for each pressed button;
+     * @param buttonNames
+     *            the names of the buttons to display.
      */
-    public ConfirmationDialog(String caption, String message, Callback callback, String... buttonNames) {
+    public ConfirmationDialog(String caption, String message, Callback callback, String defaultButton, String... buttonNames) {
         super(caption);
 
         if (buttonNames == null || buttonNames.length <= 1) {
@@ -88,7 +99,7 @@ public class ConfirmationDialog extends 
         layout.setMargin(true);
         layout.setSpacing(true);
 
-        addComponents(message, buttonNames);
+        addComponents(message, defaultButton, buttonNames);
     }
 
     /**
@@ -98,6 +109,7 @@ public class ConfirmationDialog extends 
         Window parent = getParent();
         if (parent != null) {
             parent.removeWindow(this);
+            parent.focus();
         }
 
         AbstractComponent comp = (AbstractComponent) event.getComponent();
@@ -107,10 +119,12 @@ public class ConfirmationDialog extends 
     /**
      * Adds all components to this dialog.
      * 
-     * @param message the optional message to display, can be <code>null</code>;
-     * @param buttonNames the names of the buttons to add, never <code>null</code> or empty.
+     * @param message
+     *            the optional message to display, can be <code>null</code>;
+     * @param buttonNames
+     *            the names of the buttons to add, never <code>null</code> or empty.
      */
-    protected void addComponents(String message, String... buttonNames) {
+    protected void addComponents(String message, String defaultButton, String... buttonNames) {
         if (message != null) {
             addComponent(new Label(message));
         }
@@ -125,6 +139,12 @@ public class ConfirmationDialog extends 
         for (String buttonName : buttonNames) {
             Button button = new Button(buttonName, this);
             button.setData(buttonName);
+            if (defaultButton != null && defaultButton.equals(buttonName)) {
+                button.setStyleName(Reindeer.BUTTON_DEFAULT);
+                button.setClickShortcut(KeyCode.ENTER);
+                // Request focus in this window...
+                button.focus();
+            }
             gl.addComponent(button);
         }
 

Modified: ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/MainActionToolbar.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/MainActionToolbar.java?rev=1537933&r1=1537932&r2=1537933&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/MainActionToolbar.java (original)
+++ ace/trunk/org.apache.ace.webui.vaadin/src/org/apache/ace/webui/vaadin/component/MainActionToolbar.java Fri Nov  1 13:31:47 2013
@@ -28,10 +28,13 @@ import java.util.concurrent.ConcurrentHa
 
 import org.apache.ace.client.repository.RepositoryAdmin;
 import org.apache.ace.webui.UIExtensionFactory;
+import org.apache.ace.webui.vaadin.ShortcutHelper;
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.event.EventHandler;
 
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.terminal.gwt.server.WebBrowser;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.Component;
@@ -51,6 +54,9 @@ public abstract class MainActionToolbar 
     private class LogoutButtonListener implements Button.ClickListener, ConfirmationDialog.Callback {
 
         public void buttonClick(ClickEvent event) {
+            // Avoid double-clicks...
+            event.getButton().setEnabled(false);
+
             final RepositoryAdmin repoAdmin = getRepositoryAdmin();
             try {
                 if (repoAdmin.isModified() && repoAdmin.isCurrent()) {
@@ -96,6 +102,9 @@ public abstract class MainActionToolbar 
     private final class RetrieveButtonListener implements Button.ClickListener, ConfirmationDialog.Callback {
 
         public void buttonClick(ClickEvent event) {
+            // Avoid double-clicks...
+            event.getButton().setEnabled(false);
+
             final RepositoryAdmin repoAdmin = getRepositoryAdmin();
             try {
                 if (repoAdmin.isModified()) {
@@ -146,6 +155,9 @@ public abstract class MainActionToolbar 
     private final class RevertButtonListener implements Button.ClickListener, ConfirmationDialog.Callback {
 
         public void buttonClick(ClickEvent event) {
+            // Avoid double-clicks...
+            event.getButton().setEnabled(false);
+
             try {
                 if (getRepositoryAdmin().isModified()) {
                     // Revert all changes...
@@ -195,10 +207,10 @@ public abstract class MainActionToolbar 
      */
     private final class StoreButtonListener implements Button.ClickListener {
 
-        /**
-         * {@inheritDoc}
-         */
         public void buttonClick(ClickEvent event) {
+            // Avoid double-clicks...
+            event.getButton().setEnabled(false);
+
             final RepositoryAdmin repoAdmin = getRepositoryAdmin();
             try {
                 if (repoAdmin.isModified()) {
@@ -262,6 +274,22 @@ public abstract class MainActionToolbar 
         initComponent();
     }
 
+    @Override
+    public void attach() {
+        try {
+            addCrossPlatformShortcut(m_retrieveButton, KeyCode.G, "Retrieves the latest changes from the server");
+            addCrossPlatformShortcut(m_storeButton, KeyCode.S, "Stores all local changes");
+            addCrossPlatformShortcut(m_revertButton, KeyCode.U, "Reverts all local changes");
+
+            if (m_showLogoutButton) {
+                addCrossPlatformShortcut(m_logoutButton, KeyCode.L, "Log out");
+            }
+        }
+        finally {
+            super.attach();
+        }
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -375,6 +403,10 @@ public abstract class MainActionToolbar 
         getWindow().showNotification(title, String.format("<br/>%s", message), Notification.TYPE_WARNING_MESSAGE);
     }
 
+    private void addCrossPlatformShortcut(Button button, int key, String description) {
+        ShortcutHelper.addCrossPlatformShortcut((WebBrowser) getWindow().getTerminal(), button, description, key);
+    }
+
     /**
      * Initializes this component.
      */
@@ -405,9 +437,9 @@ public abstract class MainActionToolbar 
 
         m_logoutButton = new Button("Logout");
         m_logoutButton.addListener(new LogoutButtonListener());
-        if (m_showLogoutButton) {
-            addComponent(m_logoutButton, 5, 0);
-        }
+        m_logoutButton.setVisible(m_showLogoutButton);
+
+        addComponent(m_logoutButton, 5, 0);
 
         // Ensure the spacer gets all the excessive room, causing the logout
         // button to appear at the right side of the screen....