platform-ui-home/workbench_design/Inside the workbench.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (view) (download) (as text)

1 : sxenos 1.1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 :     <html>
3 :     <head>
4 : sxenos 1.4 <meta http-equiv="Content-Type"
5 :     content="text/html; charset=windows-1252">
6 : sxenos 1.1 <title>Inside the Workbench: A guide to the workbench internals</title>
7 : sxenos 1.4 <link rel="stylesheet" href="default_style.css">
8 : sxenos 1.1 </head>
9 : sxenos 1.4 <body link="#0000ff" vlink="#800080">
10 :     <div align="right">&nbsp; <font face="Times New Roman, Times, serif"
11 :     size="2">Copyright &copy; 2005 International Business Machines Corp.</font>
12 :     <table border="0" cellpadding="2" cellspacing="0" width="100%">
13 : sxenos 1.1 <tbody>
14 :     <tr>
15 :     <td colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font
16 : sxenos 1.4 face="Arial,Helvetica"><font color="#ffffff">&nbsp;Eclipse Corner
17 :     Article</font></font></b></td>
18 : sxenos 1.1 </tr>
19 :     </tbody>
20 :     </table>
21 :     </div>
22 : sxenos 1.4 <div align="left">
23 :     <h1><a class="mozTocH1" name="mozTocId282580"></a><img
24 :     src="images/Idea.jpg" align="middle" height="86" width="120"></h1>
25 :     </div>
26 :     <p>&nbsp;</p>
27 :     <h1 align="center"><a class="mozTocH1" name="mozTocId119947"></a>Inside
28 :     the
29 : sxenos 1.1 Workbench<br>
30 :     A guide to the workbench internals<br>
31 : sxenos 1.4 </h1>
32 :     <blockquote>
33 :     <b>Summary</b>
34 :     <br>
35 :     This document describes how the Eclipse 3.1 workbench works. It
36 :     describes the infrastructure that makes views and editors work. The
37 : sxenos 1.1 goal is to make the reader familiar with important classes in the
38 :     workbench, and how they interact. It is assumed that the reader is
39 : sxenos 1.3 already familiar with using the workbench APIs and with creating views,
40 : sxenos 1.4 editors, action sets, etc.
41 :     <p><b>Stefan Xenos, IBM</b> <br>
42 :     <font size="-1">July 12, 2005</font> </p>
43 :     </blockquote>
44 : sxenos 1.1 <br>
45 :     <hr style="width: 100%; height: 2px;">
46 : sxenos 1.4 <h1><a class="mozTocH1" name="mozTocId744856"></a>Table of Contents</h1>
47 : sxenos 1.1 <ul id="mozToc">
48 : sxenos 1.4 <!--mozToc h2 1 h3 2 h4 3 h5 4 h6 5--><li><a href="#mozTocId917303">1.0
49 :     Introduction
50 :     </a></li>
51 :     <li><a href="#mozTocId270357">2.0 Inside a part
52 :     </a>
53 : sxenos 1.1 <ul>
54 : sxenos 1.4 <li><a href="#mozTocId713423">2.1 Part Lifecycle
55 :     </a></li>
56 :     <li><a href="#mozTocId789670">2.2 Part Construction</a></li>
57 : sxenos 1.1 </ul>
58 :     </li>
59 : sxenos 1.4 <li><a href="#mozTocId409413">3.0 Workbench Layout
60 :     </a>
61 : sxenos 1.1 <ul>
62 : sxenos 1.4 <li><a href="#mozTocId95893">3.1 An example layout</a></li>
63 :     <li><a href="#mozTocId114962">3.2 Zoom / Unzoom
64 :     protocol
65 :     </a></li>
66 :     <li><a href="#mozTocId977378">3.3 Layout protocol
67 :     </a></li>
68 :     <li><a href="#mozTocId162591">3.4 PartStack:
69 :     Communicating with the Presentation API
70 :     </a></li>
71 :     <li><a href="#mozTocId479574">3.5
72 :     PartSashContainer: The main workbench layout </a></li>
73 :     <li><a href="#mozTocId887241">3.6 Drag / Drop</a></li>
74 : sxenos 1.1 </ul>
75 :     </li>
76 : sxenos 1.4 <li><a href="#mozTocId443855">3.0 Action Bars</a>
77 : sxenos 1.1 <ul>
78 : sxenos 1.4 <li><a href="#mozTocId652269">3.1 Editor Action Bars
79 :     </a></li>
80 :     <li><a href="#mozTocId340925">3.2 Action Sets
81 :     </a></li>
82 :     <li><a href="#mozTocId277128">3.3 View Actions</a></li>
83 : sxenos 1.1 </ul>
84 :     </li>
85 : sxenos 1.4 <li><a href="#mozTocId642161">4.0 General
86 :     Conventions</a>
87 : sxenos 1.1 <ul>
88 : sxenos 1.4 <li><a href="#mozTocId892615">4.1 Objects must not
89 :     be returned through API until they are fully initialized</a></li>
90 :     <li><a href="#mozTocId308622">4.2 No method may
91 :     open a modal dialog unless its JavaDoc says so</a></li>
92 :     <li><a href="#mozTocId753192">4.3 Lazy creation
93 :     should happen as late as possible
94 :     </a></li>
95 :     <li><a href="#mozTocId921869">4.4 getters should
96 :     not modify the thing they are supposed to measure
97 :     </a></li>
98 : sxenos 1.1 </ul>
99 :     </li>
100 :     </ul>
101 : sxenos 1.4 <br>
102 : sxenos 1.1 <div style="margin-left: 40px;"><span style="font-weight: bold;"></span></div>
103 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId917303"></a><span
104 : sxenos 1.1 style="font-weight: bold;"></span><span style="font-weight: bold;">1.0
105 :     Introduction</span>
106 :     <br>
107 : sxenos 1.4 </h2>
108 : sxenos 1.3 <span style="font-weight: bold;"></span> This document describes
109 :     workbench internals and not API. The design of internals changes
110 :     frequently. For information on newer Eclipse versions, the latest
111 :     version of this document can be found on the <a
112 :     href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-ui-home/dev.html">UI
113 :     development resources page</a>.<br>
114 :     <br>
115 : sxenos 1.1 <br>
116 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
117 : sxenos 1.4 1: Ownership of views and editors<br>
118 : sxenos 1.1 <br>
119 :     </span></div>
120 :     <div style="text-align: center;"><img alt=""
121 :     src="workbench_high_level.PNG" style="width: 600px; height: 340px;"><br>
122 :     </div>
123 :     <br>
124 : sxenos 1.4 Figure 1 shows how views and editors are owned by the workbench.<br>
125 : sxenos 1.1 <br>
126 :     The Workbench contains one or more WorkbenchWindows, each of which
127 :     contain zero or more WorkbenchPages. The WorkbenchWindow supplies the
128 :     trim widgets, and the WorkbenchPage supplies the window
129 :     contents. In theory, a WorkbenchWindow can contain any number of pages,
130 :     but in practice there is never more than 1 page in a window.<br>
131 :     <br>
132 :     Views and editors are owned by the page, through a ViewFactory and
133 :     EditorManager respectively. EditorManager stores the list of editors
134 :     and their shared
135 :     resources, and ViewFactory stores a reference counted list of views.
136 :     The workbench works in terms of EditorReferences and ViewReferences,
137 :     and in this article the terms "editor" or "view" will refer to these
138 :     classes specifically. In situations where the distinction between
139 :     editors and views is not important, we will simply use the term "part".
140 :     The implementation of the part (typically an IEditorPart or IViewPart)
141 : sxenos 1.4 is created lazily when it is first needed. As shown in Figure 2, a
142 : sxenos 1.1 part reference exists for every tab but the implementation is only
143 :     created the first time it becomes visible.<br>
144 :     <br>
145 :     The page owns a set of perspectives. Perspectives contain a layout and
146 :     information about what action sets to enable. Although perspectives
147 :     appear to contain views and the editor area, they only own a layout.
148 :     The page itself maintains a reference count for how many perspectives
149 :     are using each view, and has complete ownership of the parts and editor
150 :     area.<br>
151 :     <br>
152 :     Not shown in figure 1 are the classes PerspectiveHelper and
153 :     EditorAreaHelper. These classes exist largely for historic purposes,
154 :     and in this article we will treat the former as though it were part of
155 :     the Perspective class and the latter as part of the WorkbenchPage class.<br>
156 :     <br>
157 :     <br>
158 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
159 : sxenos 1.4 2: Workbench objects and what they look like<br>
160 : sxenos 1.1 <br>
161 :     </span></div>
162 :     <div style="text-align: center;"><img alt="" src="what_you_see.PNG"
163 :     style="width: 892px; height: 700px;"><br>
164 :     </div>
165 :     <br>
166 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId270357"></a>2.0 Inside a part<br>
167 :     </h2>
168 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">
169 : sxenos 1.4 Figure 3: Anatomy of a part</span><br>
170 : sxenos 1.1 </div>
171 :     <div style="text-align: center;"><img alt="" src="anatomy_of_a_part.PNG"
172 :     style="width: 420px; height: 280px;"><br>
173 :     </div>
174 : sxenos 1.4 Internally, a part consists of several objects (Figure 3).
175 : sxenos 1.1 WorkbenchPartReference is the topmost representation of the part.
176 :     Depending on where it is used, the part reference is often exposed as
177 :     IWorkbenchPartReference, IViewReference, IEditorRefenece, or
178 :     IPresentablePart, or PartPane. These are essentially different
179 :     interfaces to the same object. The I*Reference interfaces are
180 :     implemented directly by WorkbenchPartReference and its subclasses.
181 :     IPresentablePart is a simple adapter that redirects its methods
182 :     directly to the part. PartPane implements the LayoutPart protocol which
183 :     is needed to insert the part into the workbench layout. PartPane also
184 :     manages the SWT resources (such as a top-level control) that are needed
185 :     to include the control in the workbench layout.<br>
186 :     <br>
187 :     The part implementation (the IEditorPart or IViewPart) is owned by the
188 :     reference. When the
189 :     implementation is created, it is given a PartSite. The PartSite (seen
190 :     by client code as an IWorkbenchPartSite, IEditorSite, or IViewSite)
191 :     allows the client code to communicate with the reference and manages
192 :     services created for the implementation.<br>
193 :     <br>
194 : sxenos 1.3 WorkbenchPartReferences allocates SWT resources lazily as needed.
195 : sxenos 1.1 Once created, the part reference must be explicitly disposed. Disposing
196 :     the reference cleans up all of its resources (including the part
197 :     implementation itself) and guarantees that the reference will never
198 :     allocate additional resources. The workbench page disposes the part
199 :     reference once it is certain that it will never need to use that part
200 :     again. Unlike SWT controls, it is valid to continue using the reference
201 :     after it has been disposed. A disposed part reference is unlikely to do
202 :     anything interesting besides returning its name and cannot be used with
203 :     any
204 :     methods in the workbench page. Since it is hard (or impossible) for
205 :     clients to track the lifecycle of the reference, they are permitted to
206 :     continue using its public interface after disposal.<br>
207 :     <br>
208 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId713423"></a>2.1 Part Lifecycle<br>
209 :     </h3>
210 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">Figure
211 : sxenos 1.4 4: WorkbenchPartReference states<br>
212 : sxenos 1.1 <br>
213 :     </span></div>
214 :     <div style="text-align: center;"><img alt="" src="part_states.PNG"
215 :     style="width: 445px; height: 590px;"><br>
216 :     </div>
217 : sxenos 1.4 Figure 4 shows the part lifecycle as a state machine. The part
218 : sxenos 1.1 reference stores its current state in the integer state field.<br>
219 :     <br>
220 :     Notes:<br>
221 :     <ul>
222 :     <li>The part is in a distinct state while it is in the process of
223 :     creating the implementation. It cannot be recursively re-created or
224 :     disposed while it is in this state.</li>
225 :     <li>The part implementation cannot be recreated once the reference
226 :     has been disposed.</li>
227 :     <li>Parts cannot return to the lazy state once they have been
228 :     created. This is a limitation in the 3.1 implementation, not a
229 :     functional requirement.</li>
230 :     <li>It is valid to continue using the public interface of
231 :     WorkbenchPartReference once it has been disposed, however a disposed
232 :     reference cannot be passed to methods in workbench page (since it is,
233 :     by definition, no longer part of any page).</li>
234 :     </ul>
235 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId789670"></a>2.2 Part Construction</h3>
236 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">Figure
237 : sxenos 1.4 5: Message sequence for creating a part<br>
238 : sxenos 1.1 <br>
239 :     </span></div>
240 :     <div style="text-align: center;"><img alt="" src="part_creation_msc.PNG"
241 :     style="width: 892px; height: 700px;"><br>
242 :     </div>
243 :     <br>
244 : sxenos 1.4 Figure 5 shows the process for creating a part. The horizontal
245 : sxenos 1.1 line separates the two phases of creating a part. First the part is
246 :     added to the layout, and then a real implementation is attached. These
247 :     are two distinct operations, and the part can exist as a tab in the
248 :     page with no implementation for some time before it becomes visible.
249 :     This diagram focuses on the interactions with the part reference, and
250 :     skips the details of adding the part to the presentation and creating
251 :     the part site.<br>
252 :     <br>
253 : sxenos 1.4 Suggestion: there are situations where it would be useful to only
254 : sxenos 1.1 add the part to the layout if it can be created successfully (this
255 :     would be necessary to pass a PartInitException thrown in the
256 :     implementation's init method up through IWorkbenchPage.openEditor). In
257 :     these situations, it would be possible to merge both operations into
258 :     one atomic operation by creating the part before adding it to the
259 :     layout. It is unknown if this would create event ordering bugs in
260 :     client code.<br>
261 :     <br>
262 :     <span style="font-weight: bold;"></span>
263 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId409413"></a>3.0 Workbench Layout<br>
264 :     </h2>
265 : sxenos 1.1 <br>
266 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
267 : sxenos 1.4 6: LayoutPart hierarchy</span><br>
268 : sxenos 1.1 <img alt="" src="LayoutPart_hierarchy.PNG"
269 :     style="width: 302px; height: 412px;"><br>
270 :     </div>
271 :     <br>
272 :     The workbench layout provides supports arranging parts using drag &amp;
273 :     drop, resizing and detaching parts, fast views, etc. This section gives
274 :     a quick overview of the layout mechanism.<br>
275 :     <br>
276 :     Anything in the workbench layout is a LayoutPart. A LayoutPart manages
277 :     a set of widgets in a rectangular region of the screen, can contain or
278 :     arrange other layout parts, returns size constraints, responds to drag
279 :     events, etc. To this extent, a LayoutPart is very similar to a custom
280 :     SWT Control. However, LayoutPart differs from Control in several
281 :     important ways.<br>
282 :     <ul>
283 :     <li>The LayoutPart hierarchy is not the same as the widget hierarchy.
284 :     Even though one LayoutPart may contain another, their widgets may be
285 :     peers. This allows drag and drop to work on platforms where SWT doesn't
286 :     support reparenting, since a LayoutPart can be reparented without
287 :     reparenting its widgets.<br>
288 :     </li>
289 :     <li>LayoutParts mainly perform layout-related tasks, unlike Controls
290 :     which also supply behavior and appearance. The behavior of a LayoutPart
291 :     is supplied by the widgets it arranges.<br>
292 :     </li>
293 :     <li>LayoutParts know about higher-level concepts like zoom, and can
294 :     specify constraints about their own size.<br>
295 :     </li>
296 :     </ul>
297 : sxenos 1.4 Figure 6 shows the LayoutPart hierarchy. Notice the symmetry
298 : sxenos 1.1 between the View* classes and the Editor* classes. These classes exist
299 :     largely for historical reasons, and it should be possible to move all
300 :     of the functionality into the Part* base classes or other objects in
301 :     the system. Since all of the interesting behavior comes from the Part*
302 :     classes, the remainder of this section will focus on them without
303 :     describing the minor differences between views and editors.<br>
304 :     <br>
305 :     PartSashContainer arranges a set of child parts separated by a bunch of
306 :     sashes. This is the object that implements the most visible aspects of
307 :     the workbench layout. It arranges rectangular regions separated by
308 :     sashes, and allows new regions to be created by splitting old ones. It
309 :     also supports the size constraints that make minimized views possible,
310 :     and determines what it means for one of these regions to be maximized.
311 :     Typically, a PartSashContainer contains a bunch of PartStacks, although
312 :     it is also possible for it to contain another PartSashContainer. The
313 :     latter case occurs since the editor area and the perspective both use a
314 :     PartSashContainer for their layout and one is embedded inside the
315 :     other. PartSashContainer owns its stacks but does not own an embedded
316 :     PartSashContainer. In a workbench window, there is one
317 :     PartSashContainer for each perspective and one for the editor area
318 :     itself.<br>
319 :     <br>
320 :     PartStack arranges a stack of PartPanes. PartStack allows the
321 :     presentation API to participate in the workbench layout. The code for
322 :     creating the tabs and arranging parts is supplied by the active
323 :     presentation.<br>
324 :     <br>
325 :     PartPane allows views and editors to participate in the workbench
326 :     layout. Although PartPanes are arranged by PartStacks they belong to
327 :     part reference, not the stack. The same PartPane can exist in more than
328 :     one PartStack at a time if that part appears in more that one
329 :     perspective.<span style="font-weight: bold;"><br>
330 :     <br>
331 :     </span>
332 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId95893"></a>3.1 An example layout</h3>
333 : sxenos 1.1 LayoutParts are best explained through example. Imagine a
334 :     WorkbenchWindow that contains custom Java and Java Browsing
335 : sxenos 1.4 perspectives that look like Figure 7 and Figure 8
336 : sxenos 1.1 respectively.<br>
337 :     <br>
338 :     <br>
339 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
340 : sxenos 1.4 7: Example Java Perspective</span><br>
341 : sxenos 1.1 <img alt="" src="perspective1.PNG" style="width: 571px; height: 495px;"><br>
342 :     <br>
343 : sxenos 1.4 <span style="font-weight: bold;">Figure 8: Example Java Browsing
344 : sxenos 1.1 perspective</span><br>
345 :     <img alt="" src="perspective2.PNG" style="width: 571px; height: 495px;"><br>
346 :     </div>
347 :     <br>
348 : sxenos 1.4 <br>
349 :     Assume that the window resembles Figure 7. In this case, the Java
350 : sxenos 1.1 perspective is active, the Java Browsing perspective is hidden, and the
351 : sxenos 1.4 objects are connected as shown in Figure 9:<br>
352 :     <br>
353 : sxenos 1.1 <br>
354 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
355 : sxenos 1.4 9: LayoutPart instances when two perspectives are open</span><br>
356 : sxenos 1.1 <img alt="" src="perspective1_2_instances.PNG"
357 :     style="width: 555px; height: 670px;"><br>
358 :     <div style="text-align: left;"><br>
359 :     </div>
360 :     </div>
361 :     <br>
362 : sxenos 1.2 <br>
363 :     All LayoutParts have a container pointer that points to the object that
364 :     is currently managing their position. Since the same LayoutPart
365 :     instance may exist in more than one perspective at once, this pointer
366 :     points to the part's container in the currently-active perspective. In
367 :     the case of the projects view, above, the part is not in the current
368 :     perspective so its container pointer is null. When another
369 :     perspective becomes active, all the container pointers move to the new
370 :     perspective. For historical reasons, this is accomplished by setting
371 :     and
372 :     clearing the contianer pointer when the container becomes visible or
373 :     invisible. This works since only one perspective is visible at a time,
374 :     but it also means that perspectives cannot be manipulated when they are
375 :     invisible.<br>
376 : sxenos 1.1 <br>
377 :     The diagram shows the internal objects that make up the only editor.
378 :     Although this detail has been omitted for the views, they would look
379 :     similar. Each view's PartPane is owned by a part reference which may
380 : sxenos 1.2 have an associated part implementation.<br>
381 : sxenos 1.1 <br>
382 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId114962"></a>3.2 Zoom / Unzoom
383 : sxenos 1.1 protocol<br>
384 : sxenos 1.4 </h3>
385 : sxenos 1.1 The notion of "zoom" is defined locally between a part and its
386 :     immediate container. Zoom changes are triggered bottom-up. A part asks
387 :     its parent to "zoom me", and the parent either does something with the
388 :     request or forwards the request up to its parent. Each container
389 :     determines what it means for a child to be zoomed. Once a part's zoom
390 :     state changes, its parent notifies it by calling setZoomed. The part
391 :     may in turn zoom or unzoom one or more of its children.<br>
392 :     <br>
393 :     Anything that can contain LayoutParts must implement the following
394 : sxenos 1.4 methods, to support zooming:<br>
395 :     <span style="font-family: monospace;"><br>
396 : sxenos 1.1 </span><code>&nbsp;&nbsp;&nbsp; /**<br>
397 :     &nbsp;&nbsp;&nbsp;&nbsp; * Called by child parts to request a zoom in,
398 :     given an immediate child <br>
399 :     &nbsp;&nbsp;&nbsp;&nbsp; * <br>
400 :     &nbsp;&nbsp;&nbsp;&nbsp; * @param toZoom part to zoom in on<br>
401 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
402 :     &nbsp;&nbsp;&nbsp; public void childRequestZoomIn(LayoutPart toZoom);<br>
403 :     &nbsp;&nbsp;&nbsp; <br>
404 :     &nbsp;&nbsp;&nbsp; /**<br>
405 :     &nbsp;&nbsp;&nbsp;&nbsp; * Called by child parts to request a zoom out<br>
406 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
407 :     &nbsp;&nbsp;&nbsp; public void childRequestZoomOut();<br>
408 :     &nbsp;&nbsp;&nbsp; <br>
409 :     &nbsp;&nbsp;&nbsp; /**<br>
410 :     &nbsp;&nbsp;&nbsp;&nbsp; * Returns true iff the given child is obscured
411 :     due to the fact that the container is zoomed into<br>
412 :     &nbsp;&nbsp;&nbsp;&nbsp; * another part. <br>
413 :     &nbsp;&nbsp;&nbsp;&nbsp; * <br>
414 :     &nbsp;&nbsp;&nbsp;&nbsp; * @param toTest part to test<br>
415 :     &nbsp;&nbsp;&nbsp;&nbsp; * @return true iff the part is currently
416 :     obscured <br>
417 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
418 :     &nbsp;&nbsp;&nbsp; public boolean childObscuredByZoom(LayoutPart
419 :     toTest);<br>
420 :     &nbsp;&nbsp;&nbsp; <br>
421 :     &nbsp;&nbsp;&nbsp; /**<br>
422 :     &nbsp;&nbsp;&nbsp;&nbsp; * Returns true iff we are zoomed into the
423 :     given part, given an immediate child of this container.<br>
424 :     &nbsp;&nbsp;&nbsp;&nbsp; * <br>
425 :     &nbsp;&nbsp;&nbsp;&nbsp; * @param toTest part to test<br>
426 :     &nbsp;&nbsp;&nbsp;&nbsp; * @return true iff this contianer is currently
427 :     zooming in on the given part<br>
428 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
429 :     &nbsp;&nbsp;&nbsp; public boolean childIsZoomed(LayoutPart toTest);<br>
430 : sxenos 1.4 <br>
431 : sxenos 1.1 </code><br>
432 : sxenos 1.4 Consider again Figure 7. If we were to double-click on the java
433 : sxenos 1.1 editor to zoom it, the LayoutParts would send messages to one another
434 :     in the following sequence. (In this diagram, each cell represents a
435 :     method call. Each column is an object. The reciever's column shows the
436 :     method name and the caller contains an arrow. Rows are in ascending
437 :     order of time.)<br>
438 :     <br>
439 :     <table style="width: 100%; text-align: left;" border="1" cellpadding="2"
440 :     cellspacing="2">
441 :     <tbody>
442 :     <tr>
443 :     <td style="vertical-align: top; font-weight: bold;">Java Editor
444 :     (PartPane)<br>
445 :     </td>
446 :     <td style="vertical-align: top; font-weight: bold;">PartStack<br>
447 :     </td>
448 :     <td style="vertical-align: top; font-weight: bold;">editor area
449 :     (EditorSashContainer)<br>
450 :     </td>
451 :     <td style="vertical-align: top; font-weight: bold;">ViewSashContainer<br>
452 :     </td>
453 :     </tr>
454 :     <tr>
455 :     <td style="vertical-align: top;">requestZoomIn<br>
456 :     </td>
457 :     <td style="vertical-align: top;"><br>
458 :     </td>
459 :     <td style="vertical-align: top;"><br>
460 :     </td>
461 :     <td style="vertical-align: top;"><br>
462 :     </td>
463 :     </tr>
464 :     <tr>
465 :     <td style="vertical-align: top;"><img alt="" src="right_arrow.PNG"
466 :     style="width: 42px; height: 17px;"><br>
467 :     </td>
468 :     <td style="vertical-align: top;">childRequestZoomIn(java editor)<br>
469 :     </td>
470 :     <td style="vertical-align: top;"><br>
471 :     </td>
472 :     <td style="vertical-align: top;"><br>
473 :     </td>
474 :     </tr>
475 :     <tr>
476 :     <td style="vertical-align: top;"><br>
477 :     </td>
478 :     <td style="vertical-align: top;"><img alt="" src="right_arrow.PNG"
479 :     style="width: 42px; height: 17px;"><br>
480 :     </td>
481 :     <td style="vertical-align: top;">childRequestZoomIn(java editor's
482 :     part stack)<br>
483 :     </td>
484 :     <td style="vertical-align: top;"><br>
485 :     </td>
486 :     </tr>
487 :     <tr>
488 :     <td style="vertical-align: top;"><br>
489 :     </td>
490 :     <td style="vertical-align: top;"><br>
491 :     </td>
492 :     <td style="vertical-align: top;">if there were other editor
493 :     stacks in the layout, we would call setVisible(false) on them here</td>
494 :     <td style="vertical-align: top;"><br>
495 :     </td>
496 :     </tr>
497 :     <tr>
498 :     <td style="vertical-align: top;"><br>
499 :     </td>
500 :     <td style="vertical-align: top;"><br>
501 :     </td>
502 :     <td style="vertical-align: top;">remember the partStack as the
503 :     zoomed part<br>
504 :     </td>
505 :     <td style="vertical-align: top;"><br>
506 :     </td>
507 :     </tr>
508 :     <tr>
509 :     <td style="vertical-align: top;"><br>
510 :     </td>
511 :     <td style="vertical-align: top;">setZoomed(true)<br>
512 :     </td>
513 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
514 :     style="width: 42px; height: 17px;"><br>
515 :     </td>
516 :     <td style="vertical-align: top;"><br>
517 :     </td>
518 :     </tr>
519 :     <tr>
520 :     <td style="vertical-align: top;">setZoomed(true)<br>
521 :     </td>
522 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
523 :     style="width: 42px; height: 17px;"><br>
524 :     </td>
525 :     <td style="vertical-align: top;"><br>
526 :     </td>
527 :     <td style="vertical-align: top;"><br>
528 :     </td>
529 :     </tr>
530 :     <tr>
531 :     <td style="vertical-align: top;"><br>
532 :     </td>
533 :     <td style="vertical-align: top;"><br>
534 :     </td>
535 :     <td style="vertical-align: top;"><img alt="" src="right_arrow.PNG"
536 :     style="width: 42px; height: 17px;"><br>
537 :     </td>
538 :     <td style="vertical-align: top;">childRequestZoomIn(editor area)<br>
539 :     </td>
540 :     </tr>
541 :     <tr>
542 :     <td style="vertical-align: top;"><br>
543 :     </td>
544 :     <td style="vertical-align: top;"><br>
545 :     </td>
546 :     <td style="vertical-align: top;"><br>
547 :     </td>
548 :     <td style="vertical-align: top;">call setVisible(false) on all
549 :     PartStacks for views in the perspective<br>
550 :     </td>
551 :     </tr>
552 :     <tr>
553 :     <td style="vertical-align: top;"><br>
554 :     </td>
555 :     <td style="vertical-align: top;"><br>
556 :     </td>
557 :     <td style="vertical-align: top;"><br>
558 :     </td>
559 :     <td style="vertical-align: top;">remember the editor area as the
560 :     zoomed part<br>
561 :     </td>
562 :     </tr>
563 :     <tr>
564 :     <td style="vertical-align: top;"><br>
565 :     </td>
566 :     <td style="vertical-align: top;"><br>
567 :     </td>
568 :     <td style="vertical-align: top;">setZoomed(true)<br>
569 :     </td>
570 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
571 :     style="width: 42px; height: 17px;"></td>
572 :     </tr>
573 :     <tr>
574 :     <td style="vertical-align: top;"><br>
575 :     </td>
576 :     <td style="vertical-align: top;"><br>
577 :     </td>
578 :     <td style="vertical-align: top;"><br>
579 :     </td>
580 :     <td style="vertical-align: top;">trigger a layout<br>
581 :     </td>
582 :     </tr>
583 :     <tr>
584 :     <td style="vertical-align: top;"><br>
585 :     </td>
586 :     <td style="vertical-align: top;"><br>
587 :     </td>
588 :     <td style="vertical-align: top;">setBounds(zoomed bounds)<br>
589 :     </td>
590 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
591 :     style="width: 42px; height: 17px;"></td>
592 :     </tr>
593 :     <tr>
594 :     <td style="vertical-align: top;"><br>
595 :     </td>
596 :     <td style="vertical-align: top;">setBounds(zoomed bounds)</td>
597 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
598 :     style="width: 42px; height: 17px;"></td>
599 :     <td style="vertical-align: top;"><br>
600 :     </td>
601 :     </tr>
602 :     <tr>
603 :     <td style="vertical-align: top;">setBounds(zoomed bounds)</td>
604 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
605 :     style="width: 42px; height: 17px;"></td>
606 :     <td style="vertical-align: top;"><br>
607 :     </td>
608 :     <td style="vertical-align: top;"><br>
609 :     </td>
610 :     </tr>
611 :     <tr>
612 :     <td style="vertical-align: top;"><br>
613 :     </td>
614 :     <td style="vertical-align: top;"><br>
615 :     </td>
616 :     <td style="vertical-align: top;">trigger a layout (nothing to do)<br>
617 :     </td>
618 :     <td style="vertical-align: top;"><br>
619 :     </td>
620 :     </tr>
621 :     </tbody>
622 :     </table>
623 :     <br>
624 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId977378"></a>3.3 Layout protocol<br>
625 :     </h3>
626 : sxenos 1.1 Every LayoutPart can specify constraints on their size. Parts specify
627 :     constraints by implementing the ISizeProvider interface. ISizeProvider
628 :     serves a similar function as the computeSize method on an SWT control,
629 :     in that the parent layout uses it to consult with the part when
630 :     computing the part's size. ISizeProvider can provide a variety of
631 :     constraints:<br>
632 :     <br>
633 :     <table style="width: 100%; text-align: left;" border="1" cellpadding="2"
634 :     cellspacing="2">
635 :     <tbody>
636 :     <tr>
637 :     <td style="vertical-align: top; font-weight: bold;">Constraint
638 :     type<br>
639 :     </td>
640 :     <td style="vertical-align: top; font-weight: bold;">Meaning<br>
641 :     </td>
642 :     </tr>
643 :     <tr>
644 :     <td style="vertical-align: top;">Minimum size<br>
645 :     </td>
646 :     <td style="vertical-align: top;">Given the available space along
647 :     one dimension, the part returns the minimum size that it can be
648 :     compressed to along the other dimension. For example, a stack would
649 :     typically set its minimum size to be large enough to fit its tabs. The
650 :     information about available perpendicular space could allow a stack to
651 :     have wrapping tabs and still reserve enough vertical space for the tabs
652 :     once they are wrapped to fill the available horizontal space.<br>
653 :     </td>
654 :     </tr>
655 :     <tr>
656 :     <td style="vertical-align: top;">Maximum size<br>
657 :     </td>
658 :     <td style="vertical-align: top;">Given the available space along
659 :     one dimension, the part returns the maximum size that it can utilize
660 :     along the other dimension. For example, minimized stacks are
661 :     implemented by setting their maximum size to the minimized size.
662 :     Non-minimized stacks typically have an unbounded maximum size.<br>
663 :     </td>
664 :     </tr>
665 :     <tr>
666 :     <td style="vertical-align: top;">Preferred size<br>
667 :     </td>
668 :     <td style="vertical-align: top;">Given the availble space along
669 :     one dimension and a preferred size, this returns the size closest to
670 :     the preferred size at which the part would look best. Parts can use
671 :     this to quantize their size. For example, a part can ensure that its
672 :     size is always chosen such that it can be completely filled with
673 :     toolbar icons leaving no space left over.<br>
674 :     </td>
675 :     </tr>
676 :     </tbody>
677 :     </table>
678 :     <br>
679 :     Although there are three kinds of constraints, they are all returned
680 :     using a single method. See the JavaDoc on ISizeProvider for more
681 :     information.<br>
682 :     <br>
683 :     Whenever a size constraint changes, the part notifies its contianer by
684 :     calling resizeChild(part). This tells the container to respond to the
685 : sxenos 1.4 new constraints, and to resize the child if necessary (suggestion:
686 : sxenos 1.1 if this is ever exposed as API, it would be better to separate the
687 :     concerns of notifying the parent of changes and triggering a layout. In
688 :     general, it may be possible for more than one part to change without
689 :     requiring a layout between each change).<br>
690 :     <br>
691 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId162591"></a>3.4 PartStack:
692 : sxenos 1.1 Communicating with the Presentation API<br>
693 : sxenos 1.4 </h3>
694 : sxenos 1.1 PartStack allows presentation to participate in the workbench layout.
695 : sxenos 1.4 As shown in Figure 10, it wraps a single instance of
696 : sxenos 1.1 StackPresentation, and allows it the presentation to manipulate parts
697 :     by converting each visible part into an IPresentablePart. The part
698 :     stack outlives the StackPresentation. Whenever the part stack needs
699 :     widgets, it creates the StackPresentation. If the widgets are no longer
700 :     needed, it disposes the StackPresentation and remembers its persisted
701 :     form. Whenever the PartStack persists its StackPresenation, it
702 :     remembers the presentation ID so that it will not try to restore one
703 :     StackPresentation from state saved by an incompatible presentation.<br>
704 :     <br>
705 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
706 : sxenos 1.4 10: Anatomy of PartStack</span><br>
707 : sxenos 1.1 <img alt="" src="PartStack.PNG" style="width: 430px; height: 225px;"><br>
708 :     <div style="text-align: left;"><br>
709 : sxenos 1.4 Suggestion: it would be useful to update this document with a state
710 : sxenos 1.1 diagram for PartStack, and message sequence charts for initializaiton
711 :     and part activation.<br>
712 :     <br>
713 :     </div>
714 :     </div>
715 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId479574"></a>3.5
716 : sxenos 1.1 PartSashContainer: The main workbench layout <br>
717 : sxenos 1.4 </h3>
718 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">Figure
719 : sxenos 1.4 11: PartSashContainer</span><br>
720 : sxenos 1.1 <img alt="" src="PartSashContainer.PNG"
721 :     style="width: 428px; height: 305px;"><br>
722 :     </div>
723 :     <br>
724 :     PartSashContainer implements the main layout for a perspective and the
725 : sxenos 1.4 editor area. As shown in Figure 11, PartSashContainer contains a
726 : sxenos 1.1 list of children, a (possibly null) zoomed part, and a LayoutTree that
727 :     manages the actual layout. <br>
728 :     <br>
729 :     LayoutTree is a binary tree (technically, a KD tree). Each internal
730 :     node is an instance of LayoutTreeNode. It contains a draggable sash
731 :     (LayoutPartSash) that divides its area among its left and right
732 :     children. LayoutTreeNodes can be horizontal or vertical based on the
733 :     orientation of the sash. For horizontal nodes, the "left" child is on
734 :     top and the "right" child is on the bottom. Leaf nodes are instances of
735 :     LayoutTree (the base class), and they point to a LayoutPart that
736 :     occupies that region of the screen. Normally, this is a PartStack, but
737 :     in general it can be any LayoutPart. <br>
738 :     <br>
739 :     Each LayoutTree occupies a recangular region of the screen that
740 :     encompasses its children. Internal nodes keep track of an integer size
741 :     for each child (implementation note: the sizes are stored in the
742 :     associated LayoutPartSash, not the LayoutTreeNode itself). Normally,
743 :     the left and right sizes are used as a ratio for dividing up the
744 :     available space. However, when one child contains the editor area, the
745 :     other becomes "non-compressible". If one side in non-compressible, the
746 :     size value is interpreted as a fixed pixel size rather than a ratio.
747 :     When the sash is moved, the size values are set to the current pixel
748 :     sizes of the left and right children.<br>
749 :     <br>
750 : sxenos 1.4 Figure 12 shows an example LayoutTree. If this tree were rendered
751 : sxenos 1.1 in a workbench window, it would resemble Figure 3.5.3. The tall
752 :     vertical sash separating the package explorer from the editor area is
753 :     the root node. The left child is the leaf node holding the package
754 :     explorer's stack. The right node is the horizontal sash separating the
755 :     problems view from the editor area. The editor area itself is a
756 :     PartSashContainer, which has its own LayoutTree. Note that the rounded
757 :     rectangles in Figure 3.5.2 are LayoutParts. The upper portion of the
758 :     rectangle is the part type and the lower portion is some text to help
759 :     locate the part in the screenshot. In this example, every internal node
760 :     has the editor area on one side of it, so all sizes are interpreted as
761 :     pixel sizes and not ratios.<br>
762 :     <div style="text-align: center;"><span style="font-weight: bold;"></span><br>
763 : sxenos 1.4 <span style="font-weight: bold;">Figure 12: Example LayoutTree</span><br
764 : sxenos 1.1 style="font-weight: bold;">
765 :     <img alt="" src="example_LayoutTree.PNG"
766 :     style="width: 480px; height: 462px; font-weight: bold;"><br>
767 :     <span style="font-weight: bold;"><br>
768 : sxenos 1.4 Figure 13: Example perspective</span><br style="font-weight: bold;">
769 : sxenos 1.1 <img alt="" src="perspective1.PNG"
770 :     style="width: 571px; height: 495px; font-weight: bold;"><br>
771 :     </div>
772 :     <br>
773 :     Like LayoutParts, LayoutTrees also implement ISizeProvider and support
774 :     size constraints. For external nodes, the size constraints come
775 :     directly from the LayoutPart. For internal nodes, the size constraints
776 :     are computed from the child nodes as follows:<br>
777 :     <ol>
778 :     <li>When computing a constraint perpendicular to the sash, the result
779 :     is the sum of the constraints of the children plus the width of the
780 :     sash.</li>
781 :     <li>When computing a constraint parallel to the sash, the result is
782 :     the maximum of the constraints of the children<br>
783 :     </li>
784 :     </ol>
785 :     An example can help make this a little less abstract. Imagine we're
786 : sxenos 1.4 computing the minimum width for the root node in Figure 12, which
787 : sxenos 1.1 is a tall vertical sash. Width measurements are perpendicular to the
788 :     sash, so we end up with case 1. The minimum width is the minimum width
789 :     of the left stack plus the sash width plus the minimum width of the
790 :     right child. This makes sense because if we made the root node any
791 :     smaller, one of the three would need to be truncated or made smaller
792 :     than their minimum size.<br>
793 :     <br>
794 :     The "right child" mentioned above is the horizontal sash separating the
795 :     problems view from the editor area. When computing its minimum width,
796 :     we hit case 2: the minimum width of a horizantal sash is the maximum of
797 :     the minimum widths of each child. Intuitively, this means that the
798 :     child with the larger minimum size will be the first to reach its
799 :     minimum when the layout gets small.<br>
800 :     <br>
801 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId887241"></a>3.6 Drag / Drop</h3>
802 : sxenos 1.1 <div style="text-align: center;"><span style="font-weight: bold;">Figure
803 : sxenos 1.4 14: LayoutPart drop regions</span><br>
804 : sxenos 1.1 </div>
805 :     <div style="text-align: center;"><img alt="" src="drag_regions.PNG"
806 :     style="width: 571px; height: 495px;"><br>
807 :     <div style="text-align: left;"><br>
808 :     Dragging a workbench part is triggered by calling DragUtil.performDrag.
809 :     SWT controls can respond to drag / drop by registering an
810 :     IDragOverListener with DragUtil .addDragTarget. If multiple drag
811 :     listeners are registered for the same screen position, the one
812 :     associated with the most specific control gets precidence.<br>
813 :     <br>
814 :     Rather than register drag listeners directly, LayoutParts implement a
815 :     getDropTarget method. When the window recieves a drag event, it
816 :     delegates to the top-level LayoutPart's getDropTarget. Each part either
817 :     delegates to one of its children or handles the drag event directly. If
818 :     the part returns null from getDropTarget, this means that the part has
819 :     no special preference for the drop event, and the parent may provide a
820 :     default behavior. Unlike IDragOverListener, getDropTarget works
821 :     top-down. The parent may overload any drag regions that are recognized
822 :     by the child, or provide default behaviors for drag regions not
823 :     recognized by the child.<br>
824 :     <br>
825 : sxenos 1.4 Figure 14 shows regions of the workbench where LayoutParts can be
826 : sxenos 1.1 dropped. The workbench checks these regions in the following order:<br>
827 :     <br>
828 :     <table style="width: 100%; text-align: left;" border="1" cellpadding="2"
829 :     cellspacing="2">
830 :     <tbody>
831 :     <tr>
832 :     <td style="vertical-align: top;"><span
833 :     style="color: rgb(0, 51, 0);">1. green region</span><br>
834 :     </td>
835 :     <td style="vertical-align: top;">The fast view bar registers a
836 :     IDragOverListener that responds to views being dragged.<br>
837 :     </td>
838 :     </tr>
839 :     <tr>
840 :     <td style="vertical-align: top;"><span
841 :     style="background-color: rgb(0, 0, 0);"><span
842 :     style="background-color: rgb(255, 255, 255);">2. black regions</span></span><br>
843 :     </td>
844 :     <td style="vertical-align: top;">These areas are reserved by
845 :     PartSashContainer.getDropTarget. When the user drags a part over this
846 :     region, the PartSashContainer interprets this as a split and does not
847 :     ask its child to participate in the drag. This ensures that it is never
848 :     possible for the child to prevent splitting by reserving its entire
849 :     area as a drop region. The region outside the PartSashContainer's
850 :     client area is handled by an IDragOverListener registered with the
851 :     shell. This allows parts to be attached to the edge of the layout by
852 :     dragging over the window trim.<br>
853 :     </td>
854 :     </tr>
855 :     <tr>
856 :     <td style="vertical-align: top;"><span
857 :     style="color: rgb(255, 0, 0);">3. red regions</span><br>
858 :     </td>
859 :     <td style="vertical-align: top;">For most of the screen area,
860 :     PartSashContainer delegates to its child (PartStack.getDropTarget).
861 :     PartStack filters out objects that don't belong in the stack (no
862 :     editors in view stacks, etc) and delegates to the presentation
863 :     (StackPresentation.dragOver). The default presentation recognizes the
864 :     tabs and title area as drop targets, but returns null everywhere else.
865 :     This is the best practice for presentations and PartStack since it
866 :     permits PartSashContainer to extend the split regions where possible.<br>
867 :     </td>
868 :     </tr>
869 :     <tr>
870 :     <td style="vertical-align: top;"><span
871 :     style="color: rgb(0, 0, 153);">4. blue regions</span><br>
872 :     </td>
873 :     <td style="vertical-align: top;">If the child doesn't have any
874 :     particular use for the drop location, the PartSashContainer extends the
875 :     split regions. If the child allows objects of this type to be added
876 :     (determined by calling LayoutPart.allowsAdd), it uses the center of the
877 :     rectangle for stacking. Otherwise, the entire region is used for
878 :     splitting. The latter case occurs when dragging views over the editor
879 :     area or when dragging over a standalone view.<br>
880 :     </td>
881 :     </tr>
882 :     <tr>
883 :     <td style="vertical-align: top;">5. outside the window (not shown)<br>
884 :     </td>
885 :     <td style="vertical-align: top;">The workbench page registers an
886 :     IDragOverListener that responds to views being dragged outside the
887 :     workbench window, and interprets this as a detach operation.<br>
888 :     </td>
889 :     </tr>
890 :     </tbody>
891 :     </table>
892 :     <br>
893 :     By convention, all methods used for drag / drop work in display
894 :     coordinates.<br>
895 : sxenos 1.4 <br>
896 : sxenos 1.1 </div>
897 :     </div>
898 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId443855"></a>4.0 Action Bars</h2>
899 : sxenos 1.1 Parts contribute to menus, toolbars, coolbars, popup menus, etc. using
900 :     action bars. Each action bar implements IActionBars. It is possible to
901 :     create one action bar as a child of another. In this situation, the
902 :     parent and child share the same widgets, but the child may be disabled
903 : sxenos 1.4 independently of the parent. Figure 15 shows how the workbench
904 : sxenos 1.1 action bars are
905 :     constructed. The rectangles indicate instances of IActionBars, and the
906 :     ovals indicate other entities that create or modify action bars.<br>
907 :     <br>
908 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
909 : sxenos 1.4 15: Action bar information flow</span><br>
910 : sxenos 1.1 <img alt="" src="action_bar_flow.PNG"
911 :     style="width: 800px; height: 600px;"><br>
912 :     <div style="text-align: left;"><p:colorscheme
913 :     colors="#FFFFFF,#000000,#808080,#000000,#00CC99,#3333CC,#CCCCFF,#B2B2B2"></p:colorscheme>
914 :     <div v:shape="_x0000_s2050" class="O">
915 :     <div style=""><span style="font-size: 50%;"><br>
916 :     </span><span style="font-family: Symbol; font-size: 50%;"></span><span
917 :     style="font-size: 50%;"></span><span
918 :     style="font-family: Symbol; font-size: 50%;"></span><span
919 :     style="font-size: 50%;"></span><span
920 :     style="font-family: Symbol; font-size: 50%;"></span><span
921 :     style="font-size: 50%;"></span></div>
922 :     <div style=""><span style="display: none;">
923 :     </span></div>
924 :     </div>
925 :     </div>
926 :     </div>
927 :     <br>
928 :     The workbench window has a top level IActionBars instance that
929 :     contributes to the main menubar, coolbar, etc. (this top-level object
930 :     is returned by WorkbenchWindow.getActionBars()).<br>
931 :     <br>
932 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId652269"></a>4.1 Editor Action Bars<br>
933 :     </h3>
934 : sxenos 1.1 Each type of editor gets a reference-counted IActionBars instance that
935 :     is a child of the window's action bars. For
936 :     example, if the workbench contains 10 java editors and 10 text editors,
937 :     it will create one IActionBars to be shared among the Java editors and
938 :     another IActionBars to be shared among the text editors. Editors can
939 :     access this shared instance by calling getSite().getActionBars().
940 :     Editor action bars are initialized by an instance of
941 :     IEditorActionBarContributor, and additional actions are added by the
942 :     editorActions
943 :     extension point.<br>
944 :     <br>
945 :     The reference counted IEditorActionBars are managed by the
946 :     EditorManager, along with the IActionBarContributor.<br>
947 :     <br>
948 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId340925"></a>4.2 Action Sets<br>
949 :     </h3>
950 : sxenos 1.1 An action set is an action bar that is identified by ID. Action sets
951 :     are contributed by the actionSets extension point, and their action
952 :     bars are a child of the workbench window's root action bars. Visibility
953 :     of action sets is controlled by the following function:<br>
954 :     <br>
955 :     <div style="margin-left: 40px;"><img alt="" src="action_set_formula.PNG"
956 :     style="width: 208px; height: 29px;"><br>
957 :     </div>
958 :     <br>
959 :     Where:<br>
960 :     <br>
961 :     <div style="margin-left: 40px;">P = set of actions enabled in the
962 :     perspective. Returned by Perspective.getAlwaysOnActionSets().
963 :     Initialized by the perspective factory, perspective extensions
964 :     extension point, and IWonkbenchPage.showActionSet.<br>
965 :     A = action sets associated with the active part (associated by the
966 :     actionSetPartAssociations extension point).<br>
967 :     E = action sets associated with the active editor (associated by the
968 :     actionSetPartAssociations extension point).<br>
969 :     D = action sets that are enabled by default (a property of the
970 :     actionSets extension markup).<br>
971 :     N = action sets that are explicitly disabled in the current
972 :     perspective. Initialized by IWorkbenchPage.hideActionSet.<br>
973 :     </div>
974 :     <br>
975 :     The sets P and N are persisted with the current perspective between
976 :     sessions. The sets A and E can change every time the active part or
977 :     editor changes.<br>
978 :     <br>
979 :     The workbench page uses the class ActionSetManager to compute action
980 :     set enablement. This class keeps two reference counts for each action
981 :     set: <br>
982 :     <ul>
983 :     <li>a "showCount" indicates how many of P, A, E, and D the action set
984 :     appears in</li>
985 :     <li>a "hideCount" indicates whether the action set appears in N</li>
986 :     </ul>
987 :     The action set is visible iff showCount is nonzero and hideCount is
988 :     zero.<br>
989 :     <br>
990 : sxenos 1.4 <h3><a class="mozTocH3" name="mozTocId277128"></a>4.3 View Actions</h3>
991 : sxenos 1.1 Each view instance is given its own IActionBars instance. Unlike editor
992 :     action bars, these are not shared and are not a child of the workbench
993 :     window's root action bars. This means that view instances can
994 :     programmatically add actions to their action bar. Additional actions
995 :     are also added to a view's action bars through the viewActions
996 :     extension point.<br>
997 :     <br>
998 : sxenos 1.4 <h2><a class="mozTocH2" name="mozTocId642161"></a>5.0 General
999 :     Conventions</h2>
1000 : sxenos 1.1 This section describes coding conventions that apply to the entire
1001 :     workbench.<br>
1002 : sxenos 1.4 <br>
1003 :     <h3><a class="mozTocH3" name="mozTocId892615"></a>5.1 Objects must not
1004 :     be returned through API until they are fully initialized</h3>
1005 : sxenos 1.1 Some objects require several public methods to be called in a specific
1006 :     order before they are considered fully initialized. For example, to
1007 :     initialize an IViewPart, it is necessary to call the constructor,
1008 :     setInitializationData, init, and createPartControl before the part is
1009 :     considered initialized. Until <span style="font-style: italic;">all</span>
1010 :     of the above have happened successfully, it must not be possible to
1011 :     reach the object through any API method.<br>
1012 :     <br>
1013 : sxenos 1.3 Keep in mind that the object may trigger other client code during its
1014 :     own
1015 : sxenos 1.1 initialization, so it should not even be possible for an object to find
1016 :     itself during construction.<br>
1017 : sxenos 1.4 <br>
1018 :     <h3><a class="mozTocH3" name="mozTocId308622"></a>5.2 No method may
1019 :     open a modal dialog unless its JavaDoc says so</h3>
1020 : sxenos 1.1 Any method that has the possibility of opening a modal (or of calling
1021 :     Display.readAndDispatch through any other means) needs to be clearly
1022 :     documented. All callers of that method must be prepared to handle
1023 :     background
1024 :     threads running arbitrary code in *syncExecs during the method call. It
1025 :     is always a bug to open a modal dialog when extending or overloading a
1026 :     method unless the JavaDoc in the base class says otherwise. Permitting
1027 :     opening of dialogs in a method that did not previously do so is a
1028 :     breaking change for all callers of that method.<br>
1029 :     <br>
1030 :     Some common bugs:<br>
1031 :     <ul>
1032 :     <li>Views are never allowed to call MessageDialog.openError from
1033 :     their createPartControls method, especially when handling an exception.</li>
1034 :     <li>Parts can be closed in a *syncExec. If a part calls a method that
1035 :     opens dialogs, it might not still exist when the method returns. After
1036 :     calling the method, the part must check that it hasn't been disposed
1037 :     before using their widgets or accessing any members that would have
1038 : sxenos 1.4 been deallocated by the disposal.</li>
1039 : sxenos 1.1 </ul>
1040 : sxenos 1.4 <br>
1041 :     <h3><a class="mozTocH3" name="mozTocId753192"></a>5.3 Lazy creation
1042 : sxenos 1.1 should happen as late as possible<br>
1043 : sxenos 1.4 </h3>
1044 : sxenos 1.1 Part implementations should be created at the latest possible moment.
1045 :     The workbench's internal state should be restored as much as possible
1046 :     before the first object is created from an extension point. Parts
1047 :     should not be materialized until they are needed.<br>
1048 : sxenos 1.4 <br>
1049 :     <h3><a class="mozTocH3" name="mozTocId921869"></a>5.4 getters should
1050 : sxenos 1.1 not modify the thing they are supposed to measure<br>
1051 : sxenos 1.4 </h3>
1052 : sxenos 1.1 This applies to any situation where there is a getter and an associated
1053 :     listener that monitors changes in the getter's value. The getter should
1054 :     never cause such a property change to be fired while computing its
1055 :     return value.<br>
1056 :     <br>
1057 :     For example, IWorkbenchPage.getActivePart() should never create the
1058 :     active part. Unless the active part already exists and a property
1059 :     change was fired to all IPartListeners, getActivePart must return null.<br>
1060 :     <br>
1061 :     <br>
1062 :     </body>
1063 :     </html>