changeset 1:f7d908568cfc

Install a custom JavaElementImageProvider subclass so that the custom title image stays in place even if the editor icon is decorated e.g. by error markers.
author Dirk Olmes <dirk@xanthippe.ping.de>
date Sat, 13 Dec 2014 13:54:38 +0100
parents ca07a15b6cc8
children 79c8c1f9fd7d
files META-INF/MANIFEST.MF src/de/codedo/java/editor/Activator.java src/de/codedo/java/editor/CodedoJavaEditor.java src/de/codedo/java/editor/CodedoJavaElementImageProvider.java src/de/codedo/java/editor/ToggleEditorIconHandler.java
diffstat 5 files changed, 138 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/META-INF/MANIFEST.MF	Thu Oct 23 22:20:08 2014 +0200
+++ b/META-INF/MANIFEST.MF	Sat Dec 13 13:54:38 2014 +0100
@@ -10,6 +10,7 @@
  org.eclipse.ui.editors,
  org.eclipse.jface.text,
  org.eclipse.jdt.ui,
- org.eclipse.jdt.core
+ org.eclipse.jdt.core,
+ org.eclipse.core.resources
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Bundle-ActivationPolicy: lazy
--- a/src/de/codedo/java/editor/Activator.java	Thu Oct 23 22:20:08 2014 +0200
+++ b/src/de/codedo/java/editor/Activator.java	Sat Dec 13 13:54:38 2014 +0100
@@ -6,45 +6,39 @@
 /**
  * The activator class controls the plug-in life cycle
  */
-public class Activator extends AbstractUIPlugin {
-
+public class Activator extends AbstractUIPlugin 
+{
 	// The plug-in ID
 	public static final String PLUGIN_ID = "de.codedo.java.editor"; //$NON-NLS-1$
 
 	// The shared instance
-	private static Activator plugin;
+	private static Activator Plugin;
+
+	private CodedoJavaElementImageProvider _javaElementImageProvider;
 	
-	/**
-	 * The constructor
-	 */
-	public Activator() {
+	public static Activator getDefault()
+	{
+		return Plugin;
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
-	 */
-	public void start(BundleContext context) throws Exception {
+	public void start(BundleContext context) throws Exception 
+	{
 		super.start(context);
-		plugin = this;
+		Plugin = this;
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-	 */
-	public void stop(BundleContext context) throws Exception {
-		plugin = null;
+	public void stop(BundleContext context) throws Exception 
+	{
+		Plugin = null;
 		super.stop(context);
 	}
-
-	/**
-	 * Returns the shared instance
-	 *
-	 * @return the shared instance
-	 */
-	public static Activator getDefault() {
-		return plugin;
+	
+	public synchronized CodedoJavaElementImageProvider getJavaElementImageProvider()
+	{
+		if (_javaElementImageProvider == null)
+		{
+			_javaElementImageProvider = new CodedoJavaElementImageProvider();
+		}
+		return _javaElementImageProvider;
 	}
-
 }
--- a/src/de/codedo/java/editor/CodedoJavaEditor.java	Thu Oct 23 22:20:08 2014 +0200
+++ b/src/de/codedo/java/editor/CodedoJavaEditor.java	Sat Dec 13 13:54:38 2014 +0100
@@ -1,51 +1,69 @@
 package de.codedo.java.editor;
 
-import java.io.InputStream;
+import java.lang.reflect.Field;
 
+import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
-import org.eclipse.swt.graphics.Device;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditorErrorTickUpdater;
+import org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider;
 import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorInput;
 
 public class CodedoJavaEditor extends CompilationUnitEditor 
 {
-	private Image _originalTitleImage;
-	private Image _customTitleImage;
-	
-	public void toggleTitleImage()
+	public CodedoJavaEditor() 
+	{
+		super();
+		installJavaElementImageProvider();
+	}
+
+	private void installJavaElementImageProvider()
 	{
-		if (_originalTitleImage == null)
+		try
 		{
-			installCustomTitleImage();
+			JavaUILabelProvider labelProvider = getJavaUILabelProvider();
+			setupJavaElementImageProvider(labelProvider);
 		}
-		else
+		catch (ReflectiveOperationException e) 
 		{
-			restoreOriginalTitleImage();
+			throw new RuntimeException(e);
 		}
 	}
 
-	private void installCustomTitleImage() 
+	private JavaUILabelProvider getJavaUILabelProvider() throws ReflectiveOperationException
+	{
+		JavaEditorErrorTickUpdater tickUpdater = getJavaEditorErrorTickUpdater();
+
+		Field field = tickUpdater.getClass().getDeclaredField("fLabelProvider");
+		field.setAccessible(true);
+		return (JavaUILabelProvider)field.get(tickUpdater);
+	}
+	
+	private JavaEditorErrorTickUpdater getJavaEditorErrorTickUpdater() throws ReflectiveOperationException 
 	{
-		_originalTitleImage = getTitleImage();
+		Field field = getClass().getSuperclass().getDeclaredField("fJavaEditorErrorTickUpdater");
+		field.setAccessible(true);
+		return (JavaEditorErrorTickUpdater)field.get(this);
+	}	
+	
+	private void setupJavaElementImageProvider(JavaUILabelProvider labelProvider) throws ReflectiveOperationException
+	{
+		CodedoJavaElementImageProvider imageProvider = Activator.getDefault().getJavaElementImageProvider();
 		
-		Image titleImage = getCustomTitleImage();
-		setTitleImage(titleImage);
+		Field field = labelProvider.getClass().getDeclaredField("fImageLabelProvider");
+		field.setAccessible(true);
+		field.set(labelProvider, imageProvider);
 	}
 
-	private Image getCustomTitleImage()
+	public void toggleTitleImage()
 	{
-		if (_customTitleImage == null)
-		{
-			Device device = getDefaultImage().getDevice();
+		IEditorInput input = getEditorInput();
+		
+		// this class is registered as Java editor so we should always have a java element here
+		IJavaElement javaElement = (IJavaElement)input.getAdapter(IJavaElement.class);
 
-			InputStream input = getClass().getClassLoader().getResourceAsStream("icons/icon.png");
-			_customTitleImage = new Image(device, input);
-		}
-		return _customTitleImage;
-	}
-	
-	private void restoreOriginalTitleImage() 
-	{
-		setTitleImage(_originalTitleImage);
-		_originalTitleImage = null;
+		CodedoJavaElementImageProvider imageProvider = Activator.getDefault().getJavaElementImageProvider();
+		Image newTitleImage =  imageProvider.toggleTitleImage(javaElement);
+		setTitleImage(newTitleImage);
 	}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/de/codedo/java/editor/CodedoJavaElementImageProvider.java	Sat Dec 13 13:54:38 2014 +0100
@@ -0,0 +1,66 @@
+package de.codedo.java.editor;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+public class CodedoJavaElementImageProvider extends JavaElementImageProvider 
+{
+	private Set<IJavaElement> _editorsWithCustomTitleImage;
+	private Image _customTitleImage;
+
+	public CodedoJavaElementImageProvider()
+	{
+		super();
+		_editorsWithCustomTitleImage = new HashSet<>();
+	}
+
+	@Override
+	public Image getImageLabel(Object element, int flags)
+	{
+		if (element instanceof IJavaElement)
+		{
+			IJavaElement javaElement = (IJavaElement)element;
+			if (_editorsWithCustomTitleImage.contains(javaElement))
+			{
+				return getCustomTitleImage();
+			}
+		}
+		
+		return super.getImageLabel(element, flags);
+	}
+
+	public Image toggleTitleImage(IJavaElement element)
+	{
+		if (_editorsWithCustomTitleImage.contains(element))
+		{
+			_editorsWithCustomTitleImage.remove(element);
+			return super.getImageLabel(element, 0);
+		}
+		else
+		{
+			_editorsWithCustomTitleImage.add(element);
+			return getCustomTitleImage();
+		}
+	}
+	
+	protected Image getCustomTitleImage()
+	{
+		if (_customTitleImage == null)
+		{
+			Image image = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_DEF_VIEW);
+			Device device = image.getDevice();
+
+			InputStream input = getClass().getClassLoader().getResourceAsStream("icons/icon.png");
+			_customTitleImage = new Image(device, input);
+		}
+		return _customTitleImage;
+	}
+}
--- a/src/de/codedo/java/editor/ToggleEditorIconHandler.java	Thu Oct 23 22:20:08 2014 +0200
+++ b/src/de/codedo/java/editor/ToggleEditorIconHandler.java	Sat Dec 13 13:54:38 2014 +0100
@@ -12,7 +12,8 @@
 	public Object execute(ExecutionEvent event) throws ExecutionException 
 	{
 		IEditorPart editorPart = HandlerUtil.getActiveEditor(event);
-		if (editorPart instanceof CodedoJavaEditor) {
+		if (editorPart instanceof CodedoJavaEditor)
+		{
 			CodedoJavaEditor editor = (CodedoJavaEditor)editorPart;
 			editor.toggleTitleImage();
 		}