annot['notes'] = notes.strip() else: annot.pop('notes', None) db = current_db() db.update_annotations({annot_id: annot}) self.details_panel.update_notes(annot) def show_dialog(self): if self.parent() is None: self.browse_panel.effective_query_changed() self.exec_() else: self.reinitialize() self.show() self.raise_() QTimer.singleShot(80, self.browse_panel.effective_query_changed) def reinitialize(self): self.browse_panel.re_initialize() if __name__ == '__main__': from calibre.library import db app = Application([]) current_db.ans = db(os.path.expanduser('~/test library')) br = AnnotationsBrowser() br.reinitialize() br.show_dialog() del br del app
#!/usr/bin/env python # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai from __future__ import (unicode_literals, division, absolute_import, print_function) __license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>' __docformat__ = 'restructuredtext en' from calibre.gui2 import Application from PyQt4.Qt import (QDialog, QGridLayout, QListWidget, QDialogButtonBox, QPushButton, QTimer, QIcon) app = Application([], force_calibre_style=True) d = QDialog() d.l = l = QGridLayout() d.setLayout(l) lw = QListWidget() lw.addItem('Some text guy') l.addWidget(lw, 0, 0, 2, 1) bb = QDialogButtonBox() bb.setStandardButtons(bb.Close) bb.accepted.connect(d.accept) bb.rejected.connect(d.reject) b = bb.addButton('Action', bb.ActionRole) b.setIcon(QIcon(I('wizard.png'))) l.addWidget(bb, 2, 0, 1, 2) bb.button(bb.Close).setDefault(True) b = QPushButton('Normal')
def main(args=sys.argv): # Ensure viewer can continue to function if GUI is closed os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None) reset_base_dir() scheme = QWebEngineUrlScheme(FAKE_PROTOCOL.encode('ascii')) scheme.setSyntax(QWebEngineUrlScheme.Syntax.Host) scheme.setFlags(QWebEngineUrlScheme.SecureScheme) QWebEngineUrlScheme.registerScheme(scheme) override = 'calibre-ebook-viewer' if islinux else None app = Application(args, override_program_name=override, color_prefs=vprefs, windows_app_uid=VIEWER_APP_UID) parser = option_parser() opts, args = parser.parse_args(args) if opts.open_at and not (opts.open_at.startswith('toc:') or opts.open_at.startswith('epubcfi(/')): raise SystemExit('Not a valid --open-at value: {}'.format( opts.open_at)) listener = None if vprefs['singleinstance']: try: listener = ensure_single_instance(args, opts.open_at) except Exception as e: import traceback error_dialog(None, _('Failed to start viewer'), as_unicode(e), det_msg=traceback.format_exc(), show=True) raise SystemExit(1) acc = EventAccumulator(app) app.file_event_hook = acc app.load_builtin_fonts() app.setWindowIcon(QIcon(I('viewer.png'))) migrate_previous_viewer_prefs() main = EbookViewer(open_at=opts.open_at, continue_reading=opts.continue_reading) main.set_exception_handler() if len(args) > 1: acc.events.append(args[-1]) acc.got_file.connect(main.handle_commandline_arg) main.show() main.msg_from_anotherinstance.connect(main.another_instance_wants_to_talk, type=Qt.QueuedConnection) if listener is not None: t = Thread(name='ConnListener', target=listen, args=(listener, main.msg_from_anotherinstance)) t.daemon = True t.start() QTimer.singleShot(0, acc.flush) if opts.raise_window: main.raise_() if opts.full_screen: main.set_full_screen(True) app.exec_() if listener is not None: listener.close()
def main(args=sys.argv): # Ensure viewer can continue to function if GUI is closed os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None) reset_base_dir() scheme = QWebEngineUrlScheme(FAKE_PROTOCOL.encode('ascii')) scheme.setSyntax(QWebEngineUrlScheme.Syntax.Host) scheme.setFlags(QWebEngineUrlScheme.Flag.SecureScheme) QWebEngineUrlScheme.registerScheme(scheme) override = 'calibre-ebook-viewer' if islinux else None processed_args = [] internal_book_data = internal_book_data_path = None for arg in args: if arg.startswith('--internal-book-data='): internal_book_data_path = arg.split('=', 1)[1] continue processed_args.append(arg) if internal_book_data_path: try: with lopen(internal_book_data_path, 'rb') as f: internal_book_data = json.load(f) finally: try: os.remove(internal_book_data_path) except EnvironmentError: pass args = processed_args app = Application(args, override_program_name=override, windows_app_uid=VIEWER_APP_UID) parser = option_parser() opts, args = parser.parse_args(args) oat = opts.open_at if oat and not (oat.startswith('toc:') or oat.startswith('toc-href:') or oat.startswith('toc-href-contains:') or oat.startswith('epubcfi(/') or is_float(oat) or oat.startswith('ref:')): raise SystemExit('Not a valid --open-at value: {}'.format( opts.open_at)) if get_session_pref('singleinstance', False): from calibre.utils.lock import SingleInstance from calibre.gui2.listener import Listener with SingleInstance(singleinstance_name) as si: if si: try: listener = Listener(address=viewer_socket_address(), parent=app) listener.start_listening() except Exception as err: error_dialog( None, _('Failed to start listener'), _('Could not start the listener used for single instance viewers. Try rebooting your computer.' ), det_msg=str(err), show=True) else: with closing(listener): run_gui(app, opts, args, internal_book_data, listener=listener) else: send_message_to_viewer_instance(args, opts.open_at) else: run_gui(app, opts, args, internal_book_data)
def initialize(self, library_path, db, listener, actions, show_gui=True): from calibre.gui2 import Application app = Application([]) app.load_builtin_fonts() w = QtWidgets.QWidget() w.show() app.exec_() #time.sleep(1000) opts = self.opts self.preferences_action, self.quit_action = actions self.library_path = library_path self.library_broker = GuiLibraryBroker(db) self.content_server = None self.server_change_notification_timer = t = QTimer(self) self.server_changes = Queue() t.setInterval(1000), t.timeout.connect( self.handle_changes_from_server_debounced), t.setSingleShot(True) self._spare_pool = None self.must_restart_before_config = False self.listener = Listener(listener) self.check_messages_timer = QTimer() self.check_messages_timer.timeout.connect( self.another_instance_wants_to_talk) self.check_messages_timer.start(1000) for ac in self.iactions.values(): try: ac.do_genesis() except Exception: # Ignore errors in third party plugins import traceback traceback.print_exc() if getattr(ac, 'plugin_path', None) is None: raise self.donate_action = QAction(QIcon(I('donate.png')), _('&Donate to support calibre'), self) for st in self.istores.values(): st.do_genesis() MainWindowMixin.init_main_window_mixin(self, db) # Jobs Button {{{ self.job_manager = JobManager() self.jobs_dialog = JobsDialog(self, self.job_manager) self.jobs_button = JobsButton(parent=self) self.jobs_button.initialize(self.jobs_dialog, self.job_manager) # }}} LayoutMixin.init_layout_mixin(self) DeviceMixin.init_device_mixin(self) self.progress_indicator = ProgressIndicator(self) self.progress_indicator.pos = (0, 20) self.verbose = opts.verbose self.get_metadata = GetMetadata() self.upload_memory = {} self.metadata_dialogs = [] self.default_thumbnail = None self.tb_wrapper = textwrap.TextWrapper(width=40) self.viewers = collections.deque() self.system_tray_icon = None do_systray = config['systray_icon'] or opts.start_in_tray if do_systray: self.system_tray_icon = factory( app_id='com.calibre-ebook.gui').create_system_tray_icon( parent=self, title='calibre') if self.system_tray_icon is not None: self.system_tray_icon.setIcon( QIcon(I('lt.png', allow_user_override=False))) if not (iswindows or isosx): self.system_tray_icon.setIcon( QIcon.fromTheme('calibre-tray', self.system_tray_icon.icon())) self.system_tray_icon.setToolTip(self.jobs_button.tray_tooltip()) self.system_tray_icon.setVisible(True) self.jobs_button.tray_tooltip_updated.connect( self.system_tray_icon.setToolTip) elif do_systray: prints( 'Failed to create system tray icon, your desktop environment probably' ' does not support the StatusNotifier spec https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/' ) self.system_tray_menu = QMenu(self) self.toggle_to_tray_action = self.system_tray_menu.addAction( QIcon(I('page.png')), '') self.toggle_to_tray_action.triggered.connect( self.system_tray_icon_activated) self.system_tray_menu.addAction(self.donate_action) self.eject_action = self.system_tray_menu.addAction( QIcon(I('eject.png')), _('&Eject connected device')) self.eject_action.setEnabled(False) self.addAction(self.quit_action) self.system_tray_menu.addAction(self.quit_action) self.keyboard.register_shortcut('quit calibre', _('Quit calibre'), default_keys=('Ctrl+Q', ), action=self.quit_action) if self.system_tray_icon is not None: self.system_tray_icon.setContextMenu(self.system_tray_menu) self.system_tray_icon.activated.connect( self.system_tray_icon_activated) self.quit_action.triggered[bool].connect(self.quit) self.donate_action.triggered[bool].connect(self.donate) self.minimize_action = QAction(_('Minimize the calibre window'), self) self.addAction(self.minimize_action) self.keyboard.register_shortcut('minimize calibre', self.minimize_action.text(), default_keys=(), action=self.minimize_action) self.minimize_action.triggered.connect(self.showMinimized) self.esc_action = QAction(self) self.addAction(self.esc_action) self.keyboard.register_shortcut('clear current search', _('Clear the current search'), default_keys=('Esc', ), action=self.esc_action) self.esc_action.triggered.connect(self.esc) self.shift_esc_action = QAction(self) self.addAction(self.shift_esc_action) self.keyboard.register_shortcut('focus book list', _('Focus the book list'), default_keys=('Shift+Esc', ), action=self.shift_esc_action) self.shift_esc_action.triggered.connect(self.shift_esc) self.ctrl_esc_action = QAction(self) self.addAction(self.ctrl_esc_action) self.keyboard.register_shortcut('clear virtual library', _('Clear the virtual library'), default_keys=('Ctrl+Esc', ), action=self.ctrl_esc_action) self.ctrl_esc_action.triggered.connect(self.ctrl_esc) self.alt_esc_action = QAction(self) self.addAction(self.alt_esc_action) self.keyboard.register_shortcut('clear additional restriction', _('Clear the additional restriction'), default_keys=('Alt+Esc', ), action=self.alt_esc_action) self.alt_esc_action.triggered.connect( self.clear_additional_restriction) # ###################### Start spare job server ######################## QTimer.singleShot(1000, self.create_spare_pool) # ###################### Location Manager ######################## self.location_manager.location_selected.connect(self.location_selected) self.location_manager.unmount_device.connect( self.device_manager.umount_device) self.location_manager.configure_device.connect( self.configure_connected_device) self.location_manager.update_device_metadata.connect( self.update_metadata_on_device) self.eject_action.triggered.connect(self.device_manager.umount_device) # ################### Update notification ################### UpdateMixin.init_update_mixin(self, opts) # ###################### Search boxes ######################## SearchRestrictionMixin.init_search_restriction_mixin(self) SavedSearchBoxMixin.init_saved_seach_box_mixin(self) # ###################### Library view ######################## LibraryViewMixin.init_library_view_mixin(self, db) SearchBoxMixin.init_search_box_mixin(self) # Requires current_db self.library_view.model().count_changed_signal.connect( self.iactions['Choose Library'].count_changed) if not gprefs.get('quick_start_guide_added', False): try: add_quick_start_guide(self.library_view) except: import traceback traceback.print_exc() for view in ('library', 'memory', 'card_a', 'card_b'): v = getattr(self, '%s_view' % view) v.selectionModel().selectionChanged.connect(self.update_status_bar) v.model().count_changed_signal.connect(self.update_status_bar) self.library_view.model().count_changed() self.bars_manager.database_changed(self.library_view.model().db) self.library_view.model().database_changed.connect( self.bars_manager.database_changed, type=Qt.QueuedConnection) # ########################## Tags Browser ############################## TagBrowserMixin.init_tag_browser_mixin(self, db) self.library_view.model().database_changed.connect( self.populate_tb_manage_menu, type=Qt.QueuedConnection) # ######################## Search Restriction ########################## if db.prefs['virtual_lib_on_startup']: self.apply_virtual_library(db.prefs['virtual_lib_on_startup']) self.rebuild_vl_tabs() # ########################## Cover Flow ################################ CoverFlowMixin.init_cover_flow_mixin(self) self._calculated_available_height = min(max_available_height() - 15, self.height()) self.resize(self.width(), self._calculated_available_height) self.build_context_menus() for ac in self.iactions.values(): try: ac.gui_layout_complete() except: import traceback traceback.print_exc() if ac.plugin_path is None: raise if config['autolaunch_server']: self.start_content_server() self.read_settings() self.finalize_layout() self.bars_manager.start_animation() self.set_window_title() for ac in self.iactions.values(): try: ac.initialization_complete() except: import traceback traceback.print_exc() if ac.plugin_path is None: raise self.set_current_library_information(current_library_name(), db.library_id, db.field_metadata) register_keyboard_shortcuts() self.keyboard.finalize() if show_gui: # Note this has to come after restoreGeometry() because of # https://bugreports.qt.io/browse/QTBUG-56831 self.show() if self.system_tray_icon is not None and self.system_tray_icon.isVisible( ) and opts.start_in_tray: self.hide_windows() self.auto_adder = AutoAdder(gprefs['auto_add_path'], self) # Now that the gui is initialized we can restore the quickview state # The same thing will be true for any action-based operation with a # layout button from calibre.gui2.actions.show_quickview import get_quickview_action_plugin qv = get_quickview_action_plugin() if qv: qv.qv_button.restore_state() self.save_layout_state() # Collect cycles now gc.collect() QApplication.instance().shutdown_signal_received.connect(self.quit) if show_gui and self.gui_debug is not None: QTimer.singleShot(10, self.show_gui_debug_msg) self.iactions['Connect Share'].check_smartdevice_menus() QTimer.singleShot(1, self.start_smartdevice) QTimer.singleShot(100, self.update_toggle_to_tray_action)