TextSourceViewerConfiguration.java :  » IDE-Eclipse » ui » org » eclipse » ui » editors » text » Java Open Source

Java Open Source » IDE Eclipse » ui 
ui » org » eclipse » ui » editors » text » TextSourceViewerConfiguration.java
/*******************************************************************************
 * 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.ui.editors.text;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Map.Entry;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.NullProgressMonitor;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
import org.eclipse.jface.preference.IPreferenceStore;

import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.DefaultTextHover;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextHoverExtension;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.IUndoManager;
import org.eclipse.jface.text.TextViewerUndoManager;
import org.eclipse.jface.text.hyperlink.DefaultHyperlinkPresenter;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter;
import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
import org.eclipse.jface.text.quickassist.QuickAssistAssistant;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.MonoReconciler;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.DefaultAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;

import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.HyperlinkDetectorRegistry;
import org.eclipse.ui.texteditor.spelling.SpellingCorrectionProcessor;
import org.eclipse.ui.texteditor.spelling.SpellingReconcileStrategy;
import org.eclipse.ui.texteditor.spelling.SpellingService;


/**
 * Source viewer configuration for the text editor.
 *
 * @since 3.0
 */
public class TextSourceViewerConfiguration extends SourceViewerConfiguration {

  /**
   * The preference store used to initialize this configuration.
   * <p>
   * Note: protected since 3.1
   * </p>
   */
  protected IPreferenceStore fPreferenceStore;

  /**
   * Creates a text source viewer configuration.
   */
  public TextSourceViewerConfiguration() {
  }

  /**
   * Creates a text source viewer configuration and
   * initializes it with the given preference store.
   *
   * @param preferenceStore  the preference store used to initialize this configuration
   */
  public TextSourceViewerConfiguration(IPreferenceStore preferenceStore) {
    fPreferenceStore= preferenceStore;
  }

  /*
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAnnotationHover(org.eclipse.jface.text.source.ISourceViewer)
   */
  public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
    return new DefaultAnnotationHover() {
      protected boolean isIncluded(Annotation annotation) {
        return isShowInVerticalRuler(annotation);
      }
    };
  }

  /*
   * @see DefaultAnnotationHover#isIncluded(Annotation)
   * @since 3.2
   */
  protected boolean isShowInVerticalRuler(Annotation annotation) {
    AnnotationPreference preference= getAnnotationPreference(annotation);
    if (preference == null)
      return true;
    String key= preference.getVerticalRulerPreferenceKey();
    // backward compatibility
    if (key != null && !fPreferenceStore.getBoolean(key))
      return false;
    
    return true;
  }

  /*
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getOverviewRulerAnnotationHover(org.eclipse.jface.text.source.ISourceViewer)
   * @since 3.2
   */
  public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) {
    return new DefaultAnnotationHover() {
      protected boolean isIncluded(Annotation annotation) {
        return isShowInOverviewRuler(annotation);
      }
    };
  }

  /*
   * @see DefaultAnnotationHover#isIncluded(Annotation)
   * @since 3.2
   */
  protected boolean isShowInOverviewRuler(Annotation annotation) {
    AnnotationPreference preference= getAnnotationPreference(annotation);
    if (preference == null)
      return true;
    String key= preference.getOverviewRulerPreferenceKey();
    if (key == null || !fPreferenceStore.getBoolean(key))
      return false;
    
    return true;
  }

  /*
   * @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer, String)
   * @since 3.2
   */
  public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String contentType) {
    return new int[] { ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK };
  }

  /*
   * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String)
   * @since 3.2
   */
  public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
    return new TextHover(sourceViewer);
  }

  /*
   * @see DefaultTextHover#isIncluded(Annotation)
   * @since 3.2
   */
  protected boolean isShownInText(Annotation annotation) {
    AnnotationPreference preference= getAnnotationPreference(annotation);
    if (preference == null)
      return false;
    String key= preference.getTextPreferenceKey();
    if (key != null) {
      if (!fPreferenceStore.getBoolean(key))
        return false;
    } else {
      key= preference.getHighlightPreferenceKey();
      if (key == null || !fPreferenceStore.getBoolean(key))
        return false;
    }
    return true;
  }
  
  /**
   * Returns the annotation preference for the given annotation.
   *
   * @param annotation the annotation
   * @return the annotation preference or <code>null</code> if none
   * @since 3.2
   */
  private AnnotationPreference getAnnotationPreference(Annotation annotation) {
    if (annotation == null || fPreferenceStore == null)
      return null;
    return EditorsUI.getAnnotationPreferenceLookup().getAnnotationPreference(annotation);
  }

  /*
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTabWidth(org.eclipse.jface.text.source.ISourceViewer)
   */
  public int getTabWidth(ISourceViewer sourceViewer) {
    if (fPreferenceStore == null)
      return super.getTabWidth(sourceViewer);
    return fPreferenceStore.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
  }

  /*
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getIndentPrefixes(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
   * @since 3.3
   */
  public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
    String[] indentPrefixes= getIndentPrefixesForTab(getTabWidth(sourceViewer));
    if (indentPrefixes == null)
      return null;

    int length= indentPrefixes.length;
    if (length > 2 && fPreferenceStore != null && fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SPACES_FOR_TABS))  {
      // Swap first with second last
      String first= indentPrefixes[0];
      indentPrefixes[0]= indentPrefixes[length - 2];
      indentPrefixes[length - 2]= first;
    }

    return indentPrefixes;
  }

  /*
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getHyperlinkDetectors(org.eclipse.jface.text.source.ISourceViewer)
   * @since 3.1
   */
  public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
    if (sourceViewer == null || fPreferenceStore == null)
      return super.getHyperlinkDetectors(sourceViewer);

    if (!fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINKS_ENABLED))
      return null;
    
    return getRegisteredHyperlinkDetectors(sourceViewer);
  }

  /**
   * Returns the registered hyperlink detectors which are used to detect
   * hyperlinks in the given source viewer.
   *
   * @param sourceViewer the source viewer to be configured by this configuration
   * @return an array with hyperlink detectors or <code>null</code> if no hyperlink detectors are registered
   * @since 3.3
   */
  protected final IHyperlinkDetector[] getRegisteredHyperlinkDetectors(ISourceViewer sourceViewer) {
    HyperlinkDetectorRegistry registry= EditorsUI.getHyperlinkDetectorRegistry();

    Map targets= getHyperlinkDetectorTargets(sourceViewer);
    Assert.isNotNull(targets);
    
    IHyperlinkDetector[] result= null;
    Iterator iter= targets.entrySet().iterator();
    while (iter.hasNext()) {
      Entry target= (Entry)iter.next();
      String targetId= (String)target.getKey();
      IAdaptable context= (IAdaptable)target.getValue(); 
      result= merge(result, registry.createHyperlinkDetectors(targetId, context));
    }
    return result;
  }

  /**
   * Returns the hyperlink detector targets supported by the
   * given source viewer.
   * <p>
   * Subclasses are allowed to modify the returned map. 
   * </p>
   * 
   * @param sourceViewer the source viewer to be configured by this configuration
   * @return the hyperlink detector targets with target id (<code>String</code>) as key
   *       and the target context (<code>IAdaptable</code>) as value 
   * @since 3.3
   */
  protected Map getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
    Map targets= new HashMap();
    targets.put("org.eclipse.ui.DefaultTextEditor", null); //$NON-NLS-1$
    return targets;
  }

  /*
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getHyperlinkStateMask(org.eclipse.jface.text.source.ISourceViewer)
   * @since 3.1
   */
  public int getHyperlinkStateMask(ISourceViewer sourceViewer) {
    if (fPreferenceStore == null)
      return super.getHyperlinkStateMask(sourceViewer);

    String modifiers= fPreferenceStore.getString(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINK_KEY_MODIFIER);
    int modifierMask= computeStateMask(modifiers);
    if (modifierMask == -1) {
      // Fall back to stored state mask
      modifierMask= fPreferenceStore.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINK_KEY_MODIFIER_MASK);
    }
    return modifierMask;
  }

  /*
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getHyperlinkPresenter(org.eclipse.jface.text.source.ISourceViewer)
   * @since 3.1
   */
  public IHyperlinkPresenter getHyperlinkPresenter(ISourceViewer sourceViewer) {
    if (fPreferenceStore == null)
      return super.getHyperlinkPresenter(sourceViewer);

    return new DefaultHyperlinkPresenter(fPreferenceStore);
  }

  /**
   * Maps the localized modifier name to a code in the same
   * manner as #findModifier.
   *
   * @param modifierName the modifier name
   * @return the SWT modifier bit, or <code>0</code> if no match was found
   * @since 3.1
   */
  protected static final int findLocalizedModifier(String modifierName) {
    if (modifierName == null)
      return 0;

    if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.CTRL)))
      return SWT.CTRL;
    if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT)))
      return SWT.SHIFT;
    if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.ALT)))
      return SWT.ALT;
    if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND)))
      return SWT.COMMAND;

    return 0;
  }

  /**
   * Computes the state mask out of the given modifiers string.
   *
   * @param modifiers a string containing modifiers
   * @return the state mask
   * @since 3.1
   */
  protected static final int computeStateMask(String modifiers) {
    if (modifiers == null)
      return -1;

    if (modifiers.length() == 0)
      return SWT.NONE;

    int stateMask= 0;
    StringTokenizer modifierTokenizer= new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$
    while (modifierTokenizer.hasMoreTokens()) {
      int modifier= findLocalizedModifier(modifierTokenizer.nextToken());
      if (modifier == 0 || (stateMask & modifier) == modifier)
        return -1;
      stateMask= stateMask | modifier;
    }
    return stateMask;
  }

  /*
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getUndoManager(org.eclipse.jface.text.source.ISourceViewer)
   * @since 3.1
   */
  public IUndoManager getUndoManager(ISourceViewer sourceViewer) {
    if (fPreferenceStore == null || !fPreferenceStore.contains(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_UNDO_HISTORY_SIZE))
      return super.getUndoManager(sourceViewer);

    int undoHistorySize= fPreferenceStore.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_UNDO_HISTORY_SIZE);
    return new TextViewerUndoManager(undoHistorySize);
  }

  /**
   * Returns the reconciler ready to be used with the given source viewer.
   * <p>
   * This implementation currently returns a {@link MonoReconciler} which
   * is responsible for spell checking. In the future a different reconciler
   * taking over more responsibilities might be returned.</p>
   * 
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer)
   * @since 3.3
   */
  public IReconciler getReconciler(ISourceViewer sourceViewer) {
    if (fPreferenceStore == null || !fPreferenceStore.getBoolean(SpellingService.PREFERENCE_SPELLING_ENABLED))
      return null;

    SpellingService spellingService= EditorsUI.getSpellingService();
    if (spellingService.getActiveSpellingEngineDescriptor(fPreferenceStore) == null)
      return null;
    
    IReconcilingStrategy strategy= new SpellingReconcileStrategy(sourceViewer, spellingService); 
    MonoReconciler reconciler= new MonoReconciler(strategy, false);
    reconciler.setIsIncrementalReconciler(false);
    reconciler.setProgressMonitor(new NullProgressMonitor());
    reconciler.setDelay(500);
    return reconciler;
  }  

  /*
   * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getQuickAssistAssistant(org.eclipse.jface.text.source.ISourceViewer)
   * @since 3.3
   */
  public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
    if (fPreferenceStore == null || !fPreferenceStore.getBoolean(SpellingService.PREFERENCE_SPELLING_ENABLED))
      return null;

    IQuickAssistAssistant assistant= new QuickAssistAssistant();
    assistant.setQuickAssistProcessor(new SpellingCorrectionProcessor());
    assistant.setInformationControlCreator(getQuickAssistAssistantInformationControlCreator());
    
    // Waiting for color preferences, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=133731
    assistant.setProposalSelectorBackground(sourceViewer.getTextWidget().getDisplay().getSystemColor(SWT.COLOR_WHITE));
    assistant.setProposalSelectorForeground(sourceViewer.getTextWidget().getDisplay().getSystemColor(SWT.COLOR_BLACK));
    
    return assistant;
  }

  /**
   * Returns the information control creator for the quick assist assistant.
   *
   * @return the information control creator
   * @since 3.3
   */
  private IInformationControlCreator getQuickAssistAssistantInformationControlCreator() {
    return new IInformationControlCreator() {
      public IInformationControl createInformationControl(Shell parent) {
        return new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(true));
      }
    };
  }

  /**
   * Helper method to merge two {@link IHyperlinkDetector} arrays.
   * 
   * @param array1 an array of hyperlink detectors or <code>null</code>
   * @param array2 an array of hyperlink detectors or <code>null</code>
   * @return an array with the merged hyperlink detectors or <code>null</code> if both given arrays are <code>null</code>
   * @since 3.3
   */
  private IHyperlinkDetector[] merge(IHyperlinkDetector[] array1, IHyperlinkDetector[] array2) {
    if (array1 == null && array2 == null)
      return null;
    else if (array1 == null)
      return array2;
    else if (array2 == null)
      return array1;
    else {
      IHyperlinkDetector[] allHyperlinkDetectors;
      int size= array1.length + array2.length;  
      allHyperlinkDetectors= new IHyperlinkDetector[size];
      System.arraycopy(array1, 0, allHyperlinkDetectors, 0, array1.length);
      System.arraycopy(array2, 0, allHyperlinkDetectors, array1.length, array2.length);
      return allHyperlinkDetectors;
    }
  }

  /**
   * Text hover with custom control creator that
   * can show the tool tip affordance.
   * 
   * @since 3.3
   */
  private final class TextHover extends DefaultTextHover implements ITextHoverExtension {
    public TextHover(ISourceViewer sourceViewer) {
      super(sourceViewer);
    }

    protected boolean isIncluded(Annotation annotation) {
      return isShownInText(annotation);
    }

    /*
     * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
     */
    public IInformationControlCreator getHoverControlCreator() {
      return new IInformationControlCreator() {
        public IInformationControl createInformationControl(Shell parent) {
          return new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(true), EditorsUI.getTooltipAffordanceString());
        }
      };
    }
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.