Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 from __future__ import print_function
00032 
00033 import sys
00034 
00035 from python_qt_binding.QtCore import Qt
00036 from python_qt_binding.QtGui import QBrush, QGraphicsEllipseItem, QGraphicsRectItem, QGraphicsSimpleTextItem, QPainterPath, QPen
00037 
00038 from .dot_shapes import QGraphicsBox3dItem
00039 from .graph_item import GraphItem
00040 
00041 
00042 class NodeItem(GraphItem):
00043 
00044     def __init__(self, highlight_level, bounding_box, label, shape, color=None, parent=None, label_pos=None, tooltip=None):
00045         super(NodeItem, self).__init__(highlight_level, parent)
00046 
00047         self._default_color = self._COLOR_BLACK if color is None else color
00048         self._brush = QBrush(self._default_color)
00049         self._label_pen = QPen()
00050         self._label_pen.setColor(self._default_color)
00051         self._label_pen.setJoinStyle(Qt.RoundJoin)
00052         self._ellipse_pen = QPen(self._label_pen)
00053         self._ellipse_pen.setWidth(1)
00054 
00055         self._incoming_edges = set()
00056         self._outgoing_edges = set()
00057 
00058         self.parse_shape(shape, bounding_box)
00059         self.addToGroup(self._graphics_item)
00060 
00061         self._label = QGraphicsSimpleTextItem(label)
00062         self._label.setFont(GraphItem._LABEL_FONT)
00063         label_rect = self._label.boundingRect()
00064         if label_pos is None:
00065             label_rect.moveCenter(bounding_box.center())
00066         else:
00067             label_rect.moveCenter(label_pos)
00068         self._label.setPos(label_rect.x(), label_rect.y())
00069         self.addToGroup(self._label)
00070         if tooltip is not None:
00071             self.setToolTip(tooltip)
00072 
00073         self.set_node_color()
00074 
00075         self.setAcceptHoverEvents(True)
00076 
00077         self.hovershape = None
00078 
00079     def parse_shape(self, shape, bounding_box):
00080         if shape in ('box', 'rect', 'rectangle'):
00081             self._graphics_item = QGraphicsRectItem(bounding_box)
00082         elif shape in ('ellipse', 'oval', 'circle'):
00083             self._graphics_item = QGraphicsEllipseItem(bounding_box)
00084         elif shape in ('box3d', ):
00085             self._graphics_item = QGraphicsBox3dItem(bounding_box)
00086         else:
00087             print("Invalid shape '%s', defaulting to ellipse" % shape, file=sys.stderr)
00088             self._graphics_item = QGraphicsEllipseItem(bounding_box)
00089 
00090     def set_hovershape(self, newhovershape):
00091         self.hovershape = newhovershape
00092 
00093     def shape(self):
00094         if self.hovershape is not None:
00095             path = QPainterPath()
00096             path.addRect(self.hovershape)
00097             return path
00098         else:
00099             return super(self.__class__, self).shape()
00100 
00101     def add_incoming_edge(self, edge):
00102         self._incoming_edges.add(edge)
00103 
00104     def add_outgoing_edge(self, edge):
00105         self._outgoing_edges.add(edge)
00106 
00107     def set_node_color(self, color=None):
00108         if color is None:
00109             color = self._default_color
00110 
00111         self._brush.setColor(color)
00112         self._ellipse_pen.setColor(color)
00113         self._label_pen.setColor(color)
00114 
00115         self._graphics_item.setPen(self._ellipse_pen)
00116         self._label.setBrush(self._brush)
00117         self._label.setPen(self._label_pen)
00118 
00119     def hoverEnterEvent(self, event):
00120         
00121         self.set_node_color(self._COLOR_RED)
00122 
00123         if self._highlight_level > 1:
00124             cyclic_edges = self._incoming_edges.intersection(self._outgoing_edges)
00125             
00126             incoming_nodes = set()
00127             for incoming_edge in self._incoming_edges.difference(cyclic_edges):
00128                 incoming_edge.set_node_color(self._COLOR_BLUE)
00129                 if incoming_edge.from_node != self:
00130                     incoming_nodes.add(incoming_edge.from_node)
00131             
00132             outgoing_nodes = set()
00133             for outgoing_edge in self._outgoing_edges.difference(cyclic_edges):
00134                 outgoing_edge.set_node_color(self._COLOR_GREEN)
00135                 if outgoing_edge.to_node != self:
00136                     outgoing_nodes.add(outgoing_edge.to_node)
00137             
00138             for edge in cyclic_edges:
00139                 edge.set_node_color(self._COLOR_TEAL)
00140 
00141             if self._highlight_level > 2:
00142                 cyclic_nodes = incoming_nodes.intersection(outgoing_nodes)
00143                 
00144                 for incoming_node in incoming_nodes.difference(cyclic_nodes):
00145                     incoming_node.set_node_color(self._COLOR_BLUE)
00146                 
00147                 for outgoing_node in outgoing_nodes.difference(cyclic_nodes):
00148                     outgoing_node.set_node_color(self._COLOR_GREEN)
00149                 
00150                 for node in cyclic_nodes:
00151                     node.set_node_color(self._COLOR_TEAL)
00152 
00153     def hoverLeaveEvent(self, event):
00154         self.set_node_color()
00155         if self._highlight_level > 1:
00156             for incoming_edge in self._incoming_edges:
00157                 incoming_edge.set_node_color()
00158                 if self._highlight_level > 2 and incoming_edge.from_node != self:
00159                     incoming_edge.from_node.set_node_color()
00160             for outgoing_edge in self._outgoing_edges:
00161                 outgoing_edge.set_node_color()
00162                 if self._highlight_level > 2 and outgoing_edge.to_node != self:
00163                     outgoing_edge.to_node.set_node_color()