Bug 409065 - [variables] Enable "Show Logical Structure" by default

Change-Id: If1334e56a3081443c2194e09d0258dafbf369534
diff --git a/org.eclipse.jdt.debug.ui/plugin.properties b/org.eclipse.jdt.debug.ui/plugin.properties
index 7476dad..c454609 100644
--- a/org.eclipse.jdt.debug.ui/plugin.properties
+++ b/org.eclipse.jdt.debug.ui/plugin.properties
@@ -272,7 +272,6 @@
 FormatStackTraceActionDelegate.tooltip= Format
 
 javaLogicalStruturePref.name=Logical Structures
-EditLogicalStructure.label=Edit Logical Structure...
 
 allInstances.label=All Ins&tances...
 allInstances.tooltip=Displays a popup window showing all live instances of the selected type in the current running VM
diff --git a/org.eclipse.jdt.debug.ui/plugin.xml b/org.eclipse.jdt.debug.ui/plugin.xml
index 81ceaef..ee5c856 100644
--- a/org.eclipse.jdt.debug.ui/plugin.xml
+++ b/org.eclipse.jdt.debug.ui/plugin.xml
@@ -895,21 +895,6 @@
             </not>
          </visibility>
       </objectContribution>
-      <objectContribution
-            objectClass="org.eclipse.jdt.debug.core.IJavaVariable"
-            id="org.eclipse.jdt.debug.ui.JavaLogicalStructureActions">
-         <action
-               enablesFor="1"
-               label="%EditLogicalStructure.label"
-               class="org.eclipse.jdt.internal.debug.ui.actions.EditVariableLogicalStructureAction"
-               menubarPath="emptyNavigationGroup"
-               id="EditLogicalStructure"/>
-         <visibility>
-            <objectState
-                  value="canEditLogicalStructure"
-                  name="JavaLogicalStructureFilter"/>
-         </visibility>
-      </objectContribution>
       <viewerContribution
             targetID="#JavaSnippetEditorContext"
             id="org.eclipse.jdt.debug.ui.JavaSnippetPopupActions">
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIElementImageDescriptor.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIElementImageDescriptor.java
new file mode 100644
index 0000000..6643b11
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIElementImageDescriptor.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2017 IBM Corporation 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:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.ui;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.debug.internal.ui.DebugPluginImages;
+import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Point;
+
+public class JDIElementImageDescriptor extends CompositeImageDescriptor {
+
+	private ImageDescriptor fBaseImage;
+	private int fFlags;
+	private Point fSize;
+	public JDIElementImageDescriptor(ImageDescriptor baseImage, int flags, Point size) {
+		fBaseImage = baseImage;
+		Assert.isNotNull(fBaseImage);
+		fFlags = flags;
+		Assert.isTrue(fFlags >= 0);
+		fSize = size;
+		Assert.isNotNull(fSize);
+	}
+
+	@Override
+	protected void drawCompositeImage(int width, int height) {
+		drawImage(createCachedImageDataProvider(fBaseImage), 0, 0);
+		drawRightBottom();
+	}
+
+	private void drawRightBottom() {
+		Point size = getSize();
+		Point pos = new Point(size.x, size.y);
+
+		if ((fFlags & JDIImageDescriptor.LOGICAL_STRUCTURE) != 0) {
+			addRightBottomImage(DebugPluginImages.getImageDescriptor(IInternalDebugUIConstants.IMG_OVR_SHOW_LOGICAL_STRUCTURE), pos);
+		}
+	}
+
+	private void addRightBottomImage(ImageDescriptor desc, Point pos) {
+		CachedImageDataProvider provider = createCachedImageDataProvider(desc);
+		int x = pos.x - provider.getWidth();
+		int y = pos.y - provider.getHeight();
+		if (x >= 0 && y >= 0) {
+			drawImage(provider, x, y);
+			pos.x = x;
+		}
+	}
+
+	@Override
+	protected Point getSize() {
+		if (fSize == null) {
+			CachedImageDataProvider provider = createCachedImageDataProvider(fBaseImage);
+			fSize = new Point(provider.getWidth(), provider.getHeight());
+		}
+		return fSize;
+	}
+
+	/**
+	 * @see Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object object) {
+		if (!(object instanceof JDIElementImageDescriptor)) {
+			return false;
+		}
+		JDIElementImageDescriptor other = (JDIElementImageDescriptor) object;
+		return (fBaseImage.equals(other.fBaseImage) && fFlags == other.fFlags);
+	}
+
+	/**
+	 * @see Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		return fBaseImage.hashCode() | fFlags;
+	}
+
+}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIImageDescriptor.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIImageDescriptor.java
index eefa81b..69cb384 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIImageDescriptor.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIImageDescriptor.java
@@ -62,6 +62,8 @@
 	/** Flag to render disabled due to trigger point adornment */
 	public final static int TRIGGER_SUPPRESSED = 0x20000;
 
+	public final static int LOGICAL_STRUCTURE = 0x400000;
+
 	private ImageDescriptor fBaseImage;
 	private int fFlags;
 	private Point fSize;
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java
index b7f7df0..71350ff 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java
@@ -22,6 +22,7 @@
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILogicalStructureType;
 import org.eclipse.debug.core.model.IBreakpoint;
 import org.eclipse.debug.core.model.IDisconnect;
 import org.eclipse.debug.core.model.IExpression;
@@ -29,9 +30,11 @@
 import org.eclipse.debug.core.model.ITerminate;
 import org.eclipse.debug.core.model.IThread;
 import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
 import org.eclipse.debug.core.model.IWatchExpression;
 import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
 import org.eclipse.debug.core.sourcelookup.containers.ZipEntryStorage;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
 import org.eclipse.debug.internal.ui.DefaultLabelProvider;
 import org.eclipse.debug.ui.DebugUITools;
 import org.eclipse.debug.ui.IDebugModelPresentation;
@@ -84,6 +87,7 @@
 import org.eclipse.jdt.ui.JavaElementImageDescriptor;
 import org.eclipse.jdt.ui.JavaElementLabelProvider;
 import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.resource.CompositeImageDescriptor;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.viewers.IColorProvider;
 import org.eclipse.jface.viewers.LabelProvider;
@@ -913,9 +917,12 @@
 	}
 
 	protected Image getVariableImage(IAdaptable element) {
-		JavaElementImageDescriptor descriptor= new JavaElementImageDescriptor(
+		CompositeImageDescriptor descriptor = new JavaElementImageDescriptor(
 			computeBaseImageDescriptor(element), computeAdornmentFlags(element), BIG_SIZE);
-		return JavaPlugin.getImageDescriptorRegistry().get(descriptor);
+		descriptor = new JDIElementImageDescriptor(descriptor, computeLogicalStructureAdornmentFlags(element), BIG_SIZE);
+		Image image = JDIDebugUIPlugin.getImageDescriptorRegistry().get(descriptor);
+
+		return image;
 	}
 
 	/**
@@ -1133,6 +1140,22 @@
 		return flags;
 	}
 
+	private int computeLogicalStructureAdornmentFlags(IAdaptable element) {
+		int flags = 0;
+		 if (element instanceof IVariable) {
+            try {
+                IValue value= ((IVariable) element).getValue();
+                ILogicalStructureType[] types = DebugPlugin.getLogicalStructureTypes(value);
+		        if (types.length > 0) {
+		        	return flags |= JDIImageDescriptor.LOGICAL_STRUCTURE;
+		        }
+            }catch (DebugException e) {
+				DebugUIPlugin.log(e.getStatus());
+            }
+		}
+        return flags;
+	}
+
 	/**
 	 * @see IDebugModelPresentation#getEditorInput(Object)
 	 */
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaLogicalStructuresPreferencePage.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaLogicalStructuresPreferencePage.java
index ef4c59c..07c859d 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaLogicalStructuresPreferencePage.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaLogicalStructuresPreferencePage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2016 IBM Corporation and others.
+ * Copyright (c) 2004, 2017 IBM Corporation 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
@@ -212,6 +212,23 @@
 	}
 
 	@Override
+	public void applyData(Object data) {
+		if (data instanceof String) {
+			Object[] logicalStructures = fLogicalStructuresContentProvider.getElements(null);
+			for (int i = 0, length = logicalStructures.length; i < length; i++) {
+				JavaLogicalStructure javaLogicalStructure = ((JavaLogicalStructure) logicalStructures[i]);
+				if (((String) data).compareToIgnoreCase(javaLogicalStructure.getId() + javaLogicalStructure.getDescription()
+						+ javaLogicalStructure.hashCode()) == 0) {
+					fLogicalStructuresViewer.setSelection(new StructuredSelection(logicalStructures[i]));
+					return;
+				}
+			}
+		} else {
+			super.applyData(data);
+		}
+	}
+
+	@Override
 	public void createControl(Composite parent) {
 		super.createControl(parent);
 		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaDebugHelpContextIds.JAVA_LOGICAL_STRUCTURES_PAGE);
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaVarActionFilter.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaVarActionFilter.java
index 93639d8..af0ec12 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaVarActionFilter.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaVarActionFilter.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2015 IBM Corporation and others.
+ * Copyright (c) 2005, 2017 IBM Corporation 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
@@ -21,11 +21,9 @@
 import org.eclipse.jdt.debug.core.IJavaObject;
 import org.eclipse.jdt.debug.core.IJavaType;
 import org.eclipse.jdt.debug.core.IJavaVariable;
-import org.eclipse.jdt.internal.debug.core.logicalstructures.JavaStructureErrorValue;
 import org.eclipse.jdt.internal.debug.core.model.JDINullValue;
 import org.eclipse.jdt.internal.debug.core.model.JDIPlaceholderValue;
 import org.eclipse.jdt.internal.debug.core.model.JDIReferenceListVariable;
-import org.eclipse.jdt.internal.debug.ui.actions.EditVariableLogicalStructureAction;
 import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression;
 import org.eclipse.ui.IActionFilter;
 
@@ -213,9 +211,6 @@
 						return JavaDetailFormattersManager.getDefault().hasSuperclassDetailFormatter(((IJavaObject)varValue).getJavaType());
 					}
 				}
-				else if (name.equals("JavaLogicalStructureFilter") && value.equals("canEditLogicalStructure")) {  //$NON-NLS-1$ //$NON-NLS-2$
-                    return varValue instanceof JavaStructureErrorValue || EditVariableLogicalStructureAction.getLogicalStructure(varValue) != null;
-                }
 			} catch (DebugException e) {}
 		}
 		else if (target instanceof JavaInspectExpression) {
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/EditVariableLogicalStructureAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/EditVariableLogicalStructureAction.java
deleted file mode 100644
index 5fefc2a..0000000
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/EditVariableLogicalStructureAction.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2015 IBM Corporation 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:
- *     IBM Corporation - initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.debug.ui.actions;
-
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.debug.core.ILogicalStructureType;
-import org.eclipse.debug.core.model.IValue;
-import org.eclipse.jdt.debug.core.IJavaVariable;
-import org.eclipse.jdt.internal.debug.core.logicalstructures.JavaLogicalStructure;
-import org.eclipse.jdt.internal.debug.core.logicalstructures.JavaLogicalStructures;
-import org.eclipse.jdt.internal.debug.core.logicalstructures.JavaStructureErrorValue;
-import org.eclipse.jdt.internal.debug.ui.EditLogicalStructureDialog;
-import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.actions.ActionDelegate;
-
-/**
- * Action which prompts the user to edit the logical structure that
- * is currently active on the given object.
- */
-public class EditVariableLogicalStructureAction extends ActionDelegate implements IObjectActionDelegate {
-
-    /**
-     * The editable structure for the currently selected variable or
-     * <code>null</code> if none.
-     */
-    private JavaLogicalStructure fStructure= null;
-
-    /* (non-Javadoc)
-     * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
-     */
-    @Override
-	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
-    }
-
-    /**
-     * Prompt the user to edit the logical structure associated with the currently
-     * selected variable.
-     */
-    @Override
-	public void run(IAction action) {
-        if (fStructure == null) {
-            return;
-        }
-        Shell shell= JDIDebugUIPlugin.getActiveWorkbenchShell();
-        if (shell != null) {
-            EditLogicalStructureDialog dialog= new EditLogicalStructureDialog(shell, fStructure);
-            if (dialog.open() == Window.OK) {
-                JavaLogicalStructures.saveUserDefinedJavaLogicalStructures();
-            }
-        }
-    }
-
-    /**
-     * @see ActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
-     */
-    @Override
-	public void selectionChanged(IAction action, ISelection selection) {
-        fStructure= null;
-        Object element = ((IStructuredSelection) selection).getFirstElement();
-        if (element instanceof IJavaVariable) {
-            try {
-                IValue value= ((IJavaVariable) element).getValue();
-                if (value instanceof JavaStructureErrorValue) {
-                    value= ((JavaStructureErrorValue) value).getParentValue();
-                }
-                ILogicalStructureType type= getLogicalStructure(value);
-                if (type instanceof JavaLogicalStructure) {
-                    JavaLogicalStructure javaStructure= (JavaLogicalStructure) type;
-                    if (!javaStructure.isContributed()) {
-                        fStructure= javaStructure;
-                    }
-                }
-            } catch (DebugException e) {
-                JDIDebugUIPlugin.log(e.getStatus());
-            }
-        }
-        action.setEnabled(fStructure != null);
-    }
-
-    /**
-     * Returns the logical structure currently associated with the given
-     * value or <code>null</code> if none.
-     * @param value the value
-     * @return the logical structure currently associated with the given
-     *  value or <code>null</code> if none.
-     */
-    public static ILogicalStructureType getLogicalStructure(IValue value) {
-        // This code is based on VariablesViewContentProvider#getLogicalValue(IValue)
-        ILogicalStructureType type = null;
-        ILogicalStructureType[] types = DebugPlugin.getLogicalStructureTypes(value);
-        if (types.length > 0) {
-            type= DebugPlugin.getDefaultStructureType(types);
-        }
-        return type;
-    }
-}