示例#1
0
    def __on_save(self, widget=None, data=None):
        new_port = Port()
        for widget in self.side_panel.get_children():
            try:
                new_port.__dict__[widget.get_name()] = widget.get_value()
            except:
                pass

        if new_port.type == "":
            message = "Type can not be empty"
            MessageDialog("Error", message, self.get_toplevel()).run()
            return
        if new_port.label == "":
            message = "Label can not be empty"
            MessageDialog("Error", message, self.get_toplevel()).run()
            return
        if new_port.name == "":
            message = "Name can not be empty"
            MessageDialog("Error", message, self.get_toplevel()).run()
            return
        contains = False
        i = 0
        for port in self.block.ports:
            if port.label == new_port.label:
                self.block.ports[i] = new_port
                contains = True
            i += 1
        if not contains:
            self.block.ports.append(new_port)
        self.__populate_list()
        self.__clean_side_panel()
示例#2
0
 def __on_props_edit_ok(self, widget=None, data=None):
     configuration = {}
     for widget in self.side_panel.get_children():
         try:
             configuration[widget.get_name()] = widget.get_value()
         except:
             pass
     if "label" not in configuration or "name" not in configuration or \
             "value" not in configuration:
         return
     if configuration["label"] == "":
         message = "Label can not be empty"
         MessageDialog("Error", message, self.get_toplevel()).run()
         return
     if configuration["name"] == "":
         message = "Name can not be empty"
         MessageDialog("Error", message, self.get_toplevel()).run()
         return
     contains = False
     i = 0
     for props in self.element.properties:
         if props["label"] == configuration["label"]:
             self.element.properties[i] = configuration
             contains = True
         i += 1
     if not contains:
         self.element.properties.append(configuration)
     self.__populate_property()
     self.__clean_side_panel()
示例#3
0
 def delete_port(self, port_key):
     result = PortControl.delete_port(port_key)
     if not result[0]:
         self.message_dialog = MessageDialog("Error", result[1],
                                             self.main_window)
         self.message_dialog.run()
     System.reload()
示例#4
0
 def delete_extension(self, element, element_type):
     if isinstance(element_type, Port):
         if not PortControl.delete_port(element):
             message = "This port is a python file installed in the System.\n"
             message = message + "Sorry, you can't remove it"
             MessageDialog("Error", message, self.main_window).run()
             return False
         System.reload()
     elif isinstance(element_type, CodeTemplate):
         filename = CodeTemplateControl.delete_code_template(element)
         if not filename:
             message = "This code template does not exist."
             MessageDialog("Error", message, self.main_window).run()
             return False
         if filename is None:
             message = "This code template is a python file installed in the System.\n"
             message = message + "Sorry, you can't remove it"
             MessageDialog("Error", message, self.main_window).run()
             return False
         System.reload()
         return True
     elif isinstance(element_type, BlockModel):
         if not BlockControl.delete_block(element):
             message = "This block is a python file installed in the System.\n"
             message = message + "Sorry, you can't remove it"
             MessageDialog("Error", message, self.main_window).run()
             return False
         self.update_blocks()
     MessageDialog("Info", str(element) + " deleted.", self.main_window).run()
     return True
示例#5
0
    def __get_code_generator(self, diagram):

        if diagram.language is None:
            message = "You shall not generate the code of an empty diagram!"
            MessageDialog("Error", message, self.main_window).run()
            return None

        if diagram.code_template is not None:
            return CodeGenerator(diagram)

        template_list = []
        code_templates = System.get_code_templates()

        for key in code_templates:
            if code_templates[key].language == diagram.language:
                template_list.append(code_templates[key])

        if len(template_list) == 0:
            message = "Generator not available for the language " + diagram.language + "."
            MessageDialog("Error", message, self.main_window).run()
            return None

        if len(template_list) == 1:
            diagram.code_template = deepcopy(template_list[0])
            return CodeGenerator(diagram)

        select = SelectCodeTemplate(self.main_window, template_list)
        diagram.code_template = deepcopy(select.get_value())
        return CodeGenerator(diagram)
示例#6
0
 def delete_block(self, block):
     result = BlockControl.delete_block(block)
     if not result[0]:
         self.message_dialog = MessageDialog("Error", result[1],
                                             self.main_window)
         self.message_dialog.run()
     self.update_blocks()
示例#7
0
 def save_source(self, codes=None, generator=None):
     """
     This method saves the source codes.
     """
     diagram = self.get_current_diagram()
     result, msg = CodeGenerator.save_source(diagram=diagram,
                                             codes=codes,
                                             generator=generator)
     if not result:
         self.message_dialog = MessageDialog("Error", msg, self.main_window)
         self.message_dialog.run()
 def test_constructor(self):
     self.dialog = MessageDialog("Test Message Dialog", "Test",
                                 self.create_main_window())
     t1 = threading.Thread(target=self.dialog.run, args=())
     t1.start()
     sleep(1)
     self.dialog.response(Gtk.ResponseType.OK)
     self.refresh_gui()
     t1.join()
     self.dialog.close()
     self.dialog.destroy()
示例#9
0
 def delete_code_template(self, code_template_name):
     result = CodeTemplateControl.delete_code_template(code_template_name)
     if not result[0]:
         self.message_dialog = MessageDialog("Error", result[1],
                                             self.main_window)
         self.message_dialog.run()
         return False
     self.message_dialog = MessageDialog("Info", result[1],
                                         self.main_window)
     self.message_dialog.run()
     System.reload()
     return True
示例#10
0
 def open(self, file_name):
     """
     This method open a file.
     """
     diagram = Diagram(self.main_window)
     result = DiagramControl(diagram).load(file_name)
     if result[0] is None:
         self.message_dialog = MessageDialog("Error", result[1],
                                             self.main_window)
         self.message_dialog.run()
         return
     diagram = result[0]
     System.add_recent_files(file_name)
示例#11
0
 def delete_code_template(self, code_template_name):
     filename = CodeTemplateControl.delete_code_template(code_template_name)
     if not filename:
         message = "This code template does not exist."
         MessageDialog("Error", message, self.main_window).run()
         return False
     if filename is None:
         message = "This code template is a python file installed in the System.\n"
         message = message + "Sorry, you can't remove it"
         MessageDialog("Error", message, self.main_window).run()
         return False
     MessageDialog("Info", "File " + filename + " deleted.",
                   self.main_window).run()
     System.reload()
     return True
示例#12
0
 def view_source(self):
     """
     This method view the source code.
     """
     diagram = self.get_current_diagram()
     generator, msg = CodeGenerator.get_code_generator(diagram)
     if generator is not None:
         codes = generator.generate_code()
         self.code_window = CodeWindow(self.main_window, codes)
         self.code_window.run()
         self.code_window.close()
         self.code_window.destroy()
     else:
         self.message_dialog = MessageDialog("Error", msg, self.main_window)
         self.message_dialog.run()
示例#13
0
    def export_diagram(self):
        """
        This method exports the diagram.
        """
        diagram = self.main_window.work_area.get_current_diagram()
        if diagram is None:
            return False

        while True:
            name = SaveDialog(self.main_window,
                              title=_("Export diagram as png"),
                              filename=System.get_user_dir() + "/" +
                              diagram.file_name + ".png",
                              filetype="png").run()

            if name is None:
                return
            if name.find(".png") == -1:
                name = name + ".png"
            if name is not None and os.path.exists(name) is True:
                msg = _("File exists. Overwrite?")
                result = ConfirmDialog(msg, self.main_window).run()
                if result == Gtk.ResponseType.OK:
                    break

        result, message = DiagramControl(diagram).export_png(name)

        if not result:
            MessageDialog("Error", message, self.main_window).run()
 def export_xml_dialog(self):
     self.export_xml()
     MessageDialog(
             "Exporting as xml",
             "Exported successfully!",
             self.main_window
             ).run()
示例#15
0
    def add_block(self, block):
        """
        This method add a block.

        Parameters:

                * **Types** (:class:`block<>`)
        Returns:

            * **Types** (:class:`boolean<boolean>`)
        """
        diagram = self.main_window.work_area.get_current_diagram()
        if diagram is None:
            return False
        new_block = BlockModel(block)
        new_block = deepcopy(new_block)
        new_block = Block(diagram, new_block)
        if not DiagramControl(diagram).add_block(new_block):
            message = "Block language is different from diagram language.\n" +\
                "Diagram is expecting to generate " + diagram.language + \
                " code while block is writen in " + block.language
            MessageDialog("Error", message, self.main_window).run()
            return None
        diagram.redraw()
        return new_block
示例#16
0
    def add_block(self, block):
        """
        This method add a block.

        Parameters:

                * **Types** (:class:`block<>`)
        Returns:

            * **Types** (:class:`boolean<boolean>`)
        """
        result = DiagramControl(self.get_current_diagram()).add_block(block)
        if not result[0]:
            message = result[1]
            self.message_dialog = MessageDialog("Error", message,
                                                self.main_window)
            self.message_dialog.run()
            return None
        return block
示例#17
0
 def __add_code_part(self, widget=None, data=None):
     name = ""
     code = ""
     for widget in self.side_panel.get_children():
         if widget.get_name() == "name":
             name = widget.get_value()
         if widget.get_name() == "code":
             code = widget.get_value()
     if name == "":
         message = "File Name can not be empty"
         MessageDialog("Error", message, self).run()
         return
     if code == "":
         message = "Code can not be empty"
         MessageDialog("Error", message, self).run()
         return
     contains = False
     i = 0
     self.codes[name] = code
     self.__populate_list()
     self.__clean_side_panel()
示例#18
0
    def save(self, save_as=False):
        """
        This method save the file.
        """
        diagram = self.get_current_diagram()
        if diagram is None:
            return False

        if diagram.file_name is "Untitled" or save_as:
            result, message = self.__select_save(diagram)
            if not result:
                return False

        result, message = DiagramControl(diagram).save()
        if not result:
            self.message_dialog = MessageDialog("Error", message,
                                                self.main_window)
            self.message_dialog.run()
            return False
        System.add_recent_files(diagram.file_name)
        self.main_window.work_area.rename_diagram(diagram)
        return True
示例#19
0
 def import_extensions(self):
     import urllib.request
     url = "https://alice.dcomp.ufsj.edu.br/mosaicode/extensions/"
     resource_file = url + "resource.txt"
     # download and read resource list
     for line in urllib.request.urlopen(resource_file):
         file_name = line.decode('utf-8')
         # download zip file
         file_path = os.path.join(System.get_user_dir(), file_name)
         urllib.request.urlretrieve(url + file_name, file_path)
         # extract it
         zip_file = zipfile.ZipFile(file_path, 'r')
         destination = os.path.join(System.get_user_dir(), "extensions")
         zip_file.extractall(destination)            
     MessageDialog(
             "Success",
              "Extensions imported successfully!",
              self.main_window).run()
     System.reload()
示例#20
0
    def save(self, save_as=False):
        """
        This method save the file.
        """
        diagram = self.main_window.work_area.get_current_diagram()
        if diagram is None:
            return False

        if diagram.file_name == "Untitled" or save_as:
            while True:
                dialog = SaveDialog(
                    self.main_window,
                    title=_("Save Diagram"),
                    filename=System.get_user_dir() + "/" + diagram.patch_name,
                    filetype="*.mscd")
                name = dialog.run()
                if name is None:
                    System.log("File not saved")
                    return

                if not name.endswith("mscd"):
                    name = (("%s" + ".mscd") % name)

                if os.path.exists(name) is True:
                    msg = _("File exists. Overwrite?")
                    result = ConfirmDialog(msg, self.main_window).run()
                    if result == Gtk.ResponseType.CANCEL:
                        continue

                diagram.file_name = name
                self.main_window.work_area.rename_diagram(diagram)
                break
        result, message = False, ""

        if diagram.file_name is not None:
            if len(diagram.file_name) > 0:
                result, message = DiagramControl(diagram).save()
                self.set_recent_files(diagram.file_name)

        if not result:
            MessageDialog("Error", message, self.main_window).run()
示例#21
0
 def delete_block(self, block):
     if not BlockControl.delete_block(block):
         message = "This block is a python file installed in the System.\n"
         message = message + "Sorry, you can't remove it"
         MessageDialog("Error", message, self.main_window).run()
     self.update_blocks()
示例#22
0
 def delete_port(self, port_key):
     if not PortControl.delete_port(port_key):
         message = "This port is a python file installed in the System.\n"
         message = message + "Sorry, you can't remove it"
         MessageDialog("Error", message, self.main_window).run()
     System.reload()
示例#23
0
    def export_extensions(self):
    
        from mosaicode.system import System as System
        System()

        result = True
        folder = "extension-" + datetime.datetime.now().strftime("%Y-%m-%d")

        # Export ports
        ports = System.get_ports()
        for key in ports:
            path = System.get_user_dir()
            path = os.path.join(path, folder, ports[key].language, 'ports')
            result = result and PortPersistence.save(ports[key], path)
        # Export Blocks
        blocks = System.get_blocks()
        result = True
        for key in blocks:
            path = System.get_user_dir()
            path = os.path.join(path,
                                folder,
                                blocks[key].language,
                                'blocks',
                                blocks[key].extension,
                                blocks[key].group)
            result = result and BlockPersistence.save(blocks[key], path)
        # Export Code Templates
        code_templates = System.get_code_templates()
        result = True
        for key in code_templates:
            path = System.get_user_dir()
            path = os.path.join(path,
                                folder,
                                code_templates[key].language,
                                'codetemplates')
            result = result and CodeTemplatePersistence.save(
                    code_templates[key], path)
        # Export examples
        path = System.get_user_dir()
        path = os.path.join(path, "extensions")
        examples = System.get_examples()
        for example in examples:
            relpath = os.path.relpath(example, path)
            path = System.get_user_dir()
            path = os.path.join(path, folder, relpath)
            os.makedirs(os.path.dirname(path), exist_ok=True)
            shutil.copy2(example, path)

        # Create a zip file to the extension
        path = System.get_user_dir()
        path = os.path.join(path, folder+".zip")
        zip_file = zipfile.ZipFile(path, 'w')

        path = System.get_user_dir()
        path = os.path.join(path, folder)

        for folderName, subfolders, filenames in os.walk(path):
            for filename in filenames:
                filePath = os.path.join(folderName, filename)
                #create complete filepath of file in directory
                # Add file to zip
                zip_file.write(filePath, os.path.relpath(filePath, path))
        zip_file.close()

        path = System.get_user_dir()
        path = os.path.join(path, folder)
        shutil.rmtree(path)

        # create a publish file
        filename = "resource.txt"
        path = System.get_user_dir()
        path = os.path.join(path, filename)
        f = open(path, "w")
        f.write(folder + ".zip")
        f.close()

        if result:
            MessageDialog(
                    "Success",
                     "File " + folder + ".zip created successfully!",
                     self.main_window).run()
        else:
            MessageDialog(
                    "Error",
                    "Could not export extension",
                    self.main_window).run()
        return result
示例#24
0
class MainControl():
    """
    This class contains methods related the MainControl class.
    """

    # ----------------------------------------------------------------------

    def __init__(self, main_window):
        self.main_window = main_window
        self.open_dialog = None
        self.save_dialog = None
        self.confirm_dialog = None
        self.preference_window = None
        self.message_dialog = None
        self.about_window = None
        self.code_window = None

        # Clipboard is here because It must be possible to exchange data between diagrams
        self.clipboard = []
        self.threads = {}
        self.publisher = Publisher()

    # ----------------------------------------------------------------------
    def init(self):
        self.update_blocks()
        # Load plugins
        for plugin in System.get_plugins():
            plugin.load(self.main_window)

        self.main_window.menu.update_recent_files()
        self.main_window.menu.update_examples()

    # ----------------------------------------------------------------------
    def get_current_diagram(self):
        return self.main_window.work_area.get_current_diagram()

    # ----------------------------------------------------------------------
    def update_blocks(self):
        System.reload()
        self.main_window.menu.update_blocks()
        self.main_window.block_notebook.update_blocks()

    # ----------------------------------------------------------------------
    def new(self):
        """
        This method create a new the diagram file.
        """
        Diagram(self.main_window)

    # ----------------------------------------------------------------------
    def select_open(self, path=None):
        """
        This method open a selected file.
        """
        if path is None:
            path = System.get_user_dir()
        self.open_dialog = OpenDialog("Open Diagram",
                                      self.main_window,
                                      filetype="mscd",
                                      path=path)
        file_name = self.open_dialog.run()
        if file_name is None or file_name == "":
            return
        self.open(file_name)

    # ----------------------------------------------------------------------
    def open(self, file_name):
        """
        This method open a file.
        """
        diagram = Diagram(self.main_window)
        result = DiagramControl(diagram).load(file_name)
        if result[0] is None:
            self.message_dialog = MessageDialog("Error", result[1],
                                                self.main_window)
            self.message_dialog.run()
            return
        diagram = result[0]
        System.add_recent_files(file_name)

    # ----------------------------------------------------------------------
    def close(self):
        """
        This method closes a tab on the work area.
        """
        self.main_window.work_area.close_tab()

    # ----------------------------------------------------------------------
    def __select_save(self, diagram):
        """
        This method selects a name to save the file.
        """
        while True:
            file_name = diagram.file_name
            if file_name == "Untitled":
                file_name = System.get_user_dir() + "/" + diagram.file_name
            self.save_dialog = SaveDialog(self.main_window,
                                          title=_("Save Diagram"),
                                          filename=file_name,
                                          filetype="*.mscd")
            name = self.save_dialog.run()
            if name is None:
                return False, "User canceled the operation"

            if os.path.exists(name) is True:
                msg = _("File exists. Overwrite?")
                self.confirm_dialog = ConfirmDialog(msg, self.main_window)
                result = self.confirm_dialog.run()
                if result == Gtk.ResponseType.CANCEL:
                    continue
            if not name.endswith("mscd"):
                name = name + ".mscd"
            diagram.file_name = name
            break
        return True, "Success"

    # ----------------------------------------------------------------------
    def save(self, save_as=False):
        """
        This method save the file.
        """
        diagram = self.get_current_diagram()
        if diagram is None:
            return False

        if diagram.file_name is "Untitled" or save_as:
            result, message = self.__select_save(diagram)
            if not result:
                return False

        result, message = DiagramControl(diagram).save()
        if not result:
            self.message_dialog = MessageDialog("Error", message,
                                                self.main_window)
            self.message_dialog.run()
            return False
        System.add_recent_files(diagram.file_name)
        self.main_window.work_area.rename_diagram(diagram)
        return True

    # ----------------------------------------------------------------------
    def save_as(self):
        """
        This method save as.
        """
        self.save(save_as=True)

    # ----------------------------------------------------------------------
    def exit(self, widget=None, data=None):
        """
        This method close main window.

        Returns:

            * **Types** (:class:`boolean<boolean>`)
        """
        PreferencesPersistence.save(System.get_preferences(),
                                    System.get_user_dir())
        if self.main_window.work_area.close_tabs():
            Gtk.main_quit()
        else:
            return True

    # ----------------------------------------------------------------------
    def add_recent_files(self, file_name):
        System.add_recent_files(file_name)
        self.main_window.menu.update_recent_files()
        PreferencesPersistence.save(System.get_preferences(),
                                    System.get_user_dir())

    # ----------------------------------------------------------------------

    def get_clipboard(self):
        """
        This method return the clipboard.
        """
        return self.clipboard

    # ----------------------------------------------------------------------
    def reset_clipboard(self):
        """
        This method clear the clipboard.
        """
        self.clipboard = []

    # ----------------------------------------------------------------------
    def preferences(self):
        """
        """
        self.preference_window = PreferenceWindow(self.main_window)
        self.preference_window.run()

    # ----------------------------------------------------------------------
    def save_source(self, codes=None, generator=None):
        """
        This method saves the source codes.
        """
        diagram = self.get_current_diagram()
        result, msg = CodeGenerator.save_source(diagram=diagram,
                                                codes=codes,
                                                generator=generator)
        if not result:
            self.message_dialog = MessageDialog("Error", msg, self.main_window)
            self.message_dialog.run()

    # ----------------------------------------------------------------------
    def view_source(self):
        """
        This method view the source code.
        """
        diagram = self.get_current_diagram()
        generator, msg = CodeGenerator.get_code_generator(diagram)
        if generator is not None:
            codes = generator.generate_code()
            self.code_window = CodeWindow(self.main_window, codes)
            self.code_window.run()
            self.code_window.close()
            self.code_window.destroy()
        else:
            self.message_dialog = MessageDialog("Error", msg, self.main_window)
            self.message_dialog.run()

    # ----------------------------------------------------------------------
    def run(self, codes=None):
        """
        This method runs the code.
        """
        diagram = self.get_current_diagram()
        generator, message = CodeGenerator.get_code_generator(diagram)
        if generator is None:
            return False

        self.save_source(codes=codes, generator=generator)

        command = diagram.code_template.command
        command = command.replace("$dir_name$", System.get_dir_name(diagram))

        def __run(self):
            process = subprocess.Popen(command,
                                       cwd=System.get_dir_name(diagram),
                                       shell=True,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE,
                                       preexec_fn=os.setsid)
            self.threads[thread] = diagram, process
            self.main_window.toolbar.update_threads(self.threads)
            (stdout_data, stderr_data) = process.communicate()
            System.log(stdout_data + "\n")
            System.log(stderr_data + "\n")
            del self.threads[thread]
            self.main_window.toolbar.update_threads(self.threads)

        System.log("Executing Code:\n" + command)
        thread = Thread(target=__run, args=(self, ))
        thread.start()

        return True

    # ----------------------------------------------------------------------
    def stop(self, widget, process):
        if process is None:
            return
        pgid = os.getpgid(process.pid)
        os.killpg(pgid, signal.SIGTERM)

    # ----------------------------------------------------------------------
    def publish(self):
        """
        This method run web server.
        """
        if self.publisher.is_running():
            self.publisher.stop()
        else:
            self.publisher.start()

    # ----------------------------------------------------------------------
    def about(self):
        """
        This method open the about window.
        """
        self.about_window = About(self.main_window)
        self.about_window.show_all()

    # ----------------------------------------------------------------------
    def search(self, query):
        """
        This method search the query in the blocks_tree_view.
        """
        self.main_window.block_notebook.search(query)

    # ----------------------------------------------------------------------
    def set_block(self, block):
        """
        This method set the block properties.
        """
        self.main_window.property_box.set_block(block)

    # ----------------------------------------------------------------------
    def get_selected_block(self):
        """
        This method get the tree view block.
        """
        return self.main_window.block_notebook.get_selected_block()

    # ----------------------------------------------------------------------
    def clear_console(self):
        """
        This method clear the console.
        """
        self.main_window.status.clear()

    # ----------------------------------------------------------------------
    def add_block(self, block):
        """
        This method add a block.

        Parameters:

                * **Types** (:class:`block<>`)
        Returns:

            * **Types** (:class:`boolean<boolean>`)
        """
        result = DiagramControl(self.get_current_diagram()).add_block(block)
        if not result[0]:
            message = result[1]
            self.message_dialog = MessageDialog("Error", message,
                                                self.main_window)
            self.message_dialog.run()
            return None
        return block

    # ----------------------------------------------------------------------
    def add_comment(self, comment=None):
        """
        This method add a block.

        Parameters:

                * **Types** (:class:`block<>`)
        Returns:

            * **Types** (:class:`boolean<boolean>`)
        """
        DiagramControl(self.get_current_diagram()).add_comment(comment)
        return True

    # ----------------------------------------------------------------------
    def select_all(self):
        DiagramControl(self.get_current_diagram()).select_all()

    # ----------------------------------------------------------------------
    def cut(self):
        """
        This method cut a block on work area.
        """
        DiagramControl(self.get_current_diagram()).cut()

    # ----------------------------------------------------------------------
    def copy(self):
        """
        This method copy a block.
        """
        DiagramControl(self.get_current_diagram()).copy()

    # ----------------------------------------------------------------------
    def paste(self):
        """
        This method paste a block.
        """
        DiagramControl(self.get_current_diagram()).paste()

    # ----------------------------------------------------------------------
    def delete(self):
        """
        This method delete a block.
        """
        DiagramControl(self.get_current_diagram()).delete()

    # ----------------------------------------------------------------------
    def zoom_in(self):
        """
        This method increases the zoom value.
        """
        DiagramControl(self.get_current_diagram()).change_zoom(System.ZOOM_IN)

    # ----------------------------------------------------------------------
    def zoom_out(self):
        """
        This method decreases the zoom.
        """
        DiagramControl(self.get_current_diagram()).change_zoom(System.ZOOM_OUT)

    # ----------------------------------------------------------------------
    def zoom_normal(self):
        """
        Set the zoom value to normal.
        """
        DiagramControl(self.get_current_diagram()).change_zoom(
            System.ZOOM_ORIGINAL)

    # ----------------------------------------------------------------------
    def undo(self):
        """
        Undo a modification.
        """
        DiagramControl(self.get_current_diagram()).undo()

    # ----------------------------------------------------------------------
    def redo(self):
        """
        Redo a modification.
        """
        DiagramControl(self.get_current_diagram()).redo()

    # ----------------------------------------------------------------------
    def align_top(self):
        DiagramControl(self.get_current_diagram()).align("TOP")

    # ----------------------------------------------------------------------
    def align_bottom(self):
        DiagramControl(self.get_current_diagram()).align("BOTTOM")

    # ----------------------------------------------------------------------
    def align_left(self):
        DiagramControl(self.get_current_diagram()).align("LEFT")

    # ----------------------------------------------------------------------
    def align_right(self):
        DiagramControl(self.get_current_diagram()).align("RIGHT")

    # ----------------------------------------------------------------------
    def collapse_all(self):
        DiagramControl(self.get_current_diagram()).collapse_all(True)

    # ----------------------------------------------------------------------
    def uncollapse_all(self):
        DiagramControl(self.get_current_diagram()).collapse_all(False)

    # ----------------------------------------------------------------------
    def redraw(self, show_grid):
        diagrams = self.main_window.work_area.get_diagrams()
        for diagram in diagrams:
            DiagramControl(diagram).set_show_grid(show_grid)

    # ----------------------------------------------------------------------
    def show_grid(self, event):
        if event is None:
            return
        self.redraw(event.get_active())

    # ----------------------------------------------------------------------
    def add_code_template(self, code_template):
        CodeTemplateControl.add_code_template(code_template)
        System.reload()

    # ----------------------------------------------------------------------
    def delete_code_template(self, code_template_name):
        result = CodeTemplateControl.delete_code_template(code_template_name)
        if not result[0]:
            self.message_dialog = MessageDialog("Error", result[1],
                                                self.main_window)
            self.message_dialog.run()
            return False
        self.message_dialog = MessageDialog("Info", result[1],
                                            self.main_window)
        self.message_dialog.run()
        System.reload()
        return True

    # ----------------------------------------------------------------------
    def add_port(self, port):
        PortControl.add_port(port)
        System.reload()

    # ----------------------------------------------------------------------
    def delete_port(self, port_key):
        result = PortControl.delete_port(port_key)
        if not result[0]:
            self.message_dialog = MessageDialog("Error", result[1],
                                                self.main_window)
            self.message_dialog.run()
        System.reload()

    # ----------------------------------------------------------------------
    def add_new_block(self, block):
        BlockControl.add_new_block(block)
        self.update_blocks()

    # ----------------------------------------------------------------------
    def delete_block(self, block):
        result = BlockControl.delete_block(block)
        if not result[0]:
            self.message_dialog = MessageDialog("Error", result[1],
                                                self.main_window)
            self.message_dialog.run()
        self.update_blocks()

    # ----------------------------------------------------------------------
    def update_all(self):
        for diagram in self.main_window.work_area.get_diagrams():
            diagram.update()