Package org.eclipse.wst.sse.ui.internal

Source Code of org.eclipse.wst.sse.ui.internal.GotoAnnotationAction$StatusLineClearer

/*******************************************************************************
* Copyright (c) 2001, 2010 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
*     Jens Lukowski/Innoopract - initial renaming/restructuring
*    
*******************************************************************************/
package org.eclipse.wst.sse.ui.internal;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.part.EditorActionBarContributor;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.IEditorStatusLine;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;
import org.eclipse.ui.texteditor.TextEditorAction;

/**
* Based on org.eclipse.jdt.internal.ui.javaeditor.GotoAnnotationAction and
* the org.eclipse.jdt.internal.ui.JavaEditor's gotoError() method. Rewritten
* based on 3.0M7 version to operate generically.
*
* @deprecated - use org.eclipse.ui.texteditor.GotoAnnotationAction
*
*/
public class GotoAnnotationAction extends TextEditorAction {

  private static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/gotoNextAnnotation")); //$NON-NLS-1$  //$NON-NLS-2$

  /**
   * Clears the status line on selection changed.
   */
  protected class StatusLineClearer implements ISelectionChangedListener {
    IStatusLineManager fStatusLineManager = null;

    protected StatusLineClearer(IStatusLineManager mgr) {
      super();
      fStatusLineManager = mgr;
    }

    /*
     * @see ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
     */
    public void selectionChanged(SelectionChangedEvent event) {
      getTextEditor().getSelectionProvider().removeSelectionChangedListener(StatusLineClearer.this);

      fStatusLineManager.setErrorMessage(null, null);
      fStatusLineManager.setMessage(null, null);
    }
  }

  private boolean fForward;
  private String fLabel;

  private String fPrefix;

  /**
   * @param prefix
   * @param editor
   */
  public GotoAnnotationAction(String prefix, boolean forward) {
    super(SSEUIMessages.getResourceBundle(), prefix, null);
    fForward = forward;
    fPrefix = prefix;
    fLabel = SSEUIMessages.getResourceBundle().getString(fPrefix);
  }

  /*
   * This is the default label used for description
   */
  public String getDefaultLabel() {
    return fLabel;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jface.action.Action#getDescription()
   */
  public String getDescription() {
    return getDefaultLabel();
  }

  /**
   * Returns the annotation closest to the given range respecting the given
   * direction. If an annotation is found, the annotations current position
   * is copied into the provided annotation position.
   *
   * @param offset
   *            the region offset
   * @param length
   *            the region length
   * @param forward
   *            <code>true</code> for forwards, <code>false</code> for
   *            backward
   * @param annotationPosition
   *            the position of the found annotation
   * @return the found annotation
   */
  protected Annotation getNextAnnotation(final int offset, final int length, boolean forward, Position annotationPosition) {
    Annotation nextAnnotation = null;
    Position nextAnnotationPosition = null;
    Annotation containingAnnotation = null;
    Position containingAnnotationPosition = null;
    boolean currentAnnotation = false;

    IDocument document = getTextEditor().getDocumentProvider().getDocument(getTextEditor().getEditorInput());
    int endOfDocument = document.getLength();
    int distance = Integer.MAX_VALUE;

    IAnnotationModel model = getTextEditor().getDocumentProvider().getAnnotationModel(getTextEditor().getEditorInput());
    // external files may not have an annotation model
    if (model != null) {
      Iterator e = model.getAnnotationIterator();
      while (e.hasNext()) {
        Annotation a = (Annotation) e.next();
        if (!isNavigationTarget(a))
          continue;

        Position p = model.getPosition(a);
        if (p == null)
          continue;

        if (forward && p.offset == offset || !forward && p.offset + p.getLength() == offset + length) {
          if (containingAnnotation == null || (forward && p.length >= containingAnnotationPosition.length || !forward && p.length >= containingAnnotationPosition.length)) {
            containingAnnotation = a;
            containingAnnotationPosition = p;
            currentAnnotation = p.length == length;
          }
        }
        else {
          int currentDistance = 0;

          if (forward) {
            currentDistance = p.getOffset() - offset;
            if (currentDistance < 0) {
              currentDistance = endOfDocument + currentDistance;
            }

            if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
              distance = currentDistance;
              nextAnnotation = a;
              nextAnnotationPosition = p;
            }
          }
          else {
            currentDistance = offset + length - (p.getOffset() + p.length);
            if (currentDistance < 0)
              currentDistance = endOfDocument + currentDistance;

            if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
              distance = currentDistance;
              nextAnnotation = a;
              nextAnnotationPosition = p;
            }
          }
        }
      }
    }
    if (containingAnnotationPosition != null && (!currentAnnotation || nextAnnotation == null)) {
      annotationPosition.setOffset(containingAnnotationPosition.getOffset());
      annotationPosition.setLength(containingAnnotationPosition.getLength());
      return containingAnnotation;
    }
    if (nextAnnotationPosition != null) {
      annotationPosition.setOffset(nextAnnotationPosition.getOffset());
      annotationPosition.setLength(nextAnnotationPosition.getLength());
    }

    return nextAnnotation;
  }

  private IStatusLineManager getStatusLineManager() {
    // The original JavaEditor M7 implementation made use of an adapter,
    // but that approach
    // fails with a MultiPageEditorSite
   
    IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
    if (window == null)
      return null;
    IWorkbenchPage page = window.getActivePage();
    if (page == null)
      return null;
    IEditorPart editor = page.getActiveEditor();
    if (editor == null)
      return null;
    IEditorActionBarContributor contributor = editor.getEditorSite().getActionBarContributor();
    if (contributor instanceof EditorActionBarContributor) {
      return ((EditorActionBarContributor) contributor).getActionBars().getStatusLineManager();
    }
    return null;
  }

  public String getText() {
    return getDefaultLabel();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jface.action.Action#getToolTipText()
   */
  public String getToolTipText() {
    return getDefaultLabel();
  }

  /**
   * Jumps to the error next according to the given direction based off
   * JavaEditor#gotoAnnotation()
   *
   * @param forward
   *            is the direction
   */
  public void gotoAnnotation(boolean forward) {
    ITextSelection selection = (ITextSelection) getTextEditor().getSelectionProvider().getSelection();
    Position position = new Position(0, 0);
    if (false /* delayed - see bug 18316 */) {
      getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
      getTextEditor().selectAndReveal(position.getOffset(), position.getLength());
    }
    else /* no delay - see bug 18316 */{
      Annotation annotation = getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
      IEditorStatusLine editorStatusLine = (IEditorStatusLine) getTextEditor().getAdapter(IEditorStatusLine.class);
      if (editorStatusLine != null) {
        editorStatusLine.setMessage(true, null, null);
        editorStatusLine.setMessage(false, null, null);
      }
      else {
        IStatusLineManager mgr = getStatusLineManager();
        if (mgr != null) {
          mgr.setErrorMessage(null);
          mgr.setMessage(null, null);
        }
      }
      if (annotation != null) {
        updateAnnotationViews(annotation);
        if (_debug) {
          System.out.println("select and reveal " + annotation.getType() + "@" + position.getOffset() + ":" + position.getLength()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }
        getTextEditor().selectAndReveal(position.getOffset(), position.getLength());
        if (editorStatusLine != null) {
          editorStatusLine.setMessage(true, null, null);
          editorStatusLine.setMessage(false, annotation.getText(), null);
        }
        else {
          IStatusLineManager mgr = getStatusLineManager();
          if (mgr != null) {
            mgr.setErrorMessage(null);
            mgr.setMessage(null, annotation.getText());
          }
          getTextEditor().getSelectionProvider().addSelectionChangedListener(new StatusLineClearer(mgr));
        }
      }
    }
  }

  /**
   * Returns whether the given annotation is configured as a target for the
   * "Go to Next/Previous Annotation" actions
   *
   * @param annotation
   *            the annotation
   * @return <code>true</code> if this is a target, <code>false</code>
   *         otherwise
   * @see Eclipse 3.0
   */
  protected boolean isNavigationTarget(Annotation annotation) {
    Preferences preferences = EditorsUI.getPluginPreferences();
    AnnotationPreference preference = EditorsUI.getAnnotationPreferenceLookup().getAnnotationPreference(annotation);
    // See bug 41689
    // String key= forward ? preference.getIsGoToNextNavigationTargetKey()
    // : preference.getIsGoToPreviousNavigationTargetKey();
    String key = preference == null ? null : preference.getIsGoToNextNavigationTargetKey();
    return (key != null && preferences.getBoolean(key));
  }

  public void run() {
    gotoAnnotation(fForward);
  }

  public void setEditor(ITextEditor editor) {
    super.setEditor(editor);
    update();
  }

  /**
   * Updates the annotation views that show the given annotation.
   *
   * @param annotation
   *            the annotation
   */
  protected void updateAnnotationViews(Annotation annotation) {
    IMarker marker = null;
    if (annotation instanceof SimpleMarkerAnnotation)
      marker = ((SimpleMarkerAnnotation) annotation).getMarker();

    if (marker != null) {
      try {
        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (window != null) {
          IWorkbenchPage page = window.getActivePage();
          if (page != null) {
            IViewPart view = null;
            if (marker.isSubtypeOf(IMarker.PROBLEM)) {
              view = page.findView(IPageLayout.ID_PROBLEM_VIEW);
            }
            else if (marker.isSubtypeOf(IMarker.TASK)) {
              view = page.findView(IPageLayout.ID_TASK_LIST);
            }
            else if (marker.isSubtypeOf(IMarker.BOOKMARK)) {
              view = page.findView(IPageLayout.ID_BOOKMARKS);
            }
//            else if (marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
//              view = page.findView(IDebugUIConstants.ID_BREAKPOINT_VIEW);
//            }
           
            if (view == null) {
              view = page.findView("org.eclipse.ui.views.AllMarkersView");
            }
            // If the view isn't open on this perspective, don't
            // interact with it
            if (view != null) {
              Method method = view.getClass().getMethod("setSelection", new Class[]{IStructuredSelection.class, boolean.class}); //$NON-NLS-1$
              if (method != null) {
                method.invoke(view, new Object[]{new StructuredSelection(marker), Boolean.TRUE});
                page.bringToTop(view);
              }
            }
          }
        }
      }
      // ignore exceptions, don't update any of the lists, just set
      // statusline
      catch (CoreException x) {
        //
      }
      catch (NoSuchMethodException x) {
        //
      }
      catch (IllegalAccessException x) {
        //
      }
      catch (InvocationTargetException x) {
        //
      }
    }
  }
}
TOP

Related Classes of org.eclipse.wst.sse.ui.internal.GotoAnnotationAction$StatusLineClearer

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.