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