diff options
author | Sayamindu Dasgupta <sayamindu@gmail.com> | 2009-08-05 08:34:30 (GMT) |
---|---|---|
committer | Sayamindu Dasgupta <sayamindu@gmail.com> | 2009-08-05 08:34:30 (GMT) |
commit | 76283f7761813fb09502e526a89e6bdbda28e91b (patch) | |
tree | 2192928a41724641e477050fdb7ec80bfd4d845b | |
parent | ab7c9f6521554f886ec12247d7cdcc7bfb71e03e (diff) |
Add support for notes associated with bookmark
-rw-r--r-- | readdialog.py | 182 | ||||
-rw-r--r-- | readsidebar.py | 112 |
2 files changed, 277 insertions, 17 deletions
diff --git a/readdialog.py b/readdialog.py new file mode 100644 index 0000000..24e7d33 --- /dev/null +++ b/readdialog.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python + +# Stolen from the PyGTK demo module by Maik Hertha <maik.hertha@berlin.de> + +import gtk +import gobject + +from sugar.graphics import style +from sugar.graphics.toolbutton import ToolButton + +from gettext import gettext as _ +import cjson + +class BaseReadDialog(gtk.Window): + def __init__(self, parent_xid, dialog_title): + gtk.Window.__init__(self) + + self.connect('realize', self.__realize_cb) + + self.set_decorated(False) + self.set_position(gtk.WIN_POS_CENTER_ALWAYS) + self.set_border_width(style.LINE_WIDTH) + + width = gtk.gdk.screen_width() - style.GRID_CELL_SIZE * 4 + height = gtk.gdk.screen_height() - style.GRID_CELL_SIZE * 4 + self.set_size_request(width, height) + + self._parent_window_xid = parent_xid + + _vbox = gtk.VBox(spacing=2) + self.add(_vbox) + + self.toolbar = gtk.Toolbar() + label = gtk.Label() + label.set_markup('<b> %s</b>' % dialog_title) + label.set_alignment(0, 0.5) + tool_item = gtk.ToolItem() + tool_item.add(label) + label.show() + self.toolbar.insert(tool_item, -1) + tool_item.show() + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_expand(True) + self.toolbar.insert(separator, -1) + separator.show() + stop = ToolButton(icon_name='dialog-cancel') + stop.set_tooltip(_('Cancel')) + stop.connect('clicked', lambda *w: self.destroy()) + self.toolbar.insert(stop, -1) + stop.show() + + accept = ToolButton(icon_name='dialog-ok') + accept.set_tooltip(_('Ok')) + accept.connect('clicked', self.accept_clicked_cb) + accept.show() + self.toolbar.insert(accept, -1) + + _vbox.pack_start(self.toolbar, expand=False) + self.toolbar.show() + + self._event_box = gtk.EventBox() + _vbox.pack_start(self._event_box, expand=True, fill = True) + self._canvas = None + + def set_canvas(self, canvas): + if self._canvas is not None: + self._event_box.remove(self._canvas) + self._event_box.add(canvas) + self._canvas = canvas + + def __realize_cb(self, widget): + self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) + self.window.set_accept_focus(True) + + parent = gtk.gdk.window_foreign_new(self._parent_window_xid) + self.window.set_transient_for(parent) + + self.modify_bg(gtk.STATE_NORMAL, + style.COLOR_WHITE.get_gdk_color()) + + if self._canvas is not None: + self._canvas.modify_bg(gtk.STATE_NORMAL, + style.COLOR_WHITE.get_gdk_color()) + self._canvas.grab_focus() + + self._event_box.modify_bg(gtk.STATE_NORMAL, + style.COLOR_WHITE.get_gdk_color()) + + def accept_clicked_cb(self, widget): + raise NotImplementedError + + +class BookmarkDialog(BaseReadDialog): + def __init__(self, parent_xid, dialog_title, bookmark_title, bookmark_content, page, sidebarinstance): + BaseReadDialog.__init__(self, parent_xid, dialog_title) + + self._sidebarinstance = sidebarinstance + self._page = page + + vbox = gtk.VBox() + thbox = gtk.HBox() + vbox.pack_start(thbox, expand = False, fill = False) + thbox.set_border_width(style.DEFAULT_SPACING * 2) + thbox.set_spacing(style.DEFAULT_SPACING) + thbox.show() + + label_title = gtk.Label(_('<b>Title</b>:')) + label_title.set_use_markup(True) + label_title.set_alignment(1, 0.5) + label_title.modify_fg(gtk.STATE_NORMAL, + style.COLOR_SELECTION_GREY.get_gdk_color()) + thbox.pack_start(label_title, expand=False, fill = False) + label_title.show() + + self._title_entry = gtk.Entry() + self._title_entry.modify_bg(gtk.STATE_INSENSITIVE, + style.COLOR_WHITE.get_gdk_color()) + self._title_entry.modify_base(gtk.STATE_INSENSITIVE, + style.COLOR_WHITE.get_gdk_color()) + self._title_entry.set_size_request(int(gtk.gdk.screen_width() / 3), -1) + + thbox.pack_start(self._title_entry, expand = False, fill = False) + self._title_entry.show() + if bookmark_title is not None: + self._title_entry.set_text(bookmark_title) + + + cvbox = gtk.VBox() + vbox.pack_start(cvbox, expand = True, fill = True) + cvbox.set_border_width(style.DEFAULT_SPACING * 2) + cvbox.set_spacing(style.DEFAULT_SPACING/2) + cvbox.show() + + label_content = gtk.Label(_('<b>Details</b>:')) + label_content.set_use_markup(True) + label_content.set_alignment(0, 0) + label_content.modify_fg(gtk.STATE_NORMAL, + style.COLOR_SELECTION_GREY.get_gdk_color()) + cvbox.pack_start(label_content, expand=False, fill = False) + label_content.show() + + sw = gtk.ScrolledWindow() + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + + self._content_entry = gtk.TextView() + self._content_entry.set_wrap_mode(gtk.WRAP_WORD) + + sw.add(self._content_entry) + sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) + + cvbox.pack_start(sw, expand = True, fill = True) + self._content_entry.show() + if bookmark_content is not None: + buffer = self._content_entry.get_buffer() + buffer.set_text(bookmark_content) + + self.set_canvas(vbox) + +class BookmarkAddDialog(BookmarkDialog): + def __init__(self, parent_xid, dialog_title, bookmark_title, bookmark_content, page, sidebarinstance): + BookmarkDialog.__init__(self, parent_xid, dialog_title, bookmark_title, bookmark_content, page, sidebarinstance) + + def accept_clicked_cb(self, widget): + title = self._title_entry.get_text() + details = self._content_entry.get_buffer().props.text + content = {'title' : unicode(title), 'content' : unicode(details)} + self._sidebarinstance._real_add_bookmark(self._page, cjson.encode(content)) + self.destroy() + +class BookmarkEditDialog(BookmarkDialog): + def __init__(self, parent_xid, dialog_title, bookmark_title, bookmark_content, page, sidebarinstance): + BookmarkDialog.__init__(self, parent_xid, dialog_title, bookmark_title, bookmark_content, page, sidebarinstance) + + def accept_clicked_cb(self, widget): + title = self._title_entry.get_text() + details = self._content_entry.get_buffer().props.text + content = {'title' : unicode(title), 'content' : unicode(details)} + self._sidebarinstance.del_bookmark(self._page) + self._sidebarinstance._real_add_bookmark(self._page, cjson.encode(content)) + self.destroy() diff --git a/readsidebar.py b/readsidebar.py index d5280cd..0b745c2 100644 --- a/readsidebar.py +++ b/readsidebar.py @@ -16,20 +16,25 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import logging -import time +import time, cjson import gtk from sugar.graphics.icon import Icon from sugar.graphics.xocolor import XoColor +from sugar import profile +from sugar.util import timestamp_to_elapsed_string from readbookmark import Bookmark from readdb import BookmarkManager +from readdialog import BookmarkAddDialog, BookmarkEditDialog from gettext import gettext as _ _logger = logging.getLogger('read-activity') +#TODO: Add support for multiple bookmarks in a single page (required when sharing) + class Sidebar(gtk.EventBox): def __init__(self): gtk.EventBox.__init__(self) @@ -45,35 +50,98 @@ class Sidebar(gtk.EventBox): self._box.show() self.show() - self._bookmarks = [] + self._bookmark_icon = None self._bookmark_manager = None self._is_showing_local_bookmark = False + self.add_events(gtk.gdk.BUTTON_PRESS_MASK) + def _add_bookmark_icon(self, bookmark): xocolor = XoColor(bookmark.color) - bookmark_icon = Icon(icon_name = 'emblem-favorite', \ + self._bookmark_icon = Icon(icon_name = 'emblem-favorite', \ pixel_size = 18, xo_color = xocolor) - tooltip_text = (_('Bookmark added by %(user)s on %(time)s') \ - % {'user': bookmark.nick, 'time': time.ctime(bookmark.timestamp)}) - bookmark_icon.set_tooltip_text(tooltip_text) + self._bookmark_icon.props.has_tooltip = True + self.__bookmark_icon_query_tooltip_cb_id = \ + self._bookmark_icon.connect('query_tooltip', self.__bookmark_icon_query_tooltip_cb, \ + bookmark) - self._box.pack_start(bookmark_icon ,expand=False,fill=False) - bookmark_icon.show_all() - - self._bookmarks.append(bookmark_icon) + self.__event_cb_id = \ + self.connect('event', self.__event_cb, bookmark) + + self._box.pack_start(self._bookmark_icon ,expand=False,fill=False) + self._bookmark_icon.show_all() if bookmark.is_local(): self._is_showing_local_bookmark = True - def _clear_bookmarks(self): - for bookmark_icon in self._bookmarks: - bookmark_icon.hide() #XXX: Is this needed?? - bookmark_icon.destroy() + def __bookmark_icon_query_tooltip_cb(self, widget, x, y, keyboard_mode, tip, bookmark): + content = cjson.decode(bookmark.title) - self._bookmarks = [] + tooltip_header = content['title'] + tooltip_body = content['content'] + #TRANS: This goes like Bookmark added by User 5 days ago (the elapsed string gets translated + #TRANS: automatically) + tooltip_footer = (_('Bookmark added by %(user)s %(time)s') \ + % {'user': bookmark.nick, 'time': timestamp_to_elapsed_string(bookmark.timestamp)}) + + vbox = gtk.VBox() + + l = gtk.Label('<big>%s</big>' % tooltip_header) + l.set_use_markup(True) + l.set_width_chars(40) + l.set_line_wrap(True) + vbox.pack_start(l, expand = False, fill = False) + l.show() + + l = gtk.Label('%s' % tooltip_body) + l.set_use_markup(True) + l.set_alignment(0, 0) + l.set_padding(2, 6) + l.set_width_chars(40) + l.set_line_wrap(True) + l.set_justify(gtk.JUSTIFY_FILL) + vbox.pack_start(l, expand = True, fill = True) + l.show() + + l = gtk.Label('<small><i>%s</i></small>' % tooltip_footer) + l.set_use_markup(True) + l.set_width_chars(40) + l.set_line_wrap(True) + vbox.pack_start(l, expand = False, fill = False) + l.show() + + tip.set_custom(vbox) + + return True - self._is_showing_local_bookmark = False + def __event_cb(self, widget, event, bookmark): + if event.type == gtk.gdk.BUTTON_PRESS and \ + self._bookmark_icon is not None: + content = cjson.decode(bookmark.title) + bookmark_title = content['title'] + bookmark_content = content['content'] + + dialog = BookmarkEditDialog(parent_xid = self.get_toplevel().window.xid, \ + dialog_title = _("Add notes for bookmark: "), \ + bookmark_title = bookmark_title, \ + bookmark_content = bookmark_content, page = bookmark.page_no, \ + sidebarinstance = self) + dialog.show_all() + + return False + + def _clear_bookmarks(self): + if self._bookmark_icon is not None: + self._bookmark_icon.disconnect(self.__bookmark_icon_query_tooltip_cb_id) + self.disconnect(self.__event_cb_id) + + self._bookmark_icon.hide() #XXX: Is this needed?? + self._bookmark_icon.destroy() + + self._bookmark_icon = None + + self._is_showing_local_bookmark = False def set_bookmarkmanager(self, filehash): self._bookmark_manager = BookmarkManager(filehash) @@ -92,7 +160,17 @@ class Sidebar(gtk.EventBox): self._add_bookmark_icon(bookmark) def add_bookmark(self, page): - self._bookmark_manager.add_bookmark(page, '') #TODO: Implement title support + bookmark_title = (_("%s's bookmark") % profile.get_nick_name()) + bookmark_content = (_("Bookmark for page %d") % page) + dialog = BookmarkAddDialog(parent_xid = self.get_toplevel().window.xid, \ + dialog_title = _("Add notes for bookmark: "), \ + bookmark_title = bookmark_title, \ + bookmark_content = bookmark_content, page = page, \ + sidebarinstance = self) + dialog.show_all() + + def _real_add_bookmark(self, page, content): + self._bookmark_manager.add_bookmark(page, unicode(content)) self.update_for_page(page) def del_bookmark(self, page): |