Commit ac6ac17eaad5859e570d82470d7c7dbb00d02477
- Diff rendering mode:
- inline
- side by side
read.db
(2 / 0)
Binary files differ
readactivity.py
(23 / 14)
  | |||
34 | 34 | from sugar.graphics.objectchooser import ObjectChooser | |
35 | 35 | ||
36 | 36 | from readtoolbar import EditToolbar, ReadToolbar, ViewToolbar | |
37 | from readsidebar import Sidebar | ||
37 | 38 | ||
38 | 39 | _HARDWARE_MANAGER_INTERFACE = 'org.laptop.HardwareManager' | |
39 | 40 | _HARDWARE_MANAGER_SERVICE = 'org.laptop.HardwareManager' | |
… | … | ||
110 | 110 | self._view.set_screen_dpi(_get_screen_dpi()) | |
111 | 111 | self._view.connect('notify::has-selection', | |
112 | 112 | self._view_notify_has_selection_cb) | |
113 | |||
114 | self._sidebar = Sidebar() | ||
115 | self._sidebar.show() | ||
113 | 116 | ||
114 | 117 | toolbox = activity.ActivityToolbox(self) | |
115 | 118 | ||
… | … | ||
126 | 126 | toolbox.add_toolbar(_('Edit'), self._edit_toolbar) | |
127 | 127 | self._edit_toolbar.show() | |
128 | 128 | ||
129 | self._read_toolbar = ReadToolbar(self._view) | ||
129 | self._read_toolbar = ReadToolbar(self._view, self._sidebar) | ||
130 | 130 | toolbox.add_toolbar(_('Read'), self._read_toolbar) | |
131 | 131 | self._read_toolbar.show() | |
132 | 132 | ||
… | … | ||
141 | 141 | self.set_toolbox(toolbox) | |
142 | 142 | toolbox.show() | |
143 | 143 | ||
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 | ||
147 | 147 | ||
148 | scrolled.add(self._view) | ||
148 | self._scrolled.add(self._view) | ||
149 | 149 | self._view.show() | |
150 | |||
151 | self.set_canvas(scrolled) | ||
152 | scrolled.show() | ||
153 | 150 | ||
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 | |||
154 | 159 | # Set up for idle suspend | |
155 | 160 | self._idle_timer = 0 | |
156 | 161 | self._service = None | |
… | … | ||
179 | 179 | _HARDWARE_MANAGER_OBJECT_PATH) | |
180 | 180 | self._service = dbus.Interface(proxy, | |
181 | 181 | _HARDWARE_MANAGER_INTERFACE) | |
182 | scrolled.props.vadjustment.connect("value-changed", | ||
182 | self._scrolled.props.vadjustment.connect("value-changed", | ||
183 | 183 | self._user_action_cb) | |
184 | scrolled.props.hadjustment.connect("value-changed", | ||
184 | self._scrolled.props.hadjustment.connect("value-changed", | ||
185 | 185 | self._user_action_cb) | |
186 | 186 | self.connect("focus-in-event", self._focus_in_event_cb) | |
187 | 187 | self.connect("focus-out-event", self._focus_out_event_cb) | |
… | … | ||
456 | 456 | self._want_document = False | |
457 | 457 | self._view.set_document(self._document) | |
458 | 458 | self._edit_toolbar.set_document(self._document) | |
459 | self._read_toolbar.set_document(self._document) | ||
459 | self._read_toolbar.set_document(self._document, filepath) | ||
460 | 460 | ||
461 | 461 | if not self.metadata['title_set_by_user'] == '1': | |
462 | 462 | info = self._document.get_info() | |
… | … | ||
470 | 470 | _logger.debug('Found sizing mode: %s', sizing_mode) | |
471 | 471 | if sizing_mode == "best-fit": | |
472 | 472 | 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) | ||
474 | 474 | elif sizing_mode == "free": | |
475 | 475 | self._view.props.sizing_mode = evince.SIZING_FREE | |
476 | 476 | self._view.props.zoom = float(self.metadata.get('Read_zoom', '1.0')) | |
477 | 477 | _logger.debug('Set zoom to %f', self._view.props.zoom) | |
478 | 478 | elif sizing_mode == "fit-width": | |
479 | 479 | 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) | ||
481 | 481 | else: | |
482 | 482 | # this may happen when we get a document from a buddy with a later | |
483 | 483 | # version of Read, for example. | |
… | … | ||
587 | 587 | _logger.debug("Keyname Release: %s, time: %s", keyname, event.time) | |
588 | 588 | ||
589 | 589 | 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) | ||
591 | 591 | ||
592 | 592 | def __view_toolbar_go_fullscreen_cb(self, view_toolbar): | |
593 | 593 | self.fullscreen() |
readbookmark.py
(15 / 0)
  | |||
1 | class 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)
  | |||
1 | import logging | ||
2 | |||
3 | import sqlite3 | ||
4 | import time | ||
5 | |||
6 | import gconf | ||
7 | |||
8 | from readbookmark import Bookmark | ||
9 | |||
10 | _logger = logging.getLogger('read-activity') | ||
11 | |||
12 | class 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() |
readsidebar.py
(78 / 0)
  | |||
1 | import logging | ||
2 | |||
3 | import gtk | ||
4 | |||
5 | from sugar.graphics.icon import Icon | ||
6 | from sugar.graphics.xocolor import XoColor | ||
7 | |||
8 | from readbookmark import Bookmark | ||
9 | from readdb import BookmarkManager | ||
10 | |||
11 | from gettext import gettext as _ | ||
12 | |||
13 | _logger = logging.getLogger('read-activity') | ||
14 | |||
15 | class 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 |
readtoolbar.py
(49 / 2)
  | |||
23 | 23 | import gtk | |
24 | 24 | import evince | |
25 | 25 | ||
26 | import md5 | ||
27 | |||
26 | 28 | from sugar.graphics.toolbutton import ToolButton | |
29 | from sugar.graphics.toggletoolbutton import ToggleToolButton | ||
27 | 30 | from sugar.graphics.menuitem import MenuItem | |
28 | 31 | from sugar.graphics import iconentry | |
29 | 32 | from sugar.activity import activity | |
33 | from sugar.graphics.icon import Icon | ||
34 | from sugar.graphics.xocolor import XoColor | ||
30 | 35 | ||
36 | def 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 | |||
31 | 49 | class EditToolbar(activity.EditToolbar): | |
32 | 50 | __gtype_name__ = 'EditToolbar' | |
33 | 51 | ||
… | … | ||
182 | 182 | class ReadToolbar(gtk.Toolbar): | |
183 | 183 | __gtype_name__ = 'ReadToolbar' | |
184 | 184 | ||
185 | def __init__(self, evince_view): | ||
185 | def __init__(self, evince_view, sidebar): | ||
186 | 186 | gtk.Toolbar.__init__(self) | |
187 | 187 | ||
188 | 188 | self._evince_view = evince_view | |
189 | self._sidebar = sidebar | ||
189 | 190 | self._document = None | |
190 | 191 | ||
191 | 192 | self._back = ToolButton('go-previous') | |
… | … | ||
255 | 255 | self.insert(navitem, -1) | |
256 | 256 | navitem.show() | |
257 | 257 | ||
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) | ||
258 | 268 | ||
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) | ||
260 | 274 | self._document = document | |
261 | 275 | page_cache = self._document.get_page_cache() | |
262 | 276 | page_cache.connect('page-changed', self._page_changed_cb) | |
263 | 277 | self._update_nav_buttons() | |
264 | 278 | self._update_toc() | |
279 | self._sidebar.set_bookmarkmanager(hash) | ||
265 | 280 | ||
266 | 281 | def _num_page_entry_insert_text_cb(self, entry, text, length, position): | |
267 | 282 | if not re.match('[0-9]', text): | |
… | … | ||
303 | 303 | ||
304 | 304 | def _go_forward_cb(self, button): | |
305 | 305 | 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) | ||
306 | 313 | ||
307 | 314 | def _page_changed_cb(self, page, proxy): | |
308 | 315 | self._update_nav_buttons() | |
309 | 316 | if hasattr(self._document, 'has_document_links'): | |
310 | 317 | if self._document.has_document_links(): | |
311 | 318 | self._toc_select_active_page() | |
319 | |||
320 | self._sidebar.update_for_page(self._document.get_page_cache().get_current_page()) | ||
312 | 321 | ||
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 | |||
313 | 326 | def _update_nav_buttons(self): | |
314 | 327 | current_page = self._document.get_page_cache().get_current_page() | |
315 | 328 | self._back.props.sensitive = current_page > 0 |