]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/TabbedPropertyPageViewSite.java
Merge remote-tracking branch 'origin/svn' commit 'ccc1271c9d6657fb9dcf4cf3cb115fa0c8c...
[simantics/platform.git] / bundles / org.simantics.browsing.ui.swt / src / org / simantics / browsing / ui / swt / TabbedPropertyPageViewSite.java
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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.browsing.ui.swt;\r
13 \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
20  *\r
21  * Contributors:\r
22  *     IBM Corporation - initial API and implementation\r
23  *******************************************************************************/\r
24 \r
25 import java.util.ArrayList;\r
26 \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
54 \r
55 /**\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
59  * <p>\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
62  * </p>\r
63  * \r
64  * TODO: copy e4 changes from MultiPageEditorSite to this class as seen fit\r
65  */\r
66 @SuppressWarnings({"restriction","deprecation","rawtypes"})\r
67 public class TabbedPropertyPageViewSite implements IViewSite, INestable {\r
68 \r
69     /**\r
70      * The nested editor.\r
71      */\r
72     private final IViewPart editor;\r
73 \r
74     /**\r
75      * The list of popup menu extenders; <code>null</code> if none registered.\r
76      */\r
77     private ArrayList menuExtenders;\r
78 \r
79     /**\r
80      * The multi-page editor.\r
81      */\r
82     private final TabbedPropertyPage multiPageEditor;\r
83 \r
84     /**\r
85      * The post selection changed listener.\r
86      */\r
87     private ISelectionChangedListener postSelectionChangedListener = null;\r
88 \r
89     /**\r
90      * The selection change listener, initialized lazily; <code>null</code> if\r
91      * not yet created.\r
92      */\r
93     private ISelectionChangedListener selectionChangedListener = null;\r
94 \r
95     /**\r
96      * The selection provider; <code>null</code> if none.\r
97      * \r
98      * @see MultiPageEditorSite#setSelectionProvider(ISelectionProvider)\r
99      */\r
100     private ISelectionProvider selectionProvider = null;\r
101 \r
102     /**\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
105      * initialized.\r
106      */\r
107     private IKeyBindingService service = null;\r
108 \r
109     /**\r
110      * The local service locator for this multi-page editor site. This value is\r
111      * never <code>null</code>.\r
112      */\r
113     private final ServiceLocator serviceLocator;\r
114 \r
115         private IEclipseContext e4Context;\r
116 \r
117     /**\r
118      * Creates a site for the given editor nested within the given multi-page\r
119      * editor.\r
120      * \r
121      * @param multiPageEditor\r
122      *            the multi-page editor\r
123      * @param editor\r
124      *            the nested editor\r
125      */\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
132 \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
138                     @Override\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
143 //                        }\r
144                     }\r
145                 });\r
146         e4Context = ((PartSite)editor.getViewSite()).getContext().createChild("TabbedPropertyPageViewSite");\r
147         serviceLocator.setContext(e4Context);\r
148         initializeDefaultServices();\r
149     }\r
150 \r
151     /**\r
152      * Initialize the slave services for this site.\r
153      */\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
159 //                    }\r
160 //                });\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
167     }\r
168 \r
169     /**\r
170      * Notifies the multi page editor service that the component within which it\r
171      * exists has become active.\r
172      * \r
173      * @since 3.2\r
174      */\r
175     public final void activate() {\r
176         e4Context.activate();\r
177         serviceLocator.activate();\r
178     }\r
179 \r
180     /**\r
181      * Notifies the multi page editor service that the component within which it\r
182      * exists has been deactived.\r
183      * \r
184      * @since 3.2\r
185      */\r
186     public final void deactivate() {\r
187         serviceLocator.deactivate();\r
188         e4Context.deactivate();\r
189     }\r
190 \r
191     /**\r
192      * Dispose the contributions.\r
193      */\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
198             }\r
199             menuExtenders = null;\r
200         }\r
201 \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
209             }\r
210             service = null;\r
211         }\r
212 \r
213         if (serviceLocator != null) {\r
214             serviceLocator.dispose();\r
215         }\r
216         e4Context.dispose();\r
217     }\r
218 \r
219     /**\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
223      * \r
224      * @return <code>null</code>\r
225      */\r
226     public IEditorActionBarContributor getActionBarContributor() {\r
227         return null;\r
228     }\r
229 \r
230     /**\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
234      * \r
235      * @return The action bars from the parent multi-page editor.\r
236      */\r
237     public IActionBars getActionBars() {\r
238         return ((IViewSite)multiPageEditor.getSite()).getActionBars();\r
239     }\r
240 \r
241     /*\r
242      * (non-Javadoc)\r
243      * \r
244      * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)\r
245      */\r
246     public Object getAdapter(Class adapter) {\r
247         return null;\r
248     }\r
249 \r
250     /**\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
254      * \r
255      * @return The decorator from the workbench window.\r
256      * @deprecated use IWorkbench.getDecoratorManager()\r
257      */\r
258     @Deprecated\r
259     public ILabelDecorator getDecoratorManager() {\r
260         return getWorkbenchWindow().getWorkbench().getDecoratorManager()\r
261         .getLabelDecorator();\r
262     }\r
263 \r
264 //    /**\r
265 //     * Returns the nested editor.\r
266 //     *\r
267 //     * @return the nested editor\r
268 //     */\r
269 //    public IEditorPart getEditor() {\r
270 //        return editor;\r
271 //    }\r
272 \r
273     /**\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
277      * \r
278      * @return An empty string.\r
279      */\r
280     public String getId() {\r
281         return ""; //$NON-NLS-1$\r
282     }\r
283 \r
284     /*\r
285      * (non-Javadoc) Method declared on IEditorSite.\r
286      */\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
294 \r
295             } else {\r
296                 /*\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
299                  * IT.\r
300                  */\r
301                 WorkbenchPlugin\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
303             }\r
304         }\r
305         return service;\r
306     }\r
307 \r
308     /**\r
309      * Returns the multi-page editor.\r
310      * \r
311      * @return the multi-page editor\r
312      */\r
313     public TabbedPropertyPage getMultiPageEditor() {\r
314         return multiPageEditor;\r
315     }\r
316 \r
317     /**\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
321      * \r
322      * @return The workbench page in which this editor site resides.\r
323      */\r
324     public IWorkbenchPage getPage() {\r
325         return getMultiPageEditor().getSite().getPage();\r
326     }\r
327 \r
328     /*\r
329      * (non-Javadoc)\r
330      * \r
331      * @see org.eclipse.ui.IWorkbenchPartSite#getPart()\r
332      */\r
333     public IWorkbenchPart getPart() {\r
334         return editor;\r
335     }\r
336 \r
337     /**\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
341      * \r
342      * @return An empty string.\r
343      */\r
344     public String getPluginId() {\r
345         return ""; //$NON-NLS-1$\r
346     }\r
347 \r
348     /**\r
349      * Returns the post selection change listener which listens to the nested\r
350      * editor's selection changes.\r
351      * \r
352      * @return the post selection change listener.\r
353      */\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
359                 }\r
360             };\r
361         }\r
362         return postSelectionChangedListener;\r
363     }\r
364 \r
365     /**\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
369      * \r
370      * @return An empty string.\r
371      */\r
372     public String getRegisteredName() {\r
373         return ""; //$NON-NLS-1$\r
374     }\r
375 \r
376     /**\r
377      * Returns the selection changed listener which listens to the nested\r
378      * editor's selection changes, and calls <code>handleSelectionChanged</code>.\r
379      * \r
380      * @return the selection changed listener\r
381      */\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
387                 }\r
388             };\r
389         }\r
390         return selectionChangedListener;\r
391     }\r
392 \r
393     /**\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
397      * \r
398      * @return The current selection provider.\r
399      */\r
400     public ISelectionProvider getSelectionProvider() {\r
401         return selectionProvider;\r
402     }\r
403 \r
404     public final Object getService(final Class key) {\r
405         return serviceLocator.getService(key);\r
406     }\r
407 \r
408     /**\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
412      * \r
413      * @return The shell in which this editor site resides.\r
414      */\r
415     public Shell getShell() {\r
416         return getMultiPageEditor().getSite().getShell();\r
417     }\r
418 \r
419     /**\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
423      * \r
424      * @return The workbench window in which this editor site resides.\r
425      */\r
426     public IWorkbenchWindow getWorkbenchWindow() {\r
427         return getMultiPageEditor().getSite().getWorkbenchWindow();\r
428     }\r
429 \r
430     /**\r
431      * Handles a post selection changed even from the nexted editor.\r
432      * <p>\r
433      * Subclasses may extend or reimplement this method\r
434      * \r
435      * @param event  the event\r
436      * \r
437      * @since 3.2\r
438      */\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
447         }\r
448     }\r
449 \r
450     /**\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
455      * event object.\r
456      * <p>\r
457      * Subclasses may extend or reimplement this method.\r
458      * </p>\r
459      * \r
460      * @param event\r
461      *            the event\r
462      */\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
471         }\r
472     }\r
473 \r
474     public final boolean hasService(final Class key) {\r
475         return serviceLocator.hasService(key);\r
476     }\r
477 \r
478     /**\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
482      * \r
483      * @param menuManager\r
484      *            The menu manager\r
485      * @param selProvider\r
486      *            The selection provider.\r
487      */\r
488     public void registerContextMenu(MenuManager menuManager,\r
489             ISelectionProvider selProvider) {\r
490         getMultiPageEditor().getSite().registerContextMenu(menuManager,\r
491                 selProvider);\r
492     }\r
493 \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
499     }\r
500 \r
501     /**\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
505      * \r
506      * @param menuID\r
507      *            The identifier for the menu.\r
508      * @param menuMgr\r
509      *            The menu manager\r
510      * @param selProvider\r
511      *            The selection provider.\r
512      */\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
517         }\r
518         PartSite.registerContextMenu(menuID, menuMgr, selProvider, true,\r
519                 editor, e4Context, menuExtenders);\r
520     }\r
521 \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
528         }\r
529         PartSite.registerContextMenu(menuId, menuManager, selectionProvider,\r
530                 includeEditorInput, editor, e4Context, menuExtenders);\r
531     }\r
532 \r
533     /**\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
538      * occurs.\r
539      * \r
540      * @param provider\r
541      *            The selection provider.\r
542      * @see MultiPageEditorSite#handleSelectionChanged(SelectionChangedEvent)\r
543      */\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
553             }\r
554         }\r
555         if (selectionProvider != null) {\r
556             selectionProvider\r
557             .addSelectionChangedListener(getSelectionChangedListener());\r
558             if (selectionProvider instanceof IPostSelectionProvider) {\r
559                 ((IPostSelectionProvider) selectionProvider)\r
560                 .addPostSelectionChangedListener(getPostSelectionChangedListener());\r
561             }\r
562         }\r
563     }\r
564 \r
565     @Override\r
566     public String getSecondaryId() {\r
567         return ((IViewSite)multiPageEditor.getSite()).getSecondaryId();\r
568     }\r
569 \r
570 }\r