diff options
author | Rogelio Mita <rogeliomita@activitycentral.com> | 2013-06-26 21:00:31 (GMT) |
---|---|---|
committer | Rogelio Mita <rogeliomita@activitycentral.com> | 2013-06-26 21:00:31 (GMT) |
commit | 23f9d64c6fc0dbbc964cda50ed137f66b84043b7 (patch) | |
tree | 82b433689ea3bfbd0a26ecce84ebaec3243f051b | |
parent | 34a0ae4ae48d6df490eeb581a7f072545b3595d5 (diff) |
Porting page button behavior to gtk3. BugFix BACK_PATH into gtk2 app
-rw-r--r-- | CeibalEncuesta/gtk2/CeibalEncuesta/CeibalEncuesta.py | 5 | ||||
-rwxr-xr-x | CeibalEncuesta/gtk3/CeibalEncuesta/CeibalEncuesta.py | 41 | ||||
-rwxr-xr-x | CeibalEncuesta/gtk3/CeibalEncuesta/Widgets.py | 146 |
3 files changed, 161 insertions, 31 deletions
diff --git a/CeibalEncuesta/gtk2/CeibalEncuesta/CeibalEncuesta.py b/CeibalEncuesta/gtk2/CeibalEncuesta/CeibalEncuesta.py index 2411457..d14fa68 100644 --- a/CeibalEncuesta/gtk2/CeibalEncuesta/CeibalEncuesta.py +++ b/CeibalEncuesta/gtk2/CeibalEncuesta/CeibalEncuesta.py @@ -119,7 +119,8 @@ class CeibalEncuesta(gtk.Window): self.__init() if getattr(self, "poll_id", None): - BACKUP_PATH = BACKUP_PATH + "/%s.encuesta" % self.poll_id + if str(self.poll_id) not in BACKUP_PATH: + BACKUP_PATH = BACKUP_PATH + "/%s.encuesta" % self.poll_id if not os.path.exists(BACKUP_PATH): self.__save_json(path=BACKUP_PATH) @@ -664,7 +665,7 @@ class CeibalEncuesta(gtk.Window): bck_path = BACKUP_PATH + "/%s.encuesta" % self.poll_id if os.path.exists(bck_path): - msg = """ + msg = u""" Existe un archivo temporal para esta encuesta en %s, si desea recuperarlo, debe utilizar la opcion 'seleccionar encuesta anterior' del asistente. Pero si desea continuar, este archivo será remplazado.""" % bck_path diff --git a/CeibalEncuesta/gtk3/CeibalEncuesta/CeibalEncuesta.py b/CeibalEncuesta/gtk3/CeibalEncuesta/CeibalEncuesta.py index b3e99da..3ceb360 100755 --- a/CeibalEncuesta/gtk3/CeibalEncuesta/CeibalEncuesta.py +++ b/CeibalEncuesta/gtk3/CeibalEncuesta/CeibalEncuesta.py @@ -35,7 +35,7 @@ from gi.repository import GObject from Widgets import Panel from Widgets import InfoWidget from Widgets import My_FileChooser -from Widgets import My_Alert_Dialog +from Widgets import My_Alert_Dialog, My_Alert_Dialog3 from Widgets import Wizard import Globales as G @@ -124,7 +124,8 @@ class CeibalEncuesta(Gtk.Window): self.__init() if getattr(self, "poll_id", None): - BACKUP_PATH = BACKUP_PATH + "/%s.encuesta" % self.poll_id + if str(self.poll_id) not in BACKUP_PATH: + BACKUP_PATH = BACKUP_PATH + "/%s.encuesta" % self.poll_id if not os.path.exists(BACKUP_PATH): self.__save_json(path=BACKUP_PATH) @@ -142,7 +143,7 @@ class CeibalEncuesta(Gtk.Window): response = dialog.run() if Gtk.ResponseType(response) == Gtk.ResponseType.CANCEL: - pass + self.emit("destroy") else: encuesta_nueva = dialog.label_1.get_text() @@ -150,12 +151,14 @@ class CeibalEncuesta(Gtk.Window): encuesta_anterior = dialog.label_3.get_text() if encuesta_nueva and lista and not encuesta_anterior: - self.__load_encuesta(None, encuesta_nueva) + continue_ = self.__load_encuesta(None, encuesta_nueva) + if not continue_: + reset = True + else: + while Gtk.events_pending(): + Gtk.main_iteration() - while Gtk.events_pending(): - Gtk.main_iteration() - - self.__load_encuestados(None, lista) + self.__load_encuestados(None, lista) elif encuesta_anterior and not encuesta_nueva and not lista: self.__load_encuesta_respondida(None, encuesta_anterior) @@ -596,6 +599,7 @@ class CeibalEncuesta(Gtk.Window): Carga una encuesta almacenada en un archivo json o shelve. """ + global BACKUP_PATH if os.path.exists(TEMPPATH): os.remove(TEMPPATH) @@ -654,6 +658,24 @@ class CeibalEncuesta(Gtk.Window): self.poll_id = poll_id + bck_path = BACKUP_PATH + "/%s.encuesta" % self.poll_id + if os.path.exists(bck_path): + msg = u""" + Existe un archivo temporal para esta encuesta en %s, + si desea recuperarlo, debe utilizar la opcion 'seleccionar encuesta anterior' del asistente. + Pero si desea continuar, este archivo será remplazado.""" % bck_path + dialog = My_Alert_Dialog3( + parent_window = self.get_toplevel(), label = msg) + + response = dialog.run() + + if Gtk.ResponseType(response) != Gtk.ResponseType.ACCEPT: + dialog.destroy() + return False + + dialog.destroy() + os.remove(bck_path) + self.panel.load_encuesta(encuesta) dict = { @@ -671,6 +693,8 @@ class CeibalEncuesta(Gtk.Window): self.__check_sensitive() + return True + def __check_sensitive(self): if self.panel.encuesta and self.panel.lista: @@ -723,7 +747,6 @@ class CeibalEncuesta(Gtk.Window): os.remove(TEMPPATH) def __salir(self, widget = None, senial = None): - sys.exit(0) if __name__ == "__main__": diff --git a/CeibalEncuesta/gtk3/CeibalEncuesta/Widgets.py b/CeibalEncuesta/gtk3/CeibalEncuesta/Widgets.py index 7d832b4..63fed94 100755 --- a/CeibalEncuesta/gtk3/CeibalEncuesta/Widgets.py +++ b/CeibalEncuesta/gtk3/CeibalEncuesta/Widgets.py @@ -36,6 +36,7 @@ WORKPATH = os.path.join(HOME, "CeibalEncuesta") PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) ICON = PROJECT_ROOT + '/Iconos/ceibal.png' NEXT_PAGE_ACTIVE = PROJECT_ROOT + "/Iconos/next-page-active.png" +NEXT_PAGE_INACTIVE = PROJECT_ROOT + "/Iconos/next-page-inactive.png" NEXT_PAGE_OVER = PROJECT_ROOT + "/Iconos/next-page-over.png" NEXT_PAGE_DOWN = PROJECT_ROOT + "/Iconos/next-page-down.png" PREV_PAGE_ACTIVE = PROJECT_ROOT + "/Iconos/prev-page-active.png" @@ -122,7 +123,6 @@ class Panel(Gtk.Paned): self.scroll_list.set_policy( Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - # self.scroll_list.add_with_viewport(self.lista) box.pack_start(self.scroll_list, True, True, 0) @@ -174,16 +174,55 @@ class Panel(Gtk.Paned): break if index_visible == 0: - self.toolbar_encuesta.anterior.set_sensitive(False) + self.toolbar_encuesta.anterior.hide() else: - self.toolbar_encuesta.anterior.set_sensitive(True) + self.toolbar_encuesta.anterior.show_now() if index_visible == grupos.index(grupos[-1]): - self.toolbar_encuesta.siguiente.set_sensitive(False) - + self.toolbar_encuesta.siguiente.hide() else: - self.toolbar_encuesta.siguiente.set_sensitive(True) + self.toolbar_encuesta.siguiente.show_now() + + self.toolbar_encuesta.siguiente.emit("update_status", self) + + def current_group(self): + grupos = self.box_encuesta.get_children() + + for child in grupos: + if child.get_visible(): + index_visible = grupos.index(child) + break + + return grupos[index_visible] + + def visible_questions(self): + + visible_questions = [] + + current_group = self.current_group() + + for question in current_group.box_preguntas: + if question.get_visible(): + visible_questions.append(question) + + return visible_questions + + def incomplete_questions(self): + without_answer = [] + + for question in self.visible_questions(): + active_options = question.widget_obtions.get_active_options() + # TODO: Revisar get_active_options para que funcione con cualquier + # tipo de widget y no diferenciar cuando es TextInput + if not len(active_options): + if question.pregunta.get("widget_type", None) == "TextInput": + if not question.widget_obtions.get_text().strip(): + without_answer.append(question) + else: + without_answer.append(question) + + return without_answer def __accion_encuesta(self, widget, accion): """ @@ -191,8 +230,6 @@ class Panel(Gtk.Paned): a otro según valor de accion. """ - self._window.get_vadjustment().set_value(0) - index_visible = 0 grupos = self.box_encuesta.get_children() @@ -206,11 +243,13 @@ class Panel(Gtk.Paned): if index_visible > 0: map(self.__hide_groups, grupos) map(self.__show_groups, [grupos[index_visible - 1]]) + self._window.get_vadjustment().set_value(0) - elif accion == "Siguiente": + elif accion == "Siguiente" and self.toolbar_encuesta.siguiente.active: if index_visible < len(grupos)-1: map(self.__hide_groups, grupos) map(self.__show_groups, [grupos[index_visible + 1]]) + self._window.get_vadjustment().set_value(0) self.__check_sensibility_butons() @@ -854,12 +893,18 @@ class Grupo(Gtk.Frame): self.show_all() + def __emit_update_button(self): + panel = self.get_toplevel().panel + siguiente = panel.toolbar_encuesta.siguiente + siguiente.emit("update_status", panel) + def __emit_text_and_change(self, pregunta, id_opcion, text, activan): """ Cuando el usuario ingresa algún valor en una entrada de texto, se manda guardar los datos y chequear las dependencias. """ + self.__emit_update_button() self.emit("text_and_change", pregunta, id_opcion, text, activan) def __change(self, widget, activan): @@ -868,6 +913,7 @@ class Grupo(Gtk.Frame): dependencias y se guardan los datos. """ + self.__emit_update_button() self.emit("new", widget, activan) def update(self, dict): @@ -878,6 +924,7 @@ class Grupo(Gtk.Frame): esos valores. """ + self.__emit_update_button() for child in self.box_preguntas.get_children(): # Si se respondió esta pregunta @@ -910,6 +957,9 @@ class Pregunta(Gtk.VBox): GObject.TYPE_NONE,(GObject.TYPE_STRING, GObject.TYPE_STRING,GObject.TYPE_PYOBJECT))} + def __str__(self): + return "pos: %s, pregunta: %s" % (self.indice, self.pregunta["name"]) + def __init__(self, indice_pregunta, pregunta): Gtk.VBox.__init__(self) @@ -923,7 +973,7 @@ class Pregunta(Gtk.VBox): self.widget_obtions = None widget = self.pregunta["widget_type"] - print self.pregunta["options"] + if widget == "DropDownList": self.widget_obtions = Widget_DropDownList(self.pregunta["options"].copy()) self.widget_obtions.connect("new", self.__change) @@ -947,6 +997,7 @@ class Pregunta(Gtk.VBox): pangoFont = Pango.FontDescription(QUESTION_FONT_SIZE) label.modify_font(pangoFont) label.set_line_wrap(True) + #label.set_size_request(900, -1) # --- QUESTION TITLE INDENT: horizontal alignment halign = Gtk.Alignment() @@ -1642,14 +1693,20 @@ class ToolbarEncuesta(Gtk.HBox): class PageButton(Gtk.Button): __gsignals__ = { - "enter-notify-event" : "override" + "enter-notify-event" : "override", + "update_status":( + GObject.SIGNAL_RUN_FIRST, + GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT, ) + ) } def __init__(self, label, img, imgs, *args, **kwargs): Gtk.Button.__init__(self, None, *args, **kwargs) + self.label = None self.accion = label + self.active = True self.imgs = { "normal": img, @@ -1664,10 +1721,10 @@ class PageButton(Gtk.Button): box = Gtk.HBox() if label: - label = Gtk.Label(label) - label.set_padding(10, 0) - label.modify_fg(0, Gdk.color_parse("#B40404")) - box.pack_start(label, False, False, 0) + self.label = Gtk.Label(label) + self.label.set_padding(10, 0) + self.label.modify_fg(0, Gdk.color_parse("#B40404")) + box.pack_start(self.label, False, False, 0) box.pack_start(self.img_normal, False, False, 0) self.add(box) @@ -1678,6 +1735,27 @@ class PageButton(Gtk.Button): self.connect("activate", self.__button_event, "down") self.connect("enter", self.__button_event, "enter") self.connect("leave", self.__button_event, "leave") + self.connect("update_status", self.__update_status) + + def __update_status(self, widget, panel): + + new_img = NEXT_PAGE_ACTIVE + incomplete_questions = panel.incomplete_questions() + color = "#B40404" + + if len(incomplete_questions): + new_img = NEXT_PAGE_INACTIVE + color = "#7EAD45" + self.active = False + else: + self.active = True + + img = Gtk.Image() + img_pixbuf = GdkPixbuf.Pixbuf.new_from_file(new_img) + img_scaled = img_pixbuf.scale_simple( + 45, 45, GdkPixbuf.InterpType.BILINEAR) + self.img_normal.set_from_pixbuf(img_scaled) + if self.label: self.label.modify_fg(0, Gdk.color_parse(color)) def do_enter_notify_event(self, widget): @@ -1685,6 +1763,8 @@ class PageButton(Gtk.Button): def __button_event(self, widget, img_file=None): + if not self.active: return + if img_file is None: return img = Gtk.Image() @@ -2034,7 +2114,9 @@ class Wizard(Gtk.Dialog): flags = Gtk.DialogFlags.MODAL, buttons = [ "Proceder", Gtk.ResponseType.ACCEPT, - "Cancelar", Gtk.ResponseType.CANCEL]) + "Salir", Gtk.ResponseType.CANCEL, + ] + ) self.set_border_width(5) @@ -2055,7 +2137,7 @@ class Wizard(Gtk.Dialog): frame0.add(box0) frame = Gtk.Frame() - frame.set_label("Seleccionar Nueva Encuesta. (archivo *.json)") + frame.set_label("Seleccionar modelo de encuesta. (archivo *.json)") box = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL) box.pack_start(abrirencuesta, False, False, 10) box.pack_start(self.label_1, False, False, 0) @@ -2065,7 +2147,7 @@ class Wizard(Gtk.Dialog): box0.pack_start(frame, False, False, 10) frame = Gtk.Frame() - frame.set_label("Seleccionar Nueva Lista. (archivo *.csv)") + frame.set_label("Seleccionar lista a encuestar. (archivo *.csv)") box = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL) box.pack_start(abrirlista, False, False, 10) box.pack_start(self.label_2, False, False, 0) @@ -2074,22 +2156,25 @@ class Wizard(Gtk.Dialog): box0.pack_start(frame, False, False, 10) + + self.vbox.pack_start(Gtk.Label("Nuevas encuestas"), False, False, 2) self.vbox.pack_start(frame0, False, False, 30) frame0.show_all() frame = Gtk.Frame() - frame.set_label("Seleccionar Encuesta Anterior. (archivo *.encuesta)") + frame.set_label("Seleccionar encuesta desde archivo temporal. (archivo *.encuesta)") box = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL) box.pack_start(cargarencuesta, False, False, 10) box.pack_start(self.label_3, False, False, 0) frame.add(box) frame.show_all() + self.vbox.pack_start(Gtk.Label("Encuestas inconclusas"), False, False, 2) self.vbox.pack_start(frame, False, False, 10) self.set_border_width(5) - self.set_size_request(500, 300) + self.set_size_request(640, 480) def __abrir_encuesta(self, widget): """ @@ -2217,3 +2302,24 @@ class My_Alert_Dialog2(Gtk.Dialog): self.vbox.pack_start(label, True, True, 0) + +class My_Alert_Dialog3(Gtk.Dialog): + + def __init__(self, parent_window = None, label = ""): + + Gtk.Dialog.__init__( + self, title = "ATENCION !", + parent = parent_window, + flags = Gtk.DialogFlags.MODAL, + buttons = ( + "Reemplazar", Gtk.ResponseType.ACCEPT, + "Volver al asistente", Gtk.ResponseType.CANCEL) + ) + + self.set_default_response(Gtk.ResponseType.CANCEL) + label = Gtk.Label(label) + label.show() + + self.set_border_width(10) + + self.vbox.pack_start(label, True, True, 0) |