1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.eclipse.org/org/documents/epl-v10.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.ide.eclipse.adt.internal.editors;
18
19import com.android.ide.eclipse.adt.AdtPlugin;
20
21import org.eclipse.jface.action.IMenuManager;
22import org.eclipse.jface.action.IStatusLineManager;
23import org.eclipse.jface.action.IToolBarManager;
24import org.eclipse.jface.viewers.ISelection;
25import org.eclipse.jface.viewers.ISelectionChangedListener;
26import org.eclipse.jface.viewers.SelectionChangedEvent;
27import org.eclipse.jface.viewers.StructuredSelection;
28import org.eclipse.swt.SWT;
29import org.eclipse.swt.widgets.Composite;
30import org.eclipse.swt.widgets.Control;
31import org.eclipse.ui.IActionBars;
32import org.eclipse.ui.PartInitException;
33import org.eclipse.ui.part.IPageBookViewPage;
34import org.eclipse.ui.part.Page;
35import org.eclipse.ui.part.PageBook;
36import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
37
38import java.util.ArrayList;
39import java.util.List;
40
41/**
42 * Outline used for XML editors that have multiple pages with separate outlines:
43 * switches between them
44 * <p>
45 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=1917
46 * <p>
47 * Modeled after .org.eclipse.pde.internal.ui.editor.PDEMultiPageContentOutline
48 */
49public class XmlEditorMultiOutline extends Page implements IContentOutlinePage,
50        ISelectionChangedListener {
51    private boolean mDisposed;
52    private PageBook mPageBook;
53    private IContentOutlinePage mCurrentPage;
54    private IActionBars mActionBars;
55    private IContentOutlinePage mEmptyPage;
56    private List<ISelectionChangedListener> mListeners;
57    private ISelection mSelection;
58
59    public XmlEditorMultiOutline() {
60    }
61
62    @Override
63    public Control getControl() {
64        return mPageBook;
65    }
66
67    @Override
68    public void createControl(Composite parent) {
69        mPageBook = new PageBook(parent, SWT.NONE);
70    }
71
72    @Override
73    public void dispose() {
74        mDisposed = true;
75        mListeners = null;
76        if (mPageBook != null && !mPageBook.isDisposed()) {
77            mPageBook.dispose();
78            mPageBook = null;
79        }
80        if (mEmptyPage != null) {
81            mEmptyPage.dispose();
82            mEmptyPage = null;
83        }
84    }
85
86    public boolean isDisposed() {
87        return mDisposed;
88    }
89
90    @Override
91    public void makeContributions(IMenuManager menuManager, IToolBarManager toolBarManager,
92            IStatusLineManager statusLineManager) {
93    }
94
95    @Override
96    public void setActionBars(IActionBars actionBars) {
97        mActionBars = actionBars;
98        if (mCurrentPage != null) {
99            setPageActive(mCurrentPage);
100        }
101    }
102
103    @Override
104    public void setFocus() {
105        if (mCurrentPage != null) {
106            mCurrentPage.setFocus();
107        }
108    }
109
110    @Override
111    public void addSelectionChangedListener(ISelectionChangedListener listener) {
112        if (mListeners == null) {
113            mListeners = new ArrayList<ISelectionChangedListener>(2);
114        }
115        mListeners.add(listener);
116    }
117
118    @Override
119    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
120        mListeners.remove(listener);
121    }
122
123    @Override
124    public ISelection getSelection() {
125        return mSelection;
126    }
127
128    @Override
129    public void selectionChanged(SelectionChangedEvent event) {
130        setSelection(event.getSelection());
131    }
132
133    public void setPageActive(IContentOutlinePage page) {
134        if (page == null) {
135            if (mEmptyPage == null) {
136                mEmptyPage = new EmptyPage();
137            }
138            page = mEmptyPage;
139        }
140        if (mCurrentPage != null) {
141            mCurrentPage.removeSelectionChangedListener(this);
142        }
143        page.addSelectionChangedListener(this);
144        mCurrentPage = page;
145        // Still initializing?
146        if (mPageBook == null) {
147            return;
148        }
149        Control control = page.getControl();
150        if (control == null || control.isDisposed()) {
151            if (page instanceof IPageBookViewPage) {
152                try {
153                    ((IPageBookViewPage) page).init(getSite());
154                } catch (PartInitException e) {
155                    AdtPlugin.log(e, null);
156                }
157            }
158            page.createControl(mPageBook);
159            page.setActionBars(mActionBars);
160            control = page.getControl();
161        }
162        mPageBook.showPage(control);
163    }
164
165    @Override
166    public void setSelection(ISelection selection) {
167        mSelection = selection;
168        if (mListeners != null) {
169            SelectionChangedEvent e = new SelectionChangedEvent(this, selection);
170            for (int i = 0; i < mListeners.size(); i++) {
171                mListeners.get(i).selectionChanged(e);
172            }
173        }
174    }
175
176    private static class EmptyPage implements IContentOutlinePage {
177        private Composite mControl;
178
179        private EmptyPage() {
180        }
181
182        @Override
183        public void createControl(Composite parent) {
184            mControl = new Composite(parent, SWT.NULL);
185        }
186
187        @Override
188        public void dispose() {
189        }
190
191        @Override
192        public Control getControl() {
193            return mControl;
194        }
195
196        @Override
197        public void setActionBars(IActionBars actionBars) {
198        }
199
200        @Override
201        public void setFocus() {
202        }
203
204        @Override
205        public void addSelectionChangedListener(ISelectionChangedListener listener) {
206        }
207
208        @Override
209        public ISelection getSelection() {
210            return StructuredSelection.EMPTY;
211        }
212
213        @Override
214        public void removeSelectionChangedListener(ISelectionChangedListener listener) {
215        }
216
217        @Override
218        public void setSelection(ISelection selection) {
219        }
220    }
221}
222