/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.browsing.ui.swt; /******************************************************************************* * Copyright (c) 2000, 2008 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 *******************************************************************************/ import java.util.ArrayList; import java.util.List; import org.eclipse.core.commands.util.Tracing; import org.eclipse.core.runtime.Adapters; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Item; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IKeyBindingService; import org.eclipse.ui.IMemento; import org.eclipse.ui.INestableKeyBindingService; import org.eclipse.ui.IPartService; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.misc.Policy; import org.eclipse.ui.internal.services.INestable; import org.eclipse.ui.internal.services.IServiceLocatorCreator; import org.eclipse.ui.internal.util.Util; import org.eclipse.ui.part.MultiPageEditorPart; import org.eclipse.ui.part.MultiPageEditorSite; import org.eclipse.ui.part.MultiPageSelectionProvider; import org.eclipse.ui.part.PageSwitcher; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.services.IDisposable; import org.eclipse.ui.services.IServiceLocator; /** * A multi-page editor is an editor with multiple pages, each of which may * contain an editor or an arbitrary SWT control. *

* Subclasses must implement the following methods: *

*

*

* Multi-page editors have a single action bar contributor, which manages * contributions for all the pages. The contributor must be a subclass of * AbstractMultiPageEditorActionBarContributor. Note that since * any nested editors are created directly in code by callers of * addPage(IEditorPart,IEditorInput), nested editors do not have * their own contributors. *

* * @see org.eclipse.ui.part.MultiPageEditorActionBarContributor * * NOTE: this class was originally copied from MultiPageEditorPart and adapter to work as a ViewPart. */ @SuppressWarnings({"restriction","deprecation","unchecked","rawtypes"}) public abstract class TabbedPropertyPage extends ViewPart { /** * Subclasses that override {@link #createPageContainer(Composite)} can use * this constant to get a site for the container that can be active while * the current page is deactivated. * * @since 3.4 * @see #activateSite() * @see #deactivateSite(boolean, boolean) * @see #getPageSite(int) */ protected static final int PAGE_CONTAINER_SITE = 65535; /** * Private tracing output. */ private static final String TRACING_COMPONENT = "MPE"; //$NON-NLS-1$ /** * The active service locator. This value may be null if * there is no selected page, or if the selected page is a control with * no site. */ private INestable activeServiceLocator; /** * The container widget. */ private CTabFolder container; private Composite pageContainer; /** * List of nested editors. Element type: IEditorPart. Need to hang onto them * here, in addition to using get/setData on the items, because dispose() * needs to access them, but widgetry has already been disposed at that * point. */ private final ArrayList nestedEditors = new ArrayList(3); private final List pageSites = new ArrayList(3); private IServiceLocator pageContainerSite; /** * Creates and adds a new page containing the given control to this * multi-page editor. The control may be null, allowing it * to be created and set later using setControl. * * @param control * the control, or null * @return the index of the new page * * @see MultiPageEditorPart#setControl(int, Control) */ public int addPage(Control control) { int index = getPageCount(); addPage(index, control); return index; } /** * @param control the control to add as a page * @param text the page title text * @param image the page title image * @return */ public int addPage(Control control, String text, Image image) { int result = addPage(control); setPageText(result, text); setPageImage(result, image); return result; } /** * Creates and adds a new page containing the given control to this * multi-page editor. The page is added at the given index. The control may * be null, allowing it to be created and set later using * setControl. * * @param index * the index at which to add the page (0-based) * @param control * the control, or null * * @see MultiPageEditorPart#setControl(int, Control) */ public void addPage(int index, Control control) { createItem(index, control); } /** * Creates an empty container. Creates a CTabFolder with no style bits set, * and hooks a selection listener which calls pageChange() * whenever the selected tab changes. * * @param parent * The composite in which the container tab folder should be * created; must not be null. * @return a new container */ private CTabFolder createContainer(Composite parent) { // use SWT.FLAT style so that an extra 1 pixel border is not reserved // inside the folder parent.setLayout(new FillLayout()); final CTabFolder newContainer = new CTabFolder(parent, getContainerStyle()); newContainer.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int newPageIndex = newContainer.indexOf((CTabItem) e.item); pageChange(newPageIndex); } }); return newContainer; } /** * Override this to customize the style given to the container * {@link CTabFolder} instance created by * {@link #createContainer(Composite)}. Default value is {@value SWT#BOTTOM} * | {@value SWT#FLAT}. * * @return swt style mask for {@link CTabFolder} */ protected int getContainerStyle() { return SWT.BOTTOM | SWT.FLAT; } /** * Creates a tab item at the given index and places the given control in the * new item. The item is a CTabItem with no style bits set. * * @param index * the index at which to add the control * @param control * is the control to be placed in an item * @return a new item */ private CTabItem createItem(int index, Control control) { CTabItem item = new CTabItem(getTabFolder(), SWT.NONE, index); item.setControl(control); return item; } /** * Creates the pages of this multi-page editor. *

* Subclasses must implement this method. *

*/ protected abstract void createPages(); /** * The MultiPageEditor implementation of this * IWorkbenchPart method creates the control for the * multi-page editor by calling createContainer, then * createPages. Subclasses should implement * createPages rather than overriding this method. * * @param parent * The parent in which the editor should be created; must not be * null. */ @Override public final void createPartControl(Composite parent) { this.pageContainer = createPageContainer(parent); this.container = createContainer(pageContainer); createPages(); // set the active page (page 0 by default), unless it has already been // done if (getActivePage() == -1) { setActivePage(0); IViewSite site = getViewSite(); if (site!=null) { final IServiceLocator serviceLocator = site; if (serviceLocator instanceof INestable) { activeServiceLocator = (INestable) serviceLocator; activeServiceLocator.activate(); } } } initializePageSwitching(); } /** * Initialize the MultiPageEditorPart to use the page switching command. * Clients can override this method with an empty body if they wish to * opt-out. * * @since 3.4 */ protected void initializePageSwitching() { new PageSwitcher(getSite().getPart()) { @Override public Object[] getPages() { int pageCount = getPageCount(); Object[] result = new Object[pageCount]; for (int i = 0; i < pageCount; i++) { result[i] = new Integer(i); } return result; } @Override public String getName(Object page) { return getPageText(((Integer) page).intValue()); } @Override public ImageDescriptor getImageDescriptor(Object page) { Image image = getPageImage(((Integer) page).intValue()); if (image == null) return null; return ImageDescriptor.createFromImage(image); } @Override public void activatePage(Object page) { setActivePage(((Integer) page).intValue()); } @Override public int getCurrentPageIndex() { return getActivePage(); } }; } /** * Creates the parent control for the container returned by * {@link #getContainer() }. * *

* Subclasses may extend and must call super implementation first. *

* * @param parent * the parent for all of the editors contents. * @return the parent for this editor's container. Must not be * null. * * @since 3.2 */ protected Composite createPageContainer(Composite parent) { return parent; } public Composite getPageContainer() { return pageContainer; } /** * Creates the site for the given nested editor. The * MultiPageEditorPart implementation of this method creates * an instance of MultiPageEditorSite. Subclasses may * reimplement to create more specialized sites. * * @param editor * the nested editor * @return the editor site */ protected IViewSite createSite(IViewPart editor) { return new TabbedPropertyPageViewSite(this, editor); } /** * The MultiPageEditorPart implementation of this * IWorkbenchPart method disposes all nested editors. * Subclasses may extend. */ @Override public void dispose() { for (int i = 0; i < nestedEditors.size(); ++i) { IEditorPart editor = (IEditorPart) nestedEditors.get(i); disposePart(editor); } nestedEditors.clear(); if (pageContainerSite instanceof IDisposable) { ((IDisposable) pageContainerSite).dispose(); pageContainerSite = null; } for (int i = 0; i < pageSites.size(); i++) { IServiceLocator sl = (IServiceLocator) pageSites.get(i); if (sl instanceof IDisposable) { ((IDisposable) sl).dispose(); } } pageSites.clear(); } /** * Returns the active nested editor if there is one. *

* Subclasses should not override this method *

* * @return the active nested editor, or null if none */ protected IEditorPart getActiveEditor() { int index = getActivePage(); if (index != -1) { return getEditor(index); } return null; } /** * Returns the index of the currently active page, or -1 if there is no * active page. *

* Subclasses should not override this method *

* * @return the index of the active page, or -1 if there is no active page */ protected int getActivePage() { CTabFolder tabFolder = getTabFolder(); if (tabFolder != null && !tabFolder.isDisposed()) { return tabFolder.getSelectionIndex(); } return -1; } /** * Returns the composite control containing this multi-page editor's pages. * This should be used as the parent when creating controls for the * individual pages. That is, when calling addPage(Control), * the passed control should be a child of this container. *

* Warning: Clients should not assume that the container is any particular * subclass of Composite. The actual class used may change in order to * improve the look and feel of multi-page editors. Any code making * assumptions on the particular subclass would thus be broken. *

*

* Subclasses should not override this method *

* * @return the composite, or null if * createPartControl has not been called yet */ protected Composite getContainer() { return container; } /** * Returns the control for the given page index, or null if * no control has been set for the page. The page index must be valid. *

* Subclasses should not override this method *

* * @param pageIndex * the index of the page * @return the control for the specified page, or null if * none has been set */ protected Control getControl(int pageIndex) { return getItem(pageIndex).getControl(); } /** * Returns the editor for the given page index. The page index must be * valid. * * @param pageIndex * the index of the page * @return the editor for the specified page, or null if the * specified page was not created with * addPage(IEditorPart,IEditorInput) */ protected IEditorPart getEditor(int pageIndex) { Item item = getItem(pageIndex); if (item != null) { Object data = item.getData(); if (data instanceof IEditorPart) { return (IEditorPart) data; } } return null; } /** * Returns the service locator for the given page index. This method can be * used to create service locators for pages that are just controls. The * page index must be valid. *

* This will return the editor site service locator for an editor, and * create one for a page that is just a control. *

* * @param pageIndex * the index of the page * @return the editor for the specified page, or null if the * specified page was not created with * addPage(IEditorPart,IEditorInput) * @since 3.4 */ protected final IServiceLocator getPageSite(int pageIndex) { if (pageIndex == PAGE_CONTAINER_SITE) { return getPageContainerSite(); } Item item = getItem(pageIndex); if (item != null) { Object data = item.getData(); if (data instanceof IEditorPart) { return ((IEditorPart) data).getSite(); } else if (data instanceof IServiceLocator) { return (IServiceLocator) data; } else if (data == null) { IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite() .getService(IServiceLocatorCreator.class); IServiceLocator sl = slc.createServiceLocator(getSite(), null, new IDisposable() { @Override public void dispose() { // TODO Auto-generated method stub } }); item.setData(sl); pageSites.add(sl); return sl; } } return null; } /** * @return A site that can be used with a header. * @since 3.4 * @see #createPageContainer(Composite) * @see #PAGE_CONTAINER_SITE * @see #getPageSite(int) */ private IServiceLocator getPageContainerSite() { if (pageContainerSite == null) { IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite() .getService(IServiceLocatorCreator.class); pageContainerSite = slc.createServiceLocator(getSite(), null, new IDisposable() { @Override public void dispose() { // TODO Auto-generated method stub } }); } return pageContainerSite; } /** * Returns the tab item for the given page index (page index is 0-based). * The page index must be valid. * * @param pageIndex * the index of the page * @return the tab item for the given page index */ private CTabItem getItem(int pageIndex) { return getTabFolder().getItem(pageIndex); } /** * Returns the number of pages in this multi-page editor. * * @return the number of pages */ protected int getPageCount() { CTabFolder folder = getTabFolder(); // May not have been created yet, or may have been disposed. if (folder != null && !folder.isDisposed()) { return folder.getItemCount(); } return 0; } /** * Returns the image for the page with the given index, or null * if no image has been set for the page. The page index must be valid. * * @param pageIndex * the index of the page * @return the image, or null if none */ protected Image getPageImage(int pageIndex) { return getItem(pageIndex).getImage(); } /** * Returns the text label for the page with the given index. Returns the * empty string if no text label has been set for the page. The page index * must be valid. * * @param pageIndex * the index of the page * @return the text label for the page */ protected String getPageText(int pageIndex) { return getItem(pageIndex).getText(); } /** * Returns the tab folder containing this multi-page editor's pages. * * @return the tab folder, or null if * createPartControl has not been called yet */ protected CTabFolder getTabFolder() { return container; } /** * Handles a property change notification from a nested editor. The default * implementation simply forwards the change to listeners on this multi-page * editor by calling firePropertyChange with the same * property id. For example, if the dirty state of a nested editor changes * (property id IEditorPart.PROP_DIRTY), this method handles * it by firing a property change event for * IEditorPart.PROP_DIRTY to property listeners on this * multi-page editor. *

* Subclasses may extend or reimplement this method. *

* * @param propertyId * the id of the property that changed */ protected void handlePropertyChange(int propertyId) { firePropertyChange(propertyId); } /** * The MultiPageEditorPart implementation of this * IEditorPart method sets its site to the given site, its * input to the given input, and the site's selection provider to a * MultiPageSelectionProvider. Subclasses may extend this * method. * * @param site * The site for which this part is being created; must not be * null. * @param input * The input on which this editor should be created; must not be * null. * @throws PartInitException * If the initialization of the part fails -- currently never. */ @Override public void init(IViewSite site, IMemento memento) throws PartInitException { setSite(site); site.setSelectionProvider(new TabbedPageSelectionProvider(this)); } /** * Notifies this multi-page editor that the page with the given id has been * activated. This method is called when the user selects a different tab. *

* The MultiPageEditorPart implementation of this method sets * focus to the new page, and notifies the action bar contributor (if there * is one). This checks whether the action bar contributor is an instance of * MultiPageEditorActionBarContributor, and, if so, calls * setActivePage with the active nested editor. This also * fires a selection change event if required. *

*

* Subclasses may extend this method. *

* * @param newPageIndex * the index of the activated page */ protected void pageChange(int newPageIndex) { deactivateSite(false, false); IPartService partService = (IPartService) getSite().getService( IPartService.class); if (partService != null && partService.getActivePart() == this) { setFocus(newPageIndex); } IEditorPart activeEditor = getEditor(newPageIndex); // IEditorActionBarContributor contributor = getViewSite() // .getActionBarContributor(); // if (contributor != null // && contributor instanceof MultiPageEditorActionBarContributor) { // ((MultiPageEditorActionBarContributor) contributor) // .setActivePage(activeEditor); // } if (activeEditor != null) { ISelectionProvider selectionProvider = activeEditor.getSite() .getSelectionProvider(); if (selectionProvider != null) { ISelectionProvider outerProvider = getSite() .getSelectionProvider(); if (outerProvider instanceof MultiPageSelectionProvider) { SelectionChangedEvent event = new SelectionChangedEvent( selectionProvider, selectionProvider.getSelection()); MultiPageSelectionProvider provider = (MultiPageSelectionProvider) outerProvider; provider.fireSelectionChanged(event); provider.firePostSelectionChanged(event); } else { if (Policy.DEBUG_MPE) { Tracing.printTrace(TRACING_COMPONENT, "MultiPageEditorPart " + getTitle() //$NON-NLS-1$ + " did not propogate selection for " //$NON-NLS-1$ + activeEditor.getTitle()); } } } } activateSite(); } /** * This method can be used by implementors of * {@link MultiPageEditorPart#createPageContainer(Composite)} to deactivate * the active inner editor services while their header has focus. A * deactivateSite() must have a matching call to activateSite() when * appropriate. *

* An new inner editor will have its site activated on a * {@link MultiPageEditorPart#pageChange(int)}. *

*

* Note: This API is evolving in 3.4 and this might not be its final * form. *

* * @param immediate * immediately deactivate the legacy keybinding service * @param containerSiteActive * Leave the page container site active. * @since 3.4 * @see #activateSite() * @see #createPageContainer(Composite) * @see #getPageSite(int) * @see #PAGE_CONTAINER_SITE */ protected final void deactivateSite(boolean immediate, boolean containerSiteActive) { // Deactivate the nested services from the last active service locator. if (activeServiceLocator != null) { activeServiceLocator.deactivate(); activeServiceLocator = null; } final int pageIndex = getActivePage(); final IKeyBindingService service = getSite().getKeyBindingService(); if (pageIndex < 0 || pageIndex >= getPageCount() || immediate) { // There is no selected page, so deactivate the active service. if (service instanceof INestableKeyBindingService) { final INestableKeyBindingService nestableService = (INestableKeyBindingService) service; nestableService.activateKeyBindingService(null); } else { WorkbenchPlugin .log("MultiPageEditorPart.setFocus() 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$ } } if (containerSiteActive) { IServiceLocator containerSite = getPageContainerSite(); if (containerSite instanceof INestable) { activeServiceLocator = (INestable) containerSite; activeServiceLocator.activate(); } } } /** * This method can be used by implementors of * {@link #createPageContainer(Composite)} to activate the active inner * editor services when their header loses focus. *

* An new inner editor will have its site activated on a * {@link #pageChange(int)}. *

*

* Note: This API is evolving in 3.4 and this might not be its final * form. *

* * @since 3.4 * @see #deactivateSite(boolean,boolean) * @see #createPageContainer(Composite) * @see #getPageSite(int) */ protected final void activateSite() { if (activeServiceLocator != null) { activeServiceLocator.deactivate(); activeServiceLocator = null; } final IKeyBindingService service = getSite().getKeyBindingService(); final int pageIndex = getActivePage(); final IEditorPart editor = getEditor(pageIndex); if (editor != null) { // active the service for this inner editor if (service instanceof INestableKeyBindingService) { final INestableKeyBindingService nestableService = (INestableKeyBindingService) service; nestableService.activateKeyBindingService(editor .getEditorSite()); } else { WorkbenchPlugin .log("MultiPageEditorPart.setFocus() 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$ } // Activate the services for the new service locator. final IServiceLocator serviceLocator = editor.getEditorSite(); if (serviceLocator instanceof INestable) { activeServiceLocator = (INestable) serviceLocator; activeServiceLocator.activate(); } } else { Item item = getItem(pageIndex); // There is no selected editor, so deactivate the active service. if (service instanceof INestableKeyBindingService) { final INestableKeyBindingService nestableService = (INestableKeyBindingService) service; nestableService.activateKeyBindingService(null); } else { WorkbenchPlugin .log("MultiPageEditorPart.setFocus() 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$ } if (item.getData() instanceof INestable) { activeServiceLocator = (INestable) item.getData(); activeServiceLocator.activate(); } } } /** * Disposes the given part and its site. * * @param part * The part to dispose; must not be null. */ private void disposePart(final IWorkbenchPart part) { SafeRunner.run(new ISafeRunnable() { public void run() { IWorkbenchPartSite partSite = part.getSite(); part.dispose(); if (partSite instanceof MultiPageEditorSite) { ((MultiPageEditorSite) partSite).dispose(); } } public void handleException(Throwable e) { // Exception has already being logged by Core. Do nothing. } }); } /** * Removes the page with the given index from this multi-page editor. The * controls for the page are disposed of; if the page has an editor, it is * disposed of too. The page index must be valid. * * @param pageIndex * the index of the page * @see MultiPageEditorPart#addPage(Control) * @see MultiPageEditorPart#addPage(IEditorPart, IEditorInput) */ public void removePage(int pageIndex) { Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount()); // get editor (if any) before disposing item IEditorPart editor = getEditor(pageIndex); // get control for the item if it's not an editor CTabItem item = getItem(pageIndex); IServiceLocator pageLocator = null; if (item.getData() instanceof IServiceLocator) { pageLocator = (IServiceLocator) item.getData(); } Control pageControl = item.getControl(); // dispose item before disposing editor, in case there's an exception // in editor's dispose item.dispose(); if (pageControl != null) { pageControl.dispose(); } // dispose editor (if any) if (editor != null) { nestedEditors.remove(editor); disposePart(editor); } if (pageLocator != null) { pageSites.remove(pageLocator); if (pageLocator instanceof IDisposable) { ((IDisposable) pageLocator).dispose(); } } } /** * Sets the currently active page. * * @param pageIndex * the index of the page to be activated; the index must be valid */ protected void setActivePage(int pageIndex) { Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount()); getTabFolder().setSelection(pageIndex); pageChange(pageIndex); } /** * Sets the control for the given page index. The page index must be valid. * * @param pageIndex * the index of the page * @param control * the control for the specified page, or null to * clear the control */ protected void setControl(int pageIndex, Control control) { getItem(pageIndex).setControl(control); } /** * The MultiPageEditor implementation of this * IWorkbenchPart method sets focus on the active nested * editor, if there is one. *

* Subclasses may extend or reimplement. *

*/ @Override public void setFocus() { setFocus(getActivePage()); } /** * Sets focus to the control for the given page. If the page has an editor, * this calls its setFocus() method. Otherwise, this calls * setFocus on the control for the page. * * @param pageIndex * the index of the page */ private void setFocus(int pageIndex) { final IEditorPart editor = getEditor(pageIndex); if (editor != null) { editor.setFocus(); } else { // Give the page's control focus. final Control control = getControl(pageIndex); if (control != null) { control.setFocus(); } } } /** * Sets the image for the page with the given index, or null * to clear the image for the page. The page index must be valid. * * @param pageIndex * the index of the page * @param image * the image, or null */ protected void setPageImage(int pageIndex, Image image) { getItem(pageIndex).setImage(image); } /** * Sets the text label for the page with the given index. The page index * must be valid. The text label must not be null. * * @param pageIndex * the index of the page * @param text * the text label */ protected void setPageText(int pageIndex, String text) { getItem(pageIndex).setText(text); } /** * If there is an adapter registered against the subclass of * MultiPageEditorPart return that. Otherwise, delegate to the internal * editor. * * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class) */ @Override public Object getAdapter(Class adapter) { Object result = super.getAdapter(adapter); // restrict delegating to the UI thread for bug 144851 if (result == null && Display.getCurrent()!=null) { IEditorPart innerEditor = getActiveEditor(); // see bug 138823 - prevent some subclasses from causing // an infinite loop if (innerEditor != null && innerEditor != this) { result = Adapters.adapt(innerEditor, adapter); } } return result; } // /** // * Find the editors contained in this multi-page editor // * whose editor input match the provided input. // * @param input the editor input // * @return the editors contained in this multi-page editor // * whose editor input match the provided input // * @since 3.3 // */ // public final IEditorPart[] findEditors(IEditorInput input) { // List result = new ArrayList(); // int count = getPageCount(); // for (int i = 0; i < count; i++) { // IEditorPart editor = getEditor(i); // if (editor != null // && editor.getEditorInput() != null // && editor.getEditorInput().equals(input)) { // result.add(editor); // } // } // return (IEditorPart[]) result.toArray(new IEditorPart[result.size()]); // } // // /** // * Set the active page of this multi-page editor to the // * page that contains the given editor part. This method has // * no effect of the given editor part is not contained in this // * multi-page editor. // * @param editorPart the editor part // * @since 3.3 // */ // public final void setActiveEditor(IEditorPart editorPart) { // int count = getPageCount(); // for (int i = 0; i < count; i++) { // IEditorPart editor = getEditor(i); // if (editor == editorPart) { // setActivePage(i); // break; // } // } // } // private IViewPart part; // // public IViewSite getSite() { // return part.getViewSite(); // } // // public IViewPart getPart() { // return part; // } // @Override public IViewSite getViewSite() { if(part instanceof IViewPart) return ((IViewPart) part).getViewSite(); else return null; } @Override public IWorkbenchPartSite getSite() { return part.getSite(); }; IWorkbenchPart part; public TabbedPropertyPage(IWorkbenchPart part) { this.part = part; // Given part may be null // assert(part != null); // setSite(part.getSite()); } }