KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > presentations > util > PresentablePartFolder


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.presentations.util;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.jface.util.Geometry;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.ControlEvent;
21 import org.eclipse.swt.events.ControlListener;
22 import org.eclipse.swt.events.DisposeEvent;
23 import org.eclipse.swt.events.DisposeListener;
24 import org.eclipse.swt.events.ShellAdapter;
25 import org.eclipse.swt.events.ShellEvent;
26 import org.eclipse.swt.events.ShellListener;
27 import org.eclipse.swt.graphics.Point;
28 import org.eclipse.swt.graphics.Rectangle;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.ui.IPropertyListener;
32 import org.eclipse.ui.internal.dnd.DragUtil;
33 import org.eclipse.ui.internal.dnd.SwtUtil;
34 import org.eclipse.ui.presentations.IPresentablePart;
35 import org.eclipse.ui.presentations.IStackPresentationSite;
36
37 /**
38  * @since 3.1
39  */

40 public final class PresentablePartFolder implements IPresentablePartList {
41     private AbstractTabFolder folder;
42     private IPresentablePart current;
43     //private ProxyControl toolbarProxy;
44
private Control contentProxy;
45     private static PartInfo tempPartInfo = new PartInfo();
46     
47     /**
48      * Movement listener. Updates the bounds of the target to match the
49      * bounds of the dummy control.
50      */

51     private ControlListener contentListener = new ControlListener() {
52
53         public void controlMoved(ControlEvent e) {
54             layoutContent();
55         }
56
57         public void controlResized(ControlEvent e) {
58         }
59         
60     };
61     
62     private ShellListener shellListener = new ShellAdapter() {
63         public void shellActivated(ShellEvent e) {
64             folder.shellActive(true);
65         }
66
67         public void shellDeactivated(ShellEvent e) {
68             folder.shellActive(false);
69         }
70     };
71
72     /**
73      * Listener attached to all child parts. It responds to changes in part properties
74      */

75     private IPropertyListener childPropertyChangeListener = new IPropertyListener() {
76         public void propertyChanged(Object JavaDoc source, int property) {
77
78             if (source instanceof IPresentablePart) {
79                 IPresentablePart part = (IPresentablePart) source;
80
81                 childPropertyChanged(part, property);
82             }
83         }
84     };
85
86     /**
87      * Dispose listener that is attached to the main control. It triggers cleanup of
88      * any listeners. This is required to prevent memory leaks.
89      */

90     private DisposeListener tabDisposeListener = new DisposeListener() {
91         public void widgetDisposed(DisposeEvent e) {
92             if (e.widget == folder.getControl()) {
93                 // If we're disposing the main control...
94
disposed();
95             }
96         }
97     };
98     private List JavaDoc partList = new ArrayList JavaDoc(4);
99     
100     public PresentablePartFolder(AbstractTabFolder folder) {
101         this.folder = folder;
102         
103         folder.getControl().getShell().addShellListener(shellListener);
104         folder.shellActive(folder.getControl().getDisplay()
105                 .getActiveShell() == folder.getControl().getShell());
106
107         folder.getControl().addDisposeListener(tabDisposeListener);
108         
109         //toolbarProxy = new ProxyControl(folder.getToolbarParent());
110

111         // NOTE: if the shape of contentProxy changes, the fix for bug 85899 in EmptyTabFolder.computeSize may need adjustment.
112
contentProxy = new Composite(folder.getContentParent(), SWT.NONE);
113         contentProxy.setVisible(false);
114         for (Control current = contentProxy; current != folder.getControl().getParent(); current = current.getParent()) {
115             current.addControlListener(contentListener);
116         }
117         folder.setContent(contentProxy);
118         
119     }
120     
121     /**
122      *
123      * @since 3.1
124      */

125     private void layoutContent() {
126         if (current != null) {
127             Rectangle clientArea = DragUtil.getDisplayBounds(contentProxy);
128             
129             current.setBounds(Geometry.toControl(folder.getControl().getParent(), clientArea));
130         }
131     }
132
133     /**
134      *
135      * @since 3.1
136      */

137     protected void disposed() {
138         folder.getControl().getShell().removeShellListener(shellListener);
139         Iterator JavaDoc iter = partList.iterator();
140         while(iter.hasNext()) {
141             IPresentablePart next = (IPresentablePart)iter.next();
142             
143             next.removePropertyListener(childPropertyChangeListener);
144         }
145     }
146     
147     /* (non-Javadoc)
148      * @see org.eclipse.ui.internal.presentations.util.IPresentablePartList#getPartList()
149      */

150     public IPresentablePart[] getPartList() {
151         AbstractTabItem[] items = folder.getItems();
152         IPresentablePart[] result = new IPresentablePart[items.length];
153         
154         for (int i = 0; i < items.length; i++) {
155             result[i] = getPartForTab(items[i]);
156             
157         }
158         
159         return result;
160     }
161     
162     /**
163      * Adds the given presentable part directly into this presentation at the
164      * given index. Does nothing if a tab already exists for the given part.
165      * This is intended to be called by TabOrder and its subclasses.
166      *
167      * @param part part to add
168      * @param idx index to insert at
169      */

170     public void insert(IPresentablePart part, int idx) {
171         Assert.isTrue(!folder.getControl().isDisposed());
172
173         if (getTab(part) != null) {
174             if(indexOf(part) != idx)
175                 move(part, idx);
176             return;
177         }
178
179         idx = Math.min(idx, folder.getItemCount());
180
181         AbstractTabItem item;
182
183         int style = SWT.NONE;
184
185         if (part.isCloseable()) {
186             style |= SWT.CLOSE;
187         }
188         
189         item = folder.add(idx, style);
190
191         item.setData(part);
192
193         initTab(item, part);
194
195         part.addPropertyListener(childPropertyChangeListener);
196         partList.add(part);
197     }
198     
199     public void remove(IPresentablePart toRemove) {
200         if (toRemove == current) {
201             select(null);
202         }
203         
204         internalRemove(toRemove);
205     }
206     
207     private void internalRemove(IPresentablePart toRemove) {
208         AbstractTabItem item = getTab(toRemove);
209         if (item != null) {
210             item.dispose();
211         }
212         if (partList.contains(toRemove)) {
213             toRemove.removePropertyListener(childPropertyChangeListener);
214             partList.remove(toRemove);
215         }
216     }
217     
218     /**
219      * Moves the given part to the given index. When this method returns,
220      * indexOf(part) will return newIndex.
221      *
222      * @param part
223      * @param newIndex
224      */

225     public void move(IPresentablePart part, int newIndex) {
226         int currentIndex = indexOf(part);
227
228         if (currentIndex == newIndex) {
229             return;
230         }
231
232         internalRemove(part);
233         insert(part, newIndex);
234         
235         if (current == part) {
236             folder.setSelection(getTab(part));
237         }
238     }
239
240     /**
241      * Returns the number of parts in this folder
242      */

243     public int size() {
244         return folder.getItemCount();
245     }
246
247     public void setBounds(Rectangle bounds) {
248         Point minSize = folder.computeSize(bounds.width, SWT.DEFAULT);
249         
250         if (folder.getState() == IStackPresentationSite.STATE_MINIMIZED && minSize.y < bounds.height) {
251             bounds = Geometry.copy(bounds);
252             bounds.height = minSize.y;
253         }
254         
255         // Set the tab folder's bounds
256
folder.getControl().setBounds(bounds);
257
258         layout(false);
259     }
260     
261     public void select(IPresentablePart toSelect) {
262         
263         if (toSelect == current) {
264             return;
265         }
266         
267         if (toSelect != null) {
268             toSelect.setVisible(true);
269         }
270         
271         if (current != null) {
272             current.setVisible(false);
273         }
274         
275         current = toSelect;
276         
277         AbstractTabItem selectedItem = getTab(toSelect);
278
279         folder.setSelection(selectedItem);
280
281         if (selectedItem != null) {
282             // Determine if we need to un-bold this tab
283
selectedItem.setBold(false);
284             initTab(selectedItem, toSelect);
285         } else {
286             setToolbar(null);
287         }
288
289         layout(true);
290     }
291     
292     private void setToolbar(Control newToolbar) {
293         if (folder.getToolbar() != newToolbar) {
294             folder.setToolbar(newToolbar);
295         }
296     }
297     private boolean isVisible = true;
298     
299     
300     private void childPropertyChanged(IPresentablePart part, int property) {
301         AbstractTabItem tab = getTab(part);
302         // If we're in the process of removing this part, it's possible that we might still receive
303
// some events for it. If everything is working perfectly, this should never happen... however,
304
// we check for this case just to be safe.
305
if (tab == null) {
306             return;
307         }
308         
309         switch (property) {
310         case IPresentablePart.PROP_HIGHLIGHT_IF_BACK:
311             if (getCurrent() != part) {//Set bold if it doesn't currently have focus
312
tab.setBold(true);
313                 initTab(tab, part);
314             }
315             break;
316             
317         case IPresentablePart.PROP_TOOLBAR:
318             if (getCurrent() == part) {
319                 folder.flushToolbarSize();
320             }
321             /* falls through */
322         case IPresentablePart.PROP_CONTENT_DESCRIPTION:
323         case IPresentablePart.PROP_PANE_MENU:
324         case IPresentablePart.PROP_TITLE:
325             initTab(tab, part);
326             if (getCurrent() == part) {
327                 layout(true);
328             }
329             break;
330         default:
331             initTab(tab, part);
332         }
333     }
334     
335     protected void initTab(AbstractTabItem item, IPresentablePart part) {
336         tempPartInfo.set(part);
337         item.setInfo(tempPartInfo);
338         
339         item.setBusy(part.isBusy());
340         if (part == getCurrent()) {
341             folder.setSelectedInfo(tempPartInfo);
342             folder.enablePaneMenu(part.getMenu() != null);
343             
344             setToolbar(part.getToolBar());
345         }
346     }
347
348     public boolean isDisposed() {
349         return SwtUtil.isDisposed(folder.getControl());
350     }
351     
352     public IPresentablePart getPartForTab(AbstractTabItem tab) {
353         Assert.isTrue(!isDisposed());
354
355         if (tab == null) {
356             return null;
357         }
358         
359         IPresentablePart part = (IPresentablePart) tab.getData();
360
361         return part;
362     }
363
364     /**
365      * Returns the tab for the given part, or null if there is no such tab
366      *
367      * @param part the part being searched for
368      * @return the tab for the given part, or null if there is no such tab
369      */

370     public AbstractTabItem getTab(IPresentablePart part) {
371         Assert.isTrue(!isDisposed());
372         
373         return folder.findItem(part);
374     }
375     
376     
377
378     public int indexOf(IPresentablePart part) {
379         AbstractTabItem item = getTab(part);
380
381         if (item == null) {
382             return -1;
383         }
384
385         return folder.indexOf(item);
386     }
387     
388     public AbstractTabFolder getTabFolder() {
389         return folder;
390     }
391     
392     public void setVisible(boolean isVisible) {
393         this.isVisible = isVisible;
394         getTabFolder().setVisible(isVisible);
395         if (isVisible) {
396             layout(true);
397         }
398     }
399     
400     public void layout(boolean changed) {
401         if (!isVisible) {
402             // Don't bother with layout if we're not visible
403
return;
404         }
405         // Lay out the tab folder and compute the client area
406
folder.layout(changed);
407
408         //toolbarProxy.layout();
409

410         layoutContent();
411     }
412     
413     public IPresentablePart getCurrent() {
414         return current;
415     }
416 }
417
Popular Tags