| /******************************************************************************* |
| * Copyright (c) 2005, 2007 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.ui.internal; |
| |
| import org.eclipse.osgi.util.NLS; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.layout.FillLayout; |
| import org.eclipse.swt.widgets.Composite; |
| |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; |
| |
| import org.eclipse.jface.action.ContributionManager; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| |
| import org.eclipse.ui.IKeyBindingService; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IViewPart; |
| import org.eclipse.ui.IViewReference; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPart2; |
| import org.eclipse.ui.IWorkbenchPart3; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.misc.StatusUtil; |
| import org.eclipse.ui.internal.misc.UIStats; |
| import org.eclipse.ui.internal.registry.ViewDescriptor; |
| import org.eclipse.ui.internal.util.Util; |
| import org.eclipse.ui.menus.IMenuService; |
| import org.eclipse.ui.part.IWorkbenchPartOrientation; |
| import org.eclipse.ui.statushandlers.StatusManager; |
| import org.eclipse.ui.views.IViewDescriptor; |
| import org.eclipse.ui.views.IViewRegistry; |
| |
| class ViewReference extends WorkbenchPartReference implements IViewReference { |
| |
| /** |
| * |
| */ |
| private final ViewFactory factory; |
| |
| String secondaryId; |
| |
| private IMemento memento; |
| |
| private ViewActionBuilder actionBuilder; |
| |
| public ViewReference(ViewFactory factory, String id, String secondaryId, |
| IMemento memento) { |
| super(); |
| this.memento = memento; |
| this.factory = factory; |
| ViewDescriptor desc = (ViewDescriptor) this.factory.viewReg.find(id); |
| ImageDescriptor iDesc = null; |
| String title = null; |
| if (desc != null) { |
| iDesc = desc.getImageDescriptor(); |
| title = desc.getLabel(); |
| } |
| |
| String name = null; |
| |
| if (memento != null) { |
| name = memento.getString(IWorkbenchConstants.TAG_PART_NAME); |
| IMemento propBag = memento.getChild(IWorkbenchConstants.TAG_PROPERTIES); |
| if (propBag != null) { |
| IMemento[] props = propBag |
| .getChildren(IWorkbenchConstants.TAG_PROPERTY); |
| for (int i = 0; i < props.length; i++) { |
| propertyCache.put(props[i].getID(), props[i].getTextData()); |
| } |
| } |
| } |
| if (name == null) { |
| name = title; |
| } |
| |
| init(id, title, "", iDesc, name, ""); //$NON-NLS-1$//$NON-NLS-2$ |
| this.secondaryId = secondaryId; |
| } |
| |
| protected PartPane createPane() { |
| return new ViewPane(this, this.factory.page); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.internal.WorkbenchPartReference#dispose() |
| */ |
| protected void doDisposePart() { |
| IViewPart view = (IViewPart) part; |
| super.doDisposePart(); |
| if (view != null) { |
| // Free action bars, pane, etc. |
| PartSite site = (PartSite) view.getSite(); |
| ViewActionBars actionBars = (ViewActionBars) site.getActionBars(); |
| // |
| // 3.3 start |
| // |
| IMenuService menuService = (IMenuService) site |
| .getService(IMenuService.class); |
| menuService.releaseContributions((ContributionManager) site.getActionBars() |
| .getMenuManager()); |
| menuService.releaseContributions((ContributionManager) site.getActionBars() |
| .getToolBarManager()); |
| // 3.3 end |
| actionBars.dispose(); |
| |
| // and now dispose the delegates since the |
| // PluginActionContributionItem |
| // can no longer do that |
| if (actionBuilder != null) { |
| actionBuilder.dispose(); |
| actionBuilder = null; |
| } |
| |
| // Free the site. |
| site.dispose(); |
| } |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.IWorkbenchPartReference#getPage() |
| */ |
| public IWorkbenchPage getPage() { |
| return this.factory.page; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.internal.WorkbenchPartReference#getRegisteredName() |
| */ |
| public String getRegisteredName() { |
| if (part != null && part.getSite() != null) { |
| return part.getSite().getRegisteredName(); |
| } |
| |
| IViewRegistry reg = this.factory.viewReg; |
| IViewDescriptor desc = reg.find(getId()); |
| if (desc != null) { |
| return desc.getLabel(); |
| } |
| return getTitle(); |
| } |
| |
| protected String computePartName() { |
| if (part instanceof IWorkbenchPart2) { |
| return super.computePartName(); |
| } |
| return getRegisteredName(); |
| } |
| |
| protected String computeContentDescription() { |
| if (part instanceof IWorkbenchPart2) { |
| return super.computeContentDescription(); |
| } |
| |
| String rawTitle = getRawTitle(); |
| |
| if (!Util.equals(rawTitle, getRegisteredName())) { |
| return rawTitle; |
| } |
| |
| return ""; //$NON-NLS-1$ |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.IViewReference |
| */ |
| public String getSecondaryId() { |
| return secondaryId; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.IViewReference#getView(boolean) |
| */ |
| public IViewPart getView(boolean restore) { |
| return (IViewPart) getPart(restore); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.IViewReference#isFastView() |
| */ |
| public boolean isFastView() { |
| return this.factory.page.isFastView(this); |
| } |
| |
| /** |
| * Wrapper for restoring the view. First, this delegates to |
| * busyRestoreViewHelper to do the real work of restoring the view. If |
| * unable to restore the view, this method tries to substitute an error part |
| * and return success. |
| * |
| * @return the created part |
| */ |
| protected IWorkbenchPart createPart() { |
| |
| // Check the status of this part |
| |
| IWorkbenchPart result = null; |
| PartInitException exception = null; |
| |
| // Try to restore the view -- this does the real work of restoring the |
| // view |
| // |
| try { |
| result = createPartHelper(); |
| } catch (PartInitException e) { |
| exception = e; |
| } |
| |
| // If unable to create the part, create an error part instead |
| // and pass the error to the status handling facility |
| if (exception != null) { |
| IStatus partStatus = exception.getStatus(); |
| IStatus displayStatus = StatusUtil.newStatus(partStatus, |
| NLS.bind(WorkbenchMessages.ViewFactory_initException, partStatus.getMessage())); |
| IStatus logStatus = StatusUtil |
| .newStatus( |
| partStatus, |
| NLS |
| .bind( |
| "Unable to create view ID {0}: {1}", getId(), partStatus.getMessage())); //$NON-NLS-1$ |
| |
| // Pass the error to the status handling facility |
| StatusManager.getManager().handle(logStatus); |
| |
| IViewDescriptor desc = factory.viewReg.find(getId()); |
| String label = getId(); |
| if (desc != null) { |
| label = desc.getLabel(); |
| } |
| |
| ErrorViewPart part = new ErrorViewPart(displayStatus); |
| |
| PartPane pane = getPane(); |
| ViewSite site = new ViewSite(this, part, factory.page, getId(), |
| PlatformUI.PLUGIN_ID, label); |
| site.setActionBars(new ViewActionBars(factory.page.getActionBars(), |
| site, (ViewPane) pane)); |
| try { |
| part.init(site); |
| } catch (PartInitException e) { |
| StatusUtil.handleStatus(e, StatusManager.SHOW |
| | StatusManager.LOG); |
| return null; |
| } |
| part.setPartName(label); |
| |
| Composite parent = (Composite) pane.getControl(); |
| Composite content = new Composite(parent, SWT.NONE); |
| content.setLayout(new FillLayout()); |
| |
| try { |
| part.createPartControl(content); |
| } catch (Exception e) { |
| content.dispose(); |
| StatusUtil.handleStatus(e, StatusManager.SHOW |
| | StatusManager.LOG); |
| return null; |
| } |
| |
| result = part; |
| } |
| |
| return result; |
| } |
| |
| private IWorkbenchPart createPartHelper() throws PartInitException { |
| |
| IWorkbenchPart result = null; |
| |
| IMemento stateMem = null; |
| if (memento != null) { |
| stateMem = memento.getChild(IWorkbenchConstants.TAG_VIEW_STATE); |
| } |
| |
| IViewDescriptor desc = factory.viewReg.find(getId()); |
| if (desc == null) { |
| throw new PartInitException( |
| NLS.bind(WorkbenchMessages.ViewFactory_couldNotCreate, getId())); |
| } |
| |
| // Create the part pane |
| PartPane pane = getPane(); |
| |
| // Create the pane's top-level control |
| pane.createControl(factory.page.getClientComposite()); |
| |
| String label = desc.getLabel(); // debugging only |
| |
| // Things that will need to be disposed if an exception occurs (they are |
| // listed here |
| // in the order they should be disposed) |
| Composite content = null; |
| IViewPart initializedView = null; |
| ViewSite site = null; |
| ViewActionBars actionBars = null; |
| // End of things that need to be explicitly disposed from the try block |
| |
| try { |
| IViewPart view = null; |
| try { |
| UIStats.start(UIStats.CREATE_PART, label); |
| view = desc.createView(); |
| } finally { |
| UIStats.end(UIStats.CREATE_PART, view, label); |
| } |
| |
| if (view instanceof IWorkbenchPart3) { |
| createPartProperties((IWorkbenchPart3)view); |
| } |
| // Create site |
| site = new ViewSite(this, view, factory.page, desc); |
| actionBars = new ViewActionBars(factory.page.getActionBars(), site, |
| (ViewPane) pane); |
| site.setActionBars(actionBars); |
| |
| try { |
| UIStats.start(UIStats.INIT_PART, label); |
| view.init(site, stateMem); |
| // Once we've called init, we MUST dispose the view. Remember |
| // the fact that |
| // we've initialized the view in case an exception is thrown. |
| initializedView = view; |
| |
| } finally { |
| UIStats.end(UIStats.INIT_PART, view, label); |
| } |
| |
| if (view.getSite() != site) { |
| throw new PartInitException( |
| WorkbenchMessages.ViewFactory_siteException, null); |
| } |
| int style = SWT.NONE; |
| if (view instanceof IWorkbenchPartOrientation) { |
| style = ((IWorkbenchPartOrientation) view).getOrientation(); |
| } |
| |
| // Create the top-level composite |
| { |
| Composite parent = (Composite) pane.getControl(); |
| content = new Composite(parent, style); |
| content.setLayout(new FillLayout()); |
| |
| try { |
| UIStats.start(UIStats.CREATE_PART_CONTROL, label); |
| view.createPartControl(content); |
| |
| parent.layout(true); |
| } finally { |
| UIStats.end(UIStats.CREATE_PART_CONTROL, view, label); |
| } |
| } |
| |
| // Install the part's tools and menu |
| { |
| // |
| // 3.3 start |
| // |
| IMenuService menuService = (IMenuService) site |
| .getService(IMenuService.class); |
| menuService.populateContributionManager( |
| (ContributionManager) site.getActionBars() |
| .getMenuManager(), "menu:" //$NON-NLS-1$ |
| + site.getId()); |
| menuService |
| .populateContributionManager((ContributionManager) site |
| .getActionBars().getToolBarManager(), |
| "toolbar:" + site.getId()); //$NON-NLS-1$ |
| // 3.3 end |
| |
| actionBuilder = new ViewActionBuilder(); |
| actionBuilder.readActionExtensions(view); |
| ActionDescriptor[] actionDescriptors = actionBuilder |
| .getExtendedActions(); |
| IKeyBindingService keyBindingService = view.getSite() |
| .getKeyBindingService(); |
| |
| if (actionDescriptors != null) { |
| for (int i = 0; i < actionDescriptors.length; i++) { |
| ActionDescriptor actionDescriptor = actionDescriptors[i]; |
| |
| if (actionDescriptor != null) { |
| IAction action = actionDescriptors[i].getAction(); |
| |
| if (action != null |
| && action.getActionDefinitionId() != null) { |
| keyBindingService.registerAction(action); |
| } |
| } |
| } |
| } |
| |
| site.getActionBars().updateActionBars(); |
| } |
| |
| // The editor should now be fully created. Exercise its public |
| // interface, and sanity-check |
| // it wherever possible. If it's going to throw exceptions or behave |
| // badly, it's much better |
| // that it does so now while we can still cancel creation of the |
| // part. |
| PartTester.testView(view); |
| |
| result = view; |
| |
| IConfigurationElement element = (IConfigurationElement) Util.getAdapter(desc, |
| IConfigurationElement.class); |
| if (element != null) { |
| factory.page.getExtensionTracker().registerObject( |
| element.getDeclaringExtension(), view, |
| IExtensionTracker.REF_WEAK); |
| } |
| } catch (Throwable e) { |
| if ((e instanceof Error) && !(e instanceof LinkageError)) { |
| throw (Error) e; |
| } |
| |
| // An exception occurred. First deallocate anything we've allocated |
| // in the try block (see the top |
| // of the try block for a list of objects that need to be explicitly |
| // disposed) |
| if (content != null) { |
| try { |
| content.dispose(); |
| } catch (RuntimeException re) { |
| StatusManager.getManager().handle( |
| StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, |
| re)); |
| } |
| } |
| |
| if (initializedView != null) { |
| try { |
| initializedView.dispose(); |
| } catch (RuntimeException re) { |
| StatusManager.getManager().handle( |
| StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, |
| re)); |
| } |
| } |
| |
| if (site != null) { |
| try { |
| site.dispose(); |
| } catch (RuntimeException re) { |
| StatusManager.getManager().handle( |
| StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, |
| re)); |
| } |
| } |
| |
| if (actionBars != null) { |
| try { |
| actionBars.dispose(); |
| } catch (RuntimeException re) { |
| StatusManager.getManager().handle( |
| StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, |
| re)); |
| } |
| } |
| |
| throw new PartInitException(WorkbenchPlugin.getStatus(e)); |
| } |
| |
| return result; |
| } |
| |
| /** |
| * The memento is that last view state saved by the workbench. |
| * |
| * @return the last state that was saved by the workbench. It can return |
| * <code>null</code>. |
| * @since 3.1.1 |
| */ |
| public IMemento getMemento() { |
| return memento; |
| } |
| } |