KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > part > MultiPageEditorSite


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.part;
12
13 import java.util.ArrayList JavaDoc;
14
15 import org.eclipse.core.expressions.Expression;
16 import org.eclipse.core.runtime.Assert;
17 import org.eclipse.jface.action.MenuManager;
18 import org.eclipse.jface.viewers.ILabelDecorator;
19 import org.eclipse.jface.viewers.IPostSelectionProvider;
20 import org.eclipse.jface.viewers.ISelectionChangedListener;
21 import org.eclipse.jface.viewers.ISelectionProvider;
22 import org.eclipse.jface.viewers.SelectionChangedEvent;
23 import org.eclipse.swt.widgets.Shell;
24 import org.eclipse.ui.IActionBars;
25 import org.eclipse.ui.IEditorActionBarContributor;
26 import org.eclipse.ui.IEditorPart;
27 import org.eclipse.ui.IEditorSite;
28 import org.eclipse.ui.IKeyBindingService;
29 import org.eclipse.ui.INestableKeyBindingService;
30 import org.eclipse.ui.IWorkbenchPage;
31 import org.eclipse.ui.IWorkbenchPart;
32 import org.eclipse.ui.IWorkbenchWindow;
33 import org.eclipse.ui.commands.ICommandService;
34 import org.eclipse.ui.contexts.IContextService;
35 import org.eclipse.ui.handlers.IHandlerService;
36 import org.eclipse.ui.internal.PartSite;
37 import org.eclipse.ui.internal.PopupMenuExtender;
38 import org.eclipse.ui.internal.WorkbenchPlugin;
39 import org.eclipse.ui.internal.commands.SlaveCommandService;
40 import org.eclipse.ui.internal.contexts.NestableContextService;
41 import org.eclipse.ui.internal.expressions.ActivePartExpression;
42 import org.eclipse.ui.internal.handlers.NestableHandlerService;
43 import org.eclipse.ui.internal.services.INestable;
44 import org.eclipse.ui.internal.services.ServiceLocator;
45 import org.eclipse.ui.services.IServiceLocator;
46 import org.eclipse.ui.services.IServiceScopes;
47
48 /**
49  * Site for a nested editor within a multi-page editor. Selection is handled by
50  * forwarding the event to the multi-page editor's selection listeners; most
51  * other methods are forwarded to the multi-page editor's site.
52  * <p>
53  * The base implementation of <code>MultiPageEditor.createSite</code> creates
54  * an instance of this class. This class may be instantiated or subclassed.
55  * </p>
56  */

57 public class MultiPageEditorSite implements IEditorSite, INestable {
58
59     /**
60      * The nested editor.
61      */

62     private IEditorPart editor;
63
64     /**
65      * The list of popup menu extenders; <code>null</code> if none registered.
66      */

67     private ArrayList JavaDoc menuExtenders;
68
69     /**
70      * The multi-page editor.
71      */

72     private MultiPageEditorPart multiPageEditor;
73
74     /**
75      * The post selection changed listener.
76      */

77     private ISelectionChangedListener postSelectionChangedListener = null;
78
79     /**
80      * The selection change listener, initialized lazily; <code>null</code> if
81      * not yet created.
82      */

83     private ISelectionChangedListener selectionChangedListener = null;
84
85     /**
86      * The selection provider; <code>null</code> if none.
87      *
88      * @see MultiPageEditorSite#setSelectionProvider(ISelectionProvider)
89      */

90     private ISelectionProvider selectionProvider = null;
91
92     /**
93      * The cached copy of the key binding service specific to this multi-page
94      * editor site. This value is <code>null</code> if it is not yet
95      * initialized.
96      */

97     private IKeyBindingService service = null;
98
99     /**
100      * The local service locator for this multi-page editor site. This value is
101      * never <code>null</code>.
102      */

103     private final ServiceLocator serviceLocator;
104
105     /**
106      * Creates a site for the given editor nested within the given multi-page
107      * editor.
108      *
109      * @param multiPageEditor
110      * the multi-page editor
111      * @param editor
112      * the nested editor
113      */

114     public MultiPageEditorSite(MultiPageEditorPart multiPageEditor,
115             IEditorPart editor) {
116         Assert.isNotNull(multiPageEditor);
117         Assert.isNotNull(editor);
118         this.multiPageEditor = multiPageEditor;
119         this.editor = editor;
120
121         final IServiceLocator parentServiceLocator = multiPageEditor.getSite();
122         serviceLocator = new ServiceLocator(parentServiceLocator);
123
124         initializeDefaultServices();
125     }
126
127     /**
128      * Initialize the slave services for this site.
129      */

130     private void initializeDefaultServices() {
131         final Expression defaultExpression = new ActivePartExpression(
132                 multiPageEditor);
133
134         final IHandlerService parentService = (IHandlerService) serviceLocator
135                 .getService(IHandlerService.class);
136         final IHandlerService slave = new NestableHandlerService(parentService,
137                 defaultExpression);
138         serviceLocator.registerService(IHandlerService.class, slave);
139
140         final IContextService parentContext = (IContextService) serviceLocator
141                 .getService(IContextService.class);
142         final IContextService context = new NestableContextService(
143                 parentContext, defaultExpression);
144         serviceLocator.registerService(IContextService.class, context);
145
146         final ICommandService parentCommandService = (ICommandService) serviceLocator
147                 .getService(ICommandService.class);
148         final ICommandService commandService = new SlaveCommandService(
149                 parentCommandService, IServiceScopes.MPESITE_SCOPE,
150                 this);
151         serviceLocator.registerService(ICommandService.class, commandService);
152
153     }
154
155     /**
156      * Notifies the multi page editor service that the component within which it
157      * exists has become active.
158      *
159      * @since 3.2
160      */

161     public final void activate() {
162         serviceLocator.activate();
163     }
164
165     /**
166      * Notifies the multi page editor service that the component within which it
167      * exists has been deactived.
168      *
169      * @since 3.2
170      */

171     public final void deactivate() {
172         serviceLocator.deactivate();
173     }
174
175     /**
176      * Dispose the contributions.
177      */

178     public void dispose() {
179         if (menuExtenders != null) {
180             for (int i = 0; i < menuExtenders.size(); i++) {
181                 ((PopupMenuExtender) menuExtenders.get(i)).dispose();
182             }
183             menuExtenders = null;
184         }
185
186         // Remove myself from the list of nested key binding services.
187
if (service != null) {
188             IKeyBindingService parentService = getEditor().getSite()
189                     .getKeyBindingService();
190             if (parentService instanceof INestableKeyBindingService) {
191                 INestableKeyBindingService nestableParent = (INestableKeyBindingService) parentService;
192                 nestableParent.removeKeyBindingService(this);
193             }
194             service = null;
195         }
196
197         if (serviceLocator != null) {
198             serviceLocator.dispose();
199         }
200     }
201
202     /**
203      * The <code>MultiPageEditorSite</code> implementation of this
204      * <code>IEditorSite</code> method returns <code>null</code>, since
205      * nested editors do not have their own action bar contributor.
206      *
207      * @return <code>null</code>
208      */

209     public IEditorActionBarContributor getActionBarContributor() {
210         return null;
211     }
212
213     /**
214      * The <code>MultiPageEditorSite</code> implementation of this
215      * <code>IEditorSite</code> method forwards to the multi-page editor to
216      * return the action bars.
217      *
218      * @return The action bars from the parent multi-page editor.
219      */

220     public IActionBars getActionBars() {
221         return multiPageEditor.getEditorSite().getActionBars();
222     }
223
224     /*
225      * (non-Javadoc)
226      *
227      * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
228      */

229     public Object JavaDoc getAdapter(Class JavaDoc adapter) {
230         return null;
231     }
232
233     /**
234      * The <code>MultiPageEditorSite</code> implementation of this
235      * <code>IWorkbenchPartSite</code> method forwards to the multi-page
236      * editor to return the decorator manager.
237      *
238      * @return The decorator from the workbench window.
239      * @deprecated use IWorkbench.getDecoratorManager()
240      */

241     public ILabelDecorator getDecoratorManager() {
242         return getWorkbenchWindow().getWorkbench().getDecoratorManager()
243                 .getLabelDecorator();
244     }
245
246     /**
247      * Returns the nested editor.
248      *
249      * @return the nested editor
250      */

251     public IEditorPart getEditor() {
252         return editor;
253     }
254
255     /**
256      * The <code>MultiPageEditorSite</code> implementation of this
257      * <code>IWorkbenchPartSite</code> method returns an empty string since
258      * the nested editor is not created from the registry.
259      *
260      * @return An empty string.
261      */

262     public String JavaDoc getId() {
263         return ""; //$NON-NLS-1$
264
}
265
266     /*
267      * (non-Javadoc) Method declared on IEditorSite.
268      */

269     public IKeyBindingService getKeyBindingService() {
270         if (service == null) {
271             service = getMultiPageEditor().getEditorSite()
272                     .getKeyBindingService();
273             if (service instanceof INestableKeyBindingService) {
274                 INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
275                 service = nestableService.getKeyBindingService(this);
276
277             } else {
278                 /*
279                  * This is an internal reference, and should not be copied by
280                  * client code. If you are thinking of copying this, DON'T DO
281                  * IT.
282                  */

283                 WorkbenchPlugin
284                         .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$
285
}
286         }
287         return service;
288     }
289
290     /**
291      * Returns the multi-page editor.
292      *
293      * @return the multi-page editor
294      */

295     public MultiPageEditorPart getMultiPageEditor() {
296         return multiPageEditor;
297     }
298
299     /**
300      * The <code>MultiPageEditorSite</code> implementation of this
301      * <code>IWorkbenchPartSite</code> method forwards to the multi-page
302      * editor to return the workbench page.
303      *
304      * @return The workbench page in which this editor site resides.
305      */

306     public IWorkbenchPage getPage() {
307         return getMultiPageEditor().getSite().getPage();
308     }
309
310     /*
311      * (non-Javadoc)
312      *
313      * @see org.eclipse.ui.IWorkbenchPartSite#getPart()
314      */

315     public IWorkbenchPart getPart() {
316         return editor;
317     }
318
319     /**
320      * The <code>MultiPageEditorSite</code> implementation of this
321      * <code>IWorkbenchPartSite</code> method returns an empty string since
322      * the nested editor is not created from the registry.
323      *
324      * @return An empty string.
325      */

326     public String JavaDoc getPluginId() {
327         return ""; //$NON-NLS-1$
328
}
329
330     /**
331      * Returns the post selection change listener which listens to the nested
332      * editor's selection changes.
333      *
334      * @return the post selection change listener.
335      */

336     private ISelectionChangedListener getPostSelectionChangedListener() {
337         if (postSelectionChangedListener == null) {
338             postSelectionChangedListener = new ISelectionChangedListener() {
339                 public void selectionChanged(SelectionChangedEvent event) {
340                     MultiPageEditorSite.this.handlePostSelectionChanged(event);
341                 }
342             };
343         }
344         return postSelectionChangedListener;
345     }
346
347     /**
348      * The <code>MultiPageEditorSite</code> implementation of this
349      * <code>IWorkbenchPartSite</code> method returns an empty string since
350      * the nested editor is not created from the registry.
351      *
352      * @return An empty string.
353      */

354     public String JavaDoc getRegisteredName() {
355         return ""; //$NON-NLS-1$
356
}
357
358     /**
359      * Returns the selection changed listener which listens to the nested
360      * editor's selection changes, and calls <code>handleSelectionChanged</code>.
361      *
362      * @return the selection changed listener
363      */

364     private ISelectionChangedListener getSelectionChangedListener() {
365         if (selectionChangedListener == null) {
366             selectionChangedListener = new ISelectionChangedListener() {
367                 public void selectionChanged(SelectionChangedEvent event) {
368                     MultiPageEditorSite.this.handleSelectionChanged(event);
369                 }
370             };
371         }
372         return selectionChangedListener;
373     }
374
375     /**
376      * The <code>MultiPageEditorSite</code> implementation of this
377      * <code>IWorkbenchPartSite</code> method returns the selection provider
378      * set by <code>setSelectionProvider</code>.
379      *
380      * @return The current selection provider.
381      */

382     public ISelectionProvider getSelectionProvider() {
383         return selectionProvider;
384     }
385
386     public final Object JavaDoc getService(final Class JavaDoc key) {
387         return serviceLocator.getService(key);
388     }
389
390     /**
391      * The <code>MultiPageEditorSite</code> implementation of this
392      * <code>IWorkbenchPartSite</code> method forwards to the multi-page
393      * editor to return the shell.
394      *
395      * @return The shell in which this editor site resides.
396      */

397     public Shell getShell() {
398         return getMultiPageEditor().getSite().getShell();
399     }
400
401     /**
402      * The <code>MultiPageEditorSite</code> implementation of this
403      * <code>IWorkbenchPartSite</code> method forwards to the multi-page
404      * editor to return the workbench window.
405      *
406      * @return The workbench window in which this editor site resides.
407      */

408     public IWorkbenchWindow getWorkbenchWindow() {
409         return getMultiPageEditor().getSite().getWorkbenchWindow();
410     }
411
412     /**
413      * Handles a post selection changed even from the nexted editor.
414      * <p>
415      * Subclasses may extend or reimplement this method
416      *
417      * @param event the event
418      *
419      * @since 3.2
420      */

421     protected void handlePostSelectionChanged(SelectionChangedEvent event) {
422         ISelectionProvider parentProvider = getMultiPageEditor().getSite()
423                 .getSelectionProvider();
424         if (parentProvider instanceof MultiPageSelectionProvider) {
425             SelectionChangedEvent newEvent = new SelectionChangedEvent(
426                     parentProvider, event.getSelection());
427             MultiPageSelectionProvider prov = (MultiPageSelectionProvider) parentProvider;
428             prov.firePostSelectionChanged(newEvent);
429         }
430     }
431
432     /**
433      * Handles a selection changed event from the nested editor. The default
434      * implementation gets the selection provider from the multi-page editor's
435      * site, and calls <code>fireSelectionChanged</code> on it (only if it is
436      * an instance of <code>MultiPageSelectionProvider</code>), passing a new
437      * event object.
438      * <p>
439      * Subclasses may extend or reimplement this method.
440      * </p>
441      *
442      * @param event
443      * the event
444      */

445     protected void handleSelectionChanged(SelectionChangedEvent event) {
446         ISelectionProvider parentProvider = getMultiPageEditor().getSite()
447                 .getSelectionProvider();
448         if (parentProvider instanceof MultiPageSelectionProvider) {
449             SelectionChangedEvent newEvent = new SelectionChangedEvent(
450                     parentProvider, event.getSelection());
451             MultiPageSelectionProvider prov = (MultiPageSelectionProvider) parentProvider;
452             prov.fireSelectionChanged(newEvent);
453         }
454     }
455
456     public final boolean hasService(final Class JavaDoc key) {
457         return serviceLocator.hasService(key);
458     }
459
460     /**
461      * The <code>MultiPageEditorSite</code> implementation of this
462      * <code>IWorkbenchPartSite</code> method forwards to the multi-page
463      * editor for registration.
464      *
465      * @param menuManager
466      * The menu manager
467      * @param selProvider
468      * The selection provider.
469      */

470     public void registerContextMenu(MenuManager menuManager,
471             ISelectionProvider selProvider) {
472         getMultiPageEditor().getSite().registerContextMenu(menuManager,
473                 selProvider);
474     }
475
476     public final void registerContextMenu(final MenuManager menuManager,
477             final ISelectionProvider selectionProvider,
478             final boolean includeEditorInput) {
479         registerContextMenu(getId(), menuManager, selectionProvider,
480                 includeEditorInput);
481     }
482
483     /**
484      * The <code>MultiPageEditorSite</code> implementation of this
485      * <code>IWorkbenchPartSite</code> method forwards to the multi-page
486      * editor for registration.
487      *
488      * @param menuID
489      * The identifier for the menu.
490      * @param menuMgr
491      * The menu manager
492      * @param selProvider
493      * The selection provider.
494      */

495     public void registerContextMenu(String JavaDoc menuID, MenuManager menuMgr,
496             ISelectionProvider selProvider) {
497         if (menuExtenders == null) {
498             menuExtenders = new ArrayList JavaDoc(1);
499         }
500         PartSite.registerContextMenu(menuID, menuMgr, selProvider, true,
501                 editor, menuExtenders);
502     }
503
504     public final void registerContextMenu(final String JavaDoc menuId,
505             final MenuManager menuManager,
506             final ISelectionProvider selectionProvider,
507             final boolean includeEditorInput) {
508         if (menuExtenders == null) {
509             menuExtenders = new ArrayList JavaDoc(1);
510         }
511         PartSite.registerContextMenu(menuId, menuManager, selectionProvider,
512                 includeEditorInput, editor, menuExtenders);
513     }
514
515     /**
516      * The <code>MultiPageEditorSite</code> implementation of this
517      * <code>IWorkbenchPartSite</code> method remembers the selection
518      * provider, and also hooks a listener on it, which calls
519      * <code>handleSelectionChanged</code> when a selection changed event
520      * occurs.
521      *
522      * @param provider
523      * The selection provider.
524      * @see MultiPageEditorSite#handleSelectionChanged(SelectionChangedEvent)
525      */

526     public void setSelectionProvider(ISelectionProvider provider) {
527         ISelectionProvider oldSelectionProvider = selectionProvider;
528         selectionProvider = provider;
529         if (oldSelectionProvider != null) {
530             oldSelectionProvider
531                     .removeSelectionChangedListener(getSelectionChangedListener());
532             if (oldSelectionProvider instanceof IPostSelectionProvider) {
533                 ((IPostSelectionProvider) oldSelectionProvider)
534                         .removePostSelectionChangedListener(getPostSelectionChangedListener());
535             }
536         }
537         if (selectionProvider != null) {
538             selectionProvider
539                     .addSelectionChangedListener(getSelectionChangedListener());
540             if (selectionProvider instanceof IPostSelectionProvider) {
541                 ((IPostSelectionProvider) selectionProvider)
542                         .addPostSelectionChangedListener(getPostSelectionChangedListener());
543             }
544         }
545     }
546 }
547
Popular Tags