Bug 550582: Allow showing shortcuts only for mouse clicks

Change-Id: I5ee95a0ab587a2ea927bec82bed7c0baadffd39c
Signed-off-by: Christian Georgi <christian.georgi@sap.com>
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IPreferenceConstants.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IPreferenceConstants.java
index f724611..b998038 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IPreferenceConstants.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IPreferenceConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -288,9 +288,19 @@
 	 * The boolean default value for this preference is: <code>false</code>.
 	 * </p>
 	 *
-	 * @since 3.115
+	 * @since 3.119
 	 */
-	String SHOW_KEYS_ENABLED = "showCommandKeys"; //$NON-NLS-1$
+	String SHOW_KEYS_ENABLED_FOR_KEYBOARD = "showCommandKeysForKeyboard"; //$NON-NLS-1$
+
+	/**
+	 * Preference for whether pressed command keys are to be visualized
+	 * <p>
+	 * The boolean default value for this preference is: <code>false</code>.
+	 * </p>
+	 *
+	 * @since 3.119
+	 */
+	String SHOW_KEYS_ENABLED_FOR_MOUSE_EVENTS = "showCommandKeysForMouseEvents"; //$NON-NLS-1$
 
 	/**
 	 * Preference for the time (in ms) after the command keys UI is to be closed
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPreferenceInitializer.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPreferenceInitializer.java
index 3074485..77ca509 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPreferenceInitializer.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPreferenceInitializer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -120,7 +120,8 @@
 		node.putInt(IPreferenceConstants.MAX_PROGRESS_ENTRIES, 20);
 
 		// Visualized command keys
-		node.putBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED, false);
+		node.putBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_KEYBOARD, false);
+		node.putBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_MOUSE_EVENTS, false);
 		node.putInt(IPreferenceConstants.SHOW_KEYS_TIME_TO_CLOSE, 3000);
 
 		node.put(IWorkbenchPreferenceConstants.RESOURCE_RENAME_MODE,
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferenceMessages.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferenceMessages.java
index d11d40e..bd370e5 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferenceMessages.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferenceMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2019 IBM Corporation and others.
+ * Copyright (c) 2006, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -67,7 +67,9 @@
 	public static String InternalFilterCheckBox_Text;
 	public static String UncategorizedFilterCheckBox_Text;
 
-	public static String ShowCommandKeys_Text;
+	public static String ShowCommandKeysGroup_Title;
+	public static String ShowCommandKeysForKeyboard_Text;
+	public static String ShowCommandKeysForMouse_Text;
 
 	static {
 		// load message values from bundle file
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferencePage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferencePage.java
index ff8eb2d..a0773e8 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferencePage.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferencePage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2019 IBM Corporation and others.
+ * Copyright (c) 2005, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -40,6 +40,7 @@
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.IDialogSettings;
 import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferencePage;
@@ -79,6 +80,7 @@
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
@@ -192,6 +194,7 @@
 	private TableViewer conflictViewer;
 
 	private Button fShowCommandKey;
+	private Button fShowCommandKeyForMouseEvents;
 
 	private ICommandImageService commandImageService;
 
@@ -1052,17 +1055,29 @@
 	private void createShowKeysControls(Composite parent) {
 		ShowKeysUI showKeysUI = new ShowKeysUI(fWorkbench, getPreferenceStore());
 
-		final Composite controls = new Composite(parent, SWT.NONE);
-		GridLayoutFactory.fillDefaults().numColumns(1).applyTo(controls);
-		fShowCommandKey = new Button(controls, SWT.CHECK);
-		fShowCommandKey.setText(NewKeysPreferenceMessages.ShowCommandKeys_Text);
-		fShowCommandKey.setSelection(getPreferenceStore().getBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED));
+		final Group group = new Group(parent, SWT.NONE);
+		group.setText(NewKeysPreferenceMessages.ShowCommandKeysGroup_Title);
+		GridDataFactory.fillDefaults().applyTo(group);
+		GridLayoutFactory.fillDefaults().numColumns(1).applyTo(group);
+		fShowCommandKey = new Button(group, SWT.CHECK);
+		fShowCommandKey.setText(NewKeysPreferenceMessages.ShowCommandKeysForKeyboard_Text);
+		fShowCommandKey.setSelection(getPreferenceStore().getBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_KEYBOARD));
 		fShowCommandKey.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
 			// show a preview of the shortcut popup
 			if (fShowCommandKey.getSelection()) {
 				showKeysUI.openForPreview(ShowKeysToggleHandler.COMMAND_ID, null);
 			}
 		}));
+		fShowCommandKeyForMouseEvents = new Button(group, SWT.CHECK);
+		fShowCommandKeyForMouseEvents.setText(NewKeysPreferenceMessages.ShowCommandKeysForMouse_Text);
+		fShowCommandKeyForMouseEvents
+				.setSelection(getPreferenceStore().getBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_MOUSE_EVENTS));
+		fShowCommandKeyForMouseEvents.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
+			// show a preview of the shortcut popup
+			if (fShowCommandKeyForMouseEvents.getSelection()) {
+				showKeysUI.openForPreview(ShowKeysToggleHandler.COMMAND_ID, null);
+			}
+		}));
 	}
 
 	@Override
@@ -1100,7 +1115,10 @@
 	@Override
 	public boolean performOk() {
 		keyController.saveBindings(fBindingService);
-		getPreferenceStore().setValue(IPreferenceConstants.SHOW_KEYS_ENABLED, fShowCommandKey.getSelection());
+		IPreferenceStore preferenceStore = getPreferenceStore();
+		preferenceStore.setValue(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_KEYBOARD, fShowCommandKey.getSelection());
+		preferenceStore.setValue(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_MOUSE_EVENTS,
+				fShowCommandKeyForMouseEvents.getSelection());
 
 		saveState(getDialogSettings());
 		return super.performOk();
@@ -1161,7 +1179,9 @@
 			}
 
 			fShowCommandKey
-					.setSelection(getPreferenceStore().getDefaultBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED));
+					.setSelection(getPreferenceStore().getDefaultBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_KEYBOARD));
+			fShowCommandKeyForMouseEvents.setSelection(
+					getPreferenceStore().getDefaultBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_MOUSE_EVENTS));
 		}
 
 		super.performDefaults();
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferencePage.properties b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferencePage.properties
index 6827bc7..11a8690 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferencePage.properties
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/NewKeysPreferencePage.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2005, 2019 IBM Corporation and others.
+# Copyright (c) 2005, 2020 IBM Corporation and others.
 #
 # This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License 2.0
@@ -55,4 +55,6 @@
 UncategorizedFilterCheckBox_Text = Filter &uncategorized commands
 KeysPreferenceFilterDialog_Title= When Context Filters
 
-ShowCommandKeys_Text=Show &key binding when command is invoked
+ShowCommandKeysGroup_Title=Show key binding when command is invoked
+ShowCommandKeysForKeyboard_Text=Through &keyboard
+ShowCommandKeysForMouse_Text=Through &mouse click
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysListener.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysListener.java
index 5a409b3..1639328 100755
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysListener.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysListener.java
@@ -20,7 +20,6 @@
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.ui.commands.ICommandService;
 import org.eclipse.ui.internal.IPreferenceConstants;
@@ -66,15 +65,12 @@
 			return;
 		}
 
-		// We never know from which thread we are called, so schedule the UI opening in
-		// the event loop. Also, this allows having the popup on top of whatever UI is
-		// opened right now. E.g. we can now draw on top of the Quick Access UI rather
-		// than being hidden underneath it.
-		Display.getDefault().asyncExec(() -> showKeysUI.open(commandId, (Event) event.getTrigger()));
+		showKeysUI.open(commandId, (Event) event.getTrigger());
 	}
 
 	private boolean isEnabled() {
-		return this.preferenceStore.getBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED);
+		return this.preferenceStore.getBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_KEYBOARD)
+				|| this.preferenceStore.getBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_MOUSE_EVENTS);
 	}
 
 	@Override
@@ -92,7 +88,8 @@
 	@Override
 	public void propertyChange(PropertyChangeEvent event) {
 		String property = event.getProperty();
-		if (IPreferenceConstants.SHOW_KEYS_ENABLED.equals(property)) {
+		if (IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_KEYBOARD.equals(property)
+				|| IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_MOUSE_EVENTS.equals(property)) {
 			ICommandService cmdService = this.serviceLocator.getService(ICommandService.class);
 			if (isEnabled()) {
 				cmdService.addExecutionListener(this);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysToggleHandler.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysToggleHandler.java
index f169ca8..7d7439c 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysToggleHandler.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysToggleHandler.java
@@ -16,7 +16,6 @@
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.internal.IPreferenceConstants;
 import org.eclipse.ui.internal.WorkbenchPlugin;
@@ -32,7 +31,10 @@
 	@Override
 	public Object execute(ExecutionEvent event) {
 		IPreferenceStore prefStore = WorkbenchPlugin.getDefault().getPreferenceStore();
-		boolean newValue = toggleValue(IPreferenceConstants.SHOW_KEYS_ENABLED, prefStore);
+		boolean newValue = toggleValue(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_KEYBOARD, prefStore);
+		// deliberately keep both values the same, i.e. set the second pref to the same
+		// value
+		prefStore.setValue(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_MOUSE_EVENTS, newValue);
 		if (newValue) {
 			showPreview(prefStore);
 		}
@@ -51,7 +53,7 @@
 			// do not end up in multiple popups
 			showKeysUI = new ShowKeysUI(PlatformUI.getWorkbench(), prefStore);
 		}
-		Display.getDefault().asyncExec(() -> showKeysUI.openForPreview(ShowKeysToggleHandler.COMMAND_ID, null));
+		showKeysUI.openForPreview(ShowKeysToggleHandler.COMMAND_ID, null);
 	}
 
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysUI.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysUI.java
index 2f80b7f..bfd664b 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysUI.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/keys/show/ShowKeysUI.java
@@ -97,21 +97,32 @@
 		if (trigger != null) {
 			int accelerator = SWTKeySupport.convertEventToUnmodifiedAccelerator(trigger);
 			KeyStroke keyStroke = SWTKeySupport.convertAcceleratorToKeyStroke(accelerator);
-			if (KeyStroke.NO_KEY != keyStroke.getNaturalKey()) {
+			// keyboard trigger
+			if (preferenceStore.getBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_KEYBOARD)
+					&& KeyStroke.NO_KEY != keyStroke.getNaturalKey()) {
 				return SWTKeySupport.getKeyFormatterForPlatform().format(keyStroke);
 			}
+			// mouse-triggered event
+			else if (preferenceStore.getBoolean(IPreferenceConstants.SHOW_KEYS_ENABLED_FOR_MOUSE_EVENTS)
+					&& KeyStroke.NO_KEY == keyStroke.getNaturalKey()) {
+				return serviceLocator.getService(IBindingService.class).getBestActiveBindingFormattedFor(commandId);
+			}
 		}
-		// fallback if trigger does not provide a key binding
-		return serviceLocator.getService(IBindingService.class).getBestActiveBindingFormattedFor(commandId);
+		return null;
 	}
 
 	private void openPopup(String shortcut, String shortcutText, String shortcutDescription) {
-		closePopup();
-		int timeToClose = this.preferenceStore.getInt(IPreferenceConstants.SHOW_KEYS_TIME_TO_CLOSE);
-		Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
-		this.shortcutPopup = new ShowKeysPopup(shell, timeToClose);
-		this.shortcutPopup.setShortcut(shortcut, shortcutText, shortcutDescription);
-		this.shortcutPopup.open();
+		// Schedule the UI opening in the event loop. This allows having the popup on
+		// top of whatever UI is opened right now. E.g. we can now draw on top of the
+		// Quick Access UI rather than being hidden underneath it.
+		Display.getDefault().asyncExec(() -> {
+			closePopup();
+			int timeToClose = this.preferenceStore.getInt(IPreferenceConstants.SHOW_KEYS_TIME_TO_CLOSE);
+			Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+			this.shortcutPopup = new ShowKeysPopup(shell, timeToClose);
+			this.shortcutPopup.setShortcut(shortcut, shortcutText, shortcutDescription);
+			this.shortcutPopup.open();
+		});
 	}
 
 	private void closePopup() {