| /******************************************************************************* |
| * Copyright (c) 2000, 2008 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.internal.texteditor.quickdiff; |
| |
| import org.eclipse.jface.viewers.IPostSelectionProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| |
| import org.eclipse.jface.text.IRewriteTarget; |
| import org.eclipse.jface.text.ITextSelection; |
| 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.ILineDiffer; |
| import org.eclipse.jface.text.source.IVerticalRulerInfo; |
| |
| import org.eclipse.ui.IEditorInput; |
| |
| import org.eclipse.ui.texteditor.IDocumentProvider; |
| import org.eclipse.ui.texteditor.IEditorStatusLine; |
| import org.eclipse.ui.texteditor.ITextEditor; |
| import org.eclipse.ui.texteditor.TextEditorAction; |
| |
| /** |
| * Abstract superclass of actions that restore / revert parts of a document displayed in the action's |
| * editor to the state described by the {@link ILineDiffer ILineDiffer} associated with the document's |
| * {@link IAnnotationModel IAnnotationModel}. |
| * |
| * @since 3.0 |
| */ |
| public abstract class QuickDiffRestoreAction extends TextEditorAction implements ISelectionChangedListener { |
| |
| private int fLastLine= -1; |
| private final boolean fIsRulerAction; |
| |
| /** |
| * Creates a new instance. |
| * |
| * @param prefix a prefix to be prepended to the various resource keys |
| * @param editor the editor this action belongs to |
| * @param isRulerAction <code>true</code> if this is a ruler action |
| */ |
| QuickDiffRestoreAction(String prefix, ITextEditor editor, boolean isRulerAction) { |
| super(QuickDiffMessages.getBundleForConstructedKeys(), prefix, editor); |
| fIsRulerAction= isRulerAction; |
| |
| ISelectionProvider selectionProvider= editor.getSelectionProvider(); |
| if (selectionProvider instanceof IPostSelectionProvider) |
| ((IPostSelectionProvider)selectionProvider).addPostSelectionChangedListener(this); |
| } |
| |
| /** |
| * Called by this action's run method inside a pair of calls to <code>IRewriteTarget.beginCompoundChange</code> |
| * and <code>IRewriteTarget.endCompoundChange</code>(). |
| * |
| * @see IRewriteTarget |
| */ |
| protected abstract void runCompoundChange(); |
| |
| @Override |
| public void run() { |
| ITextEditor editor= getTextEditor(); |
| if (editor == null || !validateEditorInputState()) |
| return; |
| IRewriteTarget target= editor.getAdapter(IRewriteTarget.class); |
| if (target != null) |
| target.beginCompoundChange(); |
| runCompoundChange(); |
| if (target != null) |
| target.endCompoundChange(); |
| |
| } |
| |
| @Override |
| public void update() { |
| /* |
| * Update only works if we're updated from the ruler action |
| * (see AbstractDecoratedTextEditor.rulerContextMenuAboutToShow). |
| */ |
| super.update(); |
| |
| setEnabled(computeEnablement()); |
| } |
| |
| @Override |
| public void selectionChanged(SelectionChangedEvent event) { |
| update(); |
| } |
| |
| /** |
| * Computes, caches and returns the internal state, including enablement. |
| * |
| * @return <code>true</code> if the action is enabled, <code>false</code> |
| * if it is not |
| */ |
| protected boolean computeEnablement() { |
| if (!super.isEnabled()) |
| return false; |
| |
| if (!canModifyEditor()) |
| return false; |
| |
| fLastLine= computeLine(fIsRulerAction); |
| return true; |
| } |
| |
| /** |
| * Returns the selection of the editor this action belongs to. |
| * |
| * @return the editor's selection, or <code>null</code> |
| */ |
| protected ITextSelection getSelection() { |
| if (getTextEditor() == null) |
| return null; |
| ISelectionProvider sp= getTextEditor().getSelectionProvider(); |
| if (sp == null) |
| return null; |
| ISelection s= sp.getSelection(); |
| if (s instanceof ITextSelection) |
| return (ITextSelection)s; |
| return null; |
| } |
| |
| /** |
| * Returns the current line of activity |
| * |
| * @return the currently active line |
| * @since 3.1 |
| */ |
| protected int getLastLine() { |
| return fLastLine; |
| } |
| |
| /** |
| * Returns the active line. |
| * |
| * @param useRulerInfo <code>true</code> if ruler info should be used |
| * @return the line of interest. |
| * @since 3.1 |
| */ |
| private int computeLine(boolean useRulerInfo) { |
| int lastLine; |
| if (useRulerInfo) { |
| IVerticalRulerInfo ruler= getRuler(); |
| if (ruler == null) |
| lastLine= -1; |
| else |
| lastLine= ruler.getLineOfLastMouseButtonActivity(); |
| } else { |
| ITextSelection selection= getSelection(); |
| if (selection == null) |
| lastLine= -1; |
| else |
| lastLine= selection.getEndLine(); |
| } |
| return lastLine; |
| } |
| |
| /** |
| * Returns the annotation model of the document displayed in this action's editor, if it |
| * implements the {@link IAnnotationModelExtension IAnnotationModelExtension} interface. |
| * |
| * @return the displayed document's annotation model if it is an <code>IAnnotationModelExtension</code>, or <code>null</code> |
| */ |
| private IAnnotationModelExtension getModel() { |
| if (getTextEditor() == null) |
| return null; |
| IDocumentProvider provider= getTextEditor().getDocumentProvider(); |
| IEditorInput editorInput= getTextEditor().getEditorInput(); |
| IAnnotationModel m= provider.getAnnotationModel(editorInput); |
| if (m instanceof IAnnotationModelExtension) |
| return (IAnnotationModelExtension)m; |
| return null; |
| } |
| |
| /** |
| * Returns the diff model associated with the annotation model of the document currently displayed |
| * in this action's editor, if any. |
| * |
| * @return the diff model associated with the displayed document, or <code>null</code> |
| */ |
| protected ILineDiffer getDiffer() { |
| IAnnotationModelExtension extension= getModel(); |
| if (extension != null) |
| return (ILineDiffer)extension.getAnnotationModel(IChangeRulerColumn.QUICK_DIFF_MODEL_ID); |
| return null; |
| } |
| |
| /** |
| * Returns a <code>IVerticalRulerInfo</code> if this action's editor adapts to one. |
| * |
| * @return the <code>IVerticalRulerInfo</code> for the editor's vertical ruler, or <code>null</code> |
| */ |
| protected IVerticalRulerInfo getRuler() { |
| if (getTextEditor() != null) |
| return getTextEditor().getAdapter(IVerticalRulerInfo.class); |
| return null; |
| } |
| |
| /** |
| * Sets the status line error message to <code>string</code>. |
| * |
| * @param string the message to be displayed as error. |
| */ |
| protected void setStatus(String string) { |
| if (getTextEditor() != null) { |
| IEditorStatusLine statusLine= getTextEditor().getAdapter(IEditorStatusLine.class); |
| if (statusLine != null) { |
| statusLine.setMessage(true, string, null); |
| } |
| } |
| } |
| } |