1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.browsing.ui.swt;
14 /*******************************************************************************
15 * Copyright (c) 2000, 2008 IBM Corporation and others.
16 * All rights reserved. This program and the accompanying materials
17 * are made available under the terms of the Eclipse Public License v1.0
18 * which accompanies this distribution, and is available at
19 * http://www.eclipse.org/legal/epl-v10.html
22 * IBM Corporation - initial API and implementation
23 *******************************************************************************/
25 import java.util.ArrayList;
27 import org.eclipse.core.runtime.Assert;
28 import org.eclipse.e4.core.contexts.IEclipseContext;
29 import org.eclipse.jface.action.MenuManager;
30 import org.eclipse.jface.viewers.ILabelDecorator;
31 import org.eclipse.jface.viewers.IPostSelectionProvider;
32 import org.eclipse.jface.viewers.ISelectionChangedListener;
33 import org.eclipse.jface.viewers.ISelectionProvider;
34 import org.eclipse.jface.viewers.SelectionChangedEvent;
35 import org.eclipse.swt.widgets.Shell;
36 import org.eclipse.ui.IActionBars;
37 import org.eclipse.ui.IEditorActionBarContributor;
38 import org.eclipse.ui.IKeyBindingService;
39 import org.eclipse.ui.INestableKeyBindingService;
40 import org.eclipse.ui.IViewPart;
41 import org.eclipse.ui.IViewSite;
42 import org.eclipse.ui.IWorkbenchPage;
43 import org.eclipse.ui.IWorkbenchPart;
44 import org.eclipse.ui.IWorkbenchWindow;
45 import org.eclipse.ui.internal.PartSite;
46 import org.eclipse.ui.internal.PopupMenuExtender;
47 import org.eclipse.ui.internal.WorkbenchPlugin;
48 import org.eclipse.ui.internal.services.INestable;
49 import org.eclipse.ui.internal.services.IServiceLocatorCreator;
50 import org.eclipse.ui.internal.services.ServiceLocator;
51 import org.eclipse.ui.part.MultiPageEditorSite;
52 import org.eclipse.ui.services.IDisposable;
53 import org.eclipse.ui.services.IServiceLocator;
56 * Site for a nested editor within a multi-page editor. Selection is handled by
57 * forwarding the event to the multi-page editor's selection listeners; most
58 * other methods are forwarded to the multi-page editor's site.
60 * The base implementation of <code>MultiPageEditor.createSite</code> creates
61 * an instance of this class. This class may be instantiated or subclassed.
64 * TODO: copy e4 changes from MultiPageEditorSite to this class as seen fit
66 @SuppressWarnings({"restriction","deprecation","rawtypes"})
67 public class TabbedPropertyPageViewSite implements IViewSite, INestable {
72 private final IViewPart editor;
75 * The list of popup menu extenders; <code>null</code> if none registered.
77 private ArrayList menuExtenders;
80 * The multi-page editor.
82 private final TabbedPropertyPage multiPageEditor;
85 * The post selection changed listener.
87 private ISelectionChangedListener postSelectionChangedListener = null;
90 * The selection change listener, initialized lazily; <code>null</code> if
93 private ISelectionChangedListener selectionChangedListener = null;
96 * The selection provider; <code>null</code> if none.
98 * @see MultiPageEditorSite#setSelectionProvider(ISelectionProvider)
100 private ISelectionProvider selectionProvider = null;
103 * The cached copy of the key binding service specific to this multi-page
104 * editor site. This value is <code>null</code> if it is not yet
107 private IKeyBindingService service = null;
110 * The local service locator for this multi-page editor site. This value is
111 * never <code>null</code>.
113 private final ServiceLocator serviceLocator;
115 private IEclipseContext e4Context;
118 * Creates a site for the given editor nested within the given multi-page
121 * @param multiPageEditor
122 * the multi-page editor
126 public TabbedPropertyPageViewSite(TabbedPropertyPage multiPageEditor,
128 Assert.isNotNull(multiPageEditor);
129 Assert.isNotNull(editor);
130 this.multiPageEditor = multiPageEditor;
131 this.editor = editor;
133 final IServiceLocator parentServiceLocator = multiPageEditor.getSite();
134 IServiceLocatorCreator slc = (IServiceLocatorCreator) parentServiceLocator
135 .getService(IServiceLocatorCreator.class);
136 this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
137 parentServiceLocator, null, new IDisposable() {
139 public void dispose() {
140 // final Control control = ((PartSite)getMultiPageEditor().getSite()).getPane().getControl();
141 // if (control != null && !control.isDisposed()) {
142 // ((PartSite)getMultiPageEditor().getSite()).getPane().doHide();
146 e4Context = ((PartSite)editor.getViewSite()).getContext().createChild("TabbedPropertyPageViewSite");
147 serviceLocator.setContext(e4Context);
148 initializeDefaultServices();
152 * Initialize the slave services for this site.
154 private void initializeDefaultServices() {
155 // serviceLocator.registerService(IMultiPageEditorSiteHolder.class,
156 // new ITabbedPropertyPageSiteHolder() {
157 // public TabbedPropertyPageViewSite getSite() {
158 // return TabbedPropertyPageViewSite.this;
161 // Not possible to initialize this service for a view site:
162 // serviceLocator.registerService(IWorkbenchLocationService.class,
163 // new WorkbenchLocationService(IServiceScopes.MPESITE_SCOPE,
164 // getWorkbenchWindow().getWorkbench(),
165 // getWorkbenchWindow(), getMultiPageEditor().getSite(),
170 * Notifies the multi page editor service that the component within which it
171 * exists has become active.
175 public final void activate() {
176 e4Context.activate();
177 serviceLocator.activate();
181 * Notifies the multi page editor service that the component within which it
182 * exists has been deactived.
186 public final void deactivate() {
187 serviceLocator.deactivate();
188 e4Context.deactivate();
192 * Dispose the contributions.
194 public void dispose() {
195 if (menuExtenders != null) {
196 for (int i = 0; i < menuExtenders.size(); i++) {
197 ((PopupMenuExtender) menuExtenders.get(i)).dispose();
199 menuExtenders = null;
202 // Remove myself from the list of nested key binding services.
203 if (service != null) {
204 IKeyBindingService parentService = getMultiPageEditor().getSite()
205 .getKeyBindingService();
206 if (parentService instanceof INestableKeyBindingService) {
207 INestableKeyBindingService nestableParent = (INestableKeyBindingService) parentService;
208 nestableParent.removeKeyBindingService(this);
213 if (serviceLocator != null) {
214 serviceLocator.dispose();
220 * The <code>MultiPageEditorSite</code> implementation of this
221 * <code>IEditorSite</code> method returns <code>null</code>, since
222 * nested editors do not have their own action bar contributor.
224 * @return <code>null</code>
226 public IEditorActionBarContributor getActionBarContributor() {
231 * The <code>MultiPageEditorSite</code> implementation of this
232 * <code>IEditorSite</code> method forwards to the multi-page editor to
233 * return the action bars.
235 * @return The action bars from the parent multi-page editor.
237 public IActionBars getActionBars() {
238 return ((IViewSite)multiPageEditor.getSite()).getActionBars();
244 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
246 public Object getAdapter(Class adapter) {
251 * The <code>MultiPageEditorSite</code> implementation of this
252 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
253 * editor to return the decorator manager.
255 * @return The decorator from the workbench window.
256 * @deprecated use IWorkbench.getDecoratorManager()
259 public ILabelDecorator getDecoratorManager() {
260 return getWorkbenchWindow().getWorkbench().getDecoratorManager()
261 .getLabelDecorator();
265 // * Returns the nested editor.
267 // * @return the nested editor
269 // public IEditorPart getEditor() {
274 * The <code>MultiPageEditorSite</code> implementation of this
275 * <code>IWorkbenchPartSite</code> method returns an empty string since
276 * the nested editor is not created from the registry.
278 * @return An empty string.
280 public String getId() {
281 return ""; //$NON-NLS-1$
285 * (non-Javadoc) Method declared on IEditorSite.
287 public IKeyBindingService getKeyBindingService() {
288 if (service == null) {
289 service = getMultiPageEditor().getSite()
290 .getKeyBindingService();
291 if (service instanceof INestableKeyBindingService) {
292 INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
293 service = nestableService.getKeyBindingService(this);
297 * This is an internal reference, and should not be copied by
298 * client code. If you are thinking of copying this, DON'T DO
302 .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$
309 * Returns the multi-page editor.
311 * @return the multi-page editor
313 public TabbedPropertyPage getMultiPageEditor() {
314 return multiPageEditor;
318 * The <code>MultiPageEditorSite</code> implementation of this
319 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
320 * editor to return the workbench page.
322 * @return The workbench page in which this editor site resides.
324 public IWorkbenchPage getPage() {
325 return getMultiPageEditor().getSite().getPage();
331 * @see org.eclipse.ui.IWorkbenchPartSite#getPart()
333 public IWorkbenchPart getPart() {
338 * The <code>MultiPageEditorSite</code> implementation of this
339 * <code>IWorkbenchPartSite</code> method returns an empty string since
340 * the nested editor is not created from the registry.
342 * @return An empty string.
344 public String getPluginId() {
345 return ""; //$NON-NLS-1$
349 * Returns the post selection change listener which listens to the nested
350 * editor's selection changes.
352 * @return the post selection change listener.
354 private ISelectionChangedListener getPostSelectionChangedListener() {
355 if (postSelectionChangedListener == null) {
356 postSelectionChangedListener = new ISelectionChangedListener() {
357 public void selectionChanged(SelectionChangedEvent event) {
358 TabbedPropertyPageViewSite.this.handlePostSelectionChanged(event);
362 return postSelectionChangedListener;
366 * The <code>MultiPageEditorSite</code> implementation of this
367 * <code>IWorkbenchPartSite</code> method returns an empty string since
368 * the nested editor is not created from the registry.
370 * @return An empty string.
372 public String getRegisteredName() {
373 return ""; //$NON-NLS-1$
377 * Returns the selection changed listener which listens to the nested
378 * editor's selection changes, and calls <code>handleSelectionChanged</code>.
380 * @return the selection changed listener
382 private ISelectionChangedListener getSelectionChangedListener() {
383 if (selectionChangedListener == null) {
384 selectionChangedListener = new ISelectionChangedListener() {
385 public void selectionChanged(SelectionChangedEvent event) {
386 TabbedPropertyPageViewSite.this.handleSelectionChanged(event);
390 return selectionChangedListener;
394 * The <code>MultiPageEditorSite</code> implementation of this
395 * <code>IWorkbenchPartSite</code> method returns the selection provider
396 * set by <code>setSelectionProvider</code>.
398 * @return The current selection provider.
400 public ISelectionProvider getSelectionProvider() {
401 return selectionProvider;
404 public final Object getService(final Class key) {
405 return serviceLocator.getService(key);
409 * The <code>MultiPageEditorSite</code> implementation of this
410 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
411 * editor to return the shell.
413 * @return The shell in which this editor site resides.
415 public Shell getShell() {
416 return getMultiPageEditor().getSite().getShell();
420 * The <code>MultiPageEditorSite</code> implementation of this
421 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
422 * editor to return the workbench window.
424 * @return The workbench window in which this editor site resides.
426 public IWorkbenchWindow getWorkbenchWindow() {
427 return getMultiPageEditor().getSite().getWorkbenchWindow();
431 * Handles a post selection changed even from the nexted editor.
433 * Subclasses may extend or reimplement this method
435 * @param event the event
439 protected void handlePostSelectionChanged(SelectionChangedEvent event) {
440 ISelectionProvider parentProvider = getMultiPageEditor().getSite()
441 .getSelectionProvider();
442 if (parentProvider instanceof TabbedPageSelectionProvider) {
443 SelectionChangedEvent newEvent = new SelectionChangedEvent(
444 parentProvider, event.getSelection());
445 TabbedPageSelectionProvider prov = (TabbedPageSelectionProvider) parentProvider;
446 prov.firePostSelectionChanged(newEvent);
451 * Handles a selection changed event from the nested editor. The default
452 * implementation gets the selection provider from the multi-page editor's
453 * site, and calls <code>fireSelectionChanged</code> on it (only if it is
454 * an instance of <code>MultiPageSelectionProvider</code>), passing a new
457 * Subclasses may extend or reimplement this method.
463 protected void handleSelectionChanged(SelectionChangedEvent event) {
464 ISelectionProvider parentProvider = getMultiPageEditor().getSite()
465 .getSelectionProvider();
466 if (parentProvider instanceof TabbedPageSelectionProvider) {
467 SelectionChangedEvent newEvent = new SelectionChangedEvent(
468 parentProvider, event.getSelection());
469 TabbedPageSelectionProvider prov = (TabbedPageSelectionProvider) parentProvider;
470 prov.fireSelectionChanged(newEvent);
474 public final boolean hasService(final Class key) {
475 return serviceLocator.hasService(key);
479 * The <code>MultiPageEditorSite</code> implementation of this
480 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
481 * editor for registration.
486 * The selection provider.
488 public void registerContextMenu(MenuManager menuManager,
489 ISelectionProvider selProvider) {
490 getMultiPageEditor().getSite().registerContextMenu(menuManager,
494 public final void registerContextMenu(final MenuManager menuManager,
495 final ISelectionProvider selectionProvider,
496 final boolean includeEditorInput) {
497 registerContextMenu(getId(), menuManager, selectionProvider,
502 * The <code>MultiPageEditorSite</code> implementation of this
503 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
504 * editor for registration.
507 * The identifier for the menu.
511 * The selection provider.
513 public void registerContextMenu(String menuID, MenuManager menuMgr,
514 ISelectionProvider selProvider) {
515 if (menuExtenders == null) {
516 menuExtenders = new ArrayList(1);
518 PartSite.registerContextMenu(menuID, menuMgr, selProvider, true,
519 editor, e4Context, menuExtenders);
522 public final void registerContextMenu(final String menuId,
523 final MenuManager menuManager,
524 final ISelectionProvider selectionProvider,
525 final boolean includeEditorInput) {
526 if (menuExtenders == null) {
527 menuExtenders = new ArrayList(1);
529 PartSite.registerContextMenu(menuId, menuManager, selectionProvider,
530 includeEditorInput, editor, e4Context, menuExtenders);
534 * The <code>MultiPageEditorSite</code> implementation of this
535 * <code>IWorkbenchPartSite</code> method remembers the selection
536 * provider, and also hooks a listener on it, which calls
537 * <code>handleSelectionChanged</code> when a selection changed event
541 * The selection provider.
542 * @see MultiPageEditorSite#handleSelectionChanged(SelectionChangedEvent)
544 public void setSelectionProvider(ISelectionProvider provider) {
545 ISelectionProvider oldSelectionProvider = selectionProvider;
546 selectionProvider = provider;
547 if (oldSelectionProvider != null) {
549 .removeSelectionChangedListener(getSelectionChangedListener());
550 if (oldSelectionProvider instanceof IPostSelectionProvider) {
551 ((IPostSelectionProvider) oldSelectionProvider)
552 .removePostSelectionChangedListener(getPostSelectionChangedListener());
555 if (selectionProvider != null) {
557 .addSelectionChangedListener(getSelectionChangedListener());
558 if (selectionProvider instanceof IPostSelectionProvider) {
559 ((IPostSelectionProvider) selectionProvider)
560 .addPostSelectionChangedListener(getPostSelectionChangedListener());
566 public String getSecondaryId() {
567 return ((IViewSite)multiPageEditor.getSite()).getSecondaryId();