#!/usr/bin/env python # -*- coding:UTF-8 -*- # objetos.py por: # Cristian García # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import mimetypes import os from gi.repository import Pango from gi.repository import Gtk from gi.repository import GObject from gi.repository import GtkSource from gi.repository import Gdk from gi.repository import Vte from gi.repository import GLib from Creditos import Creditos import Globales as G def dialogo_cerrar(direccion, buffer, cristianedit, accion): """Diálogo que cierra el programa o guarda según el usuario""" dialog = Gtk.MessageDialog(type=Gtk.MessageType(1)) dialog.add_buttons(Gtk.STOCK_NO, 0, Gtk.STOCK_YES, 1) archivo = direccion.split('/')[-1] dialog.set_markup('%s' % \ 'El archivo %s tiene cambios sin guardar' % archivo) dialog.format_secondary_text('¿Guardar antes de salir?') respuesta = dialog.run() dialog.destroy() if respuesta == 1: cristianedit.guardar(None, direccion=direccion) if accion == 'cerrar': Gtk.main_quit() def dialogo_reemplazar(direccion, buffer, cristianedit): """Preguntar si reemplazar o no, cuando la dirección ya existe""" dialog = Gtk.MessageDialog(type=Gtk.MessageType(2)) dialog.add_buttons(Gtk.STOCK_NO, 0, Gtk.STOCK_YES, 1) dialog.set_markup('%s' % 'La dirección especificada ya existe...') dialog.format_secondary_text( 'Sí sobrescribe el archivo, se reemplazará su contenido.') respuesta = dialog.run() dialog.destroy() if respuesta == 1: escritura = open(direccion, 'w') escritura.write(cristianedit.get_texto()) buffer.set_modified(False) escritura.close() else: dialog.destroy() class Menu(Gtk.MenuBar): """Barra de Menú""" def __init__(self, padre): Gtk.MenuBar.__init__(self) items = [] self.padre = padre self.grupo = Gtk.AccelGroup() self.recientes = [] self.ventana = self.padre.get_parent().get_parent() self.ventana.add_accel_group(self.grupo) menu_archivo = Gtk.MenuItem('_Archivo') menu_recientes = Gtk.MenuItem('_Recientes') menu_editar = Gtk.MenuItem('_Editar') menu_ayuda = Gtk.MenuItem('Ay_uda') menu_archivo.set_use_underline(True) menu_recientes.set_use_underline(True) menu_editar.set_use_underline(True) menu_ayuda.set_use_underline(True) self.add(menu_archivo) self.add(menu_editar) self.add(menu_ayuda) archivo = Gtk.Menu() self.menu_recientes = Gtk.Menu() editar = Gtk.Menu() ayuda = Gtk.Menu() menu_archivo.set_submenu(archivo) menu_editar.set_submenu(editar) menu_recientes.set_submenu(self.menu_recientes) menu_ayuda.set_submenu(ayuda) self.menu_item('_Nuevo', self.padre.pagina_nueva, archivo, 'N') archivo.append(Gtk.SeparatorMenuItem()) self.menu_item('_Abrir', self.padre.abrir, archivo, 'O') self.menu_item('_Guardar', self.padre.guardar, archivo, 'S') self.menu_item('Guardar _como', self.padre.guardar_como, archivo) archivo.append(Gtk.SeparatorMenuItem()) archivo.append(menu_recientes) self.menu_item('_Deshacer', self.deshacer, editar, 'Z') self.menu_item('_Rehacer', self.rehacer, editar, 'R') editar.append(Gtk.SeparatorMenuItem()) self.menu_item('In_sertar fecha y hora', self.padre.text_hora, editar) editar.append(Gtk.SeparatorMenuItem()) self.menu_item('_Estado del archivo', self.padre.estado, editar, 'E') editar.append(Gtk.SeparatorMenuItem()) self.menu_item('Mostrar _teclado...', self.teclado, editar, 'T') self.menu_item('Acerca _de', self.creditos, ayuda) def teclado(self, widget): texto = widget.get_label() if texto == 'Mostrar _teclado...': self.padre.mostrar_teclado(True) widget.set_label('Ocultar _teclado') else: self.padre.mostrar_teclado(False) widget.set_label('Mostrar _teclado...') def creditos(self, widget): """Muestra el diálogo con los créditos""" Creditos(self.padre.get_parent().get_parent()) def deshacer(self, widget): """Obtiene el view actual y le pasa deshacer""" view = self.padre.get_view() view.deshacer() def rehacer(self, widget): """Obtiene el view actual y le pasa rehacer""" view = self.padre.get_view() view.rehacer() def menu_item(self, etiqueta, callback, menu, letra=None, devolver=None): """Creando los item para los menús""" item = Gtk.MenuItem(etiqueta) item.connect('activate', callback) menu.append(item) item.set_use_underline(True) if letra: item.add_accelerator('activate', self.grupo, ord(letra), Gdk.ModifierType(4), Gtk.AccelFlags(1)) if devolver: return item def abrir_reciente(self, widget): """Abre un archivo desde un menuitem""" direccion = widget.get_label().split(' ')[-1] self.padre.abrir(None, direccion) def actualizar_recientes(self, recientes): """Agregar menuitems por cada archivo reciente""" self.borrar_recientes() numero = 1 if ', ' in recientes: lista = recientes.split(', ') for archivo in lista: if os.path.exists(archivo) and not archivo in self.recientes: asbpath = os.path.abspath(archivo) if os.path.exists(asbpath): direccion = asbpath else: direccion = archivo texto = '_' + str(numero) + ' - ' + direccion self.menu_item(texto, self.abrir_reciente, self.menu_recientes) self.recientes.append(archivo) numero += 1 self.show_all() def borrar_recientes(self): for item in self.menu_recientes: self.menu_recientes.remove(item) while len(self.recientes) != 0: for x in self.recientes: self.recientes.remove(x) class Buffer(GtkSource.Buffer): """Buffer de Texto""" def __init__(self): GtkSource.Buffer.__init__(self) self.lenguaje = None self.lenguaje_manager = G.lenguaje_manager self.lenguajes = G.lenguajes def buscar_lenguaje(self, filename, combo): """Busca el lenguaje de programación en un archivo al guardarlo o abrirlo, sí es que tiene uno""" lenguaje = self.lenguaje_manager.guess_language(filename, None) if lenguaje: self.set_highlight_syntax(True) self.set_language(lenguaje) try: nombre = lenguaje.get_name() numero = self.lenguajes.index(nombre.lower()) combo.set_active(numero + 1) except: pass else: self.set_highlight_syntax(False) combo.set_active(0) def get_lenguaje(self): """Devuelve el lenguaje seleccionado""" return self.lenguaje class View(GtkSource.View): """Visor de Texto""" def __init__(self, buffer=None): GtkSource.View.__init__(self) self.set_buffer(buffer) self.set_size_request(400, 500) self.lenguaje_manager = G.lenguaje_manager self.lenguajes = G.lenguajes self.estilo_manager = G.estilo_manager self.estilos = G.estilos def deshacer(self): """Deshace cambios""" if self.get_buffer().can_undo(): self.get_buffer().undo() def rehacer(self): """Rehace cambios""" if self.get_buffer().can_redo(): self.get_buffer().redo() def configurar(self, configuraciones): """Establecer configuración según los argumentos.""" buffer = self.get_buffer() enumeracion = configuraciones['enumeracion'] margen = configuraciones['margen'] is_margen = configuraciones['is_margen'] ajuste = configuraciones['ajuste'] ajuste_palabras = configuraciones['ajuste_palabras'] tabulador = configuraciones['tabulador'] insertar_espacios = configuraciones['insertar_espacios'] sangria = configuraciones['sangria'] tema = configuraciones['tema'] fuente = Pango.font_description_from_string(configuraciones['fuente']) self.set_property('show-line-numbers', enumeracion) self.set_property('right-margin-position', margen) self.set_property('show-right-margin', is_margen) if ajuste: self.set_wrap_mode(Gtk.WrapMode(1)) if ajuste and ajuste_palabras: self.set_wrap_mode(Gtk.WrapMode(2)) self.set_tab_width(tabulador) self.set_property('insert-spaces-instead-of-tabs', insertar_espacios) self.set_property('auto-indent', sangria) buffer.set_style_scheme(self.estilo_manager.get_scheme(tema)) self.modify_font(fuente) def buscar_texto(self, texto, enter=None): """Buscar Texto""" buffer = self.get_buffer() cursor_mark = buffer.get_insert() start = buffer.get_iter_at_mark(cursor_mark) if start.get_offset() == buffer.get_char_count(): start = buffer.get_start_iter() self.seleccionar_texto(texto, start, enter) def seleccionar_texto(self, text, start, enter): """Selecciona el texto solicitado, y mueve el scrolled sí es necesario""" buffer = self.get_buffer() end = buffer.get_end_iter() match = start.forward_search(text, 0, end) if match: match_start, match_end = match if not enter: buffer.select_range(match_start, match_end) else: buffer.select_range(match_end, match_start) self.scroll_to_iter(match_end, 0.1, 1, 1, 1) else: start = buffer.get_start_iter() try: self.seleccionar_texto(text, start, None) except RuntimeError: pass class Notebook(Gtk.Notebook): """Cuaderno de Fichas""" __gsignals__ = { 'boton-cerrar-clicked': (GObject.SIGNAL_RUN_FIRST, None, (object,)) } def __init__(self, padre=None): Gtk.Notebook.__init__(self) self.numero = 0 self.botones = [] self.labels = [] self.padre = padre self.set_scrollable(True) def agregar(self, objeto, label, barra): """Agrega una página al Widget clase""" hbox = Gtk.HBox() imagen = Gtk.Image() imagen.set_from_stock(Gtk.STOCK_CLOSE, Gtk.IconSize(4)) boton = Gtk.Button(None, image=imagen) hbox.pack_start(label, False, False, 0) hbox.pack_start(boton, False, False, 0) self.botones.append(boton) self.labels.append(label) vbox = Gtk.VBox() scrolled = self.crear_scrolled() vbox.pack_start(scrolled, True, True, 0) vbox.pack_start(barra, False, False, 0) scrolled.add(objeto) self.append_page(vbox, hbox) hbox.show() boton.show() label.show() self.show_all() numero = 0 for x in self.botones: x.numero = numero numero += 1 boton.connect('clicked', self.borrar_pagina_desde_boton, vbox) def crear_scrolled(self): """Crea y devuelve un GtkScrolledWindow()""" scrolled = Gtk.ScrolledWindow() scrolled.set_policy(Gtk.PolicyType(1), Gtk.PolicyType(1)) scrolled.set_shadow_type(Gtk.ShadowType(1)) return scrolled def borrar_pagina(self, numero=None): """Borra la página actual""" if numero == None: self.remove_page(self.get_current_page()) else: self.remove_page(numero) self.set_show_tabs(self.get_n_pages() > 1) def borrar_pagina_desde_boton(self, widget, objeto): """Borrar página desde el botón de cerrado""" self.emit('boton-cerrar-clicked', objeto) class Barra(Gtk.Toolbar): """Barra de herramientas.""" __gsignals__ = { 'abrir': (GObject.SIGNAL_RUN_FIRST, None, []), 'guardar': (GObject.SIGNAL_RUN_FIRST, None, []), 'nuevo': (GObject.SIGNAL_RUN_FIRST, None, []), 'deshacer': (GObject.SIGNAL_RUN_FIRST, None, []), 'rehacer': (GObject.SIGNAL_RUN_FIRST, None, []), 'ejecutar': (GObject.SIGNAL_RUN_FIRST, None, []), 'tipografia': (GObject.SIGNAL_RUN_FIRST, None, []), 'preferencias': (GObject.SIGNAL_RUN_FIRST, None, []), 'buscar_changed': (GObject.SIGNAL_RUN_FIRST, None, (str,)), 'buscar_activate': (GObject.SIGNAL_RUN_FIRST, None, (str,)), } def __init__(self): Gtk.Toolbar.__init__(self) self.toolbutton(Gtk.STOCK_OPEN, 'abrir', 'Abrir archivo.') self.toolbutton(Gtk.STOCK_SAVE, 'guardar', 'Guardar archivo.') self.separador() self.toolbutton(Gtk.STOCK_NEW, 'nuevo', 'Nuevo archivo.') self.separador() self.toolbutton(Gtk.STOCK_UNDO, 'deshacer', 'Deshacer cambios.') self.toolbutton(Gtk.STOCK_REDO, 'rehacer', 'Rehacer cambios.') #self.toolbutton(Gtk.STOCK_EXECUTE, 'ejecutar', 'Ejecutar archivo.') self.separador() self.toolbutton(Gtk.STOCK_SELECT_FONT, 'tipografia', 'Seleccionar fuente de texto.') self.toolbutton(Gtk.STOCK_PREFERENCES, 'preferencias', 'Preferencias.') self.separador() item = Gtk.ToolItem() self.add(item) entry = Gtk.Entry() entry.props.secondary_icon_stock = 'gtk-find' entry.connect('changed', self.emitir_buscar, 'buscar_changed') entry.connect('activate', self.emitir_buscar, 'buscar_activate') entry.connect('icon-release', self.emitir_buscar, 'buscar_activate') item.add(entry) self.show_all() def separador(self): """Crea y empaqueta un separador""" separador = Gtk.SeparatorToolItem() separador.set_size_request(10, 10) self.add(separador) def toolbutton(self, stock, senial, tooltip=None): """Crea un boton para el Widget clase""" toolbutton = Gtk.ToolButton(stock) toolbutton.connect('clicked', self.emitir, senial) if tooltip: toolbutton.set_tooltip_text(tooltip) self.add(toolbutton) def emitir(self, widget, senial): """Emite la señal que corresponde al argumento 'senial'.""" self.emit(senial) def emitir_buscar(self, widget, senial): """Emite la señal que corresponde al argumento 'senial', con el texto como parámetro.""" texto = widget.get_text() self.emit(senial, texto) class Navegador(Gtk.FileChooserDialog): """Navegador de archivos""" def __init__(self, titulo, padre, accion, botones): Gtk.FileChooserDialog.__init__(self, titulo, None, accion, botones) self.set_focus_visible(False) if accion == Gtk.FileChooserAction(0): self.set_select_multiple(True) self.set_default_response(1) filter = Gtk.FileFilter() boton = Gtk.Button(None, Gtk.STOCK_CANCEL) filter.set_name('Archivos de Texto') filter.add_mime_type('text/*') boton_ok = list(self.action_area)[0] self.action_area.remove(boton_ok) self.action_area.add(boton) self.action_area.add(boton_ok) self.add_filter(filter) boton.connect('clicked', self.cerrar) boton.show() def cerrar(self, widget): """Destruye al Widget clase""" self.destroy() class BarraInferior(Gtk.HBox): """Un GtkHBox() que contiene los Widgets de la parte inferior de la ventana""" def __init__(self): Gtk.HBox.__init__(self) self.combo = ComboLenguajes() self.b_estado = Gtk.Statusbar() self.b_estado.push(0, 'Línea:0, Columna:0') self.pack_end(self.b_estado, False, False, 20) self.pack_end(self.combo, False, False, 0) def get_combo(self): """Devuelve el GtkComboBoxText() con los lenguajes de programación""" return self.combo def get_statusbar(self): """Devuelve la barra de estado""" return self.b_estado class ComboEstilos(Gtk.ComboBoxText): """Un GtkComboBoxText para mostrar y utilizar los temas instalados en el sistema""" def __init__(self, estilo_principal=0): Gtk.ComboBoxText.__init__(self) for estilo in G.estilos: self.append_text(estilo) self.set_active(G.estilos.index(estilo_principal)) class ComboLenguajes(Gtk.ComboBoxText): """Un GtkComboBoxText para mostrar los lenguajes de programación instalados en el sistema""" def __init__(self): Gtk.ComboBoxText.__init__(self) self.lenguaje_manager = G.lenguaje_manager self.lenguajes = G.lenguajes for lenguaje in self.lenguajes: self.append_text(lenguaje) self.set_active(0) def update(self, view, direccion, buffer): """Muestra el lenguaje del View actual, esta función sire para cuando se cambia de página""" if direccion != 'Sin dirección': tipo = list(mimetypes.guess_type(direccion))[0] else: tipo = 'text/plain' self.buscar_lenguaje(tipo, buffer) def get_lenguajes(self): """Devuelve la lista con los lenguajes.""" return self.lenguajes def get_lenguaje_manager(self): """Devuelve la variable 'lenguaje_manager'.""" return self.lenguaje_manager class DialogoCerrar(Gtk.MessageDialog): """El díalogo que le pregunta al usuario sí en realidad quiere borrar la página del GtkNotebook()""" def __init__(self, direccion, pagina, notebook, lugares, etiquetas, padre): Gtk.MessageDialog.__init__(self, type=Gtk.MessageType(2), title='Hay cambios sin guardar') self.direccion = direccion self.pagina = pagina self.notebook = notebook self.lugares = lugares self.etiquetas = etiquetas self.padre = padre self.set_markup('%s' % 'Sí cierra, se perderán los cambios') boton_cerrar = Gtk.Button(None, Gtk.STOCK_CANCEL) boton_cerrar.connect('clicked', self.cerrar) self.action_area.add(boton_cerrar) boton_no = Gtk.Button('_No guardar') boton_no.connect('clicked', self.borrar) self.action_area.add(boton_no) boton_si = Gtk.Button(None, Gtk.STOCK_SAVE) boton_si.connect('clicked', self.guardar) self.action_area.add(boton_si) self.show_all() def cerrar(self, widget): """Cierra la clase destrullendola""" self.destroy() def borrar(self, widget): """Borra la pestaña""" self.etiquetas.remove(self.etiquetas[self.pagina]) self.lugares.remove(self.lugares[self.pagina]) self.notebook.borrar_pagina() self.cerrar(None) self.change_page(self, None, None) def guardar(self, widget): """Guarda el archivo antes de cerrar la pestaña""" if not self.direccion == 'Sin dirección': self.padre.guardar(None, direccion=self.direccion) else: self.padre.guardar_como(None) self.borrar(None) class DialogoEstado(Gtk.Dialog): def __init__(self, padre, notebook): Gtk.Dialog.__init__(self) self.padre = padre self.notebook = notebook self.label_caracteres = Gtk.Label() self.label_lineas = Gtk.Label() self.label_modificado = Gtk.Label() self.label_fuente = Gtk.Label() self.entry_lugar = Gtk.Entry() self.label_pestania = Gtk.Label() self.entry_lugar.set_editable(False) self.actualizar_estado() self.tabla = Gtk.Table(7, 2, False) label_caracteres = Gtk.Label('Cantidad de caractéres:') label_lineas = Gtk.Label('Cantidad de líneas:') entry_lugar = Gtk.Label('Ubicación de archivo:') label_modificado = Gtk.Label('Estado de modificación:') label_fuente = Gtk.Label('Fuente de Texto:') label_pestania = Gtk.Label('Pestaña actual:') lista = [self.label_caracteres, self.label_lineas, self.entry_lugar, self.label_modificado, self.label_pestania] for label in lista: label.modify_font(Pango.FontDescription('bold')) fuente = self.padre.get_fuente() fuente = Pango.FontDescription(fuente) fuente.set_size(14000) self.label_fuente.modify_font(fuente) self.tabla.attach(label_caracteres, 0, 1, 0, 1) self.tabla.attach(label_lineas, 0, 1, 1, 2) self.tabla.attach(entry_lugar, 0, 1, 2, 3) self.tabla.attach(label_modificado, 0, 1, 3, 4) self.tabla.attach(label_fuente, 0, 1, 4, 5) self.tabla.attach(label_pestania, 0, 1, 5, 6) self.tabla.attach(self.label_caracteres, 1, 2, 0, 1) self.tabla.attach(self.label_lineas, 1, 2, 1, 2) self.tabla.attach(self.entry_lugar, 1, 2, 2, 3) self.tabla.attach(self.label_modificado, 1, 2, 3, 4) self.tabla.attach(self.label_fuente, 1, 2, 4, 5) self.tabla.attach(self.label_pestania, 1, 2, 5, 6) self.vbox.pack_start(self.tabla, True, True, 0) boton_cerrar = Gtk.Button(None, Gtk.STOCK_CLOSE) boton_cerrar.connect('clicked', self.cerrar) self.action_area.add(boton_cerrar) boton_actualizar = Gtk.Button('_Actualizar estado') boton_actualizar.set_use_underline(True) boton_actualizar.connect('clicked', self.actualizar_estado) self.action_area.add(boton_actualizar) def actualizar_estado(self, *args): """Actualiza la información que se guarda y muestran en las etiquetas""" buffer = self.padre.get_buffer() direccion = self.padre.get_direccion() fuente = self.padre.get_fuente() pagina = self.notebook.get_current_page() + 1 paginas = self.notebook.get_n_pages() self.label_caracteres.set_text(str(buffer.get_char_count())) self.label_lineas.set_text(str(buffer.get_line_count())) self.label_fuente.set_text(fuente) self.entry_lugar.set_text(direccion) self.label_pestania.set_text(str(pagina) + '/' + str(paginas)) if buffer.get_modified(): self.label_modificado.set_text('Modificado') else: self.label_modificado.set_text('Sin modificar') def cerrar(self, widget): """Destruye al Widget clase""" self.destroy() class SelectordeFuente(Gtk.FontSelectionDialog): __gsignals__ = { 'font-changed': (GObject.SIGNAL_RUN_FIRST, None, (str,)) } def __init__(self, fuente): Gtk.FontSelectionDialog.__init__(self, title='Fuente de texto...') self.fuente = fuente close_button = Gtk.Button(None, Gtk.STOCK_CLOSE) ok_button = Gtk.Button(None, Gtk.STOCK_OK) for x in list(self.action_area): x.destroy() self.set_font_name(self.fuente) self.action_area.add(close_button) self.action_area.add(ok_button) ok_button.connect('clicked', self.aplicar_fuente) close_button.connect('clicked', self.cerrar) self.show_all() def aplicar_fuente(self, widget): """Emite la señal 'font-changed'""" self.emit('font-changed', self.get_font_name()) def cerrar(self, widget): """Destruye al Widget clase""" self.destroy() class Configuraciones(Gtk.Dialog): __gsignals__ = { 'configuration-changed': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)) } def __init__(self, padre, configuraciones): Gtk.Dialog.__init__(self, 'Configurar CristianEdit') self.padre = padre self.configuraciones = configuraciones self.set_resizable(False) notebook = Gtk.Notebook() vbox1 = Gtk.VBox() vbox2 = Gtk.VBox() vbox1.a = Gtk.HBox() vbox1.b = Gtk.HBox() self.vbox.pack_start(notebook, True, True, 0) boton_enumeracion = Gtk.CheckButton('Mostrar los números de líneas') boton_margen = Gtk.CheckButton('Mostrar margen derecho en la columna:') boton_ajuste1 = Gtk.CheckButton('Ajuste de Texto') boton_ajuste2 = Gtk.CheckButton('No dividir palabras en dos líneas') boton_insertar = Gtk.CheckButton( 'Insertar espacios en lugar de tabulaciones') boton_sangria = Gtk.CheckButton('Sangría automatica') ajuste1 = Gtk.Adjustment(self.configuraciones['margen'], 1, 1000, 1, 10) ajuste2 = Gtk.Adjustment(self.configuraciones['tabulador'], 1, 30, 1, 10) spin1 = Gtk.SpinButton() spin2 = Gtk.SpinButton() label1 = Gtk.Label('Editor') label2 = Gtk.Label('Taulador') label3 = Gtk.Label('Sangría') label4 = Gtk.Label('Tema de colores') l = [label1, label2, label3, label4] for x in l: x.modify_font(Pango.FontDescription('bold')) boton_margen.set_active(self.configuraciones['is_margen']) boton_enumeracion.set_active(self.configuraciones['enumeracion']) spin1.set_adjustment(ajuste1) spin2.set_adjustment(ajuste2) boton_ajuste1.set_active(self.configuraciones['ajuste']) boton_ajuste2.set_active(self.configuraciones['ajuste_palabras']) boton_insertar.set_active(self.configuraciones['insertar_espacios']) boton_sangria.set_active(self.configuraciones['sangria']) spin1.set_sensitive(boton_margen.get_active()) boton_ajuste2.set_sensitive(boton_ajuste1.get_active()) boton_enumeracion.connect('clicked', self.change_enumeracion) spin1.connect('value-changed', self.margen_changed) spin2.connect('value-changed', self.tabulador_changed) boton_margen.connect('clicked', self.is_margen_changed, spin1) boton_ajuste1.connect('clicked', self.change_ajuste, boton_ajuste2) boton_ajuste2.connect('clicked', self.change_ajuste_palabras) boton_insertar.connect('clicked', self.insertar_espacios_changed) boton_sangria.connect('clicked', self.sangria_changed) vbox1.pack_start(label1, False, False, 10) vbox1.pack_start(boton_enumeracion, False, False, 0) vbox1.pack_start(vbox1.a, False, False, 0) vbox1.pack_start(label2, False, False, 10) vbox1.pack_start(vbox1.b, False, False, 0) vbox1.pack_start(boton_sangria, False, False, 0) vbox1.pack_start(boton_insertar, False, False, 0) vbox1.a.pack_start(boton_margen, False, False, 0) vbox1.a.pack_start(spin1, False, False, 0) vbox1.b.pack_start(Gtk.Label('Ancho del tabulador:'), False, False, 0) vbox1.b.pack_start(spin2, False, False, 0) vbox1.pack_start(label3, False, False, 10) vbox1.pack_start(boton_ajuste1, False, False, 0) vbox1.pack_start(boton_ajuste2, False, False, 0) combo_estilos = ComboEstilos(self.configuraciones['tema']) print "\n\n\n\n\n", self.configuraciones['tema'], "\n\n\n\n\n" combo_estilos.connect('changed', self.estilo_changed) vbox2.pack_start(label4, False, False, 10) vbox2.pack_start(combo_estilos, False, False, 0) notebook.append_page(vbox1, Gtk.Label('Editor')) notebook.append_page(vbox2, Gtk.Label('Temas de colores')) boton = Gtk.Button(None, Gtk.STOCK_OK) boton.connect('clicked', self.cerrar) self.action_area.add(boton) def estilo_changed(self, widget): """Establece en tema de colores""" self.configuraciones['tema'] = G.estilos[widget.get_active()] self.emit('configuration-changed', self.configuraciones) def sangria_changed(self, widget): """Establece o desabilita la sangría automatica""" self.configuraciones['sangria'] = widget.get_active() self.emit('configuration-changed', self.configuraciones) def insertar_espacios_changed(self, widget): """Establece sí resaltar la línea actual o no""" self.configuraciones['insertar_espacios'] = widget.get_active() self.emit('configuration-changed', self.configuraciones) def tabulador_changed(self, widget): """Establece el ancho del tabulador""" self.configuraciones['tabulador'] = widget.get_value() self.emit('configuration-changed', self.configuraciones) def change_ajuste(self, widget, boton): """Activa/Desactiva ajuste de texto""" self.configuraciones['ajuste'] = widget.get_active() boton.set_sensitive(self.configuraciones['ajuste']) if self.configuraciones['ajuste']: self.configuraciones['ajuste_palabras'] = False if boton.get_active() and boton.get_sensitive(): self.configuraciones['ajuste_palabras'] = True self.emit('configuration-changed', self.configuraciones) def change_ajuste_palabras(self, widget): """Ajuste por palabras, no divide las palabras en dos líneas""" self.configuraciones['ajuste_palabras'] = widget.get_active() self.emit('configuration-changed', self.configuraciones) def change_enumeracion(self, widget): """Hace que la enumeración sea igual al estado de activación del botón""" self.configuraciones['enumeracion'] = widget.get_active() self.emit('configuration-changed', self.configuraciones) def margen_changed(self, widget): """Establece en la columna en la que se muestra el margen derecho""" self.configuraciones['margen'] = widget.get_value() self.emit('configuration-changed', self.configuraciones) def is_margen_changed(self, widget, spin): """Establece sí el usuario quiere o no margen derecho""" self.configuraciones['is_margen'] = widget.get_active() spin.set_sensitive(self.configuraciones['is_margen']) self.emit('configuration-changed', self.configuraciones) def cerrar(self, widget): """Destruir al Widget clase""" self.destroy() class DialogoAdvertencia(Gtk.Dialog): def __init__(self, padre, direccion, cristianedit): Gtk.Dialog.__init__(self, 'Hay cambios sin guardar', padre, Gtk.DialogFlags.MODAL, buttons=(Gtk.STOCK_CANCEL, 0, Gtk.STOCK_OK, 1)) self.direccion = direccion self.cristianedit = cristianedit if direccion == 'Sin dirección': nombre = 'Sin título' else: nombre = direccion.split('/')[-1] label = Gtk.Label('El archivo %s se ha modificado y no se han guardado\ los cambios, ¿Desdea guardar antes de salir?' % nombre) label.modify_font(Pango.FontDescription('bold')) respuesta = self.run() if respuesta == 0: Gtk.main_quit() elif respuesta == 1: self.cristianedit.guardar(None, self.direccion) class Teclado(Gtk.Dialog): def __init__(self, padre): Gtk.Dialog.__init__(self) self.estado = 'minusculas' self.padre = padre self.set_title('Teclado de CristianEdit 2') self.set_resizable(False) vbox = Gtk.VBox() self.vbox.hbox = Gtk.HBox() self.vbox.vbox = Gtk.VBox() self.vbox.hbox0 = Gtk.HBox() self.vbox.hbox1 = Gtk.HBox() self.vbox.hbox2 = Gtk.HBox() self.vbox.hbox3 = Gtk.HBox() self.vbox.hbox4 = Gtk.HBox() self.vbox.hbox5 = Gtk.HBox() self.vbox.hbox6 = Gtk.HBox() self.vbox.pack_start(self.vbox.hbox, False, False, 0) self.vbox.hbox.pack_start(self.vbox.vbox, True, True, 0) self.vbox.hbox.pack_start(vbox, True, True, 0) self.vbox.vbox.pack_start(self.vbox.hbox0, False, False, 10) self.vbox.vbox.pack_start(self.vbox.hbox1, False, False, 0) self.vbox.vbox.pack_start(self.vbox.hbox2, False, False, 0) self.vbox.vbox.pack_start(self.vbox.hbox3, False, False, 0) self.vbox.vbox.pack_start(self.vbox.hbox4, False, False, 10) self.vbox.vbox.pack_start(self.vbox.hbox5, False, False, 0) self.vbox.vbox.pack_start(self.vbox.hbox6, False, False, 10) borrar = Gtk.Button('Borrar') borrar.connect('pressed', self.borrar) vbox.pack_start(borrar, False, False, 4) enter = Gtk.Button('Enter') enter.connect('pressed', self.clic, '\n') vbox.pack_start(enter, True, True, 10) espacio = Gtk.Button('Espacio') espacio.connect('pressed', self.clic, ' ') self.vbox.hbox6.pack_start(espacio, True, True, 10) self.lista0 = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'] self.lista1 = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'] self.lista2 = ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ñ'] self.lista3 = ['z', 'x', 'c', 'v', 'b', 'n', 'm'] self.lista4 = ['á', 'é', 'í', 'ó', 'ú'] self.lista5 = ['¿', '?', '¡', '+', '*', '-', '{', '}', '[', ']', "'"] for x in self.lista5: boton = Gtk.Button(x) boton.modify_font(Pango.FontDescription('bold')) boton.connect('pressed', self.clic) self.vbox.hbox5.pack_start(boton, False, False, 0) self.recargar() boton_cambio = Gtk.Button('_Mostrar Mayúsculas') boton_cambio.set_use_underline(True) boton_cambio.connect('clicked', self.cambio) self.action_area.add(boton_cambio) boton_cerrar = Gtk.Button(None, Gtk.STOCK_CLOSE) boton_cerrar.connect('clicked', self.cerrar) self.action_area.add(boton_cerrar) self.action_area.show() boton_cerrar.show() def cerrar(self, widget): """Destruye al Widget clase""" self.destroy() def recargar(self): """Borra y crea los botones nuevamente""" for x in self.vbox.hbox0: x.destroy() for x in self.vbox.hbox1: x.destroy() for x in self.vbox.hbox2: x.destroy() for x in self.vbox.hbox3: x.destroy() for x in self.vbox.hbox4: x.destroy() for letra0 in self.lista0: boton = Gtk.Button(letra0) boton.modify_font(Pango.FontDescription('bold')) boton.connect('pressed', self.clic) self.vbox.hbox0.pack_start(boton, False, False, 0) for letra1 in self.lista1: boton = Gtk.Button(letra1) boton.modify_font(Pango.FontDescription('bold')) boton.connect('pressed', self.clic) self.vbox.hbox1.pack_start(boton, False, False, 0) for letra2 in self.lista2: boton = Gtk.Button(letra2) boton.modify_font(Pango.FontDescription('bold')) boton.connect('pressed', self.clic) self.vbox.hbox2.pack_start(boton, False, False, 0) for letra3 in self.lista3: boton = Gtk.Button(letra3) boton.modify_font(Pango.FontDescription('bold')) boton.connect('pressed', self.clic) self.vbox.hbox3.pack_start(boton, False, False, 0) for letra4 in self.lista4: boton = Gtk.Button(letra4) boton.modify_font(Pango.FontDescription('bold')) boton.connect('pressed', self.clic) self.vbox.hbox4.pack_start(boton, False, False, 0) self.show_all() def cambio(self, widget): """Cambia las letras por mayúsculas a minúsculas y viceversa""" if self.estado != 'minusculas': self.lista0 = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'] self.lista1 = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'] self.lista2 = ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ñ'] self.lista3 = ['z', 'x', 'c', 'v', 'b', 'n', 'm'] self.lista4 = ['á', 'é', 'í', 'ó', 'ú'] self.estado = 'minusculas' widget.set_label('_Mostrar Mayúsculas') else: self.lista0 = ['!', '"', '#', '$', '%', '&', '/', '(', ')', '='] self.lista1 = ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'] self.lista2 = ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Ñ'] self.lista3 = ['Z', 'X', 'C', 'V', 'B', 'N', 'M'] self.lista4 = ['Á', 'É', 'Í', 'Ó', 'Ú'] self.estado = 'mayusculas' widget.set_label('_Mostrar Minúsculas') self.recargar() def clic(self, widget, especial=None): """Escribe el texto""" buffer = self.padre.get_buffer() if not especial: texto = widget.get_label() else: texto = especial buffer.insert_at_cursor(texto) def borrar(self, widget): """Borrar el carácter actual""" buffer = self.padre.get_buffer() if buffer.get_selection_bounds(): start, end = buffer.get_bounds() inicio, fin = buffer.get_selection_bounds() texto_start = list(buffer.get_text(start, inicio, 0)) texto_end = list(buffer.get_text(fin, end, 0)) string1 = '' string2 = '' for x1 in texto_start: string1 = string1 + x1 for x2 in texto_end: string1 = string1 + x2 else: start, fin = buffer.get_bounds() actual = buffer.get_iter_at_mark(buffer.get_insert()) numero = actual.get_offset() texto_start = list(buffer.get_text(start, actual, 0))[:numero - 1] texto_end = list(buffer.get_text(actual, fin, 0))#[numero:] string1 = '' string2 = '' for x1 in texto_start: string1 = string1 + x1 for x2 in texto_end: string2 = string2 + x2 buffer.set_text(string1 + string2) class TerminalToolbar(Gtk.Toolbar): def __init__(self, padre): Gtk.Toolbar.__init__(self) self.padre = padre self.toolbutton(Gtk.STOCK_NEW, 'Nueva terminal', self.crear_pagina) def crear_pagina(self, widget): """Llama a la función de CristianEdit con el mismo nombre""" self.padre.crear_pagina() def toolbutton(self, stock, tooltip=None, callback=None): """Crea un boton para el Widget clase""" toolbutton = Gtk.ToolButton(stock) self.add(toolbutton) if callback: toolbutton.connect('clicked', callback) if tooltip != None: toolbutton.set_tooltip_text(tooltip) class Terminal(Vte.Terminal): def configurar(self): """Configura al Widget clase""" #shape: 0: Normal - Block # 1: Barra simple - Ibeam # 2: Guión bajo - Underline shape = Vte.TerminalCursorShape(2) fg_color = '#00FF00' bg_color = '#000000' lineas = 1000 fuente = 'Monospace' transparente = True nivel = 0.50 self.set_cursor_shape(shape) self.set_colors(Gdk.color_parse(fg_color), Gdk.color_parse(bg_color), []) self.set_scrollback_lines(lineas) self.set_font(Pango.FontDescription(fuente)) self.set_background_transparent(transparente) self.set_background_saturation(nivel) def __init__(self, direccion, emulacion): Vte.Terminal.__init__(self) vteflags = Vte.PtyFlags(1) lista = ['algo'] glibflags = GLib.SpawnFlags(1) algo = 'algo' self.configurar() #banderas de vte, dirección, emulación, lista, banderas de glib, función self.fork_command_full(vteflags, direccion, emulacion, lista, glibflags, self.benvienida, algo) def benvienida(self, widget): """Imprime un texto cuando recién se crea el Widget clase""" print G.BIENVENIDA def tecla(self, widget, event): """Obtiene el evento de teclado y llama a la función evento""" tecla = Gdk.keyval_name(event.keyval) self.evento(event) def evento(self, event): """Reacciona a los eventos de teclado""" pass class TerminalNotebook(Gtk.Notebook): __gsignals__ = { 'boton-cerrar-clicked': (GObject.SIGNAL_RUN_FIRST, None, (object,)) } def __init__(self): Gtk.Notebook.__init__(self) self.set_scrollable(True) def nueva_pagina(self, objeto, label): """Crea una página al Widget clase""" vbox = Gtk.VBox() scrolled = Gtk.ScrolledWindow() hbox = Gtk.HBox() boton = Gtk.ToolButton(Gtk.STOCK_CLOSE) hbox.pack_start(label, False, False, 0) hbox.pack_start(boton, False, False, 0) vbox.add(scrolled) scrolled.add(objeto) self.append_page(vbox, hbox) hbox.show_all() boton.connect('clicked', self.cerrar, vbox) def borrar_pagina(self, numero=None): """Borra una página según un número, o la actual""" if not numero: numero = self.get_current_page() self.remove_page(numero) def desplazar_al_final(self): """Activa la última pestaña""" numero = self.get_n_pages() for x in range(0, numero): self.next_page() def cerrar(self, widget, objeto): """Emite la señal 'boton-cerrar-clicked'""" self.emit('boton-cerrar-clicked', objeto)