001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.editors.quickdiff;
011:
012: import java.util.ResourceBundle;
013:
014: import org.eclipse.jface.viewers.IPostSelectionProvider;
015: import org.eclipse.jface.viewers.ISelection;
016: import org.eclipse.jface.viewers.ISelectionChangedListener;
017: import org.eclipse.jface.viewers.ISelectionProvider;
018: import org.eclipse.jface.viewers.SelectionChangedEvent;
019:
020: import org.eclipse.jface.text.IRewriteTarget;
021: import org.eclipse.jface.text.ITextSelection;
022: import org.eclipse.jface.text.source.IAnnotationModel;
023: import org.eclipse.jface.text.source.IAnnotationModelExtension;
024: import org.eclipse.jface.text.source.IChangeRulerColumn;
025: import org.eclipse.jface.text.source.ILineDiffer;
026: import org.eclipse.jface.text.source.IVerticalRulerInfo;
027:
028: import org.eclipse.ui.IEditorInput;
029: import org.eclipse.ui.texteditor.IDocumentProvider;
030: import org.eclipse.ui.texteditor.IEditorStatusLine;
031: import org.eclipse.ui.texteditor.ITextEditor;
032: import org.eclipse.ui.texteditor.TextEditorAction;
033:
034: /**
035: * Abstract superclass of actions that restore / revert parts of a document displayed in the action's
036: * editor to the state described by the {@link ILineDiffer ILineDiffer} associated with the document's
037: * {@link IAnnotationModel IAnnotationModel}.
038: *
039: * @since 3.1
040: */
041: public abstract class QuickDiffRestoreAction extends TextEditorAction
042: implements ISelectionChangedListener {
043:
044: private int fLastLine = -1;
045: private final boolean fIsRulerAction;
046:
047: /**
048: * Creates a new instance.
049: *
050: * @param bundle the resource bundle
051: * @param prefix a prefix to be prepended to the various resource keys
052: * @param editor the editor this action belongs to
053: * @param isRulerAction <code>true</code> if this is a ruler action
054: */
055: QuickDiffRestoreAction(ResourceBundle bundle, String prefix,
056: ITextEditor editor, boolean isRulerAction) {
057: super (bundle, prefix, editor);
058: fIsRulerAction = isRulerAction;
059:
060: ISelectionProvider selectionProvider = editor
061: .getSelectionProvider();
062: if (selectionProvider instanceof IPostSelectionProvider)
063: ((IPostSelectionProvider) selectionProvider)
064: .addPostSelectionChangedListener(this );
065: }
066:
067: /**
068: * Called by this action's run method inside a pair of calls to <code>IRewriteTarget.beginCompoundChange</code>
069: * and <code>IRewriteTarget.endCompoundChange</code>().
070: *
071: * @see IRewriteTarget
072: */
073: protected abstract void runCompoundChange();
074:
075: /*
076: * @see org.eclipse.jface.action.IAction#run()
077: */
078: public void run() {
079: ITextEditor editor = getTextEditor();
080: if (editor == null || !validateEditorInputState())
081: return;
082: IRewriteTarget target = (IRewriteTarget) editor
083: .getAdapter(IRewriteTarget.class);
084: if (target != null)
085: target.beginCompoundChange();
086: runCompoundChange();
087: if (target != null)
088: target.endCompoundChange();
089:
090: }
091:
092: /*
093: * @see org.eclipse.ui.texteditor.IUpdate#update()
094: */
095: public void update() {
096: /*
097: * Update only works if we're updated from the ruler action
098: * (see AbstractDecoratedTextEditor.rulerContextMenuAboutToShow).
099: */
100: super .update();
101:
102: setEnabled(computeEnablement());
103: }
104:
105: /*
106: * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
107: * @since 3.3
108: */
109: public void selectionChanged(SelectionChangedEvent event) {
110: update();
111: }
112:
113: /**
114: * Computes, caches and returns the internal state, including enablement.
115: *
116: * @return <code>true</code> if the action is enabled, <code>false</code>
117: * if it is not
118: */
119: protected boolean computeEnablement() {
120: if (!super .isEnabled())
121: return false;
122:
123: if (!canModifyEditor())
124: return false;
125:
126: fLastLine = computeLine(fIsRulerAction);
127: return true;
128: }
129:
130: /**
131: * Returns the selection of the editor this action belongs to.
132: *
133: * @return the editor's selection, or <code>null</code>
134: */
135: protected ITextSelection getSelection() {
136: if (getTextEditor() == null)
137: return null;
138: ISelectionProvider sp = getTextEditor().getSelectionProvider();
139: if (sp == null)
140: return null;
141: ISelection s = sp.getSelection();
142: if (s instanceof ITextSelection)
143: return (ITextSelection) s;
144: return null;
145: }
146:
147: /**
148: * Returns the current line of activity
149: *
150: * @return the currently active line
151: * @since 3.1
152: */
153: protected int getLastLine() {
154: return fLastLine;
155: }
156:
157: /**
158: * Returns the active line
159: *
160: * @param useRulerInfo
161: * @return the line of interest.
162: * @since 3.1
163: */
164: private int computeLine(boolean useRulerInfo) {
165: int lastLine;
166: if (useRulerInfo) {
167: IVerticalRulerInfo ruler = getRuler();
168: if (ruler == null)
169: lastLine = -1;
170: else
171: lastLine = ruler.getLineOfLastMouseButtonActivity();
172: } else {
173: ITextSelection selection = getSelection();
174: if (selection == null)
175: lastLine = -1;
176: else
177: lastLine = selection.getEndLine();
178: }
179: return lastLine;
180: }
181:
182: /**
183: * Returns the annotation model of the document displayed in this action's editor, if it
184: * implements the {@link IAnnotationModelExtension IAnnotationModelExtension} interface.
185: *
186: * @return the displayed document's annotation model if it is an <code>IAnnotationModelExtension</code>, or <code>null</code>
187: */
188: private IAnnotationModelExtension getModel() {
189: if (getTextEditor() == null)
190: return null;
191: IDocumentProvider provider = getTextEditor()
192: .getDocumentProvider();
193: IEditorInput editorInput = getTextEditor().getEditorInput();
194: IAnnotationModel m = provider.getAnnotationModel(editorInput);
195: if (m instanceof IAnnotationModelExtension)
196: return (IAnnotationModelExtension) m;
197: return null;
198: }
199:
200: /**
201: * Returns the diff model associated with the annotation model of the document currently displayed
202: * in this action's editor, if any.
203: *
204: * @return the diff model associated with the displayed document, or <code>null</code>
205: */
206: protected ILineDiffer getDiffer() {
207: IAnnotationModelExtension extension = getModel();
208: if (extension != null)
209: return (ILineDiffer) extension
210: .getAnnotationModel(IChangeRulerColumn.QUICK_DIFF_MODEL_ID);
211: return null;
212: }
213:
214: /**
215: * Returns a <code>IVerticalRulerInfo</code> if this action's editor adapts to one.
216: *
217: * @return the <code>IVerticalRulerInfo</code> for the editor's vertical ruler, or <code>null</code>
218: */
219: protected IVerticalRulerInfo getRuler() {
220: if (getTextEditor() != null)
221: return (IVerticalRulerInfo) getTextEditor().getAdapter(
222: IVerticalRulerInfo.class);
223: return null;
224: }
225:
226: /**
227: * Sets the status line error message to <code>string</code>.
228: *
229: * @param string the message to be displayed as error.
230: */
231: protected void setStatus(String string) {
232: if (getTextEditor() != null) {
233: IEditorStatusLine statusLine = (IEditorStatusLine) getTextEditor()
234: .getAdapter(IEditorStatusLine.class);
235: if (statusLine != null) {
236: statusLine.setMessage(true, string, null);
237: }
238: }
239: }
240: }
|