Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 56eb0aca1f7306e954763fc378d3d86e823e4b29 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.texteditor.quickdiff;

import java.util.ResourceBundle;

import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;

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 {
	
	private int fLastLine= -1;
	private final boolean fIsRulerAction;

	/**
	 * Creates a new instance.
	 * 
	 * @param bundle the resource bundle
	 * @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(ResourceBundle bundle, String prefix, ITextEditor editor, boolean isRulerAction) {
		super(bundle, prefix, editor);
		fIsRulerAction= isRulerAction;
	}
	
	/**
	 * 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();
	
	/*
	 * @see org.eclipse.jface.action.IAction#run()
	 */
	public void run() {
		ITextEditor editor= getTextEditor();
		if (editor == null || !validateEditorInputState())
			return;
		IRewriteTarget target= (IRewriteTarget)editor.getAdapter(IRewriteTarget.class);
		if (target != null)
			target.beginCompoundChange();
		runCompoundChange();
		if (target != null) 
			target.endCompoundChange();
		
	}
	
	/*
	 * @see org.eclipse.jface.action.IAction#isEnabled()
	 */
	public boolean isEnabled() {
		if (!fIsRulerAction)
			setEnabled(computeEnablement());
		
		return super.isEnabled();
	}
	
	/*
	 * @see org.eclipse.ui.texteditor.IUpdate#update()
	 */
	public void update() {
		/*
		 * Update only works if we're updated from the ruler action
		 * (see AbstractDecoratedTextEditor.rulerContextMenuAboutToShow).
		 */
		super.update();
		
		setEnabled(computeEnablement());
	}
	
	/**
	 * 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
	 * @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 (IVerticalRulerInfo)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= (IEditorStatusLine) getTextEditor().getAdapter(IEditorStatusLine.class);
			if (statusLine != null) {
				statusLine.setMessage(true, string, null);
			}
		}
	}
}

Back to the top