1 /*******************************************************************************
2  * Copyright (c) 2009, 2016 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  *     Simon Scholz <simon.scholz@vogella.com> - Bug 450411, 486876
14  *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 395825, 433188
15  ******************************************************************************/
16 package org.eclipse.e4.ui.workbench.modeling;
17 
18 import java.util.Collection;
19 import java.util.Optional;
20 import org.eclipse.core.runtime.AssertionFailedException;
21 import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
22 import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
23 import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
24 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
25 
26 /**
27  * The part service provides clients with the functionalities of showing and hiding parts. Part
28  * events can also be tracked via the part service.
29  * <p>
30  * It is expected that any methods that are exposed by this service that takes an <code>MPart</code>
31  * as an argument be a part that is actually being managed by this service.
32  * </p>
33  *
34  * @since 1.0
35  * @noimplement This interface is not intended to be implemented by clients.
36  */
37 public interface EPartService {
38 
39 	/**
40 	 * Used to tag the currently active part in a presentation for subsequent activation on session
41 	 * startup
42 	 */
43 	String ACTIVE_ON_CLOSE_TAG = "activeOnClose"; //$NON-NLS-1$
44 
45 	/**
46 	 * Applicable states that a part can be in. This will be used in conjunction with
47 	 * {@link EPartService#showPart(String, PartState)}.
48 	 */
49 	public enum PartState {
50 
51 		/**
52 		 * Part state that indicates the part should be made visible and activated.
53 		 */
54 		ACTIVATE,
55 
56 		/**
57 		 * Part state that indicates the part should be made visible though it may not necessarily
58 		 * be granted focus. If the part will be displayed in the same stack as the currently active
59 		 * part, then this has the same effect as <code>ACTIVATE</code>.
60 		 */
61 		VISIBLE,
62 
63 		/**
64 		 * Part state that indicates the part should be created but not necessarily made visible.
65 		 */
66 		CREATE
67 	}
68 
69 	/**
70 	 * A tag on a part to indicate that it should be removed from the model when it is hidden.
71 	 *
72 	 * @see #hidePart(MPart)
73 	 */
74 	String REMOVE_ON_HIDE_TAG = "removeOnHide"; //$NON-NLS-1$
75 
76 	/**
77 	 * Adds the given listener for part lifecycle events. Has no effect if an identical listener has
78 	 * already been registered.
79 	 * <p>
80 	 * <b>Note:</b> Listeners should be removed when no longer necessary.
81 	 * </p>
82 	 *
83 	 * @param listener
84 	 *            the listener to attach
85 	 */
addPartListener(IPartListener listener)86 	void addPartListener(IPartListener listener);
87 
88 	/**
89 	 * Removes the given listener so that it will no longer be notified of part lifecycle events.
90 	 * Has no effect if an identical listener has not been registered.
91 	 *
92 	 * @param listener
93 	 *            the listener to remove
94 	 */
removePartListener(IPartListener listener)95 	void removePartListener(IPartListener listener);
96 
97 	/**
98 	 * Activates the given part. The part will be brought to top (if necessary) and granted focus.
99 	 *
100 	 * @param part
101 	 *            the part to activate, must not be <code>null</code>
102 	 */
activate(MPart part)103 	void activate(MPart part);
104 
105 	/**
106 	 * Activates the given part. The part will be brought to top (if necessary) and, if
107 	 * {@code requiresFocus} is true, then granted focus.
108 	 *
109 	 * @param part
110 	 *            the part to activate, must not be <code>null</code>
111 	 * @param requiresFocus
112 	 *            if true, then also cause the part to acquire focus
113 	 */
activate(MPart part, boolean requiresFocus)114 	void activate(MPart part, boolean requiresFocus);
115 
116 	/**
117 	 * Ask the service to assign activation to a valid part in the currently active presentation.
118 	 */
requestActivation()119 	void requestActivation();
120 
121 	/**
122 	 * Brings this part to the top so that it will become visible to the end user. This does not
123 	 * imply that the part will be granted focus.
124 	 *
125 	 * @param part
126 	 *            the part to bring to top
127 	 */
bringToTop(MPart part)128 	void bringToTop(MPart part);
129 
130 	/**
131 	 * Finds and returns a part with the given id.
132 	 *
133 	 * @param id
134 	 *            the id of the part to search for, must not be <code>null</code>
135 	 * @return the part with the specified id, or <code>null</code> if no such part could be found
136 	 */
findPart(String id)137 	MPart findPart(String id);
138 
139 	/**
140 	 * Returns a collection of all the parts that are being managed by this part service.
141 	 *
142 	 * @return a collection of parts that are being managed by this service, never <code>null</code>
143 	 */
getParts()144 	Collection<MPart> getParts();
145 
146 	/**
147 	 * Returns the active part.
148 	 *
149 	 * @return an active part within the scope of this service, or <code>null</code> if no part is
150 	 *         currently active
151 	 */
getActivePart()152 	MPart getActivePart();
153 
154 	/**
155 	 * Returns whether the specified part is currently visible to the end user.
156 	 *
157 	 * @param part
158 	 *            the part to check
159 	 * @return <code>true</code> if the part is currently visible, <code>false</code> otherwise
160 	 */
isPartVisible(MPart part)161 	boolean isPartVisible(MPart part);
162 
163 	/**
164 	 * Creates a new part of the given id.
165 	 *
166 	 * @param partDescriptorId the identifier of the Part Descriptor, must not be
167 	 *                         <code>null</code>
168 	 * @return a new part of the given id, or <code>null</code> if no part
169 	 *         descriptors can be found that match the specified partDescriptorId
170 	 */
createPart(String partDescriptorId)171 	MPart createPart(String partDescriptorId);
172 
173 	/**
174 	 * Creates a new placeholder for a part of the given id.
175 	 *
176 	 * @param id
177 	 *            the identifier of the part, must not be <code>null</code>
178 	 * @return a new part of the given id, or <code>null</code> if no part descriptors can be found
179 	 *         that match the specified id
180 	 */
createSharedPart(String id)181 	MPlaceholder createSharedPart(String id);
182 
183 	/**
184 	 * Creates a new placeholder for a part of the given id.
185 	 *
186 	 * @param id
187 	 *            the identifier of the part, must not be <code>null</code>
188 	 * @param force
189 	 *            <code>true</code> if a new part should be created, <code>false</code> if the
190 	 *            window should be queried for a shared part first
191 	 * @return a new part of the given id, or <code>null</code> if no part descriptors can be found
192 	 *         that match the specified id
193 	 */
createSharedPart(String id, boolean force)194 	MPlaceholder createSharedPart(String id, boolean force);
195 
196 	/**
197 	 * Shows a part with the identified by the given id. In the event that there are multiple parts
198 	 * with the specified id, the client is recommended to use {@link #getParts()} and iterate over
199 	 * the collection to find the interested part and invoke {@link #showPart(MPart, PartState)} on
200 	 * it. The behavior of this method is dictated by the supplied state.
201 	 * <ul>
202 	 * <li>If <code>ACTIVATE</code> is supplied, then the part is made visible and granted focus.</li>
203 	 * <li>If <code>VISIBLE</code> is supplied, then the part will be made visible and possibly be
204 	 * granted focus depending on where it is relative to the active part. If it is in the same
205 	 * stack as the currently active part, then it will be granted focus.</li>
206 	 * <li>If <code>CREATE</code> is supplied, then the part will be instantiated though its
207 	 * contents may not necessarily be visible to the end user. visible to the end user.</li>
208 	 * </ul>
209 	 *
210 	 * @param id
211 	 *            the identifier of the part, must not be <code>null</code>
212 	 * @param partState
213 	 *            the desired state of the shown part to be in
214 	 * @return the shown part, or <code>null</code> if no parts or part descriptors can be found
215 	 *         that match the specified id
216 	 */
showPart(String id, PartState partState)217 	MPart showPart(String id, PartState partState);
218 
219 	/**
220 	 * Shows the given part.
221 	 * <ul>
222 	 * <li>If there cannot be multiple parts of this type and a part already exists,
223 	 * the already existing part will be shown and returned.</li>
224 	 * <li>If multiple parts of this type is allowed, then the provided part will be
225 	 * shown and returned</li>
226 	 * </ul>
227 	 * <p>
228 	 * The behavior of this method is dictated by the supplied state.
229 	 * </p>
230 	 * <ul>
231 	 * <li>If <code>ACTIVATE</code> is supplied, then the part is made visible and
232 	 * granted focus.</li>
233 	 * <li>If <code>VISIBLE</code> is supplied, then the part will be made visible
234 	 * and possibly be granted focus depending on where it is relative to the active
235 	 * part. If it is in the same stack as the currently active part, then it will
236 	 * be granted focus.</li>
237 	 * <li>If <code>CREATE</code> is supplied, then the part will be instantiated
238 	 * though its contents may not necessarily be visible to the end user. visible
239 	 * to the end user.</li>
240 	 * </ul>
241 	 *
242 	 * @param part      the part to show
243 	 * @param partState the desired state of the shown part to be in
244 	 * @return the shown part
245 	 */
showPart(MPart part, PartState partState)246 	MPart showPart(MPart part, PartState partState);
247 
248 	/**
249 	 * Hides the given part. The part must be a part managed by this service.
250 	 * <p>
251 	 * If the part has been tagged with the {@link #REMOVE_ON_HIDE_TAG} tag, it will be removed from
252 	 * the model when the service hides it.
253 	 * </p>
254 	 * <p>
255 	 * To save the part before hiding, use {@link #savePart(MPart, boolean)}:
256 	 * </p>
257 	 *
258 	 * <pre>
259 	 * if (partService.savePart(part, true)) {
260 	 * 	partService.hidePart(part);
261 	 * }
262 	 * </pre>
263 	 *
264 	 * @param part
265 	 *            the part to hide
266 	 * @see #savePart(MPart, boolean)
267 	 */
hidePart(MPart part)268 	void hidePart(MPart part);
269 
270 	/**
271 	 * Hides the given part. The part must be a part managed by this service.
272 	 * <p>
273 	 * If <code>force</code> is <code>true</code> or the part has been tagged with the
274 	 * {@link #REMOVE_ON_HIDE_TAG} tag, it will be removed from the model when the service hides it.
275 	 * </p>
276 	 * <p>
277 	 * To save the part before hiding, use {@link #savePart(MPart, boolean)}:
278 	 * </p>
279 	 *
280 	 * <pre>
281 	 * if (partService.savePart(part, true)) {
282 	 * 	partService.hidePart(part);
283 	 * }
284 	 * </pre>
285 	 *
286 	 * @param part
287 	 *            the part to hide
288 	 * @param force
289 	 *            if the part should be removed from the model regardless of its
290 	 *            {@link #REMOVE_ON_HIDE_TAG} tag
291 	 * @see #savePart(MPart, boolean)
292 	 */
hidePart(MPart part, boolean force)293 	void hidePart(MPart part, boolean force);
294 
295 	/**
296 	 * Returns a collection of all the dirty parts that are being managed by this service.
297 	 *
298 	 *
299 	 * @return a collection of dirty parts that are being managed by this service, never
300 	 *         <code>null</code>
301 	 */
getDirtyParts()302 	Collection<MPart> getDirtyParts();
303 
304 	/**
305 	 * Saves the contents of the part if it is dirty and returns whether the operation completed.
306 	 *
307 	 * @param part
308 	 *            the part to save
309 	 * @param confirm
310 	 *            <code>true</code> if the user should be prompted prior to saving the changes, and
311 	 *            <code>false</code> to save changes without asking
312 	 * @return <code>true</code> if the operation completed successfully, <code>false</code> if the
313 	 *         user canceled the operation or if an error occurred while saving the changes
314 	 * @see #hidePart(MPart, boolean)
315 	 */
savePart(MPart part, boolean confirm)316 	boolean savePart(MPart part, boolean confirm);
317 
318 	/**
319 	 * Saves the contents of all dirty parts and returns whether the operation completed.
320 	 *
321 	 * @param confirm
322 	 *            <code>true</code> if the user should be prompted prior to saving the changes, and
323 	 *            <code>false</code> to save changes without asking
324 	 * @return <code>true</code> if the operation completed successfully, <code>false</code> if the
325 	 *         user canceled the operation or if an error occurred while saving the changes
326 	 */
saveAll(boolean confirm)327 	boolean saveAll(boolean confirm);
328 
329 	/**
330 	 * Returns a collection of all {@link MInputPart} with the inputURI-Attribute
331 	 * set to the given value
332 	 *
333 	 * @param inputUri
334 	 *            the input uri to search for, must not be <code>null</code>
335 	 * @return list of parts or an empty collection
336 	 * @throws AssertionFailedException
337 	 *             if null passed as argument
338 	 * @deprecated This method should never be used as MInputPart are deprecated
339 	 * @noreference This method is not intended to be referenced by clients.
340 	 * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=509868">Bug
341 	 *      509868</a>
342 	 */
getInputParts(String inputUri)343 	@Deprecated Collection<MInputPart> getInputParts(String inputUri);
344 
345 	/**
346 	 * Switch to the specified perspective. It will be selected and brought to top (if necessary).
347 	 * It may not necessarily be granted focus if there is another active window present.
348 	 *
349 	 * @param perspective
350 	 *            the perspective to switch to, must not be <code>null</code> and it must be a
351 	 *            perspective that's being managed by this service
352 	 *
353 	 * @since 1.4
354 	 */
switchPerspective(MPerspective perspective)355 	void switchPerspective(MPerspective perspective);
356 
357 	/**
358 	 * Switch to the specified perspective. It will be selected and brought to top
359 	 * (if necessary). It may not necessarily be granted focus if there is another
360 	 * active window present.
361 	 *
362 	 * @param perspectiveId the perspective to switch to, must not be
363 	 *                      <code>null</code> and it must identify a perspective
364 	 *                      that's being managed by this service
365 	 * @return an java.util.Optional&lt;MPerspective&gt; containing the perspective,
366 	 *         which has been switched to or an empty Optional.
367 	 *
368 	 * @since 1.4
369 	 */
switchPerspective(String perspectiveId)370 	Optional<MPerspective> switchPerspective(String perspectiveId);
371 
372 	/**
373 	 * Indicates whether a part with a certain elementId is currently rendered in a certain
374 	 * perspective or not.
375 	 *
376 	 * @param elementId
377 	 *            the id of the part, which should be checked
378 	 * @param perspective
379 	 *            the perspective, which may contain the part with the given elementId
380 	 * @return <code>true</code> if the part with the given elementId is rendered in the given
381 	 *         perspective and <code>false</code> otherwise
382 	 * @since 1.3
383 	 */
isPartOrPlaceholderInPerspective(String elementId, MPerspective perspective)384 	boolean isPartOrPlaceholderInPerspective(String elementId, MPerspective perspective);
385 }