--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.browsing.ui.swt;\r
+\r
+/*******************************************************************************\r
+ * Copyright (c) 2000, 2008 IBM Corporation and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * IBM Corporation - initial API and implementation\r
+ *******************************************************************************/\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.eclipse.core.runtime.Assert;\r
+import org.eclipse.e4.core.contexts.IEclipseContext;\r
+import org.eclipse.jface.action.MenuManager;\r
+import org.eclipse.jface.viewers.ILabelDecorator;\r
+import org.eclipse.jface.viewers.IPostSelectionProvider;\r
+import org.eclipse.jface.viewers.ISelectionChangedListener;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.SelectionChangedEvent;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.IActionBars;\r
+import org.eclipse.ui.IEditorActionBarContributor;\r
+import org.eclipse.ui.IKeyBindingService;\r
+import org.eclipse.ui.INestableKeyBindingService;\r
+import org.eclipse.ui.IViewPart;\r
+import org.eclipse.ui.IViewSite;\r
+import org.eclipse.ui.IWorkbenchPage;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.IWorkbenchWindow;\r
+import org.eclipse.ui.internal.PartSite;\r
+import org.eclipse.ui.internal.PopupMenuExtender;\r
+import org.eclipse.ui.internal.WorkbenchPlugin;\r
+import org.eclipse.ui.internal.services.INestable;\r
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;\r
+import org.eclipse.ui.internal.services.ServiceLocator;\r
+import org.eclipse.ui.part.MultiPageEditorSite;\r
+import org.eclipse.ui.services.IDisposable;\r
+import org.eclipse.ui.services.IServiceLocator;\r
+\r
+/**\r
+ * Site for a nested editor within a multi-page editor. Selection is handled by\r
+ * forwarding the event to the multi-page editor's selection listeners; most\r
+ * other methods are forwarded to the multi-page editor's site.\r
+ * <p>\r
+ * The base implementation of <code>MultiPageEditor.createSite</code> creates\r
+ * an instance of this class. This class may be instantiated or subclassed.\r
+ * </p>\r
+ * \r
+ * TODO: copy e4 changes from MultiPageEditorSite to this class as seen fit\r
+ */\r
+@SuppressWarnings({"restriction","deprecation","rawtypes"})\r
+public class TabbedPropertyPageViewSite implements IViewSite, INestable {\r
+\r
+ /**\r
+ * The nested editor.\r
+ */\r
+ private final IViewPart editor;\r
+\r
+ /**\r
+ * The list of popup menu extenders; <code>null</code> if none registered.\r
+ */\r
+ private ArrayList menuExtenders;\r
+\r
+ /**\r
+ * The multi-page editor.\r
+ */\r
+ private final TabbedPropertyPage multiPageEditor;\r
+\r
+ /**\r
+ * The post selection changed listener.\r
+ */\r
+ private ISelectionChangedListener postSelectionChangedListener = null;\r
+\r
+ /**\r
+ * The selection change listener, initialized lazily; <code>null</code> if\r
+ * not yet created.\r
+ */\r
+ private ISelectionChangedListener selectionChangedListener = null;\r
+\r
+ /**\r
+ * The selection provider; <code>null</code> if none.\r
+ * \r
+ * @see MultiPageEditorSite#setSelectionProvider(ISelectionProvider)\r
+ */\r
+ private ISelectionProvider selectionProvider = null;\r
+\r
+ /**\r
+ * The cached copy of the key binding service specific to this multi-page\r
+ * editor site. This value is <code>null</code> if it is not yet\r
+ * initialized.\r
+ */\r
+ private IKeyBindingService service = null;\r
+\r
+ /**\r
+ * The local service locator for this multi-page editor site. This value is\r
+ * never <code>null</code>.\r
+ */\r
+ private final ServiceLocator serviceLocator;\r
+\r
+ private IEclipseContext e4Context;\r
+\r
+ /**\r
+ * Creates a site for the given editor nested within the given multi-page\r
+ * editor.\r
+ * \r
+ * @param multiPageEditor\r
+ * the multi-page editor\r
+ * @param editor\r
+ * the nested editor\r
+ */\r
+ public TabbedPropertyPageViewSite(TabbedPropertyPage multiPageEditor,\r
+ IViewPart editor) {\r
+ Assert.isNotNull(multiPageEditor);\r
+ Assert.isNotNull(editor);\r
+ this.multiPageEditor = multiPageEditor;\r
+ this.editor = editor;\r
+\r
+ final IServiceLocator parentServiceLocator = multiPageEditor.getSite();\r
+ IServiceLocatorCreator slc = (IServiceLocatorCreator) parentServiceLocator\r
+ .getService(IServiceLocatorCreator.class);\r
+ this.serviceLocator = (ServiceLocator) slc.createServiceLocator(\r
+ parentServiceLocator, null, new IDisposable() {\r
+ @Override\r
+ public void dispose() {\r
+// final Control control = ((PartSite)getMultiPageEditor().getSite()).getPane().getControl();\r
+// if (control != null && !control.isDisposed()) {\r
+// ((PartSite)getMultiPageEditor().getSite()).getPane().doHide();\r
+// }\r
+ }\r
+ });\r
+ e4Context = ((PartSite)editor.getViewSite()).getContext().createChild("TabbedPropertyPageViewSite");\r
+ serviceLocator.setContext(e4Context);\r
+ initializeDefaultServices();\r
+ }\r
+\r
+ /**\r
+ * Initialize the slave services for this site.\r
+ */\r
+ private void initializeDefaultServices() {\r
+// serviceLocator.registerService(IMultiPageEditorSiteHolder.class,\r
+// new ITabbedPropertyPageSiteHolder() {\r
+// public TabbedPropertyPageViewSite getSite() {\r
+// return TabbedPropertyPageViewSite.this;\r
+// }\r
+// });\r
+ // Not possible to initialize this service for a view site:\r
+// serviceLocator.registerService(IWorkbenchLocationService.class,\r
+// new WorkbenchLocationService(IServiceScopes.MPESITE_SCOPE,\r
+// getWorkbenchWindow().getWorkbench(),\r
+// getWorkbenchWindow(), getMultiPageEditor().getSite(),\r
+// this, null, 3));\r
+ }\r
+\r
+ /**\r
+ * Notifies the multi page editor service that the component within which it\r
+ * exists has become active.\r
+ * \r
+ * @since 3.2\r
+ */\r
+ public final void activate() {\r
+ e4Context.activate();\r
+ serviceLocator.activate();\r
+ }\r
+\r
+ /**\r
+ * Notifies the multi page editor service that the component within which it\r
+ * exists has been deactived.\r
+ * \r
+ * @since 3.2\r
+ */\r
+ public final void deactivate() {\r
+ serviceLocator.deactivate();\r
+ e4Context.deactivate();\r
+ }\r
+\r
+ /**\r
+ * Dispose the contributions.\r
+ */\r
+ public void dispose() {\r
+ if (menuExtenders != null) {\r
+ for (int i = 0; i < menuExtenders.size(); i++) {\r
+ ((PopupMenuExtender) menuExtenders.get(i)).dispose();\r
+ }\r
+ menuExtenders = null;\r
+ }\r
+\r
+ // Remove myself from the list of nested key binding services.\r
+ if (service != null) {\r
+ IKeyBindingService parentService = getMultiPageEditor().getSite()\r
+ .getKeyBindingService();\r
+ if (parentService instanceof INestableKeyBindingService) {\r
+ INestableKeyBindingService nestableParent = (INestableKeyBindingService) parentService;\r
+ nestableParent.removeKeyBindingService(this);\r
+ }\r
+ service = null;\r
+ }\r
+\r
+ if (serviceLocator != null) {\r
+ serviceLocator.dispose();\r
+ }\r
+ e4Context.dispose();\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IEditorSite</code> method returns <code>null</code>, since\r
+ * nested editors do not have their own action bar contributor.\r
+ * \r
+ * @return <code>null</code>\r
+ */\r
+ public IEditorActionBarContributor getActionBarContributor() {\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IEditorSite</code> method forwards to the multi-page editor to\r
+ * return the action bars.\r
+ * \r
+ * @return The action bars from the parent multi-page editor.\r
+ */\r
+ public IActionBars getActionBars() {\r
+ return ((IViewSite)multiPageEditor.getSite()).getActionBars();\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * \r
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)\r
+ */\r
+ public Object getAdapter(Class adapter) {\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page\r
+ * editor to return the decorator manager.\r
+ * \r
+ * @return The decorator from the workbench window.\r
+ * @deprecated use IWorkbench.getDecoratorManager()\r
+ */\r
+ @Deprecated\r
+ public ILabelDecorator getDecoratorManager() {\r
+ return getWorkbenchWindow().getWorkbench().getDecoratorManager()\r
+ .getLabelDecorator();\r
+ }\r
+\r
+// /**\r
+// * Returns the nested editor.\r
+// *\r
+// * @return the nested editor\r
+// */\r
+// public IEditorPart getEditor() {\r
+// return editor;\r
+// }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method returns an empty string since\r
+ * the nested editor is not created from the registry.\r
+ * \r
+ * @return An empty string.\r
+ */\r
+ public String getId() {\r
+ return ""; //$NON-NLS-1$\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc) Method declared on IEditorSite.\r
+ */\r
+ public IKeyBindingService getKeyBindingService() {\r
+ if (service == null) {\r
+ service = getMultiPageEditor().getSite()\r
+ .getKeyBindingService();\r
+ if (service instanceof INestableKeyBindingService) {\r
+ INestableKeyBindingService nestableService = (INestableKeyBindingService) service;\r
+ service = nestableService.getKeyBindingService(this);\r
+\r
+ } else {\r
+ /*\r
+ * This is an internal reference, and should not be copied by\r
+ * client code. If you are thinking of copying this, DON'T DO\r
+ * IT.\r
+ */\r
+ WorkbenchPlugin\r
+ .log("MultiPageEditorSite.getKeyBindingService() Parent key binding service was not an instance of INestableKeyBindingService. It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$\r
+ }\r
+ }\r
+ return service;\r
+ }\r
+\r
+ /**\r
+ * Returns the multi-page editor.\r
+ * \r
+ * @return the multi-page editor\r
+ */\r
+ public TabbedPropertyPage getMultiPageEditor() {\r
+ return multiPageEditor;\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page\r
+ * editor to return the workbench page.\r
+ * \r
+ * @return The workbench page in which this editor site resides.\r
+ */\r
+ public IWorkbenchPage getPage() {\r
+ return getMultiPageEditor().getSite().getPage();\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * \r
+ * @see org.eclipse.ui.IWorkbenchPartSite#getPart()\r
+ */\r
+ public IWorkbenchPart getPart() {\r
+ return editor;\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method returns an empty string since\r
+ * the nested editor is not created from the registry.\r
+ * \r
+ * @return An empty string.\r
+ */\r
+ public String getPluginId() {\r
+ return ""; //$NON-NLS-1$\r
+ }\r
+\r
+ /**\r
+ * Returns the post selection change listener which listens to the nested\r
+ * editor's selection changes.\r
+ * \r
+ * @return the post selection change listener.\r
+ */\r
+ private ISelectionChangedListener getPostSelectionChangedListener() {\r
+ if (postSelectionChangedListener == null) {\r
+ postSelectionChangedListener = new ISelectionChangedListener() {\r
+ public void selectionChanged(SelectionChangedEvent event) {\r
+ TabbedPropertyPageViewSite.this.handlePostSelectionChanged(event);\r
+ }\r
+ };\r
+ }\r
+ return postSelectionChangedListener;\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method returns an empty string since\r
+ * the nested editor is not created from the registry.\r
+ * \r
+ * @return An empty string.\r
+ */\r
+ public String getRegisteredName() {\r
+ return ""; //$NON-NLS-1$\r
+ }\r
+\r
+ /**\r
+ * Returns the selection changed listener which listens to the nested\r
+ * editor's selection changes, and calls <code>handleSelectionChanged</code>.\r
+ * \r
+ * @return the selection changed listener\r
+ */\r
+ private ISelectionChangedListener getSelectionChangedListener() {\r
+ if (selectionChangedListener == null) {\r
+ selectionChangedListener = new ISelectionChangedListener() {\r
+ public void selectionChanged(SelectionChangedEvent event) {\r
+ TabbedPropertyPageViewSite.this.handleSelectionChanged(event);\r
+ }\r
+ };\r
+ }\r
+ return selectionChangedListener;\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method returns the selection provider\r
+ * set by <code>setSelectionProvider</code>.\r
+ * \r
+ * @return The current selection provider.\r
+ */\r
+ public ISelectionProvider getSelectionProvider() {\r
+ return selectionProvider;\r
+ }\r
+\r
+ public final Object getService(final Class key) {\r
+ return serviceLocator.getService(key);\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page\r
+ * editor to return the shell.\r
+ * \r
+ * @return The shell in which this editor site resides.\r
+ */\r
+ public Shell getShell() {\r
+ return getMultiPageEditor().getSite().getShell();\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page\r
+ * editor to return the workbench window.\r
+ * \r
+ * @return The workbench window in which this editor site resides.\r
+ */\r
+ public IWorkbenchWindow getWorkbenchWindow() {\r
+ return getMultiPageEditor().getSite().getWorkbenchWindow();\r
+ }\r
+\r
+ /**\r
+ * Handles a post selection changed even from the nexted editor.\r
+ * <p>\r
+ * Subclasses may extend or reimplement this method\r
+ * \r
+ * @param event the event\r
+ * \r
+ * @since 3.2\r
+ */\r
+ protected void handlePostSelectionChanged(SelectionChangedEvent event) {\r
+ ISelectionProvider parentProvider = getMultiPageEditor().getSite()\r
+ .getSelectionProvider();\r
+ if (parentProvider instanceof TabbedPageSelectionProvider) {\r
+ SelectionChangedEvent newEvent = new SelectionChangedEvent(\r
+ parentProvider, event.getSelection());\r
+ TabbedPageSelectionProvider prov = (TabbedPageSelectionProvider) parentProvider;\r
+ prov.firePostSelectionChanged(newEvent);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Handles a selection changed event from the nested editor. The default\r
+ * implementation gets the selection provider from the multi-page editor's\r
+ * site, and calls <code>fireSelectionChanged</code> on it (only if it is\r
+ * an instance of <code>MultiPageSelectionProvider</code>), passing a new\r
+ * event object.\r
+ * <p>\r
+ * Subclasses may extend or reimplement this method.\r
+ * </p>\r
+ * \r
+ * @param event\r
+ * the event\r
+ */\r
+ protected void handleSelectionChanged(SelectionChangedEvent event) {\r
+ ISelectionProvider parentProvider = getMultiPageEditor().getSite()\r
+ .getSelectionProvider();\r
+ if (parentProvider instanceof TabbedPageSelectionProvider) {\r
+ SelectionChangedEvent newEvent = new SelectionChangedEvent(\r
+ parentProvider, event.getSelection());\r
+ TabbedPageSelectionProvider prov = (TabbedPageSelectionProvider) parentProvider;\r
+ prov.fireSelectionChanged(newEvent);\r
+ }\r
+ }\r
+\r
+ public final boolean hasService(final Class key) {\r
+ return serviceLocator.hasService(key);\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page\r
+ * editor for registration.\r
+ * \r
+ * @param menuManager\r
+ * The menu manager\r
+ * @param selProvider\r
+ * The selection provider.\r
+ */\r
+ public void registerContextMenu(MenuManager menuManager,\r
+ ISelectionProvider selProvider) {\r
+ getMultiPageEditor().getSite().registerContextMenu(menuManager,\r
+ selProvider);\r
+ }\r
+\r
+ public final void registerContextMenu(final MenuManager menuManager,\r
+ final ISelectionProvider selectionProvider,\r
+ final boolean includeEditorInput) {\r
+ registerContextMenu(getId(), menuManager, selectionProvider,\r
+ includeEditorInput);\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page\r
+ * editor for registration.\r
+ * \r
+ * @param menuID\r
+ * The identifier for the menu.\r
+ * @param menuMgr\r
+ * The menu manager\r
+ * @param selProvider\r
+ * The selection provider.\r
+ */\r
+ public void registerContextMenu(String menuID, MenuManager menuMgr,\r
+ ISelectionProvider selProvider) {\r
+ if (menuExtenders == null) {\r
+ menuExtenders = new ArrayList(1);\r
+ }\r
+ PartSite.registerContextMenu(menuID, menuMgr, selProvider, true,\r
+ editor, e4Context, menuExtenders);\r
+ }\r
+\r
+ public final void registerContextMenu(final String menuId,\r
+ final MenuManager menuManager,\r
+ final ISelectionProvider selectionProvider,\r
+ final boolean includeEditorInput) {\r
+ if (menuExtenders == null) {\r
+ menuExtenders = new ArrayList(1);\r
+ }\r
+ PartSite.registerContextMenu(menuId, menuManager, selectionProvider,\r
+ includeEditorInput, editor, e4Context, menuExtenders);\r
+ }\r
+\r
+ /**\r
+ * The <code>MultiPageEditorSite</code> implementation of this\r
+ * <code>IWorkbenchPartSite</code> method remembers the selection\r
+ * provider, and also hooks a listener on it, which calls\r
+ * <code>handleSelectionChanged</code> when a selection changed event\r
+ * occurs.\r
+ * \r
+ * @param provider\r
+ * The selection provider.\r
+ * @see MultiPageEditorSite#handleSelectionChanged(SelectionChangedEvent)\r
+ */\r
+ public void setSelectionProvider(ISelectionProvider provider) {\r
+ ISelectionProvider oldSelectionProvider = selectionProvider;\r
+ selectionProvider = provider;\r
+ if (oldSelectionProvider != null) {\r
+ oldSelectionProvider\r
+ .removeSelectionChangedListener(getSelectionChangedListener());\r
+ if (oldSelectionProvider instanceof IPostSelectionProvider) {\r
+ ((IPostSelectionProvider) oldSelectionProvider)\r
+ .removePostSelectionChangedListener(getPostSelectionChangedListener());\r
+ }\r
+ }\r
+ if (selectionProvider != null) {\r
+ selectionProvider\r
+ .addSelectionChangedListener(getSelectionChangedListener());\r
+ if (selectionProvider instanceof IPostSelectionProvider) {\r
+ ((IPostSelectionProvider) selectionProvider)\r
+ .addPostSelectionChangedListener(getPostSelectionChangedListener());\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String getSecondaryId() {\r
+ return ((IViewSite)multiPageEditor.getSite()).getSecondaryId();\r
+ }\r
+\r
+}\r