/* * Licensed to "Neo Technology," Network Engine for Objects in Lund AB * (http://neotechnology.com) under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. Neo Technology licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License * at (http://www.apache.org/licenses/LICENSE-2.0). Unless required by * applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS * OF ANY KIND, either express or implied. See the License for the specific * language governing permissions and limitations under the License. */ package org.neo4j.neoclipse.view; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; import org.eclipse.draw2d.IFigure; import org.eclipse.jface.viewers.IColorProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ITableColorProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.zest.core.viewers.IConnectionStyleProvider; import org.eclipse.zest.core.widgets.ZestStyles; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; import org.neo4j.neoclipse.Activator; import org.neo4j.neoclipse.Icons; import org.neo4j.neoclipse.decorate.SimpleGraphDecorator; import org.neo4j.neoclipse.decorate.SimpleGraphDecorator.Settings; import org.neo4j.neoclipse.decorate.SimpleGraphDecorator.ViewSettings; import org.neo4j.neoclipse.graphdb.GraphCallable; import org.neo4j.neoclipse.preference.DecoratorPreferences; import org.neo4j.neoclipse.reltype.DirectedRelationship; import org.neo4j.neoclipse.reltype.NodeIconUtil; import org.neo4j.neoclipse.reltype.RelationshipTypeControl; import org.neo4j.neoclipse.reltype.RelationshipTypeEditingSupport; /** * Provides the labels for graph elements. * * @author Peter Hänsgen * @author Anders Nawroth */ public class NeoGraphLabelProvider extends LabelProvider implements IConnectionStyleProvider, IColorProvider, ILabelProvider, ITableLabelProvider, ITableColorProvider, InputChangeListener { /** * Handler for node/relationship decoration.. */ private SimpleGraphDecorator graphDecorator; /** * Settings for {@link SimpleGraphDecorator} */ private final Settings settings = new Settings(); /** * View settings for {@link SimpleGraphDecorator} */ private final ViewSettings viewSettings = new ViewSettings(); /** * Marked relationships. */ private final Set<Relationship> markedRels = new HashSet<Relationship>(); /** * Marked nodes. */ private final Set<Node> markedNodes = new HashSet<Node>(); private static final Image CHECKED = Icons.CHECKED.image(); private static final Image UNCHECKED = Icons.UNCHECKED.image(); private Node inputNode = null; public NeoGraphLabelProvider() { // read all preferences refreshNodeIconLocation(); refreshNodePropertyNames(); refreshRelPropertyNames(); refreshNodeIconPropertyNames(); // get reference node settings.setDirections( Arrays.asList( Direction.INCOMING, Direction.OUTGOING ) ); // refresh relationship colors refreshGraphDecorator(); } /** * Get the current view settings. */ public ViewSettings getViewSettings() { return viewSettings; } /** * Check if a node is the reference node. * * @param node * @return */ private boolean isReferenceNode( final Node node ) { try { return Activator.getDefault().getGraphDbServiceManager().submitTask( new GraphCallable<Boolean>() { public Boolean call( final GraphDatabaseService graphDb ) { Node referenceNode = graphDb.getReferenceNode(); if ( referenceNode == null ) { return false; } return referenceNode.equals( node ); } }, "is ref node" ).get(); } catch ( Exception e ) { ErrorMessage.showDialog( "Create relationship(s)", e ); } return false; } /** * Check if the current node is the input node. * * @param node * @return */ private boolean isInputNode( final Node node ) { if ( inputNode == null ) { return false; } return inputNode.equals( node ); } /** * Handle change of node in graph view. */ public void inputChange( final Node node ) { inputNode = node; } /** * Mark relationships. * * @param rels relationships to mark */ public void addMarkedRels( final Collection<Relationship> rels ) { markedRels.addAll( rels ); } /** * Clear marked relationships. */ public void clearMarkedRels() { markedRels.clear(); } /** * Mark nodes. * * @param nodes nodes to mark */ public void addMarkedNodes( final Collection<Node> nodes ) { markedNodes.addAll( nodes ); } /** * Clear marked nodes. */ public void clearMarkedNodes() { markedNodes.clear(); } /** * Returns the icon for an element. */ @Override public Image getImage( final Object element ) { if ( element instanceof Node ) { Node node = (Node) element; if ( viewSettings.isShowNodeIcons() && !"".equals( settings.getNodeIconLocation() ) ) { return graphDecorator.getNodeImageFromProperty( node, isReferenceNode( node ) ); } else { return graphDecorator.getNodeImage( node, isReferenceNode( node ) ); } } return null; } /** * Returns the text for an element. */ @Override public String getText( final Object element ) { if ( element instanceof Node ) { Node node = (Node) element; return graphDecorator.getNodeText( node, isReferenceNode( node ) ); } else if ( element instanceof Relationship ) { Relationship rel = (Relationship) element; return graphDecorator.getRelationshipText( rel ); } else if ( element instanceof RelationshipTypeControl ) { DirectedRelationship typeControl = (DirectedRelationship) element; return typeControl.getRelType().name(); } else if ( element == null ) { return ""; } return element.toString(); } /** * Remove relationship colors, start over creating new ones. */ public void refreshRelationshipColors() { refreshGraphDecorator(); } private final void refreshGraphDecorator() { graphDecorator = new SimpleGraphDecorator( settings, viewSettings ); } /** * Read the location of node icons from preferences. */ public void readNodeIconLocation() { refreshNodeIconLocation(); refreshGraphDecorator(); } private final void refreshNodeIconLocation() { settings.setNodeIconLocation( NodeIconUtil.getIconLocation().getPath() ); } /** * Read the names of properties to look up for node labels from preferences. */ public void readNodePropertyNames() { refreshNodePropertyNames(); refreshGraphDecorator(); } private final void refreshNodePropertyNames() { settings.setNodePropertyNames( Activator.getDefault().getPreferenceStore().getString( DecoratorPreferences.NODE_PROPERTY_NAMES ) ); } /** * Read the names of properties to look up for relationship labels from * preferences. */ public void readRelPropertyNames() { refreshRelPropertyNames(); refreshGraphDecorator(); } private final void refreshRelPropertyNames() { settings.setRelPropertyNames( Activator.getDefault().getPreferenceStore().getString( DecoratorPreferences.RELATIONSHIP_PROPERTY_NAMES ) ); } /** * Read the names of properties to look up for node icon names from * preferences. */ public void readNodeIconPropertyNames() { refreshNodeIconPropertyNames(); refreshGraphDecorator(); } private final void refreshNodeIconPropertyNames() { settings.setNodeIconPropertyNames( Activator.getDefault().getPreferenceStore().getString( DecoratorPreferences.NODE_ICON_PROPERTY_NAMES ) ); } public Color getColor( final Object o ) { if ( o instanceof Relationship ) { Relationship rel = (Relationship) o; if ( !viewSettings.isShowRelationshipColors() || !( o instanceof Relationship ) ) { return graphDecorator.getRelationshipColor(); } if ( markedRels.contains( rel ) ) { return graphDecorator.getMarkedRelationshipColor( rel ); } return graphDecorator.getRelationshipColor( rel ); } else if ( o instanceof RelationshipType ) { RelationshipType relType = (RelationshipType) o; return graphDecorator.getRelationshipColor( relType ); } return null; } public int getConnectionStyle( final Object rel ) { int style = 0; if ( viewSettings.isShowArrows() ) { style |= ZestStyles.CONNECTIONS_DIRECTED; } if ( rel instanceof Relationship && markedRels.contains( rel ) ) { style |= graphDecorator.getMarkedRelationshipStyle( rel ); } return style; } public Color getHighlightColor( final Object rel ) { return graphDecorator.getRelationshipHighlightColor( (Relationship) rel ); } public int getLineWidth( final Object rel ) { if ( rel instanceof Relationship && markedRels.contains( rel ) ) { return graphDecorator.getMarkedLineWidth(); } else { return graphDecorator.getLineWidth(); } } public IFigure getTooltip( final Object entity ) { // got this working only for rels. use a Label (draw2d). return null; } public Color getBackground( final Object element ) { if ( element instanceof Node && viewSettings.isShowNodeColors() ) { if ( markedNodes.contains( element ) ) { return graphDecorator.getMarkedNodeColor( (Node) element ); } return graphDecorator.getNodeColor( (Node) element ); } return null; } public Color getForeground( final Object element ) { if ( element instanceof Node ) { Node node = (Node) element; return graphDecorator.getNodeForegroundColor( node, isInputNode( node ) ); } return null; } public Image getColumnImage( final Object element, final int index ) { if ( element instanceof RelationshipTypeControl ) { RelationshipTypeControl control = (RelationshipTypeControl) element; if ( index == 1 ) { return control.isIn() ? CHECKED : UNCHECKED; } if ( index == 2 ) { return control.isOut() ? CHECKED : UNCHECKED; } } return null; } public String getColumnText( final Object element, final int index ) { if ( index == 0 && element instanceof RelationshipTypeControl ) { DirectedRelationship control = (DirectedRelationship) element; return control.getRelType().name(); } return null; } public Color getBackground( final Object element, final int index ) { // TODO Auto-generated method stub return null; } public Color getForeground( final Object element, final int index ) { if ( !viewSettings.isShowRelationshipColors() || index != 0 || !( element instanceof RelationshipTypeControl ) ) { return graphDecorator.getRelationshipColor(); } DirectedRelationship control = (DirectedRelationship) element; return graphDecorator.getRelationshipColor( control.getRelType() ); } /** * Get the relationship types that was decorated. * * @return */ public Set<RelationshipType> getRelationshipTypes() { return graphDecorator.getRelationshipTypes(); } /** * Create the table columns of the Relationship types view. * * @param tableViewer */ public void createTableColumns( final TableViewer tableViewer ) { Table table = tableViewer.getTable(); TableViewerColumn column = new TableViewerColumn( tableViewer, SWT.LEFT ); TableColumn col = column.getColumn(); col.setText( "Relationship type" ); col.setWidth( 200 ); col.setResizable( true ); column.setEditingSupport( new RelationshipTypeEditingSupport( tableViewer, RelationshipTypeEditingSupport.ColumnType.HEADING ) ); column = new TableViewerColumn( tableViewer, SWT.LEFT ); col = column.getColumn(); col.setText( "In" ); col.setToolTipText( "Filter incoming relationships of this relationship type." ); col.setWidth( 60 ); col.setImage( Icons.INCOMING.image() ); col.setResizable( true ); column.setEditingSupport( new RelationshipTypeEditingSupport( tableViewer, RelationshipTypeEditingSupport.ColumnType.IN ) ); column = new TableViewerColumn( tableViewer, SWT.LEFT ); col = column.getColumn(); col.setText( "Out" ); col.setToolTipText( "Filter outgoing relationships of this relationship type." ); col.setWidth( 60 ); col.setImage( Icons.OUTGOING.image() ); col.setResizable( true ); column.setEditingSupport( new RelationshipTypeEditingSupport( tableViewer, RelationshipTypeEditingSupport.ColumnType.OUT ) ); table.setHeaderVisible( true ); table.setLinesVisible( true ); } public boolean propertyChanged( final PropertyChangeEvent event ) { String property = event.getProperty(); if ( DecoratorPreferences.NODE_PROPERTY_NAMES.equals( property ) ) { readNodePropertyNames(); return true; } else if ( DecoratorPreferences.RELATIONSHIP_PROPERTY_NAMES.equals( property ) ) { readRelPropertyNames(); return true; } else if ( DecoratorPreferences.NODE_ICON_LOCATION.equals( property ) ) { readNodeIconLocation(); return true; } else if ( DecoratorPreferences.NODE_ICON_PROPERTY_NAMES.equals( property ) ) { readNodeIconPropertyNames(); return true; } return false; } }