1 /*******************************************************************************
2 * Copyright (C) 2016, Thomas Wolf <thomas.wolf@paranor.ch>
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
10 *******************************************************************************/
11 package org
.eclipse
.egit
.ui
.internal
.commit
;
13 import java
.util
.HashMap
;
15 import java
.util
.concurrent
.CopyOnWriteArrayList
;
17 import org
.eclipse
.egit
.core
.AdapterUtils
;
18 import org
.eclipse
.egit
.ui
.internal
.UIText
;
19 import org
.eclipse
.jface
.dialogs
.IPageChangedListener
;
20 import org
.eclipse
.jface
.util
.SafeRunnable
;
21 import org
.eclipse
.jface
.viewers
.ISelection
;
22 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
23 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
24 import org
.eclipse
.jface
.viewers
.SelectionChangedEvent
;
25 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
26 import org
.eclipse
.swt
.SWT
;
27 import org
.eclipse
.swt
.widgets
.Composite
;
28 import org
.eclipse
.swt
.widgets
.Control
;
29 import org
.eclipse
.ui
.IEditorPart
;
30 import org
.eclipse
.ui
.SubActionBars
;
31 import org
.eclipse
.ui
.part
.IPage
;
32 import org
.eclipse
.ui
.part
.MessagePage
;
33 import org
.eclipse
.ui
.part
.MultiPageEditorPart
;
34 import org
.eclipse
.ui
.part
.Page
;
35 import org
.eclipse
.ui
.part
.PageBook
;
36 import org
.eclipse
.ui
.views
.contentoutline
.ContentOutlinePage
;
37 import org
.eclipse
.ui
.views
.contentoutline
.IContentOutlinePage
;
40 * A {@link ContentOutlinePage} for {@link MultiPageEditorPart}s. The
41 * {@link org.eclipse.ui.views.contentoutline.ContentOutline ContentOutline}
42 * view only automatically handles outline pages of top-level editors, but not
43 * of nested editors. (It reacts only to part events, not to page change events,
44 * and moreover the MultiPageEditorPart framework does not send events when
45 * pages are added or removed.)
47 * This class manages content outline pages for nested editors in its own
48 * {@link PageBook}. Nested editors can provide their outline pages as usual by
49 * adapting to {@link IContentOutlinePage}.
52 public class MultiPageEditorContentOutlinePage
extends ContentOutlinePage
{
54 private final MultiPageEditorPart editorPart
;
56 private final ISelectionChangedListener globalSelectionListener
= //
57 event
-> fireSelectionChangedEvent(event
);
59 private final CopyOnWriteArrayList
<ISelectionChangedListener
> selectionListeners
= new CopyOnWriteArrayList
<>();
61 private PageBook book
;
63 private MessagePage emptyPage
;
65 private IPage currentPage
;
67 private IPageChangedListener pageListener
;
69 private final Map
<IEditorPart
, IPage
> pages
= new HashMap
<>();
71 private final Map
<IPage
, SubActionBars
> bars
= new HashMap
<>();
74 * Creates a new {@link MultiPageEditorContentOutlinePage} for the given
75 * top-level editor part. It will track page changes and create and manage
76 * outline pages for any nested {@link IEditorPart}s of that top-level
80 * the outline page belongs to
82 public MultiPageEditorContentOutlinePage(MultiPageEditorPart editorPart
) {
84 this.editorPart
= editorPart
;
88 public void createControl(Composite parent
) {
89 book
= new PageBook(parent
, SWT
.NONE
);
90 emptyPage
= new MessagePage();
91 emptyPage
.createControl(book
);
93 .setMessage(UIText
.MultiPageEditorContentOutlinePage_NoOutline
);
94 Object activePage
= editorPart
.getSelectedPage();
95 if (activePage
instanceof IEditorPart
) {
96 showPage(createOutlinePage((IEditorPart
) activePage
));
98 currentPage
= emptyPage
;
99 book
.showPage(emptyPage
.getControl());
101 pageListener
= (event
) -> {
102 Object newPage
= event
.getSelectedPage();
103 if (!(newPage
instanceof IEditorPart
)) {
107 IPage newOutlinePage
= pages
.get(newPage
);
108 if (newOutlinePage
== null) {
109 newOutlinePage
= createOutlinePage((IEditorPart
) newPage
);
111 showPage(newOutlinePage
);
113 editorPart
.addPageChangedListener(pageListener
);
117 public void dispose() {
118 if (pageListener
!= null) {
119 editorPart
.removePageChangedListener(pageListener
);
123 selectionListeners
.clear();
124 for (SubActionBars bar
: bars
.values()) {
128 if (currentPage
instanceof ISelectionProvider
) {
129 ((ISelectionProvider
) currentPage
)
130 .removeSelectionChangedListener(globalSelectionListener
);
137 if (emptyPage
!= null) {
144 public Control
getControl() {
149 public void setFocus() {
150 // See org.eclipse.ui.part.PageBookView
152 currentPage
.setFocus();
156 public void addSelectionChangedListener(
157 ISelectionChangedListener listener
) {
158 selectionListeners
.addIfAbsent(listener
);
162 public ISelection
getSelection() {
163 if (currentPage
instanceof ISelectionProvider
) {
164 return ((ISelectionProvider
) currentPage
).getSelection();
166 return StructuredSelection
.EMPTY
;
170 public void removeSelectionChangedListener(
171 ISelectionChangedListener listener
) {
172 selectionListeners
.remove(listener
);
176 public void setSelection(ISelection selection
) {
177 if (currentPage
instanceof ISelectionProvider
) {
178 ((ISelectionProvider
) currentPage
).setSelection(selection
);
182 private void showPage(IPage page
) {
186 if (currentPage
== page
) {
189 if (currentPage
instanceof ISelectionProvider
) {
190 ((ISelectionProvider
) currentPage
)
191 .removeSelectionChangedListener(globalSelectionListener
);
193 SubActionBars localBars
= bars
.get(currentPage
);
194 if (localBars
!= null) {
195 localBars
.deactivate();
198 if (currentPage
instanceof ISelectionProvider
) {
199 ((ISelectionProvider
) currentPage
)
200 .addSelectionChangedListener(globalSelectionListener
);
202 localBars
= bars
.get(currentPage
);
203 Control control
= page
.getControl();
204 if (control
== null || control
.isDisposed()) {
205 page
.createControl(book
);
206 page
.setActionBars(localBars
);
207 control
= page
.getControl();
209 if (localBars
!= null) {
210 localBars
.activate();
212 getSite().getActionBars().updateActionBars();
213 book
.showPage(control
);
214 if (currentPage
instanceof ISelectionProvider
) {
215 ISelection selection
= ((ISelectionProvider
) currentPage
)
217 fireSelectionChangedEvent(new SelectionChangedEvent(
218 (ISelectionProvider
) currentPage
, selection
));
220 fireSelectionChangedEvent(
221 new SelectionChangedEvent(this, StructuredSelection
.EMPTY
));
225 private IPage
createOutlinePage(IEditorPart editor
) {
226 IContentOutlinePage outlinePage
= AdapterUtils
.adapt(editor
,
227 IContentOutlinePage
.class);
228 if (outlinePage
== null) {
229 pages
.put(editor
, emptyPage
);
232 pages
.put(editor
, outlinePage
);
233 if (outlinePage
instanceof NestedContentOutlinePage
) {
234 ((Page
) outlinePage
).init(getSite());
236 SubActionBars pageBars
= new SubActionBars(getSite().getActionBars());
237 bars
.put(outlinePage
, pageBars
);
241 private void fireSelectionChangedEvent(SelectionChangedEvent event
) {
242 for (ISelectionChangedListener listener
: selectionListeners
) {
243 SafeRunnable
.run(new SafeRunnable() {
247 listener
.selectionChanged(event
);