Package org.eclipse.php.internal.debug.ui.actions

Source Code of org.eclipse.php.internal.debug.ui.actions.PopupInspectAction

/*******************************************************************************
* Copyright (c) 2000, 2007 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.php.internal.debug.ui.actions;

import org.eclipse.core.internal.runtime.AdapterManager;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.*;
import org.eclipse.debug.ui.DebugPopup;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.InspectPopupDialog;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.php.internal.debug.core.IPHPDebugConstants;
import org.eclipse.php.internal.debug.core.xdebug.dbgp.model.DBGpStackFrame;
import org.eclipse.php.internal.debug.core.zend.model.PHPStackFrame;
import org.eclipse.php.internal.debug.ui.PHPDebugUIPlugin;
import org.eclipse.php.internal.debug.ui.watch.IWatchExpressionResultExtension;
import org.eclipse.php.internal.debug.ui.watch.PHPWatchExpressionDelegate;
import org.eclipse.php.internal.debug.ui.watch.XDebugWatchExpressionDelegate;
import org.eclipse.php.internal.ui.PHPUiPlugin;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.*;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.texteditor.ITextEditor;

/**
* Action to do simple code evaluation. The evaluation is done in the UI thread
* and the expression and result are displayed using the IDataDisplay.
*/
public class PopupInspectAction implements IWorkbenchWindowActionDelegate,
    IObjectActionDelegate, IEditorActionDelegate, IPartListener,
    IViewActionDelegate {

  public static final String ACTION_DEFININITION_ID = "org.eclipse.php.debug.ui.commands.Inspect"; //$NON-NLS-1$

  private IAction fAction;
  private IWorkbenchPart fTargetPart;
  private IWorkbenchWindow fWindow;
  private IRegion fRegion;

  /**
   * Is the action waiting for an evaluation.
   */
  private boolean fEvaluating;

  /**
   * The new target part to use with the evaluation completes.
   */
  private IWorkbenchPart fNewTargetPart = null;

  /**
   * Used to resolve editor input for selected stack frame
   */
  private IDebugModelPresentation fPresentation;

  private IExpression expression;

  private ITextEditor fTextEditor;
  private ISelection fSelectionBeforeEvaluation;

  private IWatchExpressionListener watchExpressionListener;

  public PopupInspectAction() {
    super();
  }

  /**
   * Returns the 'object' context for this evaluation, or <code>null</code> if
   * none. If the evaluation is being performed in the context of the
   * variables view/inspector. Then perform the evaluation in the context of
   * the selected value.
   *
   * @return Java object or <code>null</code>
   */
  protected String getObjectContext() {
    IWorkbenchPage page = PHPUiPlugin.getActivePage();
    IStructuredSelection selection = null;
    if (page != null) {
      ISelection sec = page.getSelection();
      if (sec instanceof IStructuredSelection) {
        selection = (IStructuredSelection) sec;
      }
    }
    if (selection instanceof TextSelection) {
      TextSelection textSelection = (TextSelection) selection;
      return textSelection.getText();
    }
    return null;
  }

  /**
   * Finds the currently selected stack frame in the UI. Stack frames from a
   * scrapbook launch are ignored.
   */
  protected IStackFrame getStackFrameContext() {
    IWorkbenchPart part = getTargetPart();
    IStackFrame frame = null;
    if (part == null) {
      frame = EvaluationContextManager.getEvaluationContext(getWindow());
    } else {
      frame = EvaluationContextManager.getEvaluationContext(part);
    }
    return frame;
  }

  /**
   * @see IEvaluationListener#evaluationComplete(IEvaluationResult)
   */
  public void evaluationComplete(final IWatchExpressionResult result) {
    // if plug-in has shutdown, ignore - see bug# 8693
    if (PHPDebugUIPlugin.getDefault() == null) {
      return;
    }

    final IValue value = result.getValue();
    if (result.hasErrors() || value != null) {
      final Display display = PHPDebugUIPlugin.getStandardDisplay();
      if (display.isDisposed()) {
        return;
      }
      displayResult(result);
    }
  }

  protected void evaluationCleanup() {
    setEvaluating(false);
    setTargetPart(fNewTargetPart);
  }

  /**
   * Display the given evaluation result.
   */
  protected void displayResult(final IWatchExpressionResult result) {
    IWorkbenchPart part = getTargetPart();
    final StyledText styledText = getStyledText(part);
    if (styledText != null) {
      expression = new IExpression() {

        public String getModelIdentifier() {
          return getDebugTarget().getModelIdentifier();
        }

        public ILaunch getLaunch() {
          return getDebugTarget().getLaunch();
        }

        public Object getAdapter(Class adapter) {
          return AdapterManager.getDefault()
              .getAdapter(this, adapter);
        }

        public String getExpressionText() {
          return result.getExpressionText();
        }

        public IValue getValue() {
          return result.getValue();
        }

        public IDebugTarget getDebugTarget() {
          IValue value = getValue();
          if (value != null) {
            return getValue().getDebugTarget();
          } else if (result instanceof IWatchExpressionResultExtension) {
            return ((IWatchExpressionResultExtension) result)
                .getDebugTarget();
          }
          // An expression should never be created with a null value
          // *and*
          // a null result.
          return null;
        }

        public void dispose() {

        }
      };
      PHPDebugUIPlugin.getStandardDisplay().asyncExec(new Runnable() {
        public void run() {
          showPopup(styledText);
        }
      });
    }
    evaluationCleanup();
  }

  protected void showPopup(StyledText textWidget) {
    IWorkbenchPart part = getTargetPart();
    if (part instanceof ITextEditor) {
      fTextEditor = (ITextEditor) part;
      fSelectionBeforeEvaluation = getTargetSelection();
    }
    DebugPopup displayPopup = new InspectPopupDialog(getShell(),
        getPopupAnchor(textWidget), ACTION_DEFININITION_ID, expression) {
      IContextActivation contextActivation;

      @Override
      protected Control createDialogArea(Composite parent) {
        Control result = super.createDialogArea(parent);
        if (fTextEditor != null) {
          IContextService contextService = (IContextService) fTextEditor
              .getSite().getService(IContextService.class);
          contextActivation = contextService
              .activateContext("org.eclipse.php.debug.ui.xdebug"); //$NON-NLS-1$
        }
        return result;
      }

      public boolean close() {
        boolean returnValue = super.close();
        if (fTextEditor != null && fSelectionBeforeEvaluation != null) {
          fTextEditor.getSelectionProvider().setSelection(
              fSelectionBeforeEvaluation);
          fTextEditor = null;
          fSelectionBeforeEvaluation = null;
        }
        // if (fTextEditor != null) {
        // IContextService contextService = (IContextService)
        // fTextEditor
        // .getSite().getService(IContextService.class);
        // contextService.deactivateContext(contextActivation);
        // }
        return returnValue;
      }
    };
    displayPopup.open();
  }

  protected void run() {
    // eval in context of object or stack frame
    final String expression = getObjectContext();
    final IStackFrame stackFrame = getStackFrameContext();
    if (stackFrame == null) {
      return;
    }

    setNewTargetPart(getTargetPart());
    if (watchExpressionListener == null) {
      watchExpressionListener = new IWatchExpressionListener() {
        public void watchEvaluationFinished(
            IWatchExpressionResult result) {
          evaluationComplete(result);
        }
      };
    }
    if (stackFrame instanceof DBGpStackFrame) {

      new XDebugWatchExpressionDelegate().evaluateExpression(expression,
          stackFrame, watchExpressionListener);

    } else if (stackFrame instanceof PHPStackFrame) {

      new PHPWatchExpressionDelegate().evaluateExpression(expression,
          stackFrame, watchExpressionListener);
    }

  }

  protected ISelection getTargetSelection() {
    IWorkbenchPart part = getTargetPart();
    if (part != null) {
      ISelectionProvider provider = part.getSite().getSelectionProvider();
      if (provider != null) {
        return provider.getSelection();
      }
    }
    return null;
  }

  /**
   * Resolve an editor input from the source element of the stack frame
   * argument, and return whether it's equal to the editor input for the
   * editor that owns this action.
   */
  protected boolean compareToEditorInput(IStackFrame stackFrame) {
    ILaunch launch = stackFrame.getLaunch();
    if (launch == null) {
      return false;
    }
    ISourceLocator locator = launch.getSourceLocator();
    if (locator == null) {
      return false;
    }
    Object sourceElement = locator.getSourceElement(stackFrame);
    if (sourceElement == null) {
      return false;
    }
    IEditorInput sfEditorInput = getDebugModelPresentation()
        .getEditorInput(sourceElement);
    if (getTargetPart() instanceof IEditorPart) {
      return ((IEditorPart) getTargetPart()).getEditorInput().equals(
          sfEditorInput);
    }
    return false;
  }

  protected Shell getShell() {
    if (getTargetPart() != null) {
      return getTargetPart().getSite().getShell();
    }
    return PHPDebugUIPlugin.getActiveWorkbenchShell();
  }

  protected boolean textHasContent(String text) {
    if (text != null) {
      int length = text.length();
      if (length > 0) {
        for (int i = 0; i < length; i++) {
          if (Character.isLetterOrDigit(text.charAt(i))) {
            return true;
          }
        }
      }
    }
    return false;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ui.IActionDelegate#run(IAction)
   */
  public void run(IAction action) {
    if (PHPUiPlugin.getActivePage() != null) {
      setTargetPart(PHPUiPlugin.getActivePage().getActivePart());
    }
    run();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ui.IActionDelegate#selectionChanged(IAction, ISelection)
   */
  public void selectionChanged(IAction action, ISelection selection) {
    setAction(action);
    if (selection instanceof ITextSelection) {
      ITextSelection textSelection = (ITextSelection) selection;
      action.setEnabled(textSelection.getLength() != 0);
    }
  }

  /**
   * @see IWorkbenchWindowActionDelegate#dispose()
   */
  public void dispose() {
    disposeDebugModelPresentation();
    IWorkbenchWindow win = getWindow();
    if (win != null) {
      win.getPartService().removePartListener(this);
    }
  }

  /**
   * @see IWorkbenchWindowActionDelegate#init(IWorkbenchWindow)
   */
  public void init(IWorkbenchWindow window) {
    setWindow(window);
    IWorkbenchPage page = window.getActivePage();
    if (page != null) {
      setTargetPart(page.getActivePart());
    }
    window.getPartService().addPartListener(this);
  }

  protected IAction getAction() {
    return fAction;
  }

  protected void setAction(IAction action) {
    fAction = action;
  }

  /**
   * Returns a debug model presentation (creating one if necessary).
   *
   * @return debug model presentation
   */
  protected IDebugModelPresentation getDebugModelPresentation() {
    if (fPresentation == null) {
      fPresentation = DebugUITools
          .newDebugModelPresentation(IPHPDebugConstants.ID_PHP_DEBUG_CORE);
    }
    return fPresentation;
  }

  /**
   * Disposes this action's debug model presentation, if one was created.
   */
  protected void disposeDebugModelPresentation() {
    if (fPresentation != null) {
      fPresentation.dispose();
    }
  }

  /**
   * @see IEditorActionDelegate#setActiveEditor(IAction, IEditorPart)
   */
  public void setActiveEditor(IAction action, IEditorPart targetEditor) {
    setAction(action);
    setTargetPart(targetEditor);
  }

  /**
   * @see IPartListener#partActivated(IWorkbenchPart)
   */
  public void partActivated(IWorkbenchPart part) {
    setTargetPart(part);
  }

  /**
   * @see IPartListener#partBroughtToTop(IWorkbenchPart)
   */
  public void partBroughtToTop(IWorkbenchPart part) {
  }

  /**
   * @see IPartListener#partClosed(IWorkbenchPart)
   */
  public void partClosed(IWorkbenchPart part) {
    if (part == getTargetPart()) {
      setTargetPart(null);
    }
    if (part == getNewTargetPart()) {
      setNewTargetPart(null);
    }
  }

  /**
   * @see IPartListener#partDeactivated(IWorkbenchPart)
   */
  public void partDeactivated(IWorkbenchPart part) {
  }

  /**
   * @see IPartListener#partOpened(IWorkbenchPart)
   */
  public void partOpened(IWorkbenchPart part) {
  }

  /**
   * @see IViewActionDelegate#init(IViewPart)
   */
  public void init(IViewPart view) {
    setTargetPart(view);
  }

  protected IWorkbenchPart getTargetPart() {
    return fTargetPart;
  }

  protected void setTargetPart(IWorkbenchPart part) {
    if (isEvaluating()) {
      // do not want to change the target part while evaluating
      // see bug 8334
      setNewTargetPart(part);
    } else {
      fTargetPart = part;
    }
  }

  protected IWorkbenchWindow getWindow() {
    return fWindow;
  }

  protected void setWindow(IWorkbenchWindow window) {
    fWindow = window;
  }

  /**
   * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
   */
  public void setActivePart(IAction action, IWorkbenchPart targetPart) {
    setAction(action);
    setTargetPart(targetPart);
  }

  protected IWorkbenchPart getNewTargetPart() {
    return fNewTargetPart;
  }

  protected void setNewTargetPart(IWorkbenchPart newTargetPart) {
    fNewTargetPart = newTargetPart;
  }

  protected boolean isEvaluating() {
    return fEvaluating;
  }

  protected void setEvaluating(boolean evaluating) {
    fEvaluating = evaluating;
  }

  /**
   * Returns the selected text region, or <code>null</code> if none.
   *
   * @return
   */
  protected IRegion getRegion() {
    return fRegion;
  }

  /**
   * Returns the styled text widget associated with the given part or
   * <code>null</code> if none.
   *
   * @param part
   *            workbench part
   * @return associated style text widget or <code>null</code>
   */
  public static StyledText getStyledText(IWorkbenchPart part) {
    ITextViewer viewer = (ITextViewer) part.getAdapter(ITextViewer.class);
    StyledText textWidget = null;
    if (viewer == null) {
      Control control = (Control) part.getAdapter(Control.class);
      if (control instanceof StyledText) {
        textWidget = (StyledText) control;
      }
    } else {
      textWidget = viewer.getTextWidget();
    }
    return textWidget;
  }

  /**
   * Returns an anchor point for a popup dialog on top of a styled text or
   * <code>null</code> if none.
   *
   * @param part
   *            or <code>null</code>
   * @return anchor point or <code>null</code>
   */
  public static Point getPopupAnchor(StyledText textWidget) {
    if (textWidget != null) {
      Point docRange = textWidget.getSelectionRange();
      int midOffset = docRange.x + (docRange.y / 2);
      Point point = textWidget.getLocationAtOffset(midOffset);
      point = textWidget.toDisplay(point);

      GC gc = new GC(textWidget);
      gc.setFont(textWidget.getFont());
      int height = gc.getFontMetrics().getHeight();
      gc.dispose();
      point.y += height;
      return point;
    }
    return null;
  }
}
TOP

Related Classes of org.eclipse.php.internal.debug.ui.actions.PopupInspectAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.