def main(): from calibre.gui2 import Application app = Application([]) spl = SplashScreen(develop=True) spl.show() spl.show_message('Testing the splash screen message...') app.exec_()
def main(): from calibre.gui2 import Application from PyQt5.Qt import QMainWindow, QStatusBar, QTimer app = Application([]) w = QMainWindow() s = QStatusBar(w) w.setStatusBar(s) s.showMessage("Testing ProceedQuestion") w.show() p = ProceedQuestion(w) def doit(): p.dummy_question() p.dummy_question(action_label="A very long button for testing relayout (indeed)") p( lambda p: None, None, "ass2", "ass2", "testing2", "testing2", det_msg="details shown first, with a long line to test wrapping of text and width layout", show_det=True, show_ok=True, ) QTimer.singleShot(10, doit) app.exec_()
def test(scale=0.25): from PyQt5.Qt import QLabel, QPixmap, QMainWindow, QWidget, QScrollArea, QGridLayout from calibre.gui2 import Application app = Application([]) mi = Metadata('Unknown', ['Kovid Goyal', 'John & Doe', 'Author']) mi.series = 'A series & styles' m = QMainWindow() sa = QScrollArea(m) w = QWidget(m) sa.setWidget(w) l = QGridLayout(w) w.setLayout(l), l.setSpacing(30) scale *= w.devicePixelRatioF() labels = [] for r, color in enumerate(sorted(default_color_themes)): for c, style in enumerate(sorted(all_styles())): mi.series_index = c + 1 mi.title = 'An algorithmic cover [%s]' % color prefs = override_prefs(cprefs, override_color_theme=color, override_style=style) scale_cover(prefs, scale) img = generate_cover(mi, prefs=prefs, as_qimage=True) img.setDevicePixelRatio(w.devicePixelRatioF()) la = QLabel() la.setPixmap(QPixmap.fromImage(img)) l.addWidget(la, r, c) labels.append(la) m.setCentralWidget(sa) w.resize(w.sizeHint()) m.show() app.exec_()
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() parser = option_parser() opts, args = parser.parse_args(args) pid = os.fork() if False and (islinux or isbsd) else -1 try: open_at = float(opts.open_at) except: open_at = None if pid <= 0: override = 'calibre-ebook-viewer' if islinux else None app = Application(args, override_program_name=override) app.setWindowIcon(QIcon(I('viewer.png'))) QApplication.setOrganizationName(ORG_NAME) QApplication.setApplicationName(APP_UID) main = EbookViewer(args[1] if len(args) > 1 else None, debug_javascript=opts.debug_javascript, open_at=open_at) # This is needed for paged mode. Without it, the first document that is # loaded will have extra blank space at the bottom, as # turn_off_internal_scrollbars does not take effect for the first # rendered document main.view.load_path(P('viewer/blank.html', allow_user_override=False)) sys.excepthook = main.unhandled_exception main.show() if opts.raise_window: main.raise_() if opts.full_screen: main.action_full_screen.trigger() with main: return app.exec_() return 0
def init_qt(args): parser = option_parser() opts, args = parser.parse_args(args) find_portable_library() if opts.with_library is not None: libpath = os.path.expanduser(opts.with_library) if not os.path.exists(libpath): os.makedirs(libpath) if os.path.isdir(libpath): prefs.set('library_path', os.path.abspath(libpath)) prints('Using library at', prefs['library_path']) override = 'calibre-gui' if islinux else None app = Application(args, override_program_name=override) app.file_event_hook = EventAccumulator() try: is_x11 = app.platformName() == 'xcb' except Exception: import traceback traceback.print_exc() is_x11 = False # Ancient broken VNC servers cannot handle icons of size greater than 256 # https://www.mobileread.com/forums/showthread.php?t=278447 ic = 'lt.png' if is_x11 else 'library.png' app.setWindowIcon(QIcon(I(ic, allow_user_override=False))) return app, opts, args
def main(): from calibre.gui2 import Application from calibre.gui2.tweak_book.boss import get_container app = Application([]) # noqa path = sys.argv[-1] container = get_container(path) d = Check() d.run_checks(container) d.show() app.exec_()
def main(): os.closerange(3, 256) from calibre.gui2 import Application app = Application([]) s = CalibreSplashScreen() s.show_message.connect(s.showMessage, type=Qt.QueuedConnection) s.shutdown.connect(app.quit, type=Qt.QueuedConnection) s.show() Thread(target=run_loop, args=(s,)).start() app.exec_()
def process_updates(self): ''' ''' self._log_location() db_folder = self._get_folder_location() if db_folder: sub_folder = os.path.join(db_folder, 'Metadata') updates = glob.glob(os.path.join(sub_folder, '*.xml')) if os.path.exists(sub_folder) and updates: self._log("processing Marvin Dropbox folder at '{0}'".format(db_folder)) pb = ProgressBar(parent=self.opts.gui, window_title="Processing Dropbox updates", on_top=True) total_books = len(updates) pb.set_maximum(total_books) pb.set_value(0) pb.show() for update in updates: with file(update) as f: doc = etree.fromstring(f.read()) if doc.tag == "metadatasnapshot" and doc.attrib['creator'] == "Marvin": book = doc.xpath('//book')[0] title = book.attrib['title'] pb.set_label('{:^100}'.format("{0}".format(title))) pb.increment() cid = self._find_in_calibre_db(book) if cid: # *** Are we going to care about who's most recent? c_last_modified = self._get_calibre_last_modified(cid) m_last_modified = self._get_marvin_last_modified(book) if c_last_modified > m_last_modified: self._log("calibre metadata is newer") elif m_last_modified > c_last_modified: self._log("Marvin metadata is newer") self._update_calibre_metadata(book, cid) self._log("*** Deleting metadata update record: NOT IMPLEMENTED ***") #os.remove(update) Application.processEvents() time.sleep(1.0) pb.hide() del pb updateCalibreGUIView() else: self._log("No MAX updates found")
def main(): from calibre.gui2 import Application from PyQt5.Qt import QMainWindow app = Application([]) w = QMainWindow() w.show() p = ProceedQuestion(None) p(lambda p,q:None, None, 'ass', 'ass', 'testing', 'testing', checkbox_msg='testing the ruddy checkbox', det_msg='details') p(lambda p:None, None, 'ass2', 'ass2', 'testing2', 'testing2', det_msg='details shown first', show_det=True, show_ok=True, geom_pref='ProceedQuestion-unit-test') app.exec_()
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() parser = option_parser() opts, args = parser.parse_args(args) open_at = float(opts.open_at.replace(',', '.')) if opts.open_at else None override = 'calibre-ebook-viewer' if islinux else None app = Application(args, override_program_name=override, color_prefs=vprefs) app.load_builtin_fonts() app.setWindowIcon(QIcon(I('viewer.png'))) QApplication.setOrganizationName(ORG_NAME) QApplication.setApplicationName(APP_UID) main = EbookViewer(args[1] if len(args) > 1 else None, debug_javascript=opts.debug_javascript, open_at=open_at, continue_reading=opts.continue_reading, start_in_fullscreen=opts.full_screen) app.installEventFilter(main) # This is needed for paged mode. Without it, the first document that is # loaded will have extra blank space at the bottom, as # turn_off_internal_scrollbars does not take effect for the first # rendered document main.view.load_path(P('viewer/blank.html', allow_user_override=False)) sys.excepthook = main.unhandled_exception main.show() if opts.raise_window: main.raise_() with main: return app.exec_() return 0
def init_qt(args): from calibre.gui2.ui import Main parser = option_parser() opts, args = parser.parse_args(args) if opts.with_library is not None: if not os.path.exists(opts.with_library): os.makedirs(opts.with_library) if os.path.isdir(opts.with_library): prefs.set('library_path', os.path.abspath(opts.with_library)) prints('Using library at', prefs['library_path']) QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setApplicationName(APP_UID) override = 'calibre-gui' if islinux else None app = Application(args, override_program_name=override) actions = tuple(Main.create_application_menubar()) app.setWindowIcon(QIcon(I('lt.png'))) return app, opts, args, actions
def _run(args, notify=None): # Ensure we can continue to function if GUI is closed os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None) reset_base_dir() if iswindows: # Ensure that all ebook editor instances are grouped together in the task # bar. This prevents them from being grouped with viewer process when # launched from within calibre, as both use calibre-parallel.exe import ctypes try: ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID( EDITOR_APP_UID ) except Exception: pass # Only available on windows 7 and newer # The following two lines are needed to prevent circular imports causing # errors during initialization of plugins that use the polish container # infrastructure. importlib.import_module('calibre.customize.ui') from calibre.gui2.tweak_book import tprefs from calibre.gui2.tweak_book.ui import Main parser = option_parser() opts, args = parser.parse_args(args) decouple('edit-book-'), set_gui_prefs(tprefs) override = 'calibre-edit-book' if islinux else None app = Application(args, override_program_name=override, color_prefs=tprefs) app.file_event_hook = EventAccumulator() app.load_builtin_fonts() app.setWindowIcon(QIcon(I('tweak.png'))) main = Main(opts, notify=notify) main.set_exception_handler() main.show() app.shutdown_signal_received.connect(main.boss.quit) if len(args) > 1: main.boss.open_book(args[1], edit_file=args[2:], clear_notify_data=False) else: for path in reversed(app.file_event_hook.events): main.boss.open_book(path) break app.file_event_hook = main.boss.open_book app.exec_() # Ensure that the parse worker has quit so that temp files can be deleted # on windows st = time.time() from calibre.gui2.tweak_book.preview import parse_worker while parse_worker.is_alive() and time.time() - st < 120: time.sleep(0.1)
def init_qt(args): parser = option_parser() opts, args = parser.parse_args(args) find_portable_library() if opts.with_library is not None: libpath = os.path.expanduser(opts.with_library) if not os.path.exists(libpath): os.makedirs(libpath) if os.path.isdir(libpath): prefs.set('library_path', os.path.abspath(libpath)) prints('Using library at', prefs['library_path']) QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setApplicationName(APP_UID) override = 'calibre-gui' if islinux else None app = Application(args, override_program_name=override) app.file_event_hook = EventAccumulator() app.setWindowIcon(QIcon(I('lt.png'))) return app, opts, args
def main(args=sys.argv, logger=None): parser = option_parser() opts, args = parser.parse_args(args) if hasattr(opts, 'help'): parser.print_help() return 1 pid = os.fork() if (islinux or isbsd) else -1 if pid <= 0: override = 'calibre-lrf-viewer' if islinux else None app = Application(args, override_program_name=override) app.setWindowIcon(QIcon(I('viewer.png'))) opts = normalize_settings(parser, opts) stream = open(args[1], 'rb') if len(args) > 1 else None main = file_renderer(stream, opts, logger=logger) main.set_exception_handler() main.show() main.render() main.activateWindow() main.raise_() return app.exec_() return 0
def windows_repair(library_path=None): from binascii import hexlify, unhexlify import cPickle, subprocess if library_path: library_path = hexlify(cPickle.dumps(library_path, -1)) winutil.prepare_for_restart() os.environ['CALIBRE_REPAIR_CORRUPTED_DB'] = library_path subprocess.Popen([sys.executable]) else: try: app = Application([]) from calibre.gui2.dialogs.restore_library import repair_library_at library_path = cPickle.loads(unhexlify(os.environ.pop('CALIBRE_REPAIR_CORRUPTED_DB'))) done = repair_library_at(library_path, wait_time=4) except Exception: done = False error_dialog(None, _('Failed to repair library'), _( 'Could not repair library. Click "Show details" for more information.'), det_msg=traceback.format_exc(), show=True) if done: subprocess.Popen([sys.executable]) app.quit()
def main(args=sys.argv): from calibre.gui2 import Application left, right = args[-2:] ext1, ext2 = left.rpartition('.')[-1].lower(), right.rpartition('.')[-1].lower() if ext1.startswith('original_'): ext1 = ext1.partition('_')[-1] if ext2.startswith('original_'): ext2 = ext2.partition('_')[-2] if os.path.isdir(left): attr = 'dir_diff' elif (ext1, ext2) in {('epub', 'epub'), ('azw3', 'azw3')}: attr = 'ebook_diff' else: attr = 'file_diff' app = Application([]) # noqa d = Diff(show_as_window=True) func = getattr(d, attr) QTimer.singleShot(0, lambda : func(left, right)) d.show() app.exec_() return 0
def windows_repair(library_path=None): import subprocess from calibre.utils.serialize import json_dumps, json_loads from polyglot.binary import as_hex_unicode, from_hex_bytes if library_path: library_path = as_hex_unicode(json_dumps(library_path)) winutil.prepare_for_restart() os.environ['CALIBRE_REPAIR_CORRUPTED_DB'] = environ_item(library_path) subprocess.Popen([sys.executable]) else: try: app = Application([]) from calibre.gui2.dialogs.restore_library import repair_library_at library_path = json_loads(from_hex_bytes(os.environ.pop('CALIBRE_REPAIR_CORRUPTED_DB'))) done = repair_library_at(library_path, wait_time=4) except Exception: done = False error_dialog(None, _('Failed to repair library'), _( 'Could not repair library. Click "Show details" for more information.'), det_msg=traceback.format_exc(), show=True) if done: subprocess.Popen([sys.executable]) app.quit()
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() parser = option_parser() opts, args = parser.parse_args(args) open_at = float(opts.open_at.replace(',', '.')) if opts.open_at else None listener = None override = 'calibre-ebook-viewer' if islinux else None acc = EventAccumulator() app = Application(args, override_program_name=override, color_prefs=vprefs) app.file_event_hook = acc app.load_builtin_fonts() app.setWindowIcon(QIcon(I('viewer.png'))) QApplication.setOrganizationName(ORG_NAME) QApplication.setApplicationName(APP_UID) if vprefs['singleinstance']: try: listener = ensure_single_instance(args, 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) main = EbookViewer(args[1] if len(args) > 1 else None, debug_javascript=opts.debug_javascript, open_at=open_at, continue_reading=opts.continue_reading, start_in_fullscreen=opts.full_screen, listener=listener, file_events=acc) app.installEventFilter(main) # This is needed for paged mode. Without it, the first document that is # loaded will have extra blank space at the bottom, as # turn_off_internal_scrollbars does not take effect for the first # rendered document main.view.load_path(P('viewer/blank.html', allow_user_override=False)) main.set_exception_handler() main.show() if opts.raise_window: main.raise_() with main: return app.exec_() return 0
def copy_to_clipboard(self, *args): ''' Store window contents to system clipboard ''' modifiers = Application.keyboardModifiers() if bool(modifiers & Qt.AltModifier): contents = self.html_wv.page().currentFrame().toHtml() #contents = BeautifulSoup(str(contents)).prettify() QApplication.clipboard().setText(contents) else: contents = self.html_wv.page().currentFrame().toPlainText() QApplication.clipboard().setText(unicode(contents)) if hasattr(self, 'ctc_button'): self.ctc_button.setText('Copied') self.ctc_button.setIcon(QIcon(I('ok.png')))
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)
return self.previous_button.setEnabled(False if row == 0 else True) self.next_button.setEnabled(False if row == self.view.model().rowCount(QModelIndex())-1 else True) self.current_row = row self.setWindowTitle(mi.title) self.cover_pixmap = QPixmap.fromImage(mi.cover_data[1]) try: dpr = self.devicePixelRatioF() except AttributeError: dpr = self.devicePixelRatio() self.cover_pixmap.setDevicePixelRatio(dpr) self.resize_cover() html = render_html(mi, self.css, True, self, pref_name='popup_book_display_fields') set_html(mi, html, self.details) self.marked = mi.marked self.cover.setBackgroundBrush(self.marked_brush if mi.marked else self.normal_brush) self.update_cover_tooltip() if __name__ == '__main__': from calibre.gui2 import Application from calibre.library import db app = Application([]) app.current_db = db() get_gui.ans = app d = Configure(app.current_db) d.exec_() del d del app
def get_installed_books(self): """ Fetch installed books from iBooks_*.sqlite or cache """ self._log("%s:get_installed_books()" % self.app_name) self.opts.pb.set_label("Getting installed books from %s" % self.app_name) self.opts.pb.set_value(0) db_profile = self._localize_database_path(self.app_id, self.books_subpath) self.books_db = db_profile['path'] cached_db = self.generate_books_db_name(self.app_name_, self.ios.device_name) # Test timestamp against cached value if self.opts.disable_caching or not self._cache_is_current(db_profile['stats'], cached_db): # (Re)load installed books from device self._log(" fetching installed books from %s on %s" % (self.app_name, self.ios.device_name)) # Mount the Media folder self.ios.mount_ios_media_folder() installed_books = set([]) self.tocs = {} # Create the books table as needed self.create_books_table(cached_db) con = sqlite3.connect(self.books_db) with con: con.row_factory = sqlite3.Row cur = con.cursor() cur.execute('''SELECT ZASSETURL, ZBOOKAUTHOR, ZSORTAUTHOR, ZBOOKTITLE, ZSORTTITLE, ZDATABASEKEY FROM ZBKBOOKINFO WHERE ZASSETURL LIKE 'file://localhost%' AND ZASSETURL LIKE '%.epub/' ''') rows = cur.fetchall() self.opts.pb.set_maximum(len(rows)) for row in rows: self.opts.pb.increment() this_is_news = False path = self._fix_iBooks_path(row[b'ZASSETURL']) mi = self._get_metadata(path, row[b'ZBOOKTITLE']) genres = mi['genre'].split(', ') if 'News' in genres: if not self.collect_news_clippings: continue this_is_news = True book_id = row[b'ZDATABASEKEY'] installed_books.add(book_id) # Populate a BookStruct b_mi = BookStruct() b_mi.active = True b_mi.author = row[b'ZBOOKAUTHOR'] b_mi.author_sort = row[b'ZSORTAUTHOR'] b_mi.book_id = book_id b_mi.genre = mi['genre'] b_mi.title = row[b'ZBOOKTITLE'] b_mi.title_sort = row[b'ZSORTTITLE'] b_mi.uuid = mi['uuid'] # Add book to books_db self.add_to_books_db(cached_db, b_mi) # Get the library cid, confidence toc_entries = None if this_is_news: cid = self.news_clippings_cid confidence = 5 if path is not None: toc_entries = self._get_epub_toc(path=path, prepend_title=b_mi.title) elif self.ios.exists(path): cid, confidence = self.parent.generate_confidence(b_mi) if confidence >= 2: toc_entries = self._get_epub_toc(cid=cid, path=path) elif path is not None: toc_entries = self._get_epub_toc(path=path) self.tocs[book_id] = toc_entries # Update the timestamp self.update_timestamp(cached_db) self.commit() self.ios.dismount_ios_media_folder() installed_books = list(installed_books) else: self._log(" retrieving cached books from %s" % cached_db) self.opts.pb.set_maximum(2) self.opts.pb.set_value(1) Application.processEvents() installed_books = self._get_cached_books(cached_db) self.installed_books = installed_books
def get_installed_books(self): """ Fetch installed books from mainDb.sqlite or cached_db Populate self.tocs: {book_id: {toc_entries} ...} """ self._log("%s:get_installed_books()" % self.app_name) self.opts.pb.set_label("Getting installed books from %s" % self.app_name) self.opts.pb.set_value(0) db_profile = self._localize_database_path(self.app_id, self.books_subpath) self.books_db = db_profile['path'] cached_db = self.generate_books_db_name(self.app_name_, self.ios.device_name) if self.opts.disable_caching or not self._cache_is_current(db_profile['stats'], cached_db): # (Re)load installed books from device self._log(" fetching installed books from %s on %s" % (self.app_name, self.ios.device_name)) # Mount the ios container self.ios.mount_ios_app(app_id=self.app_id) installed_books = set([]) self.tocs = {} # Create the books table as needed self.create_books_table(cached_db) con = sqlite3.connect(self.books_db) with con: con.row_factory = sqlite3.Row cur = con.cursor() cur.execute('''SELECT Author, AuthorSort, Title, CalibreTitleSort, FileName, Books.ID AS id_, UUID FROM Books ''') rows = cur.fetchall() self.opts.pb.set_maximum(len(rows)) for row in rows: self.opts.pb.increment() this_is_news = False path = self._fix_Marvin_path(row[b'FileName']) book_id = row[b'id_'] # Get the genre(s) for this book genre_cur = con.cursor() genre_cur.execute("""SELECT Subject FROM BookSubjects WHERE BookID = '{0}' """.format(book_id)) genres = None genre_rows = genre_cur.fetchall() if genre_rows is not None: genres = ', '.join([genre[b'Subject'] for genre in genre_rows]) genre_cur.close() if 'News' in genres: if not self.collect_news_clippings: continue this_is_news = True installed_books.add(book_id) # Populate a BookStruct b_mi = BookStruct() b_mi.active = True b_mi.author = row[b'Author'] b_mi.author_sort = row[b'AuthorSort'] b_mi.book_id = book_id b_mi.genre = genres b_mi.title = row[b'Title'] b_mi.title_sort = row[b'CalibreTitleSort'] b_mi.uuid = row[b'UUID'] # Add book to books_db self.add_to_books_db(cached_db, b_mi) # Get the library cid, confidence toc_entries = None if this_is_news: cid = self.news_clippings_cid confidence = 5 if path is not None: toc_entries = self._get_epub_toc(path=path, prepend_title=b_mi.title) else: cid, confidence = self.parent.generate_confidence(b_mi) if confidence >= 2: toc_entries = self._get_epub_toc(cid=cid, path=path) elif path is not None: toc_entries = self._get_epub_toc(path=path) self.tocs[book_id] = toc_entries # Update the timestamp self.update_timestamp(cached_db) self.commit() self.ios.disconnect_idevice() installed_books = list(installed_books) else: # Load installed books from cache self._log(" retrieving cached books from %s" % cached_db) self.opts.pb.set_maximum(2) self.opts.pb.set_value(1) Application.processEvents() installed_books = self._get_cached_books(cached_db) self.installed_books = installed_books
def wait_for_draw(self): # Without this the splash screen is not painted on linux and windows self.drawn_once = False st = time.time() while not self.drawn_once and (time.time() - st < 0.1): Application.instance().processEvents()
def restore_defaults(self): self.settings.restore_defaults() self.settings.save_as_prefs() def _save_settings(self): gprefs.set('cover_generation_save_settings_for_future', self.save_settings.isChecked()) gprefs.set('cover_settings_dialog_geom', bytearray(self.saveGeometry())) self.settings.save_state() def accept(self): self._save_settings() self.prefs_for_rendering = self.settings.prefs_for_rendering if self.save_settings.isChecked(): self.settings.save_as_prefs() QDialog.accept(self) def reject(self): self._save_settings() QDialog.reject(self) if __name__ == '__main__': from calibre.gui2 import Application app = Application([]) d = CoverSettingsDialog() d.show() app.exec_() del d del app
def _run(args, notify=None): # Ensure we can continue to function if GUI is closed os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None) reset_base_dir() if iswindows: # Ensure that all ebook editor instances are grouped together in the task # bar. This prevents them from being grouped with viewer process when # launched from within calibre, as both use calibre-parallel.exe import ctypes try: ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('com.calibre-ebook.edit-book') except: pass # Only available on windows 7 and newer # The following two lines are needed to prevent circular imports causing # errors during initialization of plugins that use the polish container # infrastructure. importlib.import_module('calibre.customize.ui') from calibre.gui2.tweak_book.ui import Main parser = option_parser() opts, args = parser.parse_args(args) if getattr(opts, 'detach', False): detach_gui() override = 'calibre-edit-book' if islinux else None app = Application(args, override_program_name=override) app.load_builtin_fonts() app.setWindowIcon(QIcon(I('tweak.png'))) Application.setOrganizationName(ORG_NAME) Application.setApplicationName(APP_UID) main = Main(opts, notify=notify) sys.excepthook = main.unhandled_exception main.show() if len(args) > 1: main.boss.open_book(args[1], edit_file=opts.edit_file, clear_notify_data=False) app.exec_()
def main(args=sys.argv): # Ensure we can continue to function if GUI is closed os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None) reset_base_dir() parser = option_parser() opts, args = parser.parse_args(args) override = 'calibre-tweak-book' if islinux else None app = Application(args, override_program_name=override) app.load_builtin_fonts() app.setWindowIcon(QIcon(I('tweak.png'))) Application.setOrganizationName(ORG_NAME) Application.setApplicationName(APP_UID) main = Main(opts) sys.excepthook = main.unhandled_exception main.show() if len(args) > 1: main.boss.open_book(args[1]) app.exec_()
self.pi.stopAnimation() self.toc_view(self.ebook) self.item_edit.load(self.ebook) self.stacks.setCurrentIndex(1) def write_toc(self): tb = None try: toc = self.toc_view.create_toc() toc.toc_title = getattr(self.toc_view, 'toc_title', None) commit_toc(self.ebook, toc, lang=self.toc_view.toc_lang, uid=self.toc_view.toc_uid) self.ebook.commit() except: import traceback tb = traceback.format_exc() self.writing_done.emit(tb) # }}} if __name__ == '__main__': app = Application([], force_calibre_style=True) app d = TOCEditor(sys.argv[-1]) d.start() d.exec_() del d # Needed to prevent sigsegv in exit cleanup
def clear_date(self): self.setDateTime(UNDEFINED_QDATETIME) def keyPressEvent(self, ev): if ev.key() == Qt.Key_Minus: ev.accept() self.clear_date() elif ev.key() == Qt.Key_Equal: self.today_date() ev.accept() elif ev.matches(QKeySequence.Copy): self.copy() ev.accept() elif ev.matches(QKeySequence.Cut): self.cut() ev.accept() elif ev.matches(QKeySequence.Paste): self.paste() ev.accept() else: return QDateTimeEdit.keyPressEvent(self, ev) if __name__ == '__main__': from calibre.gui2 import Application app = Application([]) app.load_builtin_fonts() w = RatingEditor.test() w.show() app.exec_()
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()
if not self.is_half_star: val //= 2 self.setCurrentIndex(val) def keyPressEvent(self, ev): if ev == QKeySequence.Undo: self.undo() return ev.accept() if ev == QKeySequence.Redo: self.redo() return ev.accept() k = ev.key() num = {getattr(Qt, "Key_%d" % i): i for i in range(6)}.get(k) if num is None: return QComboBox.keyPressEvent(self, ev) ev.accept() if self.is_half_star: num *= 2 self.setCurrentIndex(num) if __name__ == "__main__": from calibre.gui2 import Application app = Application([]) app.load_builtin_fonts() q = RatingEditor(is_half_star=True) q.rating_value = 7 q.show() app.exec_()
def _run(args, notify=None): # Ensure we can continue to function if GUI is closed os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None) reset_base_dir() if iswindows: # Ensure that all ebook editor instances are grouped together in the task # bar. This prevents them from being grouped with viewer process when # launched from within calibre, as both use calibre-parallel.exe import ctypes try: ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('com.calibre-ebook.edit-book') except Exception: pass # Only available on windows 7 and newer # The following two lines are needed to prevent circular imports causing # errors during initialization of plugins that use the polish container # infrastructure. importlib.import_module('calibre.customize.ui') from calibre.gui2.tweak_book import tprefs from calibre.gui2.tweak_book.ui import Main parser = option_parser() opts, args = parser.parse_args(args) decouple('edit-book-'), set_gui_prefs(tprefs) override = 'calibre-edit-book' if islinux else None app = Application(args, override_program_name=override, color_prefs=tprefs) app.file_event_hook = EventAccumulator() app.load_builtin_fonts() app.setWindowIcon(QIcon(I('tweak.png'))) Application.setOrganizationName(ORG_NAME) Application.setApplicationName(APP_UID) main = Main(opts, notify=notify) main.set_exception_handler() main.show() app.shutdown_signal_received.connect(main.boss.quit) if len(args) > 1: main.boss.open_book(args[1], edit_file=args[2:], clear_notify_data=False) else: for path in reversed(app.file_event_hook.events): main.boss.open_book(path) break app.file_event_hook = main.boss.open_book app.exec_() # Ensure that the parse worker has quit so that temp files can be deleted # on windows st = time.time() from calibre.gui2.tweak_book.preview import parse_worker while parse_worker.is_alive() and time.time() - st < 120: time.sleep(0.1)
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 OSError: 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 main(args=sys.argv): # Ensure we can continue to function if GUI is closed os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None) reset_base_dir() # The following two lines are needed to prevent circular imports causing # errors during initialization of plugins that use the polish container # infrastructure. importlib.import_module('calibre.customize.ui') from calibre.gui2.tweak_book.ui import Main parser = option_parser() opts, args = parser.parse_args(args) if getattr(opts, 'detach', False): detach_gui() override = 'calibre-tweak-book' if islinux else None app = Application(args, override_program_name=override) app.load_builtin_fonts() app.setWindowIcon(QIcon(I('tweak.png'))) Application.setOrganizationName(ORG_NAME) Application.setApplicationName(APP_UID) main = Main(opts) sys.excepthook = main.unhandled_exception main.show() if len(args) > 1: main.boss.open_book(args[1]) app.exec_()
if rules['version'] != self.model.EXIM_VERSION: raise ValueError('Unsupported rules version: {}'.format(rules['version'])) if rules['type'] != self.pref_name: raise ValueError('Rules are not of the correct type') rules = list(rules['rules']) except Exception as e: return error_dialog(self, _('No valid rules found'), _( 'No valid rules were found in {}.').format(files[0]), det_msg=as_unicode(e), show=True) self.model.import_rules(rules) self.changed.emit() # }}} if __name__ == '__main__': from calibre.gui2 import Application app = Application([]) from calibre.library import db db = db() if False: d = RuleEditor(db.field_metadata, 'column_icon_rules') d.add_blank_condition() d.exec_() kind, col, r = d.rule print ('Column to be colored:', col) print ('Template:') print (r.template)
lm_in_menubar = self.models['menubar-device'][1].has_action('Location Manager') if not pref_in_toolbar and not pref_in_menubar: error_dialog(self, _('Preferences missing'), _( 'The Preferences action must be in either the main toolbar or the menubar.'), show=True) raise AbortCommit() if not lm_in_toolbar and not lm_in_menubar: error_dialog(self, _('Location manager missing'), _( 'The Location manager must be in either the main toolbar or the menubar when a device is connected.'), show=True) raise AbortCommit() # Save data. for am, cm in self.models.values(): cm.commit() return False def restore_defaults(self): for am, cm in self.models.values(): cm.restore_defaults() am.restore_defaults() self.changed_signal.emit() def refresh_gui(self, gui): gui.bars_manager.init_bars() gui.bars_manager.update_bars() if __name__ == '__main__': from calibre.gui2 import Application app = Application([]) test_widget('Interface', 'Toolbar')
except AttributeError: dpr = self.devicePixelRatio() self.cover_pixmap.setDevicePixelRatio(dpr) self.marked = mi.marked self.resize_cover() html = render_html(mi, True, self, pref_name='popup_book_display_fields') set_html(mi, html, self.details) self.update_cover_tooltip() def open_with(self, entry): id_ = self.view.model().id(self.current_row) self.open_cover_with.emit(id_, entry) def choose_open_with(self): from calibre.gui2.open_with import choose_program entry = choose_program('cover_image', self) if entry is not None: self.open_with(entry) if __name__ == '__main__': from calibre.gui2 import Application from calibre.library import db app = Application([]) app.current_db = db() get_gui.ans = app d = Configure(app.current_db) d.exec_() del d del app