Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/hover/ExpressionInformationControlCreator.java')
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/hover/ExpressionInformationControlCreator.java471
1 files changed, 471 insertions, 0 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/hover/ExpressionInformationControlCreator.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/hover/ExpressionInformationControlCreator.java
new file mode 100644
index 000000000..980925a44
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/hover/ExpressionInformationControlCreator.java
@@ -0,0 +1,471 @@
+package org.eclipse.debug.internal.ui.hover;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.SWTFactory;
+import org.eclipse.debug.internal.ui.model.elements.ElementContentProvider;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
+import org.eclipse.debug.internal.ui.views.variables.details.DefaultDetailPane;
+import org.eclipse.debug.internal.ui.views.variables.details.DetailPaneProxy;
+import org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer;
+import org.eclipse.debug.ui.AbstractDebugView;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.text.AbstractInformationControl;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IInformationControlExtension2;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Creates an information control to display an expression in a hover control.
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ *
+ * @since 3.3
+ */
+public class ExpressionInformationControlCreator implements IInformationControlCreator {
+
+ class ExpressionInformationControl extends AbstractInformationControl implements IInformationControlExtension2 {
+
+ /**
+ * Dialog setting key for height
+ */
+ private static final String HEIGHT = "HEIGHT"; //$NON-NLS-1$
+
+ /**
+ * Dialog setting key for width.
+ */
+ private static final String WIDTH = "WIDTH"; //$NON-NLS-1$
+
+ /**
+ * Dialog setting key for tree sash weight
+ */
+ private static final String SASH_WEIGHT_TREE = "SashWeightTree"; //$NON-NLS-1$
+
+ /**
+ * Dialog setting key for details sash weight
+ */
+ private static final String SASH_WEIGHT_DETAILS = "SashWeightDetails"; //$NON-NLS-1$
+
+ /**
+ * Variable to display.
+ */
+ private IVariable fVariable;
+
+ private IPresentationContext fContext;
+ private TreeModelViewer fViewer;
+ private SashForm fSashForm;
+ private Composite fDetailPaneComposite;
+ private DetailPaneProxy fDetailPane;
+ private Tree fTree;
+
+ /**
+ * Creates the content for the root element of the tree viewer in the hover
+ */
+ private class TreeRoot extends ElementContentProvider {
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext)
+ */
+ @Override
+ protected int getChildCount(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
+ return 1;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext)
+ */
+ @Override
+ protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
+ return new Object[] { fVariable };
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.viewers.model.provisional.elements.ElementContentProvider#supportsContextId(java.lang.String)
+ */
+ @Override
+ protected boolean supportsContextId(String id) {
+ return true;
+ }
+ }
+
+ /**
+ * Inner class implementing IDetailPaneContainer methods. Handles changes to detail
+ * pane and provides limited access to the detail pane proxy.
+ */
+ private class DetailPaneContainer implements IDetailPaneContainer{
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getCurrentPaneID()
+ */
+ @Override
+ public String getCurrentPaneID() {
+ return fDetailPane.getCurrentPaneID();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getCurrentSelection()
+ */
+ @Override
+ public IStructuredSelection getCurrentSelection() {
+ return (IStructuredSelection)fViewer.getSelection();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#refreshDetailPaneContents()
+ */
+ @Override
+ public void refreshDetailPaneContents() {
+ fDetailPane.display(getCurrentSelection());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getParentComposite()
+ */
+ @Override
+ public Composite getParentComposite() {
+ return fDetailPaneComposite;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getWorkbenchPartSite()
+ */
+ @Override
+ public IWorkbenchPartSite getWorkbenchPartSite() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#paneChanged(java.lang.String)
+ */
+ @Override
+ public void paneChanged(String newPaneID) {
+ if (newPaneID.equals(DefaultDetailPane.ID)){
+ fDetailPane.getCurrentControl().setForeground(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+ fDetailPane.getCurrentControl().setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ }
+ }
+
+ }
+
+ /**
+ * Constructs a new control in the given shell.
+ *
+ * @param parentShell shell
+ * @param resize whether resize is supported
+ */
+ ExpressionInformationControl(Shell parentShell, boolean resize) {
+ super(parentShell, resize);
+ create();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.AbstractInformationControl#computeSizeHint()
+ */
+ @Override
+ public Point computeSizeHint() {
+ IDialogSettings settings = getDialogSettings(false);
+ if (settings != null) {
+ int x = getIntSetting(settings, WIDTH);
+ if (x > 0) {
+ int y = getIntSetting(settings, HEIGHT);
+ if (y > 0) {
+ return new Point(x,y);
+ }
+ }
+ }
+ return super.computeSizeHint();
+ }
+
+ /**
+ * Returns the dialog settings for this hover or <code>null</code> if none
+ *
+ * @param create whether to create the settings
+ */
+ private IDialogSettings getDialogSettings(boolean create) {
+ IDialogSettings settings = DebugUIPlugin.getDefault().getDialogSettings();
+ IDialogSettings section = settings.getSection(this.getClass().getName());
+ if (section == null & create) {
+ section = settings.addNewSection(this.getClass().getName());
+ }
+ return section;
+ }
+
+ /**
+ * Returns an integer value in the given dialog settings or -1 if none.
+ *
+ * @param settings dialog settings
+ * @param key key
+ * @return value or -1 if not present
+ */
+ private int getIntSetting(IDialogSettings settings, String key) {
+ try {
+ return settings.getInt(key);
+ } catch (NumberFormatException e) {
+ return -1;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.AbstractInformationControl#dispose()
+ */
+ @Override
+ public void dispose() {
+ persistSettings(getShell());
+ fContext.dispose();
+ super.dispose();
+ }
+
+ /**
+ * Persists dialog settings.
+ *
+ * @param shell
+ */
+ private void persistSettings(Shell shell) {
+ if (shell != null && !shell.isDisposed()) {
+ if (isResizable()) {
+ IDialogSettings settings = getDialogSettings(true);
+ Point size = shell.getSize();
+ settings.put(WIDTH, size.x);
+ settings.put(HEIGHT, size.y);
+ int[] weights = fSashForm.getWeights();
+ settings.put(SASH_WEIGHT_TREE, weights[0]);
+ settings.put(SASH_WEIGHT_DETAILS, weights[1]);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.AbstractInformationControl#setVisible(boolean)
+ */
+ @Override
+ public void setVisible(boolean visible) {
+ if (!visible) {
+ persistSettings(getShell());
+ }
+ super.setVisible(visible);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.AbstractInformationControl#createContent(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected void createContent(Composite parent) {
+
+ fSashForm = new SashForm(parent, parent.getStyle());
+ fSashForm.setOrientation(SWT.VERTICAL);
+
+ // update presentation context
+ AbstractDebugView view = getViewToEmulate();
+ fContext = new PresentationContext(IDebugUIConstants.ID_VARIABLE_VIEW);
+ if (view != null) {
+ // copy over properties
+ IPresentationContext copy = ((TreeModelViewer)view.getViewer()).getPresentationContext();
+ String[] properties = copy.getProperties();
+ for (int i = 0; i < properties.length; i++) {
+ String key = properties[i];
+ fContext.setProperty(key, copy.getProperty(key));
+ }
+ }
+
+ fViewer = new TreeModelViewer(fSashForm, SWT.NO_TRIM | SWT.MULTI | SWT.VIRTUAL, fContext);
+ fViewer.setAutoExpandLevel(1);
+
+ if (view != null) {
+ // copy over filters
+ StructuredViewer structuredViewer = (StructuredViewer) view.getViewer();
+ if (structuredViewer != null) {
+ ViewerFilter[] filters = structuredViewer.getFilters();
+ for (int i = 0; i < filters.length; i++) {
+ fViewer.addFilter(filters[i]);
+ }
+ }
+ }
+
+ fDetailPaneComposite = SWTFactory.createComposite(fSashForm, 1, 1, GridData.FILL_BOTH);
+ Layout layout = fDetailPaneComposite.getLayout();
+ if (layout instanceof GridLayout) {
+ GridLayout gl = (GridLayout) layout;
+ gl.marginHeight = 0;
+ gl.marginWidth = 0;
+ }
+
+ fDetailPane = new DetailPaneProxy(new DetailPaneContainer());
+ fDetailPane.display(null); // Bring up the default pane so the user doesn't see an empty composite
+
+ fTree = fViewer.getTree();
+ fTree.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ fDetailPane.display((IStructuredSelection)fViewer.getSelection());
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {}
+ });
+
+ initSashWeights();
+
+ // add update listener to auto-select and display details of root expression
+ fViewer.addViewerUpdateListener(new IViewerUpdateListener() {
+ @Override
+ public void viewerUpdatesComplete() {
+ }
+ @Override
+ public void viewerUpdatesBegin() {
+ }
+ @Override
+ public void updateStarted(IViewerUpdate update) {
+ }
+ @Override
+ public void updateComplete(IViewerUpdate update) {
+ if (update instanceof IChildrenUpdate) {
+ TreeSelection selection = new TreeSelection(new TreePath(new Object[]{fVariable}));
+ fViewer.setSelection(selection);
+ fDetailPane.display(selection);
+ fViewer.removeViewerUpdateListener(this);
+ }
+ }
+ });
+
+ setForegroundColor(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+ setBackgroundColor(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ }
+
+
+ /**
+ * Attempts to find an appropriate view to emulate, this will either be the
+ * variables view or the expressions view.
+ * @return a view to emulate or <code>null</code>
+ */
+ private AbstractDebugView getViewToEmulate() {
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ AbstractDebugView expressionsView = (AbstractDebugView) page.findView(IDebugUIConstants.ID_EXPRESSION_VIEW);
+ if (expressionsView != null && expressionsView.isVisible()) {
+ return expressionsView;
+ }
+ AbstractDebugView variablesView = (AbstractDebugView) page.findView(IDebugUIConstants.ID_VARIABLE_VIEW);
+ if (variablesView != null && variablesView.isVisible()) {
+ return variablesView;
+ }
+ if (expressionsView != null) {
+ return expressionsView;
+ }
+ return variablesView;
+ }
+
+ /**
+ * Initializes the sash form weights from the preference store (using default values if
+ * no sash weights were stored previously).
+ */
+ protected void initSashWeights(){
+ IDialogSettings settings = getDialogSettings(false);
+ if (settings != null) {
+ int tree = getIntSetting(settings, SASH_WEIGHT_TREE);
+ if (tree > 0) {
+ int details = getIntSetting(settings, SASH_WEIGHT_DETAILS);
+ if (details > 0) {
+ fSashForm.setWeights(new int[]{tree, details});
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.AbstractInformationControl#setForegroundColor(org.eclipse.swt.graphics.Color)
+ */
+ @Override
+ public void setForegroundColor(Color foreground) {
+ super.setForegroundColor(foreground);
+ fDetailPaneComposite.setForeground(foreground);
+ fTree.setForeground(foreground);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.AbstractInformationControl#setBackgroundColor(org.eclipse.swt.graphics.Color)
+ */
+ @Override
+ public void setBackgroundColor(Color background) {
+ super.setBackgroundColor(background);
+ fDetailPaneComposite.setBackground(background);
+ fTree.setBackground(background);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.AbstractInformationControl#setFocus()
+ */
+ @Override
+ public void setFocus() {
+ super.setFocus();
+ fTree.setFocus();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IInformationControlExtension#hasContents()
+ */
+ @Override
+ public boolean hasContents() {
+ return fVariable != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
+ */
+ @Override
+ public void setInput(Object input) {
+ if (input instanceof IVariable) {
+ fVariable = (IVariable) input;
+ fViewer.setInput(new TreeRoot());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.AbstractInformationControl#getInformationPresenterControlCreator()
+ */
+ @Override
+ public IInformationControlCreator getInformationPresenterControlCreator() {
+ return new ExpressionInformationControlCreator() {
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.debug.ui.ExpressionInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell)
+ */
+ @Override
+ public IInformationControl createInformationControl(Shell shell) {
+ return new ExpressionInformationControl(shell, true);
+ }
+ };
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell)
+ */
+ @Override
+ public IInformationControl createInformationControl(Shell parent) {
+ return new ExpressionInformationControl(parent, false);
+ }
+
+
+}

Back to the top