diff options
author | flavio <fdanesse@gmail.com> | 2013-03-15 23:51:01 (GMT) |
---|---|---|
committer | flavio <fdanesse@gmail.com> | 2013-03-15 23:51:01 (GMT) |
commit | 756ee4922586b28cdf665fc359c3450f661fca7a (patch) | |
tree | 7f582dfe099616ccc3dd44c15165f8b57ea2f6c1 | |
parent | 1fa593df04e53e80cf30be24eb9aa1fddc316398 (diff) |
-rw-r--r-- | SugarCeibalNotifica.py | 587 | ||||
-rw-r--r-- | activity/activity.info | 2 |
2 files changed, 588 insertions, 1 deletions
diff --git a/SugarCeibalNotifica.py b/SugarCeibalNotifica.py new file mode 100644 index 0000000..d961153 --- /dev/null +++ b/SugarCeibalNotifica.py @@ -0,0 +1,587 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Plan Ceibal - Uruguay +# Flavio Danesse - fdanesse@activitycentral.com + +# 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 shelve +import os +import gtk +import sys +import gobject + +from ceibal.notifier.store import * + +from sugar.activity import activity +from sugar.activity.widgets import StopButton + +BASE = os.path.dirname(__file__) + +pixbuf1 = gtk.gdk.pixbuf_new_from_file_at_size( + os.path.join(BASE, "Iconos", "ceibal-gris.png"), 32,32) + +pixbuf2 = gtk.gdk.pixbuf_new_from_file_at_size( + os.path.join(BASE, "Iconos", "ceibal.png"), 32,32) + +class CeibalNotifica(activity.Activity): + + def __init__(self, handle): + + activity.Activity.__init__(self, handle, False) + + self.set_title("Ceibal Notifica") + self.set_border_width(2) + + self.text_buffer = None + self.text_view = None + self.store = None + self.listore_model = None + self.modelsort = None + self.notify_store = None + self.info_toolbar = None + self.control_toolbar = None + self.filter = None + + self.set_layout() + self.show_all() + + self.connect("delete_event", self.delete_event) + self.notify_store.connect("show_notify", self.show_notify) + self.notify_store.connect("delete_notify", self.delete_notify) + self.notify_store.connect("marcar_notify", self.marcar_notify) + self.control_toolbar.connect("get_filter", self.get_filter) + self.control_toolbar.connect("make_filter", self.make_filter) + self.control_toolbar.connect("show_filter", self.show_filter) + self.control_toolbar.connect("exit", self.salir) + + self.load_notify() + self.notify_store.columns_autosize() + + def set_layout(self): + + self.listore_model = ListoreModel() + self.modelsort = gtk.TreeModelSort(self.listore_model) + self.notify_store = Notify_Store(self.modelsort) + self.text_buffer = gtk.TextBuffer() + + self.text_view = gtk.TextView(buffer=self.text_buffer) + self.text_view.set_editable(False) + self.text_view.set_wrap_mode(gtk.WRAP_WORD) + self.text_view.set_justification(gtk.JUSTIFY_FILL) + self.text_view.set_pixels_above_lines(5) + self.text_view.set_pixels_below_lines(15) + self.text_view.set_pixels_inside_wrap(5) + self.text_view.set_left_margin(10) + self.text_view.set_right_margin(10) + + hpanel = gtk.HPaned() + self.store = Store() + + scroll = gtk.ScrolledWindow() + scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scroll.add_with_viewport(self.notify_store) + + hpanel.pack1(scroll, resize = False, shrink = True) + + scroll = gtk.ScrolledWindow() + scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scroll.add_with_viewport(self.text_view) + + hpanel.pack2(scroll, resize = False, shrink = True) + + vbox = gtk.VBox() + + self.info_toolbar = ToolbarInfo() + self.control_toolbar = ToolbarControl() + + vbox.pack_start(self.control_toolbar, False, False, 0) + vbox.pack_start(hpanel, True, True, 0) + vbox.pack_start(self.info_toolbar, False, False, 0) + + hpanel.show_all() + self.set_canvas(vbox) + + def get_filter(self, widget, value): + + filtro_nivel2 = self.store.db.get_categories(value=value) + widget.set_filter(filtro_nivel2) + + def make_filter(self, widget, value): + + self.filter = value + self.load_notify() + widget.make_filter(self.filter) + + def show_notify(self, widget, text, info): + + self.text_buffer.set_text(text) + self.info_toolbar.set_text(info) + + def delete_notify(self, widget, path): + + iter = widget.get_model().get_iter(path) + id_registro = int(widget.get_model().get_value(iter, 1)) + self.store.db.remove_message(id_registro) + iter = self.listore_model.get_iter(path) + self.listore_model.remove(iter) + self.update_view() + + def show_filter(self, widget): + + if self.filter[0] == 'Ninguno' and self.filter[1] == 'Ninguno': return + + valor = 0 + + if self.filter[0] == 'Prioridad': valor = 2 + if self.filter[0] == 'Lanzamiento': valor = 5 + if self.filter[0] == 'Expiración': valor = 6 + if self.filter[0] == 'Tipo': valor = 7 + + iter = self.listore_model.get_iter_first() + + while iter: + val = self.listore_model.get_value(iter, valor) + path = self.listore_model.get_path(iter) + iter = self.listore_model.iter_next(self.listore_model.get_iter(path)) + + if val != self.filter[1]: + self.listore_model.remove(self.listore_model.get_iter(path)) + + def marcar_notify(self, widget, path): + + iter = widget.get_model().get_iter(path) + id_registro = int(widget.get_model().get_value(iter, 1)) + marca = not self.store.db.is_fav(id_registro) + self.store.db.set_fav(id_registro, fav=marca) + iter = self.listore_model.get_iter(path) + fav = self.store.db.is_fav(id_registro) + self.listore_model.set_value(iter, 8, fav) + self.update_view() + + def update_view(self): + + path = self.notify_store.get_path_selected() + + if path == None: path = 0 + + self.notify_store.treeselection.select_path(path) + + try: + iter = self.listore_model.get_iter(path) + + if self.listore_model.get_value(iter, 8): + self.listore_model.set_value(iter, 0, pixbuf2) + + else: + self.listore_model.set_value(iter, 0, pixbuf1) + + except: + self.text_buffer.set_text('') + self.info_toolbar.set_text('') + + def load_notify(self): + + notificaciones = self.store.db.get_messages([]) + self.listore_model.clear() + + for notif in notificaciones: + self.add_notify(notif) + + def add_notify(self, notify): + + mark = pixbuf1 + + if bool(notify['fav']): mark = pixbuf2 + + notify = [mark, notify['id'], notify['priority'], notify['title'], notify['text'], + notify['launched'], notify['expires'], notify['type'], bool(notify['fav'])] + io = self.modelsort.get_model().append(notify) + sel = self.notify_store.get_selection() + il = self.modelsort.convert_child_iter_to_iter(None, io) + sel.select_iter(il) + + def delete_event(self, widget, event): + + self.salir() + + return False + + def salir(self, widget=None): + + sys.exit(0) + +class ListoreModel(gtk.ListStore): + + def __init__(self): + + gtk.ListStore.__init__(self, gtk.gdk.Pixbuf, + gobject.TYPE_STRING, gobject.TYPE_STRING, + gobject.TYPE_STRING, gobject.TYPE_STRING, + gobject.TYPE_STRING, gobject.TYPE_STRING, + gobject.TYPE_STRING, gobject.TYPE_BOOLEAN) + +class Notify_Store(gtk.TreeView): + + __gsignals__ = { + "show_notify": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (gobject.TYPE_STRING, + gobject.TYPE_STRING)), + "delete_notify": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)), + "marcar_notify": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,))} + + def __init__(self, model): + + gtk.TreeView.__init__(self, model) + + self.set_property("rules-hint", True) + self.add_events(gtk.gdk.BUTTON2_MASK) + + self.connect("button-press-event", self.handle_click) + + self.set_headers_clickable(True) + self.set_columns() + self.show_all() + + self.treeselection = self.get_selection() + self.treeselection.set_mode(gtk.SELECTION_SINGLE) + self.treeselection.set_select_function( + self.func_selections, + self.get_model(), True) + + def set_columns(self): + + self.append_column(self.make_column_mark('', 0, True)) + self.append_column(self.make_column('id', 1, False)) + self.append_column(self.make_column('Prioridad', 2, True)) + self.append_column(self.make_column('Título', 3, True)) + self.append_column(self.make_column('Notificación', 4, False)) + self.append_column(self.make_column('Lanzamiento', 5, False)) + self.append_column(self.make_column('Expira', 6, True)) + self.append_column(self.make_column('Tipo', 7, True)) + self.append_column(self.make_column('Favorito', 8, False)) + + def make_column_mark(self, text, index, visible): + + render = gtk.CellRendererPixbuf() + column = gtk.TreeViewColumn(text, render, pixbuf = index) + column.set_property("visible", visible) + return column + + def make_column(self, text, index, visible): + + render = gtk.CellRendererText() + column = gtk.TreeViewColumn(text, render, text=index) + column.set_sort_column_id(index) + column.set_property('visible', visible) + return column + + def func_selections(self, selection, model, path, is_selected, user_data): + + iter = self.get_model().get_iter(path) + texto = self.get_model().get_value(iter, 4) + nid = self.get_model().get_value(iter, 1) + lanzamiento = self.get_model().get_value(iter, 5) + fav = self.get_model().get_value(iter, 8) + + if fav: + fav = "Si" + + else: + fav = "No" + + info = "id: %s Lanzamiento: %s Favorito: %s" % (nid, lanzamiento, fav) + self.emit("show_notify", texto, info) + + return True + + def handle_click(self, widget, event): + + boton = event.button + pos = (int(event.x), int(event.y)) + tiempo = event.time + + try: + path, col, x, y = widget.get_path_at_pos(pos[0], pos[1]) + + if boton == 1: + return + + elif boton == 3: + self.get_menu(boton, pos, tiempo, path) + return + + elif boton == 2: + return + + except: + pass + + def get_menu(self, boton, pos, tiempo, path): + + menu = gtk.Menu() + + eliminar = gtk.MenuItem("Eliminar Notificación.") + menu.append(eliminar) + + eliminar.connect_object("activate", self.emit_delete_notify, path) + iter = self.get_model().get_iter(path) + fav = self.get_model().get_value(iter, 8) + + marcar = gtk.MenuItem("Marcar Como Favorito.") + + if fav: marcar = gtk.MenuItem("Desmarcar Como Favorito.") + + menu.append(marcar) + + marcar.connect_object("activate", self.emit_marcar_notify, path) + menu.show_all() + + gtk.Menu.popup(menu, None, None, None, boton, tiempo) + + def get_path_selected(self): + + (model, iter) = self.get_selection().get_selected() + path = None + + if iter: + treemodelrow = model[iter] + path = treemodelrow.path + + return path + + def emit_delete_notify(self, path): + + self.emit("delete_notify", path) + + def emit_marcar_notify(self, path): + + self.emit("marcar_notify", path) + +class ToolbarInfo(gtk.Toolbar): + + def __init__(self): + + gtk.Toolbar.__init__(self) + + self.modify_bg(gtk.STATE_NORMAL, + gtk.gdk.Color(0, 20000, 0, 1)) + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_size_request(0, -1) + separator.set_expand(True) + self.insert(separator, -1) + + item = gtk.ToolItem() + self.info_label = gtk.Label("") + self.info_label.modify_fg(gtk.STATE_NORMAL, + gtk.gdk.Color(65535, 65535, 65535,1)) + self.info_label.show() + item.add(self.info_label) + self.insert(item, -1) + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_size_request(0, -1) + separator.set_expand(True) + self.insert(separator, -1) + + def set_text(self, text=""): + + self.info_label.set_text(text) + +class ToolbarControl(gtk.Toolbar): + + __gsignals__ = { + "get_filter": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (gobject.TYPE_STRING,)), + "make_filter": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)), + "show_filter": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, []), + "exit": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, [])} + + def __init__(self): + + gtk.Toolbar.__init__(self) + + self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0, 0, 1)) + self.filter_combo1 = None + self.filter_combo2 = None + + self.set_layout() + self.show_all() + + self.filter_combo1.connect("change_selection", self.emit_get_filter) + self.filter_combo2.connect("change_selection", self.emit_make_filter) + + def set_layout(self): + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_size_request(10, -1) + separator.set_expand(False) + self.insert(separator, -1) + + item = gtk.ToolItem() + label = gtk.Label("Filtrar por:") + label.modify_fg(gtk.STATE_NORMAL, + gtk.gdk.Color(65535, 65535, 65535,1)) + label.show() + item.add(label) + self.insert(item, -1) + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_size_request(10, -1) + separator.set_expand(False) + self.insert(separator, -1) + + item = gtk.ToolItem() + self.filter_combo1 = Combo() + self.filter_combo1.set_items(["Tipo", "Prioridad", + "Lanzamiento", "Expiración"]) + self.filter_combo1.show() + item.add(self.filter_combo1) + self.insert(item, -1) + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_size_request(10, -1) + separator.set_expand(False) + self.insert(separator, -1) + + item = gtk.ToolItem() + label = gtk.Label("Seleccionar:") + label.modify_fg(gtk.STATE_NORMAL, + gtk.gdk.Color(65535, 65535, 65535,1)) + label.show() + item.add(label) + self.insert(item, -1) + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_size_request(10, -1) + separator.set_expand(False) + self.insert(separator, -1) + + item = gtk.ToolItem() + self.filter_combo2 = Combo() + self.filter_combo2.set_items([]) + self.filter_combo2.get_model().clear() + self.filter_combo2.show() + item.add(self.filter_combo2) + self.insert(item, -1) + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_size_request(0, -1) + separator.set_expand(True) + self.insert(separator, -1) + + stopbutton = gtk.ToolButton() + image = gtk.Image() + image.set_from_stock(gtk.STOCK_STOP, 32) + stopbutton.set_icon_widget(image) + image.show() + stopbutton.connect('clicked', self.emit_exit) + self.insert(stopbutton, -1) + stopbutton.show() + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_size_request(10, -1) + separator.set_expand(False) + self.insert(separator, -1) + + def emit_get_filter(self, widget, value): + + self.emit("get_filter", value) + + def emit_make_filter(self, widget, value): + + val1 = self.filter_combo1.get_value_select() + self.emit("make_filter", [val1,value]) + + def set_filter(self, lista): + + self.filter_combo2.set_items(lista) + + def make_filter(self, filter): + + if filter[0] == 'Ninguno': + self.filter_combo2.get_model().clear() + + self.emit('show_filter') + + def emit_exit(self, widget): + + self.emit('exit') + +class Combo(gtk.ComboBox): + + __gsignals__ = { + "change_selection": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (gobject.TYPE_STRING,))} + + def __init__(self): + + gtk.ComboBox.__init__(self, gtk.ListStore(str)) + + cell = gtk.CellRendererText() + self.pack_start(cell, True) + self.add_attribute(cell, 'text', 0) + + self.show_all() + + self.connect("changed", self.emit_selection) + + def set_items(self, items): + + self.get_model().clear() + self.append_text("Ninguno") + + for item in items: + self.append_text(str(item)) + + self.set_active(0) + + def emit_selection(self, widget): + + indice = widget.get_active() + + if indice < 0: return + + iter = widget.get_model().get_iter(indice) + value = widget.get_model().get_value(iter, 0) + + self.emit("change_selection", value) + + def get_value_select(self): + + indice = self.get_active() + + if indice < 0: return None + + iter = self.get_model().get_iter(indice) + value = self.get_model().get_value(iter, 0) + + return value +
\ No newline at end of file diff --git a/activity/activity.info b/activity/activity.info index 0f30591..1157ae8 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -2,7 +2,7 @@ name = CeibalNotifica activity_version = 1 bundle_id = org.laptop.CeibalNotifica -exec = sugar-activity CeibalNotifica.CeibalNotifica +exec = sugar-activity SugarCeibalNotifica.CeibalNotifica icon = ceibal-notifica show_launcher = yes license = GPLv3+ |