Bug 518939 - Fix text zoom enablement in multi page editors

Change-Id: I2b13a98af986419a38b63043aa680b3e8d628fd2
Signed-off-by: Sebastian Ratz <sebastian.ratz@sap.com>
diff --git a/org.eclipse.ui.workbench.texteditor.tests/META-INF/MANIFEST.MF b/org.eclipse.ui.workbench.texteditor.tests/META-INF/MANIFEST.MF
index 4a1e176..6df2e3b 100644
--- a/org.eclipse.ui.workbench.texteditor.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.ui.workbench.texteditor.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Plugin.name
 Bundle-SymbolicName: org.eclipse.ui.workbench.texteditor.tests
-Bundle-Version: 3.11.100.qualifier
+Bundle-Version: 3.12.0.qualifier
 Bundle-Vendor: %Plugin.providerName
 Bundle-Localization: plugin
 Export-Package: 
@@ -15,6 +15,7 @@
  org.eclipse.ui.workbench.texteditor;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.ui;bundle-version="[3.5.0,4.0.0)",
  org.junit;bundle-version="4.12.0",
- org.eclipse.text.tests;bundle-version="[3.5.0,4.0.0)"
+ org.eclipse.text.tests;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.core.expressions;bundle-version="[3.5.0,4.0.0)"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Eclipse-BundleShape: dir
diff --git a/org.eclipse.ui.workbench.texteditor.tests/pom.xml b/org.eclipse.ui.workbench.texteditor.tests/pom.xml
index a8128a6..a2a8006 100644
--- a/org.eclipse.ui.workbench.texteditor.tests/pom.xml
+++ b/org.eclipse.ui.workbench.texteditor.tests/pom.xml
@@ -19,7 +19,7 @@
   </parent>
   <groupId>org.eclipse.ui</groupId>
   <artifactId>org.eclipse.ui.workbench.texteditor.tests</artifactId>
-  <version>3.11.100-SNAPSHOT</version>
+  <version>3.12.0-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
   <properties>
   	<testSuite>${project.artifactId}</testSuite>
diff --git a/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/AbstractTextZoomHandlerTest.java b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/AbstractTextZoomHandlerTest.java
new file mode 100644
index 0000000..f8e0fba
--- /dev/null
+++ b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/AbstractTextZoomHandlerTest.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2017 SAP SE 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:
+ *     SAP SE - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.workbench.texteditor.tests;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import org.eclipse.swt.widgets.Composite;
+
+import org.eclipse.core.expressions.EvaluationContext;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.AbstractMultiEditor;
+import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.part.MultiPageEditorPart;
+
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+import org.eclipse.ui.texteditor.TextZoomInHandler;
+
+public class AbstractTextZoomHandlerTest {
+
+	@Test
+	public void textZoomIsSupportedForAbstractTextEditor() {
+		IEditorPart part= new TestAbstractTextEditor();
+
+		assertZoomSupported(part, true);
+	}
+
+	@Test
+	public void textZoomIsNotSupportedForNonTextEditor() {
+		IEditorPart part= new TestNonTextEditor();
+
+		assertZoomSupported(part, false);
+	}
+
+	@Test
+	public void textZoomIsSupportedForMultiPageEditorPartWithAbstractTextEditorPage() {
+		EditorPart part= new TestMultiPageEditorPart(new TestAbstractTextEditor());
+
+		assertZoomSupported(part, true);
+	}
+
+	@Test
+	public void textZoomIsNotSupportedForMultiPageEditorPartWithNonTextPage() {
+		EditorPart part= new TestMultiPageEditorPart(new TestNonTextEditor());
+
+		assertZoomSupported(part, false);
+	}
+
+	@Test
+	public void textZoomIsSupportedForMultiEditorWithTextPage() {
+		EditorPart part= new TestMultiEditor(new TestAbstractTextEditor());
+
+		assertZoomSupported(part, true);
+	}
+
+	@Test
+	public void textZoomIsNotSupportedForMultiEditorWithNonTextPage() {
+		EditorPart part= new TestMultiEditor(new TestNonTextEditor());
+
+		assertZoomSupported(part, false);
+	}
+
+	@Test
+	public void textZoomIsSupportedForAdaptableToAbstractTextEditor() {
+		IEditorPart part= new TestAdaptableToAbstractTestEditor();
+
+		assertZoomSupported(part, true);
+	}
+
+	@Test
+	public void textZoomIsNotSupportedForGenericObject() {
+		assertZoomSupported(new Object(), false);
+	}
+
+	private void assertZoomSupported(Object receiver, boolean expectedEnabled) {
+		TextZoomInHandler textZoomHandler= new TextZoomInHandler();
+
+		EvaluationContext evaluationContext= new EvaluationContext(null, new Object());
+		evaluationContext.addVariable(ISources.ACTIVE_EDITOR_NAME, receiver);
+
+		textZoomHandler.setEnabled(evaluationContext);
+
+		boolean actualEnabled= textZoomHandler.isEnabled();
+
+		assertEquals(expectedEnabled, actualEnabled);
+	}
+
+	private static class TestAbstractTextEditor extends AbstractTextEditor {
+
+		@Override
+		public <T> T getAdapter(Class<T> adapter) {
+			return null;
+		}
+
+		@Override
+		public void init(IEditorSite site, IEditorInput input) throws PartInitException { //
+		}
+	}
+
+	private static class TestNonTextEditor extends EditorPart {
+
+		@Override
+		public <T> T getAdapter(Class<T> adapter) {
+			return null;
+		}
+
+		@Override
+		public void doSave(IProgressMonitor monitor) { //
+		}
+
+		@Override
+		public void doSaveAs() { //
+		}
+
+		@Override
+		public void init(IEditorSite site, IEditorInput input) throws PartInitException { //
+		}
+
+		@Override
+		public boolean isDirty() { //
+			return false;
+		}
+
+		@Override
+		public boolean isSaveAsAllowed() { //
+			return false;
+		}
+
+		@Override
+		public void createPartControl(Composite parent) { //
+		}
+
+		@Override
+		public void setFocus() { //
+		}
+	}
+
+	private static class TestAdaptableToAbstractTestEditor extends TestNonTextEditor {
+
+		@Override
+		public <T> T getAdapter(Class<T> adapter) {
+			if (adapter == AbstractTextEditor.class) {
+				return adapter.cast(new TestAbstractTextEditor());
+			}
+			return null;
+		}
+	}
+
+	private static class TestMultiEditor extends AbstractMultiEditor {
+
+		@Override
+		public <T> T getAdapter(Class<T> adapter) {
+			return null;
+		}
+
+		public TestMultiEditor(IEditorPart child) {
+			setChildren(new IEditorPart[] { child });
+		}
+
+		@Override
+		public void createPartControl(Composite parent) { //
+		}
+
+		@Override
+		protected void innerEditorsCreated() { //
+		}
+
+		@Override
+		public Composite getInnerEditorContainer(IEditorReference innerEditorReference) {
+			return null;
+		}
+	}
+
+	private static class TestMultiPageEditorPart extends MultiPageEditorPart {
+
+		private IEditorPart child;
+
+		public TestMultiPageEditorPart(IEditorPart child) {
+			this.child= child;
+		}
+
+		@Override
+		public <T> T getAdapter(Class<T> adapter) {
+			return null;
+		}
+
+		@Override
+		public boolean isSaveAsAllowed() {
+			return false;
+		}
+
+		@Override
+		public void doSaveAs() { //
+		}
+
+		@Override
+		public void doSave(IProgressMonitor monitor) { //
+		}
+
+		@Override
+		protected void createPages() { //
+		}
+
+		@Override
+		public void init(IEditorSite site, IEditorInput input) throws PartInitException { //
+		}
+
+		@Override
+		public Object getSelectedPage() {
+			return child;
+		}
+	}
+
+}
diff --git a/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/WorkbenchTextEditorTestSuite.java b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/WorkbenchTextEditorTestSuite.java
index ec8d266..7c3a171 100644
--- a/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/WorkbenchTextEditorTestSuite.java
+++ b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/WorkbenchTextEditorTestSuite.java
@@ -33,7 +33,8 @@
 		ChangeRegionTest.class,
 		RulerTestSuite.class,
 		HunkComputerTest.class,
-		ScreenshotTest.class
+		ScreenshotTest.class,
+		AbstractTextZoomHandlerTest.class
 })
 public class WorkbenchTextEditorTestSuite {
 	// see @SuiteClasses
diff --git a/org.eclipse.ui.workbench.texteditor/plugin.xml b/org.eclipse.ui.workbench.texteditor/plugin.xml
index 7316269..c5b9c21 100644
--- a/org.eclipse.ui.workbench.texteditor/plugin.xml
+++ b/org.eclipse.ui.workbench.texteditor/plugin.xml
@@ -1308,24 +1308,10 @@
       <handler
             class="org.eclipse.ui.texteditor.TextZoomInHandler"
             commandId="org.eclipse.ui.edit.text.zoomIn">
-         <enabledWhen>
-            <with variable="activePart">
-               <instanceof
-                     value="org.eclipse.ui.texteditor.ITextEditor">
-               </instanceof>
-            </with>
-         </enabledWhen>
       </handler>
       <handler
             class="org.eclipse.ui.texteditor.TextZoomOutHandler"
             commandId="org.eclipse.ui.edit.text.zoomOut">
-         <enabledWhen>
-            <with variable="activePart">
-               <instanceof
-                     value="org.eclipse.ui.texteditor.ITextEditor">
-               </instanceof>
-            </with>
-         </enabledWhen>
       </handler>
    </extension>
    <extension
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextZoomHandler.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextZoomHandler.java
index d65e489..d082503 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextZoomHandler.java
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextZoomHandler.java
@@ -22,6 +22,7 @@
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.IEvaluationContext;
 
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.Platform;
@@ -31,7 +32,8 @@
 import org.eclipse.jface.resource.FontRegistry;
 import org.eclipse.jface.resource.JFaceResources;
 
-import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.ISources;
 import org.eclipse.ui.handlers.HandlerUtil;
 import org.eclipse.ui.part.AbstractMultiEditor;
 import org.eclipse.ui.part.MultiPageEditorPart;
@@ -93,7 +95,10 @@
 	}
 
 	private AbstractTextEditor getActiveTextEditor(ExecutionEvent event) {
-		IWorkbenchPart part= HandlerUtil.getActiveEditor(event);
+		return getActiveTextEditor(HandlerUtil.getActiveEditor(event));
+	}
+
+	private AbstractTextEditor getActiveTextEditor(IEditorPart part) {
 		if (part instanceof AbstractTextEditor) {
 			return (AbstractTextEditor)part;
 		} else if ((part instanceof AbstractMultiEditor) && ((AbstractMultiEditor)part).getActiveEditor() instanceof AbstractTextEditor) {
@@ -105,8 +110,15 @@
 	}
 
 	@Override
-	public boolean isEnabled() {
-		return true;
+	public void setEnabled(Object evaluationContext) {
+		boolean enabled = false;
+		if (evaluationContext instanceof IEvaluationContext) {
+			Object activeEditor = ((IEvaluationContext) evaluationContext).getVariable(ISources.ACTIVE_EDITOR_NAME);
+			if (activeEditor instanceof IEditorPart) {
+				enabled = getActiveTextEditor((IEditorPart) activeEditor) != null;
+			}
+		}
+		setBaseEnabled(enabled);
 	}
 
 	/**