Bug 393365 - Quick Access drop down is not accessible

Change-Id: I7e5a335cffee4513fb14be149a09c3dc2e4c70cc
Signed-off-by: wsudol <wojciech.sudol@pl.ibm.com>
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessMessages.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessMessages.java
index aab4d95..4ad6999 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessMessages.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessMessages.java
@@ -32,6 +32,7 @@
 	public static String QuickAccess_StartTypingToFindMatches;
 	public static String QuickAccess_AvailableCategories;
 	public static String QuickAccess_EnterSearch;
+	public static String QuickAccess_SelectedString;
 	public static String QuickAccessContents_NoMatchingResults;
 	public static String QuickAccessContents_PressKeyToLimitResults;
 	public static String QuickAccessContents_QuickAccess;
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java
index aa137d9..8a75eb7 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java
@@ -36,7 +36,11 @@
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.util.Geometry;
 import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.accessibility.ACC;
+import org.eclipse.swt.accessibility.AccessibleAdapter;
+import org.eclipse.swt.accessibility.AccessibleEvent;
 import org.eclipse.swt.events.ControlEvent;
 import org.eclipse.swt.events.ControlListener;
 import org.eclipse.swt.events.FocusAdapter;
@@ -57,6 +61,7 @@
 import org.eclipse.swt.widgets.Monitor;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.ISources;
 import org.eclipse.ui.IWorkbenchCommandConstants;
@@ -99,6 +104,9 @@
 	private EPartService partService;
 	private Table table;
 
+	private String selectedString = ""; //$NON-NLS-1$
+	private AccessibleAdapter accessibleListener;
+
 	// private Object invokingCommandKeySequences;
 	// private Object invokingCommand;
 
@@ -150,6 +158,7 @@
 				dialogHeight = shell.getSize().y;
 				dialogWidth = shell.getSize().x;
 				shell.setVisible(false);
+				removeAccessibleListener();
 			}
 
 			protected QuickAccessElement getPerfectMatch(String filter) {
@@ -233,8 +242,15 @@
 				boolean nowVisible = text.getText().length() > 0;
 				if (!wasVisible && nowVisible) {
 					layoutShell();
+					addAccessibleListener();
 					quickAccessContents.preOpen();
 				}
+				if (wasVisible && !nowVisible) {
+					removeAccessibleListener();
+				}
+				if (nowVisible) {
+					notifyAccessibleTextChanged();
+				}
 				shell.setVisible(nowVisible);
 			}
 		});
@@ -252,6 +268,10 @@
 				} else if (e.keyCode == SWT.ARROW_DOWN) {
 					e.doit = false;
 				}
+				if (e.doit == false) {
+					// arrow key pressed
+					notifyAccessibleTextChanged();
+				}
 			}
 		});
 		quickAccessContents.createInfoLabel(shell);
@@ -382,6 +402,7 @@
 			layoutShell();
 			quickAccessContents.preOpen();
 			shell.setVisible(true);
+			addAccessibleListener();
 			quickAccessContents.refresh(text.getText().toLowerCase());
 		} else {
 			quickAccessContents.setShowAllMatches(!quickAccessContents.getShowAllMatches());
@@ -411,6 +432,50 @@
 		}
 	}
 
+	/**
+	 * Adds a listener to the
+	 * <code>org.eclipse.swt.accessibility.Accessible</code> object assigned to
+	 * the Quick Access search box. The listener sets a name of a selected
+	 * element in the search result list as a text to read for a screen reader.
+	 */
+	private void addAccessibleListener() {
+		if (accessibleListener == null) {
+			accessibleListener = new AccessibleAdapter() {
+				public void getName(AccessibleEvent e) {
+					e.result = selectedString;
+				}
+			};
+			text.getAccessible().addAccessibleListener(accessibleListener);
+		}
+	}
+
+	/**
+	 * Removes a listener from the
+	 * <code>org.eclipse.swt.accessibility.Accessible</code> object assigned to
+	 * the Quick Access search box.
+	 */
+	private void removeAccessibleListener() {
+		if (accessibleListener != null) {
+			text.getAccessible().removeAccessibleListener(accessibleListener);
+			accessibleListener = null;
+		}
+		selectedString = ""; //$NON-NLS-1$
+	}
+
+	/**
+	 * Notifies <code>org.eclipse.swt.accessibility.Accessible<code> object
+	 * that selected item has been changed.
+	 */
+	private void notifyAccessibleTextChanged() {
+		if (table.getSelection().length == 0) {
+			return;
+		}
+		TableItem item = table.getSelection()[0];
+		selectedString = NLS.bind(QuickAccessMessages.QuickAccess_SelectedString, item.getText(0),
+				item.getText(1));
+		text.getAccessible().sendEvent(ACC.EVENT_NAME_CHANGED, null);
+	}
+
 	private void restoreDialog() {
 		IDialogSettings dialogSettings = getDialogSettings();
 		if (dialogSettings != null) {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/messages.properties b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/messages.properties
index 32ebae8..3988b93 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/messages.properties
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/messages.properties
@@ -21,6 +21,7 @@
 QuickAccess_StartTypingToFindMatches=Start typing to find matches.
 QuickAccess_AvailableCategories=Available categories:
 QuickAccess_EnterSearch=Quick Access
+QuickAccess_SelectedString={0}: {1}
 QuickAccessContents_NoMatchingResults=No matches found
 QuickAccessContents_PressKeyToLimitResults=Press ''{0}'' to limit matches
 QuickAccessContents_QuickAccess=Quick Access