Web · Wiki · Activities · Blog · Lists · Chat · Meeting · Bugs · Git · Translate · Archive · People · Donate

Commit ac6ac17eaad5859e570d82470d7c7dbb00d02477

Bookmark support
read.db
(2 / 0)
Binary files differ
  
3434from sugar.graphics.objectchooser import ObjectChooser
3535
3636from readtoolbar import EditToolbar, ReadToolbar, ViewToolbar
37from readsidebar import Sidebar
3738
3839_HARDWARE_MANAGER_INTERFACE = 'org.laptop.HardwareManager'
3940_HARDWARE_MANAGER_SERVICE = 'org.laptop.HardwareManager'
110110 self._view.set_screen_dpi(_get_screen_dpi())
111111 self._view.connect('notify::has-selection',
112112 self._view_notify_has_selection_cb)
113
114 self._sidebar = Sidebar()
115 self._sidebar.show()
113116
114117 toolbox = activity.ActivityToolbox(self)
115118
126126 toolbox.add_toolbar(_('Edit'), self._edit_toolbar)
127127 self._edit_toolbar.show()
128128
129 self._read_toolbar = ReadToolbar(self._view)
129 self._read_toolbar = ReadToolbar(self._view, self._sidebar)
130130 toolbox.add_toolbar(_('Read'), self._read_toolbar)
131131 self._read_toolbar.show()
132132
141141 self.set_toolbox(toolbox)
142142 toolbox.show()
143143
144 scrolled = gtk.ScrolledWindow()
145 scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
146 scrolled.props.shadow_type = gtk.SHADOW_NONE
144 self._scrolled = gtk.ScrolledWindow()
145 self._scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
146 self._scrolled.props.shadow_type = gtk.SHADOW_NONE
147147
148 scrolled.add(self._view)
148 self._scrolled.add(self._view)
149149 self._view.show()
150
151 self.set_canvas(scrolled)
152 scrolled.show()
153150
151 hbox = gtk.HBox()
152 hbox.pack_start(self._sidebar, expand=False, fill=False)
153 hbox.pack_start(self._scrolled, expand=True, fill=True)
154
155 self.set_canvas(hbox)
156 self._scrolled.show()
157 hbox.show()
158
154159 # Set up for idle suspend
155160 self._idle_timer = 0
156161 self._service = None
179179 _HARDWARE_MANAGER_OBJECT_PATH)
180180 self._service = dbus.Interface(proxy,
181181 _HARDWARE_MANAGER_INTERFACE)
182 scrolled.props.vadjustment.connect("value-changed",
182 self._scrolled.props.vadjustment.connect("value-changed",
183183 self._user_action_cb)
184 scrolled.props.hadjustment.connect("value-changed",
184 self._scrolled.props.hadjustment.connect("value-changed",
185185 self._user_action_cb)
186186 self.connect("focus-in-event", self._focus_in_event_cb)
187187 self.connect("focus-out-event", self._focus_out_event_cb)
456456 self._want_document = False
457457 self._view.set_document(self._document)
458458 self._edit_toolbar.set_document(self._document)
459 self._read_toolbar.set_document(self._document)
459 self._read_toolbar.set_document(self._document, filepath)
460460
461461 if not self.metadata['title_set_by_user'] == '1':
462462 info = self._document.get_info()
470470 _logger.debug('Found sizing mode: %s', sizing_mode)
471471 if sizing_mode == "best-fit":
472472 self._view.props.sizing_mode = evince.SIZING_BEST_FIT
473 self._view.update_view_size(self.canvas)
473 self._view.update_view_size(self._scrolled)
474474 elif sizing_mode == "free":
475475 self._view.props.sizing_mode = evince.SIZING_FREE
476476 self._view.props.zoom = float(self.metadata.get('Read_zoom', '1.0'))
477477 _logger.debug('Set zoom to %f', self._view.props.zoom)
478478 elif sizing_mode == "fit-width":
479479 self._view.props.sizing_mode = evince.SIZING_FIT_WIDTH
480 self._view.update_view_size(self.canvas)
480 self._view.update_view_size(self._scrolled)
481481 else:
482482 # this may happen when we get a document from a buddy with a later
483483 # version of Read, for example.
587587 _logger.debug("Keyname Release: %s, time: %s", keyname, event.time)
588588
589589 def __view_toolbar_needs_update_size_cb(self, view_toolbar):
590 self._view.update_view_size(self.canvas)
590 self._view.update_view_size(self._scrolled)
591591
592592 def __view_toolbar_go_fullscreen_cb(self, view_toolbar):
593593 self.fullscreen()
  
1class Bookmark:
2 def __init__(self, data):
3 self.md5 = data[0]
4 self.page_no = data[1]
5 self.title = data[2]
6 self.timestamp = data[3]
7 self.nick = data[4]
8 self.color = data[5]
9 self.local = data[6]
10
11 def belongstopage(self, page_no):
12 return self.page_no == page_no
13
14 def is_local(self):
15 return bool(self.local)
readdb.py
(65 / 0)
  
1import logging
2
3import sqlite3
4import time
5
6import gconf
7
8from readbookmark import Bookmark
9
10_logger = logging.getLogger('read-activity')
11
12class BookmarkManager:
13 def __init__(self, hash, dbpath='read.db'):
14 self._hash = hash
15 self._conn = sqlite3.connect(dbpath)
16 self._cur = self._conn.cursor()
17
18 self._bookmarks = []
19 self._populate_bookmarks()
20
21 def add_bookmark(self, page, title, local=1):
22 # locale = 0 means that this is a bookmark originally
23 # created by the person who originally shared the file
24 timestamp = time.time()
25 client = gconf.client_get_default()
26 user = client.get_string("/desktop/sugar/user/nick")
27 color = client.get_string("/desktop/sugar/user/color")
28
29 t = (self._hash, page, title, timestamp, user, color, local)
30 self._cur.execute('insert into bookmarks values (?, ?, ?, ?, ?, ?, ?)', t)
31 self._conn.commit()
32
33 self._resync_bookmark_cache()
34
35 def del_bookmark(self, page):
36 client = gconf.client_get_default()
37 user = client.get_string("/desktop/sugar/user/nick")
38
39 # We delete only the locally made bookmark
40
41 t = (self._hash, page, user)
42 self._cur.execute('delete from bookmarks where md5=? and page=? and user=?', t)
43 self._conn.commit()
44
45 self._resync_bookmark_cache()
46
47 def _populate_bookmarks(self):
48 # TODO: Figure out if caching the entire set of bookmarks is a good idea or not
49 self._cur.execute('select * from bookmarks where md5=?', (self._hash,))
50
51 for row in self._cur:
52 self._bookmarks.append(Bookmark(row))
53
54 def get_bookmarks_for_page(self, page):
55 bookmarks = []
56 for bookmark in self._bookmarks:
57 if bookmark.belongstopage(page):
58 bookmarks.append(bookmark)
59
60 return bookmarks
61
62 def _resync_bookmark_cache(self):
63 # To be called when a new bookmark has been added/removed
64 self._bookmarks = []
65 self._populate_bookmarks()
  
1import logging
2
3import gtk
4
5from sugar.graphics.icon import Icon
6from sugar.graphics.xocolor import XoColor
7
8from readbookmark import Bookmark
9from readdb import BookmarkManager
10
11from gettext import gettext as _
12
13_logger = logging.getLogger('read-activity')
14
15class Sidebar(gtk.EventBox):
16 def __init__(self):
17 gtk.EventBox.__init__(self)
18 self.set_size_request(20, -1)
19 # Take care of the background first
20 white = gtk.gdk.color_parse("white")
21 self.modify_bg(gtk.STATE_NORMAL, white)
22
23 self._box = gtk.VButtonBox()
24 self._box.set_layout(gtk.BUTTONBOX_CENTER)
25 self.add(self._box)
26
27 self._box.show()
28 self.show()
29
30 self._bookmarks = []
31 self._bookmark_manager = None
32 self._is_showing_local_bookmark = False
33
34 def _add_bookmark_icon(self, bookmark):
35 xocolor = XoColor(bookmark.color)
36 bookmark_icon = Icon(icon_name = 'emblem-favorite', \
37 pixel_size = 18, xo_color = xocolor)
38 bookmark_icon.set_tooltip_text(_("Stupid tooltip"))
39 self._box.pack_start(bookmark_icon ,expand=False,fill=False)
40 bookmark_icon.show_all()
41
42 self._bookmarks.append(bookmark_icon)
43
44 if bookmark.is_local():
45 self._is_showing_local_bookmark = True
46
47 def _clear_bookmarks(self):
48 for bookmark_icon in self._bookmarks:
49 bookmark_icon.hide() #XXX: Is this needed??
50 bookmark_icon.destroy()
51
52 self._bookmarks = []
53
54 self._is_showing_local_bookmark = False
55
56 def set_bookmarkmanager(self, filehash):
57 self._bookmark_manager = BookmarkManager(filehash)
58
59 def update_for_page(self, page):
60 self._clear_bookmarks()
61 if self._bookmark_manager is None:
62 return
63
64 bookmarks = self._bookmark_manager.get_bookmarks_for_page(page)
65
66 for bookmark in bookmarks:
67 self._add_bookmark_icon(bookmark)
68
69 def add_bookmark(self, page):
70 self._bookmark_manager.add_bookmark(page, '') #TODO: Implement title support
71 self.update_for_page(page)
72
73 def del_bookmark(self, page):
74 self._bookmark_manager.del_bookmark(page)
75 self.update_for_page(page)
76
77 def is_showing_local_bookmark(self):
78 return self._is_showing_local_bookmark
  
2323import gtk
2424import evince
2525
26import md5
27
2628from sugar.graphics.toolbutton import ToolButton
29from sugar.graphics.toggletoolbutton import ToggleToolButton
2730from sugar.graphics.menuitem import MenuItem
2831from sugar.graphics import iconentry
2932from sugar.activity import activity
33from sugar.graphics.icon import Icon
34from sugar.graphics.xocolor import XoColor
3035
36def get_md5(filename): #FIXME: Should be moved somewhere else
37 filename = filename.replace('file://', '') #XXX: hack
38 fh = open(filename)
39 digest = md5.new()
40 while 1:
41 buf = fh.read(4096)
42 if buf == "":
43 break
44 digest.update(buf)
45 fh.close()
46 return digest.hexdigest()
47
48
3149class EditToolbar(activity.EditToolbar):
3250 __gtype_name__ = 'EditToolbar'
3351
182182class ReadToolbar(gtk.Toolbar):
183183 __gtype_name__ = 'ReadToolbar'
184184
185 def __init__(self, evince_view):
185 def __init__(self, evince_view, sidebar):
186186 gtk.Toolbar.__init__(self)
187187
188188 self._evince_view = evince_view
189 self._sidebar = sidebar
189190 self._document = None
190191
191192 self._back = ToolButton('go-previous')
255255 self.insert(navitem, -1)
256256 navitem.show()
257257
258 spacer = gtk.SeparatorToolItem()
259 self.insert(spacer, -1)
260 spacer.show()
261
262 bookmarkitem = gtk.ToolItem()
263 self._bookmarker = ToggleToolButton('emblem-favorite')
264 self._bookmarker_toggle_handler_id = self._bookmarker.connect('toggled',
265 self._bookmarker_toggled_cb)
266
267 bookmarkitem.add(self._bookmarker)
258268
259 def set_document(self, document):
269 self.insert(bookmarkitem, -1)
270 bookmarkitem.show_all()
271
272 def set_document(self, document, filepath):
273 hash = get_md5(filepath)
260274 self._document = document
261275 page_cache = self._document.get_page_cache()
262276 page_cache.connect('page-changed', self._page_changed_cb)
263277 self._update_nav_buttons()
264278 self._update_toc()
279 self._sidebar.set_bookmarkmanager(hash)
265280
266281 def _num_page_entry_insert_text_cb(self, entry, text, length, position):
267282 if not re.match('[0-9]', text):
303303
304304 def _go_forward_cb(self, button):
305305 self._evince_view.next_page()
306
307 def _bookmarker_toggled_cb(self, button):
308 page = self._document.get_page_cache().get_current_page()
309 if self._bookmarker.props.active:
310 self._sidebar.add_bookmark(page)
311 else:
312 self._sidebar.del_bookmark(page)
306313
307314 def _page_changed_cb(self, page, proxy):
308315 self._update_nav_buttons()
309316 if hasattr(self._document, 'has_document_links'):
310317 if self._document.has_document_links():
311318 self._toc_select_active_page()
319
320 self._sidebar.update_for_page(self._document.get_page_cache().get_current_page())
312321
322 self._bookmarker.handler_block(self._bookmarker_toggle_handler_id)
323 self._bookmarker.props.active = self._sidebar.is_showing_local_bookmark()
324 self._bookmarker.handler_unblock(self._bookmarker_toggle_handler_id)
325
313326 def _update_nav_buttons(self):
314327 current_page = self._document.get_page_cache().get_current_page()
315328 self._back.props.sensitive = current_page > 0