/*******************************************************************************
* Copyright (c) 2008 Scott Stanchfield, based on ANTLR-Eclipse plugin
* by Torsten Juergeleit.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors
* Torsten Juergeleit - original ANTLR Eclipse plugin
* Scott Stanchfield - modifications for ANTXR
*******************************************************************************/
package com.javadude.antxr.eclipse.ui.editor.outline;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
import com.javadude.antxr.eclipse.core.parser.ISegment;
import com.javadude.antxr.eclipse.ui.actions.CollapseAllAction;
import com.javadude.antxr.eclipse.ui.actions.LexicalSortingAction;
import com.javadude.antxr.eclipse.ui.editor.AntxrEditor;
/**
* A content outline page which represents the content of an ANTXR grammar file.
*/
public class AntxrOutlinePage extends ContentOutlinePage {
private AntxrEditor fEditor;
private Object fInput;
private String fSelectedSegmentID;
private AntxrOutlineLabelProvider fLabelProvider;
private boolean fIsDisposed;
/**
* Create the outline page
* @param anEditor the editor
*/
public AntxrOutlinePage(AntxrEditor anEditor) {
fEditor = anEditor;
fIsDisposed = true;
}
/** {@inheritDoc} */
public void createControl(Composite aParent) {
super.createControl(aParent);
fLabelProvider = new AntxrOutlineLabelProvider();
// Init tree viewer
TreeViewer viewer = getTreeViewer();
viewer.setContentProvider(new AntxrOutlineContentProvider(fEditor));
viewer.setLabelProvider(fLabelProvider);
viewer.addSelectionChangedListener(this);
if (fInput != null) {
viewer.setInput(fInput);
}
fIsDisposed = false;
// Add collapse all button to viewer's toolbar
IToolBarManager mgr = getSite().getActionBars().getToolBarManager();
mgr.add(new CollapseAllAction(viewer));
mgr.add(new LexicalSortingAction(viewer));
// Refresh outline according to initial cursor position
update();
}
/** {@inheritDoc} */
public void selectionChanged(SelectionChangedEvent anEvent) {
super.selectionChanged(anEvent);
ISelection selection = anEvent.getSelection();
if (!selection.isEmpty()) {
ISegment segment = (ISegment)
((IStructuredSelection)selection).getFirstElement();
if (fSelectedSegmentID == null || isDifferentSegment(segment)) {
fEditor.highlightSegment(segment, true);
fSelectedSegmentID = segment.getUniqueID();
} else {
fEditor.revealSegment(segment);
}
}
}
/**
* Select part of the grammar
* @param aLine the line to select
* @param aForceSelect should we force the selection?
*/
public void selectSegment(int aLine, boolean aForceSelect) {
if (aLine > 0) {
TreeViewer viewer = getTreeViewer();
ISegment segment = fEditor.getSegment(aLine);
viewer.removeSelectionChangedListener(this);
if (segment == null) {
if (fSelectedSegmentID != null) {
viewer.setSelection(new StructuredSelection());
fEditor.resetHighlightRange();
fSelectedSegmentID = null;
}
} else {
if (aForceSelect || isDifferentSegment(segment)) {
viewer.setSelection(new StructuredSelection(segment));
fEditor.highlightSegment(segment, false);
fSelectedSegmentID = segment.getUniqueID();
}
viewer.reveal(segment);
}
viewer.addSelectionChangedListener(this);
}
}
private boolean isDifferentSegment(ISegment aSegment) {
return (fSelectedSegmentID == null ||
!fSelectedSegmentID.equals(aSegment.getUniqueID()));
}
/**
* @param aInput
*/
public void setInput(Object aInput) {
fInput = aInput;
update();
}
/**
* Updates the outline page.
*/
public void update() {
TreeViewer viewer = getTreeViewer();
if (viewer != null) {
Control control = viewer.getControl();
if (control != null && !control.isDisposed()) {
viewer.removeSelectionChangedListener(this);
control.setRedraw(false);
viewer.setInput(fInput);
// viewer.expandAll();
control.setRedraw(true);
selectSegment(fEditor.getCursorLine(), true);
viewer.addSelectionChangedListener(this);
}
}
}
/** {@inheritDoc} */
public void dispose() {
setInput(null);
if (fLabelProvider != null) {
fLabelProvider.dispose();
fLabelProvider = null;
}
fIsDisposed = true;
super.dispose();
}
/**
* Have we disposed the outline yet?
* @return true if disposed
*/
public boolean isDisposed() {
return fIsDisposed;
}
}