blob: 9a6be660e7678456a57c288b087886e172d9ace0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 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
* Dan Rubel (dan_rubel@instantiations.com) - accessor to get context menu ids
*******************************************************************************/
package org.eclipse.ui.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.e4.core.services.context.IEclipseContext;
import org.eclipse.e4.core.services.context.spi.ContextFunction;
import org.eclipse.e4.extensions.ModelReference;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.SubActionBars;
import org.eclipse.ui.internal.progress.WorkbenchSiteProgressService;
import org.eclipse.ui.internal.services.IServiceLocatorCreator;
import org.eclipse.ui.internal.services.IWorkbenchLocationService;
import org.eclipse.ui.internal.services.ServiceLocator;
import org.eclipse.ui.internal.services.WorkbenchLocationService;
import org.eclipse.ui.internal.testing.WorkbenchPartTestable;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
import org.eclipse.ui.services.IDisposable;
import org.eclipse.ui.services.IServiceScopes;
import org.eclipse.ui.testing.IWorkbenchPartTestable;
/**
* <code>PartSite</code> is the general implementation for an
* <code>IWorkbenchPartSite</code>. A site maintains the context for a part,
* including the part, its pane, active contributions, selection provider, etc.
* Together, these components make up the complete behavior for a part as if it
* was implemented by one person.
*
* The <code>PartSite</code> lifecycle is as follows ..
*
* <ol>
* <li>a site is constructed</li>
* <li>a part is constructed and stored in the part</li>
* <li>the site calls part.init()</li>
* <li>a pane is constructed and stored in the site</li>
* <li>the action bars for a part are constructed and stored in the site</li>
* <li>the pane is added to a presentation</li>
* <li>the SWT widgets for the pane and part are created</li>
* <li>the site is activated, causing the actions to become visible</li>
* </ol>
*/
public abstract class PartSite implements IWorkbenchPartSite {
/**
* This is a helper method for the register context menu functionality. It
* is provided so that different implementations of the
* <code>IWorkbenchPartSite</code> interface don't have to worry about how
* context menus should work.
*
* @param menuId
* the menu id
* @param menuManager
* the menu manager
* @param selectionProvider
* the selection provider
* @param includeEditorInput
* whether editor inputs should be included in the structured
* selection when calculating contributions
* @param part
* the part for this site
* @param menuExtenders
* the collection of menu extenders for this site
* @see IWorkbenchPartSite#registerContextMenu(MenuManager,
* ISelectionProvider)
*/
public static final void registerContextMenu(final String menuId,
final MenuManager menuManager,
final ISelectionProvider selectionProvider,
final boolean includeEditorInput, final IWorkbenchPart part,
final Collection menuExtenders) {
/*
* Check to see if the same menu manager and selection provider have
* already been used. If they have, then we can just add another menu
* identifier to the existing PopupMenuExtender.
*/
final Iterator extenderItr = menuExtenders.iterator();
boolean foundMatch = false;
while (extenderItr.hasNext()) {
final PopupMenuExtender existingExtender = (PopupMenuExtender) extenderItr
.next();
if (existingExtender.matches(menuManager, selectionProvider, part)) {
existingExtender.addMenuId(menuId);
foundMatch = true;
break;
}
}
if (!foundMatch) {
menuExtenders.add(new PopupMenuExtender(menuId, menuManager,
selectionProvider, part, includeEditorInput));
}
}
private IWorkbenchPartReference partReference;
private IWorkbenchPart part;
private IWorkbenchPage page;
private String extensionID;
private String pluginID;
private String extensionName;
private SubActionBars actionBars;
private KeyBindingService keyBindingService;
protected ArrayList menuExtenders;
private WorkbenchSiteProgressService progressService;
protected final ServiceLocator serviceLocator;
protected IEclipseContext e4Context;
/**
* Build the part site.
*
* @param ref
* the part reference
* @param part
* the part
* @param page
* the page it belongs to
*/
public PartSite(IWorkbenchPartReference ref, IWorkbenchPart part,
IWorkbenchPage page) {
this.partReference = ref;
this.part = part;
this.page = page;
extensionID = "org.eclipse.ui.UnknownID"; //$NON-NLS-1$
extensionName = "Unknown Name"; //$NON-NLS-1$
// Initialize the service locator.
final WorkbenchWindow workbenchWindow = (WorkbenchWindow) page
.getWorkbenchWindow();
IServiceLocatorCreator slc = (IServiceLocatorCreator) workbenchWindow
.getService(IServiceLocatorCreator.class);
this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
workbenchWindow, null, new IDisposable() {
public void dispose() {
final Control control = getPane().getControl();
if (control != null && !control.isDisposed()) {
getPane().doHide();
}
}
});
e4Context = ((ModelReference) partReference).getModel().getContext();
this.serviceLocator.setContext(e4Context);
initializeDefaultServices();
}
/**
* Initialize the local services.
*/
private void initializeDefaultServices() {
serviceLocator.registerService(IWorkbenchLocationService.class,
new WorkbenchLocationService(IServiceScopes.PARTSITE_SCOPE,
getWorkbenchWindow().getWorkbench(),
getWorkbenchWindow(), this, null, null, 2));
// added back for legacy reasons
serviceLocator.registerService(IWorkbenchPartSite.class, this);
e4Context.set(IWorkbenchSiteProgressService.class.getName(),
new ContextFunction() {
@Override
public Object compute(IEclipseContext context,
Object[] arguments) {
if (progressService == null) {
progressService = new WorkbenchSiteProgressService(
PartSite.this);
}
return progressService;
}
});
e4Context.set(IKeyBindingService.class.getName(),
new ContextFunction() {
@Override
public Object compute(IEclipseContext context,
Object[] arguments) {
if (keyBindingService == null) {
keyBindingService = new KeyBindingService(
PartSite.this);
}
return keyBindingService;
}
});
}
/**
* Dispose the contributions.
*/
public void dispose() {
if (menuExtenders != null) {
HashSet managers = new HashSet(menuExtenders.size());
for (int i = 0; i < menuExtenders.size(); i++) {
PopupMenuExtender ext = (PopupMenuExtender) menuExtenders
.get(i);
managers.add(ext.getManager());
ext.dispose();
}
if (managers.size() > 0) {
for (Iterator iterator = managers.iterator(); iterator
.hasNext();) {
MenuManager mgr = (MenuManager) iterator.next();
mgr.dispose();
}
}
menuExtenders = null;
}
if (keyBindingService != null) {
keyBindingService.dispose();
keyBindingService = null;
}
if (progressService != null) {
progressService.dispose();
progressService = null;
}
if (serviceLocator != null) {
serviceLocator.dispose();
}
part = null;
}
/**
* Returns the action bars for the part. If this part is a view then it has
* exclusive use of the action bars. If this part is an editor then the
* action bars are shared among this editor and other editors of the same
* type.
*/
public IActionBars getActionBars() {
return actionBars;
}
/**
* Returns the part registry extension ID.
*
* @return the registry extension ID
*/
public String getId() {
return extensionID;
}
/**
* Returns the page containing this workbench site's part.
*
* @return the page containing this part
*/
public IWorkbenchPage getPage() {
return page;
}
/**
* Gets the part pane.
*/
public PartPane getPane() {
return null;
}
/**
* Returns the part.
*/
public IWorkbenchPart getPart() {
return part;
}
/**
* Returns the part reference.
*/
public IWorkbenchPartReference getPartReference() {
return partReference;
}
/**
* Returns the part registry plugin ID. It cannot be <code>null</code>.
*
* @return the registry plugin ID
*/
public String getPluginId() {
return pluginID;
}
/**
* Returns the registered name for this part.
*/
public String getRegisteredName() {
return extensionName;
}
/**
* Returns the selection provider for a part.
*/
public ISelectionProvider getSelectionProvider() {
return (ISelectionProvider) e4Context.get(ISelectionProvider.class
.getName());
}
/**
* Returns the shell containing this part.
*
* @return the shell containing this part
*/
public Shell getShell() {
return (Shell) e4Context.get(Shell.class.getName());
}
/**
* Returns the workbench window containing this part.
*
* @return the workbench window containing this part
*/
public IWorkbenchWindow getWorkbenchWindow() {
return page.getWorkbenchWindow();
}
/**
* Register a popup menu for extension.
*/
public void registerContextMenu(String menuID, MenuManager menuMgr,
ISelectionProvider selProvider) {
if (menuExtenders == null) {
menuExtenders = new ArrayList(1);
}
registerContextMenu(menuID, menuMgr, selProvider, true, getPart(),
menuExtenders);
}
/**
* Register a popup menu with the default id for extension.
*/
public void registerContextMenu(MenuManager menuMgr,
ISelectionProvider selProvider) {
registerContextMenu(getId(), menuMgr, selProvider);
}
// getContextMenuIds() added by Dan Rubel (dan_rubel@instantiations.com)
/**
* Get the registered popup menu identifiers
*/
public String[] getContextMenuIds() {
if (menuExtenders == null) {
return new String[0];
}
ArrayList menuIds = new ArrayList(menuExtenders.size());
for (Iterator iter = menuExtenders.iterator(); iter.hasNext();) {
final PopupMenuExtender extender = (PopupMenuExtender) iter.next();
menuIds.addAll(extender.getMenuIds());
}
return (String[]) menuIds.toArray(new String[menuIds.size()]);
}
/**
* Sets the action bars for the part.
*/
public void setActionBars(SubActionBars bars) {
e4Context.set(IActionBars.class.getName(), bars);
actionBars = bars;
}
/**
* Sets the configuration element for a part.
*/
public void setConfigurationElement(IConfigurationElement configElement) {
// Get extension ID.
extensionID = configElement.getAttribute("id"); //$NON-NLS-1$
// Get plugin ID.
pluginID = configElement.getNamespace();
// Get extension name.
String name = configElement.getAttribute("name"); //$NON-NLS-1$
if (name != null) {
extensionName = name;
}
}
protected void setPluginId(String pluginId) {
this.pluginID = pluginId;
}
/**
* Sets the part registry extension ID.
*
* @param id
* the registry extension ID
*/
protected void setId(String id) {
extensionID = id;
}
/**
* Sets the part.
*/
public void setPart(IWorkbenchPart newPart) {
part = newPart;
}
/**
* Sets the registered name for this part.
*
* @param name
* the registered name
*/
protected void setRegisteredName(String name) {
extensionName = name;
}
/**
* Set the selection provider for a part.
*/
public void setSelectionProvider(ISelectionProvider provider) {
e4Context.set(ISelectionProvider.class.getName(), provider);
if (provider != null) {
final IEclipseContext outputContext = (IEclipseContext) e4Context
.get(IServiceConstants.OUTPUTS);
provider
.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
outputContext.set(IServiceConstants.SELECTION,
event.getSelection());
}
});
}
}
/*
* @see IWorkbenchPartSite#getKeyBindingService()
*/
public IKeyBindingService getKeyBindingService() {
return (IKeyBindingService) e4Context.get(IKeyBindingService.class
.getName());
}
protected String getInitialScopeId() {
return null;
}
/**
* Get an adapter for this type.
*
* @param adapter
* @return
*/
public final Object getAdapter(Class adapter) {
if (IWorkbenchSiteProgressService.class == adapter) {
return getSiteProgressService();
}
if (IWorkbenchPartTestable.class == adapter) {
return new WorkbenchPartTestable(this);
}
return Platform.getAdapterManager().getAdapter(this, adapter);
}
public void activateActionBars(boolean forceVisibility) {
if (serviceLocator != null) {
serviceLocator.activate();
}
if (actionBars != null) {
actionBars.activate(forceVisibility);
}
}
public void deactivateActionBars(boolean forceHide) {
if (actionBars != null) {
actionBars.deactivate(forceHide);
}
if (serviceLocator != null) {
serviceLocator.deactivate();
}
}
/**
* Get a progress service for the receiver.
*
* @return WorkbenchSiteProgressService
*/
WorkbenchSiteProgressService getSiteProgressService() {
return (WorkbenchSiteProgressService) e4Context
.get(IWorkbenchSiteProgressService.class.getName());
}
public final Object getService(final Class key) {
return serviceLocator.getService(key);
}
public final boolean hasService(final Class key) {
return serviceLocator.hasService(key);
}
/**
* Prints out the identifier, the plug-in identifier and the registered
* name. This is for debugging purposes only.
*
* @since 3.2
*/
public String toString() {
final StringBuffer buffer = new StringBuffer();
buffer.append("PartSite(id="); //$NON-NLS-1$
buffer.append(getId());
buffer.append(",pluginId="); //$NON-NLS-1$
buffer.append(getPluginId());
buffer.append(",registeredName="); //$NON-NLS-1$
buffer.append(getRegisteredName());
buffer.append(",hashCode="); //$NON-NLS-1$
buffer.append(hashCode());
buffer.append(')');
return buffer.toString();
}
public IEclipseContext getContext() {
return e4Context;
}
}