Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRogelio Mita <rogeliomita@activitycentral.com>2013-06-26 21:00:31 (GMT)
committer Rogelio Mita <rogeliomita@activitycentral.com>2013-06-26 21:00:31 (GMT)
commit23f9d64c6fc0dbbc964cda50ed137f66b84043b7 (patch)
tree82b433689ea3bfbd0a26ecce84ebaec3243f051b
parent34a0ae4ae48d6df490eeb581a7f072545b3595d5 (diff)
Porting page button behavior to gtk3. BugFix BACK_PATH into gtk2 app
-rw-r--r--CeibalEncuesta/gtk2/CeibalEncuesta/CeibalEncuesta.py5
-rwxr-xr-xCeibalEncuesta/gtk3/CeibalEncuesta/CeibalEncuesta.py41
-rwxr-xr-xCeibalEncuesta/gtk3/CeibalEncuesta/Widgets.py146
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)