| /******************************************************************************* |
| * Copyright (c) 2006, 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 API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.internal.texteditor; |
| |
| |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.RGB; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| |
| import org.eclipse.core.runtime.Assert; |
| |
| import org.eclipse.jface.dialogs.MessageDialogWithToggle; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.preference.PreferenceConverter; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.window.Window; |
| |
| import org.eclipse.jface.text.ITextViewer; |
| import org.eclipse.jface.text.revisions.IRevisionRulerColumn; |
| import org.eclipse.jface.text.revisions.IRevisionRulerColumnExtension; |
| import org.eclipse.jface.text.revisions.IRevisionRulerColumnExtension.RenderingMode; |
| import org.eclipse.jface.text.revisions.RevisionInformation; |
| import org.eclipse.jface.text.source.AnnotationModel; |
| import org.eclipse.jface.text.source.CompositeRuler; |
| import org.eclipse.jface.text.source.IAnnotationHover; |
| import org.eclipse.jface.text.source.IAnnotationModel; |
| import org.eclipse.jface.text.source.IAnnotationModelExtension; |
| import org.eclipse.jface.text.source.IChangeRulerColumn; |
| import org.eclipse.jface.text.source.ILineDifferExtension; |
| import org.eclipse.jface.text.source.ILineDifferExtension2; |
| import org.eclipse.jface.text.source.ISharedTextColors; |
| import org.eclipse.jface.text.source.ISourceViewer; |
| import org.eclipse.jface.text.source.IVerticalRulerColumn; |
| import org.eclipse.jface.text.source.IVerticalRulerInfo; |
| import org.eclipse.jface.text.source.IVerticalRulerInfoExtension; |
| import org.eclipse.jface.text.source.IVerticalRulerListener; |
| import org.eclipse.jface.text.source.LineNumberChangeRulerColumn; |
| import org.eclipse.jface.text.source.LineNumberRulerColumn; |
| |
| import org.eclipse.ui.internal.editors.text.EditorsPlugin; |
| |
| import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor; |
| import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; |
| import org.eclipse.ui.texteditor.AbstractTextEditor; |
| import org.eclipse.ui.texteditor.AnnotationPreference; |
| import org.eclipse.ui.texteditor.ITextEditor; |
| import org.eclipse.ui.texteditor.ITextEditorExtension; |
| import org.eclipse.ui.texteditor.ITextEditorExtension2; |
| import org.eclipse.ui.texteditor.MarkerAnnotationPreferences; |
| import org.eclipse.ui.texteditor.quickdiff.QuickDiff; |
| import org.eclipse.ui.texteditor.rulers.AbstractContributedRulerColumn; |
| |
| import org.eclipse.ui.editors.text.EditorsUI; |
| |
| /** |
| * The line number ruler contribution. Encapsulates a {@link LineNumberChangeRulerColumn} as a |
| * contribution to the <code>rulerColumns</code> extension point. Instead of instantiating the |
| * delegate itself, it calls <code>createLineNumberRulerColumn()</code> in |
| * {@link AbstractDecoratedTextEditor} via {@link ICompatibilityForwarder} to maintain compatibility |
| * with previous releases. |
| * |
| * @since 3.3 |
| */ |
| public class LineNumberColumn extends AbstractContributedRulerColumn implements IVerticalRulerInfo, IVerticalRulerInfoExtension { |
| /** |
| * Forwarder for preference checks and ruler creation. Needed to maintain the forwarded APIs in |
| * {@link AbstractDecoratedTextEditor}. |
| */ |
| public static interface ICompatibilityForwarder { |
| IVerticalRulerColumn createLineNumberRulerColumn(); |
| boolean isQuickDiffEnabled(); |
| boolean isLineNumberRulerVisible(); |
| } |
| |
| /** The contribution id of the line number / change ruler. */ |
| public static final String ID= "org.eclipse.ui.editors.columns.linenumbers"; //$NON-NLS-1$ |
| |
| private static final String FG_COLOR_KEY= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR; |
| private static final String BG_COLOR_KEY= AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND; |
| private static final String USE_DEFAULT_BG_KEY= AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT; |
| private final static String LINE_NUMBER_KEY= AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER; |
| private final static String REVISION_ASK_BEFORE_QUICKDIFF_SWITCH_KEY= AbstractDecoratedTextEditorPreferenceConstants.REVISION_ASK_BEFORE_QUICKDIFF_SWITCH; |
| |
| /** |
| * The delegate and implemenation of the ruler. |
| */ |
| private IVerticalRulerColumn fDelegate; |
| /** |
| * The annotation preferences. |
| */ |
| private final MarkerAnnotationPreferences fAnnotationPreferences= EditorsPlugin.getDefault().getMarkerAnnotationPreferences(); |
| |
| /** |
| * Preference dispatcher that registers a single listener so we don't have to manage every |
| * single preference listener. |
| */ |
| private PropertyEventDispatcher fDispatcher; |
| private ISourceViewer fViewer; |
| private ICompatibilityForwarder fForwarder; |
| |
| @Override |
| public Control createControl(CompositeRuler parentRuler, Composite parentControl) { |
| Assert.isTrue(fDelegate != null); |
| ITextViewer viewer= parentRuler.getTextViewer(); |
| Assert.isLegal(viewer instanceof ISourceViewer); |
| fViewer= (ISourceViewer) viewer; |
| initialize(); |
| Control control= fDelegate.createControl(parentRuler, parentControl); |
| return control; |
| } |
| |
| @Override |
| public Control getControl() { |
| return fDelegate.getControl(); |
| } |
| |
| @Override |
| public int getWidth() { |
| return fDelegate.getWidth(); |
| } |
| |
| @Override |
| public void redraw() { |
| fDelegate.redraw(); |
| } |
| |
| @Override |
| public void setFont(Font font) { |
| fDelegate.setFont(font); |
| } |
| |
| @Override |
| public void setModel(IAnnotationModel model) { |
| if (getQuickDiffPreference()) |
| fDelegate.setModel(model); |
| } |
| |
| @Override |
| public int getLineOfLastMouseButtonActivity() { |
| if (fDelegate instanceof IVerticalRulerInfo) |
| return ((IVerticalRulerInfo)fDelegate).getLineOfLastMouseButtonActivity(); |
| return -1; |
| } |
| |
| @Override |
| public int toDocumentLineNumber(int y_coordinate) { |
| if (fDelegate instanceof IVerticalRulerInfo) |
| return ((IVerticalRulerInfo)fDelegate).toDocumentLineNumber(y_coordinate); |
| return -1; |
| } |
| |
| @Override |
| public void addVerticalRulerListener(IVerticalRulerListener listener) { |
| if (fDelegate instanceof IVerticalRulerInfoExtension) |
| ((IVerticalRulerInfoExtension) fDelegate).addVerticalRulerListener(listener); |
| } |
| |
| @Override |
| public IAnnotationHover getHover() { |
| if (fDelegate instanceof IVerticalRulerInfoExtension) |
| return ((IVerticalRulerInfoExtension) fDelegate).getHover(); |
| return null; |
| } |
| |
| @Override |
| public IAnnotationModel getModel() { |
| if (fDelegate instanceof IVerticalRulerInfoExtension) |
| return ((IVerticalRulerInfoExtension) fDelegate).getModel(); |
| return null; |
| } |
| |
| @Override |
| public void removeVerticalRulerListener(IVerticalRulerListener listener) { |
| if (fDelegate instanceof IVerticalRulerInfoExtension) |
| ((IVerticalRulerInfoExtension) fDelegate).removeVerticalRulerListener(listener); |
| } |
| |
| @Override |
| public void columnRemoved() { |
| if (fDispatcher != null) { |
| fDispatcher.dispose(); |
| fDispatcher= null; |
| } |
| } |
| |
| private IPreferenceStore getPreferenceStore() { |
| return EditorsUI.getPreferenceStore(); |
| } |
| |
| private ISharedTextColors getSharedColors() { |
| return EditorsUI.getSharedTextColors(); |
| } |
| |
| /** |
| * Initializes the given line number ruler column from the preference store. |
| */ |
| private void initialize() { |
| final IPreferenceStore store= getPreferenceStore(); |
| if (store == null) |
| return; |
| |
| // initial set up |
| updateForegroundColor(store, fDelegate); |
| updateBackgroundColor(store, fDelegate); |
| |
| updateLineNumbersVisibility(fDelegate); |
| updateQuickDiffVisibility(fDelegate); |
| updateCharacterMode(store, fDelegate); |
| updateRevisionRenderingMode(store, fDelegate); |
| updateRevisionAuthorVisibility(store, fDelegate); |
| updateRevisionIdVisibility(store, fDelegate); |
| |
| Map<Object, AnnotationPreference> annotationPrefs= getAnnotationPreferenceMap(); |
| final AnnotationPreference changedPref= annotationPrefs.get("org.eclipse.ui.workbench.texteditor.quickdiffChange"); //$NON-NLS-1$ |
| final AnnotationPreference addedPref= annotationPrefs.get("org.eclipse.ui.workbench.texteditor.quickdiffAddition"); //$NON-NLS-1$ |
| final AnnotationPreference deletedPref= annotationPrefs.get("org.eclipse.ui.workbench.texteditor.quickdiffDeletion"); //$NON-NLS-1$ |
| updateChangedColor(changedPref, store, fDelegate); |
| updateAddedColor(addedPref, store, fDelegate); |
| updateDeletedColor(deletedPref, store, fDelegate); |
| |
| fDelegate.redraw(); |
| |
| // listen to changes |
| fDispatcher= new PropertyEventDispatcher(store); |
| |
| fDispatcher.addPropertyChangeListener(FG_COLOR_KEY, new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateForegroundColor(store, fDelegate); |
| fDelegate.redraw(); |
| } |
| }); |
| IPropertyChangeListener backgroundHandler= new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateBackgroundColor(store, fDelegate); |
| fDelegate.redraw(); |
| } |
| }; |
| fDispatcher.addPropertyChangeListener(BG_COLOR_KEY, backgroundHandler); |
| fDispatcher.addPropertyChangeListener(USE_DEFAULT_BG_KEY, backgroundHandler); |
| |
| fDispatcher.addPropertyChangeListener(LINE_NUMBER_KEY, new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| // only handle quick diff on/off information, but not ruler visibility (handled by AbstractDecoratedTextEditor) |
| updateLineNumbersVisibility(fDelegate); |
| } |
| }); |
| |
| fDispatcher.addPropertyChangeListener(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_CHARACTER_MODE, new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateCharacterMode(store, fDelegate); |
| } |
| }); |
| |
| fDispatcher.addPropertyChangeListener(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_RENDERING_MODE, new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateRevisionRenderingMode(store, fDelegate); |
| } |
| }); |
| |
| fDispatcher.addPropertyChangeListener(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_SHOW_AUTHOR, new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateRevisionAuthorVisibility(store, fDelegate); |
| } |
| }); |
| |
| fDispatcher.addPropertyChangeListener(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_SHOW_REVISION, new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateRevisionIdVisibility(store, fDelegate); |
| } |
| }); |
| |
| fDispatcher.addPropertyChangeListener(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON, new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateQuickDiffVisibility(fDelegate); |
| } |
| }); |
| |
| if (changedPref != null) { |
| fDispatcher.addPropertyChangeListener(changedPref.getColorPreferenceKey(), new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateChangedColor(changedPref, store, fDelegate); |
| fDelegate.redraw(); |
| } |
| }); |
| } |
| if (addedPref != null) { |
| fDispatcher.addPropertyChangeListener(addedPref.getColorPreferenceKey(), new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateAddedColor(addedPref, store, fDelegate); |
| fDelegate.redraw(); |
| } |
| }); |
| } |
| if (deletedPref != null) { |
| fDispatcher.addPropertyChangeListener(deletedPref.getColorPreferenceKey(), new IPropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| updateDeletedColor(deletedPref, store, fDelegate); |
| fDelegate.redraw(); |
| } |
| }); |
| } |
| } |
| |
| private Map<Object, AnnotationPreference> getAnnotationPreferenceMap() { |
| Map<Object, AnnotationPreference> annotationPrefs= new HashMap<>(); |
| Iterator<AnnotationPreference> iter= fAnnotationPreferences.getAnnotationPreferences().iterator(); |
| while (iter.hasNext()) { |
| AnnotationPreference pref= iter.next(); |
| Object type= pref.getAnnotationType(); |
| annotationPrefs.put(type, pref); |
| } |
| return annotationPrefs; |
| } |
| |
| private void updateForegroundColor(IPreferenceStore store, IVerticalRulerColumn column) { |
| RGB rgb= getColorFromStore(store, FG_COLOR_KEY); |
| if (rgb == null) |
| rgb= new RGB(0, 0, 0); |
| ISharedTextColors sharedColors= getSharedColors(); |
| if (column instanceof LineNumberRulerColumn) |
| ((LineNumberRulerColumn) column).setForeground(sharedColors.getColor(rgb)); |
| } |
| |
| private void updateBackgroundColor(IPreferenceStore store, IVerticalRulerColumn column) { |
| // background color: same as editor, or system default |
| RGB rgb; |
| if (store.getBoolean(USE_DEFAULT_BG_KEY)) |
| rgb= null; |
| else |
| rgb= getColorFromStore(store, BG_COLOR_KEY); |
| ISharedTextColors sharedColors= getSharedColors(); |
| if (column instanceof LineNumberRulerColumn) |
| ((LineNumberRulerColumn) column).setBackground(sharedColors.getColor(rgb)); |
| } |
| |
| private void updateChangedColor(AnnotationPreference pref, IPreferenceStore store, IVerticalRulerColumn column) { |
| if (pref != null && column instanceof IChangeRulerColumn) { |
| RGB rgb= getColorFromAnnotationPreference(store, pref); |
| ((IChangeRulerColumn) column).setChangedColor(getSharedColors().getColor(rgb)); |
| } |
| } |
| |
| private void updateAddedColor(AnnotationPreference pref, IPreferenceStore store, IVerticalRulerColumn column) { |
| if (pref != null && column instanceof IChangeRulerColumn) { |
| RGB rgb= getColorFromAnnotationPreference(store, pref); |
| ((IChangeRulerColumn) column).setAddedColor(getSharedColors().getColor(rgb)); |
| } |
| } |
| |
| private void updateDeletedColor(AnnotationPreference pref, IPreferenceStore store, IVerticalRulerColumn column) { |
| if (pref != null && column instanceof IChangeRulerColumn) { |
| RGB rgb= getColorFromAnnotationPreference(store, pref); |
| ((IChangeRulerColumn) column).setDeletedColor(getSharedColors().getColor(rgb)); |
| } |
| } |
| |
| private void updateCharacterMode(IPreferenceStore store, IVerticalRulerColumn column) { |
| if (column instanceof LineNumberChangeRulerColumn) { |
| LineNumberChangeRulerColumn lncrc= (LineNumberChangeRulerColumn) column; |
| lncrc.setDisplayMode(store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_CHARACTER_MODE)); |
| } |
| } |
| |
| private void updateLineNumbersVisibility(IVerticalRulerColumn column) { |
| if (column instanceof LineNumberChangeRulerColumn) |
| ((LineNumberChangeRulerColumn) column).showLineNumbers(getLineNumberPreference()); |
| } |
| |
| private void updateRevisionRenderingMode(IPreferenceStore store, IVerticalRulerColumn column) { |
| if (column instanceof IRevisionRulerColumnExtension) { |
| String option= store.getString(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_RENDERING_MODE); |
| RenderingMode[] modes= { IRevisionRulerColumnExtension.AUTHOR, IRevisionRulerColumnExtension.AGE, IRevisionRulerColumnExtension.AUTHOR_SHADED_BY_AGE }; |
| for (int i= 0; i < modes.length; i++) { |
| if (modes[i].name().equals(option)) { |
| ((IRevisionRulerColumnExtension) column).setRevisionRenderingMode(modes[i]); |
| return; |
| } |
| } |
| } |
| } |
| |
| private void updateRevisionAuthorVisibility(IPreferenceStore store, IVerticalRulerColumn column) { |
| if (column instanceof IRevisionRulerColumnExtension) { |
| boolean show= store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_SHOW_AUTHOR); |
| ((IRevisionRulerColumnExtension) column).showRevisionAuthor(show); |
| } |
| } |
| |
| private void updateRevisionIdVisibility(IPreferenceStore store, IVerticalRulerColumn column) { |
| if (column instanceof IRevisionRulerColumnExtension) { |
| boolean show= store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.REVISION_RULER_SHOW_REVISION); |
| ((IRevisionRulerColumnExtension) column).showRevisionId(show); |
| } |
| } |
| |
| private void updateQuickDiffVisibility(IVerticalRulerColumn column) { |
| boolean show= getQuickDiffPreference(); |
| if (show == isShowingChangeInformation()) |
| return; |
| |
| if (show) |
| installChangeRulerModel(column); |
| else |
| uninstallChangeRulerModel(column); |
| } |
| |
| /** |
| * Returns whether the line number ruler column should be |
| * visible according to the preference store settings. Subclasses may override this |
| * method to provide a custom preference setting. |
| * |
| * @return <code>true</code> if the line numbers should be visible |
| */ |
| private boolean getLineNumberPreference() { |
| if (fForwarder != null) |
| return fForwarder.isLineNumberRulerVisible(); |
| IPreferenceStore store= getPreferenceStore(); |
| return store != null ? store.getBoolean(LINE_NUMBER_KEY) : false; |
| } |
| |
| /** |
| * Returns whether quick diff info should be visible upon opening an editor |
| * according to the preference store settings. |
| * |
| * @return <code>true</code> if the line numbers should be visible |
| */ |
| private boolean getQuickDiffPreference() { |
| if (fForwarder != null) |
| return fForwarder.isQuickDiffEnabled(); |
| IPreferenceStore store= getPreferenceStore(); |
| boolean setting= store != null ? store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON) : false; |
| if (!setting) |
| return false; |
| |
| boolean modifiable; |
| ITextEditor editor= getEditor(); |
| if (editor instanceof ITextEditorExtension2) { |
| ITextEditorExtension2 ext= (ITextEditorExtension2) editor; |
| modifiable= ext.isEditorInputModifiable(); |
| } else if (editor instanceof ITextEditorExtension) { |
| ITextEditorExtension ext= (ITextEditorExtension) editor; |
| modifiable= ext.isEditorInputReadOnly(); |
| } else if (editor != null) { |
| modifiable= editor.isEditable(); |
| } else { |
| modifiable= true; |
| } |
| return modifiable; |
| } |
| |
| /** |
| * Extracts the color preference for the given preference from the given store. |
| * If the given store indicates that the default value is to be used, or |
| * the value stored in the preferences store is <code>null</code>, |
| * the value is taken from the <code>AnnotationPreference</code>'s default |
| * color value. |
| * <p> |
| * The return value is |
| * </p> |
| * |
| * @param store the preference store |
| * @param pref the annotation preference |
| * @return the RGB color preference, not <code>null</code> |
| */ |
| private static RGB getColorFromAnnotationPreference(IPreferenceStore store, AnnotationPreference pref) { |
| String key= pref.getColorPreferenceKey(); |
| RGB rgb= null; |
| if (store.contains(key)) { |
| if (store.isDefault(key)) |
| rgb= pref.getColorPreferenceValue(); |
| else |
| rgb= PreferenceConverter.getColor(store, key); |
| } |
| if (rgb == null) |
| rgb= pref.getColorPreferenceValue(); |
| return rgb; |
| } |
| |
| private static RGB getColorFromStore(IPreferenceStore store, String key) { |
| RGB rgb= null; |
| if (store.contains(key)) { |
| if (store.isDefault(key)) |
| rgb= PreferenceConverter.getDefaultColor(store, key); |
| else |
| rgb= PreferenceConverter.getColor(store, key); |
| } |
| return rgb; |
| } |
| |
| /** |
| * Ensures that quick diff information is displayed and the quick diff provider is the one with |
| * the specified id. If a different quick diff provider is in use, the user may be asked whether |
| * he wants to switch. |
| * |
| * @param diffProviderId the quick diff provider id to use |
| * @return <code>true</code> if quick diff could be enabled for the given id, |
| * <code>false</code> otherwise |
| */ |
| private boolean ensureQuickDiffProvider(String diffProviderId) { |
| if (!isShowingChangeInformation()) |
| installChangeRulerModel(fDelegate); // FIXME pass provider id |
| |
| IAnnotationModel annotationModel= fViewer.getAnnotationModel(); |
| IAnnotationModel oldDiffer= getDiffer(); |
| if (oldDiffer == null && annotationModel != null) |
| return false; // quick diff is enabled, but no differ? not working for whatever reason |
| |
| if (annotationModel == null) |
| annotationModel= new AnnotationModel(); |
| if (!(annotationModel instanceof IAnnotationModelExtension)) |
| return false; |
| |
| QuickDiff util= new QuickDiff(); |
| Object oldDifferId= util.getConfiguredQuickDiffProvider(oldDiffer); |
| if (oldDifferId.equals(diffProviderId)) { |
| if (oldDiffer instanceof ILineDifferExtension) |
| ((ILineDifferExtension) oldDiffer).resume(); |
| return true; |
| } |
| |
| // Check whether the desired provider is available at all |
| IAnnotationModel newDiffer= util.createQuickDiffAnnotationModel(getEditor(), diffProviderId); |
| if (util.getConfiguredQuickDiffProvider(newDiffer).equals(oldDifferId)) { |
| if (oldDiffer instanceof ILineDifferExtension) |
| ((ILineDifferExtension) oldDiffer).resume(); |
| return true; |
| } |
| |
| // quick diff is showing with the wrong provider - ask the user whether he wants to switch |
| IPreferenceStore store= EditorsUI.getPreferenceStore(); |
| if (oldDiffer != null && !store.getString(REVISION_ASK_BEFORE_QUICKDIFF_SWITCH_KEY).equals(MessageDialogWithToggle.ALWAYS)) { |
| MessageDialogWithToggle toggleDialog= MessageDialogWithToggle.openOkCancelConfirm( |
| fViewer.getTextWidget().getShell(), |
| RulerMessages.AbstractDecoratedTextEditor_revision_quickdiff_switch_title, |
| RulerMessages.AbstractDecoratedTextEditor_revision_quickdiff_switch_message, |
| RulerMessages.AbstractDecoratedTextEditor_revision_quickdiff_switch_rememberquestion, |
| true, |
| store, |
| REVISION_ASK_BEFORE_QUICKDIFF_SWITCH_KEY); |
| if (toggleDialog.getReturnCode() != Window.OK) |
| return false; |
| } |
| |
| IAnnotationModelExtension modelExtension=(IAnnotationModelExtension) annotationModel; |
| modelExtension.removeAnnotationModel(IChangeRulerColumn.QUICK_DIFF_MODEL_ID); |
| |
| |
| modelExtension.addAnnotationModel(IChangeRulerColumn.QUICK_DIFF_MODEL_ID, newDiffer); |
| |
| if (fDelegate instanceof IChangeRulerColumn) |
| ((IChangeRulerColumn) fDelegate).setModel(annotationModel); // picks up the new model attachment |
| |
| return true; |
| } |
| |
| /** |
| * Installs the differ annotation model with the current quick diff display. |
| * |
| * @param column the column to install the model on |
| */ |
| private void installChangeRulerModel(IVerticalRulerColumn column) { |
| if (column instanceof IChangeRulerColumn) { |
| IAnnotationModel model= getAnnotationModelWithDiffer(); |
| ((IChangeRulerColumn) column).setModel(model); |
| if (model != null) { |
| ISourceViewer viewer= fViewer; |
| if (viewer != null && viewer.getAnnotationModel() == null && column.getControl() != null) |
| viewer.showAnnotations(true); |
| } |
| } |
| } |
| |
| /** |
| * Uninstalls the differ annotation model from the current quick diff display. |
| * |
| * @param column the column to remove the model from |
| */ |
| private void uninstallChangeRulerModel(IVerticalRulerColumn column) { |
| if (column instanceof IChangeRulerColumn) |
| ((IChangeRulerColumn) column).setModel(null); |
| IAnnotationModel model= getDiffer(); |
| if (model instanceof ILineDifferExtension) |
| ((ILineDifferExtension) model).suspend(); |
| |
| ISourceViewer viewer= fViewer; |
| if (viewer != null && viewer.getAnnotationModel() == null) |
| viewer.showAnnotations(false); |
| } |
| |
| /** |
| * Returns the annotation model that contains the quick diff annotation model. |
| * <p> |
| * Extracts the line differ from the displayed document's annotation model. If none can be found, |
| * a new differ is created and attached to the annotation model.</p> |
| * |
| * @return the annotation model that contains the line differ, or <code>null</code> if none could be found or created |
| * @see IChangeRulerColumn#QUICK_DIFF_MODEL_ID |
| */ |
| private IAnnotationModel getAnnotationModelWithDiffer() { |
| ISourceViewer viewer= fViewer; |
| if (viewer == null) |
| return null; |
| |
| IAnnotationModel m= viewer.getAnnotationModel(); |
| IAnnotationModelExtension model= null; |
| if (m instanceof IAnnotationModelExtension) |
| model= (IAnnotationModelExtension) m; |
| |
| IAnnotationModel differ= getDiffer(); |
| // create diff model if it doesn't |
| if (differ == null) { |
| IPreferenceStore store= getPreferenceStore(); |
| if (store != null) { |
| String defaultId= store.getString(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_DEFAULT_PROVIDER); |
| differ= new QuickDiff().createQuickDiffAnnotationModel(getEditor(), defaultId); |
| if (differ != null) { |
| if (model == null) |
| model= new AnnotationModel(); |
| model.addAnnotationModel(IChangeRulerColumn.QUICK_DIFF_MODEL_ID, differ); |
| } |
| } |
| } else if (differ instanceof ILineDifferExtension2) { |
| if (((ILineDifferExtension2) differ).isSuspended()) |
| ((ILineDifferExtension) differ).resume(); |
| } else if (differ instanceof ILineDifferExtension) { |
| ((ILineDifferExtension) differ).resume(); |
| } |
| |
| return (IAnnotationModel)model; |
| } |
| |
| /** |
| * Extracts the line differ from the displayed document's annotation model. If none can be found, |
| * <code>null</code> is returned. |
| * |
| * @return the line differ, or <code>null</code> if none could be found |
| */ |
| private IAnnotationModel getDiffer() { |
| // get annotation model extension |
| ISourceViewer viewer= fViewer; |
| if (viewer == null) |
| return null; |
| |
| IAnnotationModel m= viewer.getAnnotationModel(); |
| if (m == null && fDelegate instanceof IChangeRulerColumn) |
| m= ((IChangeRulerColumn)fDelegate).getModel(); |
| |
| if (!(m instanceof IAnnotationModelExtension)) |
| return null; |
| |
| IAnnotationModelExtension model= (IAnnotationModelExtension)m; |
| |
| // get diff model if it exists already |
| return model.getAnnotationModel(IChangeRulerColumn.QUICK_DIFF_MODEL_ID); |
| } |
| |
| /** |
| * Sets the forwarder. Used by {@link AbstractDecoratedTextEditor} to maintain the contract of |
| * its {@link AbstractDecoratedTextEditor#createLineNumberRulerColumn} method. |
| * |
| * @param forwarder the forwarder |
| */ |
| public void setForwarder(ICompatibilityForwarder forwarder) { |
| fForwarder= forwarder; |
| fDelegate= forwarder.createLineNumberRulerColumn(); |
| } |
| |
| /** |
| * Initializes the given line number ruler column from the preference store. |
| * |
| * @param rulerColumn the ruler column to be initialized |
| */ |
| public void initializeLineNumberRulerColumn(LineNumberRulerColumn rulerColumn) { |
| IPreferenceStore store= getPreferenceStore(); |
| if (store != null) { |
| updateForegroundColor(store, rulerColumn); |
| updateBackgroundColor(store, rulerColumn); |
| updateLineNumbersVisibility(rulerColumn); |
| rulerColumn.redraw(); |
| } |
| } |
| |
| /** |
| * Returns <code>true</code> if the ruler is showing line numbers, <code>false</code> if it |
| * is only showing change information. |
| * |
| * @return <code>true</code> if line numbers are shown, <code>false</code> otherwise |
| */ |
| public boolean isShowingLineNumbers() { |
| return fDelegate instanceof LineNumberChangeRulerColumn && ((LineNumberChangeRulerColumn) fDelegate).isShowingLineNumbers(); |
| } |
| |
| /** |
| * Returns <code>true</code> if the ruler is showing change information, <code>false</code> |
| * if it is only showing line numbers. |
| * |
| * @return <code>true</code> if change information is shown, <code>false</code> otherwise |
| */ |
| public boolean isShowingChangeInformation() { |
| return fDelegate instanceof LineNumberChangeRulerColumn && ((LineNumberChangeRulerColumn) fDelegate).isShowingChangeInformation(); |
| } |
| |
| /** |
| * Shows revision information on the receiver. |
| * |
| * @param info the revision information to show |
| * @param quickDiffProviderId the id of the corresponding quick diff provider |
| */ |
| public void showRevisionInformation(RevisionInformation info, String quickDiffProviderId) { |
| if (!ensureQuickDiffProvider(quickDiffProviderId)) |
| return; |
| |
| if (fDelegate instanceof IRevisionRulerColumn) |
| ((IRevisionRulerColumn) fDelegate).setRevisionInformation(info); |
| } |
| |
| /** |
| * Hides revision information. |
| */ |
| public void hideRevisionInformation() { |
| if (fDelegate instanceof IRevisionRulerColumn) |
| ((IRevisionRulerColumn) fDelegate).setRevisionInformation(null); |
| } |
| |
| /** |
| * Returns <code>true</code> if the ruler is showing revision information, <code>false</code> |
| * if it is only showing line numbers. |
| * |
| * @return <code>true</code> if revision information is shown, <code>false</code> otherwise |
| */ |
| public boolean isShowingRevisionInformation() { |
| if (fDelegate instanceof LineNumberChangeRulerColumn) |
| return ((LineNumberChangeRulerColumn) fDelegate).isShowingRevisionInformation(); |
| return false; |
| } |
| |
| /** |
| * Returns the selection provider of the revision column, <code>null</code> if none is |
| * available. |
| * |
| * @return the revision selection provider |
| */ |
| public ISelectionProvider getRevisionSelectionProvider() { |
| if (fDelegate instanceof IRevisionRulerColumnExtension) |
| return ((IRevisionRulerColumnExtension) fDelegate).getRevisionSelectionProvider(); |
| return null; |
| } |
| } |