KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > presentations > DefaultPartPresentation


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

11 package org.eclipse.ui.internal.presentations;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.jface.action.GroupMarker;
18 import org.eclipse.jface.action.IMenuManager;
19 import org.eclipse.jface.action.MenuManager;
20 import org.eclipse.jface.action.Separator;
21 import org.eclipse.jface.resource.ColorRegistry;
22 import org.eclipse.jface.resource.FontRegistry;
23 import org.eclipse.jface.util.Assert;
24 import org.eclipse.jface.util.Geometry;
25 import org.eclipse.jface.util.IPropertyChangeListener;
26 import org.eclipse.jface.util.PropertyChangeEvent;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.custom.CTabFolderEvent;
29 import org.eclipse.swt.custom.CTabItem;
30 import org.eclipse.swt.events.DisposeEvent;
31 import org.eclipse.swt.events.DisposeListener;
32 import org.eclipse.swt.events.MouseAdapter;
33 import org.eclipse.swt.events.MouseEvent;
34 import org.eclipse.swt.events.MouseListener;
35 import org.eclipse.swt.events.SelectionAdapter;
36 import org.eclipse.swt.events.SelectionEvent;
37 import org.eclipse.swt.events.ShellAdapter;
38 import org.eclipse.swt.events.ShellEvent;
39 import org.eclipse.swt.events.ShellListener;
40 import org.eclipse.swt.graphics.Color;
41 import org.eclipse.swt.graphics.Font;
42 import org.eclipse.swt.graphics.GC;
43 import org.eclipse.swt.graphics.Image;
44 import org.eclipse.swt.graphics.Point;
45 import org.eclipse.swt.graphics.Rectangle;
46 import org.eclipse.swt.widgets.Control;
47 import org.eclipse.swt.widgets.Event;
48 import org.eclipse.swt.widgets.Label;
49 import org.eclipse.swt.widgets.Listener;
50 import org.eclipse.swt.widgets.Menu;
51 import org.eclipse.swt.widgets.Monitor;
52 import org.eclipse.swt.widgets.Shell;
53 import org.eclipse.swt.widgets.ToolBar;
54 import org.eclipse.swt.widgets.ToolItem;
55 import org.eclipse.ui.IMemento;
56 import org.eclipse.ui.IPropertyListener;
57 import org.eclipse.ui.PlatformUI;
58 import org.eclipse.ui.internal.IWorkbenchConstants;
59 import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
60 import org.eclipse.ui.internal.IWorkbenchThemeConstants;
61 import org.eclipse.ui.internal.WorkbenchImages;
62 import org.eclipse.ui.internal.WorkbenchMessages;
63 import org.eclipse.ui.internal.dnd.DragUtil;
64 import org.eclipse.ui.internal.util.Util;
65 import org.eclipse.ui.presentations.IPartMenu;
66 import org.eclipse.ui.presentations.IPresentablePart;
67 import org.eclipse.ui.presentations.IPresentationSerializer;
68 import org.eclipse.ui.presentations.IStackPresentationSite;
69 import org.eclipse.ui.presentations.PresentationUtil;
70 import org.eclipse.ui.presentations.StackDropResult;
71 import org.eclipse.ui.presentations.StackPresentation;
72 import org.eclipse.ui.themes.ITheme;
73 import org.eclipse.ui.themes.IThemeManager;
74
75 /**
76  * Base class for StackPresentations that display IPresentableParts in a PaneFolder.
77  *
78  * @since 3.0
79  */

80 public class DefaultPartPresentation extends StackPresentation {
81     
82     private PaneFolder tabFolder;
83     private IPresentablePart current;
84     private int activeState = StackPresentation.AS_INACTIVE;
85     private MenuManager systemMenuManager = new MenuManager();
86     private Label titleLabel;
87     private Listener dragListener;
88     private List JavaDoc activationList = new ArrayList JavaDoc(10);
89     private boolean activationListChange = true;
90     
91     /**
92      * While we are dragging a tab from this folder, this holdes index of the tab
93      * being dragged. Set to -1 if we are not currently dragging a tab from this folder.
94      */

95     private int dragStart = -1;
96         
97     private final static String JavaDoc TAB_DATA = DefaultPartPresentation.class.getName() + ".partId"; //$NON-NLS-1$
98

99     private PaneFolderButtonListener buttonListener = new PaneFolderButtonListener() {
100         public void stateButtonPressed(int buttonId) {
101             getSite().setState(buttonId);
102         }
103
104         public void closeButtonPressed(CTabItem item) {
105             IPresentablePart part = getPartForTab(item);
106             
107             getSite().close(new IPresentablePart[]{part});
108         }
109         
110         public void showList(CTabFolderEvent event) {
111             event.doit = false;
112             showPartList();
113         }
114     };
115     
116     private MouseListener mouseListener = new MouseAdapter() {
117         public void mouseDown(MouseEvent e) {
118             if (e.widget instanceof Control) {
119                 Control ctrl = (Control)e.widget;
120                 
121                 Point globalPos = ctrl.toDisplay(new Point(e.x, e.y));
122                             
123                 // PR#1GDEZ25 - If selection will change in mouse up ignore mouse down.
124
// Else, set focus.
125
CTabItem newItem = tabFolder.getItem(tabFolder.getControl().toControl(globalPos));
126                 if (newItem != null) {
127                     CTabItem oldItem = tabFolder.getSelection();
128                     if (newItem != oldItem)
129                         return;
130                 }
131                 if (current != null) {
132                     current.setFocus();
133                 }
134             }
135         }
136         
137         public void mouseDoubleClick(MouseEvent e) {
138             if (getSite().getState() == IStackPresentationSite.STATE_MAXIMIZED) {
139                 getSite().setState(IStackPresentationSite.STATE_RESTORED);
140             } else {
141                 getSite().setState(IStackPresentationSite.STATE_MAXIMIZED);
142             }
143         }
144     };
145     
146     private Listener menuListener = new Listener() {
147         /* (non-Javadoc)
148          * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
149          */

150         public void handleEvent(Event event) {
151             Point pos = new Point(event.x, event.y);
152
153             showSystemMenu(pos);
154         }
155     };
156     
157     private Listener selectionListener = new Listener() {
158         public void handleEvent(Event e) {
159             if (ignoreSelectionChanges) {
160                 return;
161             }
162             
163             IPresentablePart item = getPartForTab((CTabItem)e.item);
164             
165             if (item != null) {
166                 setSelection((CTabItem)e.item);
167             }
168         }
169     };
170     
171     private IPropertyListener childPropertyChangeListener = new IPropertyListener() {
172         public void propertyChanged(Object JavaDoc source, int property) {
173             
174             if(isDisposed())
175                 return;
176             
177             if (source instanceof IPresentablePart) {
178                 IPresentablePart part = (IPresentablePart) source;
179                 childPropertyChanged(part, property);
180             }
181         }
182     };
183     
184     private DisposeListener tabDisposeListener = new DisposeListener() {
185         public void widgetDisposed(DisposeEvent e) {
186             if (e.widget instanceof CTabItem) {
187                 CTabItem item = (CTabItem)e.widget;
188                 
189                 IPresentablePart part = getPartForTab(item);
190                 
191                 part.removePropertyListener(childPropertyChangeListener);
192             }
193         }
194     };
195     
196     private DisposeListener folderDisposeListener = new DisposeListener() {
197         public void widgetDisposed(DisposeEvent e) {
198             DefaultPartPresentation.this.widgetDisposed();
199         }
200     };
201     
202     private ToolBar viewToolBar;
203     
204     private boolean shellActive = true;
205     
206     private boolean ignoreSelectionChanges = false;
207     
208     private ShellListener shellListener = new ShellAdapter() {
209
210         public void shellActivated(ShellEvent e) {
211             shellActive = true;
212             updateGradient();
213         }
214
215
216         public void shellDeactivated(ShellEvent e) {
217             shellActive = false;
218             updateGradient();
219         }
220     };
221     
222     /**
223      * property listener that listens for theme events and updates the tab folder
224      * accordingly
225      */

226     private IPropertyChangeListener themeListener = new IPropertyChangeListener() {
227
228         /* (non-Javadoc)
229          * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
230          */

231         public void propertyChange(PropertyChangeEvent event) {
232             
233             if(isDisposed())
234                 return;
235             
236             String JavaDoc property = event.getProperty();
237             if (property.equals(IThemeManager.CHANGE_CURRENT_THEME)) {
238                 updateGradient();
239                 setTitleAttributes();
240             }
241             else if (property.equals(IWorkbenchThemeConstants.INACTIVE_TAB_BG_START)
242                     || property.equals(IWorkbenchThemeConstants.INACTIVE_TAB_BG_END)
243                     || property.equals(IWorkbenchThemeConstants.INACTIVE_TAB_TEXT_COLOR)
244                     || property.equals(IWorkbenchThemeConstants.ACTIVE_TAB_TEXT_COLOR)
245                     || property.equals(IWorkbenchThemeConstants.ACTIVE_TAB_BG_START)
246                     || property.equals(IWorkbenchThemeConstants.ACTIVE_TAB_BG_END)
247                     || property.equals(IWorkbenchThemeConstants.TAB_TEXT_FONT)) {
248                 updateGradient();
249             }
250             else if (property.equals(IWorkbenchThemeConstants.VIEW_MESSAGE_TEXT_FONT)) {
251                 setTitleAttributes();
252             }
253         }
254     };
255
256     public DefaultPartPresentation(PaneFolder control, IStackPresentationSite stackSite) {
257         super(stackSite);
258         
259         shellActive = control.getControl().getShell().equals(control.getControl().getDisplay().getActiveShell());
260         
261         tabFolder = control;
262         // Add listener to check for premature disposal
263
tabFolder.getControl().addDisposeListener(folderDisposeListener);
264         
265         tabFolder.setMinimizeVisible(stackSite.supportsState(IStackPresentationSite.STATE_MINIMIZED));
266         tabFolder.setMaximizeVisible(stackSite.supportsState(IStackPresentationSite.STATE_MAXIMIZED));
267         
268         tabFolder.getControl().getShell().addShellListener(shellListener);
269         
270         titleLabel = new Label(tabFolder.getControl(), SWT.NONE);
271         titleLabel.setVisible(false);
272         titleLabel.moveAbove(null);
273
274         PlatformUI
275             .getWorkbench()
276             .getThemeManager()
277             .addPropertyChangeListener(themeListener);
278         
279         
280         viewToolBar = new ToolBar(control.getControl(), SWT.FLAT);
281         viewToolBar.moveAbove(null);
282         
283         ToolItem pullDownButton = new ToolItem(viewToolBar, SWT.PUSH);
284         // Image img = WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_VIEW_MENU);
285
Image hoverImage =
286             WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_VIEW_MENU_HOVER);
287         pullDownButton.setDisabledImage(hoverImage); // TODO: comment this out?
288
// PR#1GE56QT - Avoid creation of unnecessary image.
289
pullDownButton.setImage(hoverImage);
290         pullDownButton.setToolTipText(WorkbenchMessages.getString("Menu")); //$NON-NLS-1$
291
pullDownButton.addSelectionListener(new SelectionAdapter() {
292             public void widgetSelected(SelectionEvent e) {
293                 showPaneMenu();
294             }
295         });
296         
297         // listener to switch between visible tabItems
298
tabFolder.getControl().addListener(SWT.Selection, selectionListener);
299
300         // listen for mouse down on tab to set focus.
301
tabFolder.getControl().addMouseListener(mouseListener);
302         
303         tabFolder.getControl().addListener(SWT.MenuDetect, menuListener);
304         
305         tabFolder.addButtonListener(buttonListener);
306         
307         dragListener = new Listener() {
308             public void handleEvent(Event event) {
309                 
310                 Point localPos = new Point(event.x, event.y);
311                 // Ignore drags unless they are on the title area
312
if ((tabFolder.getControl().getStyle() & SWT.TOP) != 0) {
313                     if (localPos.y > tabFolder.getTabHeight()) {
314                         return;
315                     }
316                 } else {
317                     if (localPos.y < tabFolder.getControl().getBounds().height - tabFolder.getTabHeight()) {
318                         return;
319                     }
320                 }
321                 
322                 CTabItem tabUnderPointer = tabFolder.getItem(localPos);
323         
324                 if (tabUnderPointer == null) {
325                     getSite().dragStart(tabFolder.getControl().toDisplay(localPos), false);
326                     return;
327                 }
328
329                 IPresentablePart part = getPartForTab(tabUnderPointer);
330                 
331                 if (getSite().isPartMoveable(part)) {
332                     dragStart = tabFolder.indexOf(tabUnderPointer);
333                     getSite().dragStart(part,
334                         tabFolder.getControl().toDisplay(localPos), false);
335                     dragStart = -1;
336                 }
337             }
338         };
339         
340         PresentationUtil.addDragListener(tabFolder.getControl(), dragListener);
341
342         titleLabel.addMouseListener(mouseListener);
343         
344         { // Initialize system menu
345
systemMenuManager.add(new GroupMarker("misc")); //$NON-NLS-1$
346
systemMenuManager.add(new GroupMarker("restore")); //$NON-NLS-1$
347
systemMenuManager.add(new UpdatingActionContributionItem(new SystemMenuRestore(getSite())));
348             
349             systemMenuManager.add(new SystemMenuMove(getSite(), getPaneName()));
350             systemMenuManager.add(new GroupMarker("size")); //$NON-NLS-1$
351
systemMenuManager.add(new GroupMarker("state")); //$NON-NLS-1$
352
systemMenuManager.add(new UpdatingActionContributionItem(new SystemMenuMinimize(getSite())));
353             
354             systemMenuManager.add(new UpdatingActionContributionItem(new SystemMenuMaximize(getSite())));
355             systemMenuManager.add(new Separator("close")); //$NON-NLS-1$
356
systemMenuManager.add(new UpdatingActionContributionItem(new SystemMenuClose(getSite())));
357             
358             getSite().addSystemActions(systemMenuManager);
359         } // End of system menu initialization
360
}
361
362     /**
363      * Restores a presentation from a previously stored state
364      *
365      * @param serializer (not null)
366      * @param savedState (not null)
367      */

368     public void restoreState(IPresentationSerializer serializer, IMemento savedState) {
369         IMemento[] parts = savedState.getChildren(IWorkbenchConstants.TAG_PART);
370         
371         for (int idx = 0; idx < parts.length; idx++) {
372             String JavaDoc id = parts[idx].getString(IWorkbenchConstants.TAG_ID);
373             
374             if (id != null) {
375                 IPresentablePart part = serializer.getPart(id);
376                 
377                 if (part != null) {
378                     addPart(part, tabFolder.getItemCount());
379                 }
380             }
381         }
382     }
383     
384     
385     /* (non-Javadoc)
386      * @see org.eclipse.ui.presentations.StackPresentation#saveState(org.eclipse.ui.presentations.IPresentationSerializer, org.eclipse.ui.IMemento)
387      */

388     public void saveState(IPresentationSerializer context, IMemento memento) {
389         super.saveState(context, memento);
390         
391         List JavaDoc parts = getPresentableParts();
392         
393         Iterator JavaDoc iter = parts.iterator();
394         while (iter.hasNext()) {
395             IPresentablePart next = (IPresentablePart)iter.next();
396             
397             IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_PART);
398             childMem.putString(IWorkbenchConstants.TAG_ID, context.getId(next));
399         }
400     }
401     
402     /**
403      * This method performs initialization that must be done after the object is created. Subclasses
404      * must call this method exactly once on the last line of any public constructor.
405      */

406     public void init() {
407         updateGradient();
408         setTitleAttributes();
409     }
410     
411     /**
412      * Sets the font on the title of this stack.
413      */

414     protected void setTitleAttributes() {
415         Assert.isTrue(!isDisposed());
416         
417         ITheme theme = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme();
418         Font messageFont = theme.getFontRegistry().get(IWorkbenchThemeConstants.VIEW_MESSAGE_TEXT_FONT);
419         if (!messageFont.equals(titleLabel.getFont())) {
420             titleLabel.setFont(messageFont);
421             setControlSize();
422         }
423     }
424     
425     /**
426      * Sets the colors of the tab to the inactive tab colors.
427      */

428     protected final void setInactiveTabColors() {
429         Assert.isTrue(!isDisposed());
430         
431         ITheme theme = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme();
432         ColorRegistry colorRegistry = theme.getColorRegistry();
433
434         drawGradient(
435                 colorRegistry.get(IWorkbenchThemeConstants.INACTIVE_TAB_TEXT_COLOR),
436                 new Color [] {
437                         colorRegistry.get(IWorkbenchThemeConstants.INACTIVE_TAB_BG_START),
438                         colorRegistry.get(IWorkbenchThemeConstants.INACTIVE_TAB_BG_END)
439                 },
440                 new int [] {theme.getInt(IWorkbenchThemeConstants.INACTIVE_TAB_PERCENT)},
441                 theme.getBoolean(IWorkbenchThemeConstants.INACTIVE_TAB_VERTICAL));
442     }
443     
444     /**
445      * Sets the colors of the tab to the active tab colors, taking into account
446      * shell focus.
447      */

448     protected final void setActiveTabColors() {
449         Assert.isTrue(!isDisposed());
450         
451         ITheme theme = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme();
452         ColorRegistry colorRegistry = theme.getColorRegistry();
453         
454         if (isShellActive()) {
455             drawGradient(
456                     colorRegistry.get(IWorkbenchThemeConstants.ACTIVE_TAB_TEXT_COLOR),
457                     new Color [] {
458                             colorRegistry.get(IWorkbenchThemeConstants.ACTIVE_TAB_BG_START),
459                             colorRegistry.get(IWorkbenchThemeConstants.ACTIVE_TAB_BG_END)
460                     },
461                     new int [] {theme.getInt(IWorkbenchThemeConstants.ACTIVE_TAB_PERCENT)},
462                     theme.getBoolean(IWorkbenchThemeConstants.ACTIVE_TAB_VERTICAL));
463         }
464         else {
465             drawGradient(
466                     colorRegistry.get(IWorkbenchThemeConstants.ACTIVE_NOFOCUS_TAB_TEXT_COLOR),
467                     new Color [] {
468                             colorRegistry.get(IWorkbenchThemeConstants.ACTIVE_NOFOCUS_TAB_BG_START),
469                             colorRegistry.get(IWorkbenchThemeConstants.ACTIVE_NOFOCUS_TAB_BG_END)
470                     },
471                     new int [] {theme.getInt(IWorkbenchThemeConstants.ACTIVE_NOFOCUS_TAB_PERCENT)},
472                     theme.getBoolean(IWorkbenchThemeConstants.ACTIVE_NOFOCUS_TAB_VERTICAL));
473             
474         }
475     }
476     
477     /**
478      * Update the folder colors and fonts based on the current active state.
479      * Subclasses should override, ensuring that they call
480      * super after all color/font changes.
481      */

482     protected void updateGradient() {
483         Assert.isTrue(!isDisposed());
484         // do nothing
485
}
486     
487     /**
488      * @return the required tab height for this folder.
489      */

490     protected int computeTabHeight() {
491         Assert.isTrue(!isDisposed());
492         
493         GC gc = new GC(tabFolder.getControl());
494         
495         // Compute the tab height
496
int tabHeight = Math.max(
497                 viewToolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT).y,
498                 gc.getFontMetrics().getHeight());
499
500         gc.dispose();
501         
502         return tabHeight;
503     }
504     
505     protected String JavaDoc getPaneName() {
506         return WorkbenchMessages.getString("DefaultPartPresentation.PaneName"); //$NON-NLS-1$
507
}
508
509     /**
510      * Displays the view menu as a popup
511      */

512     public void showPaneMenu() {
513         Assert.isTrue(!isDisposed());
514         
515         IPartMenu menu = getPartMenu();
516         
517         if (menu != null) {
518             Rectangle bounds = DragUtil.getDisplayBounds(viewToolBar);
519             menu.showMenu(new Point(bounds.x, bounds.y + bounds.height));
520         }
521     }
522
523     /**
524      * Returns the currently selected part, or <code>null</code>.
525      *
526      * @return the currently selected part, or <code>null</code>
527      */

528     protected IPresentablePart getCurrent() {
529         Assert.isTrue(!isDisposed());
530         
531         return current;
532     }
533     
534     /**
535      * Returns the index of the tab for the given part, or returns tabFolder.getItemCount()
536      * if there is no such tab.
537      *
538      * @param part part being searched for
539      * @return the index of the tab for the given part, or the number of tabs
540      * if there is no such tab
541      */

542     protected final int indexOf(IPresentablePart part) {
543         Assert.isTrue(!isDisposed());
544         
545         if (part == null) {
546             return tabFolder.getItemCount();
547         }
548     
549         CTabItem[] items = tabFolder.getItems();
550         
551         for (int idx = 0; idx < items.length; idx++) {
552             IPresentablePart tabPart = getPartForTab(items[idx]);
553             
554             if (part == tabPart) {
555                 return idx;
556             }
557         }
558         
559         return items.length;
560     }
561     
562     /**
563      * Returns the tab for the given part, or null if there is no such tab
564      *
565      * @param part the part being searched for
566      * @return the tab for the given part, or null if there is no such tab
567      */

568     protected final CTabItem getTab(IPresentablePart part) {
569         Assert.isTrue(!isDisposed());
570         CTabItem[] items = tabFolder.getItems();
571         
572         int idx = indexOf(part);
573         
574         if (idx < items.length) {
575             return items[idx];
576         }
577         
578         return null;
579     }
580     
581     /**
582      * @param part
583      * @param property
584      */

585     protected void childPropertyChanged(IPresentablePart part, int property) {
586         
587         CTabItem tab = getTab(part);
588         // If we're in the process of removing this part, it's possible that we might still receive
589
// some events for it. If everything is working perfectly, this should never happen... however,
590
// we check for this case just to be safe.
591
if (tab == null) {
592             return;
593         }
594         
595         initTab(tab, part);
596         
597         switch (property) {
598          case IPresentablePart.PROP_BUSY:
599             break;
600          case IPresentablePart.PROP_HIGHLIGHT_IF_BACK:
601             FontRegistry registry =
602                 PlatformUI.getWorkbench().
603                     getThemeManager().getCurrentTheme().
604                         getFontRegistry();
605             
606             if(getCurrent() != part)//Set bold if it does currently have focus
607
tab.setFont(registry.getBold(IWorkbenchThemeConstants.TAB_TEXT_FONT));
608             break;
609          case IPresentablePart.PROP_CONTENT_DESCRIPTION:
610          case IPresentablePart.PROP_TOOLBAR:
611          case IPresentablePart.PROP_PANE_MENU:
612          case IPresentablePart.PROP_TITLE:
613             if (getCurrent() == part) {
614                 setControlSize();
615             }
616             break;
617         }
618     }
619
620     protected final IPresentablePart getPartForTab(CTabItem item) {
621         Assert.isTrue(!isDisposed());
622         
623         IPresentablePart part = (IPresentablePart)item.getData(TAB_DATA);
624         
625         return part;
626     }
627     
628     /**
629      * Returns the underlying tab folder for this presentation.
630      *
631      * @return
632      */

633     protected PaneFolder getTabFolder() {
634         Assert.isTrue(!isDisposed());
635         return tabFolder;
636     }
637     
638     /**
639      * Returns true iff the underlying tab folder has been disposed.
640      *
641      * @return
642      */

643     public boolean isDisposed() {
644         return tabFolder == null || tabFolder.isDisposed();
645     }
646     
647     /**
648      * Sets the gradient for the selected tab
649      *
650      * @param fgColor
651      * @param bgColors
652      * @param percentages
653      * @param vertical
654      */

655     public void drawGradient(Color fgColor, Color [] bgColors, int [] percentages, boolean vertical) {
656         Assert.isTrue(!isDisposed());
657         
658         tabFolder.setSelectionForeground(fgColor);
659         tabFolder.setSelectionBackground(bgColors, percentages, vertical);
660     }
661     
662     public boolean isActive() {
663         Assert.isTrue(!isDisposed());
664         
665         return activeState == StackPresentation.AS_ACTIVE_FOCUS;
666     }
667     
668     public int getActive() {
669         Assert.isTrue(!isDisposed());
670         
671         return activeState;
672     }
673     
674     protected String JavaDoc getCurrentTitle() {
675         Assert.isTrue(!isDisposed());
676         
677         if (current == null) {
678             return ""; //$NON-NLS-1$
679
}
680         
681         String JavaDoc result = current.getTitleStatus();
682         
683         return result;
684     }
685
686     protected void layout(boolean changed) {
687         Assert.isTrue(!isDisposed());
688         
689         if (changed) {
690             String JavaDoc currentTitle = getCurrentTitle();
691             
692             if (!currentTitle.equals(Util.ZERO_LENGTH_STRING)) {
693                 tabFolder.setTopLeft(titleLabel);
694                 titleLabel.setText(currentTitle);
695                 titleLabel.setVisible(true);
696             } else {
697                 tabFolder.setTopLeft(null);
698                 titleLabel.setVisible(false);
699             }
700             
701             Control currentToolbar = getCurrentToolbar();
702             tabFolder.setTopCenter(currentToolbar);
703                 
704             IPartMenu partMenu = getPartMenu();
705             
706             if (partMenu != null) {
707                 tabFolder.setTopRight(viewToolBar);
708                 viewToolBar.setVisible(true);
709             } else {
710                 tabFolder.setTopRight(null);
711                 viewToolBar.setVisible(false);
712             }
713         }
714
715         tabFolder.layout(changed);
716
717         if (current != null) {
718             Rectangle clientArea = tabFolder.getClientArea();
719             Rectangle bounds = tabFolder.getControl().getBounds();
720             clientArea.x += bounds.x;
721             clientArea.y += bounds.y;
722             
723             current.setBounds(clientArea);
724         }
725     }
726     
727     /**
728      * Set the size of a page in the folder.
729      */

730     protected void setControlSize() {
731         Assert.isTrue(!isDisposed());
732         
733         layout(true);
734     }
735     
736     /**
737      * Returns the IPartMenu for the currently selected part, or null if the current
738      * part does not have a menu.
739      *
740      * @return the IPartMenu for the currently selected part or null if none
741      */

742     protected IPartMenu getPartMenu() {
743         Assert.isTrue(!isDisposed());
744         
745         IPresentablePart part = getCurrentPart();
746         if (part == null) {
747             return null;
748         }
749
750         return part.getMenu();
751     }
752         
753     
754     // This is final because subclasses should overload widgetDisposed() instead.
755
/* (non-Javadoc)
756      * @see org.eclipse.ui.internal.skins.Presentation#dispose()
757      */

758     public final void dispose() {
759         if (isDisposed()) {
760             return;
761         }
762         // Dispose the tab folder. This will cause widgetDisposed (below) to be called,
763
// which does the real cleanup. This pattern ensures that the disposal code
764
// will run even if the widget was prematurely disposed (due to its parent
765
// being destroyed).
766
tabFolder.getControl().dispose();
767     }
768     
769     /**
770      * Called when the tabFolder is disposed. This does the real cleanup.
771      */

772     protected void widgetDisposed() {
773         tabFolder.getControl().getShell().removeShellListener(shellListener);
774         PresentationUtil.removeDragListener(tabFolder.getControl(), dragListener);
775         
776         systemMenuManager.dispose();
777         systemMenuManager.removeAll();
778         
779         tabFolder.getControl().removeDisposeListener(folderDisposeListener);
780         tabFolder = null;
781         
782         titleLabel.dispose();
783         titleLabel = null;
784         
785         viewToolBar.dispose();
786         
787         PlatformUI
788         .getWorkbench()
789         .getThemeManager()
790         .removePropertyChangeListener(themeListener);
791         
792         activationList = null;
793     }
794     
795     /* (non-Javadoc)
796      * @see org.eclipse.ui.presentations.StackPresentation#setActive(int)
797      */

798     public void setActive(int newState) {
799         Assert.isTrue(!isDisposed());
800         
801         activeState = newState;
802     }
803     
804     private CTabItem createPartTab(IPresentablePart part, int tabIndex) {
805         Assert.isTrue(!isDisposed());
806         
807         tabIndex = Math.min(tabIndex, tabFolder.getItemCount());
808         
809         CTabItem tabItem;
810
811         int style = SWT.NONE;
812         
813         if (getSite().isCloseable(part)) {
814             style |= SWT.CLOSE;
815         }
816         
817         ignoreSelectionChanges = true;
818         try {
819             tabItem = tabFolder.createItem(style, tabIndex);
820         } finally {
821             ignoreSelectionChanges = false;
822         }
823                 
824         tabItem.setData(TAB_DATA, part);
825         
826         part.addPropertyListener(childPropertyChangeListener);
827         tabItem.addDisposeListener(tabDisposeListener);
828     
829         initTab(tabItem, part);
830         
831         return tabItem;
832     }
833     
834     /**
835      * Initializes a tab for the given part. Sets the text, icon, tool tip,
836      * etc. This will also be called whenever a relevant property changes
837      * in the part to reflect those changes in the tab. Subclasses may override
838      * to change the appearance of tabs for a particular part.
839      *
840      * @param tabItem tab for the part
841      * @param part the part being displayed
842      */

843     protected void initTab(CTabItem tabItem, IPresentablePart part) {
844         Assert.isTrue(!isDisposed());
845         
846         tabItem.setText(part.getName());
847         
848         tabItem.setImage(part.getTitleImage());
849         
850         String JavaDoc toolTipText = part.getTitleToolTip();
851         if (!toolTipText.equals(Util.ZERO_LENGTH_STRING)) {
852             tabItem.setToolTipText(toolTipText);
853         }
854         
855         FontRegistry registry =
856             PlatformUI.getWorkbench().
857                 getThemeManager().getCurrentTheme().
858                     getFontRegistry();
859         
860         if(part.isBusy())
861             tabItem.setFont(registry.getItalic(IWorkbenchThemeConstants.TAB_TEXT_FONT));
862         else{
863             tabItem.setFont(null);
864         }
865
866     }
867     
868     /* (non-Javadoc)
869      * @see org.eclipse.ui.internal.skins.StackPresentation#addPart(org.eclipse.ui.internal.skins.IPresentablePart, org.eclipse.ui.internal.skins.IPresentablePart)
870      */

871     public void addPart(IPresentablePart newPart, Object JavaDoc cookie) {
872         
873         int idx;
874         List JavaDoc lruList = null;
875         
876         if (cookie instanceof Integer JavaDoc) {
877             idx = ((Integer JavaDoc)cookie).intValue();
878             addPart(newPart, idx);
879             return;
880         } else {
881             if (cookie != null && cookie instanceof List JavaDoc) {
882                 // When adding a part, the LRU list and index are being passed
883
// from #selectPart(...). In selectPart, when the item is invisible on
884
// the left hand side of the tab folder and the user selects it from the chevron,
885
// save the LRU list of visible items, get the position at which we should re-insert
886
// the item, then remove the item and call addPart(...) with this information.
887
// All this to support resize of the CTabFolder pushing tabs off the left and
888
// retaining the ability for them to come back from the left during resize, when
889
// possible
890
List JavaDoc list = (List JavaDoc)cookie;
891                 lruList = (List JavaDoc)list.get(0);
892                 idx = ((Integer JavaDoc)list.get(1)).intValue();
893             }
894             else {
895                 // just calling addPart(...) and the item is inserted in the default location
896
idx = getItemInsertionIndex();
897                 lruList = getVisibleItemsLRUList();
898             }
899         }
900         
901         addPart(newPart, idx);
902         
903         // after adding, need to check if the part is showing, as there are cases where
904
// the part can be added at the given index and not appear (for example, when the list
905
// becomes more constrained due to the addition of a chevron)
906
if (tabFolder.getItemCount() > 1) {
907             // get the tab for the item. dont rely on the ideal insertion index as this may be altered
908
CTabItem myItem = getTab(newPart);
909             if (myItem == null)
910                 return;
911             // make sure the part is showing
912
while (!myItem.isShowing()) {
913                 IPresentablePart lruPart = null;
914                 CTabItem lruItem = null;
915                 
916                 // get the least recently used item that is showing
917
// and remove it
918
for (int i = 0; i < lruList.size(); i++) {
919                     lruItem = (CTabItem)lruList.get(i);
920                     if (!myItem.equals(lruItem)) {
921                         lruItem = (CTabItem)lruList.remove(i);
922                         break;
923                     }
924                 }
925                 if (myItem.equals(lruItem) || lruItem == null)
926                     break;
927                 
928                 lruPart = getPartForTab(lruItem);
929                 // do not update the activation order of the part that will
930
// be removed and added after the new item
931
try {
932                     activationListChange = false;
933                     removePart(lruPart);
934                     // decrement the index of the item being added as the removal
935
// is always of an item with a lower index then the item being added on the right
936
addPart(lruPart, --idx+1);
937                 }
938                 finally {
939                     activationListChange = true;
940                 }
941             }
942         }
943     }
944     
945     /**
946      * @return a list containing the CTabItem items that are
947      * visible in the CTabFolder
948      */

949     private List JavaDoc getVisibleItemsLRUList() {
950         List JavaDoc lruList = new ArrayList JavaDoc(10);
951         // save current visible items in the least recently used order
952

953         // Sort the items whose tabs are showing based on activation order.
954
// for each item in the CTabFolder, cross index that in the activation
955
// list to come up with a LRU ordered list of CTabItems.
956
// NOTE: the activation list is not always a complete list of all items
957
// for example on startup it can be empty
958
for (int i = 0; i < tabFolder.getItemCount(); i++) {
959             CTabItem item = tabFolder.getItem(i);
960             // only care about items that are showing
961
if (item.isShowing()) {
962                 int lruListSize = lruList.size();
963                 if (lruListSize == 0)
964                     lruList.add(item);
965                 else {
966                     int j = 0;
967                     // any item that is NOT in the activation list, returns -1 as an
968
// index hence the item will be inserted at the begining of the LRU
969
// list make it the least recently used
970
for (j = 0; j < lruListSize; j++) {
971                         if (activationList.indexOf(getPartForTab(item)) <
972                                 activationList.indexOf(getPartForTab((CTabItem)lruList.get(j))))
973                             break;
974                     }
975                     lruList.add(j, item);
976                 }
977             }
978         }
979         return lruList;
980     }
981
982     /**
983      * @return the index at which a new item
984      * should be inserted
985      */

986     private int getItemInsertionIndex() {
987         // Select a location for newly inserted parts
988
// Insert after the last showing item on the right
989
int idx = tabFolder.getItemCount();
990         
991         // add to the end if the bounds are 0 - the isShowing/getBounds logic
992
// below does not work when opening an initial perspective because no
993
// items are showing (the folders bounds are set to 0)
994
// Items on GTK wont have a width of 0 - so use 1
995
if (!tabFolder.getControl().isVisible() || tabFolder.getControl().getBounds().width <= 1)
996             return idx;
997         for (int i = 0; i < idx; i++) {
998             CTabItem item = tabFolder.getItem(i);
999             // make sure the item is not showing and it is on the right
1000
if (!item.isShowing() && item.getBounds().x >= 0) {
1001                return i;
1002            }
1003        }
1004        return idx;
1005    }
1006
1007    /**
1008     * Adds the given presentable part to this presentation at the given index.
1009     * Does nothing if a tab already exists for the given part.
1010     *
1011     * @param newPart
1012     * @param index
1013     */

1014    public void addPart(IPresentablePart newPart, int index) {
1015        // If we already have a tab for this part, do nothing
1016
if (getTab(newPart) != null) {
1017            return;
1018        }
1019        createPartTab(newPart, index);
1020        
1021        setControlSize();
1022        // in some cases we don't want addPart to affect the activation list
1023
// such as when we are moving an items location because it was
1024
// the least recently used
1025
if (activationListChange)
1026            activationList.add(newPart);
1027    }
1028
1029    /* (non-Javadoc)
1030     * @see org.eclipse.ui.internal.skins.StackPresentation#removePart(org.eclipse.ui.internal.skins.IPresentablePart)
1031     */

1032    public void removePart(IPresentablePart oldPart) {
1033        if (current == oldPart) {
1034            current = null;
1035            // Remove any references to the old widget
1036
tabFolder.setTopLeft(null);
1037            tabFolder.setTopCenter(null);
1038            tabFolder.setTopRight(null);
1039        }
1040        
1041        CTabItem item = getTab(oldPart);
1042        if (item == null) {
1043            return;
1044        }
1045        oldPart.setVisible(false);
1046        
1047        // in some cases we don't want removePart to affect the activation list
1048
// such as when we are moving an items location because it was
1049
// the least recently used
1050
if (activationListChange)
1051            activationList.remove(oldPart);
1052        
1053        ignoreSelectionChanges = true;
1054        try {
1055            item.dispose();
1056        } finally {
1057            ignoreSelectionChanges = false;
1058        }
1059    }
1060    
1061    /* (non-Javadoc)
1062     * @see org.eclipse.ui.internal.skins.StackPresentation#selectPart(org.eclipse.ui.internal.skins.IPresentablePart)
1063     */

1064    public void selectPart(IPresentablePart toSelect) {
1065        Assert.isTrue(!isDisposed());
1066        
1067        if (toSelect == current) {
1068            return;
1069        }
1070        
1071        IPresentablePart oldPart = current;
1072        
1073        current = toSelect;
1074        
1075        if (current != null) {
1076            CTabItem item = getTab(toSelect);
1077            if (item != null)
1078                // If the item is not currently visible, move it
1079
// to last visible position on the right
1080
// When loading the workbench, all tabs are invisible
1081
// we don't want to change tab ordering in this case
1082
if (isVisibleTabs()) {
1083                    if (!item.isShowing() && tabFolder.getItemCount() > 1) {
1084                        try {
1085                        activationListChange = false;
1086                        // Save a list of the visible items in LRU order
1087
List JavaDoc lruList = getVisibleItemsLRUList();
1088                        int idx = getItemInsertionIndex();
1089                        // If we remove an item from the left
1090
// decrement the index by 1
1091
if (item.getBounds().x < 0)
1092                            idx--;
1093                        
1094                        removePart(toSelect);
1095                        
1096                        // pass the LRU list and insertion index
1097
// to addPart, as it was before the remove happened
1098
List JavaDoc cookie = new ArrayList JavaDoc(2);
1099                        cookie.add(lruList);
1100                        cookie.add(new Integer JavaDoc(idx));
1101                        
1102                        addPart(toSelect, cookie);
1103                        }
1104                        finally {
1105                            activationListChange = true;
1106                        }
1107                    }
1108                }
1109            current = toSelect;
1110            tabFolder.setSelection(indexOf(current));
1111            current.setVisible(true);
1112            // if the act of setting the part visible has caused it to be
1113
// removed or the folder to be disposed (the case when restoring
1114
// editors with non-existant input) then don't modify the state of
1115
// this presentation any further - leave the last tab visible
1116
// see Bug 63721
1117
if (isDisposed())
1118                return;
1119            if (getTab(toSelect) == null) {
1120                selectPart(oldPart);
1121                return;
1122            }
1123            setControlSize();
1124            // update the newly selected item in the activation order
1125
if (activationListChange) {
1126                activationList.remove(toSelect);
1127                activationList.add(toSelect);
1128            }
1129        }
1130        
1131        if (oldPart != null) {
1132            oldPart.setVisible(false);
1133        }
1134    }
1135    
1136    /**
1137     * @return <code>true</code> if at least one tab is visible
1138     * <code>false</code> otherwise
1139     */

1140    private boolean isVisibleTabs() {
1141        boolean result = false;
1142        for (int i = 0; i < tabFolder.getItemCount(); i++) {
1143            CTabItem item = tabFolder.getItem(i);
1144            if (item.isShowing()) {
1145                result = true;
1146                break;
1147            }
1148        }
1149        return result;
1150    }
1151    
1152    public IPresentablePart getCurrentPart() {
1153        Assert.isTrue(!isDisposed());
1154        
1155        return current;
1156    }
1157    
1158    /* (non-Javadoc)
1159     * @see org.eclipse.ui.internal.skins.Presentation#setBounds(org.eclipse.swt.graphics.Rectangle)
1160     */

1161    public void setBounds(Rectangle bounds) {
1162        Assert.isTrue(!isDisposed());
1163        
1164        tabFolder.aboutToResize();
1165        tabFolder.getControl().setBounds(bounds);
1166        layout(false);
1167    }
1168    
1169    /* (non-Javadoc)
1170     * @see org.eclipse.ui.internal.skins.Presentation#computeMinimumSize()
1171     */

1172    public Point computeMinimumSize() {
1173        return tabFolder.computeMinimumSize();
1174    }
1175    
1176    /* (non-Javadoc)
1177     * @see org.eclipse.ui.internal.skins.Presentation#setVisible(boolean)
1178     */

1179    public void setVisible(boolean isVisible) {
1180        Assert.isTrue(!isDisposed());
1181        
1182        if (current != null) {
1183            current.setVisible(isVisible);
1184        }
1185        tabFolder.getControl().setVisible(isVisible);
1186    }
1187
1188    /* (non-Javadoc)
1189     * @see org.eclipse.ui.internal.skins.Presentation#setState(int)
1190     */

1191    public void setState(int state) {
1192        Assert.isTrue(!isDisposed());
1193        
1194        tabFolder.setState(state);
1195    }
1196    
1197    /* (non-Javadoc)
1198     * @see org.eclipse.ui.internal.skins.Presentation#getSystemMenuManager()
1199     */

1200    public IMenuManager getSystemMenuManager() {
1201        Assert.isTrue(!isDisposed());
1202        
1203        return systemMenuManager;
1204    }
1205    
1206    /**
1207     * @param part
1208     * @param point
1209     */

1210    protected void showSystemMenu(Point point) {
1211        Assert.isTrue(!isDisposed());
1212        
1213        Menu aMenu = systemMenuManager.createContextMenu(tabFolder.getControl().getParent());
1214        systemMenuManager.update(true);
1215        aMenu.setLocation(point.x, point.y);
1216        aMenu.setVisible(true);
1217    }
1218
1219    /* (non-Javadoc)
1220     * @see org.eclipse.ui.internal.skins.Presentation#getControl()
1221     */

1222    public Control getControl() {
1223        Assert.isTrue(!isDisposed());
1224        
1225        return tabFolder.getControl();
1226    }
1227
1228    /* (non-Javadoc)
1229     * @see org.eclipse.ui.internal.skins.StackPresentation#dragOver(org.eclipse.swt.widgets.Control, org.eclipse.swt.graphics.Point)
1230     */

1231    public StackDropResult dragOver(Control currentControl, Point location) {
1232        Assert.isTrue(!isDisposed());
1233        
1234        // Determine which tab we're currently dragging over
1235
Point localPos = tabFolder.getControl().toControl(location);
1236        
1237        CTabItem tabUnderPointer = tabFolder.getItem(localPos);
1238
1239        // This drop target only deals with tabs... if we're not dragging over
1240
// a tab, exit.
1241
if (tabUnderPointer == null) {
1242            Rectangle titleArea = tabFolder.getTitleArea();
1243            
1244            // If we're dragging over the title area, treat this as a drop in the last
1245
// tab position.
1246
if (titleArea.contains(localPos)) {
1247                int dragOverIndex = tabFolder.getItemCount();
1248                CTabItem lastTab = tabFolder.getItem(dragOverIndex - 1);
1249
1250                // Can't drag to end unless you can see the end
1251
if (!lastTab.isShowing()) {
1252                    return null;
1253                }
1254                
1255                if (dragStart >= 0) {
1256                    dragOverIndex--;
1257
1258                    return new StackDropResult(Geometry.toDisplay(tabFolder.getControl(),
1259                            lastTab.getBounds()),
1260                        new Integer JavaDoc(dragOverIndex));
1261                }
1262
1263                // Make the drag-over rectangle look like a tab at the end of the tab region.
1264
// We don't actually know how wide the tab will be when it's dropped, so just
1265
// make it 3 times wider than it is tall.
1266
Rectangle dropRectangle = Geometry.toDisplay(tabFolder.getControl(), titleArea);
1267        
1268                dropRectangle.width = 3 * dropRectangle.height;
1269                return new StackDropResult(dropRectangle, new Integer JavaDoc(dragOverIndex));
1270                
1271            } else {
1272                return null;
1273            }
1274        }
1275        
1276        if (!tabUnderPointer.isShowing()) {
1277            return null;
1278        }
1279        
1280        return new StackDropResult(Geometry.toDisplay(tabFolder.getControl(), tabUnderPointer.getBounds()),
1281                new Integer JavaDoc(tabFolder.indexOf(tabUnderPointer)));
1282    }
1283        
1284    /**
1285     * Returns the toolbar control for the currently selected part, or null if none (not
1286     * all parts have a toolbar).
1287     *
1288     * @return the current toolbar or null if none
1289     */

1290    protected Control getCurrentToolbar() {
1291        Assert.isTrue(!isDisposed());
1292        
1293        IPresentablePart part = getCurrentPart();
1294        if (part == null) {
1295            return null;
1296        }
1297
1298        return part.getToolBar();
1299    }
1300    
1301    /* (non-Javadoc)
1302     * @see org.eclipse.ui.presentations.StackPresentation#showSystemMenu()
1303     */

1304    public void showSystemMenu() {
1305        Assert.isTrue(!isDisposed());
1306        
1307        IPresentablePart part = getCurrentPart();
1308        if (part != null) {
1309            Rectangle bounds = DragUtil.getDisplayBounds(tabFolder.getControl());
1310            
1311            int idx = tabFolder.getSelectionIndex();
1312            if (idx > -1) {
1313                CTabItem item = tabFolder.getItem(idx);
1314                Rectangle itemBounds = item.getBounds();
1315                
1316                bounds.x += itemBounds.x;
1317                bounds.y += itemBounds.y;
1318            }
1319            
1320            Point location = new Point(bounds.x, bounds.y + tabFolder.getTabHeight());
1321            showSystemMenu(location);
1322        }
1323    }
1324
1325    /* (non-Javadoc)
1326     * @see org.eclipse.ui.presentations.StackPresentation#getTabList(IPresentablePart)
1327     */

1328    public Control[] getTabList(IPresentablePart part) {
1329        Assert.isTrue(!isDisposed());
1330        
1331        ArrayList JavaDoc list = new ArrayList JavaDoc();
1332        if (tabFolder.getTabPosition() == SWT.BOTTOM) {
1333            if (part.getToolBar() != null) list.add(part.getToolBar());
1334            if (part.getControl() != null) list.add(part.getControl());
1335            if (getTabFolder() != null) list.add(getTabFolder().getControl());
1336        }
1337        else {
1338            if (getTabFolder() != null) list.add(getTabFolder().getControl());
1339            if (part.getToolBar() != null) list.add(part.getToolBar());
1340            if (part.getControl() != null) list.add(part.getControl());
1341        }
1342        return (Control[]) list.toArray(new Control[list.size()]);
1343    }
1344    
1345    protected void showList(Shell parentShell, int x, int y) {
1346        Assert.isTrue(!isDisposed());
1347        
1348        final PaneFolder tabFolder = getTabFolder();
1349
1350        int shellStyle = SWT.RESIZE | SWT.ON_TOP | SWT.NO_TRIM;
1351        int tableStyle = SWT.V_SCROLL | SWT.H_SCROLL;
1352        final BasicStackList editorList = new BasicStackList(tabFolder.getControl().getShell(),
1353                shellStyle, tableStyle);
1354        editorList.setInput(this);
1355        Point size = editorList.computeSizeHint();
1356        
1357        Monitor mon = getTabFolder().getControl().getMonitor();
1358        Rectangle bounds = mon.getClientArea();
1359        if (x + size.x > bounds.x + bounds.width) x = bounds.x + bounds.width - size.x;
1360        if (y + size.y > bounds.y + bounds.height) y = bounds.y + bounds.height - size.y;
1361        editorList.setLocation(new Point(x, y));
1362        editorList.setVisible(true);
1363        editorList.setFocus();
1364        editorList.getTableViewer().getTable().getShell().addListener(
1365                SWT.Deactivate, new Listener() {
1366
1367                    public void handleEvent(Event event) {
1368                        editorList.setVisible(false);
1369                    }
1370                });
1371    }
1372    
1373    /*
1374     * Shows the list of tabs at the top left corner of the editor
1375     */

1376    public void showPartList() {
1377        Assert.isTrue(!isDisposed());
1378        
1379        PaneFolder tabFolder = getTabFolder();
1380        Shell shell = tabFolder.getControl().getShell();
1381        
1382        // get the last visible item
1383
int numItems = tabFolder.getItemCount();
1384        CTabItem item = null, tempItem = null;
1385        for (int i = 0; i < numItems; i++) {
1386            tempItem = tabFolder.getItem(i);
1387            if (tempItem.isShowing())
1388                item = tempItem;
1389        }
1390        
1391        // if we have no visible tabs, abort.
1392
if (item == null)
1393            return;
1394        
1395        Rectangle itemBounds = item.getBounds();
1396        int x = itemBounds.x+itemBounds.width;
1397        int y = itemBounds.y + itemBounds.height;
1398        Point location = item.getDisplay().map(tabFolder.getControl(), null, x, y);
1399        showList(shell, location.x, location.y);
1400    }
1401    
1402    void setSelection(CTabItem tabItem) {
1403        getSite().selectPart(getPartForTab(tabItem));
1404    }
1405
1406    void close(IPresentablePart[] presentablePart) {
1407        getSite().close(presentablePart);
1408    }
1409    
1410    /**
1411     * Returns the List of IPresentablePart currently in this presentation
1412     */

1413    List JavaDoc getPresentableParts() {
1414        Assert.isTrue(!isDisposed());
1415        
1416        CTabItem[] items = tabFolder.getItems();
1417        List JavaDoc result = new ArrayList JavaDoc(items.length);
1418        
1419        for (int idx = 0; idx < tabFolder.getItemCount(); idx++) {
1420            result.add(getPartForTab(items[idx]));
1421        }
1422        
1423        return result;
1424    }
1425    
1426    Image getLabelImage(IPresentablePart presentablePart) {
1427        return presentablePart.getTitleImage();
1428    }
1429    
1430    String JavaDoc getLabelText(IPresentablePart presentablePart,
1431            boolean includePath) {
1432        String JavaDoc title = presentablePart.getName();
1433        return title;
1434    }
1435    
1436    /**
1437     * Answers whether the shell containing this presentation is currently the active shell.
1438     */

1439    protected boolean isShellActive() {
1440        Assert.isTrue(!isDisposed());
1441        
1442        return shellActive;
1443    }
1444}
1445
Popular Tags