Update org.apache.commons:commons-compress to 1.25.0
[egit/eclipse.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / commit / MultiPageEditorContentOutlinePage.java
blob027af0c8959786d23cabf635439ec791ae1f4bf2
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;
14 import java.util.Map;
15 import java.util.concurrent.CopyOnWriteArrayList;
17 import org.eclipse.core.runtime.Adapters;
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.IPageSite;
33 import org.eclipse.ui.part.MessagePage;
34 import org.eclipse.ui.part.MultiPageEditorPart;
35 import org.eclipse.ui.part.Page;
36 import org.eclipse.ui.part.PageBook;
37 import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
38 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
40 /**
41 * A {@link ContentOutlinePage} for {@link MultiPageEditorPart}s. The
42 * {@link org.eclipse.ui.views.contentoutline.ContentOutline ContentOutline}
43 * view only automatically handles outline pages of top-level editors, but not
44 * of nested editors. (It reacts only to part events, not to page change events,
45 * and moreover the MultiPageEditorPart framework does not send events when
46 * pages are added or removed.)
47 * <p>
48 * This class manages content outline pages for nested editors in its own
49 * {@link PageBook}. Nested editors can provide their outline pages as usual by
50 * adapting to {@link IContentOutlinePage}.
51 * </p>
53 public class MultiPageEditorContentOutlinePage extends ContentOutlinePage {
55 private final MultiPageEditorPart editorPart;
57 private final ISelectionChangedListener globalSelectionListener = this::fireSelectionChangedEvent;
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<>();
73 /**
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
77 * editor part.
79 * @param editorPart
80 * the outline page belongs to
82 public MultiPageEditorContentOutlinePage(MultiPageEditorPart editorPart) {
83 super();
84 this.editorPart = editorPart;
87 @Override
88 public void createControl(Composite parent) {
89 book = new PageBook(parent, SWT.NONE);
90 emptyPage = new MessagePage();
91 emptyPage.createControl(book);
92 emptyPage
93 .setMessage(UIText.MultiPageEditorContentOutlinePage_NoOutline);
94 Object activePage = editorPart.getSelectedPage();
95 if (activePage instanceof IEditorPart) {
96 showPage(createOutlinePage((IEditorPart) activePage));
97 } else {
98 currentPage = emptyPage;
99 book.showPage(emptyPage.getControl());
101 pageListener = (event) -> {
102 Object newPage = event.getSelectedPage();
103 if (!(newPage instanceof IEditorPart)) {
104 showPage(emptyPage);
105 return;
107 IPage newOutlinePage = pages.get(newPage);
108 if (newOutlinePage == null) {
109 newOutlinePage = createOutlinePage((IEditorPart) newPage);
111 showPage(newOutlinePage);
113 editorPart.addPageChangedListener(pageListener);
116 @Override
117 public void dispose() {
118 if (pageListener != null) {
119 editorPart.removePageChangedListener(pageListener);
120 pageListener = null;
122 pages.clear();
123 selectionListeners.clear();
124 for (SubActionBars bar : bars.values()) {
125 bar.dispose();
127 bars.clear();
128 if (currentPage instanceof ISelectionProvider) {
129 ((ISelectionProvider) currentPage)
130 .removeSelectionChangedListener(globalSelectionListener);
132 currentPage = null;
133 if (book != null) {
134 book.dispose();
135 book = null;
137 if (emptyPage != null) {
138 emptyPage.dispose();
139 emptyPage = null;
143 @Override
144 public Control getControl() {
145 return book;
148 @Override
149 public void setFocus() {
150 // See org.eclipse.ui.part.PageBookView
151 book.setFocus();
152 currentPage.setFocus();
155 @Override
156 public void addSelectionChangedListener(
157 ISelectionChangedListener listener) {
158 selectionListeners.addIfAbsent(listener);
161 @Override
162 public ISelection getSelection() {
163 if (currentPage instanceof ISelectionProvider) {
164 return ((ISelectionProvider) currentPage).getSelection();
166 return StructuredSelection.EMPTY;
169 @Override
170 public void removeSelectionChangedListener(
171 ISelectionChangedListener listener) {
172 selectionListeners.remove(listener);
175 @Override
176 public void setSelection(ISelection selection) {
177 if (currentPage instanceof ISelectionProvider) {
178 ((ISelectionProvider) currentPage).setSelection(selection);
182 private void showPage(IPage page) {
183 if (page == null) {
184 page = emptyPage;
186 if (currentPage == page) {
187 return;
189 if (currentPage instanceof ISelectionProvider) {
190 ((ISelectionProvider) currentPage)
191 .removeSelectionChangedListener(globalSelectionListener);
193 SubActionBars localBars = bars.get(currentPage);
194 if (localBars != null) {
195 localBars.deactivate();
197 currentPage = page;
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)
216 .getSelection();
217 fireSelectionChangedEvent(new SelectionChangedEvent(
218 (ISelectionProvider) currentPage, selection));
219 } else {
220 fireSelectionChangedEvent(
221 new SelectionChangedEvent(this, StructuredSelection.EMPTY));
225 private IPage createOutlinePage(IEditorPart editor) {
226 IContentOutlinePage outlinePage = Adapters.adapt(editor,
227 IContentOutlinePage.class);
228 if (!(outlinePage instanceof Page)) {
229 pages.put(editor, emptyPage);
230 return emptyPage;
232 pages.put(editor, outlinePage);
233 // ContentOutlinePage insists on setting itself as selection provider.
234 // For pages nested inside a MultiPageEditorContentOutlinePage this is
235 // wrong. Save and restore the selection provider.
236 IPageSite pageSite = getSite();
237 ISelectionProvider provider = pageSite.getSelectionProvider();
238 ((Page) outlinePage).init(getSite());
239 pageSite.setSelectionProvider(provider);
240 SubActionBars pageBars = new SubActionBars(getSite().getActionBars());
241 bars.put(outlinePage, pageBars);
242 return outlinePage;
245 private void fireSelectionChangedEvent(SelectionChangedEvent event) {
246 for (ISelectionChangedListener listener : selectionListeners) {
247 SafeRunnable.run(new SafeRunnable() {
249 @Override
250 public void run() {
251 listener.selectionChanged(event);