/*
* Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC
* All rights reserved.
*
* The source code of this document is proprietary work, and is not licensed for
* distribution. For information about licensing, contact Sam Harwell at:
* sam@tunnelvisionlabs.com
*/
package org.antlr.works.editor.antlr4.navigation;
import java.awt.BorderLayout;
import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ActionMap;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.text.AttributeSet;
import javax.swing.text.Document;
import javax.swing.text.StyleConstants;
import org.antlr.netbeans.editor.navigation.AbstractNavigatorPanel;
import org.antlr.netbeans.editor.text.OffsetRegion;
import org.antlr.netbeans.parsing.spi.ParserDataDefinition;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.editor.settings.AttributesUtilities;
import org.netbeans.spi.editor.highlighting.support.OffsetsBag;
import org.openide.cookies.EditorCookie;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.explorer.view.BeanTreeView;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.nodes.Node;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
/**
*
* @author Sam Harwell
*/
@NbBundle.Messages({
"LBL_DisplayName=Parse Tree (Development)",
"HINT_DisplayName=Parse Tree (Development)",
})
public abstract class TreeNavigatorPanel extends AbstractNavigatorPanel<JComponent> {
// -J-Dorg.antlr.works.editor.antlr4.navigation.TreeNavigatorPanel.level=FINE
private static final Logger LOGGER = Logger.getLogger(TreeNavigatorPanel.class.getName());
private static final AttributeSet HIGHLIGHT = AttributesUtilities.createImmutable(StyleConstants.Background, new Color(224, 224, 224));
private static final AttributeSet HIGHLIGHT_PREF = AttributesUtilities.createImmutable(StyleConstants.Underline, new Color(30, 255, 0));
private final ExplorerManager _manager = new ExplorerManager();
protected TreeNavigatorPanel(@NonNull String mimeType, @NonNull ParserDataDefinition<?>... dataDefinitions) {
super(mimeType, dataDefinitions);
_manager.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
setHighlights(getCurrentFile(), _manager);
}
}
});
}
@Override
public String getDisplayName() {
return Bundle.LBL_DisplayName();
}
@Override
public String getDisplayHint() {
return Bundle.HINT_DisplayName();
}
@Override
public void panelActivated(Lookup context) {
super.panelActivated(context);
}
@Override
public void panelDeactivated() {
try {
// clear highlights
_manager.setSelectedNodes(new Node[0]);
} catch (PropertyVetoException ex) {
}
super.panelDeactivated();
}
@Override
public Lookup getLookup() {
JComponent component = getComponent();
if (component instanceof Lookup.Provider) {
return ((Lookup.Provider)component).getLookup();
}
return null;
}
public void setParseTree(ParseTreeNode rootNode) {
_manager.setRootContext(rootNode);
}
protected final ExplorerManager getExplorerManager() {
return _manager;
}
protected abstract FileObject getCurrentFile();
protected static OffsetsBag getBag(Document doc) {
OffsetsBag bag = (OffsetsBag) doc.getProperty(TreeNavigatorPanel.class);
if (bag == null) {
doc.putProperty(TreeNavigatorPanel.class, bag = new OffsetsBag(doc));
}
return bag;
}
protected void setHighlights(FileObject file, ExplorerManager manager) {
if (file == null) {
return;
}
try {
DataObject od = DataObject.find(file);
EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
if (ec == null) {
return;
}
Document doc = ec.getDocument();
if (doc == null) {
return;
}
OffsetsBag bag = new OffsetsBag(doc, true);
for (Node n : manager.getSelectedNodes()) {
if (n instanceof OffsetProvider) {
OffsetProvider p = (OffsetProvider) n;
OffsetRegion span = p.getSpan();
if (span != null) {
bag.addHighlight(span.getStart(), span.getEnd(), HIGHLIGHT);
}
OffsetRegion emphasis = p.getEmphasis();
if (emphasis != null) {
bag.addHighlight(emphasis.getStart(), emphasis.getEnd(), HIGHLIGHT_PREF);
}
}
}
getBag(doc).setHighlights(bag);
} catch (DataObjectNotFoundException ex) {
LOGGER.log(Level.WARNING, ex.getMessage(), ex);
}
}
@Override
protected JComponent createPanelUI() {
return new Panel();
}
protected class Panel extends JPanel implements ExplorerManager.Provider, Lookup.Provider {
private final Lookup _lookup = ExplorerUtils.createLookup(_manager, new ActionMap());
public Panel() {
setLayout(new BorderLayout());
BeanTreeView view = new BeanTreeView();
view.setRootVisible(true);
view.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
add(view, BorderLayout.CENTER);
}
@Override
public ExplorerManager getExplorerManager() {
return _manager;
}
@Override
public Lookup getLookup() {
return _lookup;
}
}
}