445806: display only search results pertinent to the active task context

Change-Id: Ic4c3c408231ad445d2609d13dc9fb0b27106c5ea
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=445806
Signed-off-by: Suzannah Smith <ssmith13@unb.ca>
diff --git a/org.eclipse.mylyn.context.ui/META-INF/MANIFEST.MF b/org.eclipse.mylyn.context.ui/META-INF/MANIFEST.MF
index 6ef3990..d629ccb 100644
--- a/org.eclipse.mylyn.context.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.context.ui/META-INF/MANIFEST.MF
@@ -31,4 +31,6 @@
  org.eclipse.mylyn.internal.context.ui.state;x-internal:=true,
  org.eclipse.mylyn.internal.context.ui.views;x-internal:=true
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: com.ibm.icu.text
+Import-Package: com.ibm.icu.text,
+ org.eclipse.jdt.core,
+ org.eclipse.search.internal.ui.text
diff --git a/org.eclipse.mylyn.context.ui/src/org/eclipse/mylyn/context/ui/SearchInterestFilter.java b/org.eclipse.mylyn.context.ui/src/org/eclipse/mylyn/context/ui/SearchInterestFilter.java
new file mode 100644
index 0000000..9476046
--- /dev/null
+++ b/org.eclipse.mylyn.context.ui/src/org/eclipse/mylyn/context/ui/SearchInterestFilter.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.context.ui;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.search.internal.ui.text.LineElement;
+
+/**
+ * @since 3.22
+ */
+public class SearchInterestFilter extends InterestFilter {
+
+	@SuppressWarnings("restriction")
+	@Override
+	public boolean select(Viewer viewer, Object parent, Object object) {
+		//Only filter out entire projects. All search results
+		//within a project that is in the current context will appear.
+		IProject project = null;
+		if (object instanceof IResource) {
+			project = ((IResource) object).getProject();
+		} else if (object instanceof IJavaElement) {
+			project = ((IJavaElement) object).getJavaProject().getProject();
+		} else if (object instanceof LineElement) {
+			project = ((LineElement) object).getParent().getProject();
+		} else {
+			//Include unknown elements in search results
+			return true;
+		}
+		return super.select(viewer, parent, project);
+	}
+
+}
diff --git a/org.eclipse.mylyn.ide.ui/META-INF/MANIFEST.MF b/org.eclipse.mylyn.ide.ui/META-INF/MANIFEST.MF
index d3983e3..7d0c541 100644
--- a/org.eclipse.mylyn.ide.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.ide.ui/META-INF/MANIFEST.MF
@@ -15,7 +15,8 @@
  org.eclipse.mylyn.commons.ui;bundle-version="[3.8.0,4.0.0)",
  org.eclipse.mylyn.context.core;bundle-version="[3.8.0,4.0.0)",
  org.eclipse.mylyn.context.ui;bundle-version="[3.8.0,4.0.0)",
- org.eclipse.mylyn.resources.ui;bundle-version="[3.8.0,4.0.0)"
+ org.eclipse.mylyn.resources.ui;bundle-version="[3.8.0,4.0.0)",
+ org.eclipse.search
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.mylyn.ide.ui,
  org.eclipse.mylyn.internal.ide.ui;x-internal:=true,
diff --git a/org.eclipse.mylyn.ide.ui/plugin.properties b/org.eclipse.mylyn.ide.ui/plugin.properties
index cc8ecf1..eb4e636 100644
--- a/org.eclipse.mylyn.ide.ui/plugin.properties
+++ b/org.eclipse.mylyn.ide.ui/plugin.properties
@@ -15,6 +15,8 @@
 
 FocusProjectExplorerAction.label = Focus on Active Task
 FocusProjectExplorerAction.tooltip = Focus on Active Task (Alt+click to reveal filtered elements)
+FocusSearchResultsViewAction.label = Focus on Active Task
+FocusSearchResultsViewAction.tooltip = Focus on Active Task (Alt+click to reveal filtered elements)
 FocusResourceNavigatorAction.label = Focus on Active Task
 FocusResourceNavigatorAction.tooltip = Focus on Active Task (Alt+click to reveal filtered elements)
 FocusProblemsListAction.label = Focus on Active Task
diff --git a/org.eclipse.mylyn.ide.ui/plugin.xml b/org.eclipse.mylyn.ide.ui/plugin.xml
index a13ee4b..f4c17d9 100644
--- a/org.eclipse.mylyn.ide.ui/plugin.xml
+++ b/org.eclipse.mylyn.ide.ui/plugin.xml
@@ -36,6 +36,29 @@
   		</action> 
       </viewContribution> 
       
+      <viewContribution 
+		id="org.eclipse.mylyn.ui.search.contribution" 
+   		targetID="org.eclipse.search.ui.views.SearchView">
+    	<action
+           class="org.eclipse.mylyn.internal.ide.ui.actions.FocusSearchResultsViewAction"
+           disabledIcon="icons/elcl16/focus-disabled.gif"
+           enablesFor="*"
+           icon="icons/elcl16/focus.gif"
+           id="org.eclipse.mylyn.ide.ui.actions.focus.search.results"
+           label="%FocusSearchResultsViewAction.label"
+           menubarPath="mylyn"
+           style="toggle"
+           toolbarPath="mylyn"
+           tooltip="%FocusSearchResultsViewAction.tooltip">
+        <enablement>
+           <systemProperty
+                 name="org.eclipse.mylyn.context.core.context.active"
+                 value="true">
+           </systemProperty>
+        </enablement> 
+  		</action> 
+      </viewContribution> 
+      
 	  <viewContribution 
 		id="org.eclipse.mylyn.ui.resource.navigator.filter" 
    		targetID="org.eclipse.ui.views.ResourceNavigator">
diff --git a/org.eclipse.mylyn.ide.ui/src/org/eclipse/mylyn/internal/ide/ui/actions/FocusSearchResultsViewAction.java b/org.eclipse.mylyn.ide.ui/src/org/eclipse/mylyn/internal/ide/ui/actions/FocusSearchResultsViewAction.java
new file mode 100644
index 0000000..249b0c0
--- /dev/null
+++ b/org.eclipse.mylyn.ide.ui/src/org/eclipse/mylyn/internal/ide/ui/actions/FocusSearchResultsViewAction.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.ide.ui.actions;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.mylyn.context.ui.AbstractFocusViewAction;
+import org.eclipse.mylyn.context.ui.SearchInterestFilter;
+import org.eclipse.search.ui.ISearchResultPage;
+import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
+import org.eclipse.search2.internal.ui.SearchView;
+import org.eclipse.ui.IViewPart;
+
+public class FocusSearchResultsViewAction extends AbstractFocusViewAction {
+
+	private static final List<String> WHITELISTED_IDS = Arrays
+			.asList(new String[] { "org.eclipse.search.text.FileSearchResultPage", //$NON-NLS-1$
+					"org.eclipse.jdt.ui.JavaSearchResultPage" //$NON-NLS-1$
+	});
+
+	public FocusSearchResultsViewAction() {
+		super(new SearchInterestFilter(), true, true, true);
+	}
+
+	@Override
+	public List<StructuredViewer> getViewers() {
+		List<StructuredViewer> viewers = new ArrayList<StructuredViewer>();
+
+		ISearchResultPage page = getCurrentPage();
+		if (page instanceof AbstractTextSearchViewPage) {
+			try {
+				Method getViewer = AbstractTextSearchViewPage.class.getDeclaredMethod("getViewer"); //$NON-NLS-1$
+				getViewer.setAccessible(true);
+				StructuredViewer viewer = (StructuredViewer) getViewer.invoke(page);
+				viewers.add(viewer);
+			} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
+					| InvocationTargetException e) {
+				// ignore
+			}
+		}
+
+		return viewers;
+	}
+
+	@SuppressWarnings("restriction")
+	private ISearchResultPage getCurrentPage() {
+		IViewPart view = super.getPartForAction();
+		return ((SearchView) view).getActivePage();
+	}
+
+	@Override
+	public boolean isEnabled() {
+		List<StructuredViewer> viewers = getViewers();
+		ISearchResultPage page = getCurrentPage();
+
+		return viewers.size() > 0 && WHITELISTED_IDS.contains(page.getID());
+	}
+
+	@Override
+	protected void updateEnablement(IAction action) {
+		action.setEnabled(isEnabled());
+	}
+}