Lines 37-42
Link Here
|
37 |
import org.eclipse.ui.IEditorSite; |
37 |
import org.eclipse.ui.IEditorSite; |
38 |
import org.eclipse.ui.IKeyBindingService; |
38 |
import org.eclipse.ui.IKeyBindingService; |
39 |
import org.eclipse.ui.INestableKeyBindingService; |
39 |
import org.eclipse.ui.INestableKeyBindingService; |
|
|
40 |
import org.eclipse.ui.IPartService; |
40 |
import org.eclipse.ui.IPropertyListener; |
41 |
import org.eclipse.ui.IPropertyListener; |
41 |
import org.eclipse.ui.IWorkbenchPart; |
42 |
import org.eclipse.ui.IWorkbenchPart; |
42 |
import org.eclipse.ui.IWorkbenchPartSite; |
43 |
import org.eclipse.ui.IWorkbenchPartSite; |
Lines 45-51
Link Here
|
45 |
import org.eclipse.ui.internal.misc.Policy; |
46 |
import org.eclipse.ui.internal.misc.Policy; |
46 |
import org.eclipse.ui.internal.services.INestable; |
47 |
import org.eclipse.ui.internal.services.INestable; |
47 |
import org.eclipse.ui.internal.util.Util; |
48 |
import org.eclipse.ui.internal.util.Util; |
|
|
49 |
import org.eclipse.ui.services.IDisposable; |
48 |
import org.eclipse.ui.services.IServiceLocator; |
50 |
import org.eclipse.ui.services.IServiceLocator; |
|
|
51 |
import org.eclipse.ui.services.IServiceLocatorCreator; |
49 |
|
52 |
|
50 |
/** |
53 |
/** |
51 |
* A multi-page editor is an editor with multiple pages, each of which may |
54 |
* A multi-page editor is an editor with multiple pages, each of which may |
Lines 73-87
Link Here
|
73 |
* @see org.eclipse.ui.part.MultiPageEditorActionBarContributor |
76 |
* @see org.eclipse.ui.part.MultiPageEditorActionBarContributor |
74 |
*/ |
77 |
*/ |
75 |
public abstract class MultiPageEditorPart extends EditorPart { |
78 |
public abstract class MultiPageEditorPart extends EditorPart { |
76 |
|
79 |
|
77 |
/** |
80 |
/** |
|
|
81 |
* Subclasses that override {@link #createPageContainer(Composite)} can use |
82 |
* this constant to get a site for the container that can be active while |
83 |
* the current page is deactivated. |
78 |
* |
84 |
* |
|
|
85 |
* @since 3.4 |
86 |
* @see #activateSite() |
87 |
* @see #deactivateSite(boolean, boolean) |
88 |
* @see #getPageSite(int) |
89 |
*/ |
90 |
protected static final int PAGE_CONTAINER_SITE = 65535; |
91 |
|
92 |
/** |
93 |
* Private tracing output. |
79 |
*/ |
94 |
*/ |
80 |
private static final String TRACING_COMPONENT = "MPE"; //$NON-NLS-1$ |
95 |
private static final String TRACING_COMPONENT = "MPE"; //$NON-NLS-1$ |
81 |
|
96 |
|
82 |
/** |
97 |
/** |
83 |
* The active service locator. This value may be <code>null</code> if |
98 |
* The active service locator. This value may be <code>null</code> if |
84 |
* there is no selected page, or if the selected page is a control. |
99 |
* there is no selected page, or if the selected page is a control with |
|
|
100 |
* no site. |
85 |
*/ |
101 |
*/ |
86 |
private INestable activeServiceLocator; |
102 |
private INestable activeServiceLocator; |
87 |
|
103 |
|
Lines 97-102
Link Here
|
97 |
* point. |
113 |
* point. |
98 |
*/ |
114 |
*/ |
99 |
private ArrayList nestedEditors = new ArrayList(3); |
115 |
private ArrayList nestedEditors = new ArrayList(3); |
|
|
116 |
|
117 |
private List pageSites = new ArrayList(3); |
118 |
|
119 |
private IServiceLocator pageContainerSite; |
100 |
|
120 |
|
101 |
/** |
121 |
/** |
102 |
* Creates an empty multi-page editor with no pages. |
122 |
* Creates an empty multi-page editor with no pages. |
Lines 341-346
Link Here
|
341 |
disposePart(editor); |
361 |
disposePart(editor); |
342 |
} |
362 |
} |
343 |
nestedEditors.clear(); |
363 |
nestedEditors.clear(); |
|
|
364 |
if (pageContainerSite instanceof IDisposable) { |
365 |
((IDisposable) pageContainerSite).dispose(); |
366 |
pageContainerSite = null; |
367 |
} |
368 |
for (int i = 0; i < pageSites.size(); i++) { |
369 |
IServiceLocator sl = (IServiceLocator) pageSites.get(i); |
370 |
if (sl instanceof IDisposable) { |
371 |
((IDisposable) sl).dispose(); |
372 |
} |
373 |
} |
374 |
pageSites.clear(); |
344 |
} |
375 |
} |
345 |
|
376 |
|
346 |
/** |
377 |
/** |
Lines 434-439
Link Here
|
434 |
} |
465 |
} |
435 |
return null; |
466 |
return null; |
436 |
} |
467 |
} |
|
|
468 |
|
469 |
/** |
470 |
* Returns the service locator for the given page index. This method can be |
471 |
* used to create service locators for pages that are just controls. The |
472 |
* page index must be valid. |
473 |
* <p> |
474 |
* This will return the editor site service locator for an editor, and |
475 |
* create one for a page that is just a control. |
476 |
* </p> |
477 |
* |
478 |
* @param pageIndex |
479 |
* the index of the page |
480 |
* @return the editor for the specified page, or <code>null</code> if the |
481 |
* specified page was not created with |
482 |
* <code>addPage(IEditorPart,IEditorInput)</code> |
483 |
* @since 3.4 |
484 |
*/ |
485 |
protected final IServiceLocator getPageSite(int pageIndex) { |
486 |
if (pageIndex == PAGE_CONTAINER_SITE) { |
487 |
return getPageContainerSite(); |
488 |
} |
489 |
|
490 |
Item item = getItem(pageIndex); |
491 |
if (item != null) { |
492 |
Object data = item.getData(); |
493 |
if (data instanceof IEditorPart) { |
494 |
return ((IEditorPart) data).getSite(); |
495 |
} else if (data instanceof IServiceLocator) { |
496 |
return (IServiceLocator) data; |
497 |
} else if (data == null) { |
498 |
IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite() |
499 |
.getService(IServiceLocatorCreator.class); |
500 |
IServiceLocator sl = slc.createServiceLocator(getSite(), null); |
501 |
item.setData(sl); |
502 |
pageSites.add(sl); |
503 |
return sl; |
504 |
} |
505 |
} |
506 |
return null; |
507 |
} |
508 |
|
509 |
/** |
510 |
* @return A site that can be used with a header. |
511 |
* @since 3.4 |
512 |
* @see #createPageContainer(Composite) |
513 |
* @see #PAGE_CONTAINER_SITE |
514 |
* @see #getPageSite(int) |
515 |
*/ |
516 |
private IServiceLocator getPageContainerSite() { |
517 |
if (pageContainerSite == null) { |
518 |
IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite() |
519 |
.getService(IServiceLocatorCreator.class); |
520 |
pageContainerSite = slc.createServiceLocator(getSite(), null); |
521 |
} |
522 |
return pageContainerSite; |
523 |
} |
437 |
|
524 |
|
438 |
/** |
525 |
/** |
439 |
* Returns the tab item for the given page index (page index is 0-based). |
526 |
* Returns the tab item for the given page index (page index is 0-based). |
Lines 581-594
Link Here
|
581 |
* the index of the activated page |
668 |
* the index of the activated page |
582 |
*/ |
669 |
*/ |
583 |
protected void pageChange(int newPageIndex) { |
670 |
protected void pageChange(int newPageIndex) { |
584 |
// Deactivate the nested services from the last active service locator. |
671 |
deactivateSite(false, false); |
585 |
if (activeServiceLocator != null) { |
672 |
|
586 |
activeServiceLocator.deactivate(); |
673 |
IPartService partService = (IPartService) getSite().getService( |
587 |
activeServiceLocator = null; |
674 |
IPartService.class); |
|
|
675 |
if (partService.getActivePart() == this) { |
676 |
setFocus(newPageIndex); |
588 |
} |
677 |
} |
589 |
|
678 |
|
590 |
setFocus(); |
|
|
591 |
IEditorPart activeEditor = getEditor(newPageIndex); |
679 |
IEditorPart activeEditor = getEditor(newPageIndex); |
|
|
680 |
|
592 |
IEditorActionBarContributor contributor = getEditorSite() |
681 |
IEditorActionBarContributor contributor = getEditorSite() |
593 |
.getActionBarContributor(); |
682 |
.getActionBarContributor(); |
594 |
if (contributor != null |
683 |
if (contributor != null |
Lines 596-610
Link Here
|
596 |
((MultiPageEditorActionBarContributor) contributor) |
685 |
((MultiPageEditorActionBarContributor) contributor) |
597 |
.setActivePage(activeEditor); |
686 |
.setActivePage(activeEditor); |
598 |
} |
687 |
} |
599 |
if (activeEditor != null) { |
|
|
600 |
|
601 |
// Activate the services for the new service locator. |
602 |
final IServiceLocator serviceLocator = activeEditor.getEditorSite(); |
603 |
if (serviceLocator instanceof INestable) { |
604 |
activeServiceLocator = (INestable) serviceLocator; |
605 |
activeServiceLocator.activate(); |
606 |
} |
607 |
|
688 |
|
|
|
689 |
if (activeEditor != null) { |
608 |
ISelectionProvider selectionProvider = activeEditor.getSite() |
690 |
ISelectionProvider selectionProvider = activeEditor.getSite() |
609 |
.getSelectionProvider(); |
691 |
.getSelectionProvider(); |
610 |
if (selectionProvider != null) { |
692 |
if (selectionProvider != null) { |
Lines 627-632
Link Here
|
627 |
} |
709 |
} |
628 |
} |
710 |
} |
629 |
} |
711 |
} |
|
|
712 |
|
713 |
activateSite(); |
714 |
} |
715 |
|
716 |
/** |
717 |
* This method can be used by implementors of |
718 |
* {@link MultiPageEditorPart#createPageContainer(Composite)} to deactivate |
719 |
* the active inner editor services while their header has focus. A |
720 |
* deactivateSite() must have a matching call to activateSite() when |
721 |
* appropriate. |
722 |
* <p> |
723 |
* An new inner editor will have its site activated on a |
724 |
* {@link MultiPageEditorPart#pageChange(int)}. |
725 |
* </p> |
726 |
* <p> |
727 |
* <b>Note:</b> This API is evolving in 3.4 and this might not be its final |
728 |
* form. |
729 |
* </p> |
730 |
* |
731 |
* @param immediate |
732 |
* immediately deactivate the legacy keybinding service |
733 |
* @param containerSiteActive |
734 |
* Leave the page container site active. |
735 |
* @since 3.4 |
736 |
* @see #activateSite() |
737 |
* @see #createPageContainer(Composite) |
738 |
* @see #getPageSite(int) |
739 |
* @see #PAGE_CONTAINER_SITE |
740 |
*/ |
741 |
protected final void deactivateSite(boolean immediate, |
742 |
boolean containerSiteActive) { |
743 |
// Deactivate the nested services from the last active service locator. |
744 |
if (activeServiceLocator != null) { |
745 |
activeServiceLocator.deactivate(); |
746 |
activeServiceLocator = null; |
747 |
} |
748 |
|
749 |
final int pageIndex = getActivePage(); |
750 |
final IKeyBindingService service = getSite().getKeyBindingService(); |
751 |
if (pageIndex < 0 || pageIndex >= getPageCount() || immediate) { |
752 |
// There is no selected page, so deactivate the active service. |
753 |
if (service instanceof INestableKeyBindingService) { |
754 |
final INestableKeyBindingService nestableService = (INestableKeyBindingService) service; |
755 |
nestableService.activateKeyBindingService(null); |
756 |
} else { |
757 |
WorkbenchPlugin |
758 |
.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$ |
759 |
} |
760 |
} |
761 |
|
762 |
if (containerSiteActive) { |
763 |
IServiceLocator containerSite = getPageContainerSite(); |
764 |
if (containerSite instanceof INestable) { |
765 |
activeServiceLocator = (INestable) containerSite; |
766 |
activeServiceLocator.activate(); |
767 |
} |
768 |
} |
769 |
} |
770 |
|
771 |
/** |
772 |
* This method can be used by implementors of |
773 |
* {@link #createPageContainer(Composite)} to activate the active inner |
774 |
* editor services when their header loses focus. |
775 |
* <p> |
776 |
* An new inner editor will have its site activated on a |
777 |
* {@link #pageChange(int)}. |
778 |
* </p> |
779 |
* <p> |
780 |
* <b>Note:</b> This API is evolving in 3.4 and this might not be its final |
781 |
* form. |
782 |
* </p> |
783 |
* |
784 |
* @since 3.4 |
785 |
* @see #deactivateSite(boolean,boolean) |
786 |
* @see #createPageContainer(Composite) |
787 |
* @see #getPageSite(int) |
788 |
*/ |
789 |
protected final void activateSite() { |
790 |
if (activeServiceLocator != null) { |
791 |
activeServiceLocator.deactivate(); |
792 |
activeServiceLocator = null; |
793 |
} |
794 |
|
795 |
final IKeyBindingService service = getSite().getKeyBindingService(); |
796 |
final int pageIndex = getActivePage(); |
797 |
final IEditorPart editor = getEditor(pageIndex); |
798 |
|
799 |
if (editor != null) { |
800 |
// active the service for this inner editor |
801 |
if (service instanceof INestableKeyBindingService) { |
802 |
final INestableKeyBindingService nestableService = (INestableKeyBindingService) service; |
803 |
nestableService.activateKeyBindingService(editor |
804 |
.getEditorSite()); |
805 |
|
806 |
} else { |
807 |
WorkbenchPlugin |
808 |
.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$ |
809 |
} |
810 |
// Activate the services for the new service locator. |
811 |
final IServiceLocator serviceLocator = editor.getEditorSite(); |
812 |
if (serviceLocator instanceof INestable) { |
813 |
activeServiceLocator = (INestable) serviceLocator; |
814 |
activeServiceLocator.activate(); |
815 |
} |
816 |
|
817 |
} else { |
818 |
Item item = getItem(pageIndex); |
819 |
|
820 |
// There is no selected editor, so deactivate the active service. |
821 |
if (service instanceof INestableKeyBindingService) { |
822 |
final INestableKeyBindingService nestableService = (INestableKeyBindingService) service; |
823 |
nestableService.activateKeyBindingService(null); |
824 |
} else { |
825 |
WorkbenchPlugin |
826 |
.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$ |
827 |
} |
828 |
|
829 |
if (item.getData() instanceof INestable) { |
830 |
activeServiceLocator = (INestable) item.getData(); |
831 |
activeServiceLocator.activate(); |
832 |
} |
833 |
} |
630 |
} |
834 |
} |
631 |
|
835 |
|
632 |
/** |
836 |
/** |
Lines 668-673
Link Here
|
668 |
|
872 |
|
669 |
// get control for the item if it's not an editor |
873 |
// get control for the item if it's not an editor |
670 |
CTabItem item = getItem(pageIndex); |
874 |
CTabItem item = getItem(pageIndex); |
|
|
875 |
IServiceLocator pageLocator = null; |
876 |
if (item.getData() instanceof IServiceLocator) { |
877 |
pageLocator = (IServiceLocator) item.getData(); |
878 |
} |
671 |
Control pageControl = item.getControl(); |
879 |
Control pageControl = item.getControl(); |
672 |
|
880 |
|
673 |
// dispose item before disposing editor, in case there's an exception |
881 |
// dispose item before disposing editor, in case there's an exception |
Lines 683-688
Link Here
|
683 |
nestedEditors.remove(editor); |
891 |
nestedEditors.remove(editor); |
684 |
disposePart(editor); |
892 |
disposePart(editor); |
685 |
} |
893 |
} |
|
|
894 |
if (pageLocator != null) { |
895 |
pageSites.remove(pageLocator); |
896 |
if (pageLocator instanceof IDisposable) { |
897 |
((IDisposable) pageLocator).dispose(); |
898 |
} |
899 |
} |
686 |
} |
900 |
} |
687 |
|
901 |
|
688 |
/** |
902 |
/** |
Lines 731-776
Link Here
|
731 |
* the index of the page |
945 |
* the index of the page |
732 |
*/ |
946 |
*/ |
733 |
private void setFocus(int pageIndex) { |
947 |
private void setFocus(int pageIndex) { |
734 |
final IKeyBindingService service = getSite().getKeyBindingService(); |
|
|
735 |
if (pageIndex < 0 || pageIndex >= getPageCount()) { |
736 |
// There is no selected page, so deactivate the active service. |
737 |
if (service instanceof INestableKeyBindingService) { |
738 |
final INestableKeyBindingService nestableService = (INestableKeyBindingService) service; |
739 |
nestableService.activateKeyBindingService(null); |
740 |
} else { |
741 |
WorkbenchPlugin |
742 |
.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$ |
743 |
} |
744 |
return; |
745 |
} |
746 |
|
747 |
final IEditorPart editor = getEditor(pageIndex); |
948 |
final IEditorPart editor = getEditor(pageIndex); |
748 |
if (editor != null) { |
949 |
if (editor != null) { |
749 |
editor.setFocus(); |
950 |
editor.setFocus(); |
750 |
// There is no selected page, so deactivate the active service. |
|
|
751 |
if (service instanceof INestableKeyBindingService) { |
752 |
final INestableKeyBindingService nestableService = (INestableKeyBindingService) service; |
753 |
if (editor != null) { |
754 |
nestableService.activateKeyBindingService(editor |
755 |
.getEditorSite()); |
756 |
} else { |
757 |
nestableService.activateKeyBindingService(null); |
758 |
} |
759 |
} else { |
760 |
WorkbenchPlugin |
761 |
.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$ |
762 |
} |
763 |
|
951 |
|
764 |
} else { |
952 |
} else { |
765 |
// There is no selected editor, so deactivate the active service. |
|
|
766 |
if (service instanceof INestableKeyBindingService) { |
767 |
final INestableKeyBindingService nestableService = (INestableKeyBindingService) service; |
768 |
nestableService.activateKeyBindingService(null); |
769 |
} else { |
770 |
WorkbenchPlugin |
771 |
.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$ |
772 |
} |
773 |
|
774 |
// Give the page's control focus. |
953 |
// Give the page's control focus. |
775 |
final Control control = getControl(pageIndex); |
954 |
final Control control = getControl(pageIndex); |
776 |
if (control != null) { |
955 |
if (control != null) { |