def test(argv): # Create graph widget app = QtWidgets.QApplication(argv) graph = GraphWidget(None) graph.ast = ASTModel.get_ast(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../../apps/simple/simple.camkes")) print ASTModel.find_instance(graph.ast.assembly.instances, "echo") is not None # find_component is not being tested because it is not used anywhere. However # there is no reason why find_component will fail to work, if everything else worked. print "visualCAmkES test passed" return 0
def open_ast(self, path_to_file, import_paths=None): """ Opens the given camkes file. Deals with the drawing. Shows an error if a CAmkES Error occurs :param path_to_file: The path to the camkes file. A string such as "/home/bob/camkes/app/kitty/kitty.camkes :return """ assert isinstance(path_to_file, six.string_types) # Checks to see if path is not empty if len(path_to_file) > 1: try: # Set the AST of GraphWidget self.root_widget.ast = ASTModel.get_ast( path_to_file, import_paths) except CAmkESError as error: # If error occurred # For terminal users: print "Error occurred when opening the file... please refer to the following error" print error # Show Error as a message popup messageBox = QtWidgets.QMessageBox() messageBox.setText("Syntax Error") # Convert all ANSI codes to HTML conv = Ansi2HTMLConverter(inline=True, dark_bg=False) html = conv.convert(str(error), full=False) html = html.replace('\n', '<br/>').replace('^', '') messageBox.setInformativeText( '<p style="font-family: monospace;"> %s </p>' % html) messageBox.exec_() else: # If no error, AST would have been successfully set. Change Window Title to name of file. # find last / (or last \ in windows) start_of_filename = path_to_file.rfind("/") if start_of_filename == -1: # Might be a windows machine start_of_filename = path_to_file.rfind('\\') if start_of_filename == -1: # If still not found, assume its just the name of the file. start_of_filename = 0 else: start_of_filename += 1 self.setWindowTitle( path_to_file[start_of_filename:path_to_file.rfind('.')])
def open_ast(self, path_to_file, import_paths=None): """ Opens the given camkes file. Deals with the drawing. Shows an error if a CAmkES Error occurs :param path_to_file: The path to the camkes file. A string such as "/home/bob/camkes/app/kitty/kitty.camkes :return """ assert isinstance(path_to_file, six.string_types) # Checks to see if path is not empty if len(path_to_file) > 1: try: # Set the AST of GraphWidget self.root_widget.ast = ASTModel.get_ast(path_to_file, import_paths) except CAmkESError as error: # If error occurred # For terminal users: print "Error occurred when opening the file... please refer to the following error" print error # Show Error as a message popup messageBox = QtWidgets.QMessageBox() messageBox.setText("Syntax Error") # Convert all ANSI codes to HTML conv = Ansi2HTMLConverter(inline=True, dark_bg=False) html = conv.convert(str(error), full=False) html = html.replace('\n', '<br/>').replace('^','') messageBox.setInformativeText('<p style="font-family: monospace;"> %s </p>' % html) messageBox.exec_() else: # If no error, AST would have been successfully set. Change Window Title to name of file. # find last / (or last \ in windows) start_of_filename = path_to_file.rfind("/") if start_of_filename == -1: # Might be a windows machine start_of_filename = path_to_file.rfind('\\') if start_of_filename == -1: # If still not found, assume its just the name of the file. start_of_filename = 0 else: start_of_filename += 1 self.setWindowTitle(path_to_file[start_of_filename:path_to_file.rfind('.')])
def sync_model(self): """ Updates view to the model representation """ # Get assembly from the ast ast_assembly = self.ast.assembly assert isinstance(ast_assembly, Assembly) # --- For each instance, create a node in the graph & a widget. --- instance_list_copy = list(ast_assembly.instances) widgets_to_remove = [] # Update widget's instance object counterpart for widget in self.widget_instances: assert isinstance(widget, InstanceWidget) new_instance_object = ASTModel.find_instance(instance_list_copy, widget.name) if new_instance_object is not None: # If found, replace widget's local copy self.sync_instance(new_instance_object, widget) instance_list_copy.remove(new_instance_object) else: # Instance object for widget not found, probably deleted - so widget not necessary widgets_to_remove.append(widget) # Delete the widget (since it is not possible to delete the widget during iteration) for widget in widgets_to_remove: self.remove_instance_widget(widget) for instance in instance_list_copy: # For all new instances (instances without widget counterpart) # Make a new widget assert isinstance(instance, Instance) new_widget = InstanceWidget(self.context_menu) new_widget.color = self.random_color_generator() self.sync_instance(instance, new_widget) new_widget.widget_moved.connect(self.update_view) # Add to internal list of widgets self.widget_instances.append(new_widget) # Add to scene self.reposition_instance_widget(new_widget, 0, 0) self.clear_connection_widgets() # Create connection widgets for all connections in assembly # Instead of syncing connections, ConnectionWidgets are considered disposable. Just delete all and remake them assert isinstance(self.ast.assembly, Assembly) for connection in self.ast.assembly.connections: assert isinstance(connection, Connection) for from_instance_end in connection.from_ends: assert isinstance(from_instance_end, ConnectionEnd) from_instance = from_instance_end.instance assert isinstance(from_instance, Instance) for to_instance_end in connection.to_ends: assert isinstance(to_instance_end, ConnectionEnd) to_instance = to_instance_end.instance assert isinstance(to_instance, Instance) new_connection_widget = self.create_connection_widget(connection, from_instance.name, from_instance_end.interface.name, to_instance.name, to_instance_end.interface.name) self.connection_widgets.append(new_connection_widget) self.add_connection_widget(new_connection_widget)