def load_finished(self, ok, data): cbd = self.calibre_book_data_for_first_book self.calibre_book_data_for_first_book = None if self.shutting_down: return open_at, self.pending_open_at = self.pending_open_at, None self.web_view.clear_caches() if not ok: self.actions_toolbar.update_action_state(False) self.setWindowTitle(self.base_window_title) tb = as_unicode(data['tb'].strip(), errors='replace') tb = re.split(r'^calibre\.gui2\.viewer\.convert_book\.ConversionFailure:\s*', tb, maxsplit=1, flags=re.M)[-1] last_line = tuple(tb.strip().splitlines())[-1] if last_line.startswith('calibre.ebooks.DRMError'): DRMErrorMessage(self).exec_() else: error_dialog(self, _('Loading book failed'), _( 'Failed to open the book at {0}. Click "Show details" for more info.').format(data['pathtoebook']), det_msg=tb, show=True) self.loading_overlay.hide() self.web_view.show_home_page() return try: set_book_path(data['base'], data['pathtoebook']) except Exception: if data['reloaded']: raise self.load_ebook(data['pathtoebook'], open_at=data['open_at'], reload_book=True) return self.current_book_data = data get_current_book_data(self.current_book_data) self.current_book_data['annotations_map'] = defaultdict(list) self.current_book_data['annotations_path_key'] = path_key(data['pathtoebook']) + '.json' self.load_book_data(cbd) self.update_window_title() initial_cfi = self.initial_cfi_for_current_book() initial_position = {'type': 'cfi', 'data': initial_cfi} if initial_cfi else None if open_at: if open_at.startswith('toc:'): initial_toc_node = self.toc_model.node_id_for_text(open_at[len('toc:'):]) initial_position = {'type': 'toc', 'data': initial_toc_node} elif open_at.startswith('toc-href:'): initial_toc_node = self.toc_model.node_id_for_href(open_at[len('toc-href:'):], exact=True) initial_position = {'type': 'toc', 'data': initial_toc_node} elif open_at.startswith('toc-href-contains:'): initial_toc_node = self.toc_model.node_id_for_href(open_at[len('toc-href-contains:'):], exact=False) initial_position = {'type': 'toc', 'data': initial_toc_node} elif open_at.startswith('epubcfi(/'): initial_position = {'type': 'cfi', 'data': open_at} elif open_at.startswith('ref:'): initial_position = {'type': 'ref', 'data': open_at[len('ref:'):]} elif is_float(open_at): initial_position = {'type': 'bookpos', 'data': float(open_at)} highlights = self.current_book_data['annotations_map']['highlight'] self.highlights_widget.load(highlights) self.web_view.start_book_load(initial_position=initial_position, highlights=highlights, current_book_data=self.current_book_data) performance_monitor('webview loading requested')
def load_ebook(self, pathtoebook, open_at=None, reload_book=False): performance_monitor('Load of book started', reset=True) self.web_view.show_home_page_on_ready = False if open_at: self.pending_open_at = open_at self.setWindowTitle(_('Loading book') + '… — {}'.format(self.base_window_title)) self.loading_overlay(_('Loading book, please wait')) self.save_annotations() self.current_book_data = {} get_current_book_data(self.current_book_data) self.search_widget.clear_searches() t = Thread(name='LoadBook', target=self._load_ebook_worker, args=(pathtoebook, open_at, reload_book or self.force_reload)) t.daemon = True t.start()
def exported_data(self): cbd = get_current_book_data() link_prefix = library_id = None if 'calibre_library_id' in cbd: library_id = cbd['calibre_library_id'] book_id = cbd['calibre_book_id'] book_fmt = cbd['calibre_book_fmt'] elif cbd.get('book_library_details'): bld = cbd['book_library_details'] book_id = bld['book_id'] book_fmt = bld['fmt'].upper() library_id = bld['library_id'] if library_id: library_id = '_hex_-' + library_id.encode('utf-8').hex() link_prefix = f'calibre://show-book/{library_id}/{book_id}/{book_fmt}?open_at=' fmt = self.export_format.currentData() if fmt == 'calibre_highlights': return json.dumps({ 'version': 1, 'type': 'calibre_highlights', 'highlights': self.annotations, }, ensure_ascii=False, sort_keys=True, indent=2) lines = [] as_markdown = fmt == 'md' for hl in self.annotations: render_highlight_as_text(hl, lines, as_markdown=as_markdown, link_prefix=link_prefix) return '\n'.join(lines).strip()
def load_ebook(self, pathtoebook, open_at=None, reload_book=False): if '.' not in os.path.basename(pathtoebook): pathtoebook = os.path.abspath(os.path.realpath(pathtoebook)) performance_monitor('Load of book started', reset=True) self.actions_toolbar.update_action_state(False) self.web_view.show_home_page_on_ready = False if open_at: self.pending_open_at = open_at self.setWindowTitle(_('Loading book') + f'… — {self.base_window_title}') self.loading_overlay(_('Loading book, please wait')) self.save_annotations() self.current_book_data = {} get_current_book_data(self.current_book_data) self.search_widget.clear_searches() t = Thread(name='LoadBook', target=self._load_ebook_worker, args=(pathtoebook, open_at, reload_book or self.force_reload)) t.daemon = True t.start()
def __init__(self, open_at=None, continue_reading=None, force_reload=False, calibre_book_data=None): MainWindow.__init__(self, None) self.annotations_saver = None self.calibre_book_data_for_first_book = calibre_book_data self.shutting_down = self.close_forced = self.shutdown_done = False self.force_reload = force_reload connect_lambda(self.book_preparation_started, self, lambda self: self.loading_overlay(_( 'Preparing book for first read, please wait')), type=Qt.ConnectionType.QueuedConnection) self.maximized_at_last_fullscreen = False self.save_pos_timer = t = QTimer(self) t.setSingleShot(True), t.setInterval(3000), t.setTimerType(Qt.TimerType.VeryCoarseTimer) connect_lambda(t.timeout, self, lambda self: self.save_annotations(in_book_file=False)) self.pending_open_at = open_at self.base_window_title = _('E-book viewer') self.setDockOptions(QMainWindow.DockOption.AnimatedDocks | QMainWindow.DockOption.AllowTabbedDocks | QMainWindow.DockOption.AllowNestedDocks) self.setWindowTitle(self.base_window_title) self.in_full_screen_mode = None self.image_popup = ImagePopup(self) self.actions_toolbar = at = ActionsToolBar(self) at.open_book_at_path.connect(self.ask_for_open) self.addToolBar(Qt.ToolBarArea.LeftToolBarArea, at) try: os.makedirs(annotations_dir) except EnvironmentError: pass self.current_book_data = {} get_current_book_data(self.current_book_data) self.book_prepared.connect(self.load_finished, type=Qt.ConnectionType.QueuedConnection) self.dock_defs = dock_defs() def create_dock(title, name, area, areas=Qt.DockWidgetArea.LeftDockWidgetArea | Qt.DockWidgetArea.RightDockWidgetArea): ans = QDockWidget(title, self) ans.setObjectName(name) self.addDockWidget(area, ans) ans.setVisible(False) ans.visibilityChanged.connect(self.dock_visibility_changed) return ans for dock_def in itervalues(self.dock_defs): setattr(self, '{}_dock'.format(dock_def.name.partition('-')[0]), create_dock( dock_def.title, dock_def.name, dock_def.initial_area, dock_def.allowed_areas)) self.toc_container = w = QWidget(self) w.l = QVBoxLayout(w) self.toc = TOCView(w) self.toc.clicked[QModelIndex].connect(self.toc_clicked) self.toc.searched.connect(self.toc_searched) self.toc_search = TOCSearch(self.toc, parent=w) w.l.addWidget(self.toc), w.l.addWidget(self.toc_search), w.l.setContentsMargins(0, 0, 0, 0) self.toc_dock.setWidget(w) self.search_widget = w = SearchPanel(self) w.search_requested.connect(self.start_search) w.hide_search_panel.connect(self.search_dock.close) w.count_changed.connect(self.search_results_count_changed) w.goto_cfi.connect(self.goto_cfi) self.search_dock.setWidget(w) self.search_dock.visibilityChanged.connect(self.search_widget.visibility_changed) self.lookup_widget = w = Lookup(self) self.lookup_dock.visibilityChanged.connect(self.lookup_widget.visibility_changed) self.lookup_dock.setWidget(w) self.bookmarks_widget = w = BookmarkManager(self) connect_lambda( w.create_requested, self, lambda self: self.web_view.trigger_shortcut('new_bookmark')) w.edited.connect(self.bookmarks_edited) w.activated.connect(self.bookmark_activated) w.toggle_requested.connect(self.toggle_bookmarks) self.bookmarks_dock.setWidget(w) self.highlights_widget = w = HighlightsPanel(self) self.highlights_dock.setWidget(w) w.toggle_requested.connect(self.toggle_highlights) self.web_view = WebView(self) self.web_view.cfi_changed.connect(self.cfi_changed) self.web_view.reload_book.connect(self.reload_book) self.web_view.toggle_toc.connect(self.toggle_toc) self.web_view.show_search.connect(self.show_search) self.web_view.find_next.connect(self.search_widget.find_next_requested) self.search_widget.show_search_result.connect(self.web_view.show_search_result) self.web_view.search_result_not_found.connect(self.search_widget.search_result_not_found) self.web_view.search_result_discovered.connect(self.search_widget.search_result_discovered) self.web_view.toggle_bookmarks.connect(self.toggle_bookmarks) self.web_view.toggle_highlights.connect(self.toggle_highlights) self.web_view.new_bookmark.connect(self.bookmarks_widget.create_new_bookmark) self.web_view.toggle_inspector.connect(self.toggle_inspector) self.web_view.toggle_lookup.connect(self.toggle_lookup) self.web_view.quit.connect(self.quit) self.web_view.update_current_toc_nodes.connect(self.toc.update_current_toc_nodes) self.web_view.toggle_full_screen.connect(self.toggle_full_screen) self.web_view.ask_for_open.connect(self.ask_for_open, type=Qt.ConnectionType.QueuedConnection) self.web_view.selection_changed.connect(self.lookup_widget.selected_text_changed, type=Qt.ConnectionType.QueuedConnection) self.web_view.selection_changed.connect(self.highlights_widget.selected_text_changed, type=Qt.ConnectionType.QueuedConnection) self.web_view.view_image.connect(self.view_image, type=Qt.ConnectionType.QueuedConnection) self.web_view.copy_image.connect(self.copy_image, type=Qt.ConnectionType.QueuedConnection) self.web_view.show_loading_message.connect(self.show_loading_message) self.web_view.show_error.connect(self.show_error) self.web_view.print_book.connect(self.print_book, type=Qt.ConnectionType.QueuedConnection) self.web_view.reset_interface.connect(self.reset_interface, type=Qt.ConnectionType.QueuedConnection) self.web_view.quit.connect(self.quit, type=Qt.ConnectionType.QueuedConnection) self.web_view.shortcuts_changed.connect(self.shortcuts_changed) self.web_view.scrollbar_context_menu.connect(self.scrollbar_context_menu) self.web_view.close_prep_finished.connect(self.close_prep_finished) self.web_view.highlights_changed.connect(self.highlights_changed) self.web_view.edit_book.connect(self.edit_book) self.actions_toolbar.initialize(self.web_view, self.search_dock.toggleViewAction()) at.update_action_state(False) self.setCentralWidget(self.web_view) self.loading_overlay = LoadingOverlay(self) self.restore_state() self.actions_toolbar.update_visibility() self.dock_visibility_changed() self.highlights_widget.request_highlight_action.connect(self.web_view.highlight_action) self.highlights_widget.web_action.connect(self.web_view.generic_action) if continue_reading: self.continue_reading() self.setup_mouse_auto_hide()