Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2010, 2014 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: IBM Corporation - initial API and implementation /
  
  package org.eclipse.e4.ui.workbench.addons.minmax;
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import  org.eclipse.e4.core.di.annotations.Optional;
  import  org.eclipse.e4.ui.di.UIEventTopic;
  import  org.eclipse.e4.ui.model.application.ui.MElementContainer;
  import  org.eclipse.e4.ui.model.application.ui.MGenericStack;
  import  org.eclipse.e4.ui.model.application.ui.MUIElement;
  import  org.eclipse.e4.ui.model.application.ui.MUILabel;
  import  org.eclipse.e4.ui.model.application.ui.SideValue;
  import  org.eclipse.e4.ui.model.application.ui.advanced.MArea;
  import  org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
  import  org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
  import  org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
  import  org.eclipse.e4.ui.model.application.ui.basic.MCompositePart;
  import  org.eclipse.e4.ui.model.application.ui.basic.MPart;
  import  org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
  import  org.eclipse.e4.ui.model.application.ui.basic.MStackElement;
  import  org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
  import  org.eclipse.e4.ui.model.application.ui.basic.MWindow;
  import  org.eclipse.e4.ui.model.application.ui.menu.MToolControl;
  import  org.eclipse.e4.ui.workbench.IPresentationEngine;
  import  org.eclipse.e4.ui.workbench.IResourceUtilities;
  import  org.eclipse.e4.ui.workbench.UIEvents;
  import  org.eclipse.e4.ui.workbench.UIEvents.EventTags;
  import  org.eclipse.e4.ui.workbench.modeling.EModelService;
  import  org.eclipse.e4.ui.workbench.modeling.EPartService;
  import  org.eclipse.e4.ui.workbench.renderers.swt.TrimmedPartLayout;
  import  org.eclipse.emf.common.util.URI;
  import  org.eclipse.swt.SWT;
  import  org.eclipse.swt.custom.CTabFolder;
  import  org.eclipse.swt.events.ControlEvent;
  import  org.eclipse.swt.events.ControlListener;
  import  org.eclipse.swt.events.DisposeEvent;
  import  org.eclipse.swt.events.DisposeListener;
  import  org.eclipse.swt.events.SelectionAdapter;
  import  org.eclipse.swt.events.SelectionEvent;
  import  org.eclipse.swt.events.SelectionListener;
  import  org.eclipse.swt.graphics.Image;
  import  org.eclipse.swt.graphics.Point;
  import  org.eclipse.swt.graphics.Rectangle;
  import  org.eclipse.swt.widgets.Composite;
  import  org.eclipse.swt.widgets.Control;
  import  org.eclipse.swt.widgets.Event;
  import  org.eclipse.swt.widgets.Listener;
  import  org.eclipse.swt.widgets.Menu;
  import  org.eclipse.swt.widgets.MenuItem;
  import  org.eclipse.swt.widgets.Shell;
  import  org.eclipse.swt.widgets.ToolBar;
  import  org.eclipse.swt.widgets.ToolItem;
Class for representing window trim containing minimized views and shared areas
  
  public class TrimStack {

Contribution URI for this class
  
  	public static String CONTRIBUTION_URI = "bundleclass://org.eclipse.e4.ui.workbench.addons.swt/org.eclipse.e4.ui.workbench.addons.minmax.TrimStack"//$NON-NLS-1$
  
  	private static final String LAYOUT_ICON_URI = "platform:/plugin/org.eclipse.e4.ui.workbench.addons.swt/icons/full/obj16/layout_co.gif"//$NON-NLS-1$
  
  	private static final String RESTORE_ICON_URI = "platform:/plugin/org.eclipse.e4.ui.workbench.addons.swt/icons/full/etool16/fastview_restore.gif"//$NON-NLS-1$
  
  	public static final String USE_OVERLAYS_KEY = "UseOverlays"//$NON-NLS-1$
  
  	static final String STATE_XSIZE = "XSize"//$NON-NLS-1$
  
  	static final String STATE_YSIZE = "YSize"//$NON-NLS-1$
  
  	public static final String MINIMIZED_AND_SHOWING = "MinimizedAndShowing"//$NON-NLS-1$
  
  	private Image layoutImage;
  
  	private Image restoreImage;
 
 	private ToolBar trimStackTB;

The context menu for this trim stack's items.
 
 	private Menu trimStackMenu;
 
 	private boolean cachedUseOverlays = true;
 	private boolean isShowing = false;
 	private MUIElement minimizedElement;
 	// private Composite clientAreaComposite;
 	private Composite hostPane;
 
 	@Named("org.eclipse.e4.ui.workbench.IResourceUtilities")
 	private IResourceUtilities<ImageDescriptorresUtils;

A map of created images from a part's icon URI path.
 
 	private Map<String, Image> imageMap = new HashMap<String, Image>();
 
 	ControlListener caResizeListener = new ControlListener() {
 		public void controlResized(ControlEvent e) {
 			if ( != null && .isVisible())
 		}
 
 		public void controlMoved(ControlEvent e) {
 		}
 	};
 
 	// Listens to ESC and closes the active fast view
 	private Listener escapeListener = new Listener() {
 		public void handleEvent(Event event) {
 			if (event.character == SWT.ESC) {
 				showStack(false);
 				.requestActivation();
 			}
 		}
 	};
 
 	EModelService modelService;
 
 	EPartService partService;
 
 	MWindow window;
 
 	MToolControl toolControl;
 
 
 	@Optional
 	private void subscribeTopicTagsChanged(
 			@UIEventTopic(UIEvents.ApplicationElement.TOPIC_TAGS) org.osgi.service.event.Event event) {
 		Object changedObj = event.getProperty(EventTags.ELEMENT);
 
 		if (!(changedObj instanceof MToolControl))
 			return;
 
 		final MToolControl changedElement = (MToolControl) changedObj;
 		if (changedElement.getObject() != this)
 			return;
 
 		if (UIEvents.isREMOVE(event)) {
 			if (UIEvents.contains(event, UIEvents.EventTags.OLD_VALUE, )) {
 				showStack(false);
 			}
 		}
 	}
 
 	private Image getOverrideImage(MUIElement element) {
 		Image result = null;
 
 		Object imageObject = element.getTransientData().get(
 				IPresentationEngine.OVERRIDE_ICON_IMAGE_KEY);
 		if (imageObject != null && imageObject instanceof Image
 				&& !((Image) imageObject).isDisposed())
 			result = (Image) imageObject;
 		return result;
 	}
 
 	private String getOverrideTitleToolTip(MUIElement element) {
 		String result = null;
 
 		Object stringObject = element.getTransientData().get(
 				IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY);
 		if (stringObject != null && stringObject instanceof String)
 			result = (StringstringObject;
 
 		if (result == null || result.length() == 0)
 			return null;
 
 		if (element instanceof MUILabel) {
 			String label = ((MUILabel)element).getLocalizedLabel();
 			if (label != null && label.length() > 0) {
 				result = label + ' ' + '(' + result + ')';
 			}
 		}
 
 		return result;
 	}

This is the new way to handle UIEvents (as opposed to subscring and unsubscribing them with the event broker. The method is described in detail at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
 
 	@SuppressWarnings("unchecked")
 	@Optional
 	private void handleTransientDataEvents(
 			@UIEventTopic(UIEvents.ApplicationElement.TOPIC_TRANSIENTDATA) org.osgi.service.event.Event event) {
 		// Prevent exceptions on shutdown
 		if ( == null || .isDisposed() || .getWidget() == null)
 			return;
 
 		MUIElement changedElement = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
 
 		String key;
 		if (UIEvents.isREMOVE(event)) {
 			key = ((Entry<StringObject>) event.getProperty(UIEvents.EventTags.OLD_VALUE))
 					.getKey();
 		} else {
 			key = ((Entry<StringObject>) event.getProperty(UIEvents.EventTags.NEW_VALUE))
 					.getKey();
 		}
 
 		if (key.equals(IPresentationEngine.OVERRIDE_ICON_IMAGE_KEY)) {
 			ToolItem toolItem = getChangedToolItem(changedElement);
 			if (toolItem != null)
 				toolItem.setImage(getImage((MUILabel) toolItem.getData()));
 		} else if (key.equals(IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY)) {
 			ToolItem toolItem = getChangedToolItem(changedElement);
 			if (toolItem != null)
 				toolItem.setToolTipText(getLabelText((MUILabel) toolItem.getData()));
 		}
 	}
 
 	private ToolItem getChangedToolItem(MUIElement changedElement) {
 		ToolItem[] toolItems = .getItems();
 		for (ToolItem toolItem : toolItems) {
 			if (changedElement.equals(toolItem.getData())) {
 				return toolItem;
 			}
 		}
 		return null;
 	}

This is the old way to subscribe to UIEvents. You should consider using the new way as shown by handleTransientDataEvents() and described in the article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
 
 	private EventHandler closeHandler = new EventHandler() {
 		public void handleEvent(org.osgi.service.event.Event event) {
 			if (!)
 				return;
 
 			// The only time we don't close is if I've selected my tab.
 			MUIElement changedElement = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
 
 			// Perspective changed, close the visible stacks
 			if (changedElement instanceof MPerspectiveStack) {
 				showStack(false);
 				return;
 			}
 
 			if (changedElement instanceof MCompositePart) {
 				MPart innerPart = getLeafPart(changedElement);
 				if (innerPart != null) {
 					return;
 				}
 			}
 
 			if (changedElement == getLeafPart()) {
 				return;
 			}
 
 			showStack(false);
 		}
 	};
 	
 	// Close any open stacks before shutting down
 	private EventHandler shutdownHandler = new EventHandler() {
 		public void handleEvent(org.osgi.service.event.Event event) {
 			showStack(false);
 		}
 	};
 
 	private void fixToolItemSelection() {
 		if ( == null || .isDisposed())
 			return;
 
 		if (!) {
 			// Not open...no selection
 			for (ToolItem item : .getItems()) {
 				item.setSelection(false);
 			}
 		} else {
 			if (isEditorStack() ||  instanceof MPlaceholder) {
 				.getItem(1).setSelection(true);
 			} else if (isPerspectiveStack()) {
 				MPerspectiveStack pStack = (MPerspectiveStack) ;
 				MUIElement selElement = pStack.getSelectedElement();
 				for (ToolItem item : .getItems()) {
 					item.setSelection(item.getData() == selElement);
 				}
 			} else {
 				MPartStack partStack = (MPartStack) ;
 				MUIElement selElement = partStack.getSelectedElement();
 				if (selElement instanceof MPlaceholder)
 					selElement = ((MPlaceholder) selElement).getRef();
 
 				for (ToolItem item : .getItems()) {
 					boolean isSel = item.getData() == selElement;
 					item.setSelection(isSel);
 				}
 			}
 		}
 	}
 
 	private boolean isEditorStack() {
 		if (!( instanceof MPlaceholder))
 			return false;
 
 		MPlaceholder ph = (MPlaceholder) ;
 		return ph.getRef() instanceof MArea;
 	}
 
 	private boolean isPerspectiveStack() {
 		return  instanceof MPerspectiveStack;
 	}
 
 	private MPart getLeafPart(MUIElement element) {
 		if (element instanceof MPlaceholder)
 			return getLeafPart(((MPlaceholder) element).getRef());
 
 		if (element instanceof MElementContainer<?>)
 			return getLeafPart(((MElementContainer<?>) element).getSelectedElement());
 
 		if (element instanceof MPart)
 			return (MPart) element;
 
 		return null;
 	}

This is the old way to subscribe to UIEvents. You should consider using the new way as shown by handleTransientDataEvents() and described in the article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
 
 	private EventHandler openHandler = new EventHandler() {
 		public void handleEvent(org.osgi.service.event.Event event) {
 			if ()
 				return;
 
 			MUIElement changedElement = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
 
 			// Open if shared area
 			if (getLeafPart() == changedElement
 					&& !( instanceof MPerspectiveStack)) {
 				showStack(true);
 				return;
 			}
 
 			MUIElement selectedElement = null;
 
 			if ( instanceof MPlaceholder) {
 				selectedElement = ((MPlaceholder) ).getRef();
 			} else if ( instanceof MPartStack) {
 				selectedElement = ((MPartStack) ).getSelectedElement();
 			}
 
 			if (selectedElement == null)
 				return;
 
 			if (selectedElement instanceof MPlaceholder)
 				selectedElement = ((MPlaceholder) selectedElement).getRef();
 
 			if (changedElement != selectedElement)
 				return;
 
 			showStack(true);
 		}
 	};

This is the old way to subscribe to UIEvents. You should consider using the new way as shown by handleTransientDataEvents() and described in the article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
 
 		public void handleEvent(org.osgi.service.event.Event event) {
 			if ( == null ||  == null)
 				return;
 
 			MUIElement changedElement = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
 
 			// if our stack is going away, so should we
 			if (changedElement ==  && !.isToBeRendered()) {
 				return;
 			}
 
 			// if one of the kids changes state, re-scrape the CTF
 			MUIElement parentElement = changedElement.getParent();
 			if (parentElement == ) {
 				.getDisplay().asyncExec(new Runnable() {
 					public void run() {
 					}
 				});
 			}
 		}
 	};

This is the old way to subscribe to UIEvents. You should consider using the new way as shown by handleTransientDataEvents() and described in the article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
 
 	private EventHandler childrenHandler = new EventHandler() {
 		public void handleEvent(org.osgi.service.event.Event event) {
 			if ( == null ||  == null)
 				return;
 
 			Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT);
 
 			// if a child has been added or removed, re-scape the CTF
 			if (changedObj == ) {
 				.getDisplay().asyncExec(new Runnable() {
 					public void run() {
 					}
 				});
 			}
 		}
 	};

This is the old way to subscribe to UIEvents. You should consider using the new way as shown by handleTransientDataEvents() and described in the article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
 
 	private EventHandler widgetHandler = new EventHandler() {
 		public void handleEvent(org.osgi.service.event.Event event) {
 			Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT);
 			if (changedObj != )
 				return;
 
 			if (.getWidget() != null) {
 				.getDisplay().asyncExec(new Runnable() {
 					public void run() {
 					}
 				});
 			}
 		}
 	};

This is the old way to subscribe to UIEvents. You should consider using the new way as shown by handleTransientDataEvents() and described in the article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
 
 	// Listener attached to every ToolItem in a TrimStack. Responsible for activating the
 	// appropriate part.
 	private SelectionListener toolItemSelectionListener = new SelectionListener() {
 		public void widgetSelected(SelectionEvent e) {
 			ToolItem toolItem = (ToolItem) e.widget;
 			MUIElement uiElement = (MUIElement) toolItem.getData();
 
 			// Clicking on the already showing item ? NOTE: the selection will already have been
 			// turned off by the time the event arrives
 			if (!toolItem.getSelection()) {
 				.requestActivation();
 				showStack(false);
 				return;
 			}
 
 			if (uiElement instanceof MPart) {
 				.activate((MPart) uiElement);
 			} else if (uiElement instanceof MPerspective) {
 				uiElement.getParent().setSelectedElement(uiElement);
 			}
 			showStack(true);
 		}
 
 		public void widgetDefaultSelected(SelectionEvent e) {
 		}
 	};
 
 	// private MTrimBar bar;
 
 	private int fixedSides;
 
 	private Composite originalParent;

This is the old way to subscribe to UIEvents. You should consider using the new way as shown by handleTransientDataEvents() and described in the article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
 
 	void addListeners() {
 		.subscribe(UIEvents.ElementContainer.TOPIC_CHILDREN, );
 		.subscribe(UIEvents.UIElement.TOPIC_TOBERENDERED, );
 		.subscribe(UIEvents.UIElement.TOPIC_WIDGET, );
 		.subscribe(UIEvents.UILifeCycle.BRINGTOTOP, );
 		.subscribe(UIEvents.UILifeCycle.ACTIVATE, );
 		.subscribe(UIEvents.UILifeCycle.APP_SHUTDOWN_STARTED, );
 	}
 
 	private Composite getCAComposite() {
 		if ( == null)
 			return null;
 
 		// Get the shell's client area composite
 		Shell theShell = .getShell();
 		if (theShell.getLayout() instanceof TrimmedPartLayout) {
 			TrimmedPartLayout tpl = (TrimmedPartLayout) theShell.getLayout();
 			if (!tpl.clientArea.isDisposed())
 				return tpl.clientArea;
 		}
 		return null;
 	}

This is the old way to subscribe to UIEvents. You should consider using the new way as shown by handleTransientDataEvents() and described in the article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
 
 	void removeListeners() {
 	}
 
 	void createWidget(Composite parent, MToolControl meCSSRenderingUtils cssUtils) {
 		if ( == null) {
 		}
 
 		MUIElement meParent = me.getParent();
 		int orientation = SWT.HORIZONTAL;
 		if (meParent instanceof MTrimBar) {
 			MTrimBar bar = (MTrimBar) meParent;
 			if (bar.getSide() == SideValue.RIGHT || bar.getSide() == SideValue.LEFT)
 				orientation = SWT.VERTICAL;
 		}
 		 = new ToolBar(parentorientation | SWT.FLAT | SWT.WRAP);
 		.addDisposeListener(new DisposeListener() {
 			public void widgetDisposed(DisposeEvent e) {
 				showStack(false);
 
 				 = null;
 				 = null;
 			}
 		});
 
 		.addListener(SWT.MenuDetect, new Listener() {
 			public void handleEvent(Event event) {
 				// Clear any existing menus
 				while (.getItemCount() > 0)
 					.getItem(0).dispose();
 
 				// Only open the menu if a tool item is selected
 				Point point = .getDisplay().map(null,
 						new Point(event.x, event.y));
 				ToolItem selectedToolItem = .getItem(point);
 				if (selectedToolItem == null) {
 					return;
 				}
 
 				// Are we hovering over a valid tool item (vs restore button)
 				Object data = selectedToolItem.getData();
 				if (data instanceof MPart) {
 					// A part on a stack or editor area
 					createPartMenu((MPart) data);
 				} else if (data instanceof MPerspective) {
 					// A perspective in a perspective stack (for now we just support restore)
 				} else if (isEditorStack()) {
 					// An empty editor area
 				} else {
 				}
 			}
 		});
 
 		 = new Menu();
 
 		ToolItem restoreBtn = new ToolItem(, SWT.PUSH);
 		restoreBtn.setToolTipText(.);
 		restoreBtn.setImage(getRestoreImage());
 		restoreBtn.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
 				.getTags().remove(IPresentationEngine.MINIMIZED);
 			}
 		});
 
 	}

Creates a restore menu item that removes the minimized tag from the minimizedElement
 
 	private void createEmtpyEditorAreaMenu() {
 		MenuItem restoreItem = new MenuItem(, SWT.NONE);
 		restoreItem.setText(.);
 		restoreItem.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
 				.getTags().remove(IPresentationEngine.MINIMIZED);
 			}
 		});
 	}

Creates a restore menu item that removes the minimized tag from the minimizedElement
 
 	private void createUseOverlaysMenu() {
 		MenuItem useOverlaysItem = new MenuItem(, SWT.CHECK);
 		useOverlaysItem.setSelection(!useOverlays());
 		useOverlaysItem.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
 				if ( != null) {
 					.getPersistedState().put(,
 							Boolean.toString(!useOverlays()));
 				}
 			}
 		});
 	}

Creates a series of menu items when a part is selected. The orientation submenu changes the layout tags on the minimizedElement. The restore item will remove the minimized tag. The close item is not available on the editor stack, but will ask the part service to hide the part.

Parameters:
selectedPart the part from the data of the selected tool item
 
 	private void createPartMenu(final MPart selectedPart) {
 		MenuItem orientationItem = new MenuItem(, SWT.CASCADE);
 		orientationItem.setText(.);
 		Menu orientationMenu = new Menu(orientationItem);
 		orientationItem.setMenu(orientationMenu);
 
 		MenuItem defaultItem = new MenuItem(orientationMenu, SWT.RADIO);
 		defaultItem.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
 				boolean doRefresh = .getTags().remove(
 						IPresentationEngine.ORIENTATION_HORIZONTAL);
 				doRefresh |= .getTags().remove(
 						IPresentationEngine.ORIENTATION_VERTICAL);
 				if ( && doRefresh) {
 				}
 			}
 		});
 
 		MenuItem horizontalItem = new MenuItem(orientationMenu, SWT.RADIO);
 		horizontalItem.setText(.);
 		horizontalItem.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
 				if (!.getTags()
 						.contains(IPresentationEngine.ORIENTATION_HORIZONTAL)) {
 					.getTags().remove(IPresentationEngine.ORIENTATION_VERTICAL);
 					.getTags().add(IPresentationEngine.ORIENTATION_HORIZONTAL);
 					if () {
 					}
 				}
 			}
 		});
 
 		MenuItem verticalItem = new MenuItem(orientationMenu, SWT.RADIO);
 		verticalItem.setText(.);
 		verticalItem.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
 				if (!.getTags().contains(IPresentationEngine.ORIENTATION_VERTICAL)) {
 					.getTags().remove(IPresentationEngine.ORIENTATION_HORIZONTAL);
 					.getTags().add(IPresentationEngine.ORIENTATION_VERTICAL);
 					if () {
 					}
 				}
 			}
 		});
 
 		// Set initial orientation selection
 		if (.getTags().contains(IPresentationEngine.ORIENTATION_HORIZONTAL)) {
 			horizontalItem.setSelection(true);
 		} else if (.getTags().contains(IPresentationEngine.ORIENTATION_VERTICAL)) {
 			verticalItem.setSelection(true);
 		} else {
 			defaultItem.setSelection(true);
 		}
 
 		MenuItem restoreItem = new MenuItem(, SWT.NONE);
 		restoreItem.setText(.);
 		restoreItem.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
 				.getTags().remove(IPresentationEngine.MINIMIZED);
 				.activate(selectedPart);
 			}
 		});
 
 		// Do not allow the shared editor area to be closed
 		if (!isEditorStack()) {
 			MenuItem closeItem = new MenuItem(, SWT.NONE);
 			closeItem.setText(.);
 			closeItem.addListener(SWT.Selection, new Listener() {
 				public void handleEvent(Event event) {
 					.hidePart(selectedPart);
 				}
 			});
 		}
 	}
 
 	void destroy() {
 		for (Image image : .values()) {
 			image.dispose();
 		}
 
 		if ( != null) {
 			.dispose();
 			 = null;
 		}
 
 		if ( != null) {
 			.dispose();
 			 = null;
 		}
 	}
 
 	public MUIElement getMinimizedElement() {
 	}
 
 	private MUIElement findElement() {
 		MUIElement result;
 		List<MPerspectiveStack> ps = .findElements(null,
 				MPerspectiveStack.classnull);
 		if (ps.size() == 0) {
 			String toolControlId = .getElementId();
 			int index = toolControlId.indexOf('(');
 			String stackId = toolControlId.substring(0, index);
 			result = .find(stackId);
 		} else {
 			String toolControlId = .getElementId();
 			int index = toolControlId.indexOf('(');
 			String stackId = toolControlId.substring(0, index);
 			String perspId = toolControlId.substring(index + 1, toolControlId.length() - 1);
 			MPerspective persp = (MPerspective) .find(perspIdps.get(0));
 			if (persp != null) {
 				result = .find(stackIdpersp);
 			} else {
 				result = .find(stackId);
 			}
 		}
 
 		return result;
 	}
 
 	private String getLabelText(MUILabel label) {
 		// Use override text if available
 		if (label instanceof MUIElement) {
 			String text = getOverrideTitleToolTip((MUIElement) label);
 			if (text != null && text.length() > 0)
 				return text;
 		}
 
 		String string = label.getLocalizedLabel();
 		return string == null ? "" : string//$NON-NLS-1$
 	}
 
 	private Image getImage(MUILabel element) {
 		// Use override image if available
 		if (element instanceof MUIElement) {
 			Image image = getOverrideImage((MUIElement) element);
 			if (image != null)
 				return image;
 		}
 
 		String iconURI = element.getIconURI();
 		if (iconURI != null && iconURI.length() > 0) {
 			Image image = .get(iconURI);
 			if (image == null) {
 				image = .imageDescriptorFromURI(URI.createURI(iconURI)).createImage();
 				.put(iconURIimage);
 			}
 			return image;
 		}
 
 		return null;
 	}
 
 	private MUILabel getLabelElement(MUIElement element) {
 		if (element instanceof MPlaceholder)
 			element = ((MPlaceholder) element).getRef();
 
 		return (MUILabel) (element instanceof MUILabel ? element : null);
 	}
 
 	private void updateTrimStackItems() {
 		// Prevent exceptions on shutdown
 		if ( == null || .isDisposed() || .getWidget() == null)
 			return;
 
 		// Remove any current items except the 'restore' button
 		while (.getItemCount() > 1) {
 			.getItem(.getItemCount() - 1).dispose();
 		}
 
 		if (isEditorStack() && .getItemCount() == 1) {
 			ToolItem ti = new ToolItem(, SWT.CHECK);
 			ti.setImage(getLayoutImage());
 			ti.addSelectionListener();
 		} else if ( instanceof MPlaceholder) {
 			MPlaceholder ph = (MPlaceholder) ;
 			if (ph.getRef() instanceof MPart) {
 				MPart part = (MPart) ph.getRef();
 				ToolItem ti = new ToolItem(, SWT.CHECK);
 				ti.setData(part);
 				ti.setImage(getImage(part));
 				ti.setToolTipText(getLabelText(part));
 				ti.addSelectionListener();
 			}
 		} else if ( instanceof MGenericStack<?>) {
 			// Handle *both* PartStacks and PerspectiveStacks here...
 			MGenericStack<?> theStack = (MGenericStack<?>) ;
 
 			// check to see if this stack has any valid elements
 			boolean hasRenderedElements = false;
 			for (MUIElement stackElement : theStack.getChildren()) {
 				if (stackElement.isToBeRendered()) {
 					hasRenderedElements = true;
 					break;
 				}
 			}
 
 			if (hasRenderedElements) {
 				for (MUIElement stackElement : theStack.getChildren()) {
 					if (!stackElement.isToBeRendered()) {
 						continue;
 					}
 
 					MUILabel labelElement = getLabelElement(stackElement);
 					ToolItem newItem = new ToolItem(, SWT.CHECK);
 					newItem.setData(labelElement);
 					newItem.setImage(getImage(labelElement));
 					newItem.setToolTipText(getLabelText(labelElement));
 					newItem.addSelectionListener();
 				}
 			} else if (theStack.getTags().contains(IPresentationEngine.NO_AUTO_COLLAPSE)) {
 				// OK to be empty and still minimized
 				ToolItem ti = new ToolItem(, SWT.CHECK);
 				ti.setImage(getLayoutImage());
 				ti.addSelectionListener();
 			} else {
 				// doesn't have any children that's showing, place it back in the presentation
 				return;
 			}
 		}
 
 		.pack();
 		.getShell().layout(new Control[] {  }, SWT.DEFER);
 	}
 
 	void restoreStack() {
 		showStack(false);
 
 		.setVisible(true);
 		.getTags().remove(IPresentationEngine.MINIMIZED);
 
 		// Activate the part that is being brought up...
 		if ( instanceof MPartStack) {
 			MPartStack theStack = (MPartStack) ;
 			MStackElement curSel = theStack.getSelectedElement();
 			Control ctrl = (Control) .getWidget();
 
 			// Hack for elems that are lazy initialized
 			if (ctrl instanceof CTabFolder && ((CTabFolder) ctrl).getSelection() == null) {
 				theStack.setSelectedElement(null);
 				theStack.setSelectedElement(curSel);
 			}
 		}
 
 		.setToBeRendered(false);
 
 		if ( != null && !.isDisposed())
 			.dispose();
 		 = null;
 	}

Sets whether this stack should be visible or hidden

Parameters:
show whether the stack should be visible
 
 	public void showStack(boolean show) {
 		Control ctrl = (Control) .getWidget();
 		CTabFolder ctf = ctrl instanceof CTabFolder ? (CTabFolder) ctrl : null;
 
 		Composite clientAreaComposite = getCAComposite();
 		if (clientAreaComposite == null || clientAreaComposite.isDisposed())
 			return;
 
 		if (show && !) {
 			if (useOverlays()) {
 				 = ctrl.getParent();
 				ctrl.setParent();
 
 				// Hack ! Force a resize of the CTF to make sure the hosted
 				// view is the correct size...see bug 434062 for details
 				if (ctf != null) {
 					Rectangle bb = ctf.getBounds();
 					bb.width--;
 					ctf.setBounds(bb);
 				}
 
 				clientAreaComposite.addControlListener();
 
 				// Set the initial location
 
 				.addListener(SWT.Traverse, );
 
 				.layout(true);
 				.moveAbove(null);
 				.setVisible(true);
 
 				// Cache the value to ensure that a stack is hidden using the same mode it was
 				// opened in
 			} else {
 				.setVisible(true);
 				ctrl.addListener(SWT.Traverse, );
 
 				// Cache the value to ensure that a stack is hidden using the same mode it was
 				// opened in
 				 = false;
 			}
 
 			 = true;
 
 			// Activate the part that is being brought up...
 			if ( instanceof MPartStack) {
				MPartStack theStack = (MPartStack) ;
				MStackElement curSel = theStack.getSelectedElement();
				// Hack for elems that are lazy initialized
				if (ctf != null && ctf.getSelection() == null) {
					theStack.setSelectedElement(null);
					theStack.setSelectedElement(curSel);
				if (curSel instanceof MPart) {
					.activate((MPart) curSel);
else if (curSel instanceof MPlaceholder) {
					MPlaceholder ph = (MPlaceholder) curSel;
					if (ph.getRef() instanceof MPart) {
						.activate((MPart) ph.getRef());
else if (isEditorStack()) {
				MArea area = (MArea) ((MPlaceholder) ).getRef();
				// See if we can find an element to activate...
				MPart partToActivate = null;
				MUIElement selectedElement = area.getSelectedElement();
				while (partToActivate == null && selectedElement != null) {
					if (selectedElement instanceof MPart) {
						partToActivate = (MPart) selectedElement;
else if (selectedElement instanceof MPlaceholder) {
						MPlaceholder ph = (MPlaceholder) selectedElement;
						if (ph.getRef() instanceof MPart) {
							partToActivate = (MPart) ph.getRef();
else {
							selectedElement = null;
else if (selectedElement instanceof MElementContainer<?>) {
						MElementContainer<?> container = (MElementContainer<?>) selectedElement;
						selectedElement = (MElementContainer<?>) container.getSelectedElement();
				// If we haven't found one then use the first
				if (partToActivate == null) {
					List<MPart> parts = .findElements(areanull, MPart.classnull);
					if (parts.size() > 0)
						partToActivate = parts.get(0);
				if (partToActivate != null) {
					.activate(partToActivate);
else if ( instanceof MPlaceholder) {
				MPlaceholder ph = (MPlaceholder) ;
				if (ph.getRef() instanceof MPart) {
					MPart part = (MPart) ph.getRef();
					.activate(part);
else if (!show && ) {
				// Check to ensure that the client area is non-null since the
				// trimstack may be currently hosted in the limbo shell
				if (clientAreaComposite != null) {
					clientAreaComposite.removeControlListener();
				ctrl.setParent();
				.dispose();
				 = null;
else {
				if (ctrl != null && !ctrl.isDisposed())
					ctrl.removeListener(SWT.Traverse, );
				.setVisible(false);
			 = false;
	}

Returns:
'true' iff the minimized stack should overlay the current presentation, 'false' means to temporarily restore the stack into the current presentation.
	private boolean useOverlays() {
		if ( == null)
			return true;
		String useOverlays = .getPersistedState().get();
		if (useOverlays == null)
			useOverlays = "true"//$NON-NLS-1$
		return Boolean.parseBoolean(useOverlays);
	private void setPaneLocation() {
		Composite clientAreaComposite = getCAComposite();
		if (clientAreaComposite == null || clientAreaComposite.isDisposed())
			return;
		Rectangle caRect = clientAreaComposite.getBounds();
		// NOTE: always starts in the persisted (or default) size
		Point paneSize = .getSize();
		// Ensure it's not clipped
		if (paneSize.x > caRect.width)
			paneSize.x = caRect.width;
		if (paneSize.y > caRect.height)
			paneSize.y = caRect.height;
		if (.getTags().contains(IPresentationEngine.ORIENTATION_HORIZONTAL))
			paneSize.x = caRect.width;
		if (.getTags().contains(IPresentationEngine.ORIENTATION_VERTICAL))
			paneSize.y = caRect.height;
		Point loc = new Point(0, 0);
		if (isFixed(SWT.LEFT))
			loc.x = caRect.x;
		else
			loc.x = (caRect.x + caRect.width) - paneSize.x;
		if (isFixed(SWT.TOP))
			loc.y = caRect.y;
		else
			loc.y = (caRect.y + caRect.height) - paneSize.y;
		.setSize(paneSize);
		.setLocation(loc);
	private void setHostSize() {
		if ( == null || .isDisposed())
			return;
		int xSize = 600;
		String xSizeStr = .getPersistedState().get();
		if (xSizeStr != null)
			xSize = Integer.parseInt(xSizeStr);
		int ySize = 400;
		String ySizeStr = .getPersistedState().get();
		if (ySizeStr != null)
			ySize = Integer.parseInt(ySizeStr);
		.setSize(xSizeySize);
	private Composite getHostPane() {
		// Create one
		 = new Composite(.getShell(), SWT.NONE);
		.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				 = null;
		});
		// Set a special layout that allows resizing
		return ;
	private int getFixedSides() {
		MUIElement tcParent = .getParent();
		if (!(tcParent instanceof MTrimBar))
			return 0;
		MTrimBar bar = (MTrimBar) tcParent;
		Composite trimComp = (Composite) bar.getWidget();
		Rectangle trimBounds = trimComp.getBounds();
		Point trimCenter = new Point(trimBounds.width / 2, trimBounds.height / 2); // adjusted to
																					// (0,0)
		Control trimCtrl = (Control) .getWidget();
		Rectangle ctrlBounds = trimCtrl.getBounds();
		Point ctrlCenter = new Point(ctrlBounds.x + (ctrlBounds.width / 2), ctrlBounds.y
				+ (ctrlBounds.height / 2));
		if (bar.getSide() == SideValue.LEFT) {
			int verticalValue = ctrlCenter.y < trimCenter.y ? SWT.TOP : SWT.BOTTOM;
			return SWT.LEFT | verticalValue;
else if (bar.getSide() == SideValue.RIGHT) {
			int verticalValue = ctrlCenter.y < trimCenter.y ? SWT.TOP : SWT.BOTTOM;
			return SWT.RIGHT | verticalValue;
else if (bar.getSide() == SideValue.TOP) {
			int horizontalValue = ctrlCenter.x < trimCenter.x ? SWT.LEFT : SWT.RIGHT;
			return SWT.TOP | horizontalValue;
else if (bar.getSide() == SideValue.BOTTOM) {
			int horizontalValue = ctrlCenter.x < trimCenter.x ? SWT.LEFT : SWT.RIGHT;
			return SWT.BOTTOM | horizontalValue;
		return SWT.BOTTOM | SWT.RIGHT;
	private Image getLayoutImage() {
		if ( == null) {
			 = .imageDescriptorFromURI(URI.createURI())
					.createImage();
		return ;
	private Image getRestoreImage() {
		if ( == null) {
			 = .imageDescriptorFromURI(URI.createURI())
					.createImage();
	private boolean isFixed(int swtSide) {
		return ( & swtSide) != 0;