Codebase list sugar-read-activity / aa5534a
Add highlight support to thetext backend - The highlights are saved in the same db we save the bookmarks. - The highlights can be removed selecting again the same tex, or a subportion of the text or puting the cursos inside the highlighted area. Gonzalo Odiard 13 years ago
6 changed file(s) with 186 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
4343 pass
4444
4545 def can_zoom_to_width(self):
46 return False
47
48 def can_highlight(self):
4649 return False
4750
4851 def connect_zoom_handler(self, handler):
108108 self._model.props.sizing_mode)
109109 self.metadata['Read_sizing_mode'] = "fit-width"
110110
111 def can_highlight(self):
112 return False
113
111114 def get_zoom(self):
112115 '''
113116 Returns the current zoom level
4747 from readtoolbar import EditToolbar, ViewToolbar
4848 from readsidebar import Sidebar
4949 from readtopbar import TopBar
50
50 from readdb import BookmarkManager
5151 import epubadapter
5252 import evinceadapter
5353 import textadapter
232232 self._bookmarker.show()
233233 toolbar_box.toolbar.insert(bookmark_item, -1)
234234 bookmark_item.show()
235
236 self._highlight_item = gtk.ToolItem()
237 self._highlight = ToggleToolButton('format-text-underline')
238 self._highlight.set_tooltip(_('Highlight'))
239 self._highlight.props.sensitive = False
240 self._highlight_id = self._highlight.connect('clicked', \
241 self.__highlight_cb)
242 self._highlight_item.add(self._highlight)
243 toolbar_box.toolbar.insert(self._highlight_item, -1)
244 self._highlight_item.show_all()
235245
236246 separator = gtk.SeparatorToolItem()
237247 separator.props.draw = False
416426 def __go_forward_page_cb(self, button):
417427 self._view.next_page()
418428
429 def __highlight_cb(self, button):
430 tuples_list = self._bookmarkmanager.get_highlights(
431 self._view.get_current_page())
432 selection_tuple = self._view.get_selection_bounds()
433 cursor_position = self._view.get_cursor_position()
434
435 old_highlight_found = None
436 for compare_tuple in tuples_list:
437 if selection_tuple:
438 if selection_tuple[0] >= compare_tuple[0] and \
439 selection_tuple[1] <= compare_tuple[1]:
440 old_highlight_found = compare_tuple
441 break
442 if cursor_position >= compare_tuple[0] and \
443 cursor_position <= compare_tuple[1]:
444 old_highlight_found = compare_tuple
445 break
446
447 if old_highlight_found == None:
448 self._bookmarkmanager.add_highlight(
449 self._view.get_current_page(), selection_tuple)
450 else:
451 self._bookmarkmanager.del_highlight(
452 self._view.get_current_page(), old_highlight_found)
453
454 self._view.show_highlights(self._bookmarkmanager.get_highlights(
455 self._view.get_current_page()))
456
419457 def __prev_bookmark_activate_cb(self, menuitem):
420458 page = self._view.get_current_page()
421 bookmarkmanager = self._sidebar.get_bookmarkmanager()
422
423 prev_bookmark = bookmarkmanager.get_prev_bookmark_for_page(page)
459
460 prev_bookmark = self._bookmarkmanager.get_prev_bookmark_for_page(page)
424461 if prev_bookmark is not None:
425462 self._view.set_current_page(prev_bookmark.page_no)
426463
427464 def __next_bookmark_activate_cb(self, menuitem):
428465 page = self._view.get_current_page()
429 bookmarkmanager = self._sidebar.get_bookmarkmanager()
430
431 next_bookmark = bookmarkmanager.get_next_bookmark_for_page(page)
466
467 next_bookmark = self._bookmarkmanager.get_next_bookmark_for_page(page)
432468 if next_bookmark is not None:
433469 self._view.set_current_page(next_bookmark.page_no)
434470
450486 self._bookmarker.props.active = \
451487 self._sidebar.is_showing_local_bookmark()
452488 self._bookmarker.handler_unblock(self._bookmarker_toggle_handler_id)
489
490 tuples_list = self._bookmarkmanager.get_highlights(
491 self._view.get_current_page())
492 self._view.show_highlights(tuples_list)
453493
454494 def _update_nav_buttons(self):
455495 current_page = self._view.get_current_page()
765805 self._topbar.set_view(self._view)
766806
767807 filehash = get_md5(filepath)
768 self._sidebar.set_bookmarkmanager(filehash)
769
808 self._bookmarkmanager = BookmarkManager(filehash)
809 self._sidebar.set_bookmarkmanager(self._bookmarkmanager)
770810 self._update_nav_buttons()
771811 self._update_toc()
772
773812 self._view.connect_page_changed_handler(self.__page_changed_cb)
774
775
776813 self._view.load_metadata(self)
777
778 self._view_toolbar._update_zoom_buttons()
814 self._update_toolbars()
779815
780816 self._edit_toolbar._search_entry.props.text = \
781817 self.metadata.get('Read_search', '')
791827 self._share_document()
792828 except Exception, e:
793829 _logger.debug('Sharing failed: %s', e)
830
831 def _update_toolbars(self):
832 self._view_toolbar._update_zoom_buttons()
833 if not self._view.can_highlight():
834 self._highlight_item.hide()
794835
795836 def _share_document(self):
796837 """Share the document."""
856897
857898 def _view_selection_changed_cb(self, view):
858899 self._edit_toolbar.copy.props.sensitive = view.get_has_selection()
900 if self._view.can_highlight():
901 # Verify if the selection already exist or the cursor
902 # is in a highlighted area
903 cursor_position = self._view.get_cursor_position()
904 logging.debug('cursor position %d' % cursor_position)
905 selection_tuple = self._view.get_selection_bounds()
906 tuples_list = self._bookmarkmanager.get_highlights( \
907 self._view.get_current_page())
908 in_bounds = False
909 for highlight_tuple in tuples_list:
910 logging.debug('control tuple %s' % str(highlight_tuple))
911 if selection_tuple:
912 if selection_tuple[0] >= highlight_tuple[0] and \
913 selection_tuple[1] <= highlight_tuple[1]:
914 in_bounds = True
915 break
916 if cursor_position >= highlight_tuple[0] and \
917 cursor_position <= highlight_tuple[1]:
918 in_bounds = True
919 break
920
921 self._highlight.props.sensitive = \
922 view.get_has_selection() or in_bounds
923
924 self._highlight.handler_block(self._highlight_id)
925 self._highlight.set_active(in_bounds)
926 self._highlight.handler_unblock(self._highlight_id)
859927
860928 def _edit_toolbar_copy_cb(self, button):
861929 self._view.copy()
1616
1717 import logging
1818
19 import os, os.path
19 import os
2020 import shutil
2121 import sqlite3
2222 import time
5353 shutil.copy(olddbpath, dbpath)
5454
5555 conn = sqlite3.connect(dbpath)
56 conn.execute("CREATE TABLE temp_bookmarks AS SELECT md5, page, title 'content', timestamp, user, color, local FROM bookmarks")
56 conn.execute("CREATE TABLE temp_bookmarks AS SELECT md5, page, " + \
57 "title 'content', timestamp, user, color, local FROM bookmarks")
5758 conn.execute("ALTER TABLE bookmarks RENAME TO bookmarks_old")
5859 conn.execute("ALTER TABLE temp_bookmarks RENAME TO bookmarks")
5960 conn.execute("DROP TABLE bookmarks_old")
6667 return None
6768
6869
70 def _init_db_highlights(conn):
71 conn.execute('CREATE TABLE IF NOT EXISTS HIGHLIGHTS ' +
72 '(md5 TEXT, page INTEGER, ' +
73 'init_pos INTEGER, end_pos INTEGER)')
74 conn.commit()
75
76
6977 class BookmarkManager:
7078
7179 def __init__(self, filehash):
7684 assert dbpath != None
7785
7886 self._conn = sqlite3.connect(dbpath)
87 _init_db_highlights(self._conn)
88
7989 self._conn.text_factory = lambda x: unicode(x, "utf-8", "ignore")
8090
8191 self._bookmarks = []
8292 self._populate_bookmarks()
93 self._highlights = {0: []}
94 self._populate_highlights()
95
96 client = gconf.client_get_default()
97 self._user = client.get_string("/desktop/sugar/user/nick")
98 self._color = client.get_string("/desktop/sugar/user/color")
8399
84100 def add_bookmark(self, page, content, local=1):
85101 # locale = 0 means that this is a bookmark originally
86102 # created by the person who originally shared the file
87103 timestamp = time.time()
88 client = gconf.client_get_default()
89 user = client.get_string("/desktop/sugar/user/nick")
90 color = client.get_string("/desktop/sugar/user/color")
91
92 t = (self._filehash, page, content, timestamp, user, color, local)
93 self._conn.execute('insert into bookmarks values (?, ?, ?, ?, ?, ?, ?)', t)
104 t = (self._filehash, page, content, timestamp, self._user, \
105 self._color, local)
106 self._conn.execute('insert into bookmarks values ' + \
107 '(?, ?, ?, ?, ?, ?, ?)', t)
94108 self._conn.commit()
95109
96110 self._resync_bookmark_cache()
97111
98112 def del_bookmark(self, page):
99 client = gconf.client_get_default()
100 user = client.get_string("/desktop/sugar/user/nick")
101
102113 # We delete only the locally made bookmark
103114
104 t = (self._filehash, page, user)
105 self._conn.execute('delete from bookmarks where md5=? and page=? and user=?', t)
115 t = (self._filehash, page, self._user)
116 self._conn.execute('delete from bookmarks ' + \
117 'where md5=? and page=? and user=?', t)
106118 self._conn.commit()
107119
108120 self._resync_bookmark_cache()
109121
110122 def _populate_bookmarks(self):
111 # TODO: Figure out if caching the entire set of bookmarks is a good idea or not
112 rows = self._conn.execute('select * from bookmarks where md5=? order by page', (self._filehash, ))
123 # TODO: Figure out if caching the entire set of bookmarks
124 # is a good idea or not
125 rows = self._conn.execute('select * from bookmarks ' + \
126 'where md5=? order by page', (self._filehash, ))
113127
114128 for row in rows:
115129 self._bookmarks.append(Bookmark(row))
154168 return bookmark
155169
156170 return None
171
172 def get_highlights(self, page):
173 try:
174 return self._highlights[page]
175 except KeyError:
176 self._highlights[page] = []
177 return self._highlights[page]
178
179 def add_highlight(self, page, highlight_tuple):
180 logging.error('Adding hg page %d %s' % (page, highlight_tuple))
181 self.get_highlights(page).append(highlight_tuple)
182
183 t = (self._filehash, page, highlight_tuple[0],
184 highlight_tuple[1])
185 self._conn.execute('insert into highlights values ' + \
186 '(?, ?, ?, ?)', t)
187 self._conn.commit()
188
189 def del_highlight(self, page, highlight_tuple):
190 self._highlights[page].remove(highlight_tuple)
191 t = (self._filehash, page, highlight_tuple[0], \
192 highlight_tuple[1])
193 self._conn.execute('delete from highlights ' + \
194 'where md5=? and page=? and init_pos=? and end_pos=?', \
195 t)
196 self._conn.commit()
197
198 def _populate_highlights(self):
199 rows = self._conn.execute('select * from highlights ' + \
200 'where md5=? order by page', (self._filehash, ))
201 for row in rows:
202 # md5 = row[0]
203 page = row[1]
204 init_pos = row[2]
205 end_pos = row[3]
206 highlight_tuple = [init_pos, end_pos]
207 self.get_highlights(page).append(highlight_tuple)
144144
145145 self._is_showing_local_bookmark = False
146146
147 def set_bookmarkmanager(self, filehash):
148 self._bookmark_manager = BookmarkManager(filehash)
147 def set_bookmarkmanager(self, bookmark_manager):
148 self._bookmark_manager = bookmark_manager
149149
150150 def get_bookmarkmanager(self):
151151 return (self._bookmark_manager)
4949 self._zoom = 100
5050 self.font_zoom_relation = self._zoom / self._font_size
5151 self._current_page = 0
52
53 self.highlight_tag = self.textview.get_buffer().create_tag()
54 self.highlight_tag.set_property('underline', 'single')
55 self.highlight_tag.set_property('foreground', 'black')
56 self.highlight_tag.set_property('background', 'yellow')
5257
5358 def load_document(self, file_path):
5459 self._etext_file = open(file_path.replace('file://', ''), 'r')
8691 textbuffer = self.textview.get_buffer()
8792 label_text = label_text + '\n\n\n'
8893 textbuffer.set_text(label_text)
94
95 def can_highlight(self):
96 return True
97
98 def get_selection_bounds(self):
99 if self.textview.get_buffer().get_selection_bounds():
100 begin, end = self.textview.get_buffer().get_selection_bounds()
101 return [begin.get_offset(), end.get_offset()]
102 else:
103 return []
104
105 def get_cursor_position(self):
106 insert_mark = self.textview.get_buffer().get_insert()
107 return self.textview.get_buffer().get_iter_at_mark( \
108 insert_mark).get_offset()
109
110 def show_highlights(self, tuples_list):
111 textbuffer = self.textview.get_buffer()
112 bounds = textbuffer.get_bounds()
113 textbuffer.remove_all_tags(bounds[0], bounds[1])
114 for highlight_tuple in tuples_list:
115 iterStart = textbuffer.get_iter_at_offset(highlight_tuple[0])
116 iterEnd = textbuffer.get_iter_at_offset(highlight_tuple[1])
117 textbuffer.apply_tag(self.highlight_tag, iterStart, iterEnd)
89118
90119 def connect_page_changed_handler(self, handler):
91120 self.connect('page-changed', handler)
147176 def get_current_file(self):
148177 pass
149178
150 def update_metadata(self):
179 def update_metadata(self, activity):
151180 pass
152181
153182 def copy(self):