def get_vt_graph(vt_list, tree_info, pdf=False):
    """get_vt_graph(vt_list: list of locator, tree_info:str)
    Load all vistrails in vt_list and dump their tree to tree_info.
    
    """
    result = []
    if is_running_gui():
        from gui.vistrail_controller import VistrailController as \
             GUIVistrailController
        for locator in vt_list:
            try:
                (v, abstractions , thumbnails, mashups)  = load_vistrail(locator)
                controller = GUIVistrailController()
                if tree_info is not None:
                        from gui.version_view import QVersionTreeView
                        version_view = QVersionTreeView()
                        from gui.pipeline_view import QPipelineView
                        pipeline_view = QPipelineView()
                        controller.current_pipeline_view = pipeline_view.scene()
                        controller.set_vistrail(v, locator, abstractions, thumbnails,
                                        mashups)
                        version_view.scene().setupScene(controller)
                        if pdf:
                            base_fname = "graph_%s.pdf" % locator.short_name
                            filename = os.path.join(tree_info, base_fname)
                            version_view.scene().saveToPDF(filename)
                        else:
                            base_fname = "graph_%s.png" % locator.short_name
                            filename = os.path.join(tree_info, base_fname)
                            version_view.scene().saveToPNG(filename)
                        del version_view
                        result.append((True, ""))
            except Exception, e:
                result.append((False, str(e)))
 def mousePressEvent(self, event):
     """ mousePressEvent(event: QMouseEvent) -> None
     Toggle port selection
     
     """
     buttons = self.translateButton(event)
     if buttons == QtCore.Qt.LeftButton:
         scenePos = self.mapToScene(event.pos())
         item = self.scene().itemAt(scenePos)
         if type(item) == QGraphicsPortItem:
             is_input = item.port.type == 'input'
             if self.single_output and not is_input and len(
                     self._selected_output_ports
             ) > 0 and item != self._selected_output_ports[0]:
                 # Deselect current output port if another port selected in single output mode
                 self._selected_output_ports[0].setPen(
                     CurrentTheme.PORT_PEN)
                 del self._selected_output_ports[:]
             if is_input:
                 port_set = self._selected_input_ports
             else:
                 port_set = self._selected_output_ports
             if item in port_set:
                 port_set.remove(item)
             else:
                 port_set.append(item)
             self._clicked_port = item
         else:
             self._clicked_port = None
         event.accept()
     else:
         QPipelineView.mousePressEvent(self, event)
 def mousePressEvent(self, event):
     """ mousePressEvent(event: QMouseEvent) -> None
     Toggle port selection
     
     """
     buttons = self.translateButton(event)
     if buttons == QtCore.Qt.LeftButton:
         scenePos = self.mapToScene(event.pos())
         item = self.scene().itemAt(scenePos)
         if type(item) == QGraphicsPortItem:
             is_input = item.port.type == 'input'
             if self.single_output and not is_input and len(self._selected_output_ports) > 0 and item != self._selected_output_ports[0]:
                 # Deselect current output port if another port selected in single output mode
                 self._selected_output_ports[0].setPen(CurrentTheme.PORT_PEN)
                 del self._selected_output_ports[:]
             if is_input:
                 port_set = self._selected_input_ports
             else:
                 port_set = self._selected_output_ports
             if item in port_set:
                 port_set.remove(item)
             else:
                 port_set.append(item)
             self._clicked_port = item
         else:
             self._clicked_port = None
         event.accept()
     else:
         QPipelineView.mousePressEvent(self, event)
Example #4
0
def get_vt_graph(vt_list, tree_info, pdf=False):
    """get_vt_graph(vt_list: list of locator, tree_info:str)
    Load all vistrails in vt_list and dump their tree to tree_info.
    
    """
    result = []
    if is_running_gui():
        from gui.vistrail_controller import VistrailController as \
             GUIVistrailController
        for locator in vt_list:
            try:
                (v, abstractions, thumbnails, mashups) = load_vistrail(locator)
                controller = GUIVistrailController()
                if tree_info is not None:
                    from gui.version_view import QVersionTreeView
                    version_view = QVersionTreeView()
                    from gui.pipeline_view import QPipelineView
                    pipeline_view = QPipelineView()
                    controller.current_pipeline_view = pipeline_view.scene()
                    controller.set_vistrail(v, locator, abstractions,
                                            thumbnails, mashups)
                    version_view.scene().setupScene(controller)
                    if pdf:
                        base_fname = "graph_%s.pdf" % locator.short_name
                        filename = os.path.join(tree_info, base_fname)
                        version_view.scene().saveToPDF(filename)
                    else:
                        base_fname = "graph_%s.png" % locator.short_name
                        filename = os.path.join(tree_info, base_fname)
                        version_view.scene().saveToPNG(filename)
                    del version_view
                    result.append((True, ""))
            except Exception, e:
                result.append((False, str(e)))
Example #5
0
 def __init__(self, parent=None):
     """ QPipelineView(parent: QWidget) -> QPipelineView
     Initialize the graphics view and its properties
     
     """
     QPipelineView.__init__(self, parent)
     self.setWindowTitle('Annotated Pipeline')
     self.inspector = PipelineInspector()
 def __init__(self, parent=None):
     """ QPipelineView(parent: QWidget) -> QPipelineView
     Initialize the graphics view and its properties
     
     """
     QPipelineView.__init__(self, parent)
     self.setWindowTitle('Annotated Pipeline')
     self.inspector = PipelineInspector()
 def paintEvent(self, event):
     """ paintEvent(event: QPaintEvent) -> None
     Fit pipeline to view on first paint
     
     """
     if not self._shown:
         self._shown = True
         self.scene().fitToView(self)
     QPipelineView.paintEvent(self, event)
 def paintEvent(self, event):
     """ paintEvent(event: QPaintEvent) -> None
     Fit pipeline to view on first paint
     
     """
     if not self._shown:
         self._shown = True
         self.scene().fitToView(self)
     QPipelineView.paintEvent(self, event)
 def mouseDoubleClickEvent(self, event):
     """ mouseDoubleClickEvent(event: QMouseEvent) -> None
     Disallow left button double clicks
     
     """
     buttons = self.translateButton(event)
     if buttons == QtCore.Qt.LeftButton:
         event.accept()
     else:
         QPipelineView.mouseDoubleClickEvent(self, event)
 def mouseMoveEvent(self, event):
     """ mousePressEvent(event: QMouseEvent) -> None
     Disallow left click and drag
     
     """
     buttons = self.translateButton(event)
     if buttons == QtCore.Qt.LeftButton:
         event.accept()
     else:
         QPipelineView.mouseMoveEvent(self, event)
Example #11
0
 def set_controller(self, controller):
     QPipelineView.set_controller(self, controller)
     #print "@@@ set_controller called", id(self.controller), len(self.controller.vistrail.actions)
     if not hasattr(self.controller, 'loaded_workflow_execs'):
         self.controller.loaded_workflow_execs = {}
         for e in self.controller.read_log().workflow_execs:
             # set workflow names
             e.db_name = controller.get_pipeline_name(e.parent_version)[10:]
             self.controller.loaded_workflow_execs[e] = e
     self.log = self.controller.loaded_workflow_execs
 def mouseMoveEvent(self, event):
     """ mousePressEvent(event: QMouseEvent) -> None
     Disallow left click and drag
     
     """
     buttons = self.translateButton(event)
     if buttons == QtCore.Qt.LeftButton:
         event.accept()
     else:
         QPipelineView.mouseMoveEvent(self, event)
 def mouseDoubleClickEvent(self, event):
     """ mouseDoubleClickEvent(event: QMouseEvent) -> None
     Disallow left button double clicks
     
     """
     buttons = self.translateButton(event)
     if buttons == QtCore.Qt.LeftButton:
         event.accept()
     else:
         QPipelineView.mouseDoubleClickEvent(self, event)
Example #14
0
 def set_controller(self, controller):
     QPipelineView.set_controller(self, controller)
     #print "@@@ set_controller called", id(self.controller), len(self.controller.vistrail.actions)
     if not hasattr(self.controller, 'loaded_workflow_execs'):
         self.controller.loaded_workflow_execs = {}
         for e in self.controller.read_log().workflow_execs:
             # set workflow names
             e.db_name = controller.get_pipeline_name(
                                     e.parent_version)[10:]
             self.controller.loaded_workflow_execs[e] = e
     self.log = self.controller.loaded_workflow_execs
Example #15
0
 def __init__(self, parent=None):
     QPipelineView.__init__(self, parent)
     self.setReadOnlyMode(True)
     self.set_title("Provenance")
     self.log = None
     self.execution = None
     self.parentExecution = None
     self.isUpdating = False
     # self.exec_to_wf_map = {}
     # self.workflow_execs = []
     # Hook shape selecting functions
     self.connect(self.scene(), QtCore.SIGNAL("moduleSelected"),
                  self.moduleSelected)
Example #16
0
 def __init__(self, parent=None):
     QPipelineView.__init__(self, parent)
     self.setReadOnlyMode(True)
     self.set_title("Provenance")
     self.log = None
     self.execution = None
     self.parentExecution = None
     self.isUpdating = False
     # self.exec_to_wf_map = {}
     # self.workflow_execs = []
     # Hook shape selecting functions
     self.connect(self.scene(), QtCore.SIGNAL("moduleSelected"),
                  self.moduleSelected)
 def mouseReleaseEvent(self, event):
     """ mouseReleaseEvent(event: QMouseEvent) -> None
     Update port highlighting
     
     """
     if event.button() == QtCore.Qt.LeftButton:
         port = self._clicked_port
         if port is not None:
             if port in self._selected_input_ports or port in self._selected_output_ports:
                 port.setPen(CurrentTheme.PORT_SELECTED_PEN)
             else:
                 port.setPen(CurrentTheme.PORT_PEN)
         event.accept()
     else:
         QPipelineView.mouseReleaseEvent(self, event)
 def mouseReleaseEvent(self, event):
     """ mouseReleaseEvent(event: QMouseEvent) -> None
     Update port highlighting
     
     """
     if event.button() == QtCore.Qt.LeftButton:
         port = self._clicked_port
         if port is not None:
             if port in self._selected_input_ports or port in self._selected_output_ports:
                 port.setPen(CurrentTheme.PORT_SELECTED_PEN)
             else:
                 port.setPen(CurrentTheme.PORT_PEN)
         event.accept()
     else:
         QPipelineView.mouseReleaseEvent(self, event)
    def __init__(self, parent=None):
        """ QPipelineTab(parent: QWidget) -> QPipelineTab        
        Make it a main window with dockable area and a QPipelineView
        in the middle
        
        """
        QDockContainer.__init__(self, parent)
        self.setWindowTitle('Pipeline')
        self.pipelineView = QPipelineView()
        self.pipelineView.scene().pipeline_tab = proxy(self)
        self.setCentralWidget(self.pipelineView)
        self.toolWindow().setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
        self.toolWindow().hide()        
        
        self.methodPalette = QMethodPalette(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.methodPalette.toolWindow())
        
        self.moduleMethods = QModuleMethods(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.moduleMethods.toolWindow())
        
        self.connect(self.toolWindow(),
                     QtCore.SIGNAL('topLevelChanged(bool)'),
                     self.updateWindowTitle)
        self.connect(self.pipelineView.scene(),
                     QtCore.SIGNAL('moduleSelected'),
                     self.moduleSelected)
        self.connect(self.pipelineView,
                     QtCore.SIGNAL('resetQuery()'),
                     self.resetQuery)

        self.controller = None
 def __init__(self,
              parent,
              scene,
              single_output=False,
              include_module_ids=[]):
     """ QReadOnlyPortSelectPipelineView(parent: QPipelineView,
                                         scene: QGraphicsScene,
                                         single_output: bool,
                                         include_module_ids: list)
                                         -> QReadOnlyPortSelectPipelineView
     Create a read only pipeline view that only allows selection of ports from
     the modules in include_module_ids.  If single_output is True, only one
     output port can be selected at a time.
     
     """
     QPipelineView.__init__(self, parent)
     self.single_output = single_output
     self._shown = False
     self._selected_input_ports = []
     self._selected_output_ports = []
     # Create custom scene
     scene_copy = QPipelineScene(self)
     scene_copy.controller = scene.controller
     scene_copy.setupScene(scene.pipeline)
     scene_copy.selectAll()
     if include_module_ids:
         # Remove modules not in the include list and associated connections
         sel_modules, sel_connections = scene_copy.get_selected_item_ids()
         [
             scene_copy.remove_module(m_id) for m_id in sel_modules
             if m_id not in include_module_ids
         ]
         [
             scene_copy.remove_connection(c_id) for c_id in sel_connections
             if c_id not in scene_copy.get_selected_item_ids()[1]
         ]
     # Hide configure button on modules
     for item in scene_copy.selectedItems():
         if type(item) == QGraphicsModuleItem:
             for c_item in item.childItems():
                 if type(c_item) == QGraphicsConfigureItem:
                     c_item.setVisible(False)
     # Unselect everything and use the newly created scene
     scene_copy.clearSelection()
     scene_copy.updateSceneBoundingRect()
     self.setScene(scene_copy)
Example #21
0
 def paintEvent(self, event):
     """ paintEvent(event: QPaintEvent) -> None
     Paint an overlay annotation on spreadsheet cell modules
     
     """
     QPipelineView.paintEvent(self, event)
     # super(QAnnotatedPipelineView, self).paintEvent(event)
     if self.scene():
         painter = QtGui.QPainter(self.viewport())
         for mId, annotatedId in \
                 self.inspector.annotated_modules.iteritems():
             item = self.scene().modules[mId]
             br = item.sceneBoundingRect()
             rect = QtCore.QRect(self.mapFromScene(br.topLeft()),
                                 self.mapFromScene(br.bottomRight()))
             QAnnotatedPipelineView.drawId(painter, rect, annotatedId)
         painter.end()
Example #22
0
    def __init__(self, parent=None):
        """ QPipelineTab(parent: QWidget) -> QPipelineTab        
        Make it a main window with dockable area and a QPipelineView
        in the middle
        
        """
        QDockContainer.__init__(self, parent)
        self.setWindowTitle('Pipeline')
        self.pipelineView = QPipelineView()
        self.pipelineView.scene().pipeline_tab = proxy(self)
        self.setCentralWidget(self.pipelineView)
        self.toolWindow().setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
        self.toolWindow().hide()

        self.methodPalette = QMethodPalette(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.methodPalette.toolWindow())

        self.moduleMethods = QModuleMethods(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.moduleMethods.toolWindow())

        self.moduleConfig = QModuleConfiguration(self,
                                                 self.pipelineView.scene())
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.moduleConfig.toolWindow())

        self.vistrailVars = QVistrailVariables(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.vistrailVars.toolWindow())

        self.connect(self.toolWindow(), QtCore.SIGNAL('topLevelChanged(bool)'),
                     self.updateWindowTitle)
        self.connect(self.pipelineView.scene(),
                     QtCore.SIGNAL('moduleSelected'), self.moduleSelected)
        self.connect(self.moduleConfig, QtCore.SIGNAL('doneConfigure'),
                     self.pipelineView.scene().perform_configure_done_actions)
        self.connect(self.pipelineView.scene(),
                     QtCore.SIGNAL('showConfigureWindow'),
                     self.moduleConfig.activate)
        self.connect(self.pipelineView, QtCore.SIGNAL('resetQuery()'),
                     self.resetQuery)

        self.controller = None
Example #23
0
def get_wf_graph(w_list, workflow_info=None, pdf=False):
    """run_and_get_results(w_list: list of (locator, version), 
                           workflow_info:str, pdf:bool)
    Load all workflows in wf_list and dump their graph to workflow_info.
    
    """
    result = []
    if is_running_gui():
        from gui.vistrail_controller import VistrailController as \
             GUIVistrailController
        for locator, workflow in w_list:
            try:
                (v, abstractions, thumbnails, mashups) = load_vistrail(locator)
                controller = GUIVistrailController()
                if type(workflow) == type("str"):
                    version = v.get_version_number(workflow)
                elif type(workflow) in [type(1), long]:
                    version = workflow
                elif workflow is None:
                    version = controller.get_latest_version_in_graph()
                else:
                    msg = "Invalid version tag or number: %s" % workflow
                    raise VistrailsInternalError(msg)
                controller.change_selected_version(version)

                if (workflow_info is not None
                        and controller.current_pipeline is not None):
                    from gui.pipeline_view import QPipelineView
                    pipeline_view = QPipelineView()
                    controller.current_pipeline_view = pipeline_view.scene()
                    controller.set_vistrail(v, locator, abstractions,
                                            thumbnails, mashups)
                    pipeline_view.scene().setupScene(
                        controller.current_pipeline)
                    if pdf:
                        base_fname = "%s_%s_pipeline.pdf" % (
                            locator.short_name, version)
                        filename = os.path.join(workflow_info, base_fname)
                        pipeline_view.scene().saveToPDF(filename)
                    else:
                        base_fname = "%s_%s_pipeline.png" % (
                            locator.short_name, version)
                        filename = os.path.join(workflow_info, base_fname)
                        pipeline_view.scene().saveToPNG(filename)
                    del pipeline_view
                    result.append((True, ""))
            except Exception, e:
                result.append((False, str(e)))
Example #24
0
 def paintEvent(self, event):
     """ paintEvent(event: QPaintEvent) -> None
     Paint an overlay annotation on spreadsheet cell modules
     
     """
     QPipelineView.paintEvent(self, event)
     # super(QAnnotatedPipelineView, self).paintEvent(event)
     if self.scene():
         painter = QtGui.QPainter(self.viewport())
         for mId, annotatedId in \
                 self.inspector.annotated_modules.iteritems():
             if mId not in self.scene().modules:
                 # faulty annotated_modules entry
                 continue
             item = self.scene().modules[mId]
             br = item.sceneBoundingRect()
             rect = QtCore.QRect(self.mapFromScene(br.topLeft()),
                                 self.mapFromScene(br.bottomRight()))
             QAnnotatedPipelineView.drawId(painter, rect, annotatedId)
         painter.end()
 def __init__(self, parent, scene, single_output=False, include_module_ids=[]):
     """ QReadOnlyPortSelectPipelineView(parent: QPipelineView,
                                         scene: QGraphicsScene,
                                         single_output: bool,
                                         include_module_ids: list)
                                         -> QReadOnlyPortSelectPipelineView
     Create a read only pipeline view that only allows selection of ports from
     the modules in include_module_ids.  If single_output is True, only one
     output port can be selected at a time.
     
     """
     QPipelineView.__init__(self, parent)
     self.single_output = single_output
     self._shown = False
     self._selected_input_ports = []
     self._selected_output_ports = []
     # Create custom scene
     scene_copy = QPipelineScene(self)
     scene_copy.controller = scene.controller
     scene_copy.setupScene(scene.pipeline)
     scene_copy.selectAll()
     if include_module_ids:
         # Remove modules not in the include list and associated connections
         sel_modules, sel_connections = scene_copy.get_selected_item_ids()
         [scene_copy.remove_module(m_id) for m_id in sel_modules if m_id not in include_module_ids]
         [scene_copy.remove_connection(c_id) for c_id in sel_connections if c_id not in scene_copy.get_selected_item_ids()[1]]
     # Hide configure button on modules
     for item in scene_copy.selectedItems():
         if type(item) == QGraphicsModuleItem:
             for c_item in item.childItems():
                 if type(c_item) == QGraphicsConfigureItem:
                     c_item.setVisible(False)
     # Unselect everything and use the newly created scene
     scene_copy.clearSelection()
     scene_copy.updateSceneBoundingRect()
     self.setScene(scene_copy)
def get_wf_graph(w_list, workflow_info=None, pdf=False):
    """run_and_get_results(w_list: list of (locator, version), 
                           workflow_info:str, pdf:bool)
    Load all workflows in wf_list and dump their graph to workflow_info.
    
    """
    result = []
    if is_running_gui():
        from gui.vistrail_controller import VistrailController as \
             GUIVistrailController
        for locator, workflow in w_list:
            try:
                (v, abstractions , thumbnails, mashups)  = load_vistrail(locator)
                controller = GUIVistrailController()
                if type(workflow) == type("str"):
                    version = v.get_version_number(workflow)
                elif type(workflow) in [ type(1), long]:
                    version = workflow
                elif workflow is None:
                    version = controller.get_latest_version_in_graph()
                else:
                    msg = "Invalid version tag or number: %s" % workflow
                    raise VistrailsInternalError(msg)
                controller.change_selected_version(version)
            
                if (workflow_info is not None and 
                    controller.current_pipeline is not None):
                    from gui.pipeline_view import QPipelineView
                    pipeline_view = QPipelineView()
                    controller.current_pipeline_view = pipeline_view.scene()
                    controller.set_vistrail(v, locator, abstractions, thumbnails,
                                        mashups)
                    pipeline_view.scene().setupScene(controller.current_pipeline)
                    if pdf:
                        base_fname = "%s_%s_pipeline.pdf" % (locator.short_name, version)
                        filename = os.path.join(workflow_info, base_fname)
                        pipeline_view.scene().saveToPDF(filename)
                    else:
                        base_fname = "%s_%s_pipeline.png" % (locator.short_name, version)
                        filename = os.path.join(workflow_info, base_fname)
                        pipeline_view.scene().saveToPNG(filename)
                    del pipeline_view
                    result.append((True, ""))
            except Exception, e:
                result.append((False, str(e)))
Example #27
0
    def createPipelineView(self):
        """ createPipelineView() -> None        
        Create a center pipeline view for Visual Diff and setup the
        view based on the diff result self.diff
        
        """
        # Initialize the shape engine
        self.pipelineView = QPipelineView()
        self.setCentralWidget(self.pipelineView)

        # Add all the shapes into the view
        self.createDiffPipeline()

        # Hook shape selecting functions
        self.connect(self.pipelineView.scene(), QtCore.SIGNAL("moduleSelected"),
                     self.moduleSelected)
Example #28
0
 def __init__(self, parent=None):
     QPipelineView.__init__(self, parent)
     self.setBackgroundBrush(CurrentTheme.QUERY_RESULT_BACKGROUND_BRUSH)
     self.scene().set_read_only_mode(True)
Example #29
0
 def __init__(self, parent=None):
     QPipelineView.__init__(self, parent)
     self.setBackgroundBrush(CurrentTheme.QUERY_BACKGROUND_BRUSH)
     self.scene().current_pipeline = Pipeline()
     self.query_controller = None
Example #30
0
class QPipelineTab(QDockContainer, QToolWindowInterface):
    """
    QPipelineTab is a tab widget setting QPipelineView in a center
    while having surrounding tool windows for manipulating a pipeline
    
    """
    def __init__(self, parent=None):
        """ QPipelineTab(parent: QWidget) -> QPipelineTab        
        Make it a main window with dockable area and a QPipelineView
        in the middle
        
        """
        QDockContainer.__init__(self, parent)
        self.setWindowTitle('Pipeline')
        self.pipelineView = QPipelineView()
        self.pipelineView.scene().pipeline_tab = proxy(self)
        self.setCentralWidget(self.pipelineView)
        self.toolWindow().setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
        self.toolWindow().hide()

        self.methodPalette = QMethodPalette(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.methodPalette.toolWindow())

        self.moduleMethods = QModuleMethods(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.moduleMethods.toolWindow())

        self.moduleConfig = QModuleConfiguration(self,
                                                 self.pipelineView.scene())
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.moduleConfig.toolWindow())

        self.vistrailVars = QVistrailVariables(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.vistrailVars.toolWindow())

        self.connect(self.toolWindow(), QtCore.SIGNAL('topLevelChanged(bool)'),
                     self.updateWindowTitle)
        self.connect(self.pipelineView.scene(),
                     QtCore.SIGNAL('moduleSelected'), self.moduleSelected)
        self.connect(self.moduleConfig, QtCore.SIGNAL('doneConfigure'),
                     self.pipelineView.scene().perform_configure_done_actions)
        self.connect(self.pipelineView.scene(),
                     QtCore.SIGNAL('showConfigureWindow'),
                     self.moduleConfig.activate)
        self.connect(self.pipelineView, QtCore.SIGNAL('resetQuery()'),
                     self.resetQuery)

        self.controller = None

    def addViewActionsToMenu(self, menu):
        """addViewActionsToMenu(menu: QMenu) -> None
        Add toggle view actions to menu
        
        """
        menu.addAction(self.methodPalette.toolWindow().toggleViewAction())
        menu.addAction(self.moduleMethods.toolWindow().toggleViewAction())
        menu.addAction(self.moduleConfig.toolWindow().toggleViewAction())
        menu.addAction(self.vistrailVars.toolWindow().toggleViewAction())

    def removeViewActionsFromMenu(self, menu):
        """removeViewActionsFromMenu(menu: QMenu) -> None
        Remove toggle view actions from menu
        
        """
        menu.removeAction(self.methodPalette.toolWindow().toggleViewAction())
        menu.removeAction(self.moduleMethods.toolWindow().toggleViewAction())
        menu.removeAction(self.moduleConfig.toolWindow().toggleViewAction())
        menu.removeAction(self.vistrailVars.toolWindow().toggleViewAction())

    def updatePipeline(self, pipeline):
        """ updatePipeline(pipeline: Pipeline) -> None        
        Setup the pipeline to display and control a specific pipeline
        
        """
        self.pipelineView.scene().setupScene(pipeline)

    def updateWindowTitle(self, topLevel):
        """ updateWindowTitle(topLevel: bool) -> None
        Change the current widget title depends on the top level status
        
        """
        if topLevel:
            self.setWindowTitle('Pipeline <' +
                                self.toolWindow().parent().windowTitle() + '>')
        else:
            self.setWindowTitle('Pipeline')

    def moduleSelected(self, moduleId, selection=[]):
        """ moduleChanged(moduleId: int, selection: [QGraphicsModuleItem])
                          -> None
        Set up the view when module selection has been changed
        
        """
        if self.pipelineView.scene().controller:
            pipeline = self.pipelineView.scene().controller.current_pipeline
        else:
            pipeline = None
        if pipeline and pipeline.modules.has_key(moduleId):
            module = pipeline.modules[moduleId]
            self.methodPalette.setEnabled(True)
            self.moduleMethods.setEnabled(True)
            self.moduleConfig.setEnabled(True)
        else:
            module = None
            self.methodPalette.setEnabled(False)
            self.moduleMethods.setEnabled(False)
            self.moduleConfig.setEnabled(False)
        self.methodPalette.setUpdatesEnabled(False)
        self.moduleMethods.setUpdatesEnabled(False)
        self.moduleConfig.setUpdatesEnabled(False)
        try:
            self.methodPalette.updateModule(module)
            self.moduleMethods.updateModule(module)
            self.moduleConfig.updateModule(module)
            self.emit(QtCore.SIGNAL('moduleSelectionChange'),
                      [m.id for m in selection])
        finally:
            self.methodPalette.setUpdatesEnabled(True)
            self.moduleMethods.setUpdatesEnabled(True)
            self.moduleConfig.setUpdatesEnabled(True)

    def setController(self, controller):
        """ setController(controller: VistrailController) -> None
        Assign a vistrail controller to this pipeline view
        
        """
        oldController = self.pipelineView.scene().controller
        if oldController != controller:
            if oldController != None:
                self.disconnect(oldController,
                                QtCore.SIGNAL('versionWasChanged'),
                                self.versionChanged)
                oldController.current_pipeline_view = None
            self.controller = controller
            self.pipelineView.scene().controller = controller
            self.connect(controller, QtCore.SIGNAL('versionWasChanged'),
                         self.versionChanged)
            self.methodPalette.controller = controller
            self.moduleMethods.controller = controller
            self.moduleConfig.controller = controller
            self.vistrailVars.updateController(controller)
            controller.current_pipeline_view = self.pipelineView.scene()

    def versionChanged(self, newVersion):
        """ versionChanged(newVersion: int) -> None        
        Update the pipeline when the new vistrail selected in the
        controller
        
        """
        self.updatePipeline(self.controller.current_pipeline)

    def resetQuery(self):
        """ resetQuery() -> None
        pass along the signal

        """
        self.emit(QtCore.SIGNAL('resetQuery()'))

    def checkModuleConfigPanel(self):
        """ checkModuleConfigPanel(self) -> None 
        This will ask if user wants to save changes """
        if self.moduleConfig.hasChanges:
            self.moduleConfig.confWidget.widget.askToSaveChanges()
def run_and_get_results(w_list, parameters='', workflow_info=None, 
                        update_vistrail=True, extra_info=None, 
                        reason='Console Mode Execution'):
    """run_and_get_results(w_list: list of (locator, version), parameters: str,
                           workflow_info:str, update_vistrail: boolean,
                           extra_info:dict)
    Run all workflows in w_list, and returns an interpreter result object.
    version can be a tag name or a version id.
    
    """
    elements = parameters.split("$&$")
    aliases = {}
    result = []
    for locator, workflow in w_list:
        (v, abstractions , thumbnails, mashups)  = load_vistrail(locator)
        controller = VistrailController(auto_save=update_vistrail)
        controller.set_vistrail(v, locator, abstractions, thumbnails, mashups)
        if type(workflow) == type("str"):
            version = v.get_version_number(workflow)
        elif type(workflow) in [ type(1), long]:
            version = workflow
        elif workflow is None:
            version = controller.get_latest_version_in_graph()
        else:
            msg = "Invalid version tag or number: %s" % workflow
            raise VistrailsInternalError(msg)
        controller.change_selected_version(version)
        
        for e in elements:
            pos = e.find("=")
            if pos != -1:
                key = e[:pos].strip()
                value = e[pos+1:].strip()
            
                if controller.current_pipeline.has_alias(key):
                    aliases[key] = value
                    
        if workflow_info is not None and controller.current_pipeline is not None:
            if is_running_gui():
                from gui.pipeline_view import QPipelineView
                pipeline_view = QPipelineView()
                pipeline_view.scene().setupScene(controller.current_pipeline)
                base_fname = "%s_%s_pipeline.pdf" % (locator.short_name, version)
                filename = os.path.join(workflow_info, base_fname)
                pipeline_view.scene().saveToPDF(filename)
                del pipeline_view
            else:
                debug.critical("Cannot save pipeline figure when not "
                               "running in gui mode")
            base_fname = "%s_%s_pipeline.xml" % (locator.short_name, version)
            filename = os.path.join(workflow_info, base_fname)
            core.db.io.save_workflow(controller.current_pipeline, filename)
        if not update_vistrail:
            conf = get_vistrails_configuration()
            if conf.has('thumbs'):
                conf.thumbs.autoSave = False
        
        (results, _) = \
            controller.execute_current_workflow(custom_aliases=aliases,
                                                extra_info=extra_info,
                                                reason=reason)
        new_version = controller.current_version
        if new_version != version:
            debug.warning("Version '%s' (%s) was upgraded. The actual "
                          "version executed was %s" % \
                              (workflow, version, new_version))
        run = results[0]
        run.workflow_info = (locator.name, new_version)
        run.pipeline = controller.current_pipeline

        if update_vistrail:
            controller.write_vistrail(locator)
        result.append(run)
    return result
class QPipelineTab(QDockContainer, QToolWindowInterface):
    """
    QPipelineTab is a tab widget setting QPipelineView in a center
    while having surrounding tool windows for manipulating a pipeline
    
    """
    def __init__(self, parent=None):
        """ QPipelineTab(parent: QWidget) -> QPipelineTab        
        Make it a main window with dockable area and a QPipelineView
        in the middle
        
        """
        QDockContainer.__init__(self, parent)
        self.setWindowTitle('Pipeline')
        self.pipelineView = QPipelineView()
        self.pipelineView.scene().pipeline_tab = proxy(self)
        self.setCentralWidget(self.pipelineView)
        self.toolWindow().setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
        self.toolWindow().hide()        
        
        self.methodPalette = QMethodPalette(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.methodPalette.toolWindow())
        
        self.moduleMethods = QModuleMethods(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.moduleMethods.toolWindow())
        
        self.moduleConfig = QModuleConfiguration(self, self.pipelineView.scene())
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, 
                           self.moduleConfig.toolWindow())
        
        self.vistrailVars = QVistrailVariables(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.vistrailVars.toolWindow())
        
        self.connect(self.toolWindow(),
                     QtCore.SIGNAL('topLevelChanged(bool)'),
                     self.updateWindowTitle)
        self.connect(self.pipelineView.scene(),
                     QtCore.SIGNAL('moduleSelected'),
                     self.moduleSelected)
        self.connect(self.moduleConfig,
                     QtCore.SIGNAL('doneConfigure'),
                     self.pipelineView.scene().perform_configure_done_actions)
        self.connect(self.pipelineView.scene(),
                     QtCore.SIGNAL('showConfigureWindow'),
                     self.moduleConfig.activate)
        self.connect(self.pipelineView,
                     QtCore.SIGNAL('resetQuery()'),
                     self.resetQuery)

        self.controller = None

    def addViewActionsToMenu(self, menu):
        """addViewActionsToMenu(menu: QMenu) -> None
        Add toggle view actions to menu
        
        """
        menu.addAction(self.methodPalette.toolWindow().toggleViewAction())
        menu.addAction(self.moduleMethods.toolWindow().toggleViewAction())
        menu.addAction(self.moduleConfig.toolWindow().toggleViewAction())
        menu.addAction(self.vistrailVars.toolWindow().toggleViewAction())

    def removeViewActionsFromMenu(self, menu):
        """removeViewActionsFromMenu(menu: QMenu) -> None
        Remove toggle view actions from menu
        
        """
        menu.removeAction(self.methodPalette.toolWindow().toggleViewAction())
        menu.removeAction(self.moduleMethods.toolWindow().toggleViewAction())
        menu.removeAction(self.moduleConfig.toolWindow().toggleViewAction())
        menu.removeAction(self.vistrailVars.toolWindow().toggleViewAction())

    def updatePipeline(self, pipeline):
        """ updatePipeline(pipeline: Pipeline) -> None        
        Setup the pipeline to display and control a specific pipeline
        
        """
        self.pipelineView.scene().setupScene(pipeline)

    def updateWindowTitle(self, topLevel):
        """ updateWindowTitle(topLevel: bool) -> None
        Change the current widget title depends on the top level status
        
        """
        if topLevel:
            self.setWindowTitle('Pipeline <' +
                                self.toolWindow().parent().windowTitle()+'>')
        else:
            self.setWindowTitle('Pipeline')

    def moduleSelected(self, moduleId, selection = []):
        """ moduleChanged(moduleId: int, selection: [QGraphicsModuleItem])
                          -> None
        Set up the view when module selection has been changed
        
        """
        if self.pipelineView.scene().controller:
            pipeline = self.pipelineView.scene().controller.current_pipeline
        else:
            pipeline = None
        if pipeline and pipeline.modules.has_key(moduleId):
            module = pipeline.modules[moduleId]
            self.methodPalette.setEnabled(True)
            self.moduleMethods.setEnabled(True)
            self.moduleConfig.setEnabled(True)
        else:
            module = None
            self.methodPalette.setEnabled(False)
            self.moduleMethods.setEnabled(False)
            self.moduleConfig.setEnabled(False)
        self.methodPalette.setUpdatesEnabled(False)
        self.moduleMethods.setUpdatesEnabled(False)
        self.moduleConfig.setUpdatesEnabled(False)
        try:
            self.methodPalette.updateModule(module)
            self.moduleMethods.updateModule(module)
            self.moduleConfig.updateModule(module)
            self.emit(QtCore.SIGNAL('moduleSelectionChange'),
                      [m.id for m in selection])
        finally:
            self.methodPalette.setUpdatesEnabled(True)
            self.moduleMethods.setUpdatesEnabled(True)
            self.moduleConfig.setUpdatesEnabled(True) 

    def setController(self, controller):
        """ setController(controller: VistrailController) -> None
        Assign a vistrail controller to this pipeline view
        
        """
        oldController = self.pipelineView.scene().controller
        if oldController!=controller:
            if oldController!=None:
                self.disconnect(oldController,
                                QtCore.SIGNAL('versionWasChanged'),
                                self.versionChanged)
                oldController.current_pipeline_view = None
            self.controller = controller
            self.pipelineView.scene().controller = controller
            self.connect(controller,
                         QtCore.SIGNAL('versionWasChanged'),
                         self.versionChanged)
            self.methodPalette.controller = controller
            self.moduleMethods.controller = controller
            self.moduleConfig.controller = controller
            self.vistrailVars.updateController(controller)
            controller.current_pipeline_view = self.pipelineView.scene()

    def versionChanged(self, newVersion):
        """ versionChanged(newVersion: int) -> None        
        Update the pipeline when the new vistrail selected in the
        controller
        
        """
        self.updatePipeline(self.controller.current_pipeline)
            
    def resetQuery(self):
        """ resetQuery() -> None
        pass along the signal

        """
        self.emit(QtCore.SIGNAL('resetQuery()'))

    def checkModuleConfigPanel(self):
        """ checkModuleConfigPanel(self) -> None 
        This will ask if user wants to save changes """
        if self.moduleConfig.hasChanges:
            self.moduleConfig.confWidget.widget.askToSaveChanges()
class QPipelineTab(QDockContainer, QToolWindowInterface):
    """
    QPipelineTab is a tab widget setting QPipelineView in a center
    while having surrounding tool windows for manipulating a pipeline
    
    """
    def __init__(self, parent=None):
        """ QPipelineTab(parent: QWidget) -> QPipelineTab        
        Make it a main window with dockable area and a QPipelineView
        in the middle
        
        """
        QDockContainer.__init__(self, parent)
        self.setWindowTitle('Pipeline')
        self.pipelineView = QPipelineView()
        self.pipelineView.scene().pipeline_tab = proxy(self)
        self.setCentralWidget(self.pipelineView)
        self.toolWindow().setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
        self.toolWindow().hide()        
        
        self.methodPalette = QMethodPalette(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.methodPalette.toolWindow())
        
        self.moduleMethods = QModuleMethods(self)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea,
                           self.moduleMethods.toolWindow())
        
        self.connect(self.toolWindow(),
                     QtCore.SIGNAL('topLevelChanged(bool)'),
                     self.updateWindowTitle)
        self.connect(self.pipelineView.scene(),
                     QtCore.SIGNAL('moduleSelected'),
                     self.moduleSelected)
        self.connect(self.pipelineView,
                     QtCore.SIGNAL('resetQuery()'),
                     self.resetQuery)

        self.controller = None

    def addViewActionsToMenu(self, menu):
        """addViewActionsToMenu(menu: QMenu) -> None
        Add toggle view actions to menu
        
        """
        menu.addAction(self.methodPalette.toolWindow().toggleViewAction())
        menu.addAction(self.moduleMethods.toolWindow().toggleViewAction())

    def removeViewActionsFromMenu(self, menu):
        """removeViewActionsFromMenu(menu: QMenu) -> None
        Remove toggle view actions from menu
        
        """
        menu.removeAction(self.methodPalette.toolWindow().toggleViewAction())
        menu.removeAction(self.moduleMethods.toolWindow().toggleViewAction())

    def updatePipeline(self, pipeline):
        """ updatePipeline(pipeline: Pipeline) -> None        
        Setup the pipeline to display and control a specific pipeline
        
        """
        self.pipelineView.scene().setupScene(pipeline)

    def updateWindowTitle(self, topLevel):
        """ updateWindowTitle(topLevel: bool) -> None
        Change the current widget title depends on the top level status
        
        """
        if topLevel:
            self.setWindowTitle('Pipeline <' +
                                self.toolWindow().parent().windowTitle()+'>')
        else:
            self.setWindowTitle('Pipeline')

    def moduleSelected(self, moduleId, selection = []):
        """ moduleChanged(moduleId: int, selection: [QGraphicsModuleItem])
                          -> None
        Set up the view when module selection has been changed
        
        """
        if self.pipelineView.scene().controller:
            pipeline = self.pipelineView.scene().controller.current_pipeline
        else:
            pipeline = None
        if pipeline and pipeline.modules.has_key(moduleId):
            module = pipeline.modules[moduleId]
            self.methodPalette.setEnabled(True)
            self.moduleMethods.setEnabled(True)
        else:
            module = None
            self.methodPalette.setEnabled(False)
            self.moduleMethods.setEnabled(False)
        self.methodPalette.setUpdatesEnabled(False)
        self.moduleMethods.setUpdatesEnabled(False)
        try:
            self.methodPalette.updateModule(module)
            self.moduleMethods.updateModule(module)
            self.emit(QtCore.SIGNAL('moduleSelectionChange'),
                      [m.id for m in selection])
        finally:
            self.methodPalette.setUpdatesEnabled(True)
            self.moduleMethods.setUpdatesEnabled(True)
             

    def setController(self, controller):
        """ setController(controller: VistrailController) -> None
        Assign a vistrail controller to this pipeline view
        
        """
        oldController = self.pipelineView.scene().controller
        if oldController!=controller:
            if oldController!=None:
                self.disconnect(oldController,
                                QtCore.SIGNAL('versionWasChanged'),
                                self.versionChanged)
                self.disconnect(oldController,
                                QtCore.SIGNAL('flushMoveActions()'),
                                self.flushMoveActions)
                oldController.current_pipeline_view = None
            self.controller = controller
            self.pipelineView.scene().controller = controller
            self.connect(controller,
                         QtCore.SIGNAL('versionWasChanged'),
                         self.versionChanged)
            self.connect(controller,
                         QtCore.SIGNAL('flushMoveActions()'),
                         self.flushMoveActions)
            self.methodPalette.controller = controller
            self.moduleMethods.controller = controller
            controller.current_pipeline_view = self.pipelineView.scene()

    def versionChanged(self, newVersion):
        """ versionChanged(newVersion: int) -> None        
        Update the pipeline when the new vistrail selected in the
        controller
        
        """
        self.updatePipeline(self.controller.current_pipeline)
            
    def flushMoveActions(self):
        """ flushMoveActions() -> None
        Update all move actions into vistrail
        
        """
        controller = self.pipelineView.scene().controller
        moves = []
        for (mId, item) in self.pipelineView.scene().modules.iteritems():
            module = controller.current_pipeline.modules[mId]
            (dx,dy) = (item.scenePos().x(), -item.scenePos().y())
            if (dx != module.center.x or dy != module.center.y):
                moves.append((mId, dx, dy))
        if len(moves)>0:
            controller.quiet = True
            controller.move_module_list(moves)
            controller.quiet = False

    def resetQuery(self):
        """ resetQuery() -> None
        pass along the signal

        """
        self.emit(QtCore.SIGNAL('resetQuery()'))
Example #34
0
def run_and_get_results(w_list,
                        parameters='',
                        workflow_info=None,
                        update_vistrail=True,
                        extra_info=None,
                        reason='Console Mode Execution'):
    """run_and_get_results(w_list: list of (locator, version), parameters: str,
                           workflow_info:str, update_vistrail: boolean,
                           extra_info:dict)
    Run all workflows in w_list, and returns an interpreter result object.
    version can be a tag name or a version id.
    
    """
    elements = parameters.split("$&$")
    aliases = {}
    result = []
    for locator, workflow in w_list:
        (v, abstractions, thumbnails, mashups) = load_vistrail(locator)
        controller = VistrailController(auto_save=update_vistrail)
        controller.set_vistrail(v, locator, abstractions, thumbnails, mashups)
        if type(workflow) == type("str"):
            version = v.get_version_number(workflow)
        elif type(workflow) in [type(1), long]:
            version = workflow
        elif workflow is None:
            version = controller.get_latest_version_in_graph()
        else:
            msg = "Invalid version tag or number: %s" % workflow
            raise VistrailsInternalError(msg)
        controller.change_selected_version(version)

        for e in elements:
            pos = e.find("=")
            if pos != -1:
                key = e[:pos].strip()
                value = e[pos + 1:].strip()

                if controller.current_pipeline.has_alias(key):
                    aliases[key] = value

        if workflow_info is not None and controller.current_pipeline is not None:
            if is_running_gui():
                from gui.pipeline_view import QPipelineView
                pipeline_view = QPipelineView()
                pipeline_view.scene().setupScene(controller.current_pipeline)
                base_fname = "%s_%s_pipeline.pdf" % (locator.short_name,
                                                     version)
                filename = os.path.join(workflow_info, base_fname)
                pipeline_view.scene().saveToPDF(filename)
                del pipeline_view
            else:
                debug.critical("Cannot save pipeline figure when not "
                               "running in gui mode")
            base_fname = "%s_%s_pipeline.xml" % (locator.short_name, version)
            filename = os.path.join(workflow_info, base_fname)
            core.db.io.save_workflow(controller.current_pipeline, filename)
        if not update_vistrail:
            conf = get_vistrails_configuration()
            if conf.has('thumbs'):
                conf.thumbs.autoSave = False

        (results, _) = \
            controller.execute_current_workflow(custom_aliases=aliases,
                                                extra_info=extra_info,
                                                reason=reason)
        new_version = controller.current_version
        if new_version != version:
            debug.warning("Version '%s' (%s) was upgraded. The actual "
                          "version executed was %s" % \
                              (workflow, version, new_version))
        run = results[0]
        run.workflow_info = (locator.name, new_version)
        run.pipeline = controller.current_pipeline

        if update_vistrail:
            controller.write_vistrail(locator)
        result.append(run)
    return result
Example #35
0
class QVisualDiff(QtGui.QMainWindow):
    """
    QVisualDiff is a main widget for Visual Diff containing a GL
    Widget to draw the pipeline
    
    """
    def __init__(self, vistrail, v1, v2,
                 controller,
                 parent=None, f=QtCore.Qt.WindowFlags()):
        """ QVisualDiff(vistrail: Vistrail, v1: str, v2: str,
                        parent: QWidget, f: WindowFlags) -> QVisualDiff
        Initialize with all
        
        """
        # Set up the version name correctly
        v1Name = vistrail.getVersionName(v1)
        if not v1Name: v1Name = 'Version %d' % v1
        v2Name = vistrail.getVersionName(v2)        
        if not v2Name: v2Name = 'Version %d' % v2
        
        # Actually perform the diff and store its result
        self.diff = vistrail.getPipelineDiff(v1, v2)

        self.v1_name = v1Name
        self.v2_name = v2Name
        self.v1 = v1
        self.v2 = v2
        self.controller = controller

        # Create the top-level Visual Diff window
        windowDecors = f | QtCore.Qt.Dialog |QtCore.Qt.WindowMaximizeButtonHint
        QtGui.QMainWindow.__init__(self, parent)
        self.setWindowTitle('Visual Diff - from %s to %s' % (v1Name, v2Name))
        self.setMouseTracking(True)
        self.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                                             QtGui.QSizePolicy.Expanding))
        self.createPipelineView()
        self.createToolBar()
        self.createToolWindows(v1Name, v2Name)

    def createPipelineView(self):
        """ createPipelineView() -> None        
        Create a center pipeline view for Visual Diff and setup the
        view based on the diff result self.diff
        
        """
        # Initialize the shape engine
        self.pipelineView = QPipelineView()
        self.setCentralWidget(self.pipelineView)

        # Add all the shapes into the view
        self.createDiffPipeline()

        # Hook shape selecting functions
        self.connect(self.pipelineView.scene(), QtCore.SIGNAL("moduleSelected"),
                     self.moduleSelected)

    def createToolBar(self):
        """ createToolBar() -> None        
        Create the default toolbar of Visual Diff window with two
        buttons to toggle the Parameter Inspector and Legend window
        
        """
        # Initialize the Visual Diff toolbar
        self.toolBar = self.addToolBar('Visual Diff Toolbar')
        self.toolBar.setMovable(False)

        # Add the Show Parameter Inspector action
        self.showInspectorAction = self.toolBar.addAction(
            CurrentTheme.VISUAL_DIFF_SHOW_PARAM_ICON,
            'Show Parameter Inspector window')
        self.showInspectorAction.setCheckable(True)
        self.connect(self.showInspectorAction, QtCore.SIGNAL("toggled(bool)"),
                     self.toggleShowInspector)
        
        # Add the Show Legend window action
        self.showLegendsAction = self.toolBar.addAction(
            CurrentTheme.VISUAL_DIFF_SHOW_LEGEND_ICON,
            'Show Legends')
        self.showLegendsAction.setCheckable(True)
        self.connect(self.showLegendsAction, QtCore.SIGNAL("toggled(bool)"),
                     self.toggleShowLegend)

        # Add the create analogy action
        self.createAnalogyAction = self.toolBar.addAction(
            CurrentTheme.VISUAL_DIFF_CREATE_ANALOGY_ICON,
            'Create analogy')
        self.connect(self.createAnalogyAction, QtCore.SIGNAL("triggered()"),
                     self.createAnalogy)

    def createAnalogy(self):
        default = 'from %s to %s' % (self.v1_name, self.v2_name)
        (result, ok) = QtGui.QInputDialog.getText(None, "Enter Analogy Name",
                                                  "Name of analogy:",
                                                  QtGui.QLineEdit.Normal,
                                                  default)
        if not ok:
            return
        result = str(result)
        try:
            self.controller.add_analogy(result, self.v1, self.v2)
        except:
            QtGui.QMessageBox.warning(self,
                                      QtCore.QString("Error"),
                                      QtCore.QString("Analogy name already exists"),
                                      QtGui.QMessageBox.Ok,
                                      QtGui.QMessageBox.NoButton,
                                      QtGui.QMessageBox.NoButton)
        
    def createToolWindows(self, v1Name, v2Name):
        """ createToolWindows(v1Name: str, v2Name: str) -> None
        Create Inspector and Legend window

        """
        self.inspector = QParamInspector(v1Name, v2Name, self)
        self.inspector.resize(QtCore.QSize(
            *CurrentTheme.VISUAL_DIFF_PARAMETER_WINDOW_SIZE))
        self.legendWindow = QLegendWindow(v1Name, v2Name,self)

    def moduleSelected(self, id, selectedItems):
        """ moduleSelected(id: int, selectedItems: [QGraphicsItem]) -> None
        When the user click on a module, display its parameter changes
        in the Inspector
        
        """
        if len(selectedItems)!=1 or id==-1:
            self.moduleUnselected()
            return
        
        # Interprete the diff result and setup item models
        (p1, p2, v1Andv2, v1Only, v2Only, paramChanged) = self.diff

        # Set the window title
        if id>self.maxId1:
            self.inspector.setWindowTitle('Parameter Changes - %s' %
                                          p2.modules[id-self.maxId1-1].name)
        else:
            self.inspector.setWindowTitle('Parameter Changes - %s' %
                                          p1.modules[id].name)
            
        # Clear the old inspector
        functions = self.inspector.functionsTab.model()
#         annotations = self.inspector.annotationsTab.model()
        functions.clearList()
#         annotations.clearList()

        # Find the parameter changed module
        matching = None
        for ((m1id, m2id), paramMatching) in paramChanged:
            if m1id==id:
                matching = paramMatching
                break

        # If the module has no parameter changed, just display nothing
        if not matching:          
            return
        
        # Else just layout the diff on a table
        functions.insertRows(0,len(matching))
        currentRow = 0
        for (f1, f2) in matching:
            if f1[0]!=None:
                functions.setData(
                    functions.index(currentRow, 0),
                    QtCore.QVariant('%s(%s)' % (f1[0],
                                                ','.join(v[1] for v in f1[1]))))
            if f2[0]!=None:
                functions.setData(
                    functions.index(currentRow, 1),
                    QtCore.QVariant('%s(%s)' % (f2[0],
                                                ','.join(v[1] for v in f2[1]))))
            if f1==f2:                
                functions.disableRow(currentRow)
            currentRow += 1

        self.inspector.functionsTab.resizeRowsToContents()
#         self.inspector.annotationsTab.resizeRowsToContents()

    def moduleUnselected(self):
        """ moduleUnselected() -> None
        When a user selects nothing, make sure to display nothing as well
        
        """
#         self.inspector.annotationsTab.model().clearList()
        self.inspector.functionsTab.model().clearList()
        self.inspector.setWindowTitle('Parameter Changes - None')

    def toggleShowInspector(self):
        """ toggleShowInspector() -> None
        Show/Hide the inspector when toggle this button
        
        """
        if self.inspector.firstTime:
            max_geom = QtGui.QApplication.desktop().screenGeometry(self)
            if (self.frameSize().width() <
                max_geom.width() - self.inspector.width()):
                self.inspector.move(self.pos().x()+self.frameSize().width(),
                                    self.pos().y())
            else:
                self.inspector.move(self.pos().x()+self.frameSize().width()-
                                   self.inspector.frameSize().width(),
                                   self.pos().y() +
                                    self.legendWindow.frameSize().height())
            self.inspector.firstTime = False
        self.inspector.setVisible(self.showInspectorAction.isChecked())
            
    def toggleShowLegend(self):
        """ toggleShowLegend() -> None
        Show/Hide the legend window when toggle this button
        
        """
        if self.legendWindow.firstTime:
            self.legendWindow.move(self.pos().x()+self.frameSize().width()-
                                   self.legendWindow.frameSize().width(),
                                   self.pos().y())
        self.legendWindow.setVisible(self.showLegendsAction.isChecked())
        if self.legendWindow.firstTime:
            self.legendWindow.firstTime = False
            self.legendWindow.setFixedSize(self.legendWindow.size())            
                
    def createDiffPipeline(self):
        """ createDiffPipeline() -> None        
        Actually walk through the self.diff result and add all modules
        into the pipeline view
        
        """

        # Interprete the diff result
        (p1, p2, v1Andv2, v1Only, v2Only, paramChanged) = self.diff
        p1.ensure_connection_specs()
        p2.ensure_connection_specs()
        p_both = Pipeline()
        # the abstraction map is the same for both p1 and p2
        p_both.set_abstraction_map(p1.abstraction_map)
        
        scene = self.pipelineView.scene()
        scene.clearItems()

        # FIXME HACK: We will create a dummy object that looks like a
        # controller so that the qgraphicsmoduleitems and the scene
        # are happy. It will simply store the pipeline will all
        # modules and connections of the diff, and know how to copy stuff
        class DummyController(object):
            def __init__(self, pip):
                self.current_pipeline = pip
                self.search = None
            def copy_modules_and_connections(self, module_ids, connection_ids):
                """copy_modules_and_connections(module_ids: [long],
                                             connection_ids: [long]) -> str
                Serializes a list of modules and connections
                """

                pipeline = Pipeline()
                pipeline.set_abstraction_map( \
                    self.current_pipeline.abstraction_map)
                for module_id in module_ids:
                    module = self.current_pipeline.modules[module_id]
                    if module.vtType == AbstractionModule.vtType:
                        abstraction = \
                            pipeline.abstraction_map[module.abstraction_id]
                        pipeline.add_abstraction(abstraction)
                    pipeline.add_module(module)
                for connection_id in connection_ids:
                    connection = self.current_pipeline.connections[connection_id]
                    pipeline.add_connection(connection)
                return core.db.io.serialize(pipeline)
                
        controller = DummyController(p_both)
        scene.controller = controller

        # Find the max version id from v1 and start the adding process
        self.maxId1 = 0
        for m1id in p1.modules.keys():
            if m1id>self.maxId1:
                self.maxId1 = m1id
        shiftId = self.maxId1 + 1

        # First add all shared modules, just use v1 module id
        for (m1id, m2id) in v1Andv2:
            item = scene.addModule(p1.modules[m1id],
                                   CurrentTheme.VISUAL_DIFF_SHARED_BRUSH)
            item.controller = controller
            p_both.add_module(copy.copy(p1.modules[m1id]))
            
        # Then add parameter changed version
        for ((m1id, m2id), matching) in paramChanged:
            m1 = p1.modules[m1id]
            m2 = p2.modules[m2id]
            
            #this is a hack for modules with a dynamic local registry.
            #The problem arises when modules have the same name but different
            #input/output ports. We just make sure that the module we add to
            # the canvas has the ports from both modules, so we don't have
            # addconnection errors.
            if m1.registry:
                m1ports = m1.port_specs.itervalues()
                ports = {}
                for p in m1.port_specs.itervalues():
                    ports[p.name] = p
                for port in m2.port_specs.itervalues():
                    if not ports.has_key(port.name):
                        m1.add_port_to_registry(port)
                    else:
                        if ports[port.name].spec != port.spec:
                            #if we add this port, we will get port overloading.
                            #To avoid this, just cast the current port to be of
                            # Module or Variant type.
                            new_port = ports[port.name]
                            m1.delete_port_from_registry(new_port.id)
                            if new_port.type == 'input':
                                new_port.spec = "(Module)"
                            else:
                                new_port.spec = "(Variant)"
                            m1.add_port_to_registry(new_port)
                            
            item = scene.addModule(p1.modules[m1id],
                                   CurrentTheme.VISUAL_DIFF_PARAMETER_CHANGED_BRUSH)
            item.controller = controller
            p_both.add_module(copy.copy(p1.modules[m1id]))

        # Now add the ones only applicable for v1, still using v1 ids
        for m1id in v1Only:
            item = scene.addModule(p1.modules[m1id],
                                   CurrentTheme.VISUAL_DIFF_FROM_VERSION_BRUSH)
            item.controller = controller
            p_both.add_module(copy.copy(p1.modules[m1id]))

        # Now add the ones for v2 only but must shift the ids away from v1
        for m2id in v2Only:
            p2.modules[m2id].id = m2id + shiftId
            item = scene.addModule(p2.modules[m2id],
                                   CurrentTheme.VISUAL_DIFF_TO_VERSION_BRUSH)
            item.controller = controller
            p_both.add_module(copy.copy(p2.modules[m2id]))

        # Create a mapping between share modules between v1 and v2
        v1Tov2 = {}
        v2Tov1 = {}
        for (m1id, m2id) in v1Andv2:
            v1Tov2[m1id] = m2id
            v2Tov1[m2id] = m1id
        for ((m1id, m2id), matching) in paramChanged:
            v1Tov2[m1id] = m2id
            v2Tov1[m2id] = m1id

        # Next we're going to add connections, only connections of
        # v2Only need to shift their ids
        if p1.connections.keys():
            connectionShift = max(p1.connections.keys())+1
        else:
            connectionShift = 0
        allConnections = copy.copy(p1.connections)
        sharedConnections = []
        v2OnlyConnections = []        
        for (cid2, connection2) in copy.copy(p2.connections.items()):
            if connection2.sourceId in v2Only:
                connection2.sourceId += shiftId
            else:
                connection2.sourceId = v2Tov1[connection2.sourceId]
                
            if connection2.destinationId in v2Only:
                connection2.destinationId += shiftId
            else:
                connection2.destinationId = v2Tov1[connection2.destinationId]

            # Is this connection also shared by p1?
            shared = False
            for (cid1, connection1) in p1.connections.items():
                if (connection1.sourceId==connection2.sourceId and
                    connection1.destinationId==connection2.destinationId and
                    connection1.source.name==connection2.source.name and
                    connection1.destination.name==connection2.destination.name):
                    sharedConnections.append(cid1)
                    shared = True
                    break
            if not shared:
                allConnections[cid2+connectionShift] = connection2
                connection2.id = cid2+connectionShift
                v2OnlyConnections.append(cid2+connectionShift)

        connectionItems = []
        for c in allConnections.values():
            p_both.add_connection(copy.copy(c))
            connectionItems.append(scene.addConnection(c))

        # Color Code connections
        for c in connectionItems:
            if c.id in sharedConnections:
                pass
            elif c.id in v2OnlyConnections:
                pen = QtGui.QPen(CurrentTheme.CONNECTION_PEN)
                pen.setBrush(CurrentTheme.VISUAL_DIFF_TO_VERSION_BRUSH)
                c.connectionPen = pen
            else:
                pen = QtGui.QPen(CurrentTheme.CONNECTION_PEN)
                pen.setBrush(CurrentTheme.VISUAL_DIFF_FROM_VERSION_BRUSH)
                c.connectionPen = pen

       

        scene.updateSceneBoundingRect()
        scene.fitToView(self.pipelineView, True)