1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.ui.texteditor;
15 
16 
17 import java.util.ResourceBundle;
18 
19 /**
20  * Skeleton of a standard text editor action. The action is
21  * initially associated with a text editor via the constructor,
22  * but can subsequently be changed using <code>setEditor</code>.
23  * Subclasses must implement the <code>run</code> method and if
24  * required override the <code>update</code> method.
25  * <p>
26  * Subclasses that may modify the editor content should use {@link #canModifyEditor()}
27  * in their <code>update</code> code to check whether updating the editor is most
28  * likely possible (even if it is read-only - this may change for editor contents
29  * that are under version control) and {@link #validateEditorInputState()} before
30  * actually modifying the editor contents.
31  * </p>
32  */
33 public abstract class TextEditorAction extends ResourceAction implements IUpdate {
34 
35 	/** The action's editor */
36 	private ITextEditor fTextEditor;
37 
38 	/**
39 	 * Creates and initializes the action for the given text editor. The action
40 	 * configures its visual representation from the given resource bundle.
41 	 *
42 	 * @param bundle the resource bundle
43 	 * @param prefix a prefix to be prepended to the various resource keys
44 	 *   (described in <code>ResourceAction</code> constructor), or
45 	 *   <code>null</code> if none
46 	 * @param editor the text editor
47 	 * @see ResourceAction#ResourceAction(ResourceBundle, String)
48 	 */
TextEditorAction(ResourceBundle bundle, String prefix, ITextEditor editor)49 	protected TextEditorAction(ResourceBundle bundle, String prefix, ITextEditor editor) {
50 		super(bundle, prefix);
51 		setEditor(editor);
52 		update();
53 	}
54 
55 	/**
56 	 * Creates and initializes the action for the given text editor. The action
57 	 * configures its visual representation from the given resource bundle.
58 	 *
59 	 * @param bundle the resource bundle
60 	 * @param prefix a prefix to be prepended to the various resource keys
61 	 *   (described in <code>ResourceAction</code> constructor), or
62 	 *   <code>null</code> if none
63 	 * @param editor the text editor
64 	 * @param style the style of this action
65 	 * @see ResourceAction#ResourceAction(ResourceBundle, String, int)
66 	 * @since 3.0
67 	 */
TextEditorAction(ResourceBundle bundle, String prefix, ITextEditor editor, int style)68 	protected TextEditorAction(ResourceBundle bundle, String prefix, ITextEditor editor, int style) {
69 		super(bundle, prefix, style);
70 		setEditor(editor);
71 		update();
72 	}
73 
74 	/**
75 	 * Returns the action's text editor.
76 	 *
77 	 * @return the action's text editor
78 	 */
getTextEditor()79 	protected ITextEditor getTextEditor() {
80 		return fTextEditor;
81 	}
82 
83 	/**
84 	 * Retargets this action to the given editor.
85 	 *
86 	 * @param editor the new editor, or <code>null</code> if none
87 	 */
setEditor(ITextEditor editor)88 	public void setEditor(ITextEditor editor) {
89 		fTextEditor= editor;
90 	}
91 
92 	/**
93 	 * Always enables this action if it is connected to a text editor.
94 	 * If the associated editor is <code>null</code>, the action is disabled.
95 	 * Subclasses may override.
96 	 */
97 	@Override
update()98 	public void update() {
99 		setEnabled(getTextEditor() != null);
100 	}
101 
102 	/**
103 	 * Checks the editor's modifiable state. Returns <code>true</code> if the editor can be modified,
104 	 * taking in account the possible editor extensions.
105 	 *
106 	 * <p>If the editor implements <code>ITextEditorExtension2</code>,
107 	 * this method returns {@link ITextEditorExtension2#isEditorInputModifiable()};<br> else if the editor
108 	 * implements <code>ITextEditorExtension</code>, it returns {@link ITextEditorExtension#isEditorInputReadOnly()};<br>
109 	 * else, {@link ITextEditor#isEditable()} is returned, or <code>false</code> if the editor is <code>null</code>.</p>
110 	 *
111 	 * <p>There is only a difference to {@link #validateEditorInputState()} if the editor implements
112 	 * <code>ITextEditorExtension2</code>.</p>
113 	 *
114 	 * @return <code>true</code> if a modifying action should be enabled, <code>false</code> otherwise
115 	 * @since 3.0
116 	 */
canModifyEditor()117 	protected boolean canModifyEditor() {
118 		ITextEditor editor= getTextEditor();
119 		if (editor instanceof ITextEditorExtension2)
120 			return ((ITextEditorExtension2) editor).isEditorInputModifiable();
121 		else if (editor instanceof ITextEditorExtension)
122 			return !((ITextEditorExtension) editor).isEditorInputReadOnly();
123 		else if (editor != null)
124 			return editor.isEditable();
125 		else
126 			return false;
127 	}
128 
129 	/**
130 	 * Checks and validates the editor's modifiable state. Returns <code>true</code> if an action
131 	 * can proceed modifying the editor's input, <code>false</code> if it should not.
132 	 *
133 	 * <p>If the editor implements <code>ITextEditorExtension2</code>,
134 	 * this method returns {@link ITextEditorExtension2#validateEditorInputState()};<br> else if the editor
135 	 * implements <code>ITextEditorExtension</code>, it returns {@link ITextEditorExtension#isEditorInputReadOnly()};<br>
136 	 * else, {@link ITextEditor#isEditable()} is returned, or <code>false</code> if the editor is <code>null</code>.</p>
137 	 *
138 	 * <p>There is only a difference to {@link #canModifyEditor()} if the editor implements
139 	 * <code>ITextEditorExtension2</code>.</p>
140 	 *
141 	 * @return <code>true</code> if a modifying action can proceed to modify the underlying document, <code>false</code> otherwise
142 	 * @since 3.0
143 	 */
validateEditorInputState()144 	protected boolean validateEditorInputState() {
145 		ITextEditor editor= getTextEditor();
146 		if (editor instanceof ITextEditorExtension2)
147 			return ((ITextEditorExtension2) editor).validateEditorInputState();
148 		else if (editor instanceof ITextEditorExtension)
149 			return !((ITextEditorExtension) editor).isEditorInputReadOnly();
150 		else if (editor != null)
151 			return editor.isEditable();
152 		else
153 			return false;
154 	}
155 }
156