/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.gef.ui.outline;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.part.PageBook;
import org.xmind.gef.tree.ITreeViewer;
import org.xmind.gef.ui.editor.IGraphicalEditor;
import org.xmind.gef.ui.editor.IGraphicalEditorPage;
/**
* @author Brian Sun
*/
public abstract class GraphicalOutlinePage extends Page
implements ISelectionProvider, ISelectionChangedListener,
IPageChangedListener, IPropertyListener {
private List<ISelectionChangedListener> selectionChangedListeners = null;
private IGraphicalEditor editor;
private PageBook pageBook;
private ITreeViewer editorTreeViewer;
private Map<Object, ITreeViewer> pageViewers = new HashMap<Object, ITreeViewer>();
private boolean showCurrentPageViewer = false;
public GraphicalOutlinePage(IGraphicalEditor editor) {
this.editor = editor;
hookEditor(editor);
}
protected void hookEditor(IGraphicalEditor editor) {
editor.addPageChangedListener(this);
editor.addPropertyListener(this);
}
protected void unhookEditor(IGraphicalEditor editor) {
editor.removePropertyListener(this);
editor.removePageChangedListener(this);
}
public void pageChanged(PageChangedEvent event) {
if (pageBook == null || pageBook.isDisposed() || !showCurrentPageViewer)
return;
updatePageBook();
}
protected IGraphicalEditor getParentEditor() {
return editor;
}
public void init(IPageSite pageSite) {
super.init(pageSite);
pageSite.setSelectionProvider(this);
}
public void createControl(Composite parent) {
pageBook = new PageBook(parent, SWT.NONE);
updatePageBook();
}
public boolean isShowCurrentPageViewer() {
return showCurrentPageViewer;
}
public void setShowCurrentPageViewer(boolean showCurrentPageViewer) {
if (showCurrentPageViewer == this.showCurrentPageViewer)
return;
this.showCurrentPageViewer = showCurrentPageViewer;
updatePageBook();
}
protected void updatePageBook() {
if (isShowCurrentPageViewer()) {
showCurrentPageViewer(false);
} else {
showEditorTreeViewer(false);
}
}
protected void refresh() {
if (isShowCurrentPageViewer()) {
showCurrentPageViewer(true);
} else {
showEditorTreeViewer(true);
}
}
protected void showEditorTreeViewer(boolean refresh) {
if (editorTreeViewer == null || editorTreeViewer.getControl() == null
|| editorTreeViewer.getControl().isDisposed()) {
editorTreeViewer = createEditorTreeViewer();
if (editorTreeViewer != null) {
configureEditorTreeViewer(editorTreeViewer);
createEditorTreeViewerControl(editorTreeViewer, pageBook);
if (!refresh) {
editorTreeViewer
.setInput(createEditorTreeViewerInput(editor));
}
}
}
if (editorTreeViewer != null) {
if (refresh) {
Object newInput = createEditorTreeViewerInput(editor);
if (newInput != editorTreeViewer.getInput()) {
editorTreeViewer.setInput(newInput);
}
}
pageBook.showPage(editorTreeViewer.getControl());
}
}
protected void showCurrentPageViewer(boolean refresh) {
IGraphicalEditorPage page = editor.getActivePageInstance();
if (page == null)
return;
Object pageInput = page.getInput();
ITreeViewer pageTreeViewer = pageViewers.get(pageInput);
if (pageTreeViewer == null || pageTreeViewer.getControl() == null
|| pageTreeViewer.getControl().isDisposed()) {
pageTreeViewer = createPageTreeViewer();
if (pageTreeViewer != null) {
configurePageTreeViewer(pageTreeViewer);
createPageTreeViewerControl(pageTreeViewer, pageBook);
if (!refresh) {
pageTreeViewer
.setInput(createPageTreeViewerInput(pageInput));
}
}
}
if (pageTreeViewer != null) {
if (refresh) {
Object newInput = createPageTreeViewerInput(pageInput);
if (newInput != pageTreeViewer.getInput()) {
pageTreeViewer.setInput(newInput);
}
}
pageBook.showPage(pageTreeViewer.getControl());
}
}
protected abstract ITreeViewer createEditorTreeViewer();
protected abstract ITreeViewer createPageTreeViewer();
protected abstract Control createEditorTreeViewerControl(ITreeViewer viewer,
Composite parent);
protected abstract Control createPageTreeViewerControl(ITreeViewer viewer,
Composite parent);
protected abstract Object createEditorTreeViewerInput(
IGraphicalEditor parentEditor);
protected abstract Object createPageTreeViewerInput(Object pageInput);
protected void configureEditorTreeViewer(ITreeViewer viewer) {
configureTreeViewer(viewer);
}
protected void configurePageTreeViewer(ITreeViewer viewer) {
configureTreeViewer(viewer);
}
protected void configureTreeViewer(ITreeViewer viewer) {
viewer.addSelectionChangedListener(this);
}
public Control getControl() {
return pageBook;
}
public void setFocus() {
pageBook.setFocus();
}
public void addSelectionChangedListener(
ISelectionChangedListener listener) {
if (selectionChangedListeners == null)
selectionChangedListeners = new ArrayList<ISelectionChangedListener>();
selectionChangedListeners.add(listener);
}
public ISelection getSelection() {
if (editorTreeViewer == null)
return StructuredSelection.EMPTY;
return editorTreeViewer.getSelection();
}
public void removeSelectionChangedListener(
ISelectionChangedListener listener) {
if (selectionChangedListeners == null)
return;
selectionChangedListeners.remove(listener);
}
public void setSelection(ISelection selection) {
if (editorTreeViewer != null) {
editorTreeViewer.setSelection(selection);
}
}
public void selectionChanged(SelectionChangedEvent event) {
fireSelectionChanged(event.getSelection());
}
/**
* Fires a selection changed event.
*
* @param selection
* the new selection
*/
protected void fireSelectionChanged(ISelection selection) {
if (selectionChangedListeners == null)
return;
// create an event
final SelectionChangedEvent event = new SelectionChangedEvent(this,
selection);
// fire the event
Object[] listeners = selectionChangedListeners.toArray();
for (int i = 0; i < listeners.length; ++i) {
final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
SafeRunner.run(new SafeRunnable() {
public void run() {
l.selectionChanged(event);
}
});
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object,
* int)
*/
public void propertyChanged(Object source, int propId) {
if (propId == IEditorPart.PROP_INPUT) {
editorInputChanged();
}
}
/**
*
*/
protected void editorInputChanged() {
refresh();
}
public void dispose() {
unhookEditor(editor);
super.dispose();
}
}