| /******************************************************************************* |
| * Copyright (c) 2009, 2014 Xored Software Inc 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: |
| * Xored Software Inc - initial API and implementation and/or initial documentation |
| *******************************************************************************/ |
| package org.eclipse.rcptt.tesla.swt.e4x; |
| |
| import java.lang.reflect.Field; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.e4.ui.model.application.ui.MUIElement; |
| import org.eclipse.e4.ui.model.application.ui.advanced.impl.AreaImpl; |
| import org.eclipse.e4.ui.model.application.ui.advanced.impl.PlaceholderImpl; |
| import org.eclipse.e4.ui.model.application.ui.basic.MWindow; |
| import org.eclipse.e4.ui.model.application.ui.basic.impl.PartImpl; |
| import org.eclipse.e4.ui.model.application.ui.basic.impl.PartStackImpl; |
| import org.eclipse.e4.ui.model.application.ui.menu.MToolControl; |
| import org.eclipse.e4.ui.workbench.addons.minmax.TrimStack; |
| import org.eclipse.e4.ui.workbench.modeling.EModelService; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.ToolBarManager; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.CTabFolder; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.ToolBar; |
| import org.eclipse.swt.widgets.ToolItem; |
| import org.eclipse.swt.widgets.Widget; |
| import org.eclipse.ui.IEditorReference; |
| import org.eclipse.ui.ISelectionService; |
| import org.eclipse.ui.IViewReference; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.PartSite; |
| import org.eclipse.ui.internal.ViewSite; |
| import org.eclipse.ui.internal.WorkbenchPartReference; |
| import org.eclipse.ui.internal.WorkbenchWindow; |
| import org.eclipse.ui.internal.e4.compatibility.ActionBars; |
| import org.eclipse.ui.internal.e4.compatibility.SelectionService; |
| import org.eclipse.ui.internal.quickaccess.SearchField; |
| import org.osgi.framework.Version; |
| |
| import org.eclipse.rcptt.util.ReflectionUtil; |
| import org.eclipse.rcptt.tesla.core.protocol.ElementKind; |
| import org.eclipse.rcptt.tesla.core.protocol.GenericElementKind; |
| import org.eclipse.rcptt.tesla.internal.core.TeslaCore; |
| import org.eclipse.rcptt.tesla.internal.ui.player.SWTUIElement; |
| import org.eclipse.rcptt.tesla.internal.ui.player.SWTUIPlayer; |
| import org.eclipse.rcptt.tesla.internal.ui.player.TeslaSWTAccess; |
| import org.eclipse.rcptt.tesla.internal.ui.player.WorkbenchUIElement; |
| import org.eclipse.rcptt.tesla.swt.workbench.IEclipseWorkbenchProvider; |
| |
| public class E4WorkbenchProvider implements IEclipseWorkbenchProvider { |
| |
| private static <T> T as(Class<T> class_, Object object) { |
| if (class_.isInstance(object)) |
| return class_.cast(object); |
| return null; |
| } |
| |
| public Menu getViewMenu(IWorkbenchPart workbenchPart, |
| IWorkbenchPartReference reference, boolean create) { |
| |
| ViewSite site = as(ViewSite.class, workbenchPart.getSite()); |
| if (site == null) |
| return null; |
| |
| ActionBars bars = as(ActionBars.class, site.getActionBars()); |
| if (bars == null) |
| return null; |
| |
| MenuManager man = as(MenuManager.class, bars.getMenuManager()); |
| if (man == null) |
| return null; |
| |
| Menu menu = man.getMenu(); |
| if ((menu == null || menu.isDisposed()) && create) |
| man.createContextMenu(site.getShell()); |
| |
| return man.getMenu(); |
| } |
| |
| public List<?> getPaneFolderButtonListeners(Object paneFolder) { |
| return new ArrayList(); |
| } |
| |
| @SuppressWarnings("restriction") |
| public Control getToolbar(IWorkbenchPartReference reference) { |
| try { |
| return ((ToolBarManager) ((PartSite) ((WorkbenchPartReference) reference) |
| .getPart(false).getSite()).getActionBars() |
| .getToolBarManager()).getControl(); |
| } catch (Exception e) { |
| // II: don't bother with NPE and class casts if internal API will |
| // change |
| return null; |
| } |
| } |
| |
| public boolean canClickView(IWorkbenchPartReference reference) { |
| return true; |
| } |
| |
| public Map<Control, SWTUIElement> getWorkbenchReference(SWTUIPlayer player) { |
| IWorkbenchWindow[] windows = PlatformUI.getWorkbench() |
| .getWorkbenchWindows(); |
| if (!Display.getCurrent() |
| .equals(PlatformUI.getWorkbench().getDisplay())) { |
| return new HashMap<Control, SWTUIElement>(); |
| } |
| Map<Control, SWTUIElement> references = new HashMap<Control, SWTUIElement>(); |
| for (IWorkbenchWindow iWorkbenchWindow : windows) { |
| // This is workbench window |
| IWorkbenchPage page = iWorkbenchWindow.getActivePage(); |
| IEditorReference[] editors = page.getEditorReferences(); |
| IViewReference[] views = page.getViewReferences(); |
| for (IViewReference iViewReference : views) { |
| WorkbenchPartReference ref = ((WorkbenchPartReference) iViewReference); |
| IWorkbenchPart refPart = ref.getPart(false); |
| if (refPart != null && ref.getPane().getControl() != null) { |
| Control control = ref.getPane().getControl(); |
| references.put(control, player.wrap(ref)); |
| Control toolbar = getToolbar(ref); |
| if (toolbar != null) { |
| references.put(toolbar, player.wrap(ref)); |
| } |
| } |
| } |
| for (IEditorReference iEditorReference : editors) { |
| WorkbenchPartReference ref = ((WorkbenchPartReference) iEditorReference); |
| IWorkbenchPart refPart = ref.getPart(false); |
| if (refPart != null && ref.getPane().getControl() != null) { |
| Control control = ref.getPane().getControl(); |
| references.put(control, player.wrap(ref)); |
| // Control toolBar = ref.getPane().getToolBar(); |
| // if (toolBar != null) { |
| // references.put(toolBar, player.wrap(ref)); |
| // } |
| } |
| } |
| } |
| return references; |
| } |
| |
| public void processTabFolderButton(Widget widget, int buttonId) { |
| if (!(widget instanceof CTabFolder)) { |
| if (widget.getData("modelElement") != null |
| && widget instanceof Control) { |
| Composite parent = ((Control) widget).getParent(); |
| if (!(parent instanceof CTabFolder)) { |
| parent = parent.getParent(); |
| if (!(parent instanceof CTabFolder)) |
| return; |
| } |
| widget = parent; |
| } |
| } |
| |
| if (!(widget instanceof CTabFolder)) |
| return; |
| |
| // -- |
| |
| CTabFolder tabFolder = (CTabFolder) widget; |
| |
| ToolItem maxItem = null, minItem = null; |
| try { |
| Field field = CTabFolder.class.getDeclaredField("maxItem"); |
| field.setAccessible(true); |
| maxItem = (ToolItem) field.get(tabFolder); |
| |
| field = CTabFolder.class.getDeclaredField("minItem"); |
| field.setAccessible(true); |
| minItem = (ToolItem) field.get(tabFolder); |
| } catch (Exception e) { |
| TeslaCore.log(e); |
| } |
| |
| if (maxItem == null |
| || (minItem == null && buttonId == IWorkbenchPage.STATE_MINIMIZED)) |
| return; |
| |
| Event e = new Event(); |
| switch (buttonId) { |
| case IWorkbenchPage.STATE_MAXIMIZED: |
| if (tabFolder.getMaximized()) |
| return; |
| e.widget = maxItem; |
| e.type = SWT.Selection; |
| maxItem.notifyListeners(SWT.Selection, e); |
| break; |
| case IWorkbenchPage.STATE_MINIMIZED: |
| if (tabFolder.getMinimized()) |
| return; |
| e.widget = minItem; |
| e.type = SWT.Selection; |
| minItem.notifyListeners(SWT.Selection, e); |
| break; |
| case IWorkbenchPage.STATE_RESTORED: |
| if (!tabFolder.getMinimized() && !tabFolder.getMaximized()) |
| return; |
| e.widget = maxItem; |
| e.type = SWT.Selection; |
| maxItem.notifyListeners(SWT.Selection, e); |
| break; |
| } |
| } |
| |
| public void processTabShowList(Widget widget) { |
| if (!(widget instanceof CTabFolder)) { |
| if (widget.getData("modelElement") != null |
| && widget instanceof Control) { |
| Composite parent = ((Control) widget).getParent(); |
| if (!(parent instanceof CTabFolder)) { |
| parent = parent.getParent(); |
| if (!(parent instanceof CTabFolder)) |
| return; |
| } |
| widget = parent; |
| } |
| } |
| |
| if (!(widget instanceof CTabFolder)) |
| return; |
| |
| // -- |
| |
| CTabFolder tabFolder = (CTabFolder) widget; |
| |
| ToolItem chevronItem = null; |
| try { |
| Field field = CTabFolder.class.getDeclaredField("chevronItem"); |
| field.setAccessible(true); |
| chevronItem = (ToolItem) field.get(tabFolder); |
| } catch (Exception e) { |
| TeslaCore.log(e); |
| } |
| |
| if (chevronItem == null) |
| return; |
| |
| if (!chevronItem.getParent().isVisible()) |
| return; |
| |
| Event e = new Event(); |
| e.widget = chevronItem; |
| e.type = SWT.Selection; |
| chevronItem.notifyListeners(SWT.Selection, e); |
| } |
| |
| public boolean isVisible(IWorkbenchPartReference reference) { |
| IWorkbenchPart part = reference.getPart(false); |
| if (part != null) { |
| return ((WorkbenchPartReference) reference).getPane().getControl() |
| .isVisible(); |
| } |
| return false; |
| } |
| |
| public boolean isActiveContainsView(IWorkbenchPage page, |
| IWorkbenchPartReference reference) { |
| // return isVisible(reference); |
| return true; |
| } |
| |
| public boolean isViewOrEditorButton(Widget widget) { |
| if (!(widget instanceof ToolItem)) |
| return false; |
| |
| ToolItem item = (ToolItem) widget; |
| String tooltip = item.getToolTipText(); |
| if (!(tooltip == null || tooltip.equals("View Menu") |
| || tooltip.equals("Maximize") || tooltip.equals("Minimize") |
| || tooltip.equals("Restore") || tooltip.equals("Show List"))) |
| return false; |
| |
| if (item.getData("theMenu") != null) // view menu |
| return true; |
| |
| // restore button |
| if (item.getParent() instanceof ToolBar |
| && TeslaSWTAccess.getThis(TrimStack.class, item, SWT.Selection) != null) |
| return true; |
| |
| Composite parent = item.getParent().getParent(); |
| if (!(parent instanceof CTabFolder)) |
| return false; |
| |
| Widget control = extractViewOrEditorControl((CTabFolder) parent); |
| return control != null; |
| } |
| |
| public boolean isSupported() { |
| Version version = TeslaCore.getPlatformVersion(); |
| if (version.getMajor() == 3 && version.getMinor() >= 103) { |
| return true; |
| } |
| return false; |
| } |
| |
| public Widget extractViewOrEditorControl(CTabFolder tabFolder) { |
| if (tabFolder.getSelection() == null) |
| return null; |
| |
| Control selection = tabFolder.getSelection().getControl(); |
| |
| if (selection instanceof Composite) { |
| |
| Object data = selection.getData("modelElement"); |
| if (data instanceof PartImpl) |
| return selection; // editors |
| |
| // views |
| Control[] children = ((Composite) selection).getChildren(); |
| for (Control c : children) { |
| if (!(c instanceof Composite)) |
| continue; |
| |
| data = c.getData("modelElement"); |
| if (!(data instanceof PartImpl)) |
| continue; |
| |
| return c; |
| } |
| |
| return null; |
| } else |
| return null; |
| } |
| |
| public CTabFolder getTabFolderFromButton(ToolItem button) { |
| Composite parent = button.getParent().getParent(); |
| if (parent instanceof CTabFolder) |
| return (CTabFolder) parent; |
| |
| // view menu |
| if (parent != null && button.getData("theMenu") != null) { |
| parent = parent.getParent(); |
| if (parent instanceof CTabFolder) |
| return (CTabFolder) parent; |
| } |
| |
| // restore button |
| TrimStack trimStack = TeslaSWTAccess.getThis(TrimStack.class, button, |
| SWT.Selection); |
| if (trimStack != null) { |
| try { |
| Field field = TrimStack.class |
| .getDeclaredField("minimizedElement"); |
| field.setAccessible(true); |
| Object minimizedElement = field.get(trimStack); |
| |
| if (minimizedElement instanceof PartStackImpl) { // views |
| Object widget = ((PartStackImpl) minimizedElement) |
| .getWidget(); |
| if (widget instanceof CTabFolder) |
| return (CTabFolder) widget; |
| } else if (minimizedElement instanceof PlaceholderImpl) { // editors |
| MUIElement ref = ((PlaceholderImpl) minimizedElement) |
| .getRef(); |
| if (ref instanceof AreaImpl) { |
| Object selected = ((AreaImpl) ref).getSelectedElement(); |
| if (selected instanceof PartStackImpl) { |
| Object widget = ((PartStackImpl) selected) |
| .getWidget(); |
| if (widget instanceof CTabFolder) |
| return (CTabFolder) widget; |
| } |
| } |
| } |
| |
| } catch (Exception e) { |
| } |
| } |
| |
| return null; |
| } |
| |
| private static final String JUNO_TEXT_FIELD = "getFilterText"; |
| private static final String KEPLER_TEXT_FIELD = "getQuickAccessSearchText"; |
| |
| public Text getQuickAccess() { |
| IWorkbenchWindow window = PlatformUI.getWorkbench() |
| .getActiveWorkbenchWindow(); |
| if (window == null) |
| return null; |
| |
| MWindow mWindow = ((WorkbenchWindow) window).getModel(); |
| if (mWindow == null) |
| return null; |
| |
| EModelService modelService = mWindow.getContext().get( |
| EModelService.class); |
| if (modelService == null) |
| return null; |
| |
| MToolControl searchField = (MToolControl) modelService.find( |
| "SearchField", mWindow); |
| if (searchField == null) |
| return null; |
| |
| if (!(searchField.getObject() instanceof SearchField)) |
| return null; |
| |
| SearchField field = (SearchField) searchField.getObject(); |
| if (field == null) |
| return null; |
| |
| Object result = ReflectionUtil.callMethod(field, JUNO_TEXT_FIELD); |
| if (result == null) { |
| result = ReflectionUtil.callMethod(field, KEPLER_TEXT_FIELD); |
| } |
| return result == null ? null : (Text) result; |
| } |
| |
| public void updateActiveSelection(List<Object> selectionData, |
| SWTUIElement parent) { |
| List<SWTUIElement> parentsList = parent.getPlayer().getParentsList( |
| parent); |
| parentsList.add(parent); |
| for (SWTUIElement e : parentsList) { |
| final GenericElementKind kind = e.getKind(); |
| if (kind.is(ElementKind.View) || kind.is(ElementKind.Editor)) { |
| if (e instanceof WorkbenchUIElement) { |
| final IWorkbenchPartReference reference = ((WorkbenchUIElement) e) |
| .getReference(); |
| IWorkbenchWindow window = reference.getPage() |
| .getWorkbenchWindow(); |
| IWorkbenchPart part = reference.getPart(true); |
| ISelectionService selectionService = window |
| .getSelectionService(); |
| |
| ((SelectionService) selectionService).updateSelection(part); |
| } |
| } |
| } |
| } |
| |
| public String getViewId(Widget widget) { |
| // not supported for now |
| return null; |
| } |
| } |