blob: 4465e1830b703987a87c41a1d66d3373db2b15f3 [file] [log] [blame]
/************************************************************************
Copyright (c) 2000, 2003 IBM Corporation and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v10.html
Contributors:
IBM - Initial implementation
Cagatay Kavukcuoglu <cagatayk@acm.org> - Fix for bug 10025 - Resizing views should not use height ratios
************************************************************************/
package org.eclipse.ui.internal;
import java.util.*;
import java.util.List;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
/**
* Represents a tab folder of editors. This layout part
* container only accepts EditorPane parts.
*/
public class EditorWorkbook extends LayoutPart
implements ILayoutContainer, IPropertyListener
{
private static final int INACTIVE = 0;
private static final int ACTIVE_FOCUS = 1;
private static final int ACTIVE_NOFOCUS = 2;
private static int tabLocation = -1; // Initialized in constructor.
private int activeState = INACTIVE;
private boolean assignFocusOnSelection = true;
private boolean ignoreTabFocusHide = false;
private boolean handleTabSelection = true;
private boolean mouseDownListenerAdded = false;
private boolean isZoomed = false;
private Composite parent;
private CTabFolder tabFolder;
private IPropertyChangeListener tabFolderListener;
private EditorArea editorArea;
private EditorPane visibleEditor;
private Map mapPartToDragMonitor = new HashMap();
private Map mapTabToEditor = new HashMap();
private List editors = new ArrayList();
private ToolBar pullDownBar;
private ToolItem pullDownButton;
private EditorList editorList;
private ViewForm listComposite;
/**
* EditorWorkbook constructor comment.
*/
public EditorWorkbook(EditorArea editorArea) {
super("editor workbook");//$NON-NLS-1$
this.editorArea = editorArea;
// Each workbook has a unique ID so
// relative positioning is unambiguous.
setID(this.toString());
// Get tab location preference.
if (tabLocation == -1)
tabLocation = getPreferenceStore().getInt(
IPreferenceConstants.EDITOR_TAB_POSITION);
}
/**
* See ILayoutContainer::add
*
* Note: the workbook currently only accepts
* editor parts.
*/
public void add(LayoutPart part) {
if (part instanceof EditorPane) {
EditorPane editorPane = (EditorPane) part;
editors.add(editorPane);
editorPane.setWorkbook(this);
editorPane.setZoomed(isZoomed);
if (tabFolder != null) {
createTab(editorPane);
createPage(editorPane);
setVisibleEditor(editorPane);
}
}
}
/**
* See ILayoutContainer::allowBorder
*
* There is already a border around the tab
* folder so no need for one from the parts.
*/
public boolean allowsBorder() {
return false;
}
public void becomeActiveWorkbook(boolean hasFocus) {
EditorArea area = getEditorArea();
if (area != null)
area.setActiveWorkbook(this, hasFocus);
}
public void createControl(Composite parent) {
if (tabFolder != null)
return;
this.parent = parent;
tabFolder = new CTabFolder(parent, SWT.BORDER | tabLocation);
// listen for property change events on the folder
tabFolderListener =
new IPropertyChangeListener(){
public void propertyChange(PropertyChangeEvent event){
if(event.getProperty().equals(IPreferenceConstants.EDITOR_TAB_WIDTH_SCALAR)){
//TODO: Need API from SWT, this is a workaround
tabFolder.MIN_TAB_WIDTH = getPreferenceStore().getInt(IPreferenceConstants.EDITOR_TAB_WIDTH_SCALAR);
if (getPreferenceStore().getBoolean(IPreferenceConstants.EDITOR_LIST_PULLDOWN_ACTIVE)) {
tabFolder.setTopRight(pullDownBar);
pullDownBar.setVisible(tabFolder.getItemCount() >= 1);
} else {
pullDownBar.setVisible(false);
tabFolder.setTopRight(null);
}
}
if(event.getProperty().equals(IPreferenceConstants.EDITOR_LIST_PULLDOWN_ACTIVE)) {
if (getPreferenceStore().getBoolean(IPreferenceConstants.EDITOR_LIST_PULLDOWN_ACTIVE)) {
tabFolder.setTopRight(pullDownBar);
pullDownBar.setVisible(tabFolder.getItemCount() >= 1);
} else {
pullDownBar.setVisible(false);
tabFolder.setTopRight(null);
}
}
// if(event.getProperty().equals(IPreferenceConstants.NUMBER_EDITOR_TABS)){
// //TODO: editor tabs
// int numberOfTabs = WorkbenchPlugin.getDefault().getPreferenceStore().getInt(IPreferenceConstants.NUMBER_EDITOR_TABS);
// }
// if(event.getProperty().equals(IPreferenceConstants.EDITOR_TABS_SPAN_MULTIPLE_LINES)){
// boolean spanMultiple = WorkbenchPlugin.getDefault().getPreferenceStore().getBoolean(IPreferenceConstants.EDITOR_TABS_SPAN_MULTIPLE_LINES);
// //TODO: editor tabs
// }
}
};
IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
store.addPropertyChangeListener(tabFolderListener);
// prevent close button and scroll buttons from taking focus
tabFolder.setTabList(new Control[0]);
// redirect drop request to the workbook
tabFolder.setData((IPartDropTarget) this);
// listener to close the editor
tabFolder.addCTabFolderListener(new CTabFolderAdapter() {
public void itemClosed(CTabFolderEvent e) {
e.doit = false; // otherwise tab is auto disposed on return
EditorPane pane = (EditorPane) mapTabToEditor.get(e.item);
pane.doHide();
}
});
// listener to switch between visible tabItems
tabFolder.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (handleTabSelection) {
EditorPane pane = (EditorPane) mapTabToEditor.get(e.item);
// Pane can be null when tab is just created but not map yet.
if (pane != null) {
setVisibleEditor(pane);
if (assignFocusOnSelection) {
// If we get a tab focus hide request, it's from
// the previous editor in this workbook which had focus.
// Therefore ignore it to avoid paint flicker
ignoreTabFocusHide = true;
pane.setFocus();
ignoreTabFocusHide = false;
}
}
}
}
});
// listener to resize visible components
tabFolder.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event e) {
setControlSize();
}
});
// listen for mouse down on tab area to set focus.
tabFolder.addMouseListener(new MouseAdapter() {
public void mouseDoubleClick(MouseEvent event) {
doZoom();
}
public void mouseDown(MouseEvent e) {
if (visibleEditor != null) {
CTabItem item = getTab(visibleEditor);
// ctrl-click close the editor
if ((e.stateMask & SWT.CTRL) != 0) {
EditorPane pane = (EditorPane) mapTabToEditor.get(item);
pane.doHide();
item.dispose();
} else {
// switch to the editor
visibleEditor.setFocus();
Rectangle bounds = item.getBounds();
if(bounds.contains(e.x,e.y)) {
if (e.button == 3)
visibleEditor.showPaneMenu(tabFolder,new Point(e.x, e.y));
else if((e.button == 1) && overImage(item,e.x))
visibleEditor.showPaneMenu();
}
}
}
}
});
// register the interested mouse down listener
if (!mouseDownListenerAdded && getEditorArea() != null) {
tabFolder.addListener(SWT.MouseDown, getEditorArea().getMouseDownListener());
mouseDownListenerAdded = true;
}
// Enable drop target data
enableDrop(this);
// Create the pulldown menu on the CTabFolder
editorList = new EditorList(getEditorArea().getWorkbenchWindow(), this);
pullDownBar = new ToolBar(tabFolder, SWT.FLAT);
pullDownButton = new ToolItem(pullDownBar, SWT.PUSH);
Image pullDownButtonImage = WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_VIEW_MENU);
pullDownButton.setDisabledImage(pullDownButtonImage);
pullDownButton.setImage(pullDownButtonImage);
pullDownButton.setToolTipText(WorkbenchMessages.getString("Editors")); //$NON-NLS-1$
pullDownButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
openEditorList();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
// Present the editorList pull-down if requested
if (store.getBoolean(IPreferenceConstants.EDITOR_LIST_PULLDOWN_ACTIVE)) {
tabFolder.setTopRight(pullDownBar);
pullDownBar.setVisible(true);
} else {
pullDownBar.setVisible(false);
tabFolder.setTopRight(null);
}
// Set the tab width
tabFolder.MIN_TAB_WIDTH = store.getInt(IPreferenceConstants.EDITOR_TAB_WIDTH_SCALAR);
// Create tabs.
Iterator enum = editors.iterator();
while (enum.hasNext()) {
EditorPane pane = (EditorPane) enum.next();
createTab(pane);
createPage(pane);
}
// Set active tab.
if (visibleEditor != null)
setVisibleEditor(visibleEditor);
else
if (getItemCount() > 0)
setVisibleEditor((EditorPane) editors.get(0));
}
private void closeEditorList() {
editorList.destroyControl();
}
public void openEditorList() {
// don't think this check is necessary, need to verify
if (listComposite != null) {
return;
}
Shell parent = getEditorArea().getWorkbenchWindow().getShell();
listComposite = new ViewForm(parent, SWT.BORDER);
listComposite.setVisible(false);
listComposite.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
listComposite = null;
}
});
parent.addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
if (listComposite != null) {
closeEditorList();
}
}
});
Control editorListControl = editorList.createControl(listComposite);
editorListControl.setVisible(false);
Table editorsTable = ((Table)editorListControl);
TableItem[] items = editorsTable.getItems();
if (items.length == 0) {
listComposite.dispose();
return;
}
listComposite.setContent(editorListControl);
listComposite.pack();
setEditorListBounds(parent);
listComposite.setVisible(true);
listComposite.moveAbove(null);
editorListControl.setVisible(true);
editorListControl.setFocus();
editorsTable.showSelection();
editorListControl.addListener(SWT.Deactivate, new Listener() {
public void handleEvent(Event event) {
if (listComposite != null) {
closeEditorList();
}
}
});
}
private void setEditorListBounds(Shell parent) {
final int MAX_ITEMS = 20;
Rectangle r = listComposite.getBounds();
int width = r.width;
int height = Math.min(r.height, MAX_ITEMS * ((Table)editorList.getControl()).getItemHeight());
Rectangle bounds = tabFolder.getClientArea();
Point point = new Point(bounds.x + bounds.width - width, bounds.y);
if (tabLocation == SWT.BOTTOM) {
point.y = bounds.y + bounds.height - height - 1;
}
point = tabFolder.toDisplay(point);
point = parent.toControl(point);
listComposite.setBounds(listComposite.computeTrim(point.x, point.y, width, height));
}
public void resizeEditorList() {
Shell parent = getEditorArea().getWorkbenchWindow().getShell();
listComposite.pack();
setEditorListBounds(parent);
}
/**
* Show a title label menu for this pane.
*/
public void showPaneMenu() {
if (visibleEditor != null) {
CTabItem item = getTab(visibleEditor);
Rectangle bounds = item.getBounds();
visibleEditor.showPaneMenu(tabFolder,new Point(bounds.x,bounds.height));
}
}
/**
* Returns true if the mouse pointer is over the
* image of the tab's label
*/
/*package*/ boolean overImage(EditorPane pane, int x) {
CTabItem item = getTab(pane);
return overImage(item, x);
}
/*
* Return true if <code>x</code> is over the label image.
*/
private boolean overImage(CTabItem item,int x) {
Rectangle imageBounds = item.getImage().getBounds();
return x < (item.getBounds().x + imageBounds.x + imageBounds.width);
}
/**
* Create a page and tab for an editor.
*/
private void createPage(EditorPane editorPane) {
editorPane.createControl(parent);
editorPane.setContainer(this);
enableDrop(editorPane);
// Update tab to be in-sync after creation of
// pane's control since prop listener was not on
IEditorReference editorRef = editorPane.getEditorReference();
updateEditorTab(editorRef);
editorRef.addPropertyListener(this);
// When first editor added, also enable workbook for
// D&D - this avoids dragging the initial empty workbook
if (mapPartToDragMonitor.size() == 1)
enableTabDrag(this, null);
}
/**
* Create a new tab for an item.
*/
private CTabItem createTab(EditorPane editorPane) {
return createTab(editorPane, tabFolder.getItemCount());
}
/**
* Create a new tab for an item at a particular index.
*/
private CTabItem createTab(EditorPane editorPane, int index) {
CTabItem tab = new CTabItem(tabFolder, SWT.NONE, index);
mapTabToEditor.put(tab, editorPane);
enableTabDrag(editorPane, tab);
updateEditorTab((IEditorReference)editorPane.getPartReference());
if (tabFolder.getItemCount() == 1) {
if (tabFolder.getTopRight() != null) {
pullDownBar.setVisible(true);
}
}
return tab;
}
private void disableTabDrag(LayoutPart part) {
PartDragDrop partDragDrop = (PartDragDrop)mapPartToDragMonitor.get(part);
if (partDragDrop != null) {
partDragDrop.dispose();
mapPartToDragMonitor.remove(part);
}
}
/**
* See LayoutPart#dispose
*/
public void dispose() {
if (tabFolder == null)
return;
for (int i = 0; i < editors.size(); i++)
removeListeners((EditorPane)editors.get(i));
editors.clear();
//Reset the visible editor so that no references are made to it.
setVisibleEditor(null);
// dispose of disabled images
for(int i = 0; i < tabFolder.getItemCount(); i++) {
CTabItem tab = tabFolder.getItem(i);
if (tab.getDisabledImage() != null)
tab.getDisabledImage().dispose();
}
tabFolder.dispose();
tabFolder = null;
mouseDownListenerAdded = false;
mapTabToEditor.clear();
IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
store.removePropertyChangeListener(tabFolderListener);
}
/**
* Zooms in on the active page in this workbook.
*/
private void doZoom() {
if (visibleEditor == null)
return;
visibleEditor.getPage().toggleZoom(visibleEditor.getPartReference());
}
/**
* Draws the applicable gradient on the active tab
*/
/* package */ void drawGradient() {
if (tabFolder == null)
return;
Color fgColor;
Color[] bgColors;
int[] bgPercents;
switch (activeState) {
case ACTIVE_FOCUS :
if (getShellActivated()) {
fgColor = WorkbenchColors.getSystemColor(SWT.COLOR_TITLE_FOREGROUND);
bgColors = WorkbenchColors.getActiveEditorGradient();
bgPercents = WorkbenchColors.getActiveEditorGradientPercents();
}
else {
fgColor = WorkbenchColors.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND);
bgColors = WorkbenchColors.getDeactivatedEditorGradient();
bgPercents = WorkbenchColors.getDeactivatedEditorGradientPercents();
}
break;
case ACTIVE_NOFOCUS :
fgColor = WorkbenchColors.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
bgColors = WorkbenchColors.getActiveNoFocusEditorGradient();
bgPercents = WorkbenchColors.getActiveNoFocusEditorGradientPercents();
break;
case INACTIVE :
default :
fgColor = null;
bgColors = null;
bgPercents = null;
break;
}
tabFolder.setSelectionForeground(fgColor);
tabFolder.setSelectionBackground(bgColors, bgPercents);
tabFolder.update();
}
/**
* enableDrop
*/
private void enableDrop(LayoutPart part) {
Control control = part.getControl();
if (control != null)
control.setData((IPartDropTarget)this); // Use workbook as drop target, not part itself.
}
private void enableTabDrag(LayoutPart part, CTabItem tab) {
CTabPartDragDrop dragSource = new CTabPartDragDrop(part, this.tabFolder, tab);
mapPartToDragMonitor.put(part, dragSource);
dragSource.addDropListener(getEditorArea().getPartDropListener());
}
/**
* Gets the presentation bounds.
*/
public Rectangle getBounds() {
if (tabFolder == null)
return new Rectangle(0, 0, 0, 0);
return tabFolder.getBounds();
}
// getMinimumHeight() added by cagatayk@acm.org
/**
* @see LayoutPart#getMinimumHeight()
*/
public int getMinimumHeight() {
if (tabFolder != null && !tabFolder.isDisposed() && getItemCount() > 0)
/* Subtract 1 for divider line, bottom border is enough
* for editor tabs.
*/
return tabFolder.computeTrim(0, 0, 0, 0).height - 1;
else
return super.getMinimumHeight();
}
/**
* See ILayoutContainer::getChildren
*/
public LayoutPart[] getChildren() {
int nSize = editors.size();
LayoutPart [] children = new LayoutPart[nSize];
editors.toArray(children);
return children;
}
/**
* Get the part control. This method may return null.
*/
public Control getControl() {
return tabFolder;
}
/**
* Return the editor area to which this editor
* workbook belongs to.
*/
public EditorArea getEditorArea() {
return editorArea;
}
/**
* Answer the number of children.
*/
public int getItemCount() {
return editors.size();
}
/**
* Return the composite used to parent all
* editors within this workbook.
*/
public Composite getParent() {
return this.parent;
}
/**
* Returns the tab for a part.
*/
private CTabItem getTab(IEditorReference editorRef) {
Iterator tabs = mapTabToEditor.keySet().iterator();
PartPane pane = ((WorkbenchPartReference)editorRef).getPane();
while (tabs.hasNext()) {
CTabItem tab = (CTabItem) tabs.next();
PartPane p = (PartPane)mapTabToEditor.get(tab);
if (p != null && p == pane)
return tab;
}
return null;
}
/**
* Returns the tab for a part.
*/
private CTabItem getTab(LayoutPart child) {
Iterator tabs = mapTabToEditor.keySet().iterator();
while (tabs.hasNext()) {
CTabItem tab = (CTabItem) tabs.next();
if (mapTabToEditor.get(tab) == child)
return tab;
}
return null;
}
/**
* Returns the tab list to use when this workbook is active.
* Includes the active editor and its tab, in the appropriate order.
*/
public Control[] getTabList() {
if (tabFolder == null) {
return new Control[0];
}
if (visibleEditor == null) {
return new Control[] { tabFolder };
}
if ((tabFolder.getStyle() & SWT.TOP) != 0) {
return new Control[] { tabFolder, visibleEditor.getControl() };
}
else {
return new Control[] { visibleEditor.getControl(), tabFolder };
}
}
/**
* Returns the visible child.
*/
public EditorPane getVisibleEditor() {
return visibleEditor;
}
/**
* Returns true if this editor workbook is the
* active one within the editor area.
*/
public boolean isActiveWorkbook() {
return getEditorArea().isActiveWorkbook(this);
}
/**
* See LayoutPart
*/
public boolean isDragAllowed(Point p) {
if (isZoomed) {
return false;
} else if (getEditorArea().getEditorWorkbookCount() == 1) {
return false;
} else if (visibleEditor != null) {
if(!overImage(visibleEditor, p.x))
return true;
}
return false;
}
/**
* Open the tracker to allow the user to move
* the specified part using keyboard.
*/
public void openTracker(LayoutPart part) {
CTabPartDragDrop dnd = (CTabPartDragDrop)mapPartToDragMonitor.get(part);
dnd.openTracker();
}
/**
* Listen for notifications from the editor part
* that its title has change or it's dirty, and
* update the corresponding tab
*
* @see IPropertyListener
*/
public void propertyChanged(Object source, int property) {
if (property == IEditorPart.PROP_DIRTY || property == IWorkbenchPart.PROP_TITLE) {
if (source instanceof IEditorPart) {
updateEditorTab((IEditorPart)source);
}
}
}
/**
* See ILayoutContainer::remove
*
* Note: workbook only handles editor parts.
*/
public void remove(LayoutPart child) {
// Get editor position.
int tabIndex = editors.indexOf(child);
if (tabIndex < 0)
return;
// Dereference the old editor.
// This must be done before "show" to get accurate decorations.
editors.remove(child);
removeListeners((EditorPane)child);
// Show new editor
if (visibleEditor == child) {
EditorPane nextEditor = null;
int maxIndex = editors.size() - 1;
if (maxIndex >= 0) {
tabIndex = Math.min(tabIndex, maxIndex);
nextEditor = (EditorPane)editors.get(tabIndex);
}
if (tabFolder != null) {
// Dispose old editor.
removeTab(getTab(child));
child.setContainer(null);
if (tabFolder.getItemCount() == 0)
pullDownBar.setVisible(false);
}
setVisibleEditor(nextEditor);
} else if (tabFolder != null) {
// Dispose old editor.
removeTab(getTab(child));
child.setContainer(null);
if (tabFolder.getItemCount() == 0)
pullDownBar.setVisible(false);
}
}
/**
* See IVisualContainer#remove
*/
public void removeAll() {
// turn off tab selection handling so as
// not to activate another editor when a
// tab is disposed. See PR 1GBXAWZ
handleTabSelection = false;
// Show empty space.
setVisibleEditor(null);
// Dispose of all tabs.
if (tabFolder != null) {
Iterator tabs = mapTabToEditor.keySet().iterator();
while (tabs.hasNext()) {
CTabItem tab = (CTabItem) tabs.next();
if (tab.getDisabledImage() != null)
tab.getDisabledImage().dispose();
tab.dispose();
EditorPane child = (EditorPane)mapTabToEditor.get(tab);
removeListeners(child);
child.setContainer(null);
}
// disable the pulldown menu
pullDownBar.setVisible(false);
}
// Clean up
mapTabToEditor.clear();
editors.clear();
handleTabSelection = true;
}
private void removeListeners(EditorPane editor) {
if (editor == null)
return;
disableTabDrag(editor);
// When last editor removed, also disable workbook for
// D&D - this avoids dragging the initial empty workbook
if (mapPartToDragMonitor.size() == 1)
disableTabDrag(this);
editor.getPartReference().removePropertyListener(this);
}
/**
* Remove the tab item from the tab folder
*/
private void removeTab(CTabItem tab) {
if (tabFolder != null) {
if (tab != null) {
mapTabToEditor.remove(tab);
if (tab.getDisabledImage() != null)
tab.getDisabledImage().dispose();
// Note, that disposing of the tab causes the
// tab folder to select another tab and fires
// a selection event. In this situation, do
// not assign focus.
assignFocusOnSelection = false;
tab.dispose();
assignFocusOnSelection = true;
}
}
}
/**
* Reorder the tab representing the specified pane.
* If a tab exists under the specified x,y location,
* then move the tab before it, otherwise place it
* as the last tab.
*/
public void reorderTab(EditorPane pane, int x, int y) {
CTabItem sourceTab = getTab(pane);
if (sourceTab == null)
return;
// adjust the y coordinate to fall within the tab area
Point location = new Point(1, 1);
if ((tabFolder.getStyle() & SWT.BOTTOM) != 0)
location.y = tabFolder.getSize().y - 4; // account for 3 pixel border
// adjust the x coordinate to be within the tab area
if (x > location.x)
location.x = x;
// find the tab under the adjusted location.
CTabItem targetTab = tabFolder.getItem(location);
// no tab under location so move editor's tab to end
if (targetTab == null) {
// do nothing if already at the end
if (tabFolder.indexOf(sourceTab) != tabFolder.getItemCount() - 1)
reorderTab(pane, sourceTab, -1);
return;
}
// do nothing if over editor's own tab
if (targetTab == sourceTab)
return;
// do nothing if already before target tab
int sourceIndex = tabFolder.indexOf(sourceTab);
int targetIndex = tabFolder.indexOf(targetTab);
if (sourceIndex == targetIndex - 1)
return;
//Source is going to be dispose so the target index will change.
if (sourceIndex < targetIndex)
targetIndex--;
reorderTab(pane, sourceTab, targetIndex);
}
/**
* Move the specified editor to the a new position.
* Move to the end if <code>newIndex</code> is less then
* zero.
*/
public void reorderTab(EditorPane pane,int newIndex) {
reorderTab(pane,getTab(pane),newIndex);
}
/**
* Reorder the tab representing the specified pane.
*/
private void reorderTab(EditorPane pane, CTabItem sourceTab, int newIndex) {
// remember if the source tab was the visible one
boolean wasVisible = (tabFolder.getSelection() == sourceTab);
// Remove old tab.
disableTabDrag(pane);
removeTab(sourceTab);
// Create the new tab at the specified index
CTabItem newTab;
if (newIndex < 0)
newTab = createTab(pane);
else
newTab = createTab(pane, newIndex);
CTabPartDragDrop partDragDrop = (CTabPartDragDrop)mapPartToDragMonitor.get(pane);
partDragDrop.setTab(newTab);
// update order of editors.
editors.remove(pane);
if (newIndex < 0)
editors.add(pane);
else
editors.add(newIndex, pane);
// update the new tab's visibility but do
// not set focus...caller's responsibility.
// Note, if the pane already had focus, it
// will still have it after the tab order change.
if (wasVisible) {
tabFolder.setSelection(newTab);
setVisibleEditor(pane);
}
}
/**
* See ILayoutContainer::replace
*
* Note: this is not currently supported
*/
public void replace(LayoutPart oldPart, LayoutPart newPart) {
}
/**
* Sets the gradient state of the active tab
*/
private void setActiveState(int state) {
if (activeState != state) {
activeState = state;
drawGradient();
}
}
/**
* Sets the presentation bounds.
*/
public void setBounds(Rectangle r) {
if (tabFolder != null) {
tabFolder.setBounds(r);
setControlSize();
}
}
/**
* Sets the parent for this part.
*/
public void setContainer(ILayoutContainer container) {
super.setContainer(container);
// register the interested mouse down listener
if (!mouseDownListenerAdded && getEditorArea() != null && tabFolder != null) {
tabFolder.addListener(SWT.MouseDown, getEditorArea().getMouseDownListener());
mouseDownListenerAdded = true;
}
}
/**
* Set the size of a page in the folder.
*/
private void setControlSize() {
if (visibleEditor == null || tabFolder == null)
return;
Rectangle bounds = PartTabFolder.calculatePageBounds(tabFolder);
visibleEditor.setBounds(bounds);
visibleEditor.moveAbove(tabFolder);
}
public void setVisibleEditor(EditorPane comp) {
if (tabFolder == null) {
visibleEditor = comp;
return;
}
if(comp != null) {
//Make sure the EditorPart is created.
Object part = comp.getPartReference().getPart(true);
if(part == null)
comp = null;
}
// Hide old part. Be sure that it is not in the middle of closing
if (visibleEditor != null && visibleEditor != comp){
visibleEditor.setVisible(false);
}
// Show new part.
visibleEditor = comp;
if (visibleEditor != null) {
CTabItem key = getTab(visibleEditor);
if (key != null) {
int index = tabFolder.indexOf(key);
tabFolder.setSelection(index);
}
setControlSize();
if(visibleEditor != null)
visibleEditor.setVisible(true);
becomeActiveWorkbook(activeState == ACTIVE_FOCUS);
}
}
public void tabFocusHide() {
if (tabFolder == null || ignoreTabFocusHide)
return;
if (isActiveWorkbook())
setActiveState(ACTIVE_NOFOCUS);
else
setActiveState(INACTIVE);
}
public void tabFocusShow(boolean hasFocus) {
if (tabFolder == null)
return;
if (hasFocus)
setActiveState(ACTIVE_FOCUS);
else
setActiveState(ACTIVE_NOFOCUS);
}
/**
* @see IPartDropTarget::targetPartFor
*/
public LayoutPart targetPartFor(LayoutPart dragSource) {
if (dragSource instanceof EditorPane || dragSource instanceof EditorWorkbook)
return this;
else
return getEditorArea();
}
/**
* Update the tab for an editor. This is typically called
* by a site when the tab title changes.
*/
public void updateEditorTab(IEditorPart part) {
PartPane pane = ((EditorSite)part.getSite()).getPane();
String title = part.getTitle();
boolean isDirty = part.isDirty();
Image image = part.getTitleImage();
String toolTip = part.getTitleToolTip();
updateEditorTab(pane,title,isDirty,image,toolTip);
}
/**
* Update the tab for an editor. This is typically called
* by a site when the tab title changes.
*/
public void updateEditorTab(IEditorReference ref) {
PartPane pane = ((WorkbenchPartReference)ref).getPane();
String title = ref.getTitle();
boolean isDirty = ref.isDirty();
Image image = ref.getTitleImage();
String toolTip = ref.getTitleToolTip();
updateEditorTab(pane,title,isDirty,image,toolTip);
}
/**
* Update the tab for an editor. This is typically called
* by a site when the tab title changes.
*/
public void updateEditorTab(PartPane pane,String title,boolean isDirty,Image image,String toolTip) {
// Get tab.
CTabItem tab = getTab(pane);
if(tab == null) return;
// Update title.
if (isDirty)
title = "*" + title;//$NON-NLS-1$
tab.setText(title);
// Update the tab image
if (image == null || image.isDisposed()) {
// Normal image.
tab.setImage(null);
// Disabled image.
Image disableImage = tab.getDisabledImage();
if (disableImage != null) {
disableImage.dispose();
tab.setDisabledImage(null);
}
} else if (!image.equals(tab.getImage())) {
// Normal image.
tab.setImage(image);
// Disabled image.
Image disableImage = tab.getDisabledImage();
if (disableImage != null)
disableImage.dispose();
Display display = tab.getDisplay();
disableImage = new Image(display, image, SWT.IMAGE_DISABLE);
tab.setDisabledImage(disableImage);
}
// Tool tip.
tab.setToolTipText(toolTip);
tab.getParent().update();
}
/**
* Zoom in on the active part.
*/
public void zoomIn() {
if (isZoomed)
return;
isZoomed = true;
// Mark it's editors as zoom in
Iterator iterator = editors.iterator();
while (iterator.hasNext())
((EditorPane) iterator.next()).setZoomed(true);
}
/**
* Zoom out and show all editors.
*/
public void zoomOut() {
if (!isZoomed)
return;
isZoomed = false;
// Mark it's editors as zoom out
Iterator iterator = editors.iterator();
while (iterator.hasNext())
((EditorPane) iterator.next()).setZoomed(false);
}
/**
* Method getEditors.
* @return EditorPane
*/
public EditorPane [] getEditors() {
int nSize = editors.size();
EditorPane [] children = new EditorPane[nSize];
editors.toArray(children);
return children;
}
}