Bug 370441 Allow to see all editors in ">>" drop-down

Update the code so that clicking on a CTabFolder's chevron will
bring up all the editors in an order dictated by the MRU
setting. If MRU is on, the list will be shown alphabetically. If
MRU is off, then the tabs that are in the folder will just be
shown as-is with no reordering.
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AbstractTableInformationControl.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/internal/workbench/renderers/swt/AbstractTableInformationControl.java
similarity index 91%
rename from bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AbstractTableInformationControl.java
rename to bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/internal/workbench/renderers/swt/AbstractTableInformationControl.java
index 9252eea..7c4b8ec 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/AbstractTableInformationControl.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/internal/workbench/renderers/swt/AbstractTableInformationControl.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * Copyright (c) 2003, 2012 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
@@ -8,8 +8,9 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-package org.eclipse.ui.internal;
+package org.eclipse.e4.ui.internal.workbench.renderers.swt;
 
+import org.eclipse.e4.ui.workbench.swt.internal.copy.StringMatcher;
 import org.eclipse.jface.util.Util;
 import org.eclipse.jface.viewers.ILabelProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -48,7 +49,6 @@
 import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.internal.misc.StringMatcher;
 
 /**
  * @since 3.0
@@ -64,14 +64,16 @@
 		/*
 		 * (non-Javadoc) Method declared on ViewerFilter.
 		 */
-		public boolean select(Viewer viewer, Object parentElement, Object element) {
+		public boolean select(Viewer viewer, Object parentElement,
+				Object element) {
 			StringMatcher matcher = getMatcher();
 			if (matcher == null || !(viewer instanceof TableViewer)) {
 				return true;
 			}
 			TableViewer tableViewer = (TableViewer) viewer;
 
-			String matchName = ((ILabelProvider) tableViewer.getLabelProvider()).getText(element);
+			String matchName = ((ILabelProvider) tableViewer.getLabelProvider())
+					.getText(element);
 
 			if (matchName == null) {
 				return false;
@@ -111,7 +113,8 @@
 	 * @param controlStyle
 	 *            the additional styles for the control
 	 */
-	public AbstractTableInformationControl(Shell parent, int shellStyle, int controlStyle) {
+	public AbstractTableInformationControl(Shell parent, int shellStyle,
+			int controlStyle) {
 		fShell = new Shell(parent, shellStyle);
 		fShell.setLayout(new FillLayout());
 
@@ -191,11 +194,12 @@
 				if (divCount == ignoreEventCount) {
 					divCount = 0;
 				}
-				if (table.equals(e.getSource()) & ++divCount == ignoreEventCount) {
+				if (table.equals(e.getSource())
+						& ++divCount == ignoreEventCount) {
 					Object o = table.getItem(new Point(e.x, e.y));
 					if (fLastItem == null ^ o == null) {
-						table.setCursor(o == null ? null : table.getDisplay().getSystemCursor(
-								SWT.CURSOR_HAND));
+						table.setCursor(o == null ? null : table.getDisplay()
+								.getSystemCursor(SWT.CURSOR_HAND));
 					}
 					if (o instanceof TableItem && lastY != e.y) {
 						lastY = e.y;
@@ -204,14 +208,16 @@
 							table.setSelection(new TableItem[] { fLastItem });
 						} else if (e.y < itemHeightdiv4) {
 							// Scroll up
-							Item item = fTableViewer.scrollUp(e.x + tableLoc.x, e.y + tableLoc.y);
+							Item item = fTableViewer.scrollUp(e.x + tableLoc.x,
+									e.y + tableLoc.y);
 							if (item instanceof TableItem) {
 								fLastItem = (TableItem) item;
 								table.setSelection(new TableItem[] { fLastItem });
 							}
 						} else if (e.y > tableHeight - itemHeightdiv4) {
 							// Scroll down
-							Item item = fTableViewer.scrollDown(e.x + tableLoc.x, e.y + tableLoc.y);
+							Item item = fTableViewer.scrollDown(e.x
+									+ tableLoc.x, e.y + tableLoc.y);
 							if (item instanceof TableItem) {
 								fLastItem = (TableItem) item;
 								table.setSelection(new TableItem[] { fLastItem });
@@ -240,13 +246,15 @@
 					}
 				}
 				if (e.button == 3) {
-					TableItem tItem = fTableViewer.getTable().getItem(new Point(e.x, e.y));
+					TableItem tItem = fTableViewer.getTable().getItem(
+							new Point(e.x, e.y));
 					if (tItem != null) {
 						Menu menu = new Menu(fTableViewer.getTable());
 						MenuItem mItem = new MenuItem(menu, SWT.NONE);
-						mItem.setText(WorkbenchMessages.PartPane_close);
+						mItem.setText(SWTRenderersMessages.menuClose);
 						mItem.addSelectionListener(new SelectionAdapter() {
-							public void widgetSelected(SelectionEvent selectionEvent) {
+							public void widgetSelected(
+									SelectionEvent selectionEvent) {
 								removeSelectedItems();
 							}
 						});
@@ -330,8 +338,8 @@
 		FontMetrics fontMetrics = gc.getFontMetrics();
 		gc.dispose();
 
-		data.heightHint = org.eclipse.jface.dialogs.Dialog.convertHeightInCharsToPixels(
-				fontMetrics, 1);
+		data.heightHint = org.eclipse.jface.dialogs.Dialog
+				.convertHeightInCharsToPixels(fontMetrics, 1);
 		data.horizontalAlignment = GridData.FILL;
 		data.verticalAlignment = GridData.BEGINNING;
 		fFilterText.setLayoutData(data);
@@ -349,8 +357,8 @@
 					break;
 				case SWT.ARROW_UP:
 					fTableViewer.getTable().setFocus();
-					fTableViewer.getTable()
-							.setSelection(fTableViewer.getTable().getItemCount() - 1);
+					fTableViewer.getTable().setSelection(
+							fTableViewer.getTable().getItemCount() - 1);
 					break;
 				case SWT.ESC:
 					dispose();
@@ -364,7 +372,8 @@
 		});
 
 		// Horizontal separator line
-		Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT);
+		Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL
+				| SWT.LINE_DOT);
 		separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
 		return fFilterText;
@@ -428,7 +437,8 @@
 	 * Implementers can modify
 	 */
 	protected Object getSelectedElement() {
-		return ((IStructuredSelection) fTableViewer.getSelection()).getFirstElement();
+		return ((IStructuredSelection) fTableViewer.getSelection())
+				.getFirstElement();
 	}
 
 	protected abstract void gotoSelectedElement();
@@ -455,7 +465,8 @@
 	}
 
 	private Object findElement(TableItem[] items) {
-		ILabelProvider labelProvider = (ILabelProvider) fTableViewer.getLabelProvider();
+		ILabelProvider labelProvider = (ILabelProvider) fTableViewer
+				.getLabelProvider();
 		for (int i = 0; i < items.length; i++) {
 			Object element = items[i].getData();
 			if (fStringMatcher == null) {
@@ -502,7 +513,8 @@
 		int tableMaxHeight = fComposite.getDisplay().getBounds().height / 2;
 		// removes padding if necessary
 		int tableHeight = (tableSize.y <= tableMaxHeight) ? tableSize.y
-				- viewerTable.getItemHeight() - viewerTable.getItemHeight() / 2 : tableMaxHeight;
+				- viewerTable.getItemHeight() - viewerTable.getItemHeight() / 2
+				: tableMaxHeight;
 		((GridData) viewerTable.getLayoutData()).heightHint = tableHeight;
 		Point fCompSize = fComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
 		fComposite.setSize(fCompSize);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/BasicPartList.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/internal/workbench/renderers/swt/BasicPartList.java
similarity index 88%
rename from bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/BasicPartList.java
rename to bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/internal/workbench/renderers/swt/BasicPartList.java
index 120fa44..b4630e9 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/BasicPartList.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/internal/workbench/renderers/swt/BasicPartList.java
@@ -9,17 +9,17 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 
-package org.eclipse.ui.internal;
+package org.eclipse.e4.ui.internal.workbench.renderers.swt;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.eclipse.e4.ui.model.application.ui.MElementContainer;
 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.advanced.MPlaceholder;
 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.workbench.modeling.EPartService;
 import org.eclipse.e4.ui.workbench.swt.util.ISWTResourceUtilities;
 import org.eclipse.emf.common.util.URI;
@@ -63,22 +63,27 @@
 
 	private ISWTResourceUtilities utils;
 
-	private MPartStack input;
+	private MElementContainer<?> input;
 
 	private EPartService partService;
 
-	public BasicPartList(Shell parent, int shellStyle, int treeStyler, EPartService partService,
-			MPartStack input, ISWTResourceUtilities utils) {
+	private boolean alphabetical;
+
+	public BasicPartList(Shell parent, int shellStyle, int treeStyler,
+			EPartService partService, MElementContainer<?> input,
+			ISWTResourceUtilities utils, boolean alphabetical) {
 		super(parent, shellStyle, treeStyler);
 		this.partService = partService;
 		this.input = input;
 		this.utils = utils;
+		this.alphabetical = alphabetical;
 	}
 
 	private Image getLabelImage(String iconURI) {
 		Image image = images.get(iconURI);
 		if (image == null) {
-			ImageDescriptor descriptor = utils.imageDescriptorFromURI(URI.createURI(iconURI));
+			ImageDescriptor descriptor = utils.imageDescriptorFromURI(URI
+					.createURI(iconURI));
 			image = descriptor.createImage();
 			images.put(iconURI, image);
 		}
@@ -87,10 +92,13 @@
 
 	protected TableViewer createTableViewer(Composite parent, int style) {
 		Table table = new Table(parent, SWT.SINGLE | (style & ~SWT.MULTI));
-		table.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));
+		table.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false,
+				false));
 		TableViewer tableViewer = new TableViewer(table);
 		tableViewer.setComparator(new ViewerComparator());
-		tableViewer.addFilter(new NamePatternFilter());
+		if (alphabetical) {
+			tableViewer.addFilter(new NamePatternFilter());
+		}
 		tableViewer.setContentProvider(ArrayContentProvider.getInstance());
 		tableViewer.setLabelProvider(new BasicStackListLabelProvider());
 
@@ -116,7 +124,8 @@
 				element = ((MPlaceholder) element).getRef();
 			}
 
-			if (element.isToBeRendered() && element.isVisible() && element instanceof MPart) {
+			if (element.isToBeRendered() && element.isVisible()
+					&& element instanceof MPart) {
 				list.add(element);
 			}
 		}
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
index 46e694e..d268ff0 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
@@ -17,6 +17,7 @@
 import javax.inject.Inject;
 import org.eclipse.e4.core.contexts.IEclipseContext;
 import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.e4.ui.internal.workbench.renderers.swt.BasicPartList;
 import org.eclipse.e4.ui.internal.workbench.renderers.swt.SWTRenderersMessages;
 import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
 import org.eclipse.e4.ui.internal.workbench.swt.CSSRenderingUtils;
@@ -38,9 +39,11 @@
 import org.eclipse.e4.ui.widgets.CTabFolderEvent;
 import org.eclipse.e4.ui.widgets.CTabItem;
 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.modeling.EModelService;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.e4.ui.workbench.swt.util.ISWTResourceUtilities;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.swt.SWT;
@@ -68,6 +71,7 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.Shell;
@@ -732,6 +736,12 @@
 			public void close(CTabFolderEvent event) {
 				event.doit = closePart(event.item);
 			}
+
+			@Override
+			public void showList(CTabFolderEvent event) {
+				event.doit = false;
+				showAvailableItems(stack, ctf);
+			}
 		};
 		ctf.addCTabFolder2Listener(closeListener);
 
@@ -763,6 +773,54 @@
 		});
 	}
 
+	private void showAvailableItems(MElementContainer<?> stack, CTabFolder ctf) {
+		IEclipseContext ctxt = getContext(stack);
+		final BasicPartList editorList = new BasicPartList(ctf.getShell(),
+				SWT.ON_TOP, SWT.V_SCROLL | SWT.H_SCROLL,
+				ctxt.get(EPartService.class), stack,
+				(ISWTResourceUtilities) ctxt.get(IResourceUtilities.class),
+				getInitialMRUValue(ctf));
+		editorList.setInput();
+
+		Point size = editorList.computeSizeHint();
+		editorList.setSize(size.x, size.y);
+
+		editorList.setLocation(ctf.toDisplay(getChevronLocation(ctf)));
+		editorList.setVisible(true);
+		editorList.setFocus();
+		editorList.getShell().addListener(SWT.Deactivate, new Listener() {
+			public void handleEvent(org.eclipse.swt.widgets.Event event) {
+				editorList.getShell().getDisplay().asyncExec(new Runnable() {
+					public void run() {
+						editorList.dispose();
+					}
+				});
+			}
+		});
+	}
+
+	private Point getChevronLocation(CTabFolder tabFolder) {
+		// get the last visible item
+		int numItems = tabFolder.getItemCount();
+		CTabItem item = null;
+		for (int i = 0; i < numItems; i++) {
+			CTabItem tempItem = tabFolder.getItem(i);
+			if (tempItem.isShowing()) {
+				item = tempItem;
+			}
+		}
+
+		// if we have no visible tabs, abort.
+		if (item == null) {
+			return new Point(0, 0);
+		}
+
+		Rectangle itemBounds = item.getBounds();
+		int x = itemBounds.x + itemBounds.width;
+		int y = itemBounds.y + itemBounds.height;
+		return new Point(x, y);
+	}
+
 	private boolean closePart(Widget widget) {
 		MUIElement uiElement = (MUIElement) widget
 				.getData(AbstractPartRenderer.OWNING_ME);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbookEditorsHandler.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbookEditorsHandler.java
index 420463a..6d74b5b 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbookEditorsHandler.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbookEditorsHandler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2011 IBM Corporation and others.
+ * Copyright (c) 2007, 2012 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
@@ -14,6 +14,7 @@
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.e4.ui.internal.workbench.renderers.swt.BasicPartList;
 import org.eclipse.e4.ui.model.application.ui.MElementContainer;
 import org.eclipse.e4.ui.model.application.ui.MUIElement;
 import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
@@ -59,7 +60,8 @@
 				EPartService partService = (EPartService) HandlerUtil.getVariableChecked(event,
 						EPartService.class.getName());
 				final BasicPartList editorList = new BasicPartList(workbenchWindow.getShell(),
-						SWT.ON_TOP, SWT.V_SCROLL | SWT.H_SCROLL, partService, activeStack, utils);
+						SWT.ON_TOP, SWT.V_SCROLL | SWT.H_SCROLL, partService, activeStack, utils,
+						true);
 				editorList.setInput();
 
 				Point size = editorList.computeSizeHint();
diff --git a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF
index 17b3ed8..d828a44 100644
--- a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF
@@ -113,6 +113,7 @@
  org.eclipse.e4.core.commands,
  org.eclipse.e4.core.commands.internal,
  org.eclipse.e4.ui.internal.workbench,
+ org.eclipse.e4.ui.internal.workbench.renderers.swt,
  org.eclipse.e4.ui.internal.workbench.swt,
  org.eclipse.e4.ui.services,
  org.eclipse.e4.ui.widgets,