Esempio n. 1
0
class BasePanel(Gtk.Paned):
    """
    Panel Horizontal:
        Izquierda:
            Estructura de Proyecto e Introspección sobre el mismo.
            
        Derecha:
            Archivos y terminales.
    """
    
    __gtype_name__ = 'BasePanel'

    __gsignals__ = {
     'update': (GObject.SIGNAL_RUN_FIRST,
        GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,
        GObject.TYPE_BOOLEAN))}
        
    def __init__(self):

        Gtk.Paned.__init__(self, orientation=Gtk.Orientation.HORIZONTAL)

        self.set_border_width(5)
        
        self.proyecto = {}
        
        self.workpanel = WorkPanel()
        self.infonotebook = InfoNotebook()
        self.seleccionado_actual = 0
        
        self.toolbarproyecto = ToolbarProyecto()
        self.toolbararchivo = ToolbarArchivo()
        toolbarbusquedas = ToolbarBusquedas()

        self.infonotebook_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        
        self.infonotebook_box.pack_start(self.toolbarproyecto, False, False, 0)
        self.infonotebook_box.pack_start(self.infonotebook, True, True, 0)
        self.infonotebook_box.pack_end(toolbarbusquedas, False, False, 0)
        
        workpanel_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        
        workpanel_box.pack_start(self.toolbararchivo, False, False, 0)
        workpanel_box.pack_end(self.workpanel, True, True, 0)

        self.pack1(self.infonotebook_box, resize = False, shrink = False)
        self.pack2(workpanel_box, resize = True, shrink = True)

        self.show_all()
        
        self.infonotebook_box.set_size_request(280, -1)
        
        self.workpanel.connect('new_select', self.__set_introspeccion)
        self.workpanel.connect('close_all_files', self.__set_introspeccion)
        self.toolbararchivo.connect('accion', self.set_accion_archivo)
        self.toolbarproyecto.connect('accion', self.set_accion_proyecto)
        toolbarbusquedas.connect("buscar", self.__buscar)
        toolbarbusquedas.connect("accion", self.__buscar_mas)
        self.infonotebook.connect('new_select', self.__set_linea)
        self.infonotebook.connect('open', self.__open_file)
        self.infonotebook.connect('search_on_grep', self.__search_grep)
        self.infonotebook.connect('remove_proyect', self.__remove_proyect)
        
    def __search_grep(self, widget, datos, parent):
        """
        Cuando se hace una busqueda grep en la
        estructura del proyecto y luego se selecciona
        una linea en los resultados de dicha búsqueda.
        
            Se abre el archivo
            Se selecciona y
            Se abre el dialogo buscar.
        """
        
        self.__open_file(None, datos[0])
        
        paginas = self.workpanel.notebook_sourceview.get_n_pages()
        
        for indice in range(paginas):
            sourceview = self.workpanel.notebook_sourceview.get_nth_page(indice).get_child()
            
            visible = sourceview.get_show_line_numbers()
            sourceview.set_show_line_numbers(True)
            
            if sourceview.archivo == datos[0]:
                self.workpanel.notebook_sourceview.set_current_page(indice)
                break
            
        dialogo = DialogoBuscar(sourceview,
            parent_window = parent,
            title = "Buscar Texto", texto = datos[2])

        dialogo.run()
        
        dialogo.destroy()
        
        sourceview.set_show_line_numbers(visible)
        
    def __open_file(self, widget, filepath):
        """
        Cuando se envia "abrir" un archivo desde el
        visor de estructura del proyecto.
        """
        
        self.workpanel.abrir_archivo(filepath)
        
    def __buscar(self, widget, texto):
        """
        Recibe el texto a buscar.
        """

        self.seleccionado_actual = 0
        self.infonotebook.buscar(texto)
        
    def __buscar_mas(self, widget, accion, texto):
        """
        Cuando se hace click en anterior o
        siguiente en la toolbar de busquedas.
        """
       
        self.infonotebook.buscar(texto)
        if self.infonotebook.get_current_page() == 0:
            tree = self.infonotebook.introspeccion
            seleccion = self.infonotebook.introspeccion.get_selection()
            posibles = self.infonotebook.introspeccion.posibles
            
        else:
            tree = self.infonotebook.estructura_proyecto
            seleccion = self.infonotebook.estructura_proyecto.get_selection()
            posibles = self.infonotebook.estructura_proyecto.posibles
        
        if accion == "Siguiente":
            self.seleccionado_actual += 1
            
        else:
            self.seleccionado_actual -= 1
        
        if self.seleccionado_actual > len(posibles) - 1:
            self.seleccionado_actual = 0
            
        elif self.seleccionado_actual < 0:
            self.seleccionado_actual = len(posibles) - 1

        if posibles != []:
            seleccion.select_iter(posibles[self.seleccionado_actual])
            new_path = tree.get_model().get_path(posibles[self.seleccionado_actual])
            tree.scroll_to_cell(new_path)
            
    def set_accion_codigo(self, widget, accion):
        """
        Cuando se hace click en una opción del menú Código.
        """
        
        self.workpanel.set_accion_codigo(accion)
        
    def set_accion_ver(self, widget, accion, valor):
        """
        Cuando se hace click en una opción del menú ver.
        """
        
        if accion == "Panel lateral":
            if not valor:
                self.infonotebook_box.hide()
                
            else:
                self.infonotebook_box.show()
                
        elif accion == "Numeracion" or accion == "Panel inferior":
            self.workpanel.set_accion_ver(accion, valor)
            
    def set_accion_archivo(self, widget, accion):
        """
        Cuando se hace click en la toolbar de archivos o
        se manda ejecutar una acción desde el menú.
        """
        
        if accion == "Nuevo Archivo":
            self.__abrir_archivo(None, None)
            
        elif accion == "Abrir Archivo":
            path = self.workpanel.get_default_path()
            
            if not path:
                path = BatovideWorkSpace
                
                if self.proyecto:
                    path = self.proyecto["path"]
            
            filechooser = Multiple_FileChooser(
                parent_window = self.get_toplevel(),
                title = "Abrir Archivo",
                path = path,
                mime_type = ["text/*", "image/svg+xml"])
                
            filechooser.connect('load', self.__abrir_archivo)
        
        elif accion == "Guardar Archivo":
            self.workpanel.guardar_archivo()
        
        elif accion == "Guardar Como":
            self.workpanel.guardar_archivo_como()
        
        elif accion in ["Deshacer", "Rehacer", "Copiar",
            "Cortar", "Pegar", "Seleccionar Todo", "Cerrar Archivo",
            "Buscar Texto", "Remplazar Texto"]:
            self.workpanel.set_accion_archivos(accion)
        
        elif accion == "Ejecutar Archivo":
            self.workpanel.ejecutar()

        elif accion == "Detener Ejecución":
            self.workpanel.detener_ejecucion()
        
        else:
            print "Accion sin asignar en BasePanel", accion
        
    def __set_linea(self, widget, texto):
        """
        Recibe la linea seleccionada en instrospeccion y
        y la pasa a workpanel para ser seleccionada en el código.
        """
        
        self.workpanel.set_linea(texto)

    def __set_introspeccion(self, widget, view=False, estructura=False):
        """
        Recibe nombre y contenido de archivo para
        realizar introspeccion sobre él.
        """
        
        nombre = "Introspección"
        text = ''
        
        if view:
            buffer = view.get_buffer()
            archivo = view.archivo
            
            if archivo:
                nombre = os.path.basename(archivo)
            
            inicio, fin = buffer.get_bounds()
            text = buffer.get_text(inicio, fin, 0)
            
        ### Setear Introspeción.
        self.infonotebook.set_introspeccion(nombre, text)
        
        ### Actualizar sourceview para actualizador de toolbars y menus.
        self.emit("update", view, True)
        
        ### Cuando se guarda un archivo.
        if estructura:
            if self.proyecto:
                if self.proyecto["path"] in archivo:
                    self.infonotebook.set_path_estructura(self.proyecto["path"])
        
    def __load(self, proyecto):
        """
        Carga los datos del proyecto en la interfaz
        de la aplicación.
        """
        
        self.proyecto = proyecto
        
        path = proyecto.get("path", False)
        main = proyecto.get("main", False)
        
        self.infonotebook.set_path_estructura(path)
        self.workpanel.abrir_archivo(os.path.join(path, main))

    def __abrir_archivo(self, widget, archivo):
        """
        Abre un archivo.
        """

        if archivo:
            import commands
            datos = commands.getoutput('file -ik %s%s%s' % ("\"", archivo, "\""))
            
            if "text" in datos or "x-python" in datos or "x-empty" in datos or "svg+xml" in datos:
                self.workpanel.abrir_archivo(archivo)
                
        else:
            self.workpanel.abrir_archivo(None)
        
    def set_accion_proyecto(self, widget, accion):
        """
        Cuando se hace click en la toolbar de proyecto o
        se manda ejecutar una acción desde el menú.
        """
        
        # FIXME: Cualquier acción en las toolbars o menu,
        # debe detener las ejecuciones en marcha?.

        if accion == "Nuevo Proyecto":
            dialog = DialogoProyecto(
                parent_window = self.get_toplevel(),
                title = "Crear nuevo proyecto")
            
            response = dialog.run()
            
            nueveoproyecto = False
            
            if Gtk.ResponseType(response) == Gtk.ResponseType.ACCEPT:
                nueveoproyecto = dialog.get_proyecto()
                
            dialog.destroy()
            
            ### El nuevo Proyecto se crea solo cuando se ha cerrado el anterior.
            if nueveoproyecto:
                anterior_cerrado = True
        
                if self.proyecto:
                    ### No se puede Crear un proyecto con el mismo nombre de uno existente
                    if nueveoproyecto["nombre"] in os.listdir(BatovideWorkSpace): return
                    anterior_cerrado = self.cerrar_proyecto()
        
                if anterior_cerrado:
                    self.proyecto = nueveoproyecto
                    self.__guardar_proyecto()
                    self.__load(self.proyecto)
                
        elif accion == "Editar Proyecto":
            if self.proyecto:
                dialog = DialogoProyecto(
                    parent_window = self.get_toplevel(),
                    title = "Editar Proyecto",
                    accion = "editar")
                    
                dialog.set_proyecto(self.proyecto)
                
                response = dialog.run()
                
                if Gtk.ResponseType(response) == Gtk.ResponseType.ACCEPT:
                    self.proyecto = dialog.get_proyecto()
                    self.__guardar_proyecto()
                    self.__load(self.proyecto)
                    
                dialog.destroy()
                
        elif accion == "Abrir Proyecto":
            filechooser = My_FileChooser(
                parent_window = self.get_toplevel(),
                action_type = Gtk.FileChooserAction.OPEN,
                filter_type = ["*.ide"],
                title = "Abrir proyecto",
                path = BatovideWorkSpace)
                
            filechooser.connect('load', self.__abrir_proyecto)

        elif accion == "Guardar Proyecto":
            self.__guardar_archivos_de_proyecto()
            self.__guardar_proyecto()
        
        elif accion == "Cerrar Proyecto":
            if self.cerrar_proyecto(): self.proyecto = {}
        
        elif accion == "Ejecutar Proyecto":
            if self.proyecto:
                main = os.path.join(self.proyecto["path"], self.proyecto["main"])
                self.workpanel.ejecutar(archivo=main)
            
        elif accion == "Detener Ejecución":
            self.workpanel.detener_ejecucion()
        
        elif accion == "Construir":
            from Widget_Setup import DialogoSetup
            
            dialog = DialogoSetup(
                parent_window = self.get_toplevel(),
                proyecto = self.proyecto)
        
            respuesta = dialog.run()
            
            dialog.destroy()

            if respuesta == Gtk.ResponseType.ACCEPT:
                pass
            
        else:
            print "Acccion sin asignar en BasePanel", accion

    def __abrir_proyecto(self, widget, archivo):
        """
        Abrir archivo de un proyecto.
        """
        
        extension = os.path.splitext(os.path.split(archivo)[1])[1]
        
        if not extension == ".ide": return
        
        import json
        import codecs
        
        pro = codecs.open(archivo, "r", "utf-8")
        proyecto = json.JSONDecoder("utf-8").decode(pro.read())
        
        proyecto["path"] = os.path.dirname(archivo)
        
        ### Validación de datos del proyecto.
        if not proyecto.get("nombre", False): return
        if not proyecto.get("main", False): return
        if not os.path.exists(os.path.join(proyecto["path"], proyecto["main"])): return
        
        anterior_cerrado = True
        
        if self.proyecto:
            if self.proyecto.get("path", False) == proyecto["path"]: return
            anterior_cerrado = self.cerrar_proyecto()
        
        ### El proyecto se carga sólo si se cerró el anterior.
        if anterior_cerrado:
            self.proyecto = {}
            self.__load(proyecto)
            self.__guardar_proyecto() ### Actualizando el path de proyecto.
        
    def __guardar_archivos_de_proyecto(self):
        """
        Guarda todos los archivos del proyecto abierto.
        """
        
        if not self.proyecto: return
    
        codeviews = self.workpanel.get_archivos_de_proyecto(self.proyecto["path"])
        
        for view in codeviews:
            view.guardar()
            
    def __guardar_proyecto(self):
        """
        Guarda el proyecto actual.
        """
        
        ### Todo Proyecto Requiere un Nombre.
        if not self.proyecto.get("nombre", False): return
        
        ### Seteo automático del path del proyecto.
        path = False
        
        if self.proyecto.get("path", False):
            path = self.proyecto["path"]
            
        else:
            path = os.path.join(BatovideWorkSpace, self.proyecto["nombre"])
            
        if not os.path.exists(path):
            os.mkdir(path)
        
        self.proyecto["path"] = path
        
        ### Seteo automático del main del proyecto.
        if not self.proyecto.get("main", False):
            self.proyecto["main"] = "Main.py"
            
        main_path = os.path.join(self.proyecto["path"], self.proyecto["main"])
        
        if not os.path.exists(main_path):
            arch = open(main_path, "w")
            arch.write("#!/usr/bin/env python\n# -*- coding: utf-8 -*-")
            arch.close()
            
        ### Seteo automático de licencia
        licencia_path = os.path.join(self.proyecto["path"], "COPYING")
        import Licencias as Lic
        
        arch = open(licencia_path, "w")
        arch.write(Lic.dict[self.proyecto["licencia"]])
        arch.close()
        
        ### Seteo automático de autores.
        autores_path = os.path.join(self.proyecto["path"], "AUTHORS")
        
        arch = open(autores_path, "w")
        for autor in self.proyecto["autores"]:
            arch.write("%s %s \n" % (autor[0].encode("utf-8"), autor[1].encode("utf-8")))

        arch.close()
        
        ### Guardar el Proyecto.
        proyecto = os.path.join(path, "proyecto.ide")
        
        import simplejson
        
        archivo = open(proyecto, "w")
        archivo.write(
            simplejson.dumps(
                self.proyecto,
                indent=4,
                separators=(", ", ":"),
                sort_keys=True
            )
        )
        archivo.close()
        
    def cerrar_proyecto(self):
        """
        Cierra el proyecto.
        """
        
        if not self.proyecto: return True
        
        codeviews = self.workpanel.get_archivos_de_proyecto(self.proyecto["path"])
        
        ### Cerrar Archivos.
        if codeviews:
            ### Cerrar Archivos. Esto pedirá guardar si hay cambios en él.
            for view in codeviews:
                view.set_accion("Cerrar Archivo")
        
        else:
            self.infonotebook.set_path_estructura(None)
            self.proyecto = {}
            return True
        
        ### Si algun archivo ha debido guardarse, no se ha cerrado.
        codeviews = self.workpanel.get_archivos_de_proyecto(self.proyecto["path"])
        
        if codeviews:
            ### Cerrar Archivos.
            for view in codeviews:
                view.set_accion("Cerrar Archivo")
                
        else:
            self.infonotebook.set_path_estructura(None)
            self.proyecto = {}
            return True
        
        ### Si todavía hay archivos abiertos, el usuario no desea cerrarlos.
        codeviews = self.workpanel.get_archivos_de_proyecto(self.proyecto["path"])
        
        if codeviews:
            return False
        
        else:
            self.infonotebook.set_path_estructura(None)
            self.proyecto = {}
            return True
        
    def __remove_proyect(self, widget):
        """
        Cuando se elimina el proyecto desde la vista de estructura.
        """
    
        self.workpanel.remove_proyect(self.proyecto["path"])
        
        self.infonotebook.set_path_estructura(None)
        self.proyecto = {}
        
        return True
Esempio n. 2
0
class BasePanel(gtk.HPaned):
    """
    Panel Horizontal:
        Izquierda:
            Estructura de Proyecto e Introspección sobre el mismo.

        Derecha:
            Archivos y terminales.
    """

    __gtype_name__ = 'BasePanel'

    __gsignals__ = {
        'update': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
                   (gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN))
    }

    def __init__(self):

        gtk.HPaned.__init__(self)

        self.set_border_width(5)

        self.proyecto = {}

        self.workpanel = WorkPanel()
        self.infonotebook = InfoNotebook()
        self.seleccionado_actual = 0

        self.toolbarproyecto = ToolbarProyecto()
        self.toolbararchivo = ToolbarArchivo()
        toolbarbusquedas = ToolbarBusquedas()

        self.infonotebook_box = gtk.VBox()

        self.infonotebook_box.pack_start(self.toolbarproyecto, False, False, 0)
        self.infonotebook_box.pack_start(self.infonotebook, True, True, 0)
        self.infonotebook_box.pack_end(toolbarbusquedas, False, False, 0)

        workpanel_box = gtk.VBox()

        workpanel_box.pack_start(self.toolbararchivo, False, False, 0)
        workpanel_box.pack_end(self.workpanel, True, True, 0)

        self.pack1(self.infonotebook_box, resize=False, shrink=False)
        self.pack2(workpanel_box, resize=True, shrink=True)

        self.show_all()

        self.infonotebook_box.set_size_request(280, -1)

        self.workpanel.connect('new_select', self.__set_introspeccion)
        self.toolbararchivo.connect('accion', self.set_accion_archivo)
        self.toolbarproyecto.connect('accion', self.set_accion_proyecto)
        toolbarbusquedas.connect("buscar", self.__buscar)
        toolbarbusquedas.connect("accion", self.__buscar_mas)
        self.infonotebook.connect('new_select', self.__set_linea)
        self.infonotebook.connect('open', self.__open_file)
        self.infonotebook.connect('search_on_grep', self.__search_grep)
        self.infonotebook.connect('remove_proyect', self.__remove_proyect)

    def __search_grep(self, widget, datos, parent):
        """
        Cuando se hace una busqueda grep en la
        estructura del proyecto y luego se selecciona
        una linea en los resultados de dicha búsqueda.

            Se abre el archivo
            Se selecciona y
            Se abre el dialogo buscar.
        """

        self.__open_file(None, datos[0])

        paginas = self.workpanel.notebook_sourceview.get_n_pages()

        for indice in range(paginas):
            sourceview = self.workpanel.notebook_sourceview.get_nth_page(
                indice).get_child()

            visible = sourceview.get_show_line_numbers()
            sourceview.set_show_line_numbers(True)

            if sourceview.archivo == datos[0]:
                self.workpanel.notebook_sourceview.set_current_page(indice)
                break

        dialogo = DialogoBuscar(sourceview,
                                parent_window=parent,
                                title="Buscar Texto",
                                texto=datos[2])

        dialogo.run()

        dialogo.destroy()

        sourceview.set_show_line_numbers(visible)

    def __open_file(self, widget, filepath):
        """
        Cuando se envia "abrir" un archivo desde el
        visor de estructura del proyecto.
        """

        self.workpanel.abrir_archivo(filepath)

    def __buscar(self, widget, texto):
        """
        Recibe el texto a buscar.
        """

        self.seleccionado_actual = 0
        self.infonotebook.buscar(texto)

    def __buscar_mas(self, widget, accion, texto):
        """
        Cuando se hace click en anterior o
        siguiente en la toolbar de busquedas.
        """

        self.infonotebook.buscar(texto)
        if self.infonotebook.get_current_page() == 0:
            tree = self.infonotebook.introspeccion
            seleccion = self.infonotebook.introspeccion.get_selection()
            posibles = self.infonotebook.introspeccion.posibles

        else:
            tree = self.infonotebook.estructura_proyecto
            seleccion = self.infonotebook.estructura_proyecto.get_selection()
            posibles = self.infonotebook.estructura_proyecto.posibles

        if accion == "Siguiente":
            self.seleccionado_actual += 1

        else:
            self.seleccionado_actual -= 1

        if self.seleccionado_actual > len(posibles) - 1:
            self.seleccionado_actual = 0

        elif self.seleccionado_actual < 0:
            self.seleccionado_actual = len(posibles) - 1

        if posibles != []:
            seleccion.select_iter(posibles[self.seleccionado_actual])
            new_path = tree.get_model().get_path(
                posibles[self.seleccionado_actual])
            tree.scroll_to_cell(new_path)

    def set_accion_codigo(self, widget, accion):
        """
        Cuando se hace click en una opción del menú Código.
        """

        self.workpanel.set_accion_codigo(accion)

    def set_accion_ver(self, widget, accion, valor):
        """
        Cuando se hace click en una opción del menú ver.
        """

        if accion == "Panel lateral":
            if not valor:
                self.infonotebook_box.hide()

            else:
                self.infonotebook_box.show()

        elif accion == "Numeracion" or accion == "Panel inferior":
            self.workpanel.set_accion_ver(accion, valor)

    def set_accion_archivo(self, widget, accion):
        """
        Cuando se hace click en la toolbar de archivos o
        se manda ejecutar una acción desde el menú.
        """

        if accion == "Nuevo Archivo":
            self.__abrir_archivo(None, None)

        elif accion == "Abrir Archivo":
            path = self.workpanel.get_default_path()

            if not path:
                path = BatovideWorkSpace

                if self.proyecto:
                    path = self.proyecto["path"]

            filechooser = Multiple_FileChooser(
                parent_window=self.get_toplevel(),
                title="Abrir Archivo",
                path=path,
                mime_type=["text/*", "image/svg+xml"])

            filechooser.connect('load', self.__abrir_archivo)

        elif accion == "Guardar Archivo":
            self.workpanel.guardar_archivo()

        elif accion == "Guardar Como":
            self.workpanel.guardar_archivo_como()

        elif accion in [
                "Deshacer", "Rehacer", "Copiar", "Cortar", "Pegar",
                "Seleccionar Todo", "Cerrar Archivo", "Buscar Texto",
                "Remplazar Texto"
        ]:
            self.workpanel.set_accion_archivos(accion)

        elif accion == "Ejecutar Archivo":
            self.workpanel.ejecutar()

        elif accion == "Detener Ejecución":
            self.workpanel.detener_ejecucion()

        else:
            print "Accion sin asignar en BasePanel", accion

    def __set_linea(self, widget, index, texto):
        """
        Recibe la linea seleccionada en instrospeccion y
        y la pasa a workpanel para ser seleccionada en el código.
        """

        self.workpanel.set_linea(index, texto)

    def __set_introspeccion(self, widget, view, estructura):
        """
        Recibe nombre y contenido de archivo para
        realizar introspeccion sobre él.
        """

        buffer = view.get_buffer()
        archivo = view.archivo
        nombre = False

        if archivo:
            nombre = os.path.basename(archivo)

        inicio, fin = buffer.get_bounds()

        # Setear Introspeción.
        self.infonotebook.set_introspeccion(nombre,
                                            buffer.get_text(inicio, fin, 0),
                                            view, "python")

        # Actualizar sourceview para actualizador de toolbars y menus.
        self.emit("update", view, True)

        # Cuando se guarda un archivo.
        if estructura:
            if self.proyecto:
                if self.proyecto["path"] in archivo:
                    self.infonotebook.set_path_estructura(
                        self.proyecto["path"])

    def __load(self, proyecto):
        """
        Carga los datos del proyecto en la interfaz
        de la aplicación.
        """

        self.proyecto = proyecto

        path = proyecto.get("path", False)
        main = proyecto.get("main", False)

        self.infonotebook.set_path_estructura(path)
        self.workpanel.abrir_archivo(os.path.join(path, main))

    def __abrir_archivo(self, widget, archivo):
        """
        Abre un archivo.
        """

        if archivo:
            import commands
            datos = commands.getoutput('file -ik %s%s%s' %
                                       ("\"", archivo, "\""))

            if "text" in datos or "x-python" in datos or \
                "x-empty" in datos or "svg+xml" in datos:
                self.workpanel.abrir_archivo(archivo)

        else:
            self.workpanel.abrir_archivo(None)

    def set_accion_proyecto(self, widget, accion):
        """
        Cuando se hace click en la toolbar de proyecto o
        se manda ejecutar una acción desde el menú.
        """

        # FIXME: Cualquier acción en las toolbars o menu,
        # debe detener las ejecuciones en marcha?.

        if accion == "Nuevo Proyecto":
            dialog = DialogoProyecto(parent_window=self.get_toplevel(),
                                     title="Crear nuevo proyecto")

            response = dialog.run()

            nueveoproyecto = False

            if gtk.ResponseType(response) == gtk.RESPONSE_ACCEPT:
                nueveoproyecto = dialog.get_proyecto()

            dialog.destroy()

            # El nuevo Proyecto se crea solo cuando se ha cerrado el anterior
            if nueveoproyecto:
                anterior_cerrado = True

                if self.proyecto:
                    # No se puede Crear un proyecto con el mismo nombre
                    # de uno existente
                    if nueveoproyecto["nombre"] in os.listdir(
                            BatovideWorkSpace):
                        return

                    anterior_cerrado = self.cerrar_proyecto()

                if anterior_cerrado:
                    self.proyecto = nueveoproyecto
                    self.__guardar_proyecto()
                    self.__load(self.proyecto)

        elif accion == "Editar Proyecto":
            if self.proyecto:
                dialog = DialogoProyecto(parent_window=self.get_toplevel(),
                                         title="Editar proyecto",
                                         accion="editar")

                dialog.set_proyecto(self.proyecto)

                response = dialog.run()

                if gtk.ResponseType(response) == gtk.RESPONSE_ACCEPT:
                    self.proyecto = dialog.get_proyecto()
                    self.__guardar_proyecto()
                    self.__load(self.proyecto)

                dialog.destroy()

        elif accion == "Abrir Proyecto":
            filechooser = My_FileChooser(
                parent_window=self.get_toplevel(),
                action_type=gtk.FILE_CHOOSER_ACTION_OPEN,
                filter_type=["*.ide"],
                title="Abrir proyecto",
                path=BatovideWorkSpace)

            filechooser.connect('load', self.__abrir_proyecto)

        elif accion == "Guardar Proyecto":
            self.__guardar_archivos_de_proyecto()
            self.__guardar_proyecto()

        elif accion == "Cerrar Proyecto":
            if self.cerrar_proyecto():
                self.proyecto = {}

        elif accion == "Ejecutar Proyecto":
            if self.proyecto:
                main = os.path.join(self.proyecto["path"],
                                    self.proyecto["main"])
                self.workpanel.ejecutar(archivo=main)

        elif accion == "Detener Ejecución":
            self.workpanel.detener_ejecucion()

        elif accion == "Construir":
            from Widget_Setup import DialogoSetup

            dialog = DialogoSetup(parent_window=self.get_toplevel(),
                                  proyecto=self.proyecto)

            respuesta = dialog.run()

            dialog.destroy()

            if respuesta == gtk.RESPONSE_ACCEPT:
                pass

        else:
            print "Acccion sin asignar en BasePanel", accion

    def __abrir_proyecto(self, widget, archivo):
        """
        Abrir archivo de un proyecto.
        """

        extension = os.path.splitext(os.path.split(archivo)[1])[1]

        if not extension == ".ide":
            return

        import json
        import codecs

        pro = codecs.open(archivo, "r", "utf-8")
        proyecto = json.JSONDecoder("utf-8").decode(pro.read())

        proyecto["path"] = os.path.dirname(archivo)

        # Validación de datos del proyecto.
        if not proyecto.get("nombre", False):
            return
        if not proyecto.get("main", False):
            return
        if not os.path.exists(os.path.join(proyecto["path"],
                                           proyecto["main"])):
            return

        anterior_cerrado = True

        if self.proyecto:
            if self.proyecto.get("path", False) == proyecto["path"]:
                return
            anterior_cerrado = self.cerrar_proyecto()

        # El proyecto se carga sólo si se cerró el anterior.
        if anterior_cerrado:
            self.proyecto = {}
            self.__load(proyecto)
            self.__guardar_proyecto()  # Actualizando el path de proyecto.

    def __guardar_archivos_de_proyecto(self):
        """
        Guarda todos los archivos del proyecto abierto.
        """

        if not self.proyecto:
            return

        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto["path"])

        for view in codeviews:
            view.guardar()

    def __guardar_proyecto(self):
        """
        Guarda el proyecto actual.
        """

        # Todo Proyecto Requiere un Nombre.
        if not self.proyecto.get("nombre", False):
            return

        # Seteo automático del path del proyecto.
        path = False

        if self.proyecto.get("path", False):
            path = self.proyecto["path"]

        else:
            path = os.path.join(BatovideWorkSpace, self.proyecto["nombre"])

        if not os.path.exists(path):
            os.mkdir(path)

        self.proyecto["path"] = path

        # Seteo automático del main del proyecto.
        if not self.proyecto.get("main", False):
            self.proyecto["main"] = "Main.py"

        main_path = os.path.join(self.proyecto["path"], self.proyecto["main"])

        if not os.path.exists(main_path):
            arch = open(main_path, "w")
            arch.write("#!/usr/bin/env python\n# -*- coding: utf-8 -*-")
            arch.close()

        # Seteo automático de licencia
        licencia_path = os.path.join(self.proyecto["path"], "COPYING")
        import Licencias as Lic

        arch = open(licencia_path, "w")
        arch.write(Lic.dict[self.proyecto["licencia"]])
        arch.close()

        # Seteo automático de autores.
        autores_path = os.path.join(self.proyecto["path"], "AUTHORS")

        arch = open(autores_path, "w")
        for autor in self.proyecto["autores"]:
            arch.write("%s %s \n" %
                       (autor[0].encode("utf-8"), autor[1].encode("utf-8")))

        arch.close()

        # Guardar el Proyecto.
        proyecto = os.path.join(path, "proyecto.ide")

        import simplejson

        archivo = open(proyecto, "w")
        archivo.write(
            simplejson.dumps(self.proyecto,
                             indent=4,
                             separators=(", ", ":"),
                             sort_keys=True))
        archivo.close()

    def cerrar_proyecto(self):
        """
        Cierra el proyecto.
        """

        if not self.proyecto:
            return True

        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto["path"])

        # Cerrar Archivos.
        if codeviews:
            # Cerrar Archivos. Esto pedirá guardar si hay cambios en él.
            for view in codeviews:
                view.set_accion("Cerrar Archivo")

        else:
            self.infonotebook.set_path_estructura(None)
            self.proyecto = {}
            return True

        # Si algun archivo ha debido guardarse, no se ha cerrado.
        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto["path"])

        if codeviews:
            # Cerrar Archivos.
            for view in codeviews:
                view.set_accion("Cerrar Archivo")

        else:
            self.infonotebook.set_path_estructura(None)
            self.proyecto = {}
            return True

        # Si todavía hay archivos abiertos, el usuario no desea cerrarlos.
        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto["path"])

        if codeviews:
            return False

        else:
            self.infonotebook.set_path_estructura(None)
            self.proyecto = {}
            return True

    def __remove_proyect(self, widget):
        """
        Cuando se elimina el proyecto desde la vista de estructura.
        """

        self.workpanel.remove_proyect(self.proyecto["path"])

        self.infonotebook.set_path_estructura(None)
        self.proyecto = {}

        return True

    def external_open_proyect(self, ide_file):
        """
        Cuando se abre el editor con archivo como parámetro.
        """

        self.__abrir_proyecto(None, ide_file)

    def external_open_file(self, archivo):
        """
        Cuando se abre el editor con archivo como parámetro.
        """

        self.__abrir_archivo(None, archivo)
Esempio n. 3
0
class BasePanel(Gtk.Paned):
    """
    Gtk.HPaned:
        Gtk.VBox: Estructura de Proyecto e Introspección sobre el mismo.
            ToolbarProyecto
            InfoNotebook
            ToolbarBusquedas

        Gtk.VBox: Archivos y terminales.
            ToolbarArchivo
            WorkPanel
    """

    __gtype_name__ = 'JAMediaEditorBasePanel'

    __gsignals__ = {
        'update': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
                   (GObject.TYPE_PYOBJECT, )),
        'proyecto_abierto':
        (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN, )),
        'ejecucion': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
                      (GObject.TYPE_STRING, GObject.TYPE_BOOLEAN))
    }

    def __init__(self):

        Gtk.Paned.__init__(self, orientation=Gtk.Orientation.HORIZONTAL)

        self.set_border_width(5)
        self.proyecto = {}

        self.workpanel = WorkPanel()
        self.infonotebook = InfoNotebook()
        self.seleccionado_actual = 0

        self.toolbarproyecto = ToolbarProyecto()
        self.toolbararchivo = ToolbarArchivo()
        toolbarbusquedas = ToolbarBusquedas()

        self.infonotebook_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        self.infonotebook_box.pack_start(self.toolbarproyecto, False, False, 0)
        self.infonotebook_box.pack_start(self.infonotebook, True, True, 0)
        self.infonotebook_box.pack_end(toolbarbusquedas, False, False, 0)

        workpanel_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        workpanel_box.pack_start(self.toolbararchivo, False, False, 0)
        workpanel_box.pack_end(self.workpanel, True, True, 0)

        self.pack1(self.infonotebook_box, resize=False, shrink=False)
        self.pack2(workpanel_box, resize=True, shrink=True)

        self.show_all()

        self.infonotebook_box.set_size_request(300, -1)

        self.workpanel.connect('new_select', self.__set_introspeccion)
        self.workpanel.connect('ejecucion', self.__re_emit_ejecucion)
        self.workpanel.connect('update', self.__re_emit_update)

        self.toolbararchivo.connect('accion', self.set_accion_archivo)
        self.toolbarproyecto.connect('accion', self.set_accion_proyecto)

        toolbarbusquedas.connect("buscar", self.__buscar)
        toolbarbusquedas.connect("accion", self.__buscar_mas)

        self.infonotebook.connect('new_select', self.__set_linea)
        self.infonotebook.connect('open', self.__abrir_archivo)
        self.infonotebook.connect('search_on_grep', self.__search_grep)
        self.infonotebook.connect('remove_proyect', self.__remove_proyect)

    def __re_emit_update(self, widget, dict):
        self.emit("update", dict)

    def __search_grep(self, widget, datos, parent):
        """
        Cuando se hace una busqueda grep en la estructura del proyecto y luego
        se selecciona una linea en los resultados de dicha búsqueda.
            Se abre el archivo
            Se selecciona y
            Se abre el dialogo buscar.
        """
        print "FIXME:", self.__search_grep
        '''
        self.__abrir_archivo(None, datos[0])

        paginas = self.workpanel.notebook_sourceview.get_n_pages()
        for indice in range(paginas):
            sourceview = self.workpanel.notebook_sourceview.get_nth_page(
                indice).get_child()

            visible = sourceview.get_show_line_numbers()
            sourceview.set_show_line_numbers(True)

            if sourceview.archivo == datos[0]:
                self.workpanel.notebook_sourceview.set_current_page(indice)
                break

        from Widgets import DialogoBuscar

        dialogo = DialogoBuscar(sourceview, parent_window=parent,
            title="Buscar Texto", texto=datos[2])

        dialogo.run()
        dialogo.destroy()
        sourceview.set_show_line_numbers(visible)
        '''

    def __buscar(self, widget, texto):
        """
        Recibe el texto a buscar.
        """
        self.seleccionado_actual = 0
        self.infonotebook.buscar(texto)

    def __buscar_mas(self, widget, accion, texto):
        """
        Cuando se hace click en anterior o siguiente en toolbar de busquedas.
        """
        self.infonotebook.buscar(texto)
        if self.infonotebook.get_current_page() == 0:
            tree = self.infonotebook.introspeccion
            seleccion = self.infonotebook.introspeccion.get_selection()
            posibles = self.infonotebook.introspeccion.posibles

        else:
            tree = self.infonotebook.estructura_proyecto
            seleccion = self.infonotebook.estructura_proyecto.get_selection()
            posibles = self.infonotebook.estructura_proyecto.posibles

        if accion == "Siguiente":
            self.seleccionado_actual += 1

        else:
            self.seleccionado_actual -= 1

        if self.seleccionado_actual > len(posibles) - 1:
            self.seleccionado_actual = 0

        elif self.seleccionado_actual < 0:
            self.seleccionado_actual = len(posibles) - 1

        if posibles != []:
            seleccion.select_iter(posibles[self.seleccionado_actual])
            new_path = tree.get_model().get_path(
                posibles[self.seleccionado_actual])
            tree.scroll_to_cell(new_path)

    def __set_linea(self, widget, index, texto):
        """
        Recibe la linea seleccionada en instrospeccion y
        y la pasa a workpanel para ser seleccionada en el código.
        """
        self.workpanel.set_linea(index, texto)

    def __re_emit_ejecucion(self, widget, tipo, valor):
        """
        Cuando se ejecutan o detienen archivos en terminales.
        """
        self.emit("ejecucion", tipo, valor)

    def __set_introspeccion(self, widget, view, tipo):
        """
        Cuando se selecciona una lengüeta en el Notebook:
            Recibe nombre y contenido de archivo para realizar
            introspeccion sobre él.
        """
        nombre = "Introspección"
        text = ''
        if view:
            _buffer = view.get_buffer()
            archivo = view.archivo

            if archivo:
                nombre = os.path.basename(archivo)

            inicio, fin = _buffer.get_bounds()
            text = _buffer.get_text(inicio, fin, 0)

        # Setear Introspeción.
        self.infonotebook.set_introspeccion(nombre, text, view, tipo)
        GLib.idle_add(self.__set_estructura, view, tipo)

    def __set_estructura(self, view, tipo):
        # FIXME: Verifica si hay archivos de proyecto y si los hay, actualiza
        # la vista de estructura. Otro punto de vista sería actualizar según
        # que archivo se ha seleccionado, en este caso, la vista de proyecto
        # solo sería activa si el archivo seleccionado está en el proyecto.
        path = self.proyecto.get("path", False)
        if path:
            codeviews = self.workpanel.get_archivos_de_proyecto(path)
            if codeviews:
                self.infonotebook.set_path_estructura(path)
                self.emit("proyecto_abierto", True)

            else:
                self.proyecto = {}
                self.emit("proyecto_abierto", False)
                self.infonotebook.set_path_estructura(False)

        else:
            self.proyecto = {}
            self.emit("proyecto_abierto", False)
            self.infonotebook.set_path_estructura(False)

    def __cargar_proyecto(self, proyecto):
        """
        Carga los datos del proyecto en la interfaz de la aplicación.
        """
        self.proyecto = proyecto
        path = proyecto.get("path", False)
        main = proyecto.get("main", False)
        self.__abrir_archivo(False, os.path.join(path, main))

    def __abrir_archivo(self, widget, archivo):
        if archivo:
            import commands
            datos = commands.getoutput('file -ik %s%s%s' %
                                       ("\"", archivo, "\""))

            if "text" in datos or "x-python" in datos or \
                "x-empty" in datos or "svg+xml" in datos or \
                "application/xml" in datos:
                self.workpanel.abrir_archivo(archivo)

        else:
            self.workpanel.abrir_archivo(False)

    def __abrir_proyecto(self, widget, archivo):
        extension = os.path.splitext(os.path.split(archivo)[1])[1]
        if not extension == ".ide":
            return

        import json
        import codecs

        pro = codecs.open(archivo, "r", "utf-8")
        proyecto = json.JSONDecoder("utf-8").decode(pro.read())
        proyecto["path"] = os.path.dirname(archivo)

        # Validación de datos del proyecto.
        if not proyecto.get("nombre", False):
            return

        if not proyecto.get("main", False):
            return

        if not os.path.exists(os.path.join(proyecto["path"],
                                           proyecto["main"])):
            return

        anterior_cerrado = self.cerrar_proyecto()
        # El proyecto se carga sólo si se cerró el anterior.
        if anterior_cerrado:
            self.__cargar_proyecto(proyecto)

    def __guardar_archivos_de_proyecto(self):
        """
        Guarda todos los archivos del proyecto abierto.
        """
        if not self.proyecto:
            return

        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto["path"])

        for view in codeviews:
            view.guardar()

    def __guardar_proyecto(self, proyecto):
        """
        Guarda el proyecto actual.
        """
        # Todo Proyecto Requiere un Nombre.
        if not proyecto.get("nombre", False):
            return

        # Seteo automático del path del proyecto.
        path = False
        if proyecto.get("path", False):
            path = proyecto["path"]

        else:
            path = os.path.join(BatovideWorkSpace, proyecto["nombre"])

        if not os.path.exists(path):
            os.mkdir(path)

        proyecto["path"] = path
        # Seteo automático del main del proyecto.
        if not proyecto.get("main", False):
            proyecto["main"] = "Main.py"

        main_path = os.path.join(proyecto["path"], proyecto["main"])
        if not os.path.exists(main_path):
            arch = open(main_path, "w")
            arch.write("#!/usr/bin/env python\n# -*- coding: utf-8 -*-")
            arch.close()

        # Seteo automático de licencia
        licencia_path = os.path.join(proyecto["path"], "COPYING")
        import Licencias as Lic

        arch = open(licencia_path, "w")
        arch.write(Lic.dict[proyecto["licencia"]])
        arch.close()

        # Seteo automático de autores.
        autores_path = os.path.join(proyecto["path"], "AUTHORS")
        arch = open(autores_path, "w")
        try:
            for autor in proyecto["autores"]:
                arch.write(u"%s %s\n" % (autor[0], autor[1]))
        except:
            print "FIXME: UnicodeEncodeError: 'ascii' codec can't encode"
            print "character u'\xed' in position 13: ordinal not in range(128)"

        arch.close()
        # Guardar el Proyecto.
        proyecto_file = os.path.join(path, "proyecto.ide")

        import json
        archivo = open(proyecto_file, "w")
        archivo.write(
            json.dumps(proyecto,
                       indent=4,
                       separators=(", ", ":"),
                       sort_keys=True))
        archivo.close()

    def __remove_proyect(self, widget):
        """
        Cuando se elimina el proyecto desde la vista de estructura.
        """
        self.workpanel.remove_proyect(self.proyecto["path"])
        self.infonotebook.set_path_estructura(False)
        self.proyecto = {}
        return True

    def cerrar_proyecto(self):
        if not self.proyecto:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True

        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto["path"])

        if codeviews:
            # Cerrar Archivos. Esto pedirá guardar si hay cambios en él.
            for view in codeviews:
                view.set_accion("Cerrar Archivo")
        else:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True

        # Si algún archivo ha debido guardarse, no se ha cerrado.
        if not self.proyecto:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True

        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto["path"])

        if codeviews:
            # Cerrar Archivos.
            for view in codeviews:
                view.set_accion("Cerrar Archivo")
        else:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True

        # Si todavía hay archivos abiertos, el usuario no desea cerrarlos.
        if not self.proyecto:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True

        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto["path"])

        if codeviews:
            return False
        else:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True

    def set_accion_proyecto(self, widget, accion):
        """
        Cuando se hace click en la toolbar de proyecto o
        se manda ejecutar una acción desde el menú.
        """
        if accion == "Nuevo Proyecto":
            from DialogoProyecto import DialogoProyecto
            dialog = DialogoProyecto(parent_window=self.get_toplevel(),
                                     title="Crear Nuevo Proyecto")

            response = dialog.run()
            nuevoproyecto = False
            if Gtk.ResponseType(response) == Gtk.ResponseType.ACCEPT:
                nuevoproyecto = dialog.get_proyecto()

            dialog.destroy()
            # El Proyecto se crea solo cuando se ha cerrado el anterior.
            if nuevoproyecto:
                if nuevoproyecto["nombre"] in os.listdir(BatovideWorkSpace):
                    print "FIXME: Ya existe un Proyecto con este Nombre"
                    return

                anterior_cerrado = self.cerrar_proyecto()
                if anterior_cerrado:
                    self.__guardar_proyecto(nuevoproyecto)
                    self.__abrir_proyecto(
                        None,
                        os.path.join(nuevoproyecto["path"], "proyecto.ide"))

        elif accion == "Editar Proyecto":
            if self.proyecto:
                from DialogoProyecto import DialogoProyecto
                dialog = DialogoProyecto(parent_window=self.get_toplevel(),
                                         title="Editar Proyecto",
                                         accion="editar")

                dialog.set_proyecto(self.proyecto)
                response = dialog.run()

                if Gtk.ResponseType(response) == Gtk.ResponseType.ACCEPT:
                    nuevoproyecto = dialog.get_proyecto()
                    self.__guardar_proyecto(nuevoproyecto)
                    self.__abrir_proyecto(
                        None,
                        os.path.join(nuevoproyecto["path"], "proyecto.ide"))

                dialog.destroy()

        elif accion == "Abrir Proyecto":
            from Widgets import My_FileChooser
            filechooser = My_FileChooser(
                parent_window=self.get_toplevel(),
                action_type=Gtk.FileChooserAction.OPEN,
                filter_type=["*.ide"],
                title="Abrir proyecto",
                path=BatovideWorkSpace)
            filechooser.connect('load', self.__abrir_proyecto)

        elif accion == "Guardar Proyecto":
            self.__guardar_archivos_de_proyecto()
            self.__guardar_proyecto(self.proyecto)

        elif accion == "Cerrar Proyecto":
            if self.cerrar_proyecto():
                self.proyecto = {}

        elif accion == "Ejecutar Proyecto":
            if self.proyecto:
                main = os.path.join(self.proyecto["path"],
                                    self.proyecto["main"])
                self.workpanel.ejecutar(archivo=main)

        elif accion == "Detener Ejecución":
            self.workpanel.detener_ejecucion()

        elif accion == "Construir":
            self.get_toplevel().set_sensitive(False)
            from Widget_Setup import DialogoSetup
            dialog = DialogoSetup(parent_window=self.get_toplevel(),
                                  proyecto=self.proyecto)

            dialog.run()
            dialog.destroy()
            self.get_toplevel().set_sensitive(True)

        else:
            print "Acccion sin asignar en BasePanel", accion

    def set_accion_codigo(self, widget, accion):
        """
        Cuando se hace click en una opción del menú Código.
        """
        self.workpanel.set_accion_codigo(accion)

    def set_accion_ver(self, widget, accion, valor):
        """
        Cuando se hace click en una opción del menú ver.
        """
        if accion == "Panel lateral":
            if not valor:
                self.infonotebook_box.hide()
            else:
                self.infonotebook_box.show()

        elif accion == "Numeracion" or accion == "Panel inferior":
            self.workpanel.set_accion_ver(accion, valor)

    def set_accion_archivo(self, widget, accion):
        """
        Cuando se hace click en la toolbar de archivos o
        se manda ejecutar una acción desde el menú.
        """

        if accion == "Nuevo Archivo":
            self.__abrir_archivo(None, None)

        elif accion == "Abrir Archivo":
            path = self.workpanel.get_default_path()

            if not path:
                path = BatovideWorkSpace
                if self.proyecto:
                    path = self.proyecto["path"]

            from Widgets import Multiple_FileChooser
            filechooser = Multiple_FileChooser(
                parent_window=self.get_toplevel(),
                title="Abrir Archivo",
                path=path,
                mime_type=["text/*", "image/svg+xml"])

            filechooser.connect('load', self.__abrir_archivo)

        elif accion == "Guardar Archivo":
            self.workpanel.guardar_archivo()

        elif accion == "Guardar Como":
            self.workpanel.guardar_archivo_como()

        elif accion in [
                "Deshacer", "Rehacer", "Copiar", "Cortar", "Pegar",
                "Seleccionar Todo", "Cerrar Archivo", "Buscar Texto",
                "Remplazar Texto"
        ]:
            self.workpanel.set_accion_archivos(accion)

        elif accion == "Ejecutar Archivo":
            self.workpanel.ejecutar()

        elif accion == "Detener Ejecución":
            self.workpanel.detener_ejecucion()

        else:
            print "Accion sin asignar en BasePanel", accion

    def external_open_proyect(self, ide_file):
        """
        Cuando se abre el editor con archivo como parámetro.
        """
        self.__abrir_proyecto(None, ide_file)

    def external_open_file(self, archivo):
        """
        Cuando se abre el editor con archivo como parámetro.
        """
        self.__abrir_archivo(None, archivo)
Esempio n. 4
0
class BasePanel(Gtk.Paned):

    __gtype_name__ = 'JAMediaEditorBasePanel'

    __gsignals__ = {
    'update': (GObject.SIGNAL_RUN_LAST,
        GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,)),
    'proyecto_abierto': (GObject.SIGNAL_RUN_LAST,
        GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
    'ejecucion': (GObject.SIGNAL_RUN_LAST,
        GObject.TYPE_NONE, (GObject.TYPE_STRING,
        GObject.TYPE_BOOLEAN)),
    'help': (GObject.SIGNAL_RUN_LAST,
        GObject.TYPE_NONE, (GObject.TYPE_STRING, GObject.TYPE_STRING))}

    def __init__(self):

        Gtk.Paned.__init__(self, orientation=Gtk.Orientation.HORIZONTAL)

        self.set_border_width(5)
        self.proyecto = {}
        self.dialogo_proyecto = False
        self.informewidget = False
        self.instalador = False

        self.workpanel = WorkPanel()
        self.infonotebook = InfoNotebook()

        self.toolbarproyecto = ToolbarProyecto()
        self.toolbararchivo = ToolbarArchivo()
        self.toolbarbusquedas = ToolbarBusquedas()

        self.infonotebook_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        self.infonotebook_box.pack_start(self.toolbarproyecto, False, False, 0)
        self.infonotebook_box.pack_start(self.infonotebook, True, True, 0)
        self.infonotebook_box.pack_end(self.toolbarbusquedas, False, False, 0)

        workpanel_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        workpanel_box.pack_start(self.toolbararchivo, False, False, 0)
        workpanel_box.pack_end(self.workpanel, True, True, 0)

        self.pack1(self.infonotebook_box, resize=False, shrink=False)
        self.pack2(workpanel_box, resize=True, shrink=True)

        self.show_all()
        self.infonotebook_box.set_size_request(280, -1)

        self.workpanel.connect('new_select', self.__set_introspeccion)
        self.workpanel.connect('ejecucion', self.__re_emit_ejecucion)
        self.workpanel.connect('update', self.__re_emit_update)

        self.toolbararchivo.connect('accion', self.set_accion_archivo)
        self.toolbarproyecto.connect('accion', self.set_accion_proyecto)

        self.toolbarbusquedas.connect("accion", self.__buscar_mas)
        self.toolbarbusquedas.connect("informe", self.__informar)

        self.infonotebook.connect('new_select', self.__set_linea)
        self.infonotebook.connect('open', self.__abrir_archivo)
        self.infonotebook.connect('search_on_grep', self.__search_grep)
        self.infonotebook.connect('remove_proyect', self.__remove_proyect)

    def __informar(self, widget):
        """
        Abre nueva lengueta en Workpanel con la información de Introspección
        del archivo seleccionado.
        """
        if self.informewidget:
            self.informewidget.destroy()
        self.informewidget = InformeWidget(self.get_toplevel())
        text = self.infonotebook.get_estructura()
        self.informewidget.setting(text)

    def __re_emit_update(self, widget, _dict):
        # Emite una señal con el estado general del archivo.
        self.emit("update", _dict)

    def __search_grep(self, widget, datos, parent):
        """
        Cuando se hace una busqueda grep en la estructura del proyecto y luego
        se selecciona una linea en los resultados de dicha búsqueda.
            Se abre el archivo
            Se selecciona y
            Se abre el dialogo buscar.
        """
        print "FIXME:", self.__search_grep
        '''
        self.__abrir_archivo(None, datos[0])

        paginas = self.workpanel.notebook_sourceview.get_n_pages()
        for indice in range(paginas):
            sourceview = self.workpanel.notebook_sourceview.get_nth_page(
                indice).get_child()

            visible = sourceview.get_show_line_numbers()
            sourceview.set_show_line_numbers(True)

            if sourceview.archivo == datos[0]:
                self.workpanel.notebook_sourceview.set_current_page(indice)
                break

        from Widgets import DialogoBuscar

        dialogo = DialogoBuscar(sourceview, parent_window=parent,
            title="Buscar Texto", texto=datos[2])

        dialogo.run()
        dialogo.destroy()
        sourceview.set_show_line_numbers(visible)
        '''

    def __buscar_mas(self, widget, accion, texto):
        self.infonotebook.buscar_mas(accion, texto)

    def __set_linea(self, widget, index, texto):
        """
        Recibe la linea seleccionada en instrospeccion y
        y la pasa a workpanel para ser seleccionada en el código.
        """
        self.workpanel.set_linea(index, texto)

    def __re_emit_ejecucion(self, widget, tipo, valor):
        # Cuando se ejecutan o detienen archivos en terminales.
        self.emit("ejecucion", tipo, valor)

    def __set_introspeccion(self, widget, view, tipo):
        """
        Cuando se selecciona una lengüeta en el Notebook:
            Recibe nombre y contenido de archivo para realizar
            introspeccion sobre él.
        """
        nombre = "Introspección"
        text = ''
        if view:
            _buffer = view.get_buffer()
            archivo = view.archivo
            if archivo:
                nombre = os.path.basename(archivo)
            inicio, fin = _buffer.get_bounds()
            text = _buffer.get_text(inicio, fin, 0)
        # Setear Introspeción.
        self.infonotebook.set_introspeccion(nombre, text, view, tipo)
        self.toolbarbusquedas.activar(bool(text))
        GLib.idle_add(self.__set_estructura, view, tipo)

    def __set_estructura(self, view, tipo):
        # FIXME: Verifica si hay archivos de proyecto y si los hay, actualiza
        # la vista de estructura. Otro punto de vista sería actualizar según
        # que archivo se ha seleccionado, en este caso, la vista de proyecto
        # solo sería activa si el archivo seleccionado está en el proyecto.
        path = self.proyecto.get("path", False)
        if path:
            if self.workpanel.get_archivos_de_proyecto(path):
                self.infonotebook.set_path_estructura(path)
                self.emit("proyecto_abierto", True)
            else:
                self.proyecto = {}
                self.emit("proyecto_abierto", False)
                self.infonotebook.set_path_estructura(False)
        else:
            self.proyecto = {}
            self.emit("proyecto_abierto", False)
            self.infonotebook.set_path_estructura(False)

    def __abrir_archivo(self, widget, archivo):
        if archivo:
            archivo = os.path.realpath(archivo)
            datos = commands.getoutput('file -ik \"%s\"' % (archivo))
            if "text" in datos or "x-python" in datos or \
                "x-empty" in datos or "svg+xml" in datos or \
                "application/xml" in datos:
                self.workpanel.abrir_archivo(archivo)
            else:
                print "FIXME: No se pudo abrir:", archivo, datos
        else:
            self.workpanel.abrir_archivo(False)

    def __abrir_proyecto(self, widget, archivo):
        archivo = os.path.realpath(archivo)
        extension = os.path.splitext(os.path.split(archivo)[1])[1]
        if not extension == ".ide":
            return

        arch = open(archivo, "r")
        proyecto = json.load(arch, "utf-8")
        arch.close()
        proyecto["path"] = os.path.dirname(archivo)

        # Validación de datos del proyecto.
        if not proyecto.get("nombre", False):
            return
        if not proyecto.get("main", False):
            proyecto["main"] = "main.py"

        main_path = os.path.join(proyecto["path"], proyecto["main"])
        if not os.path.exists(main_path):
            arch = open(main_path, "w")
            arch.write("#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n")
            arch.close()

        if self.cerrar_proyecto():
            self.proyecto = proyecto
            self.__abrir_archivo(False, main_path)

    def __guardar_archivos_de_proyecto(self):
        if not self.proyecto:
            return
        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto["path"])
        for view in codeviews:
            view.guardar()

    def __remove_proyect(self, widget):
        # Cuando se elimina el proyecto desde la vista de estructura.
        pass
        #self.workpanel.remove_proyect(self.proyecto["path"])
        #self.infonotebook.set_path_estructura(False)
        #self.proyecto = {}
        #return True

    def __dialogo_proyecto_run(self, title="Nuevo Proyecto", path=""):
        self.dialogo_proyecto = DialogoProyecto(
            parent_window=self.get_toplevel())
        self.dialogo_proyecto.connect("load", self.__abrir_proyecto)
        self.dialogo_proyecto.setting(title, path)

    def __dialogo_instalador_run(self, path):
        self.instalador = Instalador(self.get_toplevel(), path)
        self.instalador.connect("help", self.__emit_help)

    def __emit_help(self, widget, text, titulo):
        self.emit("help", text, titulo)

    def cerrar_proyecto(self):
        if not self.proyecto:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True
        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto.get("path", ""))
        if codeviews:
            # Cerrar Archivos. Esto pedirá guardar si hay cambios en él.
            for view in codeviews:
                view.set_accion("Cerrar Archivo")
        else:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True
        # Si algún archivo ha debido guardarse, no se ha cerrado.
        if not self.proyecto:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True
        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto.get("path", ""))
        if codeviews:
            # Cerrar Archivos.
            for view in codeviews:
                view.set_accion("Cerrar Archivo")
        else:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True
        # Si todavía hay archivos abiertos, el usuario no desea cerrarlos.
        if not self.proyecto:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True
        codeviews = self.workpanel.get_archivos_de_proyecto(
            self.proyecto.get("path", ""))
        if codeviews:
            return False
        else:
            self.proyecto = {}
            self.infonotebook.set_path_estructura(False)
            return True

    def set_accion_proyecto(self, widget, accion):
        """
        Cuando se hace click en la toolbar de proyecto o
        se manda ejecutar una acción desde el menú.
        """
        if self.dialogo_proyecto:
            self.dialogo_proyecto.destroy()
            self.dialogo_proyecto = False
        if self.instalador:
            self.instalador.destroy()
            self.instalador = False
        if accion == "Nuevo Proyecto":
            if self.cerrar_proyecto():
                self.__dialogo_proyecto_run("Nuevo Proyecto")
        elif accion == "Editar Proyecto":
            if self.proyecto:
                self.__dialogo_proyecto_run("Editar Proyecto",
                    self.proyecto["path"])
        elif accion == "Abrir Proyecto":
            filechooser = My_FileChooser(parent_window=self.get_toplevel(),
                action_type=Gtk.FileChooserAction.OPEN, filter_type=["*.ide"],
                title="Abrir proyecto", path=BatovideWorkSpace)
            filechooser.connect('load', self.__abrir_proyecto)
        elif accion == "Guardar Proyecto":
            self.__guardar_archivos_de_proyecto()
        elif accion == "Cerrar Proyecto":
            self.cerrar_proyecto()
        elif accion == "Ejecutar Proyecto":
            if self.proyecto:
                main = os.path.join(self.proyecto["path"],
                    self.proyecto["main"])
                self.workpanel.ejecutar(archivo=main)
        elif accion == "Detener Ejecución":
            self.workpanel.detener_ejecucion()
        elif accion == "Construir":
            self.__dialogo_instalador_run(self.proyecto["path"])
        else:
            print "Acccion sin asignar en BasePanel", accion

    def set_accion_codigo(self, widget, accion):
        # Cuando se hace click en una opción del menú Código.
        self.workpanel.set_accion_codigo(accion)

    def set_accion_ver(self, widget, accion, valor):
        # Cuando se hace click en una opción del menú ver.
        if accion == "Panel lateral":
            if not valor:
                self.infonotebook_box.hide()
            else:
                self.infonotebook_box.show()
        elif accion == "Numeracion" or accion == "Panel inferior":
            self.workpanel.set_accion_ver(accion, valor)

    def set_accion_archivo(self, widget, accion):
        """
        Cuando se hace click en la toolbar de archivos o
        se manda ejecutar una acción desde el menú.
        """
        if accion == "Nuevo Archivo":
            self.__abrir_archivo(None, None)
        elif accion == "Abrir Archivo":
            path = self.workpanel.get_default_path()
            if not path:
                path = BatovideWorkSpace
                if self.proyecto:
                    path = self.proyecto["path"]
            filechooser = Multiple_FileChooser(
                parent_window=self.get_toplevel(), title="Abrir Archivo",
                path=path, mime_type=["text/*", "image/svg+xml"])
            filechooser.connect('load', self.__abrir_archivo)
        elif accion == "Guardar Archivo":
            self.workpanel.guardar_archivo()
        elif accion == "Guardar Como":
            self.workpanel.guardar_archivo_como()
        elif accion in ["Deshacer", "Rehacer", "Copiar",
            "Cortar", "Pegar", "Seleccionar Todo", "Cerrar Archivo",
            "Buscar Texto", "Remplazar Texto"]:
            self.workpanel.set_accion_archivos(accion)
        elif accion == "Ejecutar Archivo":
            self.workpanel.ejecutar()
        elif accion == "Detener Ejecución":
            self.workpanel.detener_ejecucion()
        else:
            print "Accion sin asignar en BasePanel", accion

    def external_open_proyect(self, ide_file):
        # Cuando se abre el editor con archivo como parámetro.
        self.__abrir_proyecto(None, ide_file)

    def external_open_file(self, archivo):
        # Cuando se abre el editor con archivo como parámetro.
        self.__abrir_archivo(None, archivo)